ReactOS  0.4.15-dev-1201-gb2cf5a4
pnp.c File Reference
#include "disk.h"
Include dependency graph for pnp.c:

Go to the source code of this file.

Macros

#define FDO_NAME_FORMAT   "\\Device\\Harddisk%d\\DR%d"
 

Functions

NTSTATUS NTAPI DiskAddDevice (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
 
NTSTATUS NTAPI DiskInitFdo (IN PDEVICE_OBJECT Fdo)
 
NTSTATUS NTAPI DiskStopDevice (IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type)
 
NTSTATUS DiskGenerateDeviceName (IN ULONG DeviceNumber, OUT PCCHAR *RawName)
 
VOID DiskCreateSymbolicLinks (IN PDEVICE_OBJECT DeviceObject)
 
VOID DiskDeleteSymbolicLinks (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI DiskRemoveDevice (IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type)
 
NTSTATUS NTAPI DiskStartFdo (IN PDEVICE_OBJECT Fdo)
 

Variables

PULONG InitSafeBootMode
 
ULONG diskDeviceSequenceNumber = 0
 
BOOLEAN DiskIsPastReinit
 

Macro Definition Documentation

◆ FDO_NAME_FORMAT

#define FDO_NAME_FORMAT   "\\Device\\Harddisk%d\\DR%d"

Function Documentation

◆ DiskAddDevice()

NTSTATUS NTAPI DiskAddDevice ( IN PDRIVER_OBJECT  DriverObject,
IN PDEVICE_OBJECT  PhysicalDeviceObject 
)

Definition at line 53 of file pnp.c.

78 {
79  ULONG rootPartitionMountable = FALSE;
80 
81  PCONFIGURATION_INFORMATION configurationInformation;
82  ULONG diskCount;
83 
85 
86  PAGED_CODE();
87 
88  //
89  // See if we should be allowing file systems to mount on partition zero.
90  //
91 
92  TRY {
93  HANDLE deviceKey = NULL;
94 
95  UNICODE_STRING diskKeyName;
96  OBJECT_ATTRIBUTES objectAttributes = {0};
97  HANDLE diskKey;
98 
99  RTL_QUERY_REGISTRY_TABLE queryTable[2] = { 0 };
100 
103  KEY_READ,
104  &deviceKey);
105 
106  if(!NT_SUCCESS(status)) {
107  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskAddDevice: Error %#08lx opening device key "
108  "for pdo %p\n",
110  LEAVE;
111  }
112 
113  RtlInitUnicodeString(&diskKeyName, L"Disk");
114  InitializeObjectAttributes(&objectAttributes,
115  &diskKeyName,
117  deviceKey,
118  NULL);
119 
120  status = ZwOpenKey(&diskKey, KEY_READ, &objectAttributes);
121  ZwClose(deviceKey);
122 
123  if(!NT_SUCCESS(status)) {
124  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskAddDevice: Error %#08lx opening disk key "
125  "for pdo %p device key %p\n",
126  status, PhysicalDeviceObject, deviceKey));
127  LEAVE;
128  }
129 
131  queryTable[0].Name = L"RootPartitionMountable";
132  queryTable[0].EntryContext = &(rootPartitionMountable);
134 
135 #pragma prefast(suppress:6309, "We don't have QueryRoutine so Context doesn't make any sense")
137  diskKey,
138  queryTable,
139  NULL,
140  NULL);
141 
142  if(!NT_SUCCESS(status)) {
143  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskAddDevice: Error %#08lx reading value from "
144  "disk key %p for pdo %p\n",
145  status, diskKey, PhysicalDeviceObject));
146  }
147 
148  ZwClose(diskKey);
149 
150  } FINALLY {
151 
152  //
153  // Do nothing.
154  //
155 
156  if(!NT_SUCCESS(status)) {
157  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_PNP, "DiskAddDevice: Will %sallow file system to mount on "
158  "partition zero of disk %p\n",
159  (rootPartitionMountable ? "" : "not "),
161  }
162  }
163 
164  //
165  // Create device objects for disk
166  //
167 
168  diskCount = 0;
169 
171  DriverObject,
173  &diskCount,
174  (BOOLEAN) !rootPartitionMountable
175  );
176 
177  //
178  // Get the number of disks already initialized.
179  //
180 
181  configurationInformation = IoGetConfigurationInformation();
182 
183  if (NT_SUCCESS(status)) {
184 
185  //
186  // Increment system disk device count.
187  //
188 
189  configurationInformation->DiskCount++;
190 
191  }
192 
193  return status;
194 
195 } // end DiskAddDevice()
#define FINALLY
Definition: classpnp.h:116
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2782
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
#define LEAVE
Definition: classpnp.h:115
#define TRY(sps, bps)
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1155
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
#define RTL_QUERY_REGISTRY_TYPECHECK
NTSTATUS DiskCreateFdo(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PULONG DeviceCount, IN BOOLEAN DasdAccessOnly)
Definition: disk.c:307
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define RTL_QUERY_REGISTRY_TYPECHECK_SHIFT
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:2335
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
#define REG_NONE
Definition: nt_native.h:1492
#define REG_DWORD
Definition: sdbapi.c:596
static SERVICE_STATUS status
Definition: service.c:31
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DriverEntry().

◆ DiskCreateSymbolicLinks()

VOID DiskCreateSymbolicLinks ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 674 of file pnp.c.

700 {
701  PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
702  PDISK_DATA diskData = commonExtension->DriverData;
703 
704  WCHAR wideSourceName[64] = { 0 };
705  UNICODE_STRING unicodeSourceName;
706 
708 
709  PAGED_CODE();
710 
711  //
712  // Build the destination for the link first using the device name
713  // stored in the device object
714  //
715 
716  NT_ASSERT(commonExtension->DeviceName.Buffer);
717 
718  if(!diskData->LinkStatus.WellKnownNameCreated) {
719  //
720  // Put together the source name using the partition and device number
721  // in the device extension and disk data segment
722  //
723 
724  status = RtlStringCchPrintfW(wideSourceName, sizeof(wideSourceName) / sizeof(wideSourceName[0]) - 1,
725  L"\\Device\\Harddisk%d\\Partition0",
726  commonExtension->PartitionZeroExtension->DeviceNumber);
727 
728  if (NT_SUCCESS(status)) {
729 
730  RtlInitUnicodeString(&unicodeSourceName, wideSourceName);
731 
732  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskCreateSymbolicLink: Linking %wZ to %wZ\n",
733  &unicodeSourceName,
734  &commonExtension->DeviceName));
735 
736  status = IoCreateSymbolicLink(&unicodeSourceName,
737  &commonExtension->DeviceName);
738 
739  if(NT_SUCCESS(status)){
740  diskData->LinkStatus.WellKnownNameCreated = TRUE;
741  }
742  }
743  }
744 
745  if (!diskData->LinkStatus.PhysicalDriveLinkCreated) {
746 
747  //
748  // Create a physical drive N link using the device number we saved
749  // away during AddDevice.
750  //
751 
752  status = RtlStringCchPrintfW(wideSourceName, sizeof(wideSourceName) / sizeof(wideSourceName[0]) - 1,
753  L"\\DosDevices\\PhysicalDrive%d",
754  commonExtension->PartitionZeroExtension->DeviceNumber);
755  if (NT_SUCCESS(status)) {
756 
757  RtlInitUnicodeString(&unicodeSourceName, wideSourceName);
758 
759  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskCreateSymbolicLink: Linking %wZ to %wZ\n",
760  &unicodeSourceName,
761  &(commonExtension->DeviceName)));
762 
763  status = IoCreateSymbolicLink(&unicodeSourceName,
764  &(commonExtension->DeviceName));
765 
766  if(NT_SUCCESS(status)) {
767  diskData->LinkStatus.PhysicalDriveLinkCreated = TRUE;
768  }
769  }
770  }
771 
772 
773  return;
774 }
#define TRUE
Definition: types.h:120
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
LONG NTSTATUS
Definition: precomp.h:26
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
UNICODE_STRING DeviceName
Definition: classpnp.h:615
struct _DISK_DATA::@1038 LinkStatus
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

Referenced by DiskInitFdo().

◆ DiskDeleteSymbolicLinks()

VOID DiskDeleteSymbolicLinks ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 778 of file pnp.c.

800 {
801  PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
802  PDISK_DATA diskData = commonExtension->DriverData;
803 
804  WCHAR wideLinkName[64] = { 0 };
805  UNICODE_STRING unicodeLinkName;
807 
808  PAGED_CODE();
809 
810  if(diskData->LinkStatus.WellKnownNameCreated) {
811 
812  status = RtlStringCchPrintfW(wideLinkName, sizeof(wideLinkName) / sizeof(wideLinkName[0]) - 1,
813  L"\\Device\\Harddisk%d\\Partition0",
814  commonExtension->PartitionZeroExtension->DeviceNumber);
815  if (NT_SUCCESS(status)) {
816  RtlInitUnicodeString(&unicodeLinkName, wideLinkName);
817  IoDeleteSymbolicLink(&unicodeLinkName);
818  }
819  diskData->LinkStatus.WellKnownNameCreated = FALSE;
820  }
821 
822  if(diskData->LinkStatus.PhysicalDriveLinkCreated) {
823 
824  status = RtlStringCchPrintfW(wideLinkName, sizeof(wideLinkName) / sizeof(wideLinkName[0]) - 1,
825  L"\\DosDevices\\PhysicalDrive%d",
826  commonExtension->PartitionZeroExtension->DeviceNumber);
827  if (NT_SUCCESS(status)) {
828  RtlInitUnicodeString(&unicodeLinkName, wideLinkName);
829  IoDeleteSymbolicLink(&unicodeLinkName);
830  }
831  diskData->LinkStatus.PhysicalDriveLinkCreated = FALSE;
832  }
833 
834 
835  return;
836 }
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
struct _DISK_DATA::@1038 LinkStatus
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DiskRemoveDevice().

◆ DiskGenerateDeviceName()

NTSTATUS DiskGenerateDeviceName ( IN ULONG  DeviceNumber,
OUT PCCHAR *  RawName 
)

Definition at line 610 of file pnp.c.

639 {
640  CHAR rawName[64] = { 0 };
642 
643  PAGED_CODE();
644 
645  status = RtlStringCchPrintfA(rawName, sizeof(rawName) - 1, FDO_NAME_FORMAT, DeviceNumber,
647  if (!NT_SUCCESS(status)) {
648  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskGenerateDeviceName: Format FDO name failed with error: 0x%X\n", status));
649  return status;
650  }
651 
652  *RawName = ExAllocatePoolWithTag(PagedPool,
653  strlen(rawName) + 1,
654  DISK_TAG_NAME);
655 
656  if(*RawName == NULL) {
658  }
659 
660  status = RtlStringCchCopyA(*RawName, strlen(rawName) + 1, rawName);
661  if (!NT_SUCCESS(status)) {
662  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskGenerateDeviceName: Device name copy failed with error: 0x%X\n", status));
663  FREE_POOL(*RawName);
664  return status;
665  }
666 
667  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskGenerateDeviceName: generated \"%s\"\n", rawName));
668 
669  return STATUS_SUCCESS;
670 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
NTSTRSAFEVAPI RtlStringCchPrintfA(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1085
smooth NULL
Definition: ftsmooth.c:416
#define FDO_NAME_FORMAT
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define DISK_TAG_NAME
Definition: disk.h:64
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
NTSTRSAFEAPI RtlStringCchCopyA(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:110
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1229
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
ULONG diskDeviceSequenceNumber
Definition: pnp.c:35
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DiskCreateFdo().

◆ DiskInitFdo()

NTSTATUS NTAPI DiskInitFdo ( IN PDEVICE_OBJECT  Fdo)

Definition at line 200 of file pnp.c.

221 {
222  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
223  PDISK_DATA diskData = (PDISK_DATA) fdoExtension->CommonExtension.DriverData;
224 
225  ULONG srbFlags = 0;
226  ULONG timeOut = 0;
227  ULONG bytesPerSector;
228 
229  PULONG dmSkew;
230 
232 
233  PAGED_CODE();
234 
235  //
236  // Build the lookaside list for srb's for the physical disk. Should only
237  // need a couple. If this fails then we don't have an emergency SRB so
238  // fail the call to initialize.
239  //
240 
241  ClassInitializeSrbLookasideList((PCOMMON_DEVICE_EXTENSION) fdoExtension,
243 
244  if (fdoExtension->DeviceDescriptor->RemovableMedia)
245  {
246  SET_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA);
247  }
248 
249  //
250  // Initialize the srb flags.
251  //
252 
253  //
254  // Because all requests share a common sense buffer, it is possible
255  // for the buffer to be overwritten if the port driver completes
256  // multiple failed requests that require a request sense before the
257  // class driver's completion routine can consume the data in the buffer.
258  // To prevent this, we allow the port driver to allocate a unique sense
259  // buffer each time it needs one. We are responsible for freeing this
260  // buffer. This also allows the adapter to be configured to support
261  // additional sense data beyond the minimum 18 bytes.
262  //
263 
265 
266  if (fdoExtension->DeviceDescriptor->CommandQueueing &&
267  fdoExtension->AdapterDescriptor->CommandQueueing) {
268 
270 
271  }
272 
273  //
274  // Look for controllers that require special flags.
275  //
276 
277  ClassScanForSpecial(fdoExtension, DiskBadControllers, DiskSetSpecialHacks);
278 
279  //
280  // Clear buffer for drive geometry.
281  //
282 
283  RtlZeroMemory(&(fdoExtension->DiskGeometry),
284  sizeof(DISK_GEOMETRY));
285 
286  //
287  // Allocate request sense buffer.
288  //
289 
290  fdoExtension->SenseData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
293 
294  if (fdoExtension->SenseData == NULL) {
295 
296  //
297  // The buffer can not be allocated.
298  //
299 
300  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskInitFdo: Can not allocate request sense buffer\n"));
301 
303  return status;
304  }
305 
306  //
307  // Set the buffer size of SenseData
308  //
309 
310  fdoExtension->SenseDataLength = SENSE_BUFFER_SIZE_EX;
311 
312  //
313  // Physical device object will describe the entire
314  // device, starting at byte offset 0.
315  //
316 
317  fdoExtension->CommonExtension.StartingOffset.QuadPart = (LONGLONG)(0);
318 
319  //
320  // Set timeout value in seconds.
321  //
322  if ( (fdoExtension->MiniportDescriptor != NULL) &&
323  (fdoExtension->MiniportDescriptor->IoTimeoutValue > 0) ) {
324  //
325  // use the value set by Storport miniport driver
326  //
327  fdoExtension->TimeOutValue = fdoExtension->MiniportDescriptor->IoTimeoutValue;
328  } else {
329  //
330  // get timeout value from registry
331  //
332  timeOut = ClassQueryTimeOutRegistryValue(Fdo);
333 
334  if (timeOut) {
335  fdoExtension->TimeOutValue = timeOut;
336  } else {
337  fdoExtension->TimeOutValue = SCSI_DISK_TIMEOUT;
338  }
339  }
340  //
341  // If this is a removable drive, build an entry in devicemap\scsi
342  // indicating it's physicaldriveN name, set up the appropriate
343  // update partitions routine and set the flags correctly.
344  // note: only do this after the timeout value is set, above.
345  //
346 
347  if (TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
348 
349  ClassUpdateInformationInRegistry( Fdo,
350  "PhysicalDrive",
351  fdoExtension->DeviceNumber,
352  NULL,
353  0);
354  //
355  // Enable media change notification for removable disks
356  //
357  ClassInitializeMediaChangeDetection(fdoExtension,
358  (PUCHAR)"Disk");
359 
360  } else {
361 
362  SET_FLAG(fdoExtension->DeviceFlags, DEV_SAFE_START_UNIT);
364 
365  }
366 
367  //
368  // The commands we send during the init could cause the flags to change
369  // in case of any error. Save the SRB flags locally and restore it at
370  // the end of this function, so that the class driver can get it.
371  //
372 
373  srbFlags = fdoExtension->SrbFlags;
374 
375 
376  //
377  // Read the drive capacity. Don't use the disk version of the routine here
378  // since we don't know the disk signature yet - the disk version will
379  // attempt to determine the BIOS reported geometry.
380  //
381 
383 
384  //
385  // Set up sector size fields.
386  //
387  // Stack variables will be used to update
388  // the partition device extensions.
389  //
390  // The device extension field SectorShift is
391  // used to calculate sectors in I/O transfers.
392  //
393  // The DiskGeometry structure is used to service
394  // IOCTls used by the format utility.
395  //
396 
397  bytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
398 
399  //
400  // Make sure sector size is not zero.
401  //
402 
403  if (bytesPerSector == 0) {
404 
405  //
406  // Default sector size for disk is 512.
407  //
408 
409  bytesPerSector = fdoExtension->DiskGeometry.BytesPerSector = 512;
410  fdoExtension->SectorShift = 9;
411  }
412 
413  //
414  // Determine is DM Driver is loaded on an IDE drive that is
415  // under control of Atapi - this could be either a crashdump or
416  // an Atapi device is sharing the controller with an IDE disk.
417  //
418 
420  fdoExtension->DiskGeometry.BytesPerSector,
421  (ULONG)0x54,
422  (PVOID *)&dmSkew);
423 
424  if (dmSkew) {
425 
426  //
427  // Update the device extension, so that the call to IoReadPartitionTable
428  // will get the correct information. Any I/O to this disk will have
429  // to be skewed by *dmSkew sectors aka DMByteSkew.
430  //
431 
432  fdoExtension->DMSkew = *dmSkew;
433  fdoExtension->DMActive = TRUE;
434  fdoExtension->DMByteSkew = fdoExtension->DMSkew * bytesPerSector;
435 
436  FREE_POOL(dmSkew);
437  }
438 
439 #if defined(_X86_) || defined(_AMD64_)
440 
441  //
442  // Try to read the signature off the disk and determine the correct drive
443  // geometry based on that. This requires rereading the disk size to get
444  // the cylinder count updated correctly.
445  //
446 
447  if(!TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
448 
449  DiskReadSignature(Fdo);
451 
452  if (diskData->GeometrySource == DiskGeometryUnknown)
453  {
454  //
455  // Neither the BIOS nor the port driver could provide us with a reliable
456  // geometry. Before we use the default, look to see if it was partitioned
457  // under Windows NT4 [or earlier] and apply the one that was used back then
458  //
459 
460  if (DiskIsNT4Geometry(fdoExtension))
461  {
462  diskData->RealGeometry = fdoExtension->DiskGeometry;
463  diskData->RealGeometry.SectorsPerTrack = 0x20;
464  diskData->RealGeometry.TracksPerCylinder = 0x40;
465  fdoExtension->DiskGeometry = diskData->RealGeometry;
466 
467  diskData->GeometrySource = DiskGeometryFromNT4;
468  }
469  }
470  }
471 
472 #endif
473 
475 
476  //
477  // Get the SCSI address if it's available for use with SMART ioctls.
478  // SMART ioctls are used for failure prediction, so we need to get
479  // the SCSI address before initializing failure prediction.
480  //
481 
482  {
483  PIRP irp;
484  KEVENT event;
485  IO_STATUS_BLOCK statusBlock = { 0 };
486 
488 
490  fdoExtension->CommonExtension.LowerDeviceObject,
491  NULL,
492  0L,
493  &(diskData->ScsiAddress),
494  sizeof(SCSI_ADDRESS),
495  FALSE,
496  &event,
497  &statusBlock);
498 
500 
501  if(irp != NULL) {
502 
503  status = IoCallDriver(fdoExtension->CommonExtension.LowerDeviceObject, irp);
504 
505  if(status == STATUS_PENDING) {
507  Executive,
508  KernelMode,
509  FALSE,
510  NULL);
511  status = statusBlock.Status;
512  }
513  }
514  }
515 
516  //
517  // Determine the type of disk and enable failure prediction in the hardware
518  // and enable failure prediction polling.
519  //
520 
521  if (InitSafeBootMode == 0) // __REACTOS__
522  {
523  DiskDetectFailurePrediction(fdoExtension,
524  &diskData->FailurePredictionCapability,
525  NT_SUCCESS(status));
526 
528  {
529  //
530  // Cool, we've got some sort of failure prediction, enable it
531  // at the hardware and then enable polling for it
532  //
533 
534  //
535  // By default we allow performance to be degradeded if failure
536  // prediction is enabled.
537  //
538 
539  diskData->AllowFPPerfHit = TRUE;
540 
541  //
542  // Enable polling only after Atapi and SBP2 add support for the new
543  // SRB flag that indicates that the request should not reset the
544  // drive spin down idle timer.
545  //
546 
548  TRUE,
550 
551  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskInitFdo: Failure Prediction Poll enabled as "
552  "%d for device %p, Status = %lx\n",
553  diskData->FailurePredictionCapability,
554  Fdo,
555  status));
556  }
557  } else {
558 
559  //
560  // In safe boot mode we do not enable failure prediction, as perhaps
561  // it is the reason why normal boot does not work
562  //
563 
565 
566  }
567 
568  //
569  // Initialize the verify mutex
570  //
571 
573 
574  //
575  // Initialize the flush group context
576  //
577 
578  RtlZeroMemory(&diskData->FlushContext, sizeof(DISK_GROUP_CONTEXT));
579 
582 
585 
586 
587  //
588  // Restore the saved value
589  //
590  fdoExtension->SrbFlags = srbFlags;
591 
592  return STATUS_SUCCESS;
593 
594 } // end DiskInitFdo()
struct _DISK_DATA * PDISK_DATA
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:888
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
#define TRUE
Definition: types.h:120
VOID NTAPI DiskSetSpecialHacks(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN ULONG_PTR Data)
Definition: disk.c:2598
CLASSPNP_SCAN_FOR_SPECIAL_INFO DiskBadControllers[]
Definition: data.c:38
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
#define DISK_DEFAULT_FAILURE_POLLING_PERIOD
Definition: disk.h:456
SCSI_ADDRESS ScsiAddress
Definition: disk.h:325
LIST_ENTRY CurrList
Definition: disk.h:108
KSPIN_LOCK Spinlock
Definition: disk.h:143
ULONG BytesPerSector
Definition: ntdddisk.h:442
#define DISK_TAG_START
Definition: disk.h:68
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
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
BOOLEAN AllowFPPerfHit
Definition: disk.h:332
_Must_inspect_result_ NTSTATUS NTAPI ClassReadDriveCapacity(_In_ PDEVICE_OBJECT Fdo)
Definition: class.c:2742
PDEVICE_OBJECT DeviceObject
Definition: kstypes.h:153
#define FALSE
Definition: types.h:117
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
VOID DiskCreateSymbolicLinks(IN PDEVICE_OBJECT DeviceObject)
Definition: pnp.c:674
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
#define MAX_SECTORS_PER_VERIFY
Definition: disk.h:435
smooth NULL
Definition: ftsmooth.c:416
KEVENT Event
Definition: disk.h:148
#define SCSI_DISK_TIMEOUT
Definition: disk.c:166
#define DEV_SAFE_START_UNIT
Definition: cdrom.h:139
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
NTSTATUS DiskEnableDisableFailurePredictPolling(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable, ULONG PollTimeInSeconds)
Definition: diskwmi.c:1193
int64_t LONGLONG
Definition: typedefs.h:68
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define DiskReadDriveCapacity(Fdo)
Definition: disk.h:814
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: classpnp.h:876
#define SENSE_BUFFER_SIZE_EX
Definition: scsi.h:596
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level)
Definition: mutex.c:67
#define PARTITION0_LIST_SIZE
Definition: disk.c:167
static const WCHAR L[]
Definition: oid.c:1250
#define VOID
Definition: acefi.h:82
FAILURE_PREDICTION_METHOD FailurePredictionCapability
Definition: disk.h:331
struct _cl_event * event
Definition: glext.h:7739
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
PULONG InitSafeBootMode
Definition: init.c:69
#define SRB_FLAGS_PORT_DRIVER_ALLOCSENSE
Definition: srb.h:405
LIST_ENTRY NextList
Definition: disk.h:118
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
DISK_GROUP_CONTEXT FlushContext
Definition: disk.h:379
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
VOID FASTCALL HalExamineMBR(IN PDEVICE_OBJECT DeviceObject, IN ULONG SectorSize, IN ULONG MbrTypeIdentifier, OUT PVOID *MbrBuffer)
Definition: disksup.c:2688
KMUTEX VerifyMutex
Definition: disk.h:372
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS DiskDetectFailurePrediction(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PFAILURE_PREDICTION_METHOD FailurePredictCapability, BOOLEAN ScsiAddressAvailable)
Definition: diskwmi.c:2230
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:387
#define PAGED_CODE()
Definition: ps.c:97

Referenced by DriverEntry().

◆ DiskRemoveDevice()

NTSTATUS NTAPI DiskRemoveDevice ( IN PDEVICE_OBJECT  DeviceObject,
IN UCHAR  Type 
)

Definition at line 841 of file pnp.c.

863 {
864  PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
865  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
866 
867  PAGED_CODE();
868 
869  //
870  // Handle query and cancel
871  //
872 
875  return STATUS_SUCCESS;
876  }
877 
878  //
879  // Delete our object directory.
880  //
881 
882  if(fdoExtension->DeviceDirectory != NULL) {
883  ZwMakeTemporaryObject(fdoExtension->DeviceDirectory);
884  ZwClose(fdoExtension->DeviceDirectory);
885  fdoExtension->DeviceDirectory = NULL;
886  }
887 
888  if(Type == IRP_MN_REMOVE_DEVICE) {
889 
890  FREE_POOL(fdoExtension->SenseData);
891 
893 
894  }
895 
897 
898  if (Type == IRP_MN_REMOVE_DEVICE)
899  {
900  ClassDeleteSrbLookasideList(commonExtension);
901  }
902 
903  return STATUS_SUCCESS;
904 }
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_REMOVE_DEVICE
Type
Definition: Type.h:6
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define IRP_MN_QUERY_REMOVE_DEVICE
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
VOID DiskDeleteSymbolicLinks(IN PDEVICE_OBJECT DeviceObject)
Definition: pnp.c:778
smooth NULL
Definition: ftsmooth.c:416
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
return STATUS_SUCCESS
Definition: btrfs.c:3014
NTSYSAPI NTSTATUS NTAPI ZwMakeTemporaryObject(_In_ HANDLE Handle)
#define PAGED_CODE()

Referenced by DriverEntry().

◆ DiskStartFdo()

NTSTATUS NTAPI DiskStartFdo ( IN PDEVICE_OBJECT  Fdo)

Definition at line 909 of file pnp.c.

937 {
938  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
939  PCOMMON_DEVICE_EXTENSION commonExtension = &(fdoExtension->CommonExtension);
940  PDISK_DATA diskData = commonExtension->DriverData;
941  STORAGE_HOTPLUG_INFO hotplugInfo = { 0 };
942  DISK_CACHE_INFORMATION cacheInfo = { 0 };
943  ULONG isPowerProtected = 0;
945 
946  PAGED_CODE();
947 
948  //
949  // Get the hotplug information, so we can turn off write cache if needed
950  //
951  // NOTE: Capabilities info is not good enough to determine hotplugedness
952  // as we cannot determine device relations information and other
953  // dependencies. Get the hotplug info instead
954  //
955 
956  {
957  PIRP irp;
958  KEVENT event;
959  IO_STATUS_BLOCK statusBlock = { 0 };
960 
962 
964  Fdo,
965  NULL,
966  0L,
967  &hotplugInfo,
968  sizeof(STORAGE_HOTPLUG_INFO),
969  FALSE,
970  &event,
971  &statusBlock);
972 
973  if (irp != NULL) {
974 
975  // send to self -- classpnp handles this
976  status = IoCallDriver(Fdo, irp);
977  if (status == STATUS_PENDING) {
979  Executive,
980  KernelMode,
981  FALSE,
982  NULL);
983 
984  status = statusBlock.Status;
985  }
987  }
988  }
989 
990  //
991  // Clear the DEV_WRITE_CACHE flag now and set
992  // it below only if we read that from the disk
993  //
994  CLEAR_FLAG(fdoExtension->DeviceFlags, DEV_WRITE_CACHE);
995  ADJUST_FUA_FLAG(fdoExtension);
996 
998 
999  //
1000  // Look into the registry to see if the user
1001  // has chosen to override the default setting
1002  //
1003  ClassGetDeviceParameter(fdoExtension,
1006  (PULONG)&diskData->WriteCacheOverride);
1007 
1008  if (diskData->WriteCacheOverride == DiskWriteCacheDefault)
1009  {
1010  //
1011  // The user has not overridden the default settings
1012  //
1014  {
1015  //
1016  // This flag indicates that we have faulty firmware and this
1017  // may cause the filesystem to refuse to mount on this media
1018  //
1019  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_PNP, "DiskStartFdo: Turning off write cache for %p due to a firmware issue\n", Fdo));
1020 
1022  }
1023  else if (hotplugInfo.DeviceHotplug && !hotplugInfo.WriteCacheEnableOverride)
1024  {
1025  //
1026  // This flag indicates that the device is hotpluggable making it unsafe to enable caching
1027  //
1028  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_PNP, "DiskStartFdo: Turning off write cache for %p due to hotpluggable device\n", Fdo));
1029 
1031  }
1032  else if (hotplugInfo.MediaHotplug)
1033  {
1034  //
1035  // This flag indicates that the media in the device cannot be reliably locked
1036  //
1037  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_PNP, "DiskStartFdo: Turning off write cache for %p due to unlockable media\n", Fdo));
1038 
1040  }
1041  else
1042  {
1043  //
1044  // Even though the device does not seem to have any obvious problems
1045  // we leave it to the user to modify the previous write cache setting
1046  //
1047  }
1048  }
1049 
1050  //
1051  // Query the disk to see if write cache is enabled
1052  // and set the DEV_WRITE_CACHE flag appropriately
1053  //
1054 
1055  status = DiskGetCacheInformation(fdoExtension, &cacheInfo);
1056 
1057  if (NT_SUCCESS(status))
1058  {
1059  if (cacheInfo.WriteCacheEnabled == TRUE)
1060  {
1061  SET_FLAG(fdoExtension->DeviceFlags, DEV_WRITE_CACHE);
1062  ADJUST_FUA_FLAG(fdoExtension);
1063 
1064  if (diskData->WriteCacheOverride == DiskWriteCacheDisable)
1065  {
1066  //
1067  // Write cache is currently enabled on this
1068  // device, but we would like to turn it off
1069  //
1070  cacheInfo.WriteCacheEnabled = FALSE;
1071 
1072  DiskSetCacheInformation(fdoExtension, &cacheInfo);
1073  }
1074  }
1075  else
1076  {
1077  if (diskData->WriteCacheOverride == DiskWriteCacheEnable)
1078  {
1079  //
1080  // Write cache is currently disabled on this
1081  // device, but we would like to turn it on
1082  //
1083  cacheInfo.WriteCacheEnabled = TRUE;
1084 
1085  DiskSetCacheInformation(fdoExtension, &cacheInfo);
1086  }
1087  }
1088  }
1089 
1090  //
1091  // Query the registry to see if this disk is power-protected or not
1092  //
1093 
1094  CLEAR_FLAG(fdoExtension->DeviceFlags, DEV_POWER_PROTECTED);
1095 
1096  ClassGetDeviceParameter(fdoExtension, DiskDeviceParameterSubkey, DiskDeviceCacheIsPowerProtected, &isPowerProtected);
1097 
1098  if (isPowerProtected == 1)
1099  {
1100  SET_FLAG(fdoExtension->DeviceFlags, DEV_POWER_PROTECTED);
1101  }
1102 
1103  ADJUST_FUA_FLAG(fdoExtension);
1104 
1105  return STATUS_SUCCESS;
1106 
1107 } // end DiskStartFdo()
BOOLEAN DeviceHotplug
Definition: imports.h:248
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
#define IOCTL_STORAGE_GET_HOTPLUG_INFO
Definition: imports.h:238
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 DEV_WRITE_CACHE
Definition: class2.h:21
BOOLEAN MediaHotplug
Definition: imports.h:247
#define DiskDeviceParameterSubkey
Definition: disk.h:403
#define CLASS_SPECIAL_DISABLE_WRITE_CACHE
Definition: classpnp.h:168
#define FALSE
Definition: types.h:117
#define ADJUST_FUA_FLAG(fdoExt)
Definition: classpnp.h:53
smooth NULL
Definition: ftsmooth.c:416
DISK_USER_WRITE_CACHE_SETTING WriteCacheOverride
Definition: disk.h:385
#define CLEAR_FLAG(Flags, Bit)
Definition: cdrom.h:1494
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
BOOLEAN WriteCacheEnableOverride
Definition: imports.h:249
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
NTSTATUS NTAPI DiskGetCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
Definition: disk.c:3015
static const WCHAR L[]
Definition: oid.c:1250
struct _cl_event * event
Definition: glext.h:7739
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define DEV_POWER_PROTECTED
Definition: cdrom.h:143
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define DiskDeviceUserWriteCacheSetting
Definition: disk.h:404
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI DiskSetCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
Definition: disk.c:3163
#define DiskDeviceCacheIsPowerProtected
Definition: disk.h:405
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

Referenced by DriverEntry().

◆ DiskStopDevice()

NTSTATUS NTAPI DiskStopDevice ( IN PDEVICE_OBJECT  DeviceObject,
IN UCHAR  Type 
)

Definition at line 598 of file pnp.c.

603 {
606  return STATUS_SUCCESS;
607 }
Type
Definition: Type.h:6
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by DriverEntry().

Variable Documentation

◆ diskDeviceSequenceNumber

ULONG diskDeviceSequenceNumber = 0

Definition at line 35 of file pnp.c.

Referenced by DiskGenerateDeviceName().

◆ DiskIsPastReinit

BOOLEAN DiskIsPastReinit

Definition at line 81 of file disk.c.

Referenced by DiskDriverReinit().

◆ InitSafeBootMode

PULONG InitSafeBootMode

Definition at line 69 of file init.c.

Referenced by DiskInitFdo().