ReactOS 0.4.15-dev-8413-gc1c91f2
common.c File Reference
#include "ntddk.h"
#include "ntddstor.h"
#include "ntstrsafe.h"
#include "cdrom.h"
#include "scratch.h"
Include dependency graph for common.c:

Go to the source code of this file.

Functions

VOID RequestSetReceivedTime (_In_ WDFREQUEST Request)
 
VOID RequestSetSentTime (_In_ WDFREQUEST Request)
 
VOID RequestClearSendTime (_In_ WDFREQUEST Request)
 
 _IRQL_requires_max_ (PASSIVE_LEVEL)
 
 _IRQL_requires_max_ (APC_LEVEL)
 
VOID DeviceSendNotification (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ const GUID *Guid, _In_ ULONG ExtraDataSize, _In_opt_ PVOID ExtraData)
 
VOID DeviceSendStartUnit (_In_ WDFDEVICE Device)
 
VOID DeviceSendIoctlAsynchronously (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ ULONG IoControlCode, _In_ PDEVICE_OBJECT TargetDeviceObject)
 
NTSTATUS NTAPI RequestAsynchronousIrpCompletion (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Context)
 
VOID NTAPI DeviceAsynchronousCompletion (_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_ PWDF_REQUEST_COMPLETION_PARAMS Params, _In_ WDFCONTEXT Context)
 
VOID DeviceReleaseQueue (_In_ WDFDEVICE Device)
 
VOID NTAPI DeviceReleaseQueueCompletion (_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_ PWDF_REQUEST_COMPLETION_PARAMS Params, _In_ WDFCONTEXT Context)
 
VOID DevicePerfIncrementErrorCount (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension)
 
VOID NTAPI DeviceRestoreDefaultSpeed (_In_ WDFWORKITEM WorkItem)
 
NTSTATUS RequestSetContextFields (_In_ WDFREQUEST Request, _In_ PSYNC_HANDLER Handler)
 
NTSTATUS RequestDuidGetDeviceIdProperty (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
NTSTATUS RequestDuidGetDeviceProperty (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDF_REQUEST_PARAMETERS RequestParameters, _Out_ size_t *DataLength)
 
VOID RequestCompletion (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ NTSTATUS Status, _In_ ULONG_PTR Information)
 
VOID NTAPI RequestDummyCompletionRoutine (_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_ PWDF_REQUEST_COMPLETION_PARAMS Params, _In_ WDFCONTEXT Context)
 
 _IRQL_requires_max_ (DISPATCH_LEVEL)
 
NTSTATUS RequestSend (_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDFIOTARGET IoTarget, _In_ ULONG Flags, _Out_opt_ PBOOLEAN RequestSent)
 

Variables

LPCSTR LockTypeStrings []
 

Function Documentation

◆ _IRQL_requires_max_() [1/3]

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 383 of file common.c.

407{
409 PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
410 BOOLEAN requestCancelled = FALSE;
411 PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(Request);
412
413 PAGED_CODE();
414
415 if (!RequestFormated)
416 {
417 // set request up for sending down
418 WdfRequestFormatRequestUsingCurrentType(Request);
419 }
420
421 // get cancellation status for the original request
422 if (requestContext->OriginalRequest != NULL)
423 {
424 requestCancelled = WdfRequestIsCanceled(requestContext->OriginalRequest);
425 }
426
427 if (!requestCancelled)
428 {
429 status = RequestSend(deviceExtension,
430 Request,
431 deviceExtension->IoTarget,
433 NULL);
434 }
435 else
436 {
438 }
439
440 return status;
441}
#define PAGED_CODE()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
_In_ WDFREQUEST _In_ BOOLEAN RequestFormated
Definition: cdrom.h:1248
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
NTSTATUS RequestSend(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ WDFIOTARGET IoTarget, _In_ ULONG Flags, _Out_opt_ PBOOLEAN RequestSent)
Definition: common.c:3793
#define STATUS_SUCCESS
Definition: shellext.h:65
WDFIOTARGET IoTarget
Definition: cdrom.h:476
WDFREQUEST OriginalRequest
Definition: cdrom.h:633
Definition: ps.c:97
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
@ WDF_REQUEST_SEND_OPTION_SYNCHRONOUS
Definition: wdfrequest.h:109

◆ _IRQL_requires_max_() [2/3]

_IRQL_requires_max_ ( DISPATCH_LEVEL  )

Definition at line 3557 of file common.c.

3587{
3589 BOOLEAN requestSent = FALSE;
3590
3591 BOOLEAN shouldRetry = TRUE;
3592 PCDB cdb = (PCDB)DeviceExtension->PowerContext.Srb.Cdb;
3593 ULONG timeoutValue = DeviceExtension->TimeOutValue;
3594 ULONG retryCount = 1;
3595
3596 // reset some fields.
3597 DeviceExtension->PowerContext.RetryIntervalIn100ns = 0;
3598 status = PowerContextReuseRequest(DeviceExtension);
3599 RequestClearSendTime(DeviceExtension->PowerContext.PowerRequest);
3600
3601 if (!NT_SUCCESS(status))
3602 {
3603 return status;
3604 }
3605
3606 // set proper timeout value and max retry count.
3607 switch(DeviceExtension->PowerContext.PowerChangeState.PowerDown)
3608 {
3612 break;
3613
3615 // Case of issuing SYNC CACHE command. Do not use power irp timeout remaining time in this case
3616 // as we want to give best try on SYNC CACHE command.
3617 retryCount = MAXIMUM_RETRIES;
3618 timeoutValue = DeviceExtension->TimeOutValue;
3619 break;
3620
3622 {
3623 // Case of issuing STOP UNIT command
3624 // As "Imme" bit is set to '1', this command should be completed in short time.
3625 // This command is at low importance, failure of this command has very small impact.
3626 ULONG secondsRemaining = 0;
3627
3628#if (WINVER >= 0x0601)
3629 // this API is introduced in Windows7
3630 PoQueryWatchdogTime(DeviceExtension->LowerPdo, &secondsRemaining);
3631#endif
3632
3633 if (secondsRemaining == 0)
3634 {
3635 // not able to retrieve remaining time from PoQueryWatchdogTime API, use default values.
3636 retryCount = MAXIMUM_RETRIES;
3637 timeoutValue = SCSI_CDROM_TIMEOUT;
3638 }
3639 else
3640 {
3641 // plan to leave about 30 seconds to lower level drivers if possible.
3642 if (secondsRemaining >= 32)
3643 {
3644 retryCount = (secondsRemaining - 30)/SCSI_CDROM_TIMEOUT + 1;
3645 timeoutValue = SCSI_CDROM_TIMEOUT;
3646
3647 if (retryCount > MAXIMUM_RETRIES)
3648 {
3649 retryCount = MAXIMUM_RETRIES;
3650 }
3651
3652 if (retryCount == 1)
3653 {
3654 timeoutValue = secondsRemaining - 30;
3655 }
3656 }
3657 else
3658 {
3659 // issue the command with minimal timeout value and do not retry on it.
3660 retryCount = 1;
3661 timeoutValue = 2;
3662 }
3663 }
3664 }
3665 break;
3666 default:
3667 NT_ASSERT( FALSE );
3669 return status;
3670 }
3671
3672 DeviceExtension->PowerContext.RetryCount = retryCount;
3673
3674 // issue command.
3675 while (shouldRetry)
3676 {
3677
3678 // set SRB fields.
3679 DeviceExtension->PowerContext.Srb.SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER |
3684
3685 DeviceExtension->PowerContext.Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
3686 DeviceExtension->PowerContext.Srb.TimeOutValue = timeoutValue;
3687
3688 if (DeviceExtension->PowerContext.PowerChangeState.PowerDown == PowerDownDeviceInitial)
3689 {
3690 DeviceExtension->PowerContext.Srb.Function = SRB_FUNCTION_LOCK_QUEUE;
3691 }
3692 else if (DeviceExtension->PowerContext.PowerChangeState.PowerDown == PowerDownDeviceLocked)
3693 {
3694 DeviceExtension->PowerContext.Srb.Function = SRB_FUNCTION_QUIESCE_DEVICE;
3695 }
3696 else if (DeviceExtension->PowerContext.PowerChangeState.PowerDown == PowerDownDeviceQuiesced)
3697 {
3698 // Case of issuing SYNC CACHE command.
3699 DeviceExtension->PowerContext.Srb.CdbLength = 10;
3700 cdb->SYNCHRONIZE_CACHE10.OperationCode = SCSIOP_SYNCHRONIZE_CACHE;
3701 }
3702 else if (DeviceExtension->PowerContext.PowerChangeState.PowerDown == PowerDownDeviceFlushed)
3703 {
3704 // Case of issuing STOP UNIT command.
3705 DeviceExtension->PowerContext.Srb.CdbLength = 6;
3706 cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
3707 cdb->START_STOP.Start = 0;
3708 cdb->START_STOP.Immediate = 1;
3709 }
3710 else if (DeviceExtension->PowerContext.PowerChangeState.PowerDown == PowerDownDeviceStopped)
3711 {
3712 DeviceExtension->PowerContext.Srb.Function = SRB_FUNCTION_UNLOCK_QUEUE;
3713 }
3714
3715 // Set up completion routine and context if requested
3717 {
3718 WdfRequestSetCompletionRoutine(DeviceExtension->PowerContext.PowerRequest,
3720 Context);
3721 }
3722
3723 status = RequestSend(DeviceExtension,
3724 DeviceExtension->PowerContext.PowerRequest,
3725 DeviceExtension->IoTarget,
3727 &requestSent);
3728
3729 if (requestSent)
3730 {
3731 if ((CompletionRoutine == NULL) &&
3732 (SRB_STATUS(DeviceExtension->PowerContext.Srb.SrbStatus) != SRB_STATUS_SUCCESS))
3733 {
3734 TracePrint((TRACE_LEVEL_ERROR,
3735 TRACE_FLAG_POWER,
3736 "%p\tError occured when issuing %s command to device. Srb %p, Status %x\n",
3737 DeviceExtension->PowerContext.PowerRequest,
3738 (DeviceExtension->PowerContext.PowerChangeState.PowerDown == PowerDownDeviceQuiesced) ? "SYNC CACHE" : "STOP UNIT",
3739 &DeviceExtension->PowerContext.Srb,
3740 DeviceExtension->PowerContext.Srb.SrbStatus));
3741
3742 NT_ASSERT(!(TEST_FLAG(DeviceExtension->PowerContext.Srb.SrbStatus, SRB_STATUS_QUEUE_FROZEN)));
3743
3744 shouldRetry = RequestSenseInfoInterpret(DeviceExtension,
3745 DeviceExtension->PowerContext.PowerRequest,
3746 &(DeviceExtension->PowerContext.Srb),
3747 retryCount - DeviceExtension->PowerContext.RetryCount,
3748 &status,
3749 &(DeviceExtension->PowerContext.RetryIntervalIn100ns));
3750
3751 if (shouldRetry && (DeviceExtension->PowerContext.RetryCount-- == 0))
3752 {
3753 shouldRetry = FALSE;
3754 }
3755 }
3756 else
3757 {
3758 // succeeded, do not need to retry.
3759 shouldRetry = FALSE;
3760 }
3761
3762 }
3763 else
3764 {
3765 // request failed to be sent
3766 shouldRetry = FALSE;
3767 }
3768
3769 if (shouldRetry)
3770 {
3772 t.QuadPart = -DeviceExtension->PowerContext.RetryIntervalIn100ns;
3774
3775 status = PowerContextReuseRequest(DeviceExtension);
3776 if (!NT_SUCCESS(status))
3777 {
3778 shouldRetry = FALSE;
3779 }
3780 }
3781 }
3782
3783 if (DeviceExtension->PowerContext.PowerChangeState.PowerDown == PowerDownDeviceQuiesced)
3784 {
3785 // record SYNC CACHE command completion time stamp.
3786 KeQueryTickCount(&DeviceExtension->PowerContext.Step1CompleteTime);
3787 }
3788
3789 return status;
3790}
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
#define SCSI_CDROM_TIMEOUT
Definition: cdrom.h:680
BOOLEAN RequestSenseInfoInterpret(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ WDFREQUEST Request, _In_ PSCSI_REQUEST_BLOCK Srb, _In_ ULONG RetriedCount, _Out_ NTSTATUS *Status, _Out_opt_ _Deref_out_range_(0, MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS) LONGLONG *RetryIntervalIn100ns)
Definition: sense.c:2467
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
@ PowerDownDeviceStopped
Definition: cdrom.h:412
@ PowerDownDeviceQuiesced
Definition: cdrom.h:410
@ PowerDownDeviceInitial
Definition: cdrom.h:408
@ PowerDownDeviceLocked
Definition: cdrom.h:409
@ PowerDownDeviceFlushed
Definition: cdrom.h:411
union _CDB * PCDB
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
#define SCSIOP_SYNCHRONIZE_CACHE
Definition: cdrw_hw.h:918
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
VOID RequestClearSendTime(_In_ WDFREQUEST Request)
Definition: common.c:111
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:402
#define SRB_FUNCTION_LOCK_QUEUE
Definition: srb.h:332
#define SRB_FUNCTION_UNLOCK_QUEUE
Definition: srb.h:333
#define SRB_FLAGS_BYPASS_LOCKED_QUEUE
Definition: srb.h:410
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:397
#define SRB_STATUS(Status)
Definition: srb.h:389
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:386
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:404
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
GLdouble GLdouble t
Definition: gl.h:2047
#define KernelMode
Definition: asm.h:34
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define SRB_FLAGS_D3_PROCESSING
Definition: srb.h:165
#define SRB_FUNCTION_QUIESCE_DEVICE
Definition: srb.h:99
#define KeQueryTickCount(CurrentCount)
Definition: ke.h:43
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
uint32_t ULONG
Definition: typedefs.h:59
Definition: cdrw_hw.h:28
struct _CDB::_START_STOP START_STOP
struct _CDB::_SYNCHRONIZE_CACHE10 SYNCHRONIZE_CACHE10
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:895
#define NT_ASSERT
Definition: rtlfuncs.h:3310

◆ _IRQL_requires_max_() [3/3]

_IRQL_requires_max_ ( PASSIVE_LEVEL  )

Definition at line 135 of file common.c.

161{
163 WDFKEY rootKey = NULL;
164 WDFKEY subKey = NULL;
165 UNICODE_STRING registrySubKeyName;
166 UNICODE_STRING registryValueName;
167 ULONG defaultParameterValue;
168
169 PAGED_CODE();
170
171 RtlInitUnicodeString(&registryValueName, ParameterName);
172
173 if (SubkeyName != NULL)
174 {
175 RtlInitUnicodeString(&registrySubKeyName, SubkeyName);
176 }
177
178 // open the hardware key
179 status = WdfDeviceOpenRegistryKey(DeviceExtension->Device,
181 KEY_READ,
183 &rootKey);
184
185 // open the sub key
186 if (NT_SUCCESS(status) && (SubkeyName != NULL))
187 {
188 status = WdfRegistryOpenKey(rootKey,
189 &registrySubKeyName,
190 KEY_READ,
192 &subKey);
193
194 if (!NT_SUCCESS(status))
195 {
196 WdfRegistryClose(rootKey);
197 rootKey = NULL;
198 }
199 }
200
201 if (NT_SUCCESS(status) && (rootKey != NULL))
202 {
203 defaultParameterValue = *ParameterValue;
204
205 status = WdfRegistryQueryULong((subKey != NULL) ? subKey : rootKey,
206 &registryValueName,
208
209 if (!NT_SUCCESS(status))
210 {
211 *ParameterValue = defaultParameterValue; // use default value
212 }
213 }
214
215 // close what we open
216 if (subKey != NULL)
217 {
218 WdfRegistryClose(subKey);
219 subKey = NULL;
220 }
221
222 if (rootKey != NULL)
223 {
224 WdfRegistryClose(rootKey);
225 rootKey = NULL;
226 }
227
228 // Windows 2000 SP3 uses the driver-specific key, so look in there
229 if (!NT_SUCCESS(status))
230 {
231 // open the software key
232 status = WdfDeviceOpenRegistryKey(DeviceExtension->Device,
234 KEY_READ,
236 &rootKey);
237
238 // open the sub key
239 if (NT_SUCCESS(status) && (SubkeyName != NULL))
240 {
241 status = WdfRegistryOpenKey(rootKey,
242 &registrySubKeyName,
243 KEY_READ,
245 &subKey);
246
247 if (!NT_SUCCESS(status))
248 {
249 WdfRegistryClose(rootKey);
250 rootKey = NULL;
251 }
252 }
253
254 if (NT_SUCCESS(status) && (rootKey != NULL))
255 {
256 defaultParameterValue = *ParameterValue;
257
258 status = WdfRegistryQueryULong((subKey != NULL) ? subKey : rootKey,
259 &registryValueName,
261
262 if (!NT_SUCCESS(status))
263 {
264 *ParameterValue = defaultParameterValue; // use default value
265 }
266 else
267 {
268 // Migrate the value over to the device-specific key
269 DeviceSetParameter(DeviceExtension, SubkeyName, ParameterName, *ParameterValue);
270 }
271 }
272
273 // close what we open
274 if (subKey != NULL)
275 {
276 WdfRegistryClose(subKey);
277 subKey = NULL;
278 }
279
280 if (rootKey != NULL)
281 {
282 WdfRegistryClose(rootKey);
283 rootKey = NULL;
284 }
285 }
286
287 return;
288
289} // end DeviceetParameter()
_In_opt_ PWSTR _In_ PWSTR ParameterName
Definition: cdrom.h:961
_In_opt_ PWSTR _In_ PWSTR _Inout_ PULONG ParameterValue
Definition: cdrom.h:963
_In_opt_ PWSTR SubkeyName
Definition: cdrom.h:960
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define PLUGPLAY_REGKEY_DRIVER
Definition: usbd.c:42
#define WDF_NO_OBJECT_ATTRIBUTES
Definition: wdftypes.h:105
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2786

◆ DeviceAsynchronousCompletion()

VOID NTAPI DeviceAsynchronousCompletion ( _In_ WDFREQUEST  Request,
_In_ WDFIOTARGET  Target,
_In_ PWDF_REQUEST_COMPLETION_PARAMS  Params,
_In_ WDFCONTEXT  Context 
)

Definition at line 1116 of file common.c.

1145{
1147 PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(context->Device);
1148
1151
1152 // If this is an execute srb, then check the return status and make sure.
1153 // the queue is not frozen.
1154 if (context->Srb.Function == SRB_FUNCTION_EXECUTE_SCSI)
1155 {
1156 // Check for a frozen queue.
1157 if (context->Srb.SrbStatus & SRB_STATUS_QUEUE_FROZEN)
1158 {
1159 // Unfreeze the queue getting the device object from the context.
1160 DeviceReleaseQueue(context->Device);
1161 }
1162 }
1163
1164 // free port-allocated sense buffer if we can detect
1165 //
1166 if (PORT_ALLOCATED_SENSE(deviceExtension, &context->Srb))
1167 {
1168 FREE_PORT_ALLOCATED_SENSE_BUFFER(deviceExtension, &context->Srb);
1169 }
1170
1172
1173 WdfObjectDelete(Request);
1174
1175} // end DeviceAsynchronousCompletion()
FORCEINLINE BOOLEAN PORT_ALLOCATED_SENSE(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: cdrom.h:826
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
FORCEINLINE VOID FREE_PORT_ALLOCATED_SENSE_BUFFER(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: cdrom.h:839
struct _COMPLETION_CONTEXT * PCOMPLETION_CONTEXT
VOID DeviceReleaseQueue(_In_ WDFDEVICE Device)
Definition: common.c:1179
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
Definition: http.c:7252
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308

◆ DevicePerfIncrementErrorCount()

VOID DevicePerfIncrementErrorCount ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension)

Definition at line 1378 of file common.c.

1381{
1382 PCDROM_PRIVATE_FDO_DATA fdoData = DeviceExtension->PrivateFdoData;
1383 KIRQL oldIrql;
1384 ULONG errors;
1385
1386 KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
1387
1388 fdoData->Perf.SuccessfulIO = 0; // implicit interlock
1389 errors = InterlockedIncrement((PLONG)&DeviceExtension->ErrorCount);
1390
1391 if (errors >= CLASS_ERROR_LEVEL_1)
1392 {
1393 // If the error count has exceeded the error limit, then disable
1394 // any tagged queuing, multiple requests per lu queueing
1395 // and sychronous data transfers.
1396 //
1397 // Clearing the no queue freeze flag prevents the port driver
1398 // from sending multiple requests per logical unit.
1399 CLEAR_FLAG(DeviceExtension->SrbFlags, SRB_FLAGS_NO_QUEUE_FREEZE);
1400 CLEAR_FLAG(DeviceExtension->SrbFlags, SRB_FLAGS_QUEUE_ACTION_ENABLE);
1401
1402 SET_FLAG(DeviceExtension->SrbFlags, SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
1403
1404 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
1405 "PerfIncrementErrorCount: Too many errors; disabling tagged queuing and "
1406 "synchronous data tranfers.\n"));
1407 }
1408
1409 if (errors >= CLASS_ERROR_LEVEL_2)
1410 {
1411 // If a second threshold is reached, disable disconnects.
1412 SET_FLAG(DeviceExtension->SrbFlags, SRB_FLAGS_DISABLE_DISCONNECT);
1413 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
1414 "PerfIncrementErrorCount: Too many errors; disabling disconnects.\n"));
1415 }
1416
1417 KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
1418 return;
1419}
#define InterlockedIncrement
Definition: armddk.h:53
#define CLEAR_FLAG(Flags, Bit)
Definition: cdrom.h:1494
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define CLASS_ERROR_LEVEL_2
Definition: cdromp.h:131
#define CLASS_ERROR_LEVEL_1
Definition: cdromp.h:130
#define SRB_FLAGS_DISABLE_DISCONNECT
Definition: srb.h:396
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:395
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
struct _CDROM_PRIVATE_FDO_DATA::@1048 Perf
KSPIN_LOCK SpinLock
Definition: cdromp.h:351
int32_t * PLONG
Definition: typedefs.h:58

Referenced by SenseInfoInterpretBySrbStatus().

◆ DeviceReleaseQueue()

VOID DeviceReleaseQueue ( _In_ WDFDEVICE  Device)

Definition at line 1179 of file common.c.

1203{
1204 PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(Device);
1206 KIRQL currentIrql;
1207
1208 // we raise irql seperately so we're not swapped out or suspended
1209 // while holding the release queue irp in this routine. this lets
1210 // us release the spin lock before lowering irql.
1211 KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
1212
1213 WdfSpinLockAcquire(deviceExtension->ReleaseQueueSpinLock);
1214
1215 if (deviceExtension->ReleaseQueueInProgress)
1216 {
1217 // Someone is already doing this work - just set the flag to indicate that
1218 // we need to release the queue again.
1219 deviceExtension->ReleaseQueueNeeded = TRUE;
1220 WdfSpinLockRelease(deviceExtension->ReleaseQueueSpinLock);
1221 KeLowerIrql(currentIrql);
1222
1223 return;
1224 }
1225
1226 // Mark that there is a release queue in progress and drop the spinlock.
1227 deviceExtension->ReleaseQueueInProgress = TRUE;
1228
1229 WdfSpinLockRelease(deviceExtension->ReleaseQueueSpinLock);
1230
1231 srb = &(deviceExtension->ReleaseQueueSrb);
1232
1233 // Optical media are removable, so we just flush the queue. This will also release it.
1235
1236 srb->OriginalRequest = WdfRequestWdmGetIrp(deviceExtension->ReleaseQueueRequest);
1237
1238 // Set a CompletionRoutine callback function.
1239 WdfRequestSetCompletionRoutine(deviceExtension->ReleaseQueueRequest,
1241 Device);
1242 // Send the request. If an error occurs, complete the request.
1243 RequestSend(deviceExtension,
1244 deviceExtension->ReleaseQueueRequest,
1245 deviceExtension->IoTarget,
1247 NULL);
1248
1249 KeLowerIrql(currentIrql);
1250
1251 return;
1252
1253} // end DeviceReleaseQueue()
EVT_WDF_REQUEST_COMPLETION_ROUTINE DeviceReleaseQueueCompletion
Definition: cdrom.h:1052
#define SRB_FUNCTION_FLUSH_QUEUE
Definition: srb.h:329
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
BOOLEAN ReleaseQueueInProgress
Definition: cdrom.h:581
BOOLEAN ReleaseQueueNeeded
Definition: cdrom.h:580
WDFSPINLOCK ReleaseQueueSpinLock
Definition: cdrom.h:576
WDFREQUEST ReleaseQueueRequest
Definition: cdrom.h:577
SCSI_REQUEST_BLOCK ReleaseQueueSrb
Definition: cdrom.h:578
PVOID OriginalRequest
Definition: srb.h:266
UCHAR Function
Definition: srb.h:250
@ WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE
Definition: wdfrequest.h:110

Referenced by DeviceAsynchronousCompletion(), DeviceReleaseQueueCompletion(), and RequestSenseInfoInterpret().

◆ DeviceReleaseQueueCompletion()

VOID NTAPI DeviceReleaseQueueCompletion ( _In_ WDFREQUEST  Request,
_In_ WDFIOTARGET  Target,
_In_ PWDF_REQUEST_COMPLETION_PARAMS  Params,
_In_ WDFCONTEXT  Context 
)

Definition at line 1257 of file common.c.

1286{
1288 WDFDEVICE device = Context;
1289 PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(device);
1290
1291 BOOLEAN releaseQueueNeeded = FALSE;
1293
1296
1300
1301 // Grab the spinlock and clear the release queue in progress flag so others
1302 // can run. Save (and clear) the state of the release queue needed flag
1303 // so that we can issue a new release queue outside the spinlock.
1304 WdfSpinLockAcquire(deviceExtension->ReleaseQueueSpinLock);
1305
1306 releaseQueueNeeded = deviceExtension->ReleaseQueueNeeded;
1307
1308 deviceExtension->ReleaseQueueNeeded = FALSE;
1309 deviceExtension->ReleaseQueueInProgress = FALSE;
1310
1311 // Reuse the ReleaseQueueRequest for the next time.
1312 status = WdfRequestReuse(Request,&params);
1313
1314 if (NT_SUCCESS(status))
1315 {
1316 // Preformat the ReleaseQueueRequest for the next time.
1317 // This should always succeed because it was already preformatted once during device initialization
1318 status = WdfIoTargetFormatRequestForInternalIoctlOthers(deviceExtension->IoTarget,
1319 Request,
1321 deviceExtension->ReleaseQueueInputMemory,
1322 NULL,
1323 NULL,
1324 NULL,
1325 NULL,
1326 NULL);
1327 }
1328
1329 if (!NT_SUCCESS(status))
1330 {
1331 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
1332 "DeviceReleaseQueueCompletion: WdfIoTargetFormatRequestForInternalIoctlOthers failed, %!STATUS!\n",
1333 status));
1334 }
1335
1337
1338 WdfSpinLockRelease(deviceExtension->ReleaseQueueSpinLock);
1339
1340 // If we need a release queue then issue one now. Another processor may
1341 // have already started one in which case we'll try to issue this one after
1342 // it is done - but we should never recurse more than one deep.
1343 if (releaseQueueNeeded)
1344 {
1346 }
1347
1348 return;
1349
1350} // DeviceReleaseQueueCompletion()
#define IOCTL_SCSI_EXECUTE_NONE
Definition: cdrw_hw.h:1453
GLenum const GLfloat * params
Definition: glext.h:5645
WDFMEMORY ReleaseQueueInputMemory
Definition: cdrom.h:579
Definition: devices.h:37
@ WDF_REQUEST_REUSE_NO_FLAGS
Definition: wdfrequest.h:92
FORCEINLINE VOID WDF_REQUEST_REUSE_PARAMS_INIT(_Out_ PWDF_REQUEST_REUSE_PARAMS Params, _In_ ULONG Flags, _In_ NTSTATUS Status)
Definition: wdfrequest.h:364

◆ DeviceRestoreDefaultSpeed()

VOID NTAPI DeviceRestoreDefaultSpeed ( _In_ WDFWORKITEM  WorkItem)

Definition at line 2631 of file common.c.

2651{
2653 WDFDEVICE device = WdfWorkItemGetParentObject(WorkItem);
2654 PCDROM_DEVICE_EXTENSION deviceExtension = DeviceGetExtension(device);
2655 PPERFORMANCE_DESCRIPTOR perfDescriptor;
2656 ULONG transferLength = sizeof(PERFORMANCE_DESCRIPTOR);
2657 SCSI_REQUEST_BLOCK srb = {0};
2658 PCDB cdb = (PCDB)srb.Cdb;
2659
2660 PAGED_CODE();
2661
2662 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DeviceRestoreDefaultSpeed: Restore device speed for %p\n", device));
2663
2664 perfDescriptor = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
2665 transferLength,
2667 if (perfDescriptor == NULL)
2668 {
2669 return;
2670 }
2671
2672 RtlZeroMemory(perfDescriptor, transferLength);
2673
2674 perfDescriptor->RestoreDefaults = TRUE;
2675
2676 srb.TimeOutValue = deviceExtension->TimeOutValue;
2677
2678 srb.CdbLength = 12;
2679 cdb->SET_STREAMING.OperationCode = SCSIOP_SET_STREAMING;
2680 REVERSE_BYTES_SHORT(&cdb->SET_STREAMING.ParameterListLength, &transferLength);
2681
2682 status = DeviceSendSrbSynchronously(device,
2683 &srb,
2684 perfDescriptor,
2685 transferLength,
2686 TRUE,
2687 NULL);
2688 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL,
2689 "DeviceRestoreDefaultSpeed: Set Streaming command completed with status: 0x%X\n", status));
2690
2691 FREE_POOL(perfDescriptor);
2692 WdfObjectDelete(WorkItem);
2693
2694 return;
2695}
#define CDROM_TAG_STREAM
Definition: cdrom.h:738
#define SCSIOP_SET_STREAMING
Definition: cdrw_hw.h:963
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _PERFORMANCE_DESCRIPTOR PERFORMANCE_DESCRIPTOR
#define REVERSE_BYTES_SHORT(Destination, Source)
Definition: scsi.h:3474
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
ULONG TimeOutValue
Definition: srb.h:262
UCHAR CdbLength
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:279
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
struct _CDB::_SET_STREAMING SET_STREAMING
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:115

◆ DeviceSendIoctlAsynchronously()

VOID DeviceSendIoctlAsynchronously ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ ULONG  IoControlCode,
_In_ PDEVICE_OBJECT  TargetDeviceObject 
)

Definition at line 1030 of file common.c.

1052{
1053 PIRP irp = NULL;
1054 PIO_STACK_LOCATION nextIrpStack = NULL;
1055
1056 irp = IoAllocateIrp(DeviceExtension->DeviceObject->StackSize, FALSE);
1057
1058 if (irp != NULL)
1059 {
1060 nextIrpStack = IoGetNextIrpStackLocation(irp);
1061
1062 nextIrpStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
1063
1064 nextIrpStack->Parameters.DeviceIoControl.OutputBufferLength = 0;
1065 nextIrpStack->Parameters.DeviceIoControl.InputBufferLength = 0;
1066 nextIrpStack->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
1067 nextIrpStack->Parameters.DeviceIoControl.Type3InputBuffer = NULL;
1068
1071 DeviceExtension,
1072 TRUE,
1073 TRUE,
1074 TRUE);
1075
1077 }
1078}
#define VOID
Definition: acefi.h:82
IO_COMPLETION_ROUTINE RequestAsynchronousIrpCompletion
Definition: cdrom.h:1257
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1674
FxIrp * irp
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IoCallDriver
Definition: irp.c:1225
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
union _IO_STACK_LOCATION::@1567 Parameters
struct _IO_STACK_LOCATION::@1567::@1568 DeviceIoControl
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695

Referenced by DeviceEvtD0Entry().

◆ DeviceSendNotification()

VOID DeviceSendNotification ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ const GUID Guid,
_In_ ULONG  ExtraDataSize,
_In_opt_ PVOID  ExtraData 
)

Definition at line 799 of file common.c.

824{
826 ULONG requiredSize;
828
829 status = RtlULongAdd((sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION) - sizeof(UCHAR)),
831 &requiredSize);
832
833 if (!(NT_SUCCESS(status)) || (requiredSize > 0x0000ffff))
834 {
835 // MAX_USHORT, max total size for these events!
836 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_MCN,
837 "Error sending event: size too large! (%x)\n",
838 requiredSize));
839 return;
840 }
841
842 notification = ExAllocatePoolWithTag(NonPagedPoolNx,
843 requiredSize,
845
846 // if none allocated, exit
847 if (notification == NULL)
848 {
849 return;
850 }
851
852 // Prepare and send the request!
853 RtlZeroMemory(notification, requiredSize);
854 notification->Version = 1;
855 notification->Size = (USHORT)(requiredSize);
856 notification->FileObject = NULL;
857 notification->NameBufferOffset = -1;
858 notification->Event = *Guid;
859
860 if (ExtraData != NULL)
861 {
862 RtlCopyMemory(notification->CustomDataBuffer, ExtraData, ExtraDataSize);
863 }
864
865 IoReportTargetDeviceChangeAsynchronous(DeviceExtension->LowerPdo,
867 NULL,
868 NULL);
869
871
872 return;
873}
#define CDROM_TAG_NOTIFICATION
Definition: cdrom.h:739
_In_ const GUID _In_ ULONG ExtraDataSize
Definition: classpnp.h:1430
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS NTAPI IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL)
Definition: pnpreport.c:498
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:762
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by DeviceInternalSetMediaChangeState(), SenseInfoInterpretByAdditionalSenseCode(), and SenseInfoInterpretForZPODD().

◆ DeviceSendStartUnit()

VOID DeviceSendStartUnit ( _In_ WDFDEVICE  Device)

Definition at line 877 of file common.c.

907{
909 PCDROM_DEVICE_EXTENSION deviceExtension = NULL;
910 WDF_OBJECT_ATTRIBUTES attributes;
911 WDFREQUEST startUnitRequest = NULL;
912 WDFMEMORY inputMemory = NULL;
913
916 PCDB cdb = NULL;
917
918 deviceExtension = DeviceGetExtension(Device);
919
920 if (NT_SUCCESS(status))
921 {
922 // Allocate Srb from nonpaged pool.
923 context = ExAllocatePoolWithTag(NonPagedPoolNx,
924 sizeof(COMPLETION_CONTEXT),
926
927 if (context == NULL)
928 {
929 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,
930 "DeviceSendStartUnit: Failed to allocate completion context\n"));
931
933 }
934 }
935
936 if (NT_SUCCESS(status))
937 {
938 // Save the device object in the context for use by the completion
939 // routine.
940 context->Device = Device;
941 srb = &context->Srb;
942
943 // Zero out srb.
944 RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
945
946 // setup SRB structure.
947 srb->Length = sizeof(SCSI_REQUEST_BLOCK);
950
953
954 // setup CDB
955 srb->CdbLength = 6;
956 cdb = (PCDB)srb->Cdb;
957
958 cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
959 cdb->START_STOP.Start = 1;
960 cdb->START_STOP.Immediate = 0;
961 cdb->START_STOP.LogicalUnitNumber = srb->Lun;
962
963 //Create Request for sending down to port driver
966 attributes.ParentObject = deviceExtension->IoTarget;
967
968 status = WdfRequestCreate(&attributes,
969 deviceExtension->IoTarget,
970 &startUnitRequest);
971 }
972
973 if (NT_SUCCESS(status))
974 {
975 srb->OriginalRequest = WdfRequestWdmGetIrp(startUnitRequest);
977
978 //Prepare the request
979 WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
980 attributes.ParentObject = startUnitRequest;
981
982 status = WdfMemoryCreatePreallocated(&attributes,
983 (PVOID)srb,
984 sizeof(SCSI_REQUEST_BLOCK),
985 &inputMemory);
986 }
987
988 if (NT_SUCCESS(status))
989 {
990 status = WdfIoTargetFormatRequestForInternalIoctlOthers(deviceExtension->IoTarget,
991 startUnitRequest,
993 inputMemory,
994 NULL,
995 NULL,
996 NULL,
997 NULL,
998 NULL);
999 }
1000
1001 if (NT_SUCCESS(status))
1002 {
1003 // Set a CompletionRoutine callback function.
1004 WdfRequestSetCompletionRoutine(startUnitRequest,
1006 context);
1007
1008 status = RequestSend(deviceExtension,
1009 startUnitRequest,
1010 deviceExtension->IoTarget,
1011 0,
1012 NULL);
1013 }
1014
1015 // release resources when failed.
1016 if (!NT_SUCCESS(status))
1017 {
1019 if (startUnitRequest != NULL)
1020 {
1021 WdfObjectDelete(startUnitRequest);
1022 }
1023 }
1024
1025 return;
1026} // end StartUnit()
#define START_UNIT_TIMEOUT
Definition: cdrom.h:132
EVT_WDF_REQUEST_COMPLETION_ROUTINE DeviceAsynchronousCompletion
Definition: cdrom.h:1045
#define CDROM_TAG_COMPLETION_CONTEXT
Definition: cdrom.h:729
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
ULONG SrbFlags
Definition: srb.h:260
USHORT Length
Definition: srb.h:249
WDFOBJECT ParentObject
Definition: wdfobject.h:130
FORCEINLINE VOID WDF_OBJECT_ATTRIBUTES_INIT(_Out_ PWDF_OBJECT_ATTRIBUTES Attributes)
Definition: wdfobject.h:147
#define WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(_attributes, _contexttype)
Definition: wdfobject.h:170

Referenced by DeviceErrorHandlerForHitachiGD2000(), and SenseInfoInterpretByAdditionalSenseCode().

◆ RequestAsynchronousIrpCompletion()

NTSTATUS NTAPI RequestAsynchronousIrpCompletion ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp,
_In_reads_opt_(_Inexpressible_("varies")) PVOID  Context 
)

Definition at line 1082 of file common.c.

1105{
1108
1109 IoFreeIrp(Irp);
1110
1112}
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055

◆ RequestClearSendTime()

VOID RequestClearSendTime ( _In_ WDFREQUEST  Request)

Definition at line 111 of file common.c.

126{
127 PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(Request);
128
129 requestContext->TimeSentDownFirstTime.QuadPart = 0;
130 requestContext->TimeSentDownLasttTime.QuadPart = 0;
131
132 return;
133}
LARGE_INTEGER TimeSentDownLasttTime
Definition: cdrom.h:637
LARGE_INTEGER TimeSentDownFirstTime
Definition: cdrom.h:636
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by _IRQL_requires_max_(), DeviceReleaseQueueCompletion(), and ScratchBuffer_BeginUseX().

◆ RequestCompletion()

VOID RequestCompletion ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ NTSTATUS  Status,
_In_ ULONG_PTR  Information 
)

Definition at line 3439 of file common.c.

3445{
3446#ifdef DBG
3447 ULONG ioctlCode = 0;
3448 WDF_REQUEST_PARAMETERS requestParameters;
3449
3450 // Get the Request parameters
3451 WDF_REQUEST_PARAMETERS_INIT(&requestParameters);
3452 WdfRequestGetParameters(Request, &requestParameters);
3453
3454 if (requestParameters.Type == WdfRequestTypeDeviceControl)
3455 {
3456 ioctlCode = requestParameters.Parameters.DeviceIoControl.IoControlCode;
3457
3458 if (requestParameters.Parameters.DeviceIoControl.IoControlCode != IOCTL_MCN_SYNC_FAKE_IOCTL)
3459 {
3460 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL,
3461 "Request complete - IOCTL - code: %X; Status: %X; Information: %X\n",
3462 ioctlCode,
3463 Status,
3464 (ULONG)Information));
3465 }
3466 else
3467 {
3468 TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_GENERAL,
3469 "Request complete - IOCTL - code: %X; Status: %X; Information: %X\n",
3470 ioctlCode,
3471 Status,
3472 (ULONG)Information));
3473 }
3474 }
3475 else if (requestParameters.Type == WdfRequestTypeRead)
3476 {
3477 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL,
3478 "Request complete - READ - Starting Offset: %X; Length: %X; Transferred Length: %X; Status: %X\n",
3479 (ULONG)requestParameters.Parameters.Read.DeviceOffset,
3480 (ULONG)requestParameters.Parameters.Read.Length,
3482 Status));
3483 }
3484 else if (requestParameters.Type == WdfRequestTypeWrite)
3485 {
3486 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL,
3487 "Request complete - WRITE - Starting Offset: %X; Length: %X; Transferred Length: %X; Status: %X\n",
3488 (ULONG)requestParameters.Parameters.Write.DeviceOffset,
3489 (ULONG)requestParameters.Parameters.Write.Length,
3491 Status));
3492 }
3493#endif
3494
3496 {
3497 PIRP irp = WdfRequestWdmGetIrp(Request);
3498 if (irp->Tail.Overlay.Thread)
3499 {
3500 IoSetHardErrorOrVerifyDevice(irp, DeviceExtension->DeviceObject);
3501 }
3502 }
3503
3504 if (!NT_SUCCESS(Status) && DeviceExtension->SurpriseRemoved == TRUE)
3505 {
3506 // IMAPI expects ERROR_DEV_NOT_EXISTS if recorder has been surprised removed,
3507 // or it will retry WRITE commands for up to 3 minutes
3508 // CDROM behavior should be consistent for all requests, including SCSI pass-through
3510 }
3511
3512 WdfRequestCompleteWithInformation(Request, Status, Information);
3513
3514 return;
3515}
#define IOCTL_MCN_SYNC_FAKE_IOCTL
Definition: cdrom.h:181
Status
Definition: gdiplustypes.h:25
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
WDF_REQUEST_TYPE Type
Definition: wdfrequest.h:142
struct _WDF_REQUEST_PARAMETERS::@3879::@3883 DeviceIoControl
union _WDF_REQUEST_PARAMETERS::@3879 Parameters
struct _WDF_REQUEST_PARAMETERS::@3879::@3882 Write
struct _WDF_REQUEST_PARAMETERS::@3879::@3881 Read
@ WdfRequestTypeWrite
Definition: wdfdevice.h:507
@ WdfRequestTypeRead
Definition: wdfdevice.h:506
@ WdfRequestTypeDeviceControl
Definition: wdfdevice.h:517
FORCEINLINE VOID WDF_REQUEST_PARAMETERS_INIT(_Out_ PWDF_REQUEST_PARAMETERS Parameters)
Definition: wdfrequest.h:211
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817

Referenced by CreateQueueEvtIoDefault(), DeviceEvtIoInCallerContext(), ReadWriteWorkItemRoutine(), RequestDispatchProcessDirectly(), RequestDispatchSpecialIoctls(), RequestDispatchSyncWithSequentialQueue(), RequestDispatchToSequentialQueue(), RequestDispatchUnknownRequests(), RequestHandleQueryPropertyDeviceUniqueId(), RequestHandleQueryPropertyWriteCache(), RequestHandleReadWrite(), RequestProcessInternalDeviceControl(), RequestSynchronizeProcessWithSerialQueue(), ScratchBuffer_ReadWriteCompletionRoutine(), ScratchBuffer_ReadWriteEvtRequestCancel(), ScratchBuffer_ReadWriteTimerRoutine(), SequentialQueueEvtCanceledOnQueue(), SequentialQueueEvtIoDeviceControl(), and SequentialQueueEvtIoReadWrite().

◆ RequestDuidGetDeviceIdProperty()

NTSTATUS RequestDuidGetDeviceIdProperty ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 2797 of file common.c.

2821{
2823 PSTORAGE_DEVICE_ID_DESCRIPTOR deviceIdDescriptor = NULL;
2824 PSTORAGE_DESCRIPTOR_HEADER descHeader = NULL;
2826
2827 *DataLength = 0;
2828
2829 // Get the VPD page 83h data.
2830 status = DeviceRetrieveDescriptor(DeviceExtension->Device,
2831 &propertyId,
2832 (PSTORAGE_DESCRIPTOR_HEADER*)&deviceIdDescriptor);
2833
2834 if (NT_SUCCESS(status) && (deviceIdDescriptor == NULL))
2835 {
2837 }
2838
2839 if (NT_SUCCESS(status))
2840 {
2841 status = WdfRequestRetrieveOutputBuffer(Request,
2842 RequestParameters.Parameters.DeviceIoControl.OutputBufferLength,
2843 &descHeader,
2844 NULL);
2845 }
2846
2847 if (NT_SUCCESS(status))
2848 {
2850 ULONG offset = descHeader->Size;
2851 PUCHAR dest = (PUCHAR)descHeader + offset;
2852 size_t outputBufferSize;
2853
2854 outputBufferSize = RequestParameters.Parameters.DeviceIoControl.OutputBufferLength;
2855
2856 // Adjust required size and potential destination location.
2857 status = RtlULongAdd(descHeader->Size, deviceIdDescriptor->Size, &descHeader->Size);
2858
2859 if (NT_SUCCESS(status) &&
2860 (outputBufferSize < descHeader->Size))
2861 {
2862 // Output buffer is too small. Return error and make sure
2863 // the caller gets info about required buffer size.
2864 *DataLength = descHeader->Size;
2866 }
2867
2868 if (NT_SUCCESS(status))
2869 {
2870 storageDuid = (PSTORAGE_DEVICE_UNIQUE_IDENTIFIER)descHeader;
2871 storageDuid->StorageDeviceIdOffset = offset;
2872
2874 deviceIdDescriptor,
2875 deviceIdDescriptor->Size);
2876
2877 *DataLength = storageDuid->Size;
2879 }
2880
2881 FREE_POOL(deviceIdDescriptor);
2882 }
2883
2884 return status;
2885}
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
_In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_PARAMETERS RequestParameters
Definition: ioctl.h:138
GLintptr offset
Definition: glext.h:5920
static char * dest
Definition: rtl.c:135
* PSTORAGE_DESCRIPTOR_HEADER
Definition: ntddstor.h:560
enum _STORAGE_PROPERTY_ID STORAGE_PROPERTY_ID
@ StorageDeviceIdProperty
Definition: ntddstor.h:514
* PSTORAGE_DEVICE_ID_DESCRIPTOR
Definition: ntddstor.h:742
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
struct _STORAGE_DEVICE_UNIQUE_IDENTIFIER * PSTORAGE_DEVICE_UNIQUE_IDENTIFIER
unsigned char * PUCHAR
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by RequestHandleQueryPropertyDeviceUniqueId().

◆ RequestDuidGetDeviceProperty()

NTSTATUS RequestDuidGetDeviceProperty ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDF_REQUEST_PARAMETERS  RequestParameters,
_Out_ size_t DataLength 
)

Definition at line 2888 of file common.c.

2912{
2914 PSTORAGE_DEVICE_DESCRIPTOR deviceDescriptor = DeviceExtension->DeviceDescriptor;
2915 PSTORAGE_DESCRIPTOR_HEADER descHeader = NULL;
2917 PUCHAR dest = NULL;
2918
2919 if (deviceDescriptor == NULL)
2920 {
2922 }
2923
2924 if (NT_SUCCESS(status))
2925 {
2926 status = WdfRequestRetrieveOutputBuffer(Request,
2927 RequestParameters.Parameters.DeviceIoControl.OutputBufferLength,
2928 &descHeader,
2929 NULL);
2930 }
2931
2932 if (NT_SUCCESS(status) &&
2933 (deviceDescriptor->SerialNumberOffset == 0))
2934 {
2936 }
2937
2938 // Use this info only if serial number is available.
2939 if (NT_SUCCESS(status))
2940 {
2941 ULONG offset = descHeader->Size;
2942 size_t outputBufferSize = RequestParameters.Parameters.DeviceIoControl.OutputBufferLength;
2943
2944 // Adjust required size and potential destination location.
2945 dest = (PUCHAR)descHeader + offset;
2946
2947 status = RtlULongAdd(descHeader->Size, deviceDescriptor->Size, &descHeader->Size);
2948
2949 if (NT_SUCCESS(status) &&
2950 (outputBufferSize < descHeader->Size))
2951 {
2952 // Output buffer is too small. Return error and make sure
2953 // the caller get info about required buffer size.
2954 *DataLength = descHeader->Size;
2956 }
2957
2958 if (NT_SUCCESS(status))
2959 {
2960 storageDuid = (PSTORAGE_DEVICE_UNIQUE_IDENTIFIER)descHeader;
2961 storageDuid->StorageDeviceOffset = offset;
2962
2964 deviceDescriptor,
2965 deviceDescriptor->Size);
2966
2967 *DataLength = storageDuid->Size;
2969 }
2970 }
2971
2972 return status;
2973}
* PSTORAGE_DEVICE_DESCRIPTOR
Definition: ntddstor.h:576

Referenced by RequestHandleQueryPropertyDeviceUniqueId().

◆ RequestDummyCompletionRoutine()

VOID NTAPI RequestDummyCompletionRoutine ( _In_ WDFREQUEST  Request,
_In_ WDFIOTARGET  Target,
_In_ PWDF_REQUEST_COMPLETION_PARAMS  Params,
_In_ WDFCONTEXT  Context 
)

Definition at line 3520 of file common.c.

3546{
3550
3551 WdfRequestCompleteWithInformation(Request,
3552 WdfRequestGetStatus(Request),
3553 WdfRequestGetInformation(Request));
3554}

◆ RequestSend()

NTSTATUS RequestSend ( _In_ PCDROM_DEVICE_EXTENSION  DeviceExtension,
_In_ WDFREQUEST  Request,
_In_ WDFIOTARGET  IoTarget,
_In_ ULONG  Flags,
_Out_opt_ PBOOLEAN  RequestSent 
)

Definition at line 3793 of file common.c.

3819{
3821 BOOLEAN requestSent = FALSE;
3823
3824 UNREFERENCED_PARAMETER(DeviceExtension);
3825
3826 if ((DeviceExtension->ZeroPowerODDInfo != NULL) &&
3827 (DeviceExtension->ZeroPowerODDInfo->InZeroPowerState != FALSE))
3828 {
3829 }
3830
3831 // Now send down the request
3832 if (NT_SUCCESS(status))
3833 {
3835
3837
3838 // send request and check status
3839
3840 // Disable SDV warning about infinitely waiting in caller's context:
3841 // 1. Some requests (such as SCSI_PASS_THROUGH, contains buffer from user space) need to be sent down in caller’s context.
3842 // Consequently, these requests wait in caller’s context until they are allowed to be sent down.
3843 // 2. Considering the situation that during sleep, a request can be hold by storage port driver. When system resumes, any time out value (if we set using KMDF time out value) might be expires.
3844 // This will cause the waiting request being failed (behavior change). We’d rather not set time out value.
3845
3846 _Analysis_assume_(options.Timeout != 0);
3847 requestSent = WdfRequestSend(Request, IoTarget, &options);
3848 _Analysis_assume_(options.Timeout == 0);
3849
3850 // If WdfRequestSend fails, or if the WDF_REQUEST_SEND_OPTION_SYNCHRONOUS flag is set,
3851 // the driver can call WdfRequestGetStatus immediately after calling WdfRequestSend.
3852 if ((requestSent == FALSE) ||
3854 {
3855 status = WdfRequestGetStatus(Request);
3856
3857 if (requestSent == FALSE)
3858 {
3859 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL,
3860 "WdfRequestSend failed: %lx\n",
3861 status
3862 ));
3863 }
3864 }
3865 else
3866 {
3868 }
3869
3870 if (RequestSent != NULL)
3871 {
3872 *RequestSent = requestSent;
3873 }
3874 }
3875
3876 return status;
3877}
VOID RequestSetSentTime(_In_ WDFREQUEST Request)
Definition: common.c:79
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
_Must_inspect_result_ _In_ WDFDEVICE _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIOTARGET * IoTarget
Definition: wdfiotarget.h:368
_Must_inspect_result_ FORCEINLINE BOOLEAN WdfRequestSend(_In_ WDFREQUEST Request, _In_ WDFIOTARGET Target, _In_opt_ PWDF_REQUEST_SEND_OPTIONS Options)
Definition: wdfrequest.h:677
FORCEINLINE VOID WDF_REQUEST_SEND_OPTIONS_INIT(_Out_ PWDF_REQUEST_SEND_OPTIONS Options, _In_ ULONG Flags)
Definition: wdfrequest.h:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by _IRQL_requires_max_(), DeviceReleaseQueue(), DeviceSendStartUnit(), RequestProcessInternalDeviceControl(), and ScratchBuffer_SendSrb().

◆ RequestSetContextFields()

NTSTATUS RequestSetContextFields ( _In_ WDFREQUEST  Request,
_In_ PSYNC_HANDLER  Handler 
)

Definition at line 2748 of file common.c.

2768{
2770 PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(Request);
2771 PKEVENT syncEvent = NULL;
2772
2773 syncEvent = ExAllocatePoolWithTag(NonPagedPoolNx,
2774 sizeof(KEVENT),
2776
2777 if (syncEvent == NULL)
2778 {
2779 // memory allocation failed.
2781 }
2782 else
2783 {
2784 // now, put the special synchronization information into the context
2785 requestContext->SyncRequired = TRUE;
2786 requestContext->SyncEvent = syncEvent;
2787 requestContext->SyncCallback = Handler;
2788
2790 }
2791
2792 return status;
2793}
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER Handler
Definition: acpixf.h:672
#define CDROM_TAG_SYNC_EVENT
Definition: cdrom.h:732
BOOLEAN SyncRequired
Definition: cdrom.h:643
PSYNC_HANDLER SyncCallback
Definition: cdrom.h:645
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by RequestDispatchSpecialIoctls(), RequestDispatchSyncWithSequentialQueue(), and RequestDispatchUnknownRequests().

◆ RequestSetReceivedTime()

VOID RequestSetReceivedTime ( _In_ WDFREQUEST  Request)

Definition at line 64 of file common.c.

67{
68 PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(Request);
70
72
73 requestContext->TimeReceived = temp;
74
75 return;
76}
static calc_node_t temp
Definition: rpn_ieee.c:38
LARGE_INTEGER TimeReceived
Definition: cdrom.h:635

Referenced by DeviceEvtIoInCallerContext().

◆ RequestSetSentTime()

VOID RequestSetSentTime ( _In_ WDFREQUEST  Request)

Definition at line 79 of file common.c.

82{
83 PCDROM_REQUEST_CONTEXT requestContext = RequestGetContext(Request);
85
87
88 if (requestContext->TimeSentDownFirstTime.QuadPart == 0)
89 {
90 requestContext->TimeSentDownFirstTime = temp;
91 }
92
93 requestContext->TimeSentDownLasttTime = temp;
94
95 if (requestContext->OriginalRequest != NULL)
96 {
97 PCDROM_REQUEST_CONTEXT originalRequestContext = RequestGetContext(requestContext->OriginalRequest);
98
99 if (originalRequestContext->TimeSentDownFirstTime.QuadPart == 0)
100 {
101 originalRequestContext->TimeSentDownFirstTime = temp;
102 }
103
104 originalRequestContext->TimeSentDownLasttTime = temp;
105 }
106
107 return;
108}

Referenced by RequestSend().

Variable Documentation

◆ LockTypeStrings

LPCSTR LockTypeStrings[]
Initial value:
= {"Simple",
"Secure",
"Internal"
}

Definition at line 58 of file common.c.