ReactOS  0.4.14-dev-552-g2fad488
autorun.c File Reference
#include "classp.h"
#include <wmidata.h>
Include dependency graph for autorun.c:

Go to the source code of this file.

Macros

#define GESN_TIMEOUT_VALUE   (0x4)
 
#define GESN_BUFFER_SIZE   (0x8)
 
#define MAXIMUM_IMMEDIATE_MCN_RETRIES   (0x20)
 
#define MCN_REG_SUBKEY_NAME   (L"MediaChangeNotification")
 
#define MCN_REG_AUTORUN_DISABLE_INSTANCE_NAME   (L"AlwaysDisableMCN")
 
#define MCN_REG_AUTORUN_ENABLE_INSTANCE_NAME   (L"AlwaysEnableMCN")
 
#define ClasspCanSendPollingIrp(fdoExtension)
 

Functions

BOOLEAN NTAPI ClasspIsMediaChangeDisabledDueToHardwareLimitation (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PUNICODE_STRING RegistryPath)
 
NTSTATUS NTAPI ClasspMediaChangeDeviceInstanceOverride (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, OUT PBOOLEAN Enabled)
 
BOOLEAN NTAPI ClasspIsMediaChangeDisabledForClass (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PUNICODE_STRING RegistryPath)
 
VOID NTAPI ClasspSetMediaChangeStateEx (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN MEDIA_CHANGE_DETECTION_STATE NewState, IN BOOLEAN Wait, IN BOOLEAN KnownStateChange)
 
NTSTATUS NTAPI ClasspMediaChangeRegistryCallBack (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
VOID NTAPI ClasspSendMediaStateIrp (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMEDIA_CHANGE_DETECTION_INFO Info, IN ULONG CountDown)
 
NTSTATUS NTAPI ClasspInitializePolling (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN BOOLEAN AllowDriveToSleep)
 
VOID NTAPI ClassSendEjectionNotification (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID NTAPI ClasspSendNotification (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN const GUID *Guid, IN ULONG ExtraDataSize, IN PVOID ExtraData)
 
VOID NTAPI ClasspInterpretGesnData (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PNOTIFICATION_EVENT_STATUS_HEADER Header, IN PBOOLEAN ResendImmediately)
 
VOID NTAPI ClasspInternalSetMediaChangeState (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN MEDIA_CHANGE_DETECTION_STATE NewState, IN BOOLEAN KnownStateChange)
 
VOID NTAPI ClassSetMediaChangeState (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN MEDIA_CHANGE_DETECTION_STATE NewState, IN BOOLEAN Wait)
 
NTSTATUS NTAPI ClasspMediaChangeDetectionCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
PIRP NTAPI ClasspPrepareMcnIrp (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMEDIA_CHANGE_DETECTION_INFO Info, IN BOOLEAN UseGesn)
 
VOID NTAPI ClassCheckMediaState (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID NTAPI ClassResetMediaChangeTimer (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
NTSTATUS NTAPI ClasspInitializeGesn (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMEDIA_CHANGE_DETECTION_INFO Info)
 
NTSTATUS NTAPI ClassInitializeTestUnitPolling (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN BOOLEAN AllowDriveToSleep)
 
VOID NTAPI ClassInitializeMediaChangeDetection (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PUCHAR EventPrefix)
 
VOID NTAPI ClassEnableMediaChangeDetection (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID NTAPI ClassDisableMediaChangeDetection (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
VOID NTAPI ClassCleanupMediaChangeDetection (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
 
NTSTATUS NTAPI ClasspMcnControl (IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PIRP Irp, IN PSCSI_REQUEST_BLOCK Srb)
 
VOID NTAPI ClasspTimerTick (PDEVICE_OBJECT DeviceObject, PVOID Context)
 
NTSTATUS NTAPI ClasspEnableTimer (PDEVICE_OBJECT DeviceObject)
 
NTSTATUS NTAPI ClasspDisableTimer (PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI ClasspFailurePredict (IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
 
VOID NTAPI ClassNotifyFailurePredicted (PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PUCHAR Buffer, ULONG BufferSize, BOOLEAN LogError, ULONG UniqueErrorValue, UCHAR PathId, UCHAR TargetId, UCHAR Lun)
 
NTSTATUS NTAPI ClassSetFailurePredictionPoll (PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, FAILURE_PREDICTION_METHOD FailurePredictionMethod, ULONG PollingPeriod)
 

Variables

GUID StoragePredictFailureEventGuid = WMI_STORAGE_PREDICT_FAILURE_EVENT_GUID
 
IO_WORKITEM_ROUTINE ClasspFailurePredict
 
ULONG BreakOnMcnDisable = FALSE
 

Macro Definition Documentation

◆ ClasspCanSendPollingIrp

#define ClasspCanSendPollingIrp (   fdoExtension)
Value:
((fdoExtension->DevicePowerState == PowerDeviceD0) && \
(! fdoExtension->PowerDownInProgress) )

Definition at line 54 of file autorun.c.

◆ GESN_BUFFER_SIZE

#define GESN_BUFFER_SIZE   (0x8)

Definition at line 29 of file autorun.c.

◆ GESN_TIMEOUT_VALUE

#define GESN_TIMEOUT_VALUE   (0x4)

Definition at line 28 of file autorun.c.

◆ MAXIMUM_IMMEDIATE_MCN_RETRIES

#define MAXIMUM_IMMEDIATE_MCN_RETRIES   (0x20)

Definition at line 30 of file autorun.c.

◆ MCN_REG_AUTORUN_DISABLE_INSTANCE_NAME

#define MCN_REG_AUTORUN_DISABLE_INSTANCE_NAME   (L"AlwaysDisableMCN")

Definition at line 32 of file autorun.c.

◆ MCN_REG_AUTORUN_ENABLE_INSTANCE_NAME

#define MCN_REG_AUTORUN_ENABLE_INSTANCE_NAME   (L"AlwaysEnableMCN")

Definition at line 33 of file autorun.c.

◆ MCN_REG_SUBKEY_NAME

#define MCN_REG_SUBKEY_NAME   (L"MediaChangeNotification")

Definition at line 31 of file autorun.c.

Function Documentation

◆ ClassCheckMediaState()

VOID NTAPI ClassCheckMediaState ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension)

Definition at line 1404 of file autorun.c.

1407 {
1408  PMEDIA_CHANGE_DETECTION_INFO info = FdoExtension->MediaChangeDetectionInfo;
1409  LONG countDown;
1410 
1411  if(info == NULL) {
1413  "ClassCheckMediaState: detection not enabled\n"));
1414  return;
1415  }
1416 
1417  //
1418  // Media change support is active and the IRP is waiting. Decrement the
1419  // timer. There is no MP protection on the timer counter. This code
1420  // is the only code that will manipulate the timer counter and only one
1421  // instance of it should be running at any given time.
1422  //
1423 
1424  countDown = InterlockedDecrement(&(info->MediaChangeCountDown));
1425 
1426  //
1427  // Try to acquire the media change event. If we can't do it immediately
1428  // then bail out and assume the caller will try again later.
1429  //
1431  info,
1432  countDown);
1433 
1434  return;
1435 } // end ClassCheckMediaState()
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
#define InterlockedDecrement
Definition: armddk.h:52
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
VOID NTAPI ClasspSendMediaStateIrp(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMEDIA_CHANGE_DETECTION_INFO Info, IN ULONG CountDown)
Definition: autorun.c:1215

Referenced by ClasspTimerTick().

◆ ClassCleanupMediaChangeDetection()

VOID NTAPI ClassCleanupMediaChangeDetection ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension)

Definition at line 2849 of file autorun.c.

2852 {
2853  PMEDIA_CHANGE_DETECTION_INFO info = FdoExtension->MediaChangeDetectionInfo;
2854 
2855  PAGED_CODE()
2856 
2857  if(info == NULL) {
2858  return;
2859  }
2860 
2861  FdoExtension->MediaChangeDetectionInfo = NULL;
2862 
2863  if (info->Gesn.Buffer) {
2864  ExFreePool(info->Gesn.Buffer);
2865  }
2866  IoFreeIrp(info->MediaChangeIrp);
2867  ExFreePool(info->SenseBuffer);
2868  ExFreePool(info);
2869  return;
2870 } // end ClassCleanupMediaChangeDetection()
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
if(!(yy_init))
Definition: macro.lex.yy.c:714
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by ClassRemoveDevice().

◆ ClassDisableMediaChangeDetection()

VOID NTAPI ClassDisableMediaChangeDetection ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension)

Definition at line 2803 of file autorun.c.

2806 {
2807  PMEDIA_CHANGE_DETECTION_INFO info = FdoExtension->MediaChangeDetectionInfo;
2808 
2809  PAGED_CODE();
2810 
2811  if(info == NULL) {
2812  return;
2813  }
2814 
2815  KeWaitForMutexObject(&info->MediaChangeMutex,
2816  UserRequest,
2817  KernelMode,
2818  FALSE,
2819  NULL);
2820 
2821  info->MediaChangeDetectionDisableCount++;
2822 
2823  DebugPrint((ClassDebugMCN, "ClassDisableMediaChangeDetection: "
2824  "disable count is %d\n",
2825  info->MediaChangeDetectionDisableCount));
2826 
2827  KeReleaseMutex(&info->MediaChangeMutex, FALSE);
2828 
2829  return;
2830 } // end ClassDisableMediaChangeDetection()
#define KeWaitForMutexObject
Definition: kefuncs.h:568
LONG NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait)
Definition: mutex.c:189
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23

Referenced by ClasspMcnControl().

◆ ClassEnableMediaChangeDetection()

VOID NTAPI ClassEnableMediaChangeDetection ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension)

Definition at line 2718 of file autorun.c.

2721 {
2722  PMEDIA_CHANGE_DETECTION_INFO info = FdoExtension->MediaChangeDetectionInfo;
2723  LONG oldCount;
2724 
2725  PAGED_CODE();
2726 
2727  if(info == NULL) {
2729  "ClassEnableMediaChangeDetection: not initialized\n"));
2730  return;
2731  }
2732 
2733  KeWaitForMutexObject(&info->MediaChangeMutex,
2734  UserRequest,
2735  KernelMode,
2736  FALSE,
2737  NULL);
2738 
2739  oldCount = --info->MediaChangeDetectionDisableCount;
2740 
2741  ASSERT(oldCount >= 0);
2742 
2743  DebugPrint((ClassDebugMCN, "ClassEnableMediaChangeDetection: Disable count "
2744  "reduced to %d - ",
2745  info->MediaChangeDetectionDisableCount));
2746 
2747  if(oldCount == 0) {
2748 
2749  //
2750  // We don't know what state the media is in anymore.
2751  //
2752 
2754  MediaUnknown,
2755  FALSE
2756  );
2757 
2758  //
2759  // Reset the MCN timer.
2760  //
2761 
2763 
2764  DebugPrint((ClassDebugMCN, "MCD is enabled\n"));
2765 
2766  } else {
2767 
2768  DebugPrint((ClassDebugMCN, "MCD still disabled\n"));
2769 
2770  }
2771 
2772 
2773  //
2774  // Let something else run.
2775  //
2776 
2777  KeReleaseMutex(&info->MediaChangeMutex, FALSE);
2778 
2779  return;
2780 } // end ClassEnableMediaChangeDetection()
#define KeWaitForMutexObject
Definition: kefuncs.h:568
LONG NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait)
Definition: mutex.c:189
#define PAGED_CODE()
Definition: video.h:57
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI ClassResetMediaChangeTimer(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: autorun.c:1456
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI ClasspInternalSetMediaChangeState(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN MEDIA_CHANGE_DETECTION_STATE NewState, IN BOOLEAN KnownStateChange)
Definition: autorun.c:591
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23

Referenced by ClasspCleanupDisableMcn(), and ClasspMcnControl().

◆ ClassInitializeMediaChangeDetection()

VOID NTAPI ClassInitializeMediaChangeDetection ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN PUCHAR  EventPrefix 
)

Definition at line 2058 of file autorun.c.

2062 {
2063  PDEVICE_OBJECT fdo = FdoExtension->DeviceObject;
2064  NTSTATUS status;
2065 
2067  fdo->DriverObject);
2068 
2069  BOOLEAN disabledForBadHardware;
2070  BOOLEAN disabled;
2071  BOOLEAN instanceOverride;
2072 
2073  PAGED_CODE();
2074 
2075  //
2076  // NOTE: This assumes that ClassInitializeMediaChangeDetection is always
2077  // called in the context of the ClassInitDevice callback. If called
2078  // after then this check will have already been made and the
2079  // once a second timer will not have been enabled.
2080  //
2081 
2082  disabledForBadHardware = ClasspIsMediaChangeDisabledDueToHardwareLimitation(
2083  FdoExtension,
2084  &(driverExtension->RegistryPath)
2085  );
2086 
2087  if (disabledForBadHardware) {
2089  "ClassInitializeMCN: Disabled due to hardware"
2090  "limitations for this device"));
2091  return;
2092  }
2093 
2094  //
2095  // autorun should now be enabled by default for all media types.
2096  //
2097 
2099  FdoExtension,
2100  &(driverExtension->RegistryPath)
2101  );
2102 
2104  "ClassInitializeMCN: Class MCN is %s\n",
2105  (disabled ? "disabled" : "enabled")));
2106 
2108  FdoExtension,
2109  &instanceOverride); // default value
2110 
2111  if (!NT_SUCCESS(status)) {
2113  "ClassInitializeMCN: Instance using default\n"));
2114  } else {
2116  "ClassInitializeMCN: Instance override: %s MCN\n",
2117  (instanceOverride ? "Enabling" : "Disabling")));
2118  disabled = !instanceOverride;
2119  }
2120 
2122  "ClassInitializeMCN: Instance MCN is %s\n",
2123  (disabled ? "disabled" : "enabled")));
2124 
2125  if (disabled) {
2126  return;
2127  }
2128 
2129  //
2130  // if the drive is not a CDROM, allow the drive to sleep
2131  //
2132  if (FdoExtension->DeviceObject->DeviceType == FILE_DEVICE_CD_ROM) {
2134  } else {
2136  }
2137 
2138  return;
2139 } // end ClassInitializeMediaChangeDetection()
NTSTATUS NTAPI ClasspInitializePolling(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN BOOLEAN AllowDriveToSleep)
Definition: autorun.c:1487
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI ClasspIsMediaChangeDisabledDueToHardwareLimitation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PUNICODE_STRING RegistryPath)
Definition: autorun.c:2337
NTSTATUS NTAPI ClasspMediaChangeDeviceInstanceOverride(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, OUT PBOOLEAN Enabled)
Definition: autorun.c:2165
UNICODE_STRING RegistryPath
Definition: kbdclass.h:25
#define PAGED_CODE()
Definition: video.h:57
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:107
unsigned char BOOLEAN
PCLASS_DRIVER_EXTENSION NTAPI ClassGetDriverExtension(IN PDRIVER_OBJECT DriverObject)
Definition: class.c:7236
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
BOOLEAN NTAPI ClasspIsMediaChangeDisabledForClass(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PUNICODE_STRING RegistryPath)
Definition: autorun.c:2569
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by CdRomInitDevice(), DiskInitFdo(), and ScsiFlopInitDevice().

◆ ClassInitializeTestUnitPolling()

NTSTATUS NTAPI ClassInitializeTestUnitPolling ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN BOOLEAN  AllowDriveToSleep 
)

Definition at line 2023 of file autorun.c.

2027 {
2029 } // end ClassInitializeTestUnitPolling()
NTSTATUS NTAPI ClasspInitializePolling(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN BOOLEAN AllowDriveToSleep)
Definition: autorun.c:1487
_In_ BOOLEAN AllowDriveToSleep
Definition: classpnp.h:1082

◆ ClassNotifyFailurePredicted()

VOID NTAPI ClassNotifyFailurePredicted ( PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
PUCHAR  Buffer,
ULONG  BufferSize,
BOOLEAN  LogError,
ULONG  UniqueErrorValue,
UCHAR  PathId,
UCHAR  TargetId,
UCHAR  Lun 
)

Definition at line 3468 of file autorun.c.

3478 {
3479  PIO_ERROR_LOG_PACKET logEntry;
3480 
3481  DebugPrint((1, "ClasspFailurePredictPollCompletion: Failure predicted for device %p\n", FdoExtension->DeviceObject));
3482 
3483  //
3484  // Fire off a WMI event
3485  //
3486  ClassWmiFireEvent(FdoExtension->DeviceObject,
3488  0,
3489  BufferSize,
3490  Buffer);
3491 
3492  //
3493  // Log an error into the eventlog
3494  //
3495 
3496  if (LogError)
3497  {
3498  logEntry = IoAllocateErrorLogEntry(
3499  FdoExtension->DeviceObject,
3500  sizeof(IO_ERROR_LOG_PACKET) + (3 * sizeof(ULONG)));
3501 
3502  if (logEntry != NULL)
3503  {
3504 
3505  logEntry->FinalStatus = STATUS_SUCCESS;
3506  logEntry->ErrorCode = IO_WRN_FAILURE_PREDICTED;
3507  logEntry->SequenceNumber = 0;
3510  logEntry->RetryCount = 0;
3511  logEntry->UniqueErrorValue = UniqueErrorValue;
3512  logEntry->DumpDataSize = 3;
3513 
3514  logEntry->DumpData[0] = PathId;
3515  logEntry->DumpData[1] = TargetId;
3516  logEntry->DumpData[2] = Lun;
3517 
3518  //
3519  // Write the error log packet.
3520  //
3521 
3522  IoWriteErrorLogEntry(logEntry);
3523  }
3524  }
3525 } // end ClassNotifyFailurePredicted()
_In_ ULONG _In_ BOOLEAN _In_ ULONG UniqueErrorValue
Definition: classpnp.h:1117
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1117
_In_ ULONG _In_ BOOLEAN LogError
Definition: classpnp.h:1117
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1117
NTSTATUS FinalStatus
Definition: iotypes.h:1966
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1117
GUID StoragePredictFailureEventGuid
Definition: autorun.c:35
VOID NTAPI IoWriteErrorLogEntry(IN PVOID ElEntry)
Definition: error.c:620
NTSTATUS ErrorCode
Definition: iotypes.h:1964
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:520
#define BufferSize
Definition: classpnp.h:419
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define IOCTL_STORAGE_PREDICT_FAILURE
Definition: ntddstor.h:135
unsigned int ULONG
Definition: retypes.h:1
#define IO_WRN_FAILURE_PREDICTED
Definition: ntiologc.h:78
return STATUS_SUCCESS
Definition: btrfs.c:2938
NTSTATUS NTAPI ClassWmiFireEvent(IN PDEVICE_OBJECT DeviceObject, IN LPGUID Guid, IN ULONG InstanceIndex, IN ULONG EventDataSize, IN PVOID EventData)
Definition: classwmi.c:721
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52

Referenced by ClassInterpretSenseInfo(), ClasspFailurePredict(), and DiskDetectFailurePrediction().

◆ ClasspDisableTimer()

NTSTATUS NTAPI ClasspDisableTimer ( PDEVICE_OBJECT  DeviceObject)

Definition at line 3285 of file autorun.c.

3288 {
3289  //PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3290  //PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
3291  //PMEDIA_CHANGE_DETECTION_INFO mCDInfo = fdoExtension->MediaChangeDetectionInfo;
3292  //PFAILURE_PREDICTION_INFO fPInfo = fdoExtension->FailurePredictionInfo;
3293  //NTSTATUS status;
3294 
3295  PAGED_CODE();
3296 
3297  if (DeviceObject->Timer != NULL) {
3298 
3299  //
3300  // we are only going to stop the actual timer in remove device routine.
3301  // it is the responsibility of the code within the timer routine to
3302  // check if the device is removed and not processing io for the final
3303  // call.
3304  // this keeps the code clean and prevents lots of bugs.
3305  //
3306 
3307 
3309  DebugPrint((3, "ClasspDisableTimer: Once a second timer disabled "
3310  "for device %p\n", DeviceObject));
3311 
3312  } else {
3313 
3314  DebugPrint((1, "ClasspDisableTimer: Timer never enabled\n"));
3315 
3316  }
3317 
3318  return STATUS_SUCCESS;
3319 } // end ClasspDisableTimer()
#define PAGED_CODE()
Definition: video.h:57
VOID NTAPI IoStopTimer(PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:166
smooth NULL
Definition: ftsmooth.c:416
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by ClassPnpStartDevice(), ClassRemoveDevice(), and ClassSetFailurePredictionPoll().

◆ ClasspEnableTimer()

NTSTATUS NTAPI ClasspEnableTimer ( PDEVICE_OBJECT  DeviceObject)

Definition at line 3234 of file autorun.c.

3237 {
3238  NTSTATUS status;
3239 
3240  PAGED_CODE();
3241 
3242  if (DeviceObject->Timer == NULL) {
3243 
3245 
3246  } else {
3247 
3249 
3250  }
3251 
3252  if (NT_SUCCESS(status)) {
3253 
3255  DebugPrint((1, "ClasspEnableTimer: Once a second timer enabled "
3256  "for device %p\n", DeviceObject));
3257 
3258  }
3259 
3260  DebugPrint((1, "ClasspEnableTimer: Device %p, Status %lx "
3261  "initializing timer\n", DeviceObject, status));
3262 
3263  return status;
3264 
3265 } // end ClasspEnableTimer()
VOID NTAPI IoStartTimer(IN PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:133
LONG NTSTATUS
Definition: precomp.h:26
#define PAGED_CODE()
Definition: video.h:57
VOID NTAPI ClasspTimerTick(PDEVICE_OBJECT DeviceObject, PVOID Context)
Definition: autorun.c:3086
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI IoInitializeTimer(IN PDEVICE_OBJECT DeviceObject, IN PIO_TIMER_ROUTINE TimerRoutine, IN PVOID Context)
Definition: iotimer.c:92
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by ClassPnpStartDevice(), and ClassSetFailurePredictionPoll().

◆ ClasspFailurePredict()

VOID NTAPI ClasspFailurePredict ( IN PDEVICE_OBJECT  DeviceObject,
IN PVOID  Context 
)

Definition at line 3341 of file autorun.c.

3345 {
3348  PIO_WORKITEM workItem;
3349  STORAGE_PREDICT_FAILURE checkFailure;
3350  SCSI_ADDRESS scsiAddress;
3351 
3352  NTSTATUS status;
3353 
3354  ASSERT(info != NULL);
3355 
3356  DebugPrint((1, "ClasspFailurePredict: Polling for failure\n"));
3357 
3358  //
3359  // Mark the work item as inactive and reset the countdown timer. we
3360  // can't risk freeing the work item until we've released the remove-lock
3361  // though - if we do it might get resused as a tag before we can release
3362  // the lock.
3363  //
3364 
3365  InterlockedExchange((PLONG)&info->CountDown, info->Period);
3366  workItem = InterlockedExchangePointer((PVOID*)&info->WorkQueueItem, NULL);
3367 
3368  if (ClasspCanSendPollingIrp(fdoExtension)) {
3369 
3370  KEVENT event;
3371  PDEVICE_OBJECT topOfStack;
3372  PIRP irp = NULL;
3373  IO_STATUS_BLOCK ioStatus;
3374 
3376 
3378 
3379  //
3380  // Send down irp to see if drive is predicting failure
3381  //
3382 
3385  topOfStack,
3386  NULL,
3387  0,
3388  &checkFailure,
3389  sizeof(STORAGE_PREDICT_FAILURE),
3390  FALSE,
3391  &event,
3392  &ioStatus);
3393 
3394 
3395  if (irp != NULL) {
3396  status = IoCallDriver(topOfStack, irp);
3397  if (status == STATUS_PENDING) {
3399  status = ioStatus.Status;
3400  }
3401  } else {
3403  }
3404 
3405  if (NT_SUCCESS(status) && (checkFailure.PredictFailure)) {
3406 
3407  checkFailure.PredictFailure = 512;
3408 
3409  //
3410  // Send down irp to get scsi address
3411  //
3413 
3414  RtlZeroMemory(&scsiAddress, sizeof(SCSI_ADDRESS));
3417  topOfStack,
3418  NULL,
3419  0,
3420  &scsiAddress,
3421  sizeof(SCSI_ADDRESS),
3422  FALSE,
3423  &event,
3424  &ioStatus);
3425 
3426  if (irp != NULL) {
3427  status = IoCallDriver(topOfStack, irp);
3428  if (status == STATUS_PENDING) {
3430  status = ioStatus.Status;
3431  }
3432  }
3433 
3434  ClassNotifyFailurePredicted(fdoExtension,
3435  (PUCHAR)&checkFailure,
3436  sizeof(checkFailure),
3437  (BOOLEAN)(fdoExtension->FailurePredicted == FALSE),
3438  2,
3439  scsiAddress.PathId,
3440  scsiAddress.TargetId,
3441  scsiAddress.Lun);
3442 
3443  fdoExtension->FailurePredicted = TRUE;
3444 
3445  }
3446 
3447  ObDereferenceObject(topOfStack);
3448  }
3449 
3451  IoFreeWorkItem(workItem);
3452  return;
3453 } // end ClasspFailurePredict()
UCHAR PathId
Definition: scsi_port.h:149
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
VOID NTAPI ClassNotifyFailurePredicted(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PUCHAR Buffer, ULONG BufferSize, BOOLEAN LogError, ULONG UniqueErrorValue, UCHAR PathId, UCHAR TargetId, UCHAR Lun)
Definition: autorun.c:3468
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
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
UCHAR TargetId
Definition: scsi_port.h:150
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _cl_event * event
Definition: glext.h:7739
#define InterlockedExchange
Definition: armddk.h:54
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define IOCTL_STORAGE_PREDICT_FAILURE
Definition: ntddstor.h:135
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
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
struct tagContext Context
Definition: acpixf.h:1030
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
signed int * PLONG
Definition: retypes.h:5
static SERVICE_STATUS status
Definition: service.c:31
#define ClasspCanSendPollingIrp(fdoExtension)
Definition: autorun.c:54
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
Definition: ps.c:97

◆ ClasspInitializeGesn()

NTSTATUS NTAPI ClasspInitializeGesn ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN PMEDIA_CHANGE_DETECTION_INFO  Info 
)

Definition at line 1668 of file autorun.c.

1672 {
1675  PSTORAGE_ADAPTER_DESCRIPTOR adapterDescriptor;
1677  PIRP irp;
1678  KEVENT event;
1679  BOOLEAN retryImmediately;
1680  ULONG i;
1681  ULONG atapiResets;
1682 
1683 
1684  PAGED_CODE();
1685  ASSERT(Info == FdoExtension->MediaChangeDetectionInfo);
1686 
1687  //
1688  // read if we already know the abilities of the device
1689  //
1690 
1694  (PULONG)&detectionState);
1695 
1696  if (detectionState == ClassDetectionUnsupported) {
1697  goto ExitWithError;
1698  }
1699 
1700  //
1701  // check if the device has a hack flag saying never to try this.
1702  //
1703 
1704  if (TEST_FLAG(FdoExtension->PrivateFdoData->HackFlags,
1706 
1707  detectionState = ClassDetectionUnsupported;
1712  goto ExitWithError;
1713 
1714  }
1715 
1716 
1717  //
1718  // else go through the process since we allocate buffers and
1719  // get all sorts of device settings.
1720  //
1721 
1722  if (Info->Gesn.Buffer == NULL) {
1725  '??cS');
1726  }
1727  if (Info->Gesn.Buffer == NULL) {
1729  goto ExitWithError;
1730  }
1731  if (Info->Gesn.Mdl != NULL) {
1732  IoFreeMdl(Info->Gesn.Mdl);
1733  }
1734  Info->Gesn.Mdl = IoAllocateMdl(Info->Gesn.Buffer,
1736  FALSE, FALSE, NULL);
1737  if (Info->Gesn.Mdl == NULL) {
1739  goto ExitWithError;
1740  }
1741 
1742  MmBuildMdlForNonPagedPool(Info->Gesn.Mdl);
1743  Info->Gesn.BufferSize = GESN_BUFFER_SIZE;
1744  Info->Gesn.EventMask = 0;
1745 
1746  //
1747  // all items are prepared to use GESN (except the event mask, so don't
1748  // optimize this part out!).
1749  //
1750  // now see if it really works. we have to loop through this because
1751  // many SAMSUNG (and one COMPAQ) drives timeout when requesting
1752  // NOT_READY events, even when the IMMEDIATE bit is set. :(
1753  //
1754  // using a drive list is cumbersome, so this might fix the problem.
1755  //
1756 
1757  adapterDescriptor = FdoExtension->AdapterDescriptor;
1758  atapiResets = 0;
1759  retryImmediately = TRUE;
1760  for (i = 0; (i < 16) && (retryImmediately != FALSE); i++) {
1761 
1763  if (irp == NULL) {
1765  goto ExitWithError;
1766  }
1767 
1768  ASSERT(TEST_FLAG(Info->MediaChangeSrb.SrbFlags, SRB_FLAGS_NO_QUEUE_FREEZE));
1769 
1770  //
1771  // replace the completion routine with a different one this time...
1772  //
1773 
1776  &event,
1777  TRUE, TRUE, TRUE);
1779 
1780  status = IoCallDriver(FdoExtension->CommonExtension.LowerDeviceObject, irp);
1781 
1782  if (status == STATUS_PENDING) {
1784  Executive,
1785  KernelMode,
1786  FALSE,
1787  NULL);
1789  }
1790  ClassReleaseRemoveLock(FdoExtension->DeviceObject, irp);
1791 
1792  if (SRB_STATUS(Info->MediaChangeSrb.SrbStatus) != SRB_STATUS_SUCCESS) {
1793  ClassInterpretSenseInfo(FdoExtension->DeviceObject,
1794  &(Info->MediaChangeSrb),
1795  IRP_MJ_SCSI,
1796  0,
1797  0,
1798  &status,
1799  NULL);
1800  }
1801 
1802  if ((adapterDescriptor->BusType == BusTypeAtapi) &&
1803  (Info->MediaChangeSrb.SrbStatus == SRB_STATUS_BUS_RESET)
1804  ) {
1805 
1806  //
1807  // ATAPI unfortunately returns SRB_STATUS_BUS_RESET instead
1808  // of SRB_STATUS_TIMEOUT, so we cannot differentiate between
1809  // the two. if we get this status four time consecutively,
1810  // stop trying this command. it is too late to change ATAPI
1811  // at this point, so special-case this here. (07/10/2001)
1812  // NOTE: any value more than 4 may cause the device to be
1813  // marked missing.
1814  //
1815 
1816  atapiResets++;
1817  if (atapiResets >= 4) {
1819  goto ExitWithError;
1820  }
1821  }
1822 
1823  if (status == STATUS_DATA_OVERRUN) {
1825  }
1826 
1828  (status == STATUS_TIMEOUT) ||
1831  ) {
1832 
1833  //
1834  // with these error codes, we don't ever want to try this command
1835  // again on this device, since it reacts poorly.
1836  //
1837 
1843  "Classpnp => GESN test failed %x for fdo %p\n",
1844  status, FdoExtension->DeviceObject));
1845  goto ExitWithError;
1846 
1847 
1848  }
1849 
1850  if (!NT_SUCCESS(status)) {
1851 
1852  //
1853  // this may be other errors that should not disable GESN
1854  // for all future start_device calls.
1855  //
1856 
1858  "Classpnp => GESN test failed %x for fdo %p\n",
1859  status, FdoExtension->DeviceObject));
1860  goto ExitWithError;
1861  }
1862 
1863  if (i == 0) {
1864 
1865  //
1866  // the first time, the request was just retrieving a mask of
1867  // available bits. use this to mask future requests.
1868  //
1869 
1870  header = (PNOTIFICATION_EVENT_STATUS_HEADER)(Info->Gesn.Buffer);
1871 
1873  "Classpnp => Fdo %p supports event mask %x\n",
1874  FdoExtension->DeviceObject, header->SupportedEventClasses));
1875 
1876 
1877  if (TEST_FLAG(header->SupportedEventClasses,
1880  "Classpnp => GESN supports MCN\n"));
1881  }
1882  if (TEST_FLAG(header->SupportedEventClasses,
1885  "Classpnp => GESN supports DeviceBusy\n"));
1886  }
1887  Info->Gesn.EventMask = header->SupportedEventClasses;
1888 
1889  //
1890  // realistically, we are only considering the following events:
1891  // EXTERNAL REQUEST - this is being tested for play/stop/etc.
1892  // MEDIA STATUS - autorun and ejection requests.
1893  // DEVICE BUSY - to allow us to predict when media will be ready.
1894  // therefore, we should not bother querying for the other,
1895  // unknown events. clear all but the above flags.
1896  //
1897 
1898  Info->Gesn.EventMask &=
1902 
1903 
1904  //
1905  // HACKHACK - REF #0001
1906  // Some devices will *never* report an event if we've also requested
1907  // that it report lower-priority events. this is due to a
1908  // misunderstanding in the specification wherein a "No Change" is
1909  // interpreted to be a real event. what should occur is that the
1910  // device should ignore "No Change" events when multiple event types
1911  // are requested unless there are no other events waiting. this
1912  // greatly reduces the number of requests that the host must send
1913  // to determine if an event has occurred. Since we must work on all
1914  // drives, default to enabling the hack until we find evidence of
1915  // proper firmware.
1916  //
1917 
1918  if (CountOfSetBitsUChar(Info->Gesn.EventMask) == 1) {
1920  "Classpnp => GESN hack %s for FDO %p\n",
1921  "not required", FdoExtension->DeviceObject));
1922  } else {
1924  "Classpnp => GESN hack %s for FDO %p\n",
1925  "enabled", FdoExtension->DeviceObject));
1926  Info->Gesn.HackEventMask = 1;
1927  }
1928 
1929  } else {
1930 
1931  //
1932  // not the first time looping through, so interpret the results.
1933  //
1934 
1936  (PVOID)Info->Gesn.Buffer,
1937  &retryImmediately);
1938 
1939  }
1940 
1941  } // end loop of GESN requests....
1942 
1943  //
1944  // we can only use this if it can be relied upon for media changes,
1945  // since we are (by definition) no longer going to be polling via
1946  // a TEST_UNIT_READY irp, and drives will not report UNIT ATTENTION
1947  // for this command (although a filter driver, such as one for burning
1948  // cd's, might still fake those errors).
1949  //
1950  // since we also rely upon NOT_READY events to change the cursor
1951  // into a "wait" cursor, we can't use GESN without NOT_READY support.
1952  //
1953 
1954  if (TEST_FLAG(Info->Gesn.EventMask,
1956  TEST_FLAG(Info->Gesn.EventMask,
1958  ) {
1959 
1961  "Classpnp => Enabling GESN support for fdo %p\n",
1962  FdoExtension->DeviceObject));
1963  Info->Gesn.Supported = TRUE;
1964 
1969 
1970  return STATUS_SUCCESS;
1971 
1972  }
1973 
1975  "Classpnp => GESN available but not enabled for fdo %p\n",
1976  FdoExtension->DeviceObject));
1977  goto ExitWithError;
1978 
1979  // fall through...
1980 
1981 ExitWithError:
1982  if (Info->Gesn.Mdl) {
1983  IoFreeMdl(Info->Gesn.Mdl);
1984  Info->Gesn.Mdl = NULL;
1985  }
1986  if (Info->Gesn.Buffer) {
1987  ExFreePool(Info->Gesn.Buffer);
1988  Info->Gesn.Buffer = NULL;
1989  }
1990  Info->Gesn.Supported = 0;
1991  Info->Gesn.EventMask = 0;
1992  Info->Gesn.BufferSize = 0;
1993  return STATUS_NOT_SUPPORTED;
1994 
1995 }
#define SRB_STATUS_BUS_RESET
Definition: srb.h:345
#define TRUE
Definition: types.h:120
* PSTORAGE_ADAPTER_DESCRIPTOR
Definition: ntddstor.h:476
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
#define NOTIFICATION_MEDIA_STATUS_CLASS_MASK
Definition: scsi.h:37
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
#define NOTIFICATION_EXTERNAL_REQUEST_CLASS_MASK
Definition: scsi.h:36
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:428
IO_COMPLETION_ROUTINE ClassSignalCompletion
Definition: classpnp.h:1137
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define NOTIFICATION_DEVICE_BUSY_CLASS_MASK
Definition: scsi.h:39
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define SRB_STATUS(Status)
Definition: srb.h:381
struct TraceInfo Info
#define PAGED_CODE()
Definition: video.h:57
#define KdPrintEx(_x_)
Definition: kdfuncs.h:114
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define IRP_MJ_SCSI
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS NTAPI ClassSetDeviceParameter(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PWSTR SubkeyName OPTIONAL, IN PWSTR ParameterName, IN ULONG ParameterValue)
Definition: utils.c:136
__inline ULONG CountOfSetBitsUChar(UCHAR _X)
Definition: tools.h:150
BOOLEAN NTAPI ClassInterpretSenseInfo(IN PDEVICE_OBJECT Fdo, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status, OUT OPTIONAL ULONG *RetryInterval)
Definition: class.c:2994
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI ClassGetDeviceParameter(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PWSTR SubkeyName OPTIONAL, IN PWSTR ParameterName, IN OUT PULONG ParameterValue)
Definition: utils.c:52
PIRP NTAPI ClasspPrepareMcnIrp(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMEDIA_CHANGE_DETECTION_INFO Info, IN BOOLEAN UseGesn)
Definition: autorun.c:1036
enum _CLASS_DETECTION_STATE CLASS_DETECTION_STATE
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define CLASSP_REG_SUBKEY_NAME
Definition: classp.h:41
struct _cl_event * event
Definition: glext.h:7739
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
#define FDO_HACK_GESN_IS_BAD
Definition: classp.h:54
VOID NTAPI ClasspInterpretGesnData(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PNOTIFICATION_EVENT_STATUS_HEADER Header, IN PBOOLEAN ResendImmediately)
Definition: autorun.c:286
#define CLASSP_REG_MMC_DETECTION_VALUE_NAME
Definition: classp.h:44
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
struct _NOTIFICATION_EVENT_STATUS_HEADER * PNOTIFICATION_EVENT_STATUS_HEADER
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define GESN_BUFFER_SIZE
Definition: autorun.c:29
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
return STATUS_SUCCESS
Definition: btrfs.c:2938
struct CFHEADER header
Definition: fdi.c:101
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
Definition: ps.c:97

Referenced by ClasspInitializePolling().

◆ ClasspInitializePolling()

NTSTATUS NTAPI ClasspInitializePolling ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN BOOLEAN  AllowDriveToSleep 
)

Definition at line 1487 of file autorun.c.

1491 {
1492  PDEVICE_OBJECT fdo = FdoExtension->DeviceObject;
1493  //PCLASS_PRIVATE_FDO_DATA fdoData = FdoExtension->PrivateFdoData;
1494 
1495  //ULONG size;
1497  PIRP irp;
1498 
1499  PAGED_CODE();
1500 
1501  if (FdoExtension->MediaChangeDetectionInfo != NULL) {
1502  return STATUS_SUCCESS;
1503  }
1504 
1508 
1509  if(info != NULL) {
1511 
1512  FdoExtension->KernelModeMcnContext.FileObject = (PVOID)-1;
1513  FdoExtension->KernelModeMcnContext.DeviceObject = (PVOID)-1;
1514  FdoExtension->KernelModeMcnContext.LockCount = 0;
1515  FdoExtension->KernelModeMcnContext.McnDisableCount = 0;
1516 
1517  /*
1518  * Allocate an IRP to carry the Test-Unit-Ready.
1519  * Allocate an extra IRP stack location
1520  * so we can cache our device object in the top location.
1521  */
1522  irp = IoAllocateIrp((CCHAR)(fdo->StackSize+1), FALSE);
1523 
1524  if (irp != NULL) {
1525 
1526  PVOID buffer;
1527 
1532 
1533  if (buffer != NULL) {
1534  PIO_STACK_LOCATION irpStack;
1535  PSCSI_REQUEST_BLOCK srb;
1536  //PCDB cdb;
1537 
1538  srb = &(info->MediaChangeSrb);
1539  info->MediaChangeIrp = irp;
1540  info->SenseBuffer = buffer;
1541 
1542  /*
1543  * For the driver that creates an IRP, there is no 'current' stack location.
1544  * Step down one IRP stack location so that the extra top one
1545  * becomes our 'current' one.
1546  */
1548 
1549  /*
1550  * Cache our device object in the extra top IRP stack location
1551  * so we have it in our completion routine.
1552  */
1553  irpStack = IoGetCurrentIrpStackLocation(irp);
1554  irpStack->DeviceObject = fdo;
1555 
1556  /*
1557  * Now start setting up the next IRP stack location for the call like any driver would.
1558  */
1559  irpStack = IoGetNextIrpStackLocation(irp);
1560  irpStack->Parameters.Scsi.Srb = srb;
1561  info->MediaChangeIrp = irp;
1562 
1563  //
1564  // Initialize the SRB
1565  //
1566 
1567  RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
1568 
1569  //
1570  // Initialize and set up the sense information buffer
1571  //
1572 
1574  srb->SenseInfoBuffer = buffer;
1576 
1577  //
1578  // Set default values for the media change notification
1579  // configuration.
1580  //
1581 
1582  info->MediaChangeCountDown = MEDIA_CHANGE_DEFAULT_TIME;
1583  info->MediaChangeDetectionDisableCount = 0;
1584 
1585  //
1586  // Assume that there is initially no media in the device
1587  // only notify upper layers if there is something there
1588  //
1589 
1590  info->MediaChangeDetectionState = MediaUnknown;
1591 
1592  info->MediaChangeIrpTimeInUse = 0;
1593  info->MediaChangeIrpLost = FALSE;
1594 
1595  //
1596  // setup all extra flags we'll be setting for this irp
1597  //
1598  info->SrbFlags = 0;
1599  if (AllowDriveToSleep) {
1601  }
1605 
1606  KeInitializeMutex(&info->MediaChangeMutex, 0x100);
1607 
1608  //
1609  // It is ok to support media change events on this
1610  // device.
1611  //
1612 
1613  FdoExtension->MediaChangeDetectionInfo = info;
1614 
1615  //
1616  // NOTE: the DeviceType is FILE_DEVICE_CD_ROM even
1617  // when the device supports DVD (no need to
1618  // check for FILE_DEVICE_DVD, as it's not a
1619  // valid check).
1620  //
1621 
1622  if (FdoExtension->DeviceObject->DeviceType == FILE_DEVICE_CD_ROM){
1623 
1624  NTSTATUS status;
1625 
1627  "ClasspInitializePolling: Testing for GESN\n"));
1629  if (NT_SUCCESS(status)) {
1631  "ClasspInitializePolling: GESN available "
1632  "for %p\n", FdoExtension->DeviceObject));
1633  ASSERT(info->Gesn.Supported );
1634  ASSERT(info->Gesn.Buffer != NULL);
1635  ASSERT(info->Gesn.BufferSize != 0);
1636  ASSERT(info->Gesn.EventMask != 0);
1637  // must return here, for ASSERTs to be valid.
1638  return STATUS_SUCCESS;
1639  }
1641  "ClasspInitializePolling: GESN *NOT* available "
1642  "for %p\n", FdoExtension->DeviceObject));
1643  }
1644 
1645  ASSERT(info->Gesn.Supported == 0);
1646  ASSERT(info->Gesn.Buffer == NULL);
1647  ASSERT(info->Gesn.BufferSize == 0);
1648  ASSERT(info->Gesn.EventMask == 0);
1649  info->Gesn.Supported = 0; // just in case....
1650  return STATUS_SUCCESS;
1651  }
1652 
1653  IoFreeIrp(irp);
1654  }
1655 
1656  ExFreePool(info);
1657  }
1658 
1659  //
1660  // nothing to free here
1661  //
1663 
1664 } // end ClasspInitializePolling()
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
LONG NTSTATUS
Definition: precomp.h:26
GLuint buffer
Definition: glext.h:5915
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define PAGED_CODE()
Definition: video.h:57
#define KdPrintEx(_x_)
Definition: kdfuncs.h:114
struct _test_info info[]
Definition: SetCursorPos.c:19
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:107
NTSTATUS NTAPI ClasspInitializeGesn(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMEDIA_CHANGE_DETECTION_INFO Info)
Definition: autorun.c:1668
#define SRB_CLASS_FLAGS_LOW_PRIORITY
Definition: classpnp.h:19
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
char CCHAR
Definition: typedefs.h:50
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
#define SRB_FLAGS_NO_KEEP_AWAKE
Definition: srb.h:404
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID NTAPI KeInitializeMutex(IN PKMUTEX Mutex, IN ULONG Level)
Definition: mutex.c:67
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
UCHAR SenseInfoBufferLength
Definition: srb.h:251
#define CLASS_TAG_MEDIA_CHANGE_DETECTION
Definition: classpnp.h:79
#define MEDIA_CHANGE_DEFAULT_TIME
Definition: cdrom.c:176
_In_ BOOLEAN AllowDriveToSleep
Definition: classpnp.h:1082
PVOID SenseInfoBuffer
Definition: srb.h:256
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2632
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: ps.c:97

Referenced by ClassInitializeMediaChangeDetection(), and ClassInitializeTestUnitPolling().

◆ ClasspInternalSetMediaChangeState()

VOID NTAPI ClasspInternalSetMediaChangeState ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN MEDIA_CHANGE_DETECTION_STATE  NewState,
IN BOOLEAN  KnownStateChange 
)

Definition at line 591 of file autorun.c.

596 {
597 #if DBG
598  PCSTR states[] = {"Unknown", "Present", "Not Present"};
599 #endif
600  MEDIA_CHANGE_DETECTION_STATE oldMediaState;
601  PMEDIA_CHANGE_DETECTION_INFO info = FdoExtension->MediaChangeDetectionInfo;
602  ULONG data;
603  //NTSTATUS status;
604 
605  ASSERT((NewState >= MediaUnknown) && (NewState <= MediaNotPresent));
606 
607  if(info == NULL) {
608  return;
609  }
610 
611  oldMediaState = InterlockedExchange(
612  (PLONG)(&info->MediaChangeDetectionState),
613  (LONG)NewState);
614 
615  if((oldMediaState == MediaUnknown) && (!KnownStateChange)) {
616 
617  //
618  // The media was in an indeterminate state before - don't notify for
619  // this change.
620  //
621 
623  "ClassSetMediaChangeState: State was unknown - this may "
624  "not be a change\n"));
625  return;
626 
627  } else if(oldMediaState == NewState) {
628 
629  //
630  // Media is in the same state it was before.
631  //
632 
633  return;
634  }
635 
636  if(info->MediaChangeDetectionDisableCount != 0) {
637 
639  ("ClassSetMediaChangeState: MCN not enabled, state "
640  "changed from %s to %s\n",
641  states[oldMediaState], states[NewState]));
642  return;
643 
644  }
645 
647  ("ClassSetMediaChangeState: State change from %s to %s\n",
648  states[oldMediaState], states[NewState]));
649 
650  //
651  // make the data useful -- it used to always be zero.
652  //
653  data = FdoExtension->MediaChangeCount;
654 
655  if (NewState == MediaPresent) {
656 
657  DBGTRACE(ClassDebugTrace, ("ClasspInternalSetMediaChangeState: media ARRIVAL"));
659  &GUID_IO_MEDIA_ARRIVAL,
660  sizeof(ULONG),
661  &data);
662 
663  }
664  else if (NewState == MediaNotPresent) {
665 
666  DBGTRACE(ClassDebugTrace, ("ClasspInternalSetMediaChangeState: media REMOVAL"));
668  &GUID_IO_MEDIA_REMOVAL,
669  sizeof(ULONG),
670  &data);
671 
672  } else {
673 
674  //
675  // Don't notify of changed going to unknown.
676  //
677 
678  return;
679  }
680 
681  return;
682 } // end ClasspInternalSetMediaChangeState()
enum _MEDIA_CHANGE_DETECTION_STATE MEDIA_CHANGE_DETECTION_STATE
VOID NTAPI ClasspSendNotification(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN const GUID *Guid, IN ULONG ExtraDataSize, IN PVOID ExtraData)
Definition: autorun.c:173
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define DBGTRACE(dbgTraceLevel, args_in_parens)
Definition: debug.h:136
#define InterlockedExchange
Definition: armddk.h:54
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
unsigned int ULONG
Definition: retypes.h:1
const char * PCSTR
Definition: typedefs.h:51
signed int * PLONG
Definition: retypes.h:5

Referenced by ClassEnableMediaChangeDetection(), and ClasspSetMediaChangeStateEx().

◆ ClasspInterpretGesnData()

VOID NTAPI ClasspInterpretGesnData ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN PNOTIFICATION_EVENT_STATUS_HEADER  Header,
IN PBOOLEAN  ResendImmediately 
)

Definition at line 286 of file autorun.c.

291 {
293  LONG dataLength;
294  LONG requiredLength;
295 
296  info = FdoExtension->MediaChangeDetectionInfo;
297 
298  //
299  // note: don't allocate anything in this routine so that we can
300  // always just 'return'.
301  //
302 
303  *ResendImmediately = FALSE;
304 
305  if (Header->NEA) {
306  return;
307  }
308  if (Header->NotificationClass == NOTIFICATION_NO_CLASS_EVENTS) {
309  return;
310  }
311 
312  //
313  // HACKHACK - REF #0001
314  // This loop is only taken initially, due to the inability to reliably
315  // auto-detect drives that report events correctly at boot. When we
316  // detect this behavior during the normal course of running, we will
317  // disable the hack, allowing more efficient use of the system. This
318  // should occur "nearly" instantly, as the drive should have multiple
319  // events queue'd (ie. power, morphing, media).
320  //
321 
322  if (info->Gesn.HackEventMask) {
323 
324  //
325  // all events use the low four bytes of zero to indicate
326  // that there was no change in status.
327  //
328 
329  UCHAR thisEvent = Header->ClassEventData[0] & 0xf;
330  UCHAR lowestSetBit;
331  UCHAR thisEventBit = (1 << Header->NotificationClass);
332 
333  ASSERT(TEST_FLAG(info->Gesn.EventMask, thisEventBit));
334 
335 
336  //
337  // some bit magic here... this results in the lowest set bit only
338  //
339 
340  lowestSetBit = info->Gesn.EventMask;
341  lowestSetBit &= (info->Gesn.EventMask - 1);
342  lowestSetBit ^= (info->Gesn.EventMask);
343 
344  if (thisEventBit != lowestSetBit) {
345 
346  //
347  // HACKHACK - REF #0001
348  // the first time we ever see an event set that is not the lowest
349  // set bit in the request (iow, highest priority), we know that the
350  // hack is no longer required, as the device is ignoring "no change"
351  // events when a real event is waiting in the other requested queues.
352  //
353 
355  "Classpnp => GESN::NONE: Compliant drive found, "
356  "removing GESN hack (%x, %x)\n",
357  thisEventBit, info->Gesn.EventMask));
358 
359  info->Gesn.HackEventMask = FALSE;
360 
361  } else if (thisEvent == 0) {
362 
363  //
364  // HACKHACK - REF #0001
365  // note: this hack prevents poorly implemented firmware from constantly
366  // returning "No Event". we do this by cycling through the
367  // supported list of events here.
368  //
369 
370  SET_FLAG(info->Gesn.NoChangeEventMask, thisEventBit);
371  CLEAR_FLAG(info->Gesn.EventMask, thisEventBit);
372 
373  //
374  // if we have cycled through all supported event types, then
375  // we need to reset the events we are asking about. else we
376  // want to resend this request immediately in case there was
377  // another event pending.
378  //
379 
380  if (info->Gesn.EventMask == 0) {
381  info->Gesn.EventMask = info->Gesn.NoChangeEventMask;
382  info->Gesn.NoChangeEventMask = 0;
383  } else {
384  *ResendImmediately = TRUE;
385  }
386  return;
387  }
388 
389  } // end if (info->Gesn.HackEventMask)
390 
391  dataLength =
392  (Header->EventDataLength[0] << 8) |
393  (Header->EventDataLength[1] & 0xff);
394  dataLength -= 2;
395  requiredLength = 4; // all events are four bytes
396 
397  if (dataLength < requiredLength) {
399  "Classpnp => GESN returned only %x bytes data for fdo %p\n",
400  dataLength, FdoExtension->DeviceObject));
401  return;
402  }
403  if (dataLength != requiredLength) {
405  "Classpnp => GESN returned too many (%x) bytes data for fdo %p\n",
406  dataLength, FdoExtension->DeviceObject));
407  dataLength = 4;
408  }
409 
410 /*
411  ClasspSendNotification(FdoExtension,
412  &GUID_IO_GENERIC_GESN_EVENT,
413  sizeof(NOTIFICATION_EVENT_STATUS_HEADER) + dataLength,
414  Header)
415 */
416 
417  switch (Header->NotificationClass) {
418 
420 
421  PNOTIFICATION_EXTERNAL_STATUS externalInfo =
422  (PNOTIFICATION_EXTERNAL_STATUS)(Header->ClassEventData);
423  DEVICE_EVENT_EXTERNAL_REQUEST externalData;
424 
425  //
426  // unfortunately, due to time constraints, we will only notify
427  // about keys being pressed, and not released. this makes keys
428  // single-function, but simplifies the code significantly.
429  //
430 
431  if (externalInfo->ExternalEvent !=
433  break;
434  }
435 
436  *ResendImmediately = TRUE;
438  "Classpnp => GESN::EXTERNAL: Event: %x Status %x Req %x\n",
439  externalInfo->ExternalEvent, externalInfo->ExternalStatus,
440  (externalInfo->Request[0] << 8) | externalInfo->Request[1]
441  ));
442 
443  RtlZeroMemory(&externalData, sizeof(DEVICE_EVENT_EXTERNAL_REQUEST));
444  externalData.Version = 1;
445  externalData.DeviceClass = 0;
446  externalData.ButtonStatus = externalInfo->ExternalEvent;
447  externalData.Request =
448  (externalInfo->Request[0] << 8) |
449  (externalInfo->Request[1] & 0xff);
450  KeQuerySystemTime(&(externalData.SystemTime));
452 
453  DBGTRACE(ClassDebugTrace, ("ClasspInterpretGesnData: media DEVICE_EXTERNAL_REQUEST"));
455  &GUID_IO_DEVICE_EXTERNAL_REQUEST,
457  &externalData);
458  return;
459  }
460 
462 
463  PNOTIFICATION_MEDIA_STATUS mediaInfo =
464  (PNOTIFICATION_MEDIA_STATUS)(Header->ClassEventData);
465 
467  break;
468  }
469 
470  *ResendImmediately = TRUE;
472  "Classpnp => GESN::MEDIA: Event: %x Status %x\n",
473  mediaInfo->MediaEvent, mediaInfo->MediaStatus));
474 
475  if ((mediaInfo->MediaEvent == NOTIFICATION_MEDIA_EVENT_NEW_MEDIA) ||
477 
478 
479  if (TEST_FLAG(FdoExtension->DeviceObject->Characteristics,
481  (ClassGetVpb(FdoExtension->DeviceObject) != NULL) &&
482  (ClassGetVpb(FdoExtension->DeviceObject)->Flags & VPB_MOUNTED)
483  ) {
484 
485  SET_FLAG(FdoExtension->DeviceObject->Flags, DO_VERIFY_VOLUME);
486 
487  }
488  InterlockedIncrement((PLONG)&FdoExtension->MediaChangeCount);
490  MediaPresent,
491  FALSE,
492  TRUE);
493 
494  } else if (mediaInfo->MediaEvent == NOTIFICATION_MEDIA_EVENT_MEDIA_REMOVAL) {
495 
498  FALSE,
499  TRUE);
500 
501  } else if (mediaInfo->MediaEvent == NOTIFICATION_MEDIA_EVENT_EJECT_REQUEST) {
502 
504  "Classpnp => GESN Ejection request received!\n"));
506 
507  }
508  break;
509 
510  }
511 
512  case NOTIFICATION_DEVICE_BUSY_CLASS_EVENTS: { // lowest priority events...
513 
514  PNOTIFICATION_BUSY_STATUS busyInfo =
515  (PNOTIFICATION_BUSY_STATUS)(Header->ClassEventData);
517 
518  //
519  // NOTE: we never actually need to immediately retry for these
520  // events: if one exists, the device is busy, and if not,
521  // we still don't want to retry.
522  //
523 
525  break;
526  }
527 
528  //
529  // else we want to report the approximated time till it's ready.
530  //
531 
532  RtlZeroMemory(&busyData, sizeof(DEVICE_EVENT_BECOMING_READY));
533  busyData.Version = 1;
534  busyData.Reason = busyInfo->DeviceBusyStatus;
535  busyData.Estimated100msToReady = (busyInfo->Time[0] << 8) |
536  (busyInfo->Time[1] & 0xff);
537 
539  "Classpnp => GESN::BUSY: Event: %x Status %x Time %x\n",
540  busyInfo->DeviceBusyEvent, busyInfo->DeviceBusyStatus,
541  busyData.Estimated100msToReady
542  ));
543 
544  DBGTRACE(ClassDebugTrace, ("ClasspInterpretGesnData: media BECOMING_READY"));
546  &GUID_IO_DEVICE_BECOMING_READY,
548  &busyData);
549  break;
550  }
551 
552  default: {
553 
554  break;
555 
556  }
557 
558  } // end switch on notification class
559  return;
560 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
PVPB NTAPI ClassGetVpb(IN PDEVICE_OBJECT DeviceObject)
Definition: class.c:8048
#define NOTIFICATION_NO_CLASS_EVENTS
Definition: scsi.h:42
#define TRUE
Definition: types.h:120
USHORT Flags
Definition: iotypes.h:169
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
#define NOTIFICATION_EXTERNAL_EVENT_BUTTON_DOWN
Definition: scsi.h:76
#define NOTIFICATION_MEDIA_EVENT_NEW_MEDIA
Definition: scsi.h:95
ULONG NTAPI KeQueryTimeIncrement(VOID)
Definition: clock.c:153
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
VOID NTAPI ClassSendEjectionNotification(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: autorun.c:139
#define NOTIFICATION_MEDIA_EVENT_MEDIA_CHANGE
Definition: scsi.h:97
#define KdPrintEx(_x_)
Definition: kdfuncs.h:114
struct _test_info info[]
Definition: SetCursorPos.c:19
#define NOTIFICATION_MEDIA_STATUS_CLASS_EVENTS
Definition: scsi.h:46
Definition: Header.h:8
VOID NTAPI ClasspSendNotification(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN const GUID *Guid, IN ULONG ExtraDataSize, IN PVOID ExtraData)
Definition: autorun.c:173
VOID NTAPI ClasspSetMediaChangeStateEx(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN MEDIA_CHANGE_DETECTION_STATE NewState, IN BOOLEAN Wait, IN BOOLEAN KnownStateChange)
Definition: autorun.c:716
long LONG
Definition: pedump.c:60
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define CLEAR_FLAG(Flags, Bit)
Definition: classpnp.h:155
smooth NULL
Definition: ftsmooth.c:416
struct _NOTIFICATION_MEDIA_STATUS * PNOTIFICATION_MEDIA_STATUS
#define NOTIFICATION_MEDIA_EVENT_EJECT_REQUEST
Definition: scsi.h:94
#define NOTIFICATION_MEDIA_EVENT_MEDIA_REMOVAL
Definition: scsi.h:96
int64_t LONGLONG
Definition: typedefs.h:66
struct _NOTIFICATION_EXTERNAL_STATUS * PNOTIFICATION_EXTERNAL_STATUS
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define NOTIFICATION_DEVICE_BUSY_CLASS_EVENTS
Definition: scsi.h:48
#define DBGTRACE(dbgTraceLevel, args_in_parens)
Definition: debug.h:136
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
#define NOTIFICATION_EXTERNAL_REQUEST_CLASS_EVENTS
Definition: scsi.h:45
#define NOTIFICATION_MEDIA_EVENT_NO_CHANGE
Definition: scsi.h:93
#define InterlockedIncrement
Definition: armddk.h:53
#define NOTIFICATION_BUSY_STATUS_NO_EVENT
Definition: scsi.h:117
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _NOTIFICATION_BUSY_STATUS * PNOTIFICATION_BUSY_STATUS
LARGE_INTEGER SystemTime
Definition: ioevent.h:92
signed int * PLONG
Definition: retypes.h:5
#define VPB_MOUNTED
Definition: iotypes.h:1764
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by ClasspInitializeGesn(), and ClasspMediaChangeDetectionCompletion().

◆ ClasspIsMediaChangeDisabledDueToHardwareLimitation()

BOOLEAN NTAPI ClasspIsMediaChangeDisabledDueToHardwareLimitation ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN PUNICODE_STRING  RegistryPath 
)

Definition at line 2337 of file autorun.c.

2341 {
2342  PSTORAGE_DEVICE_DESCRIPTOR deviceDescriptor = FdoExtension->DeviceDescriptor;
2343  OBJECT_ATTRIBUTES objectAttributes;
2344  HANDLE serviceKey = NULL;
2345  RTL_QUERY_REGISTRY_TABLE parameters[2];
2346 
2347  UNICODE_STRING deviceUnicodeString;
2348  ANSI_STRING deviceString;
2349  ULONG mediaChangeNotificationDisabled = FALSE;
2350 
2351  NTSTATUS status;
2352 
2353 
2354  PAGED_CODE();
2355 
2356  //
2357  // open the service key.
2358  //
2359 
2360  InitializeObjectAttributes(&objectAttributes,
2361  RegistryPath,
2363  NULL,
2364  NULL);
2365 
2366  status = ZwOpenKey(&serviceKey,
2367  KEY_READ,
2368  &objectAttributes);
2369 
2371 
2372 
2373  if(!NT_SUCCESS(status)) {
2374 
2375  //
2376  // always take the safe path. if we can't open the service key,
2377  // disable autorun
2378  //
2379 
2380  return TRUE;
2381 
2382  }
2383 
2384  TRY {
2385  //
2386  // Determine if drive is in a list of those requiring
2387  // autorun to be disabled. this is stored in a REG_MULTI_SZ
2388  // named AutoRunAlwaysDisable. this is required as some autochangers
2389  // must load the disc to reply to ChkVerify request, causing them
2390  // to cycle discs continuously.
2391  //
2392 
2393  PWSTR nullMultiSz;
2394  PCSTR vendorId;
2395  PCSTR productId;
2396  PCSTR revisionId;
2397  ULONG length;
2398  ULONG offset;
2399 
2400  deviceString.Buffer = NULL;
2401  deviceUnicodeString.Buffer = NULL;
2402 
2403  //
2404  // there may be nothing to check against
2405  //
2406 
2407  if ((deviceDescriptor->VendorIdOffset == 0) &&
2408  (deviceDescriptor->ProductIdOffset == 0)) {
2409  LEAVE;
2410  }
2411 
2412  length = 0;
2413 
2414  if (deviceDescriptor->VendorIdOffset == 0) {
2415  vendorId = NULL;
2416  } else {
2417  vendorId = (PCSTR) deviceDescriptor + deviceDescriptor->VendorIdOffset;
2418  length = strlen(vendorId);
2419  }
2420 
2421  if ( deviceDescriptor->ProductIdOffset == 0 ) {
2422  productId = NULL;
2423  } else {
2424  productId = (PCSTR) deviceDescriptor + deviceDescriptor->ProductIdOffset;
2425  length += strlen(productId);
2426  }
2427 
2428  if ( deviceDescriptor->ProductRevisionOffset == 0 ) {
2429  revisionId = NULL;
2430  } else {
2431  revisionId = (PCSTR) deviceDescriptor + deviceDescriptor->ProductRevisionOffset;
2432  length += strlen(revisionId);
2433  }
2434 
2435  //
2436  // allocate a buffer for the string
2437  //
2438 
2439  deviceString.Length = (USHORT)( length );
2440  deviceString.MaximumLength = deviceString.Length + 1;
2441  deviceString.Buffer = ExAllocatePoolWithTag( NonPagedPool,
2442  deviceString.MaximumLength,
2444  );
2445  if (deviceString.Buffer == NULL) {
2447  "ClassMediaChangeDisabledForHardware: Unable to alloc "
2448  "string buffer\n" ));
2449  LEAVE;
2450  }
2451 
2452  //
2453  // copy strings to the buffer
2454  //
2455  offset = 0;
2456 
2457  if (vendorId != NULL) {
2458  RtlCopyMemory(deviceString.Buffer + offset,
2459  vendorId,
2460  strlen(vendorId));
2461  offset += strlen(vendorId);
2462  }
2463 
2464  if ( productId != NULL ) {
2465  RtlCopyMemory(deviceString.Buffer + offset,
2466  productId,
2467  strlen(productId));
2468  offset += strlen(productId);
2469  }
2470  if ( revisionId != NULL ) {
2471  RtlCopyMemory(deviceString.Buffer + offset,
2472  revisionId,
2473  strlen(revisionId));
2474  offset += strlen(revisionId);
2475  }
2476 
2477  ASSERT(offset == deviceString.Length);
2478 
2479  deviceString.Buffer[deviceString.Length] = '\0'; // Null-terminated
2480 
2481  //
2482  // convert to unicode as registry deals with unicode strings
2483  //
2484 
2485  status = RtlAnsiStringToUnicodeString( &deviceUnicodeString,
2486  &deviceString,
2487  TRUE
2488  );
2489  if (!NT_SUCCESS(status)) {
2491  "ClassMediaChangeDisabledForHardware: cannot convert "
2492  "to unicode %lx\n", status));
2493  LEAVE;
2494  }
2495 
2496  //
2497  // query the value, setting valueFound to true if found
2498  //
2499 
2500  RtlZeroMemory(parameters, sizeof(parameters));
2501 
2502  nullMultiSz = L"\0";
2504  parameters[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
2505  parameters[0].Name = L"AutoRunAlwaysDisable";
2506  parameters[0].EntryContext = &mediaChangeNotificationDisabled;
2507  parameters[0].DefaultType = REG_MULTI_SZ;
2508  parameters[0].DefaultData = nullMultiSz;
2509  parameters[0].DefaultLength = 0;
2510 
2512  serviceKey,
2513  parameters,
2514  &deviceUnicodeString,
2515  NULL);
2516 
2517  if ( !NT_SUCCESS(status) ) {
2518  LEAVE;
2519  }
2520 
2521  } FINALLY {
2522 
2523  if (deviceString.Buffer != NULL) {
2524  ExFreePool( deviceString.Buffer );
2525  }
2526  if (deviceUnicodeString.Buffer != NULL) {
2527  RtlFreeUnicodeString( &deviceUnicodeString );
2528  }
2529 
2530  ZwClose(serviceKey);
2531  }
2532 
2533  if (mediaChangeNotificationDisabled) {
2534  DebugPrint((ClassDebugMCN, "ClassMediaChangeDisabledForHardware: "
2535  "Device is on disable list\n"));
2536  return TRUE;
2537  }
2538  return FALSE;
2539 
2540 } // end ClasspIsMediaChangeDisabledDueToHardwareLimitation()
#define FINALLY
Definition: classpnp.h:113
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
#define LEAVE
Definition: classpnp.h:112
GLintptr offset
Definition: glext.h:5920
#define TRY(sps, bps)
#define PAGED_CODE()
Definition: video.h:57
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
* PSTORAGE_DEVICE_DESCRIPTOR
Definition: ntddstor.h:457
#define REG_MULTI_SZ
Definition: nt_native.h:1501
smooth NULL
Definition: ftsmooth.c:416
USHORT MaximumLength
Definition: env_spec_w32.h:377
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define CLASS_TAG_AUTORUN_DISABLE
Definition: classpnp.h:77
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
const char * PCSTR
Definition: typedefs.h:51
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS NTAPI ClasspMediaChangeRegistryCallBack(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: autorun.c:2998
Definition: ps.c:97

Referenced by ClassInitializeMediaChangeDetection().

◆ ClasspIsMediaChangeDisabledForClass()

BOOLEAN NTAPI ClasspIsMediaChangeDisabledForClass ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN PUNICODE_STRING  RegistryPath 
)

Definition at line 2569 of file autorun.c.

2573 {
2574  //PSTORAGE_DEVICE_DESCRIPTOR deviceDescriptor = FdoExtension->DeviceDescriptor;
2575 
2576  OBJECT_ATTRIBUTES objectAttributes;
2577  HANDLE serviceKey = NULL;
2578  HANDLE parametersKey = NULL;
2579  RTL_QUERY_REGISTRY_TABLE parameters[3];
2580 
2581  UNICODE_STRING paramStr;
2582  //UNICODE_STRING deviceUnicodeString;
2583  //ANSI_STRING deviceString;
2584 
2585  //
2586  // Default to ENABLING MediaChangeNotification (!)
2587  //
2588 
2589  ULONG mcnRegistryValue = 1;
2590 
2591  NTSTATUS status;
2592 
2593 
2594  PAGED_CODE();
2595 
2596  //
2597  // open the service key.
2598  //
2599 
2600  InitializeObjectAttributes(&objectAttributes,
2601  RegistryPath,
2603  NULL,
2604  NULL);
2605 
2606  status = ZwOpenKey(&serviceKey,
2607  KEY_READ,
2608  &objectAttributes);
2609 
2611 
2612  if(!NT_SUCCESS(status)) {
2613 
2614  //
2615  // return the default value, which is the
2616  // inverse of the registry setting default
2617  // since this routine asks if it's disabled
2618  //
2619 
2620  DebugPrint((ClassDebugMCN, "ClassCheckServiceMCN: Defaulting to %s\n",
2621  (mcnRegistryValue ? "Enabled" : "Disabled")));
2622  return (BOOLEAN)(!mcnRegistryValue);
2623 
2624  }
2625 
2626  RtlZeroMemory(parameters, sizeof(parameters));
2627 
2628  //
2629  // Open the parameters key (if any) beneath the services key.
2630  //
2631 
2632  RtlInitUnicodeString(&paramStr, L"Parameters");
2633 
2634  InitializeObjectAttributes(&objectAttributes,
2635  &paramStr,
2637  serviceKey,
2638  NULL);
2639 
2640  status = ZwOpenKey(&parametersKey,
2641  KEY_READ,
2642  &objectAttributes);
2643 
2644  if (!NT_SUCCESS(status)) {
2645  parametersKey = NULL;
2646  }
2647 
2648 
2649 
2650  //
2651  // Check for the Autorun value.
2652  //
2653 
2654  parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
2655  parameters[0].Name = L"Autorun";
2656  parameters[0].EntryContext = &mcnRegistryValue;
2657  parameters[0].DefaultType = REG_DWORD;
2658  parameters[0].DefaultData = &mcnRegistryValue;
2659  parameters[0].DefaultLength = sizeof(ULONG);
2660 
2662  serviceKey,
2663  parameters,
2664  NULL,
2665  NULL);
2666 
2667  DebugPrint((ClassDebugMCN, "ClassCheckServiceMCN: "
2668  "<Service>/Autorun flag = %d\n", mcnRegistryValue));
2669 
2670  if(parametersKey != NULL) {
2671 
2673  parametersKey,
2674  parameters,
2675  NULL,
2676  NULL);
2677  DebugPrint((ClassDebugMCN, "ClassCheckServiceMCN: "
2678  "<Service>/Parameters/Autorun flag = %d\n",
2679  mcnRegistryValue));
2680  ZwClose(parametersKey);
2681 
2682  }
2683  ZwClose(serviceKey);
2684 
2685  DebugPrint((ClassDebugMCN, "ClassCheckServiceMCN: "
2686  "Autoplay for device %p is %s\n",
2687  FdoExtension->DeviceObject,
2688  (mcnRegistryValue ? "on" : "off")
2689  ));
2690 
2691  //
2692  // return if it is _disabled_, which is the
2693  // inverse of the registry setting
2694  //
2695 
2696  return (BOOLEAN)(!mcnRegistryValue);
2697 } // end ClasspIsMediaChangeDisabledForClass()
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
#define PAGED_CODE()
Definition: video.h:57
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define RTL_REGISTRY_OPTIONAL
Definition: nt_native.h:169
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
#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
Definition: ps.c:97

Referenced by ClassInitializeMediaChangeDetection().

◆ ClasspMcnControl()

NTSTATUS NTAPI ClasspMcnControl ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN PIRP  Irp,
IN PSCSI_REQUEST_BLOCK  Srb 
)

Definition at line 2890 of file autorun.c.

2895 {
2896  PCOMMON_DEVICE_EXTENSION commonExtension =
2898 
2900  PPREVENT_MEDIA_REMOVAL request = Irp->AssociatedIrp.SystemBuffer;
2901 
2902  PFILE_OBJECT fileObject = irpStack->FileObject;
2903  PFILE_OBJECT_EXTENSION fsContext = NULL;
2904 
2906 
2907  PAGED_CODE();
2908 
2909  //
2910  // Check to make sure we have a file object extension to keep track of this
2911  // request. If not we'll fail it before synchronizing.
2912  //
2913 
2914  TRY {
2915 
2916  if(fileObject != NULL) {
2917  fsContext = ClasspGetFsContext(commonExtension, fileObject);
2918  }else if(Irp->RequestorMode == KernelMode) { // && fileObject == NULL
2919  fsContext = &FdoExtension->KernelModeMcnContext;
2920  }
2921 
2922  if (fsContext == NULL) {
2923 
2924  //
2925  // This handle isn't setup correctly. We can't let the
2926  // operation go.
2927  //
2928 
2930  LEAVE;
2931  }
2932 
2933  if(request->PreventMediaRemoval) {
2934 
2935  //
2936  // This is a lock command. Reissue the command in case bus or
2937  // device was reset and the lock was cleared.
2938  //
2939 
2942 
2943  } else {
2944 
2945  if(fsContext->McnDisableCount == 0) {
2947  LEAVE;
2948  }
2949 
2952  }
2953 
2954  } FINALLY {
2955 
2956  Irp->IoStatus.Status = status;
2957 
2958  if(Srb) {
2959  ExFreePool(Srb);
2960  }
2961 
2962  ClassReleaseRemoveLock(FdoExtension->DeviceObject, Irp);
2963  ClassCompleteRequest(FdoExtension->DeviceObject,
2964  Irp,
2965  IO_NO_INCREMENT);
2966  }
2967  return status;
2968 } // end ClasspMcnControl(
PFILE_OBJECT_EXTENSION NTAPI ClasspGetFsContext(IN PCOMMON_DEVICE_EXTENSION CommonExtension, IN PFILE_OBJECT FileObject)
Definition: create.c:969
#define FINALLY
Definition: classpnp.h:113
VOID NTAPI ClassDisableMediaChangeDetection(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: autorun.c:2803
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
#define LEAVE
Definition: classpnp.h:112
#define TRY(sps, bps)
#define PAGED_CODE()
Definition: video.h:57
#define STATUS_INVALID_DEVICE_STATE
Definition: udferr_usr.h:178
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI ClassEnableMediaChangeDetection(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: autorun.c:2718
struct _COMMON_DEVICE_EXTENSION * PCOMMON_DEVICE_EXTENSION
* PFILE_OBJECT
Definition: iotypes.h:1955
#define InterlockedDecrement
Definition: armddk.h:52
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
#define InterlockedIncrement
Definition: armddk.h:53
VOID NTAPI ClassCompleteRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: lock.c:376
Definition: tftpd.h:85
#define IO_NO_INCREMENT
Definition: iotypes.h:566
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
return STATUS_SUCCESS
Definition: btrfs.c:2938
signed int * PLONG
Definition: retypes.h:5
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
Definition: ps.c:97

Referenced by ClassDeviceControl().

◆ ClasspMediaChangeDetectionCompletion()

NTSTATUS NTAPI ClasspMediaChangeDetectionCompletion ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Context 
)

Definition at line 814 of file autorun.c.

819 {
821  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
822  PCLASS_PRIVATE_FDO_DATA fdoData;
824  //PIO_STACK_LOCATION nextIrpStack;
826  BOOLEAN retryImmediately = FALSE;
827 
828  //
829  // Since the class driver created this request, it's completion routine
830  // will not get a valid device object handed in. Use the one in the
831  // irp stack instead
832  //
833 
835  fdoExtension = DeviceObject->DeviceExtension;
836  fdoData = fdoExtension->PrivateFdoData;
837  info = fdoExtension->MediaChangeDetectionInfo;
838 
839  ASSERT(info->MediaChangeIrp != NULL);
841  DBGTRACE(ClassDebugMCN, ("> ClasspMediaChangeDetectionCompletion: Device %p completed MCN irp %p.", DeviceObject, Irp));
842 
843  /*
844  * HACK for IoMega 2GB Jaz drive:
845  * This drive spins down on its own to preserve the media.
846  * When spun down, TUR fails with 2/4/0 (SCSI_SENSE_NOT_READY/SCSI_ADSENSE_LUN_NOT_READY/?).
847  * ClassInterpretSenseInfo would then call ClassSendStartUnit to spin the media up, which defeats the
848  * purpose of the spindown.
849  * So in this case, make this into a successful TUR.
850  * This allows the drive to stay spun down until it is actually accessed again.
851  * (If the media were actually removed, TUR would fail with 2/3a/0 ).
852  * This hack only applies to drives with the CAUSE_NOT_REPORTABLE_HACK bit set; this
853  * is set by disk.sys when HackCauseNotReportableHack is set for the drive in its BadControllers list.
854  */
855  if ((SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) &&
857  (srb->SenseInfoBufferLength >= RTL_SIZEOF_THROUGH_FIELD(SENSE_DATA, AdditionalSenseCode))){
858 
859  PSENSE_DATA senseData = srb->SenseInfoBuffer;
860 
861  if ((senseData->SenseKey == SCSI_SENSE_NOT_READY) &&
864  }
865  }
866 
867 
868  //
869  // use ClassInterpretSenseInfo() to check for media state, and also
870  // to call ClassError() with correct parameters.
871  //
873  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
874 
875  DBGTRACE(ClassDebugMCN, ("ClasspMediaChangeDetectionCompletion - failed - srb status=%s, sense=%s/%s/%s.", DBGGETSRBSTATUSSTR(srb), DBGGETSENSECODESTR(srb), DBGGETADSENSECODESTR(srb), DBGGETADSENSEQUALIFIERSTR(srb)));
876 
878  srb,
879  IRP_MJ_SCSI,
880  0,
881  0,
882  &status,
883  NULL);
884 
885  }
886  else {
887 
889 
890  if (!info->Gesn.Supported) {
891 
892  DBGTRACE(ClassDebugMCN, ("ClasspMediaChangeDetectionCompletion - succeeded and GESN NOT supported, setting MediaPresent."));
893 
894  //
895  // success != media for GESN case
896  //
897 
899 
900  }
901  else {
902  DBGTRACE(ClassDebugMCN, ("ClasspMediaChangeDetectionCompletion - succeeded (GESN supported)."));
903  }
904  }
905 
906  if (info->Gesn.Supported) {
907 
908  if (status == STATUS_DATA_OVERRUN) {
909  DBGTRACE(ClassDebugMCN, ("ClasspMediaChangeDetectionCompletion - Overrun"));
911  }
912 
913  if (!NT_SUCCESS(status)) {
914  DBGTRACE(ClassDebugMCN, ("ClasspMediaChangeDetectionCompletion: GESN failed with status %x", status));
915  } else {
916 
917  //
918  // for GESN, need to interpret the results of the data.
919  // this may also require an immediate retry
920  //
921 
922  if (Irp->IoStatus.Information == 8 ) {
923  ClasspInterpretGesnData(fdoExtension,
924  (PVOID)info->Gesn.Buffer,
925  &retryImmediately);
926  }
927 
928  } // end of NT_SUCCESS(status)
929 
930  } // end of Info->Gesn.Supported
931 
932  //
933  // free port-allocated sense buffer, if any.
934  //
935 
936  if (PORT_ALLOCATED_SENSE(fdoExtension, srb)) {
937  FREE_PORT_ALLOCATED_SENSE_BUFFER(fdoExtension, srb);
938  }
939 
940  //
941  // Remember the IRP and SRB for use the next time.
942  //
943 
945  IoGetNextIrpStackLocation(Irp)->Parameters.Scsi.Srb = srb;
946 
947  //
948  // Reset the MCN timer.
949  //
950 
951  ClassResetMediaChangeTimer(fdoExtension);
952 
953  //
954  // run a sanity check to make sure we're not recursing continuously
955  //
956 
957  if (retryImmediately) {
958 
959  info->MediaChangeRetryCount++;
960  if (info->MediaChangeRetryCount > MAXIMUM_IMMEDIATE_MCN_RETRIES) {
961  ASSERT(!"Recursing too often in MCN?");
962  info->MediaChangeRetryCount = 0;
963  retryImmediately = FALSE;
964  }
965 
966  } else {
967 
968  info->MediaChangeRetryCount = 0;
969 
970  }
971 
972 
973  //
974  // release the remove lock....
975  //
976 
977  {
978  UCHAR uniqueValue;
979  ClassAcquireRemoveLock(DeviceObject, (PIRP)(&uniqueValue));
981 
982 
983  //
984  // set the irp as not in use
985  //
986  {
987  volatile LONG irpWasInUse;
988  irpWasInUse = InterlockedCompareExchange(&info->MediaChangeIrpInUse, 0, 1);
989  #if _MSC_FULL_VER != 13009111 // This compiler always takes the wrong path here.
990  ASSERT(irpWasInUse);
991  #endif
992  }
993 
994  //
995  // now send it again before we release our last remove lock
996  //
997 
998  if (retryImmediately) {
999  ClasspSendMediaStateIrp(fdoExtension, info, 0);
1000  }
1001  else {
1002  DBGTRACE(ClassDebugMCN, ("ClasspMediaChangeDetectionCompletion - not retrying immediately"));
1003  }
1004 
1005  //
1006  // release the temporary remove lock
1007  //
1008 
1009  ClassReleaseRemoveLock(DeviceObject, (PIRP)(&uniqueValue));
1010  }
1011 
1012  DBGTRACE(ClassDebugMCN, ("< ClasspMediaChangeDetectionCompletion"));
1013 
1015 }
UCHAR SenseKey
Definition: cdrw_hw.h:1167
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
PMEDIA_CHANGE_DETECTION_INFO MediaChangeDetectionInfo
Definition: classpnp.h:721
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
_In_ PIRP Irp
Definition: csq.h:116
#define CLASS_SPECIAL_CAUSE_NOT_REPORTABLE_HACK
Definition: scsi_port.h:175
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN LoggedTURFailureSinceLastIO
Definition: classp.h:417
#define InterlockedCompareExchange
Definition: interlocked.h:104
VOID NTAPI ClassSetMediaChangeState(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN MEDIA_CHANGE_DETECTION_STATE NewState, IN BOOLEAN Wait)
Definition: autorun.c:780
#define DBGGETSENSECODESTR(_pSrb)
Definition: debug.h:141
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define MAXIMUM_IMMEDIATE_MCN_RETRIES
Definition: autorun.c:30
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
struct _test_info info[]
Definition: SetCursorPos.c:19
#define IRP_MJ_SCSI
long LONG
Definition: pedump.c:60
#define DBGGETADSENSEQUALIFIERSTR(_pSrb)
Definition: debug.h:143
BOOLEAN NTAPI ClassInterpretSenseInfo(IN PDEVICE_OBJECT Fdo, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status, OUT OPTIONAL ULONG *RetryInterval)
Definition: class.c:2994
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static __inline BOOLEAN PORT_ALLOCATED_SENSE(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: classpnp.h:1244
VOID NTAPI ClassResetMediaChangeTimer(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: autorun.c:1456
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static __inline VOID FREE_PORT_ALLOCATED_SENSE_BUFFER(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: classpnp.h:1255
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:679
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
#define DBGTRACE(dbgTraceLevel, args_in_parens)
Definition: debug.h:136
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
VOID NTAPI ClasspInterpretGesnData(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PNOTIFICATION_EVENT_STATUS_HEADER Header, IN PBOOLEAN ResendImmediately)
Definition: autorun.c:286
#define DBGGETADSENSECODESTR(_pSrb)
Definition: debug.h:142
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
UCHAR SenseInfoBufferLength
Definition: srb.h:251
#define DBGGETSRBSTATUSSTR(_pSrb)
Definition: debug.h:145
PVOID SenseInfoBuffer
Definition: srb.h:256
struct tagContext Context
Definition: acpixf.h:1030
VOID NTAPI ClasspSendMediaStateIrp(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMEDIA_CHANGE_DETECTION_INFO Info, IN ULONG CountDown)
Definition: autorun.c:1215
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
Definition: ps.c:97

Referenced by ClasspPrepareMcnIrp().

◆ ClasspMediaChangeDeviceInstanceOverride()

NTSTATUS NTAPI ClasspMediaChangeDeviceInstanceOverride ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
OUT PBOOLEAN  Enabled 
)

Definition at line 2165 of file autorun.c.

2169 {
2170  HANDLE deviceParameterHandle; // cdrom instance key
2171  HANDLE driverParameterHandle; // cdrom specific key
2172  RTL_QUERY_REGISTRY_TABLE queryTable[3];
2173  OBJECT_ATTRIBUTES objectAttributes;
2174  UNICODE_STRING subkeyName;
2175  NTSTATUS status;
2176  ULONG alwaysEnable;
2177  ULONG alwaysDisable;
2178  ULONG i;
2179 
2180 
2181  PAGED_CODE();
2182 
2183  deviceParameterHandle = NULL;
2184  driverParameterHandle = NULL;
2186  alwaysEnable = FALSE;
2187  alwaysDisable = FALSE;
2188 
2189  TRY {
2190 
2194  &deviceParameterHandle
2195  );
2196  if (!NT_SUCCESS(status)) {
2197 
2198  //
2199  // this can occur when a new device is added to the system
2200  // this is due to cdrom.sys being an 'essential' driver
2201  //
2203  "ClassMediaChangeDeviceInstanceDisabled: "
2204  "Could not open device registry key [%lx]\n", status));
2205  LEAVE;
2206  }
2207 
2209  InitializeObjectAttributes(&objectAttributes,
2210  &subkeyName,
2212  deviceParameterHandle,
2214 
2215  status = ZwCreateKey(&driverParameterHandle,
2216  KEY_READ,
2217  &objectAttributes,
2218  0,
2221  NULL);
2222 
2223  if (!NT_SUCCESS(status)) {
2225  "ClassMediaChangeDeviceInstanceDisabled: "
2226  "subkey could not be created. %lx\n", status));
2227  LEAVE;
2228  }
2229 
2230  //
2231  // Default to not changing autorun behavior, based upon setting
2232  // registryValue to zero.
2233  //
2234 
2235  for (i=0;i<2;i++) {
2236 
2237  RtlZeroMemory(&queryTable[0], sizeof(queryTable));
2238 
2239  queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
2240  queryTable[0].DefaultType = REG_DWORD;
2241  queryTable[0].DefaultLength = 0;
2242 
2243  if (i==0) {
2245  queryTable[0].EntryContext = &alwaysDisable;
2246  queryTable[0].DefaultData = &alwaysDisable;
2247  } else {
2249  queryTable[0].EntryContext = &alwaysEnable;
2250  queryTable[0].DefaultData = &alwaysEnable;
2251  }
2252 
2253  //
2254  // don't care if it succeeds, since we set defaults above
2255  //
2256 
2258  (PWSTR)driverParameterHandle,
2259  queryTable,
2260  NULL,
2261  NULL);
2262  }
2263 
2264  } FINALLY {
2265 
2266  if (driverParameterHandle) ZwClose(driverParameterHandle);
2267  if (deviceParameterHandle) ZwClose(deviceParameterHandle);
2268 
2269  }
2270 
2271  if (alwaysEnable && alwaysDisable) {
2272 
2274  "ClassMediaChangeDeviceInstanceDisabled: %s selected\n",
2275  "Both Enable and Disable set -- DISABLE"));
2278  *Enabled = FALSE;
2279 
2280  } else if (alwaysDisable) {
2281 
2283  "ClassMediaChangeDeviceInstanceDisabled: %s selected\n",
2284  "DISABLE"));
2287  *Enabled = FALSE;
2288 
2289  } else if (alwaysEnable) {
2290 
2292  "ClassMediaChangeDeviceInstanceDisabled: %s selected\n",
2293  "ENABLE"));
2296  *Enabled = TRUE;
2297 
2298  } else {
2299 
2301  "ClassMediaChangeDeviceInstanceDisabled: %s selected\n",
2302  "DEFAULT"));
2304 
2305  }
2306 
2307  return status;
2308 
2309 } // end ClasspMediaChangeDeviceInstanceOverride()
#define FINALLY
Definition: classpnp.h:113
#define TRUE
Definition: types.h:120
#define PLUGPLAY_REGKEY_DEVICE
Definition: iofuncs.h:2738
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
#define LEAVE
Definition: classpnp.h:112
#define TRY(sps, bps)
#define PAGED_CODE()
Definition: video.h:57
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
#define MCN_REG_AUTORUN_ENABLE_INSTANCE_NAME
Definition: autorun.c:33
#define MCN_REG_AUTORUN_DISABLE_INSTANCE_NAME
Definition: autorun.c:32
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define RTL_REGISTRY_HANDLE
Definition: nt_native.h:168
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:4586
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define REG_DWORD
Definition: sdbapi.c:596
static SERVICE_STATUS status
Definition: service.c:31
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define MCN_REG_SUBKEY_NAME
Definition: autorun.c:31
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
Definition: ps.c:97

Referenced by ClassInitializeMediaChangeDetection().

◆ ClasspMediaChangeRegistryCallBack()

NTSTATUS NTAPI ClasspMediaChangeRegistryCallBack ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 2998 of file autorun.c.

3006 {
3007  PULONG valueFound;
3008  PUNICODE_STRING deviceString;
3009  PWSTR keyValue;
3010 
3011  PAGED_CODE();
3013 
3014 
3015  //
3016  // if we have already set the value to true, exit
3017  //
3018 
3019  valueFound = EntryContext;
3020  if ((*valueFound) != 0) {
3021  DebugPrint((ClassDebugMCN, "ClasspMcnRegCB: already set to true\n"));
3022  return STATUS_SUCCESS;
3023  }
3024 
3025  if (ValueLength == sizeof(WCHAR)) {
3026  DebugPrint((ClassDebugError, "ClasspMcnRegCB: NULL string should "
3027  "never be passed to registry call-back!\n"));
3028  return STATUS_SUCCESS;
3029  }
3030 
3031 
3032  //
3033  // if the data is not a terminated string, exit
3034  //
3035 
3036  if (ValueType != REG_SZ) {
3037  return STATUS_SUCCESS;
3038  }
3039 
3040  deviceString = Context;
3041  keyValue = ValueData;
3042  ValueLength -= sizeof(WCHAR); // ignore the null character
3043 
3044  //
3045  // do not compare more memory than is in deviceString
3046  //
3047 
3048  if (ValueLength > deviceString->Length) {
3049  ValueLength = deviceString->Length;
3050  }
3051 
3052  //
3053  // if the strings match, disable autorun
3054  //
3055 
3056  if (RtlCompareMemory(deviceString->Buffer, keyValue, ValueLength) == ValueLength) {
3057  DebugPrint((ClassDebugMCN, "ClasspRegMcnCB: Match found\n"));
3058  DebugPrint((ClassDebugMCN, "ClasspRegMcnCB: DeviceString at %p\n",
3059  deviceString->Buffer));
3060  DebugPrint((ClassDebugMCN, "ClasspRegMcnCB: KeyValue at %p\n",
3061  keyValue));
3062  (*valueFound) = TRUE;
3063  }
3064 
3065  return STATUS_SUCCESS;
3066 } // end ClasspMediaChangeRegistryCallBack()
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
uint16_t * PWSTR
Definition: typedefs.h:54
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4016
#define PAGED_CODE()
Definition: video.h:57
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4004
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
unsigned int * PULONG
Definition: retypes.h:1
struct tagContext Context
Definition: acpixf.h:1030
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define REG_SZ
Definition: layer.c:22

Referenced by ClasspIsMediaChangeDisabledDueToHardwareLimitation().

◆ ClasspPrepareMcnIrp()

PIRP NTAPI ClasspPrepareMcnIrp ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN PMEDIA_CHANGE_DETECTION_INFO  Info,
IN BOOLEAN  UseGesn 
)

Definition at line 1036 of file autorun.c.

1041 {
1042  PSCSI_REQUEST_BLOCK srb;
1043  PIO_STACK_LOCATION irpStack;
1044  PIO_STACK_LOCATION nextIrpStack;
1045  NTSTATUS status;
1046  PCDB cdb;
1047  PIRP irp;
1048  PVOID buffer;
1049 
1050  //
1051  // Setup the IRP to perform a test unit ready.
1052  //
1053 
1054  irp = Info->MediaChangeIrp;
1055 
1056  ASSERT(irp);
1057 
1058  if (irp == NULL) {
1059  return NULL;
1060  }
1061 
1062  //
1063  // don't keep sending this if the device is being removed.
1064  //
1065 
1066  status = ClassAcquireRemoveLock(FdoExtension->DeviceObject, irp);
1067  if (status == REMOVE_COMPLETE) {
1069  return NULL;
1070  }
1071  else if (status == REMOVE_PENDING) {
1072  ClassReleaseRemoveLock(FdoExtension->DeviceObject, irp);
1073  return NULL;
1074  }
1075  else {
1076  ASSERT(status == NO_REMOVE);
1077  }
1078 
1079  irp->IoStatus.Status = STATUS_SUCCESS;
1080  irp->IoStatus.Information = 0;
1081  irp->Flags = 0;
1082  irp->UserBuffer = NULL;
1083 
1084  //
1085  // If the irp is sent down when the volume needs to be
1086  // verified, CdRomUpdateGeometryCompletion won't complete
1087  // it since it's not associated with a thread. Marking
1088  // it to override the verify causes it always be sent
1089  // to the port driver
1090  //
1091 
1092  irpStack = IoGetCurrentIrpStackLocation(irp);
1093  irpStack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
1094 
1095  nextIrpStack = IoGetNextIrpStackLocation(irp);
1097  nextIrpStack->Parameters.Scsi.Srb = &(Info->MediaChangeSrb);
1098 
1099  //
1100  // Prepare the SRB for execution.
1101  //
1102 
1103  srb = nextIrpStack->Parameters.Scsi.Srb;
1104  buffer = srb->SenseInfoBuffer;
1105  RtlZeroMemory(srb, sizeof(SCSI_REQUEST_BLOCK));
1107 
1108 
1109  srb->QueueTag = SP_UNTAGGED;
1111  srb->Length = sizeof(SCSI_REQUEST_BLOCK);
1113  srb->SenseInfoBuffer = buffer;
1114  srb->SrbStatus = 0;
1115  srb->ScsiStatus = 0;
1116  srb->OriginalRequest = irp;
1118 
1119  srb->SrbFlags = FdoExtension->SrbFlags;
1120  SET_FLAG(srb->SrbFlags, Info->SrbFlags);
1121 
1122  srb->TimeOutValue = FdoExtension->TimeOutValue * 2;
1123 
1124  if (srb->TimeOutValue == 0) {
1125 
1126  if (FdoExtension->TimeOutValue == 0) {
1127 
1129  "ClassSendTestUnitIrp: FdoExtension->TimeOutValue "
1130  "is set to zero?! -- resetting to 10\n"));
1131  srb->TimeOutValue = 10 * 2; // reasonable default
1132 
1133  } else {
1134 
1136  "ClassSendTestUnitIrp: Someone set "
1137  "srb->TimeOutValue to zero?! -- resetting to %x\n",
1138  FdoExtension->TimeOutValue * 2));
1139  srb->TimeOutValue = FdoExtension->TimeOutValue * 2;
1140 
1141  }
1142 
1143  }
1144 
1145  if (!UseGesn) {
1146 
1147  srb->CdbLength = 6;
1148  srb->DataTransferLength = 0;
1150  nextIrpStack->Parameters.DeviceIoControl.IoControlCode =
1152  srb->DataBuffer = NULL;
1153  srb->DataTransferLength = 0;
1154  irp->MdlAddress = NULL;
1155 
1156  cdb = (PCDB) &srb->Cdb[0];
1157  cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
1158 
1159  } else {
1160 
1161  ASSERT(Info->Gesn.Buffer);
1162 
1163  srb->TimeOutValue = GESN_TIMEOUT_VALUE; // much shorter timeout for GESN
1164 
1165  srb->CdbLength = 10;
1167  nextIrpStack->Parameters.DeviceIoControl.IoControlCode =
1169  srb->DataBuffer = Info->Gesn.Buffer;
1170  srb->DataTransferLength = Info->Gesn.BufferSize;
1171  irp->MdlAddress = Info->Gesn.Mdl;
1172 
1173  cdb = (PCDB) &srb->Cdb[0];
1174  cdb->GET_EVENT_STATUS_NOTIFICATION.OperationCode =
1176  cdb->GET_EVENT_STATUS_NOTIFICATION.Immediate = 1;
1177  cdb->GET_EVENT_STATUS_NOTIFICATION.EventListLength[0] =
1178  (UCHAR)((Info->Gesn.BufferSize) >> 8);
1179  cdb->GET_EVENT_STATUS_NOTIFICATION.EventListLength[1] =
1180  (UCHAR)((Info->Gesn.BufferSize) & 0xff);
1181  cdb->GET_EVENT_STATUS_NOTIFICATION.NotificationClassRequest =
1182  Info->Gesn.EventMask;
1183 
1184  }
1185 
1188  srb,
1189  TRUE,
1190  TRUE,
1191  TRUE);
1192 
1193  return irp;
1194 
1195 }
#define TRUE
Definition: types.h:120
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
ULONG SrbFlags
Definition: srb.h:252
#define SCSIOP_GET_EVENT_STATUS
Definition: cdrw_hw.h:934
PVOID OriginalRequest
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:271
#define GESN_TIMEOUT_VALUE
Definition: autorun.c:28
#define REMOVE_COMPLETE
Definition: classpnp.h:95
PVOID DataBuffer
Definition: srb.h:255
ULONG DataTransferLength
Definition: srb.h:253
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
UCHAR CdbLength
Definition: srb.h:250
GLuint buffer
Definition: glext.h:5915
UCHAR QueueAction
Definition: srb.h:249
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
ULONG TimeOutValue
Definition: srb.h:254
UCHAR SrbStatus
Definition: srb.h:243
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
struct TraceInfo Info
#define KdPrintEx(_x_)
Definition: kdfuncs.h:114
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define SP_UNTAGGED
Definition: srb.h:225
UCHAR ScsiStatus
Definition: srb.h:244
smooth NULL
Definition: ftsmooth.c:416
union _CDB * PCDB
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
UCHAR QueueTag
Definition: srb.h:248
UCHAR Function
Definition: srb.h:242
USHORT Length
Definition: srb.h:241
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define NO_REMOVE
Definition: classpnp.h:93
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:394
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
#define REMOVE_PENDING
Definition: classpnp.h:94
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
#define IOCTL_SCSI_EXECUTE_NONE
Definition: cdrw_hw.h:1453
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
UCHAR SenseInfoBufferLength
Definition: srb.h:251
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
struct _CDB::_CDB6GENERIC CDB6GENERIC
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
PVOID SenseInfoBuffer
Definition: srb.h:256
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
NTSTATUS NTAPI ClasspMediaChangeDetectionCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: autorun.c:814
struct _CDB::_GET_EVENT_STATUS_NOTIFICATION GET_EVENT_STATUS_NOTIFICATION
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
Definition: ps.c:97

Referenced by ClasspInitializeGesn(), and ClasspSendMediaStateIrp().

◆ ClasspSendMediaStateIrp()

VOID NTAPI ClasspSendMediaStateIrp ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN PMEDIA_CHANGE_DETECTION_INFO  Info,
IN ULONG  CountDown 
)

Definition at line 1215 of file autorun.c.

1220 {
1221  BOOLEAN requestPending = FALSE;
1222  LONG irpInUse;
1223  //LARGE_INTEGER zero;
1224  //NTSTATUS status;
1225 
1226  DBGTRACE(ClassDebugMCN, ("> ClasspSendMediaStateIrp"));
1227 
1228  if (((FdoExtension->CommonExtension.CurrentState != IRP_MN_START_DEVICE) ||
1229  (FdoExtension->DevicePowerState != PowerDeviceD0)
1230  ) &&
1231  (!Info->MediaChangeIrpLost)) {
1232 
1233  //
1234  // the device may be stopped, powered down, or otherwise queueing io,
1235  // so should not timeout the autorun irp (yet) -- set to zero ticks.
1236  // scattered code relies upon this to not prematurely "lose" an
1237  // autoplay irp that was queued.
1238  //
1239 
1240  Info->MediaChangeIrpTimeInUse = 0;
1241  }
1242 
1243  //
1244  // if the irp is not in use, mark it as such.
1245  //
1246 
1247  irpInUse = InterlockedCompareExchange(&Info->MediaChangeIrpInUse, 1, 0);
1248 
1249  if (irpInUse) {
1250 
1251  LONG timeInUse;
1252 
1253  timeInUse = InterlockedIncrement(&Info->MediaChangeIrpTimeInUse);
1254 
1255  DebugPrint((ClassDebugMCN, "ClasspSendMediaStateIrp: irp in use for "
1256  "%x seconds when synchronizing for MCD\n", timeInUse));
1257 
1258  if (Info->MediaChangeIrpLost == FALSE) {
1259 
1260  if (timeInUse > MEDIA_CHANGE_TIMEOUT_TIME) {
1261 
1262  //
1263  // currently set to five minutes. hard to imagine a drive
1264  // taking that long to spin up.
1265  //
1266 
1268  "CdRom%d: Media Change Notification has lost "
1269  "it's irp and doesn't know where to find it. "
1270  "Leave it alone and it'll come home dragging "
1271  "it's stack behind it.\n",
1272  FdoExtension->DeviceNumber));
1273  Info->MediaChangeIrpLost = TRUE;
1274  }
1275  }
1276 
1277  DBGTRACE(ClassDebugMCN, ("< ClasspSendMediaStateIrp - irpInUse"));
1278  return;
1279 
1280  }
1281 
1282  TRY {
1283 
1284  if (Info->MediaChangeDetectionDisableCount != 0) {
1285  DebugPrint((ClassDebugTrace, "ClassCheckMediaState: device %p has "
1286  " detection disabled \n", FdoExtension->DeviceObject));
1287  LEAVE;
1288  }
1289 
1290  if (FdoExtension->DevicePowerState != PowerDeviceD0) {
1291 
1292  if (TEST_FLAG(Info->SrbFlags, SRB_FLAGS_NO_KEEP_AWAKE)) {
1294  "ClassCheckMediaState: device %p is powered "
1295  "down and flags are set to let it sleep\n",
1296  FdoExtension->DeviceObject));
1298  LEAVE;
1299  }
1300 
1301  //
1302  // NOTE: we don't increment the time in use until our power state
1303  // changes above. this way, we won't "lose" the autoplay irp.
1304  // it's up to the lower driver to determine if powering up is a
1305  // good idea.
1306  //
1307 
1309  "ClassCheckMediaState: device %p needs to powerup "
1310  "to handle this io (may take a few extra seconds).\n",
1311  FdoExtension->DeviceObject));
1312 
1313  }
1314 
1315  Info->MediaChangeIrpTimeInUse = 0;
1316  Info->MediaChangeIrpLost = FALSE;
1317 
1318  if (CountDown == 0) {
1319 
1320  PIRP irp;
1321 
1323  "ClassCheckMediaState: timer expired\n"));
1324 
1325  if (Info->MediaChangeDetectionDisableCount != 0) {
1327  "ClassCheckMediaState: detection disabled\n"));
1328  LEAVE;
1329  }
1330 
1331  //
1332  // Prepare the IRP for the test unit ready
1333  //
1334 
1336  Info,
1337  Info->Gesn.Supported);
1338 
1339  //
1340  // Issue the request.
1341  //
1342 
1344  "ClasspSendMediaStateIrp: Device %p getting TUR "
1345  " irp %p\n", FdoExtension->DeviceObject, irp));
1346 
1347  if (irp == NULL) {
1348  LEAVE;
1349  }
1350 
1351 
1352  //
1353  // note: if we send it to the class dispatch routines, there is
1354  // a timing window here (since they grab the remove lock)
1355  // where we'd be removed. ELIMINATE the window by grabbing
1356  // the lock ourselves above and sending it to the lower
1357  // device object directly or to the device's StartIo
1358  // routine (which doesn't acquire the lock).
1359  //
1360 
1361  requestPending = TRUE;
1362 
1363  DBGTRACE(ClassDebugMCN, (" ClasspSendMediaStateIrp - calling IoCallDriver."));
1364  IoCallDriver(FdoExtension->CommonExtension.LowerDeviceObject, irp);
1365  }
1366 
1367  } FINALLY {
1368 
1369  if(requestPending == FALSE) {
1370  irpInUse = InterlockedCompareExchange(&Info->MediaChangeIrpInUse, 0, 1);
1371  #if _MSC_FULL_VER != 13009111 // This compiler always takes the wrong path here.
1372  ASSERT(irpInUse);
1373  #endif
1374  }
1375 
1376  }
1377 
1378  DBGTRACE(ClassDebugMCN, ("< ClasspSendMediaStateIrp"));
1379 
1380  return;
1381 } // end ClasspSendMediaStateIrp()
#define FINALLY
Definition: classpnp.h:113
#define TRUE
Definition: types.h:120
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
#define MEDIA_CHANGE_TIMEOUT_TIME
Definition: classpnp.h:130
#define LEAVE
Definition: classpnp.h:112
#define TRY(sps, bps)
#define InterlockedCompareExchange
Definition: interlocked.h:104
struct TraceInfo Info
long LONG
Definition: pedump.c:60
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI ClassResetMediaChangeTimer(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: autorun.c:1456
PIRP NTAPI ClasspPrepareMcnIrp(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMEDIA_CHANGE_DETECTION_INFO Info, IN BOOLEAN UseGesn)
Definition: autorun.c:1036
#define IRP_MN_START_DEVICE
#define SRB_FLAGS_NO_KEEP_AWAKE
Definition: srb.h:404
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define DBGTRACE(dbgTraceLevel, args_in_parens)
Definition: debug.h:136
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define InterlockedIncrement
Definition: armddk.h:53
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218

Referenced by ClassCheckMediaState(), and ClasspMediaChangeDetectionCompletion().

◆ ClasspSendNotification()

VOID NTAPI ClasspSendNotification ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN const GUID Guid,
IN ULONG  ExtraDataSize,
IN PVOID  ExtraData 
)

Definition at line 173 of file autorun.c.

179 {
181  ULONG requiredSize;
182 
183  requiredSize =
184  (sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION) - sizeof(UCHAR)) +
186 
187  if (requiredSize > 0x0000ffff) {
188  // MAX_USHORT, max total size for these events!
190  "Error sending event: size too large! (%x)\n",
191  requiredSize));
192  return;
193  }
194 
196  requiredSize,
197  'oNcS');
198 
199  //
200  // if none allocated, exit
201  //
202 
203  if (notification == NULL) {
204  return;
205  }
206 
207  //
208  // Prepare and send the request!
209  //
210 
211  RtlZeroMemory(notification, requiredSize);
212  notification->Version = 1;
213  notification->Size = (USHORT)(requiredSize);
214  notification->FileObject = NULL;
215  notification->NameBufferOffset = -1;
216  notification->Event = *Guid;
217  RtlCopyMemory(notification->CustomDataBuffer, ExtraData, ExtraDataSize);
218 
220  notification,
221  NULL, NULL);
222 
224  notification = NULL;
225  return;
226 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _TARGET_DEVICE_CUSTOM_NOTIFICATION TARGET_DEVICE_CUSTOM_NOTIFICATION
_In_ const GUID _In_ ULONG ExtraDataSize
Definition: classpnp.h:1236
#define KdPrintEx(_x_)
Definition: kdfuncs.h:114
static GUID * Guid
Definition: apphelp.c:93
smooth NULL
Definition: ftsmooth.c:416
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned short USHORT
Definition: pedump.c:61
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS NTAPI IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL)
Definition: pnpreport.c:519
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by ClassInterpretSenseInfo(), ClasspInternalSetMediaChangeState(), ClasspInterpretGesnData(), and ClassSendEjectionNotification().

◆ ClasspSetMediaChangeStateEx()

VOID NTAPI ClasspSetMediaChangeStateEx ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN MEDIA_CHANGE_DETECTION_STATE  NewState,
IN BOOLEAN  Wait,
IN BOOLEAN  KnownStateChange 
)

Definition at line 716 of file autorun.c.

722 {
723  PMEDIA_CHANGE_DETECTION_INFO info = FdoExtension->MediaChangeDetectionInfo;
726 
727  DBGTRACE(ClassDebugMCN, ("> ClasspSetMediaChangeStateEx"));
728 
729  //
730  // Reset SMART status on media removal as the old status may not be
731  // valid when there is no media in the device or when new media is
732  // inserted.
733  //
734 
735  if (NewState == MediaNotPresent) {
736 
737  FdoExtension->FailurePredicted = FALSE;
738  FdoExtension->FailureReason = 0;
739 
740  }
741 
742 
743  zero.QuadPart = 0;
744 
745  if(info == NULL) {
746  return;
747  }
748 
749  status = KeWaitForMutexObject(&info->MediaChangeMutex,
750  Executive,
751  KernelMode,
752  FALSE,
753  ((Wait != FALSE) ? NULL : &zero));
754 
755  if(status == STATUS_TIMEOUT) {
756 
757  //
758  // Someone else is in the process of setting the media state
759  //
760 
761  DBGWARN(("ClasspSetMediaChangeStateEx - timed out waiting for mutex"));
762  return;
763  }
764 
765  //
766  // Change the media present state and signal an event, if applicable
767  //
768 
769  ClasspInternalSetMediaChangeState(FdoExtension, NewState, KnownStateChange);
770 
771  KeReleaseMutex(&info->MediaChangeMutex, FALSE);
772 
773  DBGTRACE(ClassDebugMCN, ("< ClasspSetMediaChangeStateEx"));
774 
775  return;
776 } // end ClassSetMediaChangeStateEx()
#define KeWaitForMutexObject
Definition: kefuncs.h:568
LONG NTSTATUS
Definition: precomp.h:26
LONG NTAPI KeReleaseMutex(IN PKMUTEX Mutex, IN BOOLEAN Wait)
Definition: mutex.c:189
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI ClasspInternalSetMediaChangeState(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN MEDIA_CHANGE_DETECTION_STATE NewState, IN BOOLEAN KnownStateChange)
Definition: autorun.c:591
static double zero
Definition: j0_y0.c:96
#define DBGTRACE(dbgTraceLevel, args_in_parens)
Definition: debug.h:136
#define DBGWARN(args_in_parens)
Definition: debug.h:134
static SERVICE_STATUS status
Definition: service.c:31
IN BOOLEAN Wait
Definition: fatprocs.h:1529
Definition: ps.c:97

Referenced by ClasspInterpretGesnData(), and ClassSetMediaChangeState().

◆ ClasspTimerTick()

VOID NTAPI ClasspTimerTick ( PDEVICE_OBJECT  DeviceObject,
PVOID  Context 
)

Definition at line 3086 of file autorun.c.

3090 {
3093  ULONG isRemoved;
3094 
3095  ASSERT(commonExtension->IsFdo);
3096 
3097  //
3098  // Do any media change work
3099  //
3101 
3102  //
3103  // We stop the timer before deleting the device. It's safe to keep going
3104  // if the flag value is REMOVE_PENDING because the removal thread will be
3105  // blocked trying to stop the timer.
3106  //
3107 
3108  ASSERT(isRemoved != REMOVE_COMPLETE);
3109 
3110  //
3111  // This routine is reasonably safe even if the device object has a pending
3112  // remove
3113 
3114  if(!isRemoved) {
3115 
3117 
3118  //
3119  // Do any media change detection work
3120  //
3121 
3122  if (fdoExtension->MediaChangeDetectionInfo != NULL) {
3123 
3124  ClassCheckMediaState(fdoExtension);
3125 
3126  }
3127 
3128  //
3129  // Do any failure prediction work
3130  //
3131  if ((info != NULL) && (info->Method != FailurePredictionNone)) {
3132 
3133  ULONG countDown;
3134  //ULONG active;
3135 
3136  if (ClasspCanSendPollingIrp(fdoExtension)) {
3137 
3138  //
3139  // Synchronization is not required here since the Interlocked
3140  // locked instruction guarantees atomicity. Other code that
3141  // resets CountDown uses InterlockedExchange which is also
3142  // atomic.
3143  //
3144  countDown = InterlockedDecrement((PLONG)&info->CountDown);
3145  if (countDown == 0) {
3146 
3147  DebugPrint((4, "ClasspTimerTick: Send FP irp for %p\n",
3148  DeviceObject));
3149 
3150  if(info->WorkQueueItem == NULL) {
3151 
3152  info->WorkQueueItem =
3153  IoAllocateWorkItem(fdoExtension->DeviceObject);
3154 
3155  if(info->WorkQueueItem == NULL) {
3156 
3157  //
3158  // Set the countdown to one minute in the future.
3159  // we'll try again then in the hopes there's more
3160  // free memory.
3161  //
3162 
3163  DebugPrint((1, "ClassTimerTick: Couldn't allocate "
3164  "item - try again in one minute\n"));
3165  InterlockedExchange((PLONG)&info->CountDown, 60);
3166 
3167  } else {
3168 
3169  //
3170  // Grab the remove lock so that removal will block
3171  // until the work item is done.
3172  //
3173 
3174  ClassAcquireRemoveLock(fdoExtension->DeviceObject,
3175  info->WorkQueueItem);
3176 
3177  IoQueueWorkItem(info->WorkQueueItem,
3180  info);
3181  }
3182 
3183  } else {
3184 
3185  DebugPrint((3, "ClasspTimerTick: Failure "
3186  "Prediction work item is "
3187  "already active for device %p\n",
3188  DeviceObject));
3189 
3190  }
3191  } // end (countdown == 0)
3192 
3193  } else {
3194  //
3195  // If device is sleeping then just rearm polling timer
3196  DebugPrint((4, "ClassTimerTick, SHHHH!!! device is %p is sleeping\n",
3197  DeviceObject));
3198  }
3199 
3200  } // end failure prediction polling
3201 
3202  //
3203  // Give driver a chance to do its own specific work
3204  //
3205 
3206  if (commonExtension->DriverExtension->InitData.ClassTick != NULL) {
3207 
3208  commonExtension->DriverExtension->InitData.ClassTick(DeviceObject);
3209 
3210  } // end device specific tick handler
3211  } // end check for removed
3212 
3214 } // end ClasspTimerTick()
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
PMEDIA_CHANGE_DETECTION_INFO MediaChangeDetectionInfo
Definition: classpnp.h:721
#define REMOVE_COMPLETE
Definition: classpnp.h:95
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
PCLASS_TICK ClassTick
Definition: classpnp.h:528
VOID NTAPI ClassCheckMediaState(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: autorun.c:1404
VOID NTAPI ClasspTimerTick(PDEVICE_OBJECT DeviceObject, PVOID Context)
Definition: autorun.c:3086
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:693
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define InterlockedDecrement
Definition: armddk.h:52
PCLASS_DRIVER_EXTENSION DriverExtension
Definition: classpnp.h:576
#define InterlockedExchange
Definition: armddk.h:54
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
IO_WORKITEM_ROUTINE ClasspFailurePredict
Definition: autorun.c:107
struct _FAILURE_PREDICTION_INFO * FailurePredictionInfo
Definition: classpnp.h:735
CLASS_INIT_DATA InitData
Definition: classpnp.h:556
unsigned int ULONG
Definition: retypes.h:1
signed int * PLONG
Definition: retypes.h:5
#define ClasspCanSendPollingIrp(fdoExtension)
Definition: autorun.c:54
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212

Referenced by ClasspEnableTimer().

◆ ClassResetMediaChangeTimer()

VOID NTAPI ClassResetMediaChangeTimer ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension)

Definition at line 1456 of file autorun.c.

1459 {
1460  PMEDIA_CHANGE_DETECTION_INFO info = FdoExtension->MediaChangeDetectionInfo;
1461 
1462  if(info != NULL) {
1463  InterlockedExchange(&(info->MediaChangeCountDown),
1465  }
1466  return;
1467 } // end ClassResetMediaChangeTimer()
smooth NULL
Definition: ftsmooth.c:416
#define InterlockedExchange
Definition: armddk.h:54
#define MEDIA_CHANGE_DEFAULT_TIME
Definition: cdrom.c:176

Referenced by CdRomStartIo(), ClassEnableMediaChangeDetection(), ClasspMediaChangeDetectionCompletion(), and ClasspSendMediaStateIrp().

◆ ClassSendEjectionNotification()

VOID NTAPI ClassSendEjectionNotification ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension)

Definition at line 139 of file autorun.c.

142 {
143  //
144  // For post-NT5.1 work, need to move EjectSynchronizationEvent
145  // to be a MUTEX so we can attempt to grab it here and benefit
146  // from deadlock detection. This will allow checking if the media
147  // has been locked by programs before broadcasting these events.
148  // (what's the point of broadcasting if the media is not locked?)
149  //
150  // This would currently only be a slight optimization. For post-NT5.1,
151  // it would allow us to send a single PERSISTENT_PREVENT to MMC devices,
152  // thereby cleaning up a lot of the ejection code. Then, when the
153  // ejection request occured, we could see if any locks for the media
154  // existed. if locked, broadcast. if not, we send the eject irp.
155  //
156 
157  //
158  // for now, just always broadcast. make this a public routine,
159  // so class drivers can add special hacks to broadcast this for their
160  // non-MMC-compliant devices also from sense codes.
161  //
162 
163  DBGTRACE(ClassDebugTrace, ("ClassSendEjectionNotification: media EJECT_REQUEST"));
165  &GUID_IO_MEDIA_EJECT_REQUEST,
166  0,
167  NULL);
168  return;
169 }
VOID NTAPI ClasspSendNotification(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN const GUID *Guid, IN ULONG ExtraDataSize, IN PVOID ExtraData)
Definition: autorun.c:173
smooth NULL
Definition: ftsmooth.c:416
#define DBGTRACE(dbgTraceLevel, args_in_parens)
Definition: debug.h:136

Referenced by ClassInterpretSenseInfo(), and ClasspInterpretGesnData().

◆ ClassSetFailurePredictionPoll()

NTSTATUS NTAPI ClassSetFailurePredictionPoll ( PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
FAILURE_PREDICTION_METHOD  FailurePredictionMethod,
ULONG  PollingPeriod 
)

Definition at line 3552 of file autorun.c.

3557 {
3559  NTSTATUS status;
3560  //DEVICE_POWER_STATE powerState;
3561 
3562  PAGED_CODE();
3563 
3564  if (FdoExtension->FailurePredictionInfo == NULL) {
3565 
3567 
3569  sizeof(FAILURE_PREDICTION_INFO),
3571 
3572  if (info == NULL) {
3573 
3575 
3576  }
3577 
3579 
3580  info->WorkQueueItem = NULL;
3582 
3583  } else {
3584 
3585  //
3586  // FaultPrediction has not been previously initialized, nor
3587  // is it being initialized now. No need to do anything.
3588  //
3589  return STATUS_SUCCESS;
3590 
3591  }
3592 
3593  FdoExtension->FailurePredictionInfo = info;
3594 
3595  } else {
3596 
3597  info = FdoExtension->FailurePredictionInfo;
3598 
3599  }
3600 
3601  KeWaitForSingleObject(&info->Event,
3602  UserRequest,
3603  UserMode,
3604  FALSE,
3605  NULL);
3606 
3607 
3608  //
3609  // Reset polling period and counter. Setup failure detection type
3610  //
3611 
3612  if (PollingPeriod != 0) {
3613 
3615 
3616  }
3617 
3618  InterlockedExchange((PLONG)&info->CountDown, info->Period);
3619 
3620  info->Method = FailurePredictionMethod;
3622 
3623  status = ClasspEnableTimer(FdoExtension->DeviceObject);
3624 
3625  if (NT_SUCCESS(status)) {
3626  DebugPrint((3, "ClassEnableFailurePredictPoll: Enabled for "
3627  "device %p\n", FdoExtension->DeviceObject));
3628  }
3629 
3630  } else {
3631 
3632  status = ClasspDisableTimer(FdoExtension->DeviceObject);
3633  DebugPrint((3, "ClassEnableFailurePredictPoll: Disabled for "
3634  "device %p\n", FdoExtension->DeviceObject));
3636 
3637  }
3638 
3639  KeSetEvent(&info->Event, IO_NO_INCREMENT, FALSE);
3640 
3641  return status;
3642 } // end ClassSetFailurePredictionPoll()
NTSTATUS NTAPI ClasspEnableTimer(PDEVICE_OBJECT DeviceObject)
Definition: autorun.c:3234
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
#define CLASS_TAG_FAILURE_PREDICT
Definition: classpnp.h:84
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define PAGED_CODE()
Definition: video.h:57
struct _test_info info[]
Definition: SetCursorPos.c:19
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define InterlockedExchange
Definition: armddk.h:54
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
_In_ FAILURE_PREDICTION_METHOD _In_ ULONG PollingPeriod
Definition: classpnp.h:1108
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define DEFAULT_FAILURE_PREDICTION_PERIOD
Definition: classpnp.h:186
NTSTATUS NTAPI ClasspDisableTimer(PDEVICE_OBJECT DeviceObject)
Definition: autorun.c:3285
#define IO_NO_INCREMENT
Definition: iotypes.h:566
_In_ FAILURE_PREDICTION_METHOD FailurePredictionMethod
Definition: classpnp.h:1108
return STATUS_SUCCESS
Definition: btrfs.c:2938
signed int * PLONG
Definition: retypes.h:5
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

Referenced by DiskEnableDisableFailurePredictPolling().

◆ ClassSetMediaChangeState()

VOID NTAPI ClassSetMediaChangeState ( IN PFUNCTIONAL_DEVICE_EXTENSION  FdoExtension,
IN MEDIA_CHANGE_DETECTION_STATE  NewState,
IN BOOLEAN  Wait 
)

Definition at line 780 of file autorun.c.

785 {
787  return;
788 }
VOID NTAPI ClasspSetMediaChangeStateEx(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN MEDIA_CHANGE_DETECTION_STATE NewState, IN BOOLEAN Wait, IN BOOLEAN KnownStateChange)
Definition: autorun.c:716
IN BOOLEAN Wait
Definition: fatprocs.h:1529

Referenced by ClassInterpretSenseInfo(), and ClasspMediaChangeDetectionCompletion().

Variable Documentation

◆ BreakOnMcnDisable

ULONG BreakOnMcnDisable = FALSE

Definition at line 2799 of file autorun.c.

◆ ClasspFailurePredict

IO_WORKITEM_ROUTINE ClasspFailurePredict

Definition at line 107 of file autorun.c.

Referenced by ClasspTimerTick().

◆ StoragePredictFailureEventGuid

GUID StoragePredictFailureEventGuid = WMI_STORAGE_PREDICT_FAILURE_EVENT_GUID

Definition at line 35 of file autorun.c.

Referenced by ClassNotifyFailurePredicted().