146 :4152)
147
148
151GesnDataInterpret(
155 )
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210{
214 LONG requiredLength = 0;
216
218
219
220
221 *ResendImmediately =
FALSE;
222
224 {
226 }
228 {
230 }
231
232
233
234
235
236
237
238
239 if (
info->Gesn.HackEventMask)
240 {
241
242
245 UCHAR thisEventBit = (1 <<
Header->NotificationClass);
246
248 {
249
251 }
252
253
254 lowestSetBit =
info->Gesn.EventMask;
255 lowestSetBit &= (
info->Gesn.EventMask - 1);
256 lowestSetBit ^= (
info->Gesn.EventMask);
257
258 if (thisEventBit != lowestSetBit)
259 {
260
261
262
263
264
266 "GESN::NONE: Compliant drive found, "
267 "removing GESN hack (%x, %x)\n",
268 thisEventBit,
info->Gesn.EventMask));
269
271 }
272 else if (thisEvent == 0)
273 {
274
275
276
277
280
281
282
283
284
285 if (
info->Gesn.EventMask == 0)
286 {
287 info->Gesn.EventMask =
info->Gesn.NoChangeEventMask;
288 info->Gesn.NoChangeEventMask = 0;
289 }
290 else
291 {
292 *ResendImmediately =
TRUE;
293 }
295 }
296
297 }
298
300 (
Header->EventDataLength[1] & 0xff);
302 requiredLength = 4;
303
305 {
307 "error - GESN returned only %x bytes data for fdo %p\n",
309
311 }
312
314 {
316 "error - GESN returned too many (%x) bytes data for fdo %p\n",
318 }
319
320 if ((
Header->ClassEventData[0] & 0xf) == 0)
321 {
322
324 }
325
326
327
328 *ResendImmediately =
TRUE;
329
330 switch (
Header->NotificationClass)
331 {
332
334 {
338
340 {
341 break;
342 }
343
344 event = (opChangeInfo->
Operation[0] << 8) |
346
347
348
349
350
351
352 if (
info->MediaChangeRetryCount >= 4)
353 {
354
355
356
357
358
359
360
361
362
363
364
365
366 static UCHAR const OpChangeMask = 0x02;
367
368
369
370
371
373 "GESN OpChange events are broken. Working around this problem in software (for WDFDEVICE %p)\n",
374 DeviceExtension->Device));
375
376
378
379
380
384
385
386
387 if (
info->Gesn.EventMask == 0)
388 {
389 info->Gesn.EventMask =
info->Gesn.NoChangeEventMask;
390 info->Gesn.NoChangeEventMask = 0;
391 *ResendImmediately =
FALSE;
392 }
393 else
394 {
395 *ResendImmediately =
TRUE;
396 }
397
398 break;
399 }
400
401
404 {
406 "GESN says features added/changed for WDFDEVICE %p\n",
407 DeviceExtension->Device));
408
409
410
411
413 {
415 }
416
417
418
419
420 {
425
428
434
437
440
441 if (DeviceExtension->DeviceAdditionalData.ErrorHandler)
442 {
443 DeviceExtension->DeviceAdditionalData.ErrorHandler(DeviceExtension,
444 &srb,
445 &tempStatus,
446 &retry);
447 }
448 }
449
450 }
451 break;
452 }
453
455 {
459
460
461
462
464 {
465 break;
466 }
467
469 "GESN::EXTERNAL: Event: %x Status %x Req %x\n",
472 ));
473
478 (externalInfo->
Request[1] & 0xff);
481
483 &GUID_IO_DEVICE_EXTERNAL_REQUEST,
485 &externalData);
486
488 }
489
491 {
494
497 {
499 "GESN::MEDIA ARRIVAL, Status %x\n",
501
503 {
505 }
509
510
511
512 if ((DeviceExtension->ZeroPowerODDInfo !=
NULL) &&
514 (DeviceExtension->ZeroPowerODDInfo->Load == 0))
515 {
517 "GesnDataInterpret: MediaArrival event detected, device marked as active\n"));
518
519 DeviceMarkActive(DeviceExtension,
TRUE,
FALSE);
520 }
521 }
523 {
525 "GESN::MEDIA REMOVAL, Status %x\n",
527
531
532
533
534 if ((DeviceExtension->ZeroPowerODDInfo !=
NULL) &&
536 (DeviceExtension->ZeroPowerODDInfo->Load == 0))
537 {
539 "GesnDataInterpret: MediaRemoval event detected, device marked as idle\n"));
540
541 DeviceMarkActive(DeviceExtension,
FALSE,
FALSE);
542 }
543 }
545 {
547 "GESN::MEDIA EJECTION, Status %x\n",
549
551 &GUID_IO_MEDIA_EJECT_REQUEST,
552 0,
554 }
555
556 break;
557 }
558
560 {
564
565
569 (busyInfo->
Time[1] & 0xff);
570
572 "GESN::BUSY: Event: %x Status %x Time %x\n",
575 ));
576
577
579 {
581 "GesnDataInterpret: media BECOMING_READY\n"));
582
584 &GUID_IO_DEVICE_BECOMING_READY,
586 &busyData);
587 }
588
589
590
591 if ((DeviceExtension->ZeroPowerODDInfo !=
NULL) &&
593 (DeviceExtension->ZeroPowerODDInfo->Load == 0) &&
596 {
597 inHomePosition = DeviceZPODDIsInHomePosition(DeviceExtension);
598
599 if (inHomePosition ==
FALSE)
600 {
602 "GesnDataInterpret: LoChange event detected, device marked as active\n"));
603
604 DeviceMarkActive(DeviceExtension,
TRUE,
FALSE);
605 }
606 else
607 {
609 "GesnDataInterpret: LoChange event detected, device marked as idle\n"));
610
611 DeviceMarkActive(DeviceExtension,
FALSE,
FALSE);
612 }
613 }
614
615 break;
616 }
617
618 default:
619 {
620 break;
621 }
622
623 }
624
626}
VOID DeviceSetMediaChangeStateEx(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ MEDIA_CHANGE_DETECTION_STATE NewState, _Inout_opt_ PMEDIA_CHANGE_DETECTION_STATE OldState)
#define GESN_DEVICE_BUSY_LOWER_THRESHOLD_100_MS
FORCEINLINE BOOLEAN IsVolumeMounted(_In_ PDEVICE_OBJECT DeviceObject)
#define TEST_FLAG(Flags, Bit)
#define CLEAR_FLAG(Flags, Bit)
FORCEINLINE ULONG CountOfSetBitsUChar(UCHAR _X)
VOID DeviceSendNotification(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ const GUID *Guid, _In_ ULONG ExtraDataSize, _In_opt_ PVOID ExtraData)
#define SET_FLAG(Flags, Bit)
struct _SENSE_DATA SENSE_DATA
#define SCSI_SENSE_UNIT_ATTENTION
#define SCSI_ADSENSE_MEDIUM_CHANGED
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define SRB_STATUS_AUTOSENSE_VALID
#define _IRQL_requires_max_(irql)
#define KeQuerySystemTime(t)
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
ULONG NTAPI KeQueryTimeIncrement(VOID)
#define STATUS_DEVICE_PROTOCOL_ERROR
#define STATUS_MEDIA_CHANGED
#define NOTIFICATION_DEVICE_BUSY_CLASS_EVENTS
#define NOTIFICATION_MEDIA_EVENT_MEDIA_CHANGE
struct _NOTIFICATION_OPERATIONAL_STATUS * PNOTIFICATION_OPERATIONAL_STATUS
struct _NOTIFICATION_EXTERNAL_STATUS * PNOTIFICATION_EXTERNAL_STATUS
#define NOTIFICATION_MEDIA_EVENT_NEW_MEDIA
#define NOTIFICATION_OPERATIONAL_OPCODE_FEATURE_CHANGE
#define NOTIFICATION_BUSY_EVENT_LO_CHANGE
#define NOTIFICATION_NO_CLASS_EVENTS
#define NOTIFICATION_EXTERNAL_EVENT_BUTTON_DOWN
#define LOADING_MECHANISM_CADDY
#define NOTIFICATION_BUSY_STATUS_NO_EVENT
struct _NOTIFICATION_MEDIA_STATUS * PNOTIFICATION_MEDIA_STATUS
#define NOTIFICATION_MEDIA_EVENT_EJECT_REQUEST
#define NOTIFICATION_MEDIA_STATUS_CLASS_EVENTS
struct _NOTIFICATION_BUSY_STATUS * PNOTIFICATION_BUSY_STATUS
#define NOTIFICATION_EXTERNAL_REQUEST_CLASS_EVENTS
#define NOTIFICATION_MEDIA_EVENT_MEDIA_REMOVAL
#define LOADING_MECHANISM_TRAY
#define NOTIFICATION_OPERATIONAL_OPCODE_FEATURE_ADDED
#define NOTIFICATION_OPERATIONAL_CHANGE_CLASS_EVENTS
#define NOTIFICATION_OPERATIONAL_EVENT_CHANGE_REQUESTED
#define TRACE_LEVEL_WARNING
#define TRACE_LEVEL_ERROR
#define TRACE_LEVEL_INFORMATION
ULONG Estimated100msToReady
UCHAR SenseInfoBufferLength
UCHAR AdditionalSenseLength
UCHAR AdditionalSenseCode