Unsafe Removal of Device Window in Windows2000

Question: We have just about completed two custom designs that are using the EZ-USB AN21xx parts. We have one remaining issue that we have not been able to figure out how to resolve. When we remove the USB cable from Win2000 we get the enclosed Unsafe Removal window. We do not get this message when we are running Win98. It only appears under 2000. We do not get the message when using the eval board on Win98 or 2000 so it seems that there is something that is different between the Cypress driver and our driver. Have you seen this message before? Do you know what we can do so that the message does not come up when we remove our device?

 

Answer:

This unsafe device removal window you're seeing is a WinME, 2K, XP "safety net" to alert the user that they did not safely remove the device using the icon in the taskbar. There's nothing you can really do on the device side, so you need to adapt the following code in your driver in order to stop getting the warning:

case IRP_MN_QUERY_CAPABILITIES:

KDPINF((DEVICEDRIVER_NAME_A": IRP_MJ_PNP:IRP_MN_QUERY_CAPABILITIES\n"));

{

PIO_STACK_LOCATION isl = IoGetCurrentIrpStackLocation(Irp);

KEVENT evt;

KeInitializeEvent(&evt, NotificationEvent, FALSE);

IoCopyCurrentIrpStackLocationToNext(Irp);

IoSetCompletionRoutine(Irp, CompletionRoutine, &evt, TRUE, TRUE, TRUE);

nts = IoCallDriver(DevExt->NlDevObj, Irp);

if (nts == STATUS_PENDING)

{

KeWaitForSingleObject(&evt, Executive, KernelMode, FALSE, NULL);

nts = Irp->IoStatus.Status;

}

if (NT_SUCCESS(nts) && NT_SUCCESS(Irp->IoStatus.Status))

{

isl->Parameters.DeviceCapabilities.Capabilities->SurpriseRemovalOK = TRUE;

}

Irp->IoStatus.Status = nts;

IoCompleteRequest(Irp, IO_NO_INCREMENT);

}

return nts;


static NTSTATUS CompletionRoutine(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)

/****************************************************************************

* DESCRIPTION:

****************************************************************************/

{

UNREFERENCED_PARAMETER(DeviceObject);

if (Irp->PendingReturned)

{

IoMarkIrpPending(Irp);

}

KeSetEvent((PKEVENT)Context, IO_INCREMENT, FALSE);

return STATUS_MORE_PROCESSING_REQUIRED;

}