ReactOS  0.4.15-dev-5452-g3c95c95
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 #ifdef _MSC_VER
136 #pragma prefast(suppress:6309, "We don't have QueryRoutine so Context doesn't make any sense")
137 #endif
139  diskKey,
140  queryTable,
141  NULL,
142  NULL);
143 
144  if(!NT_SUCCESS(status)) {
145  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskAddDevice: Error %#08lx reading value from "
146  "disk key %p for pdo %p\n",
147  status, diskKey, PhysicalDeviceObject));
148  }
149 
150  ZwClose(diskKey);
151 
152  } FINALLY {
153 
154  //
155  // Do nothing.
156  //
157 
158  if(!NT_SUCCESS(status)) {
159  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_PNP, "DiskAddDevice: Will %sallow file system to mount on "
160  "partition zero of disk %p\n",
161  (rootPartitionMountable ? "" : "not "),
163  }
164  }
165 
166  //
167  // Create device objects for disk
168  //
169 
170  diskCount = 0;
171 
173  DriverObject,
175  &diskCount,
176  (BOOLEAN) !rootPartitionMountable
177  );
178 
179  //
180  // Get the number of disks already initialized.
181  //
182 
183  configurationInformation = IoGetConfigurationInformation();
184 
185  if (NT_SUCCESS(status)) {
186 
187  //
188  // Increment system disk device count.
189  //
190 
191  configurationInformation->DiskCount++;
192 
193  }
194 
195  return status;
196 
197 } // 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:2786
#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:1157
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define RTL_QUERY_REGISTRY_TYPECHECK
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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
NTSTATUS DiskCreateFdo(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PULONG DeviceCount, IN BOOLEAN DasdAccessOnly)
Definition: disk.c:307
#define RTL_QUERY_REGISTRY_TYPECHECK_SHIFT
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:2191
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 676 of file pnp.c.

702 {
703  PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
704  PDISK_DATA diskData = commonExtension->DriverData;
705 
706  WCHAR wideSourceName[64] = { 0 };
707  UNICODE_STRING unicodeSourceName;
708 
710 
711  PAGED_CODE();
712 
713  //
714  // Build the destination for the link first using the device name
715  // stored in the device object
716  //
717 
718  NT_ASSERT(commonExtension->DeviceName.Buffer);
719 
720  if(!diskData->LinkStatus.WellKnownNameCreated) {
721  //
722  // Put together the source name using the partition and device number
723  // in the device extension and disk data segment
724  //
725 
726  status = RtlStringCchPrintfW(wideSourceName, sizeof(wideSourceName) / sizeof(wideSourceName[0]) - 1,
727  L"\\Device\\Harddisk%d\\Partition0",
728  commonExtension->PartitionZeroExtension->DeviceNumber);
729 
730  if (NT_SUCCESS(status)) {
731 
732  RtlInitUnicodeString(&unicodeSourceName, wideSourceName);
733 
734  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskCreateSymbolicLink: Linking %wZ to %wZ\n",
735  &unicodeSourceName,
736  &commonExtension->DeviceName));
737 
738  status = IoCreateSymbolicLink(&unicodeSourceName,
739  &commonExtension->DeviceName);
740 
741  if(NT_SUCCESS(status)){
742  diskData->LinkStatus.WellKnownNameCreated = TRUE;
743  }
744  }
745  }
746 
747  if (!diskData->LinkStatus.PhysicalDriveLinkCreated) {
748 
749  //
750  // Create a physical drive N link using the device number we saved
751  // away during AddDevice.
752  //
753 
754  status = RtlStringCchPrintfW(wideSourceName, sizeof(wideSourceName) / sizeof(wideSourceName[0]) - 1,
755  L"\\DosDevices\\PhysicalDrive%d",
756  commonExtension->PartitionZeroExtension->DeviceNumber);
757  if (NT_SUCCESS(status)) {
758 
759  RtlInitUnicodeString(&unicodeSourceName, wideSourceName);
760 
761  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskCreateSymbolicLink: Linking %wZ to %wZ\n",
762  &unicodeSourceName,
763  &(commonExtension->DeviceName)));
764 
765  status = IoCreateSymbolicLink(&unicodeSourceName,
766  &(commonExtension->DeviceName));
767 
768  if(NT_SUCCESS(status)) {
769  diskData->LinkStatus.PhysicalDriveLinkCreated = TRUE;
770  }
771  }
772  }
773 
774 
775  return;
776 }
#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
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define L(x)
Definition: ntvdm.h:50
struct _DISK_DATA::@1018 LinkStatus
UNICODE_STRING DeviceName
Definition: classpnp.h:615
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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:3310
Definition: ps.c:97

Referenced by DiskInitFdo().

◆ DiskDeleteSymbolicLinks()

VOID DiskDeleteSymbolicLinks ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 780 of file pnp.c.

802 {
803  PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
804  PDISK_DATA diskData = commonExtension->DriverData;
805 
806  WCHAR wideLinkName[64] = { 0 };
807  UNICODE_STRING unicodeLinkName;
809 
810  PAGED_CODE();
811 
812  if(diskData->LinkStatus.WellKnownNameCreated) {
813 
814  status = RtlStringCchPrintfW(wideLinkName, sizeof(wideLinkName) / sizeof(wideLinkName[0]) - 1,
815  L"\\Device\\Harddisk%d\\Partition0",
816  commonExtension->PartitionZeroExtension->DeviceNumber);
817  if (NT_SUCCESS(status)) {
818  RtlInitUnicodeString(&unicodeLinkName, wideLinkName);
819  IoDeleteSymbolicLink(&unicodeLinkName);
820  }
821  diskData->LinkStatus.WellKnownNameCreated = FALSE;
822  }
823 
824  if(diskData->LinkStatus.PhysicalDriveLinkCreated) {
825 
826  status = RtlStringCchPrintfW(wideLinkName, sizeof(wideLinkName) / sizeof(wideLinkName[0]) - 1,
827  L"\\DosDevices\\PhysicalDrive%d",
828  commonExtension->PartitionZeroExtension->DeviceNumber);
829  if (NT_SUCCESS(status)) {
830  RtlInitUnicodeString(&unicodeLinkName, wideLinkName);
831  IoDeleteSymbolicLink(&unicodeLinkName);
832  }
833  diskData->LinkStatus.PhysicalDriveLinkCreated = FALSE;
834  }
835 
836 
837  return;
838 }
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
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define L(x)
Definition: ntvdm.h:50
struct _DISK_DATA::@1018 LinkStatus
#define FALSE
Definition: types.h:117
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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 612 of file pnp.c.

641 {
642  CHAR rawName[64] = { 0 };
644 
645  PAGED_CODE();
646 
647  status = RtlStringCchPrintfA(rawName, sizeof(rawName) - 1, FDO_NAME_FORMAT, DeviceNumber,
649  if (!NT_SUCCESS(status)) {
650  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskGenerateDeviceName: Format FDO name failed with error: 0x%X\n", status));
651  return status;
652  }
653 
654  *RawName = ExAllocatePoolWithTag(PagedPool,
655  strlen(rawName) + 1,
656  DISK_TAG_NAME);
657 
658  if(*RawName == NULL) {
660  }
661 
662  status = RtlStringCchCopyA(*RawName, strlen(rawName) + 1, rawName);
663  if (!NT_SUCCESS(status)) {
664  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "DiskGenerateDeviceName: Device name copy failed with error: 0x%X\n", status));
665  FREE_POOL(*RawName);
666  return status;
667  }
668 
669  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP, "DiskGenerateDeviceName: generated \"%s\"\n", rawName));
670 
671  return STATUS_SUCCESS;
672 }
#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 FDO_NAME_FORMAT
#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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define DISK_TAG_NAME
Definition: disk.h:64
#define NULL
Definition: types.h:112
NTSTRSAFEAPI RtlStringCchCopyA(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:110
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1229
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 202 of file pnp.c.

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

Referenced by DriverEntry().

◆ DiskRemoveDevice()

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

Definition at line 843 of file pnp.c.

865 {
866  PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
867  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
868 
869  PAGED_CODE();
870 
871  //
872  // Handle query and cancel
873  //
874 
877  return STATUS_SUCCESS;
878  }
879 
880  //
881  // Delete our object directory.
882  //
883 
884  if(fdoExtension->DeviceDirectory != NULL) {
885  ZwMakeTemporaryObject(fdoExtension->DeviceDirectory);
886  ZwClose(fdoExtension->DeviceDirectory);
887  fdoExtension->DeviceDirectory = NULL;
888  }
889 
890  if(Type == IRP_MN_REMOVE_DEVICE) {
891 
892  FREE_POOL(fdoExtension->SenseData);
893 
895 
896  }
897 
899 
900  if (Type == IRP_MN_REMOVE_DEVICE)
901  {
902  ClassDeleteSrbLookasideList(commonExtension);
903  }
904 
905  return STATUS_SUCCESS;
906 }
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_REMOVE_DEVICE
VOID DiskDeleteSymbolicLinks(IN PDEVICE_OBJECT DeviceObject)
Definition: pnp.c:780
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IRP_MN_QUERY_REMOVE_DEVICE
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
Type
Definition: Type.h:6
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSYSAPI NTSTATUS NTAPI ZwMakeTemporaryObject(_In_ HANDLE Handle)
#define PAGED_CODE()

Referenced by DriverEntry().

◆ DiskStartFdo()

NTSTATUS NTAPI DiskStartFdo ( IN PDEVICE_OBJECT  Fdo)

Definition at line 911 of file pnp.c.

939 {
940  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
941  PCOMMON_DEVICE_EXTENSION commonExtension = &(fdoExtension->CommonExtension);
942  PDISK_DATA diskData = commonExtension->DriverData;
943  STORAGE_HOTPLUG_INFO hotplugInfo = { 0 };
944  DISK_CACHE_INFORMATION cacheInfo = { 0 };
945  ULONG isPowerProtected = 0;
947 
948  PAGED_CODE();
949 
950  //
951  // Get the hotplug information, so we can turn off write cache if needed
952  //
953  // NOTE: Capabilities info is not good enough to determine hotplugedness
954  // as we cannot determine device relations information and other
955  // dependencies. Get the hotplug info instead
956  //
957 
958  {
959  PIRP irp;
960  KEVENT event;
961  IO_STATUS_BLOCK statusBlock = { 0 };
962 
964 
966  Fdo,
967  NULL,
968  0L,
969  &hotplugInfo,
970  sizeof(STORAGE_HOTPLUG_INFO),
971  FALSE,
972  &event,
973  &statusBlock);
974 
975  if (irp != NULL) {
976 
977  // send to self -- classpnp handles this
979  if (status == STATUS_PENDING) {
981  Executive,
982  KernelMode,
983  FALSE,
984  NULL);
985 
986  status = statusBlock.Status;
987  }
989  }
990  }
991 
992  //
993  // Clear the DEV_WRITE_CACHE flag now and set
994  // it below only if we read that from the disk
995  //
996  CLEAR_FLAG(fdoExtension->DeviceFlags, DEV_WRITE_CACHE);
997  ADJUST_FUA_FLAG(fdoExtension);
998 
1000 
1001  //
1002  // Look into the registry to see if the user
1003  // has chosen to override the default setting
1004  //
1005  ClassGetDeviceParameter(fdoExtension,
1008  (PULONG)&diskData->WriteCacheOverride);
1009 
1010  if (diskData->WriteCacheOverride == DiskWriteCacheDefault)
1011  {
1012  //
1013  // The user has not overridden the default settings
1014  //
1016  {
1017  //
1018  // This flag indicates that we have faulty firmware and this
1019  // may cause the filesystem to refuse to mount on this media
1020  //
1021  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_PNP, "DiskStartFdo: Turning off write cache for %p due to a firmware issue\n", Fdo));
1022 
1024  }
1025  else if (hotplugInfo.DeviceHotplug && !hotplugInfo.WriteCacheEnableOverride)
1026  {
1027  //
1028  // This flag indicates that the device is hotpluggable making it unsafe to enable caching
1029  //
1030  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_PNP, "DiskStartFdo: Turning off write cache for %p due to hotpluggable device\n", Fdo));
1031 
1033  }
1034  else if (hotplugInfo.MediaHotplug)
1035  {
1036  //
1037  // This flag indicates that the media in the device cannot be reliably locked
1038  //
1039  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_PNP, "DiskStartFdo: Turning off write cache for %p due to unlockable media\n", Fdo));
1040 
1042  }
1043  else
1044  {
1045  //
1046  // Even though the device does not seem to have any obvious problems
1047  // we leave it to the user to modify the previous write cache setting
1048  //
1049  }
1050  }
1051 
1052  //
1053  // Query the disk to see if write cache is enabled
1054  // and set the DEV_WRITE_CACHE flag appropriately
1055  //
1056 
1057  status = DiskGetCacheInformation(fdoExtension, &cacheInfo);
1058 
1059  if (NT_SUCCESS(status))
1060  {
1061  if (cacheInfo.WriteCacheEnabled == TRUE)
1062  {
1063  SET_FLAG(fdoExtension->DeviceFlags, DEV_WRITE_CACHE);
1064  ADJUST_FUA_FLAG(fdoExtension);
1065 
1066  if (diskData->WriteCacheOverride == DiskWriteCacheDisable)
1067  {
1068  //
1069  // Write cache is currently enabled on this
1070  // device, but we would like to turn it off
1071  //
1072  cacheInfo.WriteCacheEnabled = FALSE;
1073 
1074  DiskSetCacheInformation(fdoExtension, &cacheInfo);
1075  }
1076  }
1077  else
1078  {
1079  if (diskData->WriteCacheOverride == DiskWriteCacheEnable)
1080  {
1081  //
1082  // Write cache is currently disabled on this
1083  // device, but we would like to turn it on
1084  //
1085  cacheInfo.WriteCacheEnabled = TRUE;
1086 
1087  DiskSetCacheInformation(fdoExtension, &cacheInfo);
1088  }
1089  }
1090  }
1091 
1092  //
1093  // Query the registry to see if this disk is power-protected or not
1094  //
1095 
1096  CLEAR_FLAG(fdoExtension->DeviceFlags, DEV_POWER_PROTECTED);
1097 
1098  ClassGetDeviceParameter(fdoExtension, DiskDeviceParameterSubkey, DiskDeviceCacheIsPowerProtected, &isPowerProtected);
1099 
1100  if (isPowerProtected == 1)
1101  {
1102  SET_FLAG(fdoExtension->DeviceFlags, DEV_POWER_PROTECTED);
1103  }
1104 
1105  ADJUST_FUA_FLAG(fdoExtension);
1106 
1107  return STATUS_SUCCESS;
1108 
1109 } // 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 DiskDeviceCacheIsPowerProtected
Definition: disk.h:405
#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
BOOLEAN MediaHotplug
Definition: imports.h:247
#define L(x)
Definition: ntvdm.h:50
#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
NTSTATUS NTAPI DiskSetCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
Definition: disk.c:3167
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
#define DEV_WRITE_CACHE
Definition: classpnp.h:178
BOOLEAN WriteCacheEnableOverride
Definition: imports.h:249
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
#define DiskDeviceUserWriteCacheSetting
Definition: disk.h:404
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
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
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 STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS NTAPI DiskGetCacheInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PDISK_CACHE_INFORMATION CacheInfo)
Definition: disk.c:3019
static SERVICE_STATUS status
Definition: service.c:31
#define DiskDeviceParameterSubkey
Definition: disk.h:403
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
FxIrp * irp
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3310
Definition: ps.c:97

Referenced by DriverEntry().

◆ DiskStopDevice()

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

Definition at line 600 of file pnp.c.

605 {
608  return STATUS_SUCCESS;
609 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
Type
Definition: Type.h:6
#define STATUS_SUCCESS
Definition: shellext.h:65

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 71 of file init.c.

Referenced by DiskInitFdo().