ReactOS  0.4.13-dev-544-gede3fdd
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)
 
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 3628 of file disk.c.

3649 {
3650  LARGE_INTEGER sectorZero;
3651  PIRP irp;
3652  IO_STATUS_BLOCK ioStatus;
3653  KEVENT event;
3654  NTSTATUS status;
3655  ULONG sectorSize;
3656  PULONG mbr;
3657  ULONG i;
3658 
3659  PAGED_CODE();
3660  sectorZero.QuadPart = (LONGLONG) 0;
3661 
3662  //
3663  // Create notification event object to be used to signal the inquiry
3664  // request completion.
3665  //
3666 
3668 
3669  //
3670  // Get sector size.
3671  //
3672 
3673  sectorSize = DeviceExtension->DiskGeometry->Geometry.BytesPerSector;
3674 
3675  //
3676  // Make sure sector size is at least 512 bytes.
3677  //
3678 
3679  if (sectorSize < 512) {
3680  sectorSize = 512;
3681  }
3682 
3683  //
3684  // Allocate buffer for sector read.
3685  //
3686 
3687  mbr = ExAllocatePool(NonPagedPoolCacheAligned, sectorSize);
3688 
3689  if (!mbr) {
3690  return FALSE;
3691  }
3692 
3693  //
3694  // Build IRP to read MBR.
3695  //
3696 
3698  DeviceExtension->DeviceObject,
3699  mbr,
3700  sectorSize,
3701  &sectorZero,
3702  &event,
3703  &ioStatus );
3704 
3705  if (!irp) {
3706  ExFreePool(mbr);
3707  return FALSE;
3708  }
3709 
3710  //
3711  // Pass request to port driver and wait for request to complete.
3712  //
3713 
3714  status = IoCallDriver(DeviceExtension->DeviceObject,
3715  irp);
3716 
3717  if (status == STATUS_PENDING) {
3719  Suspended,
3720  KernelMode,
3721  FALSE,
3722  NULL);
3723  status = ioStatus.Status;
3724  }
3725 
3726  if (!NT_SUCCESS(status)) {
3727  ExFreePool(mbr);
3728  return FALSE;
3729  }
3730 
3731  //
3732  // Calculate MBR checksum.
3733  //
3734 
3735  *Checksum = 0;
3736 
3737  for (i = 0; i < 128; i++) {
3738  *Checksum += mbr[i];
3739  }
3740 
3741  *Checksum = ~*Checksum + 1;
3742 
3743  ExFreePool(mbr);
3744  return TRUE;
3745 }
#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:1073
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:5030
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:4639
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:251
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSTATUS ScsiClassReadDriveCapacity(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:1029
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:4616
#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:3421
#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:1250
NTSTATUS ScsiClassClaimDevice(IN PDEVICE_OBJECT PortDeviceObject, IN PSCSI_INQUIRY_DATA LunInfo, IN BOOLEAN Release, OUT PDEVICE_OBJECT *NewPortDeviceObject OPTIONAL)
Definition: class2.c:4740
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:2777
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:5068
#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 1073 of file disk.c.

1077 {
1078  CCHAR ntNameBuffer[MAXIMUM_FILENAME_LENGTH];
1079  ULONG partitionNumber = 0;
1080  NTSTATUS status;
1081  PDEVICE_OBJECT deviceObject = NULL;
1082  PDISK_GEOMETRY_EX diskGeometry = NULL;
1083  PDRIVE_LAYOUT_INFORMATION partitionList = NULL;
1084  PDEVICE_EXTENSION deviceExtension;
1085  PDEVICE_EXTENSION physicalDeviceExtension;
1086  PCLASS_INIT_DATA initData = NULL;
1087  PDISK_DATA diskData;
1088  PDISK_DATA physicalDiskData;
1089  ULONG bytesPerSector;
1090  UCHAR sectorShift;
1091  ULONG srbFlags;
1092  ULONG dmByteSkew = 0;
1093  PULONG dmSkew;
1094  BOOLEAN dmActive = FALSE;
1095  ULONG numberListElements = 0;
1096 
1097 
1098  //
1099  // Get physical device geometry information for partition table reads.
1100  //
1101 
1102  physicalDeviceExtension = PhysicalDeviceObject->DeviceExtension;
1103  diskGeometry = physicalDeviceExtension->DiskGeometry;
1104  bytesPerSector = diskGeometry->Geometry.BytesPerSector;
1105 
1106  //
1107  // Make sure sector size is not zero.
1108  //
1109 
1110  if (bytesPerSector == 0) {
1111 
1112  //
1113  // Default sector size for disk is 512.
1114  //
1115 
1116  bytesPerSector = diskGeometry->Geometry.BytesPerSector = 512;
1117  }
1118 
1119  sectorShift = physicalDeviceExtension->SectorShift;
1120 
1121  //
1122  // Set pointer to disk data area that follows device extension.
1123  //
1124 
1125  diskData = (PDISK_DATA)(physicalDeviceExtension + 1);
1126  diskData->PartitionListState = Initializing;
1127 
1128  //
1129  // Determine is DM Driver is loaded on an IDE drive that is
1130  // under control of Atapi - this could be either a crashdump or
1131  // an Atapi device is sharing the controller with an IDE disk.
1132  //
1133 
1135  physicalDeviceExtension->DiskGeometry->Geometry.BytesPerSector,
1136  (ULONG)0x54,
1137  (PVOID)&dmSkew);
1138 
1139  if (dmSkew) {
1140 
1141  //
1142  // Update the device extension, so that the call to IoReadPartitionTable
1143  // will get the correct information. Any I/O to this disk will have
1144  // to be skewed by *dmSkew sectors aka DMByteSkew.
1145  //
1146 
1147  physicalDeviceExtension->DMSkew = *dmSkew;
1148  physicalDeviceExtension->DMActive = TRUE;
1149  physicalDeviceExtension->DMByteSkew = physicalDeviceExtension->DMSkew * bytesPerSector;
1150 
1151  //
1152  // Save away the information that we need, since this deviceExtension will soon be
1153  // blown away.
1154  //
1155 
1156  dmActive = TRUE;
1157  dmByteSkew = physicalDeviceExtension->DMByteSkew;
1158 
1159  }
1160 
1161 #ifdef __REACTOS__
1162  //
1163  // HACK so that we can use NT5+ NTOS functions with this NT4 driver
1164  // for removable devices and avoid an infinite recursive loop between
1165  // disk!UpdateRemovableGeometry() and ntos!IoReadPartitionTable().
1166  //
1167  diskData->UpdateRemovableGeometryCount = 0;
1168 #endif
1169 
1170  //
1171  // Create objects for all the partitions on the device.
1172  //
1173 
1175  physicalDeviceExtension->DiskGeometry->Geometry.BytesPerSector,
1176  TRUE,
1177  (PVOID)&partitionList);
1178 
1179  //
1180  // If the I/O read partition table failed and this is a removable device,
1181  // then fix up the partition list to make it look like there is one
1182  // zero length partition.
1183  //
1184  DPRINT("IoReadPartitionTable() status: 0x%08X\n", status);
1185  if ((!NT_SUCCESS(status) || partitionList->PartitionCount == 0) &&
1186  PhysicalDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1187 
1188  if (!NT_SUCCESS(status)) {
1189 
1190  //
1191  // Remember this disk is not ready.
1192  //
1193 
1194  diskData->DriveNotReady = TRUE;
1195 
1196  } else {
1197 
1198  //
1199  // Free the partition list allocated by IoReadPartitionTable.
1200  //
1201 
1202  ExFreePool(partitionList);
1203  }
1204 
1205  //
1206  // Allocate and zero a partition list.
1207  //
1208 
1209  partitionList = ExAllocatePool(NonPagedPool, sizeof(*partitionList));
1210 
1211 
1212  if (partitionList != NULL) {
1213 
1214  RtlZeroMemory( partitionList, sizeof( *partitionList ));
1215 
1216  //
1217  // Set the partition count to one and the status to success
1218  // so one device object will be created. Set the partition type
1219  // to a bogus value.
1220  //
1221 
1222  partitionList->PartitionCount = 1;
1223 
1225  }
1226  }
1227 
1228  if (NT_SUCCESS(status)) {
1229 
1230  //
1231  // Record disk signature.
1232  //
1233 
1234  diskData->Signature = partitionList->Signature;
1235 
1236  //
1237  // If disk signature is zero, then calculate the MBR checksum.
1238  //
1239 
1240  if (!diskData->Signature) {
1241 
1242  if (!CalculateMbrCheckSum(physicalDeviceExtension,
1243  &diskData->MbrCheckSum)) {
1244 
1245  DebugPrint((1,
1246  "SCSIDISK: Can't calculate MBR checksum for disk %x\n",
1247  physicalDeviceExtension->DeviceNumber));
1248  } else {
1249 
1250  DebugPrint((2,
1251  "SCSIDISK: MBR checksum for disk %x is %x\n",
1252  physicalDeviceExtension->DeviceNumber,
1253  diskData->MbrCheckSum));
1254  }
1255  }
1256 
1257  //
1258  // Check the registry and determine if the BIOS knew about this drive. If
1259  // it did then update the geometry with the BIOS information.
1260  //
1261 
1262  UpdateGeometry(physicalDeviceExtension);
1263 
1264  srbFlags = physicalDeviceExtension->SrbFlags;
1265 
1266  initData = ExAllocatePool(NonPagedPool, sizeof(CLASS_INIT_DATA));
1267  if (!initData)
1268  {
1269  DebugPrint((1,
1270  "Disk.CreatePartitionDeviceObjects - Allocation of initData failed\n"));
1271 
1273  goto CreatePartitionDeviceObjectsExit;
1274  }
1275 
1276  RtlZeroMemory(initData, sizeof(CLASS_INIT_DATA));
1277 
1278  initData->InitializationDataSize = sizeof(CLASS_INIT_DATA);
1280  initData->DeviceType = FILE_DEVICE_DISK;
1281  initData->DeviceCharacteristics = PhysicalDeviceObject->Characteristics;
1282  initData->ClassError = physicalDeviceExtension->ClassError;
1283  initData->ClassReadWriteVerification = physicalDeviceExtension->ClassReadWriteVerification;
1284  initData->ClassFindDevices = physicalDeviceExtension->ClassFindDevices;
1285  initData->ClassDeviceControl = physicalDeviceExtension->ClassDeviceControl;
1286  initData->ClassShutdownFlush = physicalDeviceExtension->ClassShutdownFlush;
1287  initData->ClassCreateClose = physicalDeviceExtension->ClassCreateClose;
1288  initData->ClassStartIo = physicalDeviceExtension->ClassStartIo;
1289 
1290  //
1291  // Create device objects for the device partitions (if any).
1292  // PartitionCount includes physical device partition 0,
1293  // so only one partition means no objects to create.
1294  //
1295 
1296  DebugPrint((2,
1297  "CreateDiskDeviceObjects: Number of partitions is %d\n",
1298  partitionList->PartitionCount));
1299 
1300  for (partitionNumber = 0; partitionNumber <
1301  partitionList->PartitionCount; partitionNumber++) {
1302 
1303  //
1304  // Create partition object and set up partition parameters.
1305  //
1306 
1307  sprintf(ntNameBuffer,
1308  "\\Device\\Harddisk%lu\\Partition%lu",
1309  physicalDeviceExtension->DeviceNumber,
1310  partitionNumber + 1);
1311 
1312  DebugPrint((2,
1313  "CreateDiskDeviceObjects: Create device object %s\n",
1314  ntNameBuffer));
1315 
1317  ntNameBuffer,
1319  &deviceObject,
1320  initData);
1321 
1322  if (!NT_SUCCESS(status)) {
1323 
1324  DebugPrint((1, "CreateDiskDeviceObjects: Can't create device object for %s\n", ntNameBuffer));
1325 
1326  break;
1327  }
1328 
1329  //
1330  // Set up device object fields.
1331  //
1332 
1333  deviceObject->Flags |= DO_DIRECT_IO;
1334 
1335  //
1336  // Check if this is during initialization. If not indicate that
1337  // system initialization already took place and this disk is ready
1338  // to be accessed.
1339  //
1340 
1341  if (!RegistryPath) {
1342  deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1343  }
1344 
1345  deviceObject->StackSize = (CCHAR)physicalDeviceExtension->PortDeviceObject->StackSize + 1;
1346 
1347  //
1348  // Set up device extension fields.
1349  //
1350 
1351  deviceExtension = deviceObject->DeviceExtension;
1352 
1353  if (dmActive) {
1354 
1355  //
1356  // Restore any saved DM values.
1357  //
1358 
1359  deviceExtension->DMByteSkew = dmByteSkew;
1360  deviceExtension->DMSkew = *dmSkew;
1361  deviceExtension->DMActive = TRUE;
1362 
1363  }
1364 
1365  //
1366  // Link new device extension to previous disk data
1367  // to support dynamic partitioning.
1368  //
1369 
1370  diskData->NextPartition = deviceExtension;
1371 
1372  //
1373  // Get pointer to new disk data.
1374  //
1375 
1376  diskData = (PDISK_DATA)(deviceExtension + 1);
1377 
1378  //
1379  // Set next partition pointer to NULL in case this is the
1380  // last partition.
1381  //
1382 
1383  diskData->NextPartition = NULL;
1384 
1385  //
1386  // Allocate spinlock for zoning for split-request completion.
1387  //
1388 
1389  KeInitializeSpinLock(&deviceExtension->SplitRequestSpinLock);
1390 
1391  //
1392  // Copy port device object pointer to device extension.
1393  //
1394 
1395  deviceExtension->PortDeviceObject = physicalDeviceExtension->PortDeviceObject;
1396 
1397  //
1398  // Set the alignment requirements for the device based on the
1399  // host adapter requirements
1400  //
1401 
1402  if (physicalDeviceExtension->PortDeviceObject->AlignmentRequirement > deviceObject->AlignmentRequirement) {
1403  deviceObject->AlignmentRequirement = physicalDeviceExtension->PortDeviceObject->AlignmentRequirement;
1404  }
1405 
1406 
1407  if (srbFlags & SRB_FLAGS_QUEUE_ACTION_ENABLE) {
1408  numberListElements = 30;
1409  } else {
1410  numberListElements = 8;
1411  }
1412 
1413  //
1414  // Build the lookaside list for srb's for this partition based on
1415  // whether the adapter and disk can do tagged queueing.
1416  //
1417 
1418  ScsiClassInitializeSrbLookasideList(deviceExtension,
1419  numberListElements);
1420 
1421  deviceExtension->SrbFlags = srbFlags;
1422 
1423  //
1424  // Set the sense-data pointer in the device extension.
1425  //
1426 
1427  deviceExtension->SenseData = physicalDeviceExtension->SenseData;
1428  deviceExtension->PortCapabilities = physicalDeviceExtension->PortCapabilities;
1429  deviceExtension->DiskGeometry = diskGeometry;
1430  diskData->PartitionOrdinal = diskData->PartitionNumber = partitionNumber + 1;
1431  diskData->PartitionType = partitionList->PartitionEntry[partitionNumber].PartitionType;
1432  diskData->BootIndicator = partitionList->PartitionEntry[partitionNumber].BootIndicator;
1433 
1434  DebugPrint((2, "CreateDiskDeviceObjects: Partition type is %x\n",
1435  diskData->PartitionType));
1436 
1437  deviceExtension->StartingOffset = partitionList->PartitionEntry[partitionNumber].StartingOffset;
1438  deviceExtension->PartitionLength = partitionList->PartitionEntry[partitionNumber].PartitionLength;
1439  diskData->HiddenSectors = partitionList->PartitionEntry[partitionNumber].HiddenSectors;
1440  deviceExtension->PortNumber = physicalDeviceExtension->PortNumber;
1441  deviceExtension->PathId = physicalDeviceExtension->PathId;
1442  deviceExtension->TargetId = physicalDeviceExtension->TargetId;
1443  deviceExtension->Lun = physicalDeviceExtension->Lun;
1444 
1445  //
1446  // Check for removable media support.
1447  //
1448 
1449  if (PhysicalDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1450  deviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
1451  }
1452 
1453  //
1454  // Set timeout value in seconds.
1455  //
1456 
1457  deviceExtension->TimeOutValue = physicalDeviceExtension->TimeOutValue;
1458  deviceExtension->DiskGeometry->Geometry.BytesPerSector = bytesPerSector;
1459  deviceExtension->SectorShift = sectorShift;
1460  deviceExtension->DeviceObject = deviceObject;
1461  deviceExtension->DeviceFlags |= physicalDeviceExtension->DeviceFlags;
1462 
1463  } // end for (partitionNumber) ...
1464 
1465  //
1466  // Free the buffer allocated by reading the
1467  // partition table.
1468  //
1469 
1470  ExFreePool(partitionList);
1471 
1472  if (dmSkew) {
1473  ExFreePool(dmSkew);
1474  }
1475 
1476  } else {
1477 
1478 CreatePartitionDeviceObjectsExit:
1479 
1480  if (partitionList) {
1481  ExFreePool(partitionList);
1482  }
1483  if (initData) {
1484  ExFreePool(initData);
1485  }
1486 
1487  if (dmSkew) {
1488  ExFreePool(dmSkew);
1489  }
1490 
1491  return status;
1492 
1493  } // end if...else
1494 
1495 
1496  physicalDiskData = (PDISK_DATA)(physicalDeviceExtension + 1);
1497  physicalDiskData->PartitionListState = Initialized;
1498 
1499  return(STATUS_SUCCESS);
1500 
1501 
1502 } // 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
DEVICE_TYPE DeviceType
Definition: class2.h:84
#define TRUE
Definition: types.h:120
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:394
#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:5030
LONG NTSTATUS
Definition: precomp.h:26
ULONG HiddenSectors
Definition: disk.c:64
ULONG BytesPerSector
Definition: ntdddisk.h:376
VOID NTAPI UpdateGeometry(IN PDEVICE_EXTENSION DeviceExtension)
Definition: disk.c:4078
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:380
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:467
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:4616
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:393
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:3628
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:310
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:2287
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
ULONG MbrCheckSum
Definition: disk.c:58
return STATUS_SUCCESS
Definition: btrfs.c:2777
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 3421 of file disk.c.

3426 {
3427  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3428  PINQUIRYDATA InquiryData = (PINQUIRYDATA)LunInfo->InquiryData;
3429  BAD_CONTROLLER_INFORMATION const *controller;
3430  ULONG j,length;
3431  PVOID modeData;
3432  PUCHAR pageData;
3433 
3434  for (j = 0; j < NUMBER_OF_BAD_CONTROLLERS; j++) {
3435 
3436  controller = &ScsiDiskBadControllers[j];
3437 
3438  if (!controller->DisableWriteCache || strncmp(controller->InquiryString, (PCCHAR)InquiryData->VendorId, strlen(controller->InquiryString))) {
3439  continue;
3440  }
3441 
3442  DebugPrint((1, "ScsiDisk.DisableWriteCache, Found bad controller! %s\n", controller->InquiryString));
3443 
3445 
3446  if (modeData == NULL) {
3447 
3448  DebugPrint((1,
3449  "ScsiDisk.DisableWriteCache: Check for write-cache enable failed\n"));
3450  return;
3451  }
3452 
3453  RtlZeroMemory(modeData, MODE_DATA_SIZE);
3454 
3456  modeData,
3459 
3460  if (length < sizeof(MODE_PARAMETER_HEADER)) {
3461 
3462  //
3463  // Retry the request in case of a check condition.
3464  //
3465 
3467  modeData,
3470 
3471  if (length < sizeof(MODE_PARAMETER_HEADER)) {
3472 
3473 
3474  DebugPrint((1,
3475  "ScsiDisk.DisableWriteCache: Mode Sense failed\n"));
3476 
3477  ExFreePool(modeData);
3478  return;
3479 
3480  }
3481  }
3482 
3483  //
3484  // If the length is greater than length indicated by the mode data reset
3485  // the data to the mode data.
3486  //
3487 
3488  if (length > (ULONG) ((PMODE_PARAMETER_HEADER) modeData)->ModeDataLength + 1) {
3489  length = ((PMODE_PARAMETER_HEADER) modeData)->ModeDataLength + 1;
3490  }
3491 
3492  //
3493  // Check to see if the write cache is enabled.
3494  //
3495 
3496  pageData = ScsiClassFindModePage( modeData, length, MODE_PAGE_CACHING, TRUE);
3497 
3498  //
3499  // Assume that write cache is disabled or not supported.
3500  //
3501 
3502  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
3503 
3504  //
3505  // Check if valid caching page exists.
3506  //
3507 
3508  if (pageData != NULL) {
3509 
3510  BOOLEAN savePage = FALSE;
3511 
3512  savePage = (BOOLEAN)(((PMODE_CACHING_PAGE)pageData)->PageSavable);
3513 
3514  //
3515  // Check if write cache is disabled.
3516  //
3517 
3518  if (((PMODE_CACHING_PAGE)pageData)->WriteCacheEnable) {
3519 
3520  PIO_ERROR_LOG_PACKET errorLogEntry;
3521  LONG errorCode;
3522 
3523 
3524  //
3525  // Disable write cache and ensure necessary fields are zeroed.
3526  //
3527 
3528  ((PMODE_CACHING_PAGE)pageData)->WriteCacheEnable = FALSE;
3529  ((PMODE_CACHING_PAGE)pageData)->Reserved = 0;
3530  ((PMODE_CACHING_PAGE)pageData)->PageSavable = 0;
3531  ((PMODE_CACHING_PAGE)pageData)->Reserved2 = 0;
3532 
3533  //
3534  // Extract length from caching page.
3535  //
3536 
3537  length = ((PMODE_CACHING_PAGE)pageData)->PageLength;
3538 
3539  //
3540  // Compensate for page code and page length.
3541  //
3542 
3543  length += 2;
3544 
3545  //
3546  // Issue mode select to set the parameter.
3547  //
3548 
3550  (PCHAR)pageData,
3551  length,
3552  savePage)) {
3553 
3554  DebugPrint((1,
3555  "SCSIDISK: Disk write cache disabled\n"));
3556 
3557  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
3558  errorCode = IO_WRITE_CACHE_DISABLED;
3559 
3560  } else {
3562  (PCHAR)pageData,
3563  length,
3564  savePage)) {
3565 
3566  DebugPrint((1,
3567  "SCSIDISK: Disk write cache disabled\n"));
3568 
3569 
3570  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
3571  errorCode = IO_WRITE_CACHE_DISABLED;
3572 
3573  } else {
3574 
3575  DebugPrint((1,
3576  "SCSIDISK: Mode select to disable write cache failed\n"));
3577 
3578  deviceExtension->DeviceFlags |= DEV_WRITE_CACHE;
3579  errorCode = IO_WRITE_CACHE_ENABLED;
3580  }
3581  }
3582 
3583  //
3584  // Log the appropriate informational or error entry.
3585  //
3586 
3588  DeviceObject,
3589  sizeof(IO_ERROR_LOG_PACKET) + 3
3590  * sizeof(ULONG));
3591 
3592  if (errorLogEntry != NULL) {
3593 
3594  errorLogEntry->FinalStatus = STATUS_SUCCESS;
3595  errorLogEntry->ErrorCode = errorCode;
3596  errorLogEntry->SequenceNumber = 0;
3597  errorLogEntry->MajorFunctionCode = IRP_MJ_SCSI;
3598  errorLogEntry->IoControlCode = 0;
3599  errorLogEntry->RetryCount = 0;
3600  errorLogEntry->UniqueErrorValue = 0x1;
3601  errorLogEntry->DumpDataSize = 3 * sizeof(ULONG);
3602  errorLogEntry->DumpData[0] = LunInfo->PathId;
3603  errorLogEntry->DumpData[1] = LunInfo->TargetId;
3604  errorLogEntry->DumpData[2] = LunInfo->Lun;
3605 
3606  //
3607  // Write the error log packet.
3608  //
3609 
3610  IoWriteErrorLogEntry(errorLogEntry);
3611  }
3612  }
3613  }
3614 
3615  //
3616  // Found device so exit the loop and return.
3617  //
3618 
3619  break;
3620  }
3621 
3622  return;
3623 }
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:1965
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:3285
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:1963
#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:3610
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:3513
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:2777
#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:451
VOID NTAPI ScsiDiskProcessError(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
Definition: disk.c:4575
NTSTATUS NTAPI ScsiDiskReadWriteVerification(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: disk.c:1507
#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:2967
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 3750 of file disk.c.

3776 {
3777  PDISK_DATA diskData = (PDISK_DATA)(DeviceExtension + 1);
3778  BOOLEAN diskFound = FALSE;
3779  OBJECT_ATTRIBUTES objectAttributes;
3780  UNICODE_STRING unicodeString;
3781  UNICODE_STRING identifier;
3782  ULONG busNumber;
3783  ULONG adapterNumber;
3784  ULONG diskNumber;
3785  HANDLE adapterKey;
3786  HANDLE spareKey;
3787  HANDLE diskKey;
3788  HANDLE targetKey;
3789  NTSTATUS status;
3790  STRING string;
3791  STRING anotherString;
3792  ULONG length;
3793  UCHAR buffer[20];
3795 
3796  PAGED_CODE();
3797 
3798  for (busNumber = 0; ; busNumber++) {
3799 
3800  //
3801  // Open controller name key.
3802  //
3803 
3804  sprintf((PCHAR)buffer,
3805  "%lu",
3806  busNumber);
3807 
3808  RtlInitString(&string,
3809  (PCSZ)buffer);
3810 
3811  status = RtlAnsiStringToUnicodeString(&unicodeString,
3812  &string,
3813  TRUE);
3814 
3815  if (!NT_SUCCESS(status)){
3816  break;
3817  }
3818 
3819  InitializeObjectAttributes(&objectAttributes,
3820  &unicodeString,
3822  BusKey,
3824 
3825  status = ZwOpenKey(&spareKey,
3826  KEY_READ,
3827  &objectAttributes);
3828 
3829  RtlFreeUnicodeString(&unicodeString);
3830 
3831  if (!NT_SUCCESS(status)) {
3832  break;
3833  }
3834 
3835  //
3836  // Open up controller ordinal key.
3837  //
3838 
3839  RtlInitUnicodeString(&unicodeString, L"DiskController");
3840  InitializeObjectAttributes(&objectAttributes,
3841  &unicodeString,
3843  spareKey,
3845 
3846  status = ZwOpenKey(&adapterKey,
3847  KEY_READ,
3848  &objectAttributes);
3849 
3850  //
3851  // This could fail even with additional adapters of this type
3852  // to search.
3853  //
3854 
3855  if (!NT_SUCCESS(status)) {
3856  continue;
3857  }
3858 
3859  for (adapterNumber = 0; ; adapterNumber++) {
3860 
3861  //
3862  // Open disk key.
3863  //
3864 
3865  sprintf((PCHAR)buffer,
3866  "%lu\\DiskPeripheral",
3867  adapterNumber);
3868 
3869  RtlInitString(&string,
3870  (PCSZ)buffer);
3871 
3872  status = RtlAnsiStringToUnicodeString(&unicodeString,
3873  &string,
3874  TRUE);
3875 
3876  if (!NT_SUCCESS(status)){
3877  break;
3878  }
3879 
3880  InitializeObjectAttributes(&objectAttributes,
3881  &unicodeString,
3883  adapterKey,
3885 
3886  status = ZwOpenKey(&diskKey,
3887  KEY_READ,
3888  &objectAttributes);
3889 
3890  RtlFreeUnicodeString(&unicodeString);
3891 
3892  if (!NT_SUCCESS(status)) {
3893  break;
3894  }
3895 
3896  for (diskNumber = 0; ; diskNumber++) {
3897 
3898  sprintf((PCHAR)buffer,
3899  "%lu",
3900  diskNumber);
3901 
3902  RtlInitString(&string,
3903  (PCSZ)buffer);
3904 
3905  status = RtlAnsiStringToUnicodeString(&unicodeString,
3906  &string,
3907  TRUE);
3908 
3909  if (!NT_SUCCESS(status)){
3910  break;
3911  }
3912 
3913  InitializeObjectAttributes(&objectAttributes,
3914  &unicodeString,
3916  diskKey,
3918 
3919  status = ZwOpenKey(&targetKey,
3920  KEY_READ,
3921  &objectAttributes);
3922 
3923  RtlFreeUnicodeString(&unicodeString);
3924 
3925  if (!NT_SUCCESS(status)) {
3926  break;
3927  }
3928 
3929  //
3930  // Allocate buffer for registry query.
3931  //
3932 
3934 
3935  if (keyData == NULL) {
3936  ZwClose(targetKey);
3937  continue;
3938  }
3939 
3940  //
3941  // Get disk peripheral identifier.
3942  //
3943 
3944  RtlInitUnicodeString(&unicodeString, L"Identifier");
3945  status = ZwQueryValueKey(targetKey,
3946  &unicodeString,
3948  keyData,
3950  &length);
3951 
3952  ZwClose(targetKey);
3953 
3954  if (!NT_SUCCESS(status)) {
3955  ExFreePool(keyData);
3956  continue;
3957  }
3958 
3959  if (keyData->DataLength < 9*sizeof(WCHAR)) {
3960  //
3961  // the data is too short to use (we subtract 9 chars in normal path)
3962  //
3963  DebugPrint((1, "EnumerateBusKey: Saved data was invalid, "
3964  "not enough data in registry!\n"));
3965  ExFreePool(keyData);
3966  continue;
3967  }
3968 
3969  //
3970  // Complete unicode string.
3971  //
3972 
3973  identifier.Buffer =
3974  (PWSTR)((PUCHAR)keyData + keyData->DataOffset);
3975  identifier.Length = (USHORT)keyData->DataLength;
3976  identifier.MaximumLength = (USHORT)keyData->DataLength;
3977 
3978  //
3979  // Convert unicode identifier to ansi string.
3980  //
3981 
3982  status =
3983  RtlUnicodeStringToAnsiString(&anotherString,
3984  &identifier,
3985  TRUE);
3986 
3987  if (!NT_SUCCESS(status)) {
3988  ExFreePool(keyData);
3989  continue;
3990  }
3991 
3992  //
3993  // If checksum is zero, then the MBR is valid and
3994  // the signature is meaningful.
3995  //
3996 
3997  if (diskData->MbrCheckSum) {
3998 
3999  //
4000  // Convert checksum to ansi string.
4001  //
4002 
4003  sprintf((PCHAR)buffer, "%08lx", diskData->MbrCheckSum);
4004 
4005  } else {
4006 
4007  //
4008  // Convert signature to ansi string.
4009  //
4010 
4011  sprintf((PCHAR)buffer, "%08lx", diskData->Signature);
4012 
4013  //
4014  // Make string point at signature. Can't use scan
4015  // functions because they are not exported for driver use.
4016  //
4017 
4018  anotherString.Buffer+=9;
4019  }
4020 
4021  //
4022  // Convert to ansi string.
4023  //
4024 
4025  RtlInitString(&string,
4026  (PCSZ)buffer);
4027 
4028 
4029  //
4030  // Make string lengths equal.
4031  //
4032 
4033  anotherString.Length = string.Length;
4034 
4035  //
4036  // Check if strings match.
4037  //
4038 
4039  if (RtlCompareString(&string,
4040  &anotherString,
4041  TRUE) == 0) {
4042 
4043  diskFound = TRUE;
4044  *DiskNumber = diskNumber;
4045  }
4046 
4047  ExFreePool(keyData);
4048 
4049  //
4050  // Readjust identifier string if necessary.
4051  //
4052 
4053  if (!diskData->MbrCheckSum) {
4054  anotherString.Buffer-=9;
4055  }
4056 
4057  RtlFreeAnsiString(&anotherString);
4058 
4059  if (diskFound) {
4060  break;
4061  }
4062  }
4063 
4064  ZwClose(diskKey);
4065  }
4066 
4067  ZwClose(adapterKey);
4068  }
4069 
4070  ZwClose(BusKey);
4071  return diskFound;
4072 
4073 } // 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:4568
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:846
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 3145 of file disk.c.

3167 {
3168  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3169  PVOID modeData;
3170  PUCHAR pageData;
3171  ULONG length;
3172 
3173  PAGED_CODE();
3174 
3176 
3177  if (modeData == NULL) {
3178  return(FALSE);
3179  }
3180 
3181  RtlZeroMemory(modeData, MODE_DATA_SIZE);
3182 
3184  modeData,
3187 
3188  if (length < sizeof(MODE_PARAMETER_HEADER)) {
3189 
3190  //
3191  // Retry the request in case of a check condition.
3192  //
3193 
3195  modeData,
3198 
3199  if (length < sizeof(MODE_PARAMETER_HEADER)) {
3200 
3201  ExFreePool(modeData);
3202  return(FALSE);
3203 
3204  }
3205  }
3206 
3207  //
3208  // If the length is greater than length indicated by the mode data reset
3209  // the data to the mode data.
3210  //
3211 
3212  if (length > (ULONG) ((PMODE_PARAMETER_HEADER) modeData)->ModeDataLength + 1) {
3213  length = ((PMODE_PARAMETER_HEADER) modeData)->ModeDataLength + 1;
3214  }
3215 
3216  //
3217  // Look for the flexible disk mode page.
3218  //
3219 
3220  pageData = ScsiClassFindModePage( modeData, length, MODE_PAGE_FLEXIBILE, TRUE);
3221 
3222  if (pageData != NULL) {
3223 
3224  DebugPrint((1, "Scsidisk: Flexible disk page found, This is a floppy.\n"));
3225  ExFreePool(modeData);
3226  return(TRUE);
3227  }
3228 
3229  //
3230  // Check to see if the write cache is enabled.
3231  //
3232 
3233  pageData = ScsiClassFindModePage( modeData, length, MODE_PAGE_CACHING, TRUE);
3234 
3235  //
3236  // Assume that write cache is disabled or not supported.
3237  //
3238 
3239  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
3240 
3241  //
3242  // Check if valid caching page exists.
3243  //
3244 
3245  if (pageData != NULL) {
3246 
3247  //
3248  // Check if write cache is disabled.
3249  //
3250 
3251  if (((PMODE_CACHING_PAGE)pageData)->WriteCacheEnable) {
3252 
3253  DebugPrint((1,
3254  "SCSIDISK: Disk write cache enabled\n"));
3255 
3256  //
3257  // Check if forced unit access (FUA) is supported.
3258  //
3259 
3260  if (((PMODE_PARAMETER_HEADER)modeData)->DeviceSpecificParameter & MODE_DSP_FUA_SUPPORTED) {
3261 
3262  deviceExtension->DeviceFlags |= DEV_WRITE_CACHE;
3263 
3264  } else {
3265 
3266  DebugPrint((1,
3267  "SCSIDISK: Disk does not support FUA or DPO\n"));
3268 
3269  //
3270  // TODO: Log this.
3271  //
3272 
3273  }
3274  }
3275  }
3276 
3277  ExFreePool(modeData);
3278  return(FALSE);
3279 
3280 } // 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:3610
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:3513
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().

◆ ResetScsiBus()

VOID NTAPI ResetScsiBus ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 4741 of file disk.c.

4761 {
4762  PIO_STACK_LOCATION irpStack;
4763  PIRP irp;
4764  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4765  PSCSI_REQUEST_BLOCK srb;
4767 
4768  DebugPrint((1, "ScsiDisk ResetScsiBus: Sending reset bus request to port driver.\n"));
4769 
4770  //
4771  // Allocate Srb from nonpaged pool.
4772  //
4773 
4775  sizeof(COMPLETION_CONTEXT));
4776 
4777  //
4778  // Save the device object in the context for use by the completion
4779  // routine.
4780  //
4781 
4782  context->DeviceObject = DeviceObject;
4783  srb = &context->Srb;
4784 
4785  //
4786  // Zero out srb.
4787  //
4788 
4790 
4791  //
4792  // Write length to SRB.
4793  //
4794 
4796 
4797  //
4798  // Set up SCSI bus address.
4799  //
4800 
4801  srb->PathId = deviceExtension->PathId;
4802  srb->TargetId = deviceExtension->TargetId;
4803  srb->Lun = deviceExtension->Lun;
4804 
4806 
4807  //
4808  // Build the asynchronous request to be sent to the port driver.
4809  // Since this routine is called from a DPC the IRP should always be
4810  // available.
4811  //
4812 
4814 
4817  context,
4818  TRUE,
4819  TRUE,
4820  TRUE);
4821 
4822  irpStack = IoGetNextIrpStackLocation(irp);
4823 
4824  irpStack->MajorFunction = IRP_MJ_SCSI;
4825 
4826  srb->OriginalRequest = irp;
4827 
4828  //
4829  // Store the SRB address in next stack for port driver.
4830  //
4831 
4832  irpStack->Parameters.Scsi.Srb = srb;
4833 
4834  //
4835  // Call the port driver with the IRP.
4836  //
4837 
4838  IoCallDriver(deviceExtension->PortDeviceObject, irp);
4839 
4840  return;
4841 
4842 } // end ResetScsiBus()
#define TRUE
Definition: types.h:120
PVOID OriginalRequest
Definition: srb.h:258
Definition: http.c:6587
#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:2479
#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:2771
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 4639 of file disk.c.

4666 {
4667  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4668  PINQUIRYDATA InquiryData = (PINQUIRYDATA)LunInfo->InquiryData;
4669  BAD_CONTROLLER_INFORMATION const *controller;
4670  ULONG j;
4671 
4672  for (j = 0; j < NUMBER_OF_BAD_CONTROLLERS; j++) {
4673 
4674  controller = &ScsiDiskBadControllers[j];
4675 
4676  if (strncmp(controller->InquiryString, (PCCHAR)InquiryData->VendorId, strlen(controller->InquiryString))) {
4677  continue;
4678  }
4679 
4680  DebugPrint((1, "ScsiDisk ScanForSpecial, Found bad controller! %s\n", controller->InquiryString));
4681 
4682  //
4683  // Found a listed controller. Determine what must be done.
4684  //
4685 
4686  if (controller->DisableTaggedQueuing) {
4687 
4688  //
4689  // Disable tagged queuing.
4690  //
4691 
4692  deviceExtension->SrbFlags &= ~SRB_FLAGS_QUEUE_ACTION_ENABLE;
4693  }
4694 
4695  if (controller->DisableSynchronousTransfers) {
4696 
4697  //
4698  // Disable synchronous data transfers.
4699  //
4700 
4701  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
4702 
4703  }
4704 
4705  if (controller->DisableDisconnects) {
4706 
4707  //
4708  // Disable disconnects.
4709  //
4710 
4711  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_DISCONNECT;
4712 
4713  }
4714 
4715  //
4716  // Found device so exit the loop and return.
4717  //
4718 
4719  break;
4720  }
4721 
4722  //
4723  // Set the StartUnit flag appropriately.
4724  //
4725 
4726  if (DeviceObject->DeviceType == FILE_DEVICE_DISK) {
4727  deviceExtension->DeviceFlags |= DEV_SAFE_START_UNIT;
4728 
4729  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
4730  if (_strnicmp((PCCHAR)InquiryData->VendorId, "iomega", strlen("iomega"))) {
4731  deviceExtension->DeviceFlags &= ~DEV_SAFE_START_UNIT;
4732  }
4733  }
4734  }
4735 
4736  return;
4737 }
#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 1602 of file disk.c.

1624 {
1626  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1627  PDISK_DATA diskData = (PDISK_DATA)(deviceExtension + 1);
1628  PSCSI_REQUEST_BLOCK srb;
1629  PCDB cdb;
1630  PMODE_PARAMETER_HEADER modeData;
1631  PIRP irp2;
1632  ULONG length;
1633  NTSTATUS status;
1634  KEVENT event;
1635  IO_STATUS_BLOCK ioStatus;
1636 
1637  PAGED_CODE();
1638 
1640 
1641  if (srb == NULL) {
1642 
1643  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1646  }
1647 
1648  //
1649  // Write zeros to Srb.
1650  //
1651 
1653 
1654  cdb = (PCDB)srb->Cdb;
1655 
1656  switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
1657 
1658  case SMART_GET_VERSION: {
1659 
1660  ULONG_PTR buffer;
1661  PSRB_IO_CONTROL srbControl;
1662  PGETVERSIONINPARAMS versionParams;
1663 
1664  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1665  sizeof(GETVERSIONINPARAMS)) {
1667  break;
1668  }
1669 
1670  //
1671  // Create notification event object to be used to signal the
1672  // request completion.
1673  //
1674 
1676 
1677  srbControl = ExAllocatePool(NonPagedPool,
1678  sizeof(SRB_IO_CONTROL) + sizeof(GETVERSIONINPARAMS));
1679 
1680  if (!srbControl) {
1682  break;
1683  }
1684 
1685  //
1686  // fill in srbControl fields
1687  //
1688 
1689  srbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
1690  RtlMoveMemory (srbControl->Signature, "SCSIDISK", 8);
1691  srbControl->Timeout = deviceExtension->TimeOutValue;
1692  srbControl->Length = sizeof(GETVERSIONINPARAMS);
1694 
1695  //
1696  // Point to the 'buffer' portion of the SRB_CONTROL
1697  //
1698 
1699  buffer = (ULONG_PTR)srbControl + srbControl->HeaderLength;
1700 
1701  //
1702  // Ensure correct target is set in the cmd parameters.
1703  //
1704 
1705  versionParams = (PGETVERSIONINPARAMS)buffer;
1706  versionParams->bIDEDeviceMap = deviceExtension->TargetId;
1707 
1708  //
1709  // Copy the IOCTL parameters to the srb control buffer area.
1710  //
1711 
1712  RtlMoveMemory((PVOID)buffer, Irp->AssociatedIrp.SystemBuffer, sizeof(GETVERSIONINPARAMS));
1713 
1714 
1716  deviceExtension->PortDeviceObject,
1717  srbControl,
1718  sizeof(SRB_IO_CONTROL) + sizeof(GETVERSIONINPARAMS),
1719  srbControl,
1720  sizeof(SRB_IO_CONTROL) + sizeof(GETVERSIONINPARAMS),
1721  FALSE,
1722  &event,
1723  &ioStatus);
1724 
1725  if (irp2 == NULL) {
1727  break;
1728  }
1729 
1730  //
1731  // Call the port driver with the request and wait for it to complete.
1732  //
1733 
1734  status = IoCallDriver(deviceExtension->PortDeviceObject, irp2);
1735 
1736  if (status == STATUS_PENDING) {
1738  status = ioStatus.Status;
1739  }
1740 
1741  //
1742  // If successful, copy the data received into the output buffer.
1743  // This should only fail in the event that the IDE driver is older than this driver.
1744  //
1745 
1746  if (NT_SUCCESS(status)) {
1747 
1748  buffer = (ULONG_PTR)srbControl + srbControl->HeaderLength;
1749 
1750  RtlMoveMemory ( Irp->AssociatedIrp.SystemBuffer, (PVOID)buffer, sizeof(GETVERSIONINPARAMS));
1751  Irp->IoStatus.Information = sizeof(GETVERSIONINPARAMS);
1752  }
1753 
1754  ExFreePool(srbControl);
1755  break;
1756  }
1757 
1758  case SMART_RCV_DRIVE_DATA: {
1759 
1760  PSENDCMDINPARAMS cmdInParameters = ((PSENDCMDINPARAMS)Irp->AssociatedIrp.SystemBuffer);
1761  ULONG controlCode = 0;
1762  PSRB_IO_CONTROL srbControl;
1763  ULONG_PTR buffer;
1764 
1765  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
1766  (sizeof(SENDCMDINPARAMS) - 1)) {
1768  break;
1769 
1770  } else if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1771  (sizeof(SENDCMDOUTPARAMS) + 512 - 1)) {
1773  break;
1774  }
1775 
1776  //
1777  // Create notification event object to be used to signal the
1778  // request completion.
1779  //
1780 
1782 
1783  if (cmdInParameters->irDriveRegs.bCommandReg == ID_CMD) {
1784 
1786  controlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
1787 
1788  } else if (cmdInParameters->irDriveRegs.bCommandReg == SMART_CMD) {
1789  switch (cmdInParameters->irDriveRegs.bFeaturesReg) {
1790  case READ_ATTRIBUTES:
1793  break;
1794  case READ_THRESHOLDS:
1797  break;
1798  default:
1800  break;
1801  }
1802  } else {
1803 
1805  }
1806 
1807  if (controlCode == 0) {
1809  break;
1810  }
1811 
1812  srbControl = ExAllocatePool(NonPagedPool,
1813  sizeof(SRB_IO_CONTROL) + length);
1814 
1815  if (!srbControl) {
1817  break;
1818  }
1819 
1820  //
1821  // fill in srbControl fields
1822  //
1823 
1824  srbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
1825  RtlMoveMemory (srbControl->Signature, "SCSIDISK", 8);
1826  srbControl->Timeout = deviceExtension->TimeOutValue;
1827  srbControl->Length = length;
1828  srbControl->ControlCode = controlCode;
1829 
1830  //
1831  // Point to the 'buffer' portion of the SRB_CONTROL
1832  //
1833 
1834  buffer = (ULONG_PTR)srbControl + srbControl->HeaderLength;
1835 
1836  //
1837  // Ensure correct target is set in the cmd parameters.
1838  //
1839 
1840  cmdInParameters->bDriveNumber = deviceExtension->TargetId;
1841 
1842  //
1843  // Copy the IOCTL parameters to the srb control buffer area.
1844  //
1845 
1846  RtlMoveMemory((PVOID)buffer, Irp->AssociatedIrp.SystemBuffer, sizeof(SENDCMDINPARAMS) - 1);
1847 
1849  deviceExtension->PortDeviceObject,
1850  srbControl,
1851  sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS) - 1,
1852  srbControl,
1853  sizeof(SRB_IO_CONTROL) + length,
1854  FALSE,
1855  &event,
1856  &ioStatus);
1857 
1858  if (irp2 == NULL) {
1860  break;
1861  }
1862 
1863  //
1864  // Call the port driver with the request and wait for it to complete.
1865  //
1866 
1867  status = IoCallDriver(deviceExtension->PortDeviceObject, irp2);
1868 
1869  if (status == STATUS_PENDING) {
1871  status = ioStatus.Status;
1872  }
1873 
1874  //
1875  // If successful, copy the data received into the output buffer
1876  //
1877 
1878  buffer = (ULONG_PTR)srbControl + srbControl->HeaderLength;
1879 
1880  if (NT_SUCCESS(status)) {
1881 
1882  RtlMoveMemory ( Irp->AssociatedIrp.SystemBuffer, (PVOID)buffer, length - 1);
1883  Irp->IoStatus.Information = length - 1;
1884 
1885  } else {
1886 
1887  RtlMoveMemory ( Irp->AssociatedIrp.SystemBuffer, (PVOID)buffer, (sizeof(SENDCMDOUTPARAMS) - 1));
1888  Irp->IoStatus.Information = sizeof(SENDCMDOUTPARAMS) - 1;
1889 
1890  }
1891 
1892  ExFreePool(srbControl);
1893  break;
1894 
1895  }
1896 
1897  case SMART_SEND_DRIVE_COMMAND: {
1898 
1899  PSENDCMDINPARAMS cmdInParameters = ((PSENDCMDINPARAMS)Irp->AssociatedIrp.SystemBuffer);
1900  PSRB_IO_CONTROL srbControl;
1901  ULONG controlCode = 0;
1902  ULONG_PTR buffer;
1903 
1904  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
1905  (sizeof(SENDCMDINPARAMS) - 1)) {
1907  break;
1908 
1909  } else if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1910  (sizeof(SENDCMDOUTPARAMS) - 1)) {
1912  break;
1913  }
1914 
1915  //
1916  // Create notification event object to be used to signal the
1917  // request completion.
1918  //
1919 
1921 
1922  length = 0;
1923 
1924  if (cmdInParameters->irDriveRegs.bCommandReg == SMART_CMD) {
1925  switch (cmdInParameters->irDriveRegs.bFeaturesReg) {
1926 
1927  case ENABLE_SMART:
1928  controlCode = IOCTL_SCSI_MINIPORT_ENABLE_SMART;
1929  break;
1930 
1931  case DISABLE_SMART:
1932  controlCode = IOCTL_SCSI_MINIPORT_DISABLE_SMART;
1933  break;
1934 
1935  case RETURN_SMART_STATUS:
1936 
1937  //
1938  // Ensure bBuffer is at least 2 bytes (to hold the values of
1939  // cylinderLow and cylinderHigh).
1940  //
1941 
1942  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1943  (sizeof(SENDCMDOUTPARAMS) - 1 + sizeof(IDEREGS))) {
1944 
1946  break;
1947  }
1948 
1949  controlCode = IOCTL_SCSI_MINIPORT_RETURN_STATUS;
1950  length = sizeof(IDEREGS);
1951  break;
1952 
1955  break;
1956 
1957  case SAVE_ATTRIBUTE_VALUES:
1959  break;
1960 
1961  case EXECUTE_OFFLINE_DIAGS:
1963  break;
1964 
1965  default:
1967  break;
1968  }
1969  } else {
1970 
1972  }
1973 
1974  if (controlCode == 0) {
1976  break;
1977  }
1978 
1979  length += (sizeof(SENDCMDOUTPARAMS) > sizeof(SENDCMDINPARAMS)) ? sizeof(SENDCMDOUTPARAMS) : sizeof(SENDCMDINPARAMS);
1980  srbControl = ExAllocatePool(NonPagedPool,
1981  sizeof(SRB_IO_CONTROL) + length);
1982 
1983  if (!srbControl) {
1985  break;
1986  }
1987 
1988  //
1989  // fill in srbControl fields
1990  //
1991 
1992  srbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
1993  RtlMoveMemory (srbControl->Signature, "SCSIDISK", 8);
1994  srbControl->Timeout = deviceExtension->TimeOutValue;
1995  srbControl->Length = length;
1996 
1997  //
1998  // Point to the 'buffer' portion of the SRB_CONTROL
1999  //
2000 
2001  buffer = (ULONG_PTR)srbControl + srbControl->HeaderLength;
2002 
2003  //
2004  // Ensure correct target is set in the cmd parameters.
2005  //
2006 
2007  cmdInParameters->bDriveNumber = deviceExtension->TargetId;
2008 
2009  //
2010  // Copy the IOCTL parameters to the srb control buffer area.
2011  //
2012 
2013  RtlMoveMemory((PVOID)buffer, Irp->AssociatedIrp.SystemBuffer, sizeof(SENDCMDINPARAMS) - 1);
2014 
2015  srbControl->ControlCode = controlCode;
2016 
2018  deviceExtension->PortDeviceObject,
2019  srbControl,
2020  sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS) - 1,
2021  srbControl,
2022  sizeof(SRB_IO_CONTROL) + length,
2023  FALSE,
2024  &event,
2025  &ioStatus);
2026 
2027  if (irp2 == NULL) {
2029  break;
2030  }
2031 
2032  //
2033  // Call the port driver with the request and wait for it to complete.
2034  //
2035 
2036  status = IoCallDriver(deviceExtension->PortDeviceObject, irp2);
2037 
2038  if (status == STATUS_PENDING) {
2040  status = ioStatus.Status;
2041  }
2042 
2043  //
2044  // Copy the data received into the output buffer. Since the status buffer
2045  // contains error information also, always perform this copy. IO will will
2046  // either pass this back to the app, or zero it, in case of error.
2047  //
2048 
2049  buffer = (ULONG_PTR)srbControl + srbControl->HeaderLength;
2050 
2051  //
2052  // Update the return buffer size based on the sub-command.
2053  //
2054 
2055  if (cmdInParameters->irDriveRegs.bFeaturesReg == RETURN_SMART_STATUS) {
2056  length = sizeof(SENDCMDOUTPARAMS) - 1 + sizeof(IDEREGS);
2057  } else {
2058  length = sizeof(SENDCMDOUTPARAMS) - 1;
2059  }
2060 
2061  RtlMoveMemory ( Irp->AssociatedIrp.SystemBuffer, (PVOID)buffer, length);
2062  Irp->IoStatus.Information = length;
2063 
2064  ExFreePool(srbControl);
2065  break;
2066 
2067  }
2068 
2071  {
2072 
2073  PDEVICE_EXTENSION physicalDeviceExtension;
2074  PDISK_DATA physicalDiskData;
2075  BOOLEAN removable = FALSE;
2076  BOOLEAN listInitialized = FALSE;
2077  ULONG copyLength;
2078 
2079  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY) {
2080  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY)) {
2082  break;
2083  }
2084 
2085  copyLength = sizeof(DISK_GEOMETRY);
2086  } else {
2087  ASSERT(irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY_EX);
2088  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(DISK_GEOMETRY_EX, Data)) {
2090  break;
2091  }
2092 
2093  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(DISK_GEOMETRY_EX)) {
2094  copyLength = sizeof(DISK_GEOMETRY_EX);
2095  } else {
2096  copyLength = FIELD_OFFSET(DISK_GEOMETRY_EX, Data);
2097  }
2098  }
2099 
2101 
2102  physicalDeviceExtension = deviceExtension->PhysicalDevice->DeviceExtension;
2103  physicalDiskData = (PDISK_DATA)(physicalDeviceExtension + 1);
2104 
2105  removable = (BOOLEAN)DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA;
2106  listInitialized = (physicalDiskData->PartitionListState == Initialized);
2107 
2108  if (removable || (!listInitialized))
2109  {
2110  //
2111  // Issue ReadCapacity to update device extension
2112  // with information for current media.
2113  //
2114 
2115  status = ScsiClassReadDriveCapacity(deviceExtension->PhysicalDevice);
2116 
2117  }
2118 
2119  if (removable) {
2120 
2121  if (!NT_SUCCESS(status)) {
2122 
2123  //
2124  // Note the drive is not ready.
2125  //
2126 
2127  diskData->DriveNotReady = TRUE;
2128 
2129  break;
2130  }
2131 
2132  //
2133  // Note the drive is now ready.
2134  //
2135 
2136  diskData->DriveNotReady = FALSE;
2137 
2138  } else if (NT_SUCCESS(status)) {
2139 
2140  // ReadDriveCapacity was alright, create Partition Objects
2141 
2142  if (physicalDiskData->PartitionListState == NotInitialized) {
2143  status = CreatePartitionDeviceObjects(deviceExtension->PhysicalDevice, NULL);
2144  }
2145  }
2146 
2147  if (NT_SUCCESS(status)) {
2148 
2149  //
2150  // Copy drive geometry information from device extension.
2151  //
2152 
2153  RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
2154  deviceExtension->DiskGeometry,
2155  copyLength);
2156 
2158  Irp->IoStatus.Information = copyLength;
2159  }
2160 
2161  break;
2162 
2163  }
2164 
2165  case IOCTL_DISK_VERIFY:
2166 
2167  {
2168 
2169  PVERIFY_INFORMATION verifyInfo = Irp->AssociatedIrp.SystemBuffer;
2170  LARGE_INTEGER byteOffset;
2171  ULONG sectorOffset;
2173 
2174  //
2175  // Validate buffer length.
2176  //
2177 
2178  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2179  sizeof(VERIFY_INFORMATION)) {
2180 
2182  break;
2183  }
2184 
2185  //
2186  // Verify sectors
2187  //
2188 
2189  srb->CdbLength = 10;
2190 
2191  cdb->CDB10.OperationCode = SCSIOP_VERIFY;
2192 
2193  //
2194  // Add disk offset to starting sector.
2195  //
2196 
2197  byteOffset.QuadPart = deviceExtension->StartingOffset.QuadPart +
2198  verifyInfo->StartingOffset.QuadPart;
2199 
2200  //
2201  // Convert byte offset to sector offset.
2202  //
2203 
2204  sectorOffset = (ULONG)(byteOffset.QuadPart >> deviceExtension->SectorShift);
2205 
2206  //
2207  // Convert ULONG byte count to USHORT sector count.
2208  //
2209 
2210  sectorCount = (USHORT)(verifyInfo->Length >> deviceExtension->SectorShift);
2211 
2212  //
2213  // Move little endian values into CDB in big endian format.
2214  //
2215 
2216  cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&sectorOffset)->Byte3;
2217  cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&sectorOffset)->Byte2;
2218  cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&sectorOffset)->Byte1;
2219  cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&sectorOffset)->Byte0;
2220 
2221  cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&sectorCount)->Byte1;
2222  cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&sectorCount)->Byte0;
2223 
2224  //
2225  // The verify command is used by the NT FORMAT utility and
2226  // requests are sent down for 5% of the volume size. The
2227  // request timeout value is calculated based on the number of
2228  // sectors verified.
2229  //
2230 
2231  srb->TimeOutValue = ((sectorCount + 0x7F) >> 7) *
2232  deviceExtension->TimeOutValue;
2233 
2235  srb,
2236  Irp,
2237  NULL,
2238  0,
2239  FALSE);
2240 
2241  return(status);
2242 
2243  }
2244 
2246 
2247  //
2248  // Return the information about the partition specified by the device
2249  // object. Note that no information is ever returned about the size
2250  // or partition type of the physical disk, as this doesn't make any
2251  // sense.
2252  //
2253 
2254  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
2255  sizeof(PARTITION_INFORMATION)) {
2256 
2258  break;
2259  }
2260 
2261  //
2262  // Update the geometry in case it has changed.
2263  //
2264 
2266 
2267  if (!NT_SUCCESS(status)) {
2268 
2269  //
2270  // Note the drive is not ready.
2271  //
2272 
2273  diskData->DriveNotReady = TRUE;
2274  break;
2275  }
2276 
2277  //
2278  // Note the drive is now ready.
2279  //
2280 
2281  diskData->DriveNotReady = FALSE;
2282 
2283  //
2284  // Handle the case were we query the whole disk
2285  //
2286 
2287  if (diskData->PartitionNumber == 0) {
2288 
2289  PPARTITION_INFORMATION outputBuffer;
2290 
2291  outputBuffer =
2292  (PPARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2293 
2294  outputBuffer->PartitionType = PARTITION_ENTRY_UNUSED;
2295  outputBuffer->StartingOffset = deviceExtension->StartingOffset;
2296  outputBuffer->PartitionLength.QuadPart = deviceExtension->PartitionLength.QuadPart;
2297  outputBuffer->HiddenSectors = 0;
2298  outputBuffer->PartitionNumber = diskData->PartitionNumber;
2299  outputBuffer->BootIndicator = FALSE;
2300  outputBuffer->RewritePartition = FALSE;
2301  outputBuffer->RecognizedPartition = FALSE;
2302 
2304  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
2305 
2306  } else {
2307 
2308  PPARTITION_INFORMATION outputBuffer;
2309 
2310  //
2311  // We query a single partition here
2312  // FIXME: this can only work for MBR-based disks, check for this!
2313  //
2314 
2315  outputBuffer =
2316  (PPARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2317 
2318  outputBuffer->PartitionType = diskData->PartitionType;
2319  outputBuffer->StartingOffset = deviceExtension->StartingOffset;
2320  outputBuffer->PartitionLength.QuadPart = deviceExtension->PartitionLength.QuadPart;
2321  outputBuffer->HiddenSectors = diskData->HiddenSectors;
2322  outputBuffer->PartitionNumber = diskData->PartitionNumber;
2323  outputBuffer->BootIndicator = diskData->BootIndicator;
2324  outputBuffer->RewritePartition = FALSE;
2325  outputBuffer->RecognizedPartition =
2327 
2329  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION);
2330  }
2331 
2332  break;
2333 
2335 
2336  //
2337  // Return the information about the partition specified by the device
2338  // object. Note that no information is ever returned about the size
2339  // or partition type of the physical disk, as this doesn't make any
2340  // sense.
2341  //
2342 
2343  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
2344  sizeof(PARTITION_INFORMATION_EX)) {
2345 
2347 
2348  }
2349 #if 0 // HACK: ReactOS partition numbers must be wrong
2350  else if (diskData->PartitionNumber == 0) {
2351 
2352  //
2353  // Partition zero is not a partition so this is not a
2354  // reasonable request.
2355  //
2356 
2358 
2359  }
2360 #endif
2361  else {
2362 
2363  PPARTITION_INFORMATION_EX outputBuffer;
2364 
2365  if (diskData->PartitionNumber == 0) {
2366  DPRINT1("HACK: Handling partition 0 request!\n");
2367  //ASSERT(FALSE);
2368  }
2369 
2370  //
2371  // Update the geometry in case it has changed.
2372  //
2373 
2375 
2376  if (!NT_SUCCESS(status)) {
2377 
2378  //
2379  // Note the drive is not ready.
2380  //
2381 
2382  diskData->DriveNotReady = TRUE;
2383  break;
2384  }
2385 
2386  //
2387  // Note the drive is now ready.
2388  //
2389 
2390  diskData->DriveNotReady = FALSE;
2391 
2392  if (diskData->PartitionType == 0 && (diskData->PartitionNumber > 0)) {
2393 
2395  break;
2396  }
2397 
2398  outputBuffer =
2399  (PPARTITION_INFORMATION_EX)Irp->AssociatedIrp.SystemBuffer;
2400 
2401  //
2402  // FIXME: hack of the year, assume that partition is MBR
2403  // Thing that can obviously be wrong...
2404  //
2405 
2406  outputBuffer->PartitionStyle = PARTITION_STYLE_MBR;
2407  outputBuffer->Mbr.PartitionType = diskData->PartitionType;
2408  outputBuffer->StartingOffset = deviceExtension->StartingOffset;
2409  outputBuffer->PartitionLength.QuadPart = deviceExtension->PartitionLength.QuadPart;
2410  outputBuffer->Mbr.HiddenSectors = diskData->HiddenSectors;
2411  outputBuffer->PartitionNumber = diskData->PartitionNumber;
2412  outputBuffer->Mbr.BootIndicator = diskData->BootIndicator;
2413  outputBuffer->RewritePartition = FALSE;
2414  outputBuffer->Mbr.RecognizedPartition =
2416 
2418  Irp->IoStatus.Information = sizeof(PARTITION_INFORMATION_EX);
2419  }
2420 
2421  break;
2422 
2424 
2425  if (diskData->PartitionNumber == 0) {
2426 
2428 
2429  } else {
2430 
2431  PSET_PARTITION_INFORMATION inputBuffer =
2432  (PSET_PARTITION_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
2433 
2434  //
2435  // Validate buffer length.
2436  //
2437 
2438  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2439  sizeof(SET_PARTITION_INFORMATION)) {
2440 
2442  break;
2443  }
2444 
2445  //
2446  // The HAL routines IoGet- and IoSetPartitionInformation were
2447  // developed before support of dynamic partitioning and therefore
2448  // don't distinguish between partition ordinal (that is the order
2449  // of a partition on a disk) and the partition number. (The
2450  // partition number is assigned to a partition to identify it to
2451  // the system.) Use partition ordinals for these legacy calls.
2452  //
2453 
2455  deviceExtension->PhysicalDevice,
2456  deviceExtension->DiskGeometry->Geometry.BytesPerSector,
2457  diskData->PartitionOrdinal,
2458  inputBuffer->PartitionType);
2459 
2460  if (NT_SUCCESS(status)) {
2461 
2462  diskData->PartitionType = inputBuffer->PartitionType;
2463  }
2464  }
2465 
2466  break;
2467 
2469 
2470  //
2471  // Return the partition layout for the physical drive. Note that
2472  // the layout is returned for the actual physical drive, regardless
2473  // of which partition was specified for the request.
2474  //
2475 
2476  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
2477  sizeof(DRIVE_LAYOUT_INFORMATION)) {
2479 
2480  } else {
2481 
2482  PDRIVE_LAYOUT_INFORMATION partitionList;
2483  PDEVICE_EXTENSION physicalExtension = deviceExtension;
2484  PPARTITION_INFORMATION partitionEntry;
2485  PDISK_DATA diskData;
2486  ULONG tempSize;
2487  ULONG i;
2488 
2489  //
2490  // Read partition information.
2491  //
2492 
2493  status = IoReadPartitionTable(deviceExtension->PhysicalDevice,
2494  deviceExtension->DiskGeometry->Geometry.BytesPerSector,
2495  FALSE,
2496  &partitionList);
2497 
2498  if (!NT_SUCCESS(status)) {
2499  break;
2500  }
2501 
2502  //
2503  // The disk layout has been returned in the partitionList
2504  // buffer. Determine its size and, if the data will fit
2505  // into the intermediary buffer, return it.
2506  //
2507 
2508  tempSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION,PartitionEntry[0]);
2509  tempSize += partitionList->PartitionCount *
2510  sizeof(PARTITION_INFORMATION);
2511 
2512  if (tempSize >
2513  irpStack->Parameters.DeviceIoControl.OutputBufferLength) {
2514 
2516  ExFreePool(partitionList);
2517  break;
2518  }
2519 
2520  //
2521  // Walk partition list to associate partition numbers with
2522  // partition entries.
2523  //
2524 
2525  for (i = 0; i < partitionList->PartitionCount; i++) {
2526 
2527  //
2528  // Walk partition chain anchored at physical disk extension.
2529  //
2530 
2531  deviceExtension = physicalExtension;
2532  diskData = (PDISK_DATA)(deviceExtension + 1);
2533 
2534  do {
2535 
2536  deviceExtension = diskData->NextPartition;
2537 
2538  //
2539  // Check if this is the last partition in the chain.
2540  //
2541 
2542  if (!deviceExtension) {
2543  break;
2544  }
2545 
2546  //
2547  // Get the partition device extension from disk data.
2548  //
2549 
2550  diskData = (PDISK_DATA)(deviceExtension + 1);
2551 
2552  //
2553  // Check if this partition is not currently being used.
2554  //
2555 
2556  if (!deviceExtension->PartitionLength.QuadPart) {
2557  continue;
2558  }
2559 
2560  partitionEntry = &partitionList->PartitionEntry[i];
2561 
2562  //
2563  // Check if empty, or describes extended partition or hasn't changed.
2564  //
2565 
2566  if (partitionEntry->PartitionType == PARTITION_ENTRY_UNUSED ||
2567  IsContainerPartition(partitionEntry->PartitionType)) {
2568  continue;
2569  }
2570 
2571  //
2572  // Check if new partition starts where this partition starts.
2573  //
2574 
2575  if (partitionEntry->StartingOffset.QuadPart !=
2576  deviceExtension->StartingOffset.QuadPart) {
2577  continue;
2578  }
2579 
2580  //
2581  // Check if partition length is the same.
2582  //
2583 
2584  if (partitionEntry->PartitionLength.QuadPart ==
2585  deviceExtension->PartitionLength.QuadPart) {
2586 
2587  //
2588  // Partitions match. Update partition number.
2589  //
2590 
2591  partitionEntry->PartitionNumber =
2592  diskData->PartitionNumber;
2593  break;
2594  }
2595 
2596  } while (TRUE);
2597  }
2598 
2599  //
2600  // Copy partition information to system buffer.
2601  //
2602 
2603  RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
2604  partitionList,
2605  tempSize);
2607  Irp->IoStatus.Information = tempSize;
2608 
2609  //
2610  // Finally, free the buffer allocated by reading the
2611  // partition table.
2612  //
2613 
2614  ExFreePool(partitionList);
2615  }
2616 
2617  break;
2618 
2620 
2621  {
2622 
2623  //
2624  // Update the disk with new partition information.
2625  //
2626 
2627  PDRIVE_LAYOUT_INFORMATION partitionList = Irp->AssociatedIrp.SystemBuffer;
2628 
2629  //
2630  // Validate buffer length.
2631  //
2632 
2633  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2634  sizeof(DRIVE_LAYOUT_INFORMATION)) {
2635 
2637  break;
2638  }
2639 
2640  length = sizeof(DRIVE_LAYOUT_INFORMATION) +
2641  (partitionList->PartitionCount - 1) * sizeof(PARTITION_INFORMATION);
2642 
2643 
2644  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2645  length) {
2646 
2648  break;
2649  }
2650 
2651  //
2652  // Verify that device object is for physical disk.
2653  //
2654 
2655  if (deviceExtension->PhysicalDevice->DeviceExtension != deviceExtension) {
2657  break;
2658  }
2659 
2660  //
2661  // Walk through partition table comparing partitions to
2662  // existing partitions to create, delete and change
2663  // device objects as necessary.
2664  //
2665 
2667  Irp);
2668 
2669  //
2670  // Write changes to disk.
2671  //
2672 
2674  deviceExtension->DeviceObject,
2675  deviceExtension->DiskGeometry->Geometry.BytesPerSector,
2676  deviceExtension->DiskGeometry->Geometry.SectorsPerTrack,
2677  deviceExtension->DiskGeometry->Geometry.TracksPerCylinder,
2678  partitionList);
2679  }
2680 
2681  //
2682  // Update IRP with bytes returned.
2683  //
2684 
2685  if (NT_SUCCESS(status)) {
2686  Irp->IoStatus.Information = length;
2687  }
2688 
2689  break;
2690 
2692 
2693  //
2694  // Map defective blocks to new location on disk.
2695  //
2696 
2697  {
2698 
2699  PREASSIGN_BLOCKS badBlocks = Irp->AssociatedIrp.SystemBuffer;
2700  ULONG bufferSize;
2701  ULONG blockNumber;
2702  ULONG blockCount;
2703 
2704  //
2705  // Validate buffer length.
2706  //
2707 
2708  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2709  sizeof(REASSIGN_BLOCKS)) {
2710 
2712  break;
2713  }
2714 
2715  bufferSize = sizeof(REASSIGN_BLOCKS) +
2716  (badBlocks->Count - 1) * sizeof(ULONG);
2717 
2718  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
2719  bufferSize) {
2720 
2722  break;
2723  }
2724 
2725  //
2726  // Build the data buffer to be transferred in the input buffer.
2727  // The format of the data to the device is:
2728  //
2729  // 2 bytes Reserved
2730  // 2 bytes Length
2731  // x * 4 btyes Block Address
2732  //
2733  // All values are big endian.
2734  //
2735 
2736  badBlocks->Reserved = 0;
2737  blockCount = badBlocks->Count;
2738 
2739  //
2740  // Convert # of entries to # of bytes.
2741  //
2742 
2743  blockCount *= 4;
2744  badBlocks->Count = (USHORT) ((blockCount >> 8) & 0XFF);
2745  badBlocks->Count |= (USHORT) ((blockCount << 8) & 0XFF00);
2746 
2747  //
2748  // Convert back to number of entries.
2749  //
2750 
2751  blockCount /= 4;
2752 
2753  for (; blockCount > 0; blockCount--) {
2754 
2755  blockNumber = badBlocks->BlockNumber[blockCount-1];
2756 
2757  REVERSE_BYTES((PFOUR_BYTE) &badBlocks->BlockNumber[blockCount-1],
2758  (PFOUR_BYTE) &blockNumber);
2759  }
2760 
2761  srb->CdbLength = 6;
2762 
2763  cdb->CDB6GENERIC.OperationCode = SCSIOP_REASSIGN_BLOCKS;
2764 
2765  //
2766  // Set timeout value.
2767  //
2768 
2769  srb->TimeOutValue = deviceExtension->TimeOutValue;
2770 
2772  srb,
2773  badBlocks,
2774  bufferSize,
2775  TRUE);
2776 
2777  Irp->IoStatus.Status = status;
2778  Irp->IoStatus.Information = 0;
2779  ExFreePool(srb);
2781  }
2782 
2783  return(status);
2784 
2786 
2787  //
2788  // Determine if the device is writable.
2789  //
2790 
2792 
2793  if (modeData == NULL) {
2795  break;
2796  }
2797 
2798  RtlZeroMemory(modeData, MODE_DATA_SIZE);
2799 
2801  (PCHAR) modeData,
2804 
2805  if (length < sizeof(MODE_PARAMETER_HEADER)) {
2806 
2807  //
2808  // Retry the request in case of a check condition.
2809  //
2810 
2812  (PCHAR) modeData,
2815 
2816  if (length < sizeof(MODE_PARAMETER_HEADER)) {
2818  ExFreePool(modeData);
2819  break;
2820  }
2821  }
2822 
2825  } else {
2827  }
2828 
2829  ExFreePool(modeData);
2830  break;
2831 
2833 
2834  //
2835  // If the caller is kernel mode, set the verify bit.
2836  //
2837 
2838  if (Irp->RequestorMode == KernelMode) {
2840  }
2842  break;
2843 
2845 
2846  //
2847  // If the caller is kernel mode, clear the verify bit.
2848  //
2849 
2850  if (Irp->RequestorMode == KernelMode) {
2852  }
2854  break;
2855 
2857 
2858  //
2859  // Search for devices that have been powered on since the last
2860  // device search or system initialization.
2861  //
2862 
2863  DebugPrint((3,"CdRomDeviceControl: Find devices\n"));
2864  status = DriverEntry(DeviceObject->DriverObject,
2865  NULL);
2866 
2867  Irp->IoStatus.Status = status;
2868  ExFreePool(srb);
2870  return status;
2871 
2873 
2874  //
2875  // If the disk is not removable then don't allow this command.
2876  //
2877 
2878  if (!(DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)) {
2880  break;
2881  }
2882 
2883  //
2884  // Fall through and let the class driver process the request.
2885  //
2886 
2888 
2889  //
2890  // Validate buffer length.
2891  //
2892 
2893  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
2894  sizeof(GET_LENGTH_INFORMATION)) {
2896 
2897  } else {
2898 
2899  PGET_LENGTH_INFORMATION lengthInformation = Irp->AssociatedIrp.SystemBuffer;
2900 
2901  //
2902  // Update the geometry in case it has changed.
2903  //
2904 
2906 
2907  if (!NT_SUCCESS(status)) {
2908 
2909  //
2910  // Note the drive is not ready.
2911  //
2912 
2913  diskData->DriveNotReady = TRUE;
2914  break;
2915  }
2916 
2917  //
2918  // Note the drive is now ready.
2919  //
2920 
2921  diskData->DriveNotReady = FALSE;
2922 
2923  //
2924  // Output data, and return
2925  //
2926 
2927  lengthInformation->Length.QuadPart = deviceExtension->PartitionLength.QuadPart;
2929  Irp->IoStatus.Information = sizeof(GET_LENGTH_INFORMATION);
2930  }
2931 
2932  break;
2933 
2934  default:
2935 
2936  //
2937  // Free the Srb, since it is not needed.
2938  //
2939 
2940  ExFreePool(srb);
2941 
2942  //
2943  // Pass the request to the common device control routine.
2944  //
2945 
2947 
2948  break;
2949 
2950  } // end switch( ...
2951 
2952  Irp->IoStatus.Status = status;
2953 
2955 
2957  }
2958 
2960  ExFreePool(srb);
2961  return(status);
2962 
2963 } // 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:1073
#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:394
#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:626
#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:612
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:245
ULONG HiddenSectors
Definition: disk.c:64
ULONG ControlCode
Definition: scsi_port.h:128
#define DISABLE_SMART
Definition: ntdddisk.h:632
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:631
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:64
#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:567
#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:1029
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
VOID NTAPI UpdateDeviceObjects(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: disk.c:4847
smooth NULL
Definition: ftsmooth.c:416
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:467
#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:613
switch(r->id)
Definition: btrfs.c:2743
#define RETURN_SMART_STATUS
Definition: ntdddisk.h:633
#define READ_ATTRIBUTE_BUFFER_SIZE
Definition: ntdddisk.h:611
#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:628
#define IOCTL_DISK_GET_LENGTH_INFO
Definition: imports.h:192
#define ID_CMD
Definition: helper.h:20
#define READ_THRESHOLDS
Definition: ntdddisk.h:625
BOOLEAN DriveNotReady
Definition: disk.c:111
#define SAVE_ATTRIBUTE_VALUES
Definition: ntdddisk.h:627
ULONG NTAPI ScsiClassModeSense(IN PDEVICE_OBJECT DeviceObject, IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode)
Definition: class2.c:3513
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:393
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:271
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:624
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:400
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:310
#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:3684
#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:515
UINT sectorCount[1]
Definition: diskio.c:16
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#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:3917
#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:399
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:2771
ULONG BlockNumber[1]
Definition: ntdddisk.h:517
return STATUS_SUCCESS
Definition: btrfs.c:2777
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:4418
struct _SENDCMDINPARAMS * PSENDCMDINPARAMS
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:536
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 3285 of file disk.c.

3313 {
3314  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3315  PCDB cdb;
3316  SCSI_REQUEST_BLOCK srb;
3317  ULONG retries = 1;
3318  ULONG length2;
3319  NTSTATUS status;
3320  ULONG_PTR buffer;
3321  PMODE_PARAMETER_BLOCK blockDescriptor;
3322 
3323  PAGED_CODE();
3324 
3325  length2 = Length + sizeof(MODE_PARAMETER_HEADER) + sizeof(MODE_PARAMETER_BLOCK);
3326 
3327  //
3328  // Allocate buffer for mode select header, block descriptor, and mode page.
3329  //
3330 
3332 
3333  RtlZeroMemory((PVOID)buffer, length2);
3334 
3335  //
3336  // Set length in header to size of mode page.
3337  //
3338 
3339  ((PMODE_PARAMETER_HEADER)buffer)->BlockDescriptorLength = sizeof(MODE_PARAMETER_BLOCK);
3340 
3341  blockDescriptor = (PMODE_PARAMETER_BLOCK)(buffer + 1);
3342 
3343  //
3344  // Set size
3345  //
3346 
3347  blockDescriptor->BlockLength[1]=0x02;
3348 
3349  //
3350  // Copy mode page to buffer.
3351  //
3352 
3353  RtlCopyMemory((PVOID)(buffer + 3), ModeSelectBuffer, Length);
3354 
3355  //
3356  // Zero SRB.
3357  //
3358 
3359  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
3360 
3361  //
3362  // Build the MODE SELECT CDB.
3363  //
3364 
3365  srb.CdbLength = 6;
3366  cdb = (PCDB)srb.Cdb;
3367 
3368  //
3369  // Set timeout value from device extension.
3370  //
3371 
3372  srb.TimeOutValue = deviceExtension->TimeOutValue * 2;
3373 
3374  cdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
3375  cdb->MODE_SELECT.SPBit = SavePage;
3376  cdb->MODE_SELECT.PFBit = 1;
3377  cdb->MODE_SELECT.ParameterListLength = (UCHAR)(length2);
3378 
3379 Retry:
3380 
3382  &srb,
3383  (PVOID)buffer,
3384  length2,
3385  TRUE);
3386 
3387 
3388  if (status == STATUS_VERIFY_REQUIRED) {
3389 
3390  //
3391  // Routine ScsiClassSendSrbSynchronous does not retry requests returned with
3392  // this status.
3393  //
3394 
3395  if (retries--) {
3396 
3397  //
3398  // Retry request.
3399  //
3400 
3401  goto Retry;
3402  }
3403 
3404  } else if (SRB_STATUS(srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN) {
3406  }
3407 
3409 
3410  if (NT_SUCCESS(status)) {
3411  return(TRUE);
3412  } else {
3413  return(FALSE);
3414  }
3415 
3416 } // 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:2777
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 4575 of file disk.c.

4604 {
4605  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4606 
4607  if (*Status == STATUS_DATA_OVERRUN &&
4608  ( Srb->Cdb[0] == SCSIOP_WRITE || Srb->Cdb[0] == SCSIOP_READ)) {
4609 
4610  *Retry = TRUE;
4611 
4612  //
4613  // Update the error count for the device.
4614  //
4615 
4616  deviceExtension->ErrorCount++;
4617  }
4618 
4619  if (SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_ERROR &&
4620  Srb->ScsiStatus == SCSISTAT_BUSY) {
4621 
4622  //
4623  // The disk drive should never be busy this long. Reset the scsi bus
4624  // maybe this will clear the condition.
4625  //
4626 
4628 
4629  //
4630  // Update the error count for the device.
4631  //
4632 
4633  deviceExtension->ErrorCount++;
4634  }
4635 }
#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:4741
#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 1507 of file disk.c.

1529 {
1530  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1532  ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
1533  LARGE_INTEGER startingOffset;
1534 
1535  //
1536  // HACK: How can we end here with null sector size?!
1537  //
1538 
1539  if (deviceExtension->DiskGeometry->Geometry.BytesPerSector == 0) {
1540  DPRINT1("Hack! Received invalid sector size\n");
1541  deviceExtension->DiskGeometry->Geometry.BytesPerSector = 512;
1542  }
1543 
1544  //
1545  // Verify parameters of this request.
1546  // Check that ending sector is within partition and
1547  // that number of bytes to transfer is a multiple of
1548  // the sector size.
1549  //
1550 
1551  startingOffset.QuadPart = (currentIrpStack->Parameters.Read.ByteOffset.QuadPart +
1552  transferByteCount);
1553 
1554  if ((startingOffset.QuadPart > deviceExtension->PartitionLength.QuadPart) ||
1555  (transferByteCount & (deviceExtension->DiskGeometry->Geometry.BytesPerSector - 1))) {
1556 
1557  //
1558  // This error maybe caused by the fact that the drive is not ready.
1559  //
1560 
1561  if (((PDISK_DATA)(deviceExtension + 1))->DriveNotReady) {
1562 
1563  //
1564  // Flag this as a user error so that a popup is generated.
1565  //
1566 
1567  Irp->IoStatus.Status = STATUS_DEVICE_NOT_READY;
1569 
1570  } else {
1571 
1572  //
1573  // Note fastfat depends on this parameter to determine when to
1574  // remount do to a sector size change.
1575  //
1576 
1577  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1578  }
1579 
1580  if (startingOffset.QuadPart > deviceExtension->PartitionLength.QuadPart) {
1581  DPRINT1("Reading beyond partition end! startingOffset: %I64d, PartitionLength: %I64d\n", startingOffset.QuadPart, deviceExtension->PartitionLength.QuadPart);
1582  }
1583 
1584  if (transferByteCount & (deviceExtension->DiskGeometry->Geometry.BytesPerSector - 1)) {
1585  DPRINT1("Not reading sectors! TransferByteCount: %lu, BytesPerSector: %lu\n", transferByteCount, deviceExtension->DiskGeometry->Geometry.BytesPerSector);
1586  }
1587 
1588  if (Irp->IoStatus.Status == STATUS_DEVICE_NOT_READY) {
1589  DPRINT1("Failing due to device not ready!\n");
1590  }
1591 
1592  return STATUS_INVALID_PARAMETER;
1593  }
1594 
1595  return STATUS_SUCCESS;
1596 
1597 } // 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:2771
return STATUS_SUCCESS
Definition: btrfs.c:2777
LONGLONG QuadPart
Definition: typedefs.h:112
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:65

Referenced by DriverEntry().

◆ ScsiDiskShutdownFlush()

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

Definition at line 2967 of file disk.c.

2994 {
2995  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
2996  PIO_STACK_LOCATION irpStack;
2997  PSCSI_REQUEST_BLOCK srb;
2998  NTSTATUS status;
2999  PCDB cdb;
3000 
3001  //
3002  // Allocate SCSI request block.
3003  //
3004 
3006 
3007  if (srb == NULL) {
3008 
3009  //
3010  // Set the status and complete the request.
3011  //
3012 
3013  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
3016  }
3017 
3019 
3020  //
3021  // Write length to SRB.
3022  //
3023 
3025 
3026  //
3027  // Set SCSI bus address.
3028  //
3029 
3030  srb->PathId = deviceExtension->PathId;
3031  srb->TargetId = deviceExtension->TargetId;
3032  srb->Lun = deviceExtension->Lun;
3033 
3034  //
3035  // Set timeout value and mark the request as not being a tagged request.
3036  //
3037 
3038  srb->TimeOutValue = deviceExtension->TimeOutValue * 4;
3039  srb->QueueTag = SP_UNTAGGED;
3041  srb->SrbFlags = deviceExtension->SrbFlags;
3042 
3043  //
3044  // If the write cache is enabled then send a synchronize cache request.
3045  //
3046 
3047  if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
3048 
3050  srb->CdbLength = 10;
3051 
3052  srb->Cdb[0] = SCSIOP_SYNCHRONIZE_CACHE;
3053 
3055  srb,
3056  NULL,
3057  0,
3058  TRUE);
3059 
3060  DebugPrint((1, "ScsiDiskShutdownFlush: Synchronize cache sent. Status = %lx\n", status ));
3061  }
3062 
3063  //
3064  // Unlock the device if it is removable and this is a shutdown.
3065  //
3066 
3067  irpStack = IoGetCurrentIrpStackLocation(Irp);
3068 
3069  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA &&
3070  irpStack->MajorFunction == IRP_MJ_SHUTDOWN) {
3071 
3072  srb->CdbLength = 6;
3073  cdb = (PVOID) srb->Cdb;
3074  cdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL;
3075  cdb->MEDIA_REMOVAL.Prevent = FALSE;
3076 
3077  //
3078  // Set timeout value.
3079  //
3080 
3081  srb->TimeOutValue = deviceExtension->TimeOutValue;
3083  srb,
3084  NULL,
3085  0,
3086  TRUE);
3087 
3088  DebugPrint((1, "ScsiDiskShutdownFlush: Unlock device request sent. Status = %lx\n", status ));
3089  }
3090 
3091  srb->CdbLength = 0;
3092 
3093  //
3094  // Save a few parameters in the current stack location.
3095  //
3096 
3097  srb->Function = irpStack->MajorFunction == IRP_MJ_SHUTDOWN ?
3099 
3100  //
3101  // Set the retry count to zero.
3102  //
3103 
3104  irpStack->Parameters.Others.Argument4 = (PVOID) 0;
3105 
3106  //
3107  // Set up IoCompletion routine address.
3108  //
3109 
3111 
3112  //
3113  // Get next stack location and
3114  // set major function code.
3115  //
3116 
3117  irpStack = IoGetNextIrpStackLocation(Irp);
3118 
3119  irpStack->MajorFunction = IRP_MJ_SCSI;
3120 
3121  //
3122  // Set up SRB for execute scsi request.
3123  // Save SRB address in next stack for port driver.
3124  //
3125 
3126  irpStack->Parameters.Scsi.Srb = srb;
3127 
3128  //
3129  // Set up Irp Address.
3130  //
3131 
3132  srb->OriginalRequest = Irp;
3133 
3134  //
3135  // Call the port driver to process the request.
3136  //
3137 
3138  return(IoCallDriver(deviceExtension->PortDeviceObject, Irp));
3139 
3140 } // end ScsiDiskShutdown()
#define TRUE
Definition: types.h:120
#define SCSIOP_SYNCHRONIZE_CACHE
Definition: cdrw_hw.h:918
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG SrbFlags
Definition: srb.h:252
PVOID OriginalRequest
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:271
struct _CDB::_MEDIA_REMOVAL MEDIA_REMOVAL
#define IRP_MJ_SHUTDOWN
_In_ PIRP Irp
Definition: csq.h:116
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
UCHAR CdbLength
Definition: srb.h:250
UCHAR QueueAction
Definition: srb.h:249
ULONG TimeOutValue
Definition: srb.h:254
#define DEV_WRITE_CACHE
Definition: class2.h:21
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define SP_UNTAGGED
Definition: srb.h:225
#define IRP_MJ_SCSI
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
void * PVOID
Definition: retypes.h:9
UCHAR QueueTag
Definition: srb.h:248
UCHAR TargetId
Definition: srb.h:246
#define SRB_FUNCTION_FLUSH
Definition: srb.h:315
UCHAR Function
Definition: srb.h:242
USHORT Length
Definition: srb.h:241
NTSTATUS NTAPI ScsiClassIoComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:1806
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define SCSIOP_MEDIUM_REMOVAL
Definition: cdrw_hw.h:902
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
NTSTATUS ScsiClassSendSrbSynchronous(IN PDEVICE_OBJECT TargetDeviceObject, IN PSCSI_REQUEST_BLOCK _srb, IN PKEVENT event)
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SRB_FUNCTION_SHUTDOWN
Definition: srb.h:314
UCHAR PathId
Definition: srb.h:245
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by DriverEntry().

◆ UpdateDeviceObjects()

VOID NTAPI UpdateDeviceObjects ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 4847 of file disk.c.

4872 {
4873  PDEVICE_EXTENSION physicalExtension = PhysicalDisk->DeviceExtension;
4874  PDRIVE_LAYOUT_INFORMATION partitionList = Irp->AssociatedIrp.SystemBuffer;
4875  ULONG partition;
4876  ULONG partitionNumber;
4877  ULONG partitionCount;
4878  ULONG lastPartition;
4879  ULONG partitionOrdinal;
4880  PPARTITION_INFORMATION partitionEntry;
4881  CCHAR ntNameBuffer[MAXIMUM_FILENAME_LENGTH];
4882  STRING ntNameString;
4883  UNICODE_STRING ntUnicodeString;
4884  PDEVICE_OBJECT deviceObject;
4885  PDEVICE_EXTENSION deviceExtension;
4886  PDISK_DATA diskData;
4887  NTSTATUS status;
4888  ULONG numberListElements;
4889  BOOLEAN found;
4890 
4891  partitionCount = ((partitionList->PartitionCount + 3) / 4) * 4;
4892 
4893  //
4894  // Zero all of the partition numbers.
4895  //
4896 
4897  for (partition = 0; partition < partitionCount; partition++) {
4898  partitionEntry = &partitionList->PartitionEntry[partition];
4899  partitionEntry->PartitionNumber = 0;
4900  }
4901 
4902  //
4903  // Walk through chain of partitions for this disk to determine
4904  // which existing partitions have no match.
4905  //
4906 
4907  deviceExtension = physicalExtension;
4908  diskData = (PDISK_DATA)(deviceExtension + 1);
4909  lastPartition = 0;
4910 
4911  do {
4912 
4913  deviceExtension = diskData->NextPartition;
4914 
4915  //
4916  // Check if this is the last partition in the chain.
4917  //
4918 
4919  if (!deviceExtension) {
4920  break;
4921  }
4922 
4923  //