ReactOS  0.4.15-dev-1374-g8d3e80e
init.c File Reference
#include "ntddk.h"
#include "ntddstor.h"
#include "ntstrsafe.h"
#include "devpkey.h"
#include "cdrom.h"
#include "scratch.h"
#include "mmc.h"
Include dependency graph for init.c:

Go to the source code of this file.

Functions

 _IRQL_requires_max_ (_IRQL_requires_max_() VOIDDeviceScanSpecialDevices(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension) APC_LEVEL)
 
NTSTATUS NTAPI DeviceEvtSelfManagedIoInit (_In_ WDFDEVICE Device)
 
 _IRQL_requires_max_ (APC_LEVEL)
 
 _IRQL_requires_max_ (PASSIVE_LEVEL)
 

Function Documentation

◆ _IRQL_requires_max_() [1/3]

_IRQL_requires_max_ ( _IRQL_requires_max_()VOIDDeviceScanSpecialDevices( _In_ PCDROM_DEVICE_EXTENSION DeviceExtension )  APC_LEVEL)

Definition at line 38 of file init.c.

118  :4152) // nonstandard extension, function/data pointer conversion in expression
119 #pragma warning(disable:26000) // read overflow reported because of pointer type conversion
120 
122 NTSTATUS
123 DeviceClaimRelease(
124  _In_ PCDROM_DEVICE_EXTENSION DeviceExtension,
126  )
127 /*++
128 
129 Routine Description:
130 
131  This function claims a device in the port driver. The port driver object
132  is updated with the correct driver object if the device is successfully
133  claimed.
134 
135 Arguments:
136 
137  Device - The WDFDEVICE that needs to be claimed or released.
138 
139  Release - Indicates the logical unit should be released rather than claimed.
140 
141 Return Value:
142 
143  Returns a status indicating success or failure of the operation.
144 
145 --*/
146 {
148  SCSI_REQUEST_BLOCK srb = {0};
150  WDFREQUEST request;
151  WDF_OBJECT_ATTRIBUTES attributes;
152 
153  PAGED_CODE();
154 
155  //Create a request
158 
159  status = WdfRequestCreate(&attributes,
160  DeviceExtension->IoTarget,
161  &request);
162 
163  if (NT_SUCCESS(status))
164  {
165  //fill up srb structure
166  srb.OriginalRequest = WdfRequestWdmGetIrp(request);
168 
169  srb.Length = sizeof(SCSI_REQUEST_BLOCK);
170 
171  srb.Function = Release
174 
175 
177  &srb,
178  sizeof(srb));
179 
180  status = WdfIoTargetSendInternalIoctlOthersSynchronously(DeviceExtension->IoTarget,
181  request,
183  &descriptor,
184  NULL,
185  NULL,
186  NULL,
187  NULL);
188 
190 
191  // The request should be deleted.
192  WdfObjectDelete(request);
193 
194  if (!NT_SUCCESS(status))
195  {
196  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
197  "DeviceClaimRelease: Failed to %s device, status: 0x%X\n",
198  Release ? "Release" : "Claim",
199  status));
200  }
201  }
202  else
203  {
204  TracePrint((TRACE_LEVEL_FATAL, TRACE_FLAG_PNP,
205  "DeviceClaimRelease: Failed to create request, status: 0x%X\n",
206  status));
207  }
208 
209  if (Release)
210  {
211  // We only release the device when we don't want to manage it.
212  // The failure status does not matter.
214  }
215 
216  return status;
217 } // end DeviceClaimRelease()
ULONG SrbFlags
Definition: srb.h:252
PVOID OriginalRequest
Definition: srb.h:258
#define SRB_FLAGS_FREE_SENSE_BUFFER
Definition: srb.h:398
LONG NTSTATUS
Definition: precomp.h:26
#define SRB_FUNCTION_CLAIM_DEVICE
Definition: srb.h:308
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
FxRequest * request
#define TRACE_LEVEL_FATAL
Definition: storswtr.h:26
descriptor
Definition: scsi.h:3951
unsigned char BOOLEAN
#define SRB_FUNCTION_RELEASE_DEVICE
Definition: srb.h:313
FORCEINLINE VOID WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(_Out_ PWDF_MEMORY_DESCRIPTOR Descriptor, _In_ PVOID Buffer, _In_ ULONG BufferLength)
Definition: wdfmemory.h:102
_IRQL_requires_max_(_IRQL_requires_max_() VOIDDeviceScanSpecialDevices(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension) APC_LEVEL)
Definition: init.c:38
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UCHAR Function
Definition: srb.h:242
USHORT Length
Definition: srb.h:241
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define IOCTL_SCSI_EXECUTE_NONE
Definition: cdrw_hw.h:1453
#define _In_
Definition: no_sal2.h:158
_In_ BOOLEAN Release
Definition: cdrom.h:920
#define NULL
Definition: types.h:112
Definition: tftpd.h:85
int disable
Definition: msacm.c:1365
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
#define warning(s)
Definition: debug.h:83
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

◆ _IRQL_requires_max_() [2/3]

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 455 of file init.c.

475 {
477  WDF_OBJECT_ATTRIBUTES attributes;
478 
479  PAGED_CODE();
480 
483  attributes.ParentObject = DeviceExtension->Device;
484 
485  status = WdfRequestCreate(&attributes,
486  DeviceExtension->IoTarget,
487  &(DeviceExtension->ReleaseQueueRequest));
488 
489  if (!NT_SUCCESS(status))
490  {
491  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "Cannot create the release queue request\n"));
492 
493  return status;
494  }
495 
496  // Initialize ReleaseQueueInputMemory, a wrapper around ReleaseQueueSrb
497  WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
498  attributes.ParentObject = DeviceExtension->ReleaseQueueRequest;
499 
500  status = WdfMemoryCreatePreallocated(&attributes,
501  &DeviceExtension->ReleaseQueueSrb,
502  sizeof(SCSI_REQUEST_BLOCK),
503  &DeviceExtension->ReleaseQueueInputMemory);
504  if (!NT_SUCCESS(status))
505  {
506  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP, "Failed to allocate ReleaseQueueSrb.\n"));
507 
508  return status;
509  }
510 
511  // Preformat the release queue request here to ensure that this call will never
512  // fail during an actual release of the queue.
513  if (NT_SUCCESS(status))
514  {
515  status = WdfIoTargetFormatRequestForInternalIoctlOthers(DeviceExtension->IoTarget,
516  DeviceExtension->ReleaseQueueRequest,
518  DeviceExtension->ReleaseQueueInputMemory,
519  NULL,
520  NULL,
521  NULL,
522  NULL,
523  NULL);
524  }
525 
526  // Set a CompletionRoutine callback function for ReleaseQueueRequest.
527  if (NT_SUCCESS(status))
528  {
529  WdfRequestSetCompletionRoutine(DeviceExtension->ReleaseQueueRequest,
531  DeviceExtension->Device);
532  }
533 
534  // Create a spinlock for ReleaseQueueRequest
535  WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
536  attributes.ParentObject = DeviceExtension->Device;
537 
538  status = WdfSpinLockCreate(&attributes,
539  &(DeviceExtension->ReleaseQueueSpinLock));
540 
541  if (!NT_SUCCESS(status))
542  {
543  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_PNP,
544  "DeviceInitReleaseQueueContext: Cannot create the release queue spinlock\n"));
545 
546  return status;
547  }
548 
549  // Initialize miscellaneous ReleaseQueue related fields
550  DeviceExtension->ReleaseQueueNeeded = FALSE;
551  DeviceExtension->ReleaseQueueInProgress = FALSE;
552  DeviceExtension->ReleaseQueueSrb.Length = sizeof(SCSI_REQUEST_BLOCK);
553 
554  return status;
555 }
EVT_WDF_REQUEST_COMPLETION_ROUTINE DeviceReleaseQueueCompletion
Definition: cdrom.h:1052
LONG NTSTATUS
Definition: precomp.h:26
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define IOCTL_SCSI_EXECUTE_NONE
Definition: cdrw_hw.h:1453
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
WDFOBJECT ParentObject
Definition: wdfobject.h:130
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

◆ _IRQL_requires_max_() [3/3]

_IRQL_requires_max_ ( PASSIVE_LEVEL  )

Definition at line 726 of file init.c.

748 {
750  WDF_MEMORY_DESCRIPTOR outputDescriptor;
751 
752  PAGED_CODE();
753 
754  if ((DeviceExtension == NULL) ||
755  (ScsiAddress == NULL))
756  {
758  }
759 
760  //Get IOTARGET for sending request to port driver.
761  WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputDescriptor,
762  (PVOID)ScsiAddress,
763  sizeof(SCSI_ADDRESS));
764 
765  status = WdfIoTargetSendIoctlSynchronously(DeviceExtension->IoTarget,
766  NULL,
768  NULL,
769  &outputDescriptor,
770  NULL,
771  NULL);
772 
773  if (!NT_SUCCESS(status))
774  {
775  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_INIT,
776  "DeviceRetrieveScsiAddress: Get Address failed %lx\n",
777  status));
778  }
779  else
780  {
781  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_INIT,
782  "GetAddress: Port %x, Path %x, Target %x, Lun %x\n",
783  ScsiAddress->PortNumber,
784  ScsiAddress->PathId,
785  ScsiAddress->TargetId,
786  ScsiAddress->Lun));
787  }
788 
789  return status;
790 }
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE VOID WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(_Out_ PWDF_MEMORY_DESCRIPTOR Descriptor, _In_ PVOID Buffer, _In_ ULONG BufferLength)
Definition: wdfmemory.h:102
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define NULL
Definition: types.h:112
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

◆ DeviceEvtSelfManagedIoInit()

NTSTATUS NTAPI DeviceEvtSelfManagedIoInit ( _In_ WDFDEVICE  Device)

Definition at line 222 of file init.c.

242 {
244  PCDROM_DEVICE_EXTENSION deviceExtension = NULL;
245 
246  PAGED_CODE();
247 
248  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_PNP,
249  "DeviceEvtSelfManagedIoInit: WDFDEVICE %p is being started.\n",
250  Device));
251 
252  deviceExtension = DeviceGetExtension(Device);
253 
254  // 1. Set/retrieve basic information, some of the following operations may depend on it
255  if (NT_SUCCESS(status))
256  {
257  // We do not care if this function fails, SCSI address is mainly for debugging/tracing purposes.
258  (VOID) DeviceRetrieveScsiAddress(deviceExtension, &deviceExtension->ScsiAddress);
259  }
260 
261  if (NT_SUCCESS(status))
262  {
263  status = DeviceRetrieveDescriptorsAndTransferLength(deviceExtension);
264  }
265 
266  if (NT_SUCCESS(status))
267  {
268  // This function should be called after DeviceRetrieveDescriptorsAndTransferLength()
269  // It depends on MaxTransferLenth fields.
270  status = DeviceInitAllocateBuffers(deviceExtension);
271  }
272 
273  // 2. The following functions depend on the allocated buffers.
274 
275  // perf re-enable after failing. Q: Is this one used by cdrom.sys?
276  if (NT_SUCCESS(status))
277  {
278  // allow perf to be re-enabled after a given number of failed IOs
279  // require this number to be at least CLASS_PERF_RESTORE_MINIMUM
281 
282  DeviceGetParameter(deviceExtension,
285  &t);
287  {
288  deviceExtension->PrivateFdoData->Perf.ReEnableThreshhold = t;
289  }
290  }
291 
292  // 3. Retrieve information about special devices and hack flags.
293  if (NT_SUCCESS(status))
294  {
295  DeviceRetrieveHackFlagsFromRegistry(deviceExtension);
296  // scan for bad items.
297  DeviceScanForSpecial(deviceExtension, CdRomBadItems, DeviceHackFlagsScan);
298  // Check to see if it's a special device that needs special error process.
299  DeviceScanSpecialDevices(deviceExtension); // may send command to device
300  }
301 
302  // 4. Initialize the hotplug information only after the ScanForSpecial routines,
303  // as it relies upon the hack flags - deviceExtension->PrivateFdoData->HackFlags.
304  if (NT_SUCCESS(status))
305  {
306  status = DeviceInitializeHotplugInfo(deviceExtension);
307  }
308 
309  if (NT_SUCCESS(status))
310  {
311  // cache the device's inquiry data
312  status = DeviceCacheDeviceInquiryData(deviceExtension);
313  if (!NT_SUCCESS(status))
314  {
315  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_INIT,
316  "Failed to cache the device's inquiry data, failng %!STATUS!\n",
317  status
318  ));
319  }
320  }
321 
322  // 5. Initialize MMC context, media change notification stuff and read media capacity
323  if (NT_SUCCESS(status))
324  {
325  status = DeviceInitializeMediaChangeDetection(deviceExtension);
326  }
327  if (NT_SUCCESS(status))
328  {
329  status = DeviceInitMmcContext(deviceExtension);
330  }
331  if (NT_SUCCESS(status))
332  {
333  status = DeviceInitializeZPODD(deviceExtension);
334  }
335  if (NT_SUCCESS(status))
336  {
337  // Do READ CAPACITY. This SCSI command returns the last sector address
338  // on the device and the bytes per sector. These are used to calculate
339  // the drive capacity in bytes.
340  status = MediaReadCapacity(Device);
341 
342  // If READ CAPACITY succeeded, we can safely conclude that there is a media present
343  if (NT_SUCCESS(status))
344  {
345  DeviceSetMediaChangeStateEx(deviceExtension,
346  MediaPresent,
347  NULL);
348  }
349 
350  // READ CAPACITY is not critical for init, ignore all errors occuring during its execution
352  }
353 
354  // 6. Perform DVD-specific initialization
355  if (NT_SUCCESS(status))
356  {
357  status = DeviceInitializeDvd(Device);
358  }
359 
360  // 7. Miscellaneous initialization actions
361  if (NT_SUCCESS(status))
362  {
363  if (deviceExtension->PrivateFdoData != NULL)
364  {
365  deviceExtension->PrivateFdoData->Perf.OriginalSrbFlags = deviceExtension->SrbFlags;
366  }
367 
368  if (deviceExtension->DeviceAdditionalData.Mmc.IsWriter)
369  {
370  // OPC can really take this long per IMAPIv1 timeout....
371  deviceExtension->TimeOutValue = max(deviceExtension->TimeOutValue, SCSI_CDROM_OPC_TIMEOUT);
372  }
373  }
374 
375  // 8. Enable the main timer, create ARC name as needed
376  if (NT_SUCCESS(status))
377  {
378  // Device successfully added and initialized, increase CdRomCount.
380 
381  deviceExtension->IsInitialized = TRUE;
382 
383  DeviceEnableMainTimer(deviceExtension);
384 
385  }
386 
387 #if (NTDDI_VERSION >= NTDDI_WIN8)
388  // 9. Set volume interface properties
389  if (NT_SUCCESS(status))
390  {
391  BOOLEAN isCritical = FALSE;
392  BOOLEAN isPortable = FALSE;
393  BOOLEAN isRemovable = TEST_FLAG(deviceExtension->DeviceObject->Characteristics, FILE_REMOVABLE_MEDIA);
394  DEVPROP_BOOLEAN propCritical = DEVPROP_FALSE;
395  DEVPROP_BOOLEAN propPortable = DEVPROP_FALSE;
396  DEVPROP_BOOLEAN propRemovable = DEVPROP_FALSE;
397 
398  status = DeviceIsPortable(deviceExtension, &isPortable);
399 
400  if (NT_SUCCESS(status))
401  {
402  if (isPortable) {
403  SET_FLAG(deviceExtension->DeviceObject->Characteristics, FILE_PORTABLE_DEVICE);
404  }
405 
406  propPortable = isPortable ? DEVPROP_TRUE : DEVPROP_FALSE;
407 
408  status = IoSetDeviceInterfacePropertyData(&deviceExtension->MountedDeviceInterfaceName,
409  &DEVPKEY_Storage_Portable,
410  0,
411  0,
413  sizeof(DEVPROP_BOOLEAN),
414  &propPortable);
415  }
416 
417  if (NT_SUCCESS(status))
418  {
419  propRemovable = isRemovable ? DEVPROP_TRUE : DEVPROP_FALSE;
420 
421  status = IoSetDeviceInterfacePropertyData(&deviceExtension->MountedDeviceInterfaceName,
422  &DEVPKEY_Storage_Removable_Media,
423  0,
424  0,
426  sizeof(DEVPROP_BOOLEAN),
427  &propRemovable);
428  }
429 
430  if (NT_SUCCESS(status))
431  {
432  isCritical = TEST_FLAG(deviceExtension->DeviceObject->Flags,
436 
437  propCritical = isCritical ? DEVPROP_TRUE : DEVPROP_FALSE;
438 
439  status = IoSetDeviceInterfacePropertyData(&deviceExtension->MountedDeviceInterfaceName,
440  &DEVPKEY_Storage_System_Critical,
441  0,
442  0,
444  sizeof(DEVPROP_BOOLEAN),
445  &propCritical);
446  }
447 
448  }
449 #endif
450 
451  return status;
452 }
#define max(a, b)
Definition: svc.c:63
CDROM_SCAN_FOR_SPECIAL_INFO CdRomBadItems[]
Definition: data.c:100
VOID DeviceSetMediaChangeStateEx(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ MEDIA_CHANGE_DETECTION_STATE NewState, _Inout_opt_ PMEDIA_CHANGE_DETECTION_STATE OldState)
Definition: autorun.c:751
BOOLEAN IsInitialized
Definition: cdrom.h:464
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
PCDROM_PRIVATE_FDO_DATA PrivateFdoData
Definition: cdrom.h:605
#define TRUE
Definition: types.h:120
CDROM_DATA DeviceAdditionalData
Definition: cdrom.h:598
#define CLASS_PERF_RESTORE_MINIMUM
Definition: cdromp.h:129
LONG NTSTATUS
Definition: precomp.h:26
GLdouble GLdouble t
Definition: gl.h:2047
#define DO_SYSTEM_SYSTEM_PARTITION
#define DEVPROP_TYPE_BOOLEAN
Definition: devpropdef.h:46
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
BOOLEAN IsWriter
Definition: cdrom.h:249
#define CLASSP_REG_PERF_RESTORE_VALUE_NAME
Definition: cdromp.h:125
#define CLASSP_REG_SUBKEY_NAME
Definition: cdromp.h:120
#define FALSE
Definition: types.h:117
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define SCSI_CDROM_OPC_TIMEOUT
Definition: cdrom.h:688
unsigned char BOOLEAN
#define DO_SYSTEM_BOOT_PARTITION
Definition: env_spec_w32.h:400
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define FILE_PORTABLE_DEVICE
Definition: winternl.h:1855
#define DEVPROP_TRUE
Definition: devpropdef.h:66
#define DO_SYSTEM_CRITICAL_PARTITION
#define VOID
Definition: acefi.h:82
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
SCSI_ADDRESS ScsiAddress
Definition: cdrom.h:521
CHAR DEVPROP_BOOLEAN
Definition: devpropdef.h:64
#define NULL
Definition: types.h:112
CDROM_MMC_EXTENSION Mmc
Definition: cdrom.h:341
struct _CDROM_PRIVATE_FDO_DATA::@1029 Perf
unsigned int ULONG
Definition: retypes.h:1
PDEVICE_OBJECT DeviceObject
Definition: cdrom.h:493
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DEVPROP_FALSE
Definition: devpropdef.h:67
UNICODE_STRING MountedDeviceInterfaceName
Definition: cdrom.h:536
static SERVICE_STATUS status
Definition: service.c:31
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define PAGED_CODE()
Definition: ps.c:97