There was an article in the last month’s hardware newsletter on
“Creating a Better End-User Experience: Avoiding the Unsafe Removal
Dialog”. Here are the excerpts from the article:
In Windows 2000 if a device driver does not explicitly tell the
operating system that it can tolerate surprise removal, the operating
system displays the following notifications:
* Unplug/Eject icon in the taskbar tray
* Unsafe Removal dialog when a bus driver reports surprise removal
of a device
In Windows Whistler if a device driver does not explicitly tell the
operating system that it can tolerate surprise removal the operating
system:
* Displays the Unplug/Eject icon in the taskbar tray
* Does not display the Unsafe Removal dialog when a bus driver
reports the surprise removal of a device
The Unsafe Removal dialog is not displayed in Windows Whistler because
testing has shown that this popup does not impact user behavior. That
is, it does not prevent end users from surprise removing hardware. End
user input has suggested that the Unsafe Removal dialog detracts from
the user experience. However, Windows Whistler preserves the
Unplug/Eject icon in the task tray so users can still access the applet
to stop devices before removal.
In Windows 2000, end users can avoid the Unsafe Removal dialog by first
stopping the device by selecting the Unplug/Eject icon in the taskbar
tray, and then unplugging the hardware. However, when the user has a
device that can be safely surprised removed, making the user go through
this process is an unnecessary burden. Instead, drivers for USB or IEEE
1394 devices that don’t maintain a persistent state should inform the
operating systems that they are able to safely tolerate a surprise
removal.
In Windows Whistler, although the Unsafe Removal dialog is not presented
upon surprise removal of hardware, it is still important to inform the
operating system that a device is able to safely tolerate a surprise
remove in appropriate cases. Conveying this information prevents the
operating system from unnecessarily displaying the Unplug/Eject icon in
the taskbar. Any reduction in the number of icons in the taskbar
improves the end user experience.
Device drivers indicate their ability to tolerate surprise removal by
setting the SurpriseRemovalOK field in the DeviceCapabilities structure
to TRUE in response to the IRP_MN_QUERY_CAPABILITIES Plug and Play IRP.
According to the Plug and Play rule, drivers should set the
SurpriseRemovalOK field in the IRP_MN_QURERY_CAPABILITIES IRP before
passing the IRP to the lower drivers in the devnode. Because the Windows
2000 USB hub driver erroneously resets this field to FALSE, Windows 2000
drivers for USB devices must set the SurpriseRemovalOK field on the way
up, as demonstrated in the sample code in this paper. Drivers for
non-USB devices or drivers that will only run under Windows Whistler
should set the SurpriseRemovalOK field on the way down.
//
// Sample code taken from PnP Dispatch Routine
//
case IRP_MN_QUERY_CAPABILITIES:
{
PIO_STACK_LOCATION IrpSp;
//
// Set the SurpiseremovalOK capability to true becase this device
// can safely tolerate suprise remove, and we want to avoid the unsafe
device
// removal UI
//
IrpSp = IoGetCurrentIrpStackLocation(Irp);
IrpSp->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK =
TRUE;
if (!IoIsWdmVersionAvailable(1, 0x20) /* & this is a for USB device
*/) {
//
// Reset the SurpriseRemovalOK capabilty back to TRUE when the IRP
is on
// the way back up to work around a bug in Windows 2000 USB hub
driver that
// incorrectly sets this capabilty to FALSE
//
// NOTE: IoIsWdmVersionAvailable(1, 0x20) returns TRUE on o/s after
// Windows 2000 & Windows Millennium Edition
//
KEVENT QueryCapabilitiesEvent;
KeInitializeEvent(&QueryCapabilitiesEvent,
SynchronizationEvent,
FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp,
SIdriverDispatchPnpComplete,
&QueryCapabilitiesEvent,
TRUE,
TRUE,
TRUE);
status = IoCallDriver(fdoData->NextLowerDriver, Irp);
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&QueryCapabilitiesEvent,
Executive,
KernelMode,
FALSE,
NULL);
status = Irp->IoStatus.Status;
}
IrpSp = IoGetCurrentIrpStackLocation(Irp);
IrpSp->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK=TRU
E;
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
} else {
//
// WDM version is 2.0 or newer (or this is not a USB driver)
// so assume the bus driver will not erronously reset the
SurpiseRemovalOK
// capapbility and just pass the IRP down
//
IoSkipCurrentIrpStackLocation (Irp);
status = IoCallDriver (fdoData->NextLowerDriver, Irp);
}
SIdriverIoDecrement(fdoData);
return status;
break;
}
//
// PnP Dipatch Routine continues…
//
NTSTATUS
SIdriverDispatchPnpComplete (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++
Routine Description:
The lower-level drivers completed the pnp IRP.
Signal this to whoever registered us.
Arguments:
DeviceObject - pointer to a device object.
Irp - pointer to an I/O Request Packet.
Context - pointer to the event to be signaled.
Return Value:
NT status code
–*/
{
PKEVENT event = (PKEVENT)Context;
UNREFERENCED_PARAMETER (DeviceObject);
//
// Wait for lower drivers to be done with the IRP.
// Important thing to note here is when you allocate
// the memory for an event in the stack you must do a
// KernelMode wait instead of UserMode to prevent
// the stack from getting paged out.
//
KeSetEvent (event, IO_NO_INCREMENT, FALSE);
//
// Take the IRP back so that we can continue using it during
// the dispatch routine.
// NB: The dispatch routine will have to call IoCompleteRequest
//
return STATUS_MORE_PROCESSING_REQUIRED;
}
Additionally, there are cases where devices that don’t use persistent
storage are not as safe to surprise remove. An example of this would be
surprise removing a PCMCIA card; in rare cases hardware limitations
could cause this removal to crash the PCI bus. For this reason, the
PCMCIA bus driver sets the SurpiseRemovalOK field to FALSE for all
PCMCIA cards.
Recall that all Plug and Play drivers need to support the
IRP_MN_SURPISE_REMOVAL Plug and Play IRP, regardless of the
SupriseRemovalOK setting. Even PCI devices can tolerate surprise removal
if they are included in a docking station. Drivers for all PCI devices
included in a docking station will receive an IRP_MN_SURPRISE_REMOVAL
IRP if the mobile PC is undocked while the operating system is running.
Please consult the Windows 2000 DDK documentation and the toaster
function driver in the toaster sample package in the Windows 2000 DDK
for details regarding the correct handling the IRP_MN_SURPRISE_REMOVAL
IRP.
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com