Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

943 lines
37 KiB

/***************************************************************************
Copyright (c) 2001 Microsoft Corporation
Module Name:
USBUTIL.C
Abstract:
Generic USB routines - must be called at PASSIVE_LEVEL
Environment:
Kernel Mode Only
Notes:
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
PURPOSE.
Copyright (c) 2001 Microsoft Corporation. All Rights Reserved.
Revision History:
01/08/2001 : created
Authors:
Tom Green
****************************************************************************/
#include "pch.h"
#include <usb.h>
#include <usbdrivr.h>
#include <usbdlib.h>
#include "intread.h"
#include "usbutil.h"
#include "usbpriv.h"
#include "usbdbg.h"
#ifdef ALLOC_PRAGMA
#endif // ALLOC_PRAGMA
#if DBG
ULONG USBUtil_DebugTraceLevel = 0;
PUSB_WRAP_PRINT USBUtil_DbgPrint = DbgPrint;
#endif
/************************************************************************/
/* USBCallSync */
/************************************************************************/
/* */
/* Routine Description: */
/* */
/* Send URB down USB stack. Synchronous call. */
/* Caller is responsible for URB (allocating and freeing) */
/* */
/* Arguments: */
/* */
/* LowerDevObj - pointer to a device object */
/* Urb - pointer to URB */
/* MillisecondsTimeout - milliseconds to wait for completion */
/* RemoveLock - pointer to remove lock */
/* */
/* Return Value: */
/* */
/* NTSTATUS */
/* */
/************************************************************************/
NTSTATUS
USBCallSyncEx(IN PDEVICE_OBJECT LowerDevObj,
IN PURB Urb,
IN LONG MillisecondsTimeout,
IN PIO_REMOVE_LOCK RemoveLock,
IN ULONG RemLockSize)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PIRP irp = NULL;
KEVENT event;
PIO_STACK_LOCATION nextStack;
BOOLEAN gotRemoveLock = FALSE;
__try
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBCallSync\n"));
ntStatus = IoAcquireRemoveLockEx(RemoveLock,
LowerDevObj,
__FILE__,
__LINE__,
RemLockSize);
if(NT_SUCCESS(ntStatus))
{
gotRemoveLock = TRUE;
}
else
{
DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBCallSync: Pending remove on device\n"));
__leave;
}
// do some parameter checking before going too far
if(LowerDevObj == NULL || Urb == NULL || MillisecondsTimeout < 0)
{
DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBCallSync: Invalid paramemter passed in\n"));
ntStatus = STATUS_INVALID_PARAMETER;
__leave;
}
// issue a synchronous request
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(LowerDevObj->StackSize, FALSE);
// check to see if we allocated an Irp
if(!irp)
{
DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBCallSync: Couldn't allocate Irp\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
// Set the Irp parameters
nextStack = IoGetNextIrpStackLocation(irp);
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
nextStack->Parameters.Others.Argument1 = Urb;
// Set the completion routine, which will signal the event
IoSetCompletionRoutine(irp,
USBCallSyncCompletionRoutine,
&event,
TRUE, // InvokeOnSuccess
TRUE, // InvokeOnError
TRUE); // InvokeOnCancel
ntStatus = IoCallDriver(LowerDevObj, irp);
// block on pending request
if(ntStatus == STATUS_PENDING)
{
LARGE_INTEGER timeout;
PLARGE_INTEGER pTimeout = NULL;
// check and see if they have passed in a number of milliseconds to time out
if(MillisecondsTimeout)
{
// setup timeout
timeout = RtlEnlargedIntegerMultiply(ONE_MILLISECOND_TIMEOUT, MillisecondsTimeout);
pTimeout = &timeout;
}
ntStatus = KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
pTimeout);
// if it timed out, cancel the irp and return appropriate status
if(ntStatus == STATUS_TIMEOUT)
{
ntStatus = STATUS_IO_TIMEOUT;
// Cancel the Irp we just sent.
IoCancelIrp(irp);
// Wait until the cancel completes
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
}
else
{
// didn't timeout, so return current status
ntStatus = irp->IoStatus.Status;
}
}
}
__finally
{
if(gotRemoveLock)
{
IoReleaseRemoveLockEx(RemoveLock, LowerDevObj, RemLockSize);
}
if(irp)
{
IoFreeIrp(irp);
}
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBCallSync\n"));
}
return ntStatus;
} // USBCallSync
/************************************************************************/
/* USBCallSyncCompletionRoutine */
/************************************************************************/
/* */
/* Routine Description: */
/* */
/* Completion routine for USB sync request. */
/* */
/* Arguments: */
/* */
/* DeviceObject - pointer to device object */
/* Irp - pointer to an I/O Request Packet */
/* Context - pointer to context of call */
/* */
/* Return Value: */
/* */
/* NTSTATUS */
/* */
/************************************************************************/
NTSTATUS
USBCallSyncCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
PKEVENT kevent;
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBCallSyncCompletionRoutine\n"));
kevent = (PKEVENT) Context;
KeSetEvent(kevent, IO_NO_INCREMENT, FALSE);
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBCallSyncCompletionRoutine\n"));
return STATUS_MORE_PROCESSING_REQUIRED;
} // USBCallSyncCompletionRoutine
/************************************************************************/
/* USBVendorRequest */
/************************************************************************/
/* */
/* Routine Description: */
/* */
/* Issue USB vendor specific request */
/* */
/* Arguments: */
/* */
/* LowerDevObj - pointer to a device object */
/* Request - request field of vendor specific command */
/* Value - value field of vendor specific command */
/* Index - index field of vendor specific command */
/* Buffer - pointer to data buffer */
/* BufferSize - data buffer length */
/* Read - data direction flag */
/* Timeout - number of milliseconds to wait for completion */
/* RemoveLock - pointer to remove lock */
/* */
/* Return Value: */
/* */
/* NTSTATUS */
/* */
/************************************************************************/
NTSTATUS
USBVendorRequestEx(IN PDEVICE_OBJECT LowerDevObj,
IN REQUEST_RECIPIENT Recipient,
IN UCHAR Request,
IN USHORT Value,
IN USHORT Index,
IN OUT PVOID Buffer,
IN OUT PULONG BufferSize,
IN BOOLEAN Read,
IN LONG MillisecondsTimeout,
IN PIO_REMOVE_LOCK RemoveLock,
IN ULONG RemLockSize)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PURB urb = NULL;
ULONG size;
ULONG length;
USHORT function;
PAGED_CODE();
__try
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBVendorRequest\n"));
// do some parameter checking before going too far
if(LowerDevObj == NULL || MillisecondsTimeout < 0)
{
DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBClassRequest: Invalid paramemter passed in\n"));
ntStatus = STATUS_INVALID_PARAMETER;
__leave;
}
// length of buffer passed in
length = BufferSize ? *BufferSize : 0;
// set the buffer length to 0 in case of error
if(BufferSize)
{
*BufferSize = 0;
}
size = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
// allocate memory for the Urb
urb = ALLOC_MEM(NonPagedPool, size, USBLIB_TAG);
// check to see if we allocated a urb
if(!urb)
{
DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBVendorRequest: Couldn't allocate URB\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
switch (Recipient) {
case Device:
function = URB_FUNCTION_VENDOR_DEVICE;
break;
case Interface:
function = URB_FUNCTION_VENDOR_INTERFACE;
break;
case Endpoint:
function = URB_FUNCTION_VENDOR_ENDPOINT;
break;
case Other:
function = URB_FUNCTION_VENDOR_OTHER;
break;
}
UsbBuildVendorRequest(urb, function,
(USHORT) size,
Read ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT,
0, Request, Value, Index, Buffer, NULL, length, NULL);
ntStatus = USBCallSyncEx(LowerDevObj,
urb,
MillisecondsTimeout,
RemoveLock,
RemLockSize);
// get length of buffer
if(BufferSize)
{
*BufferSize = urb->UrbControlVendorClassRequest.TransferBufferLength;
}
}
__finally
{
if(urb)
{
FREE_MEM(urb);
}
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBVendorRequest\n"));
}
return ntStatus;
} // USBVendorRequest
/************************************************************************/
/* USBClassRequest */
/************************************************************************/
/* */
/* Routine Description: */
/* */
/* Issue USB Class specific request */
/* */
/* Arguments: */
/* */
/* LowerDevObj - pointer to a device object */
/* Recipient - request recipient
/* Request - request field of class specific command */
/* Value - value field of class specific command */
/* Index - index field of class specific command */
/* Buffer - pointer to data buffer */
/* BufferSize - data buffer length */
/* Read - data direction flag */
/* RemoveLock - pointer to remove lock */
/* Timeout - number of milliseconds to wait for completion */
/* */
/* Return Value: */
/* */
/* NTSTATUS */
/* */
/************************************************************************/
NTSTATUS
USBClassRequestEx(IN PDEVICE_OBJECT LowerDevObj,
IN REQUEST_RECIPIENT Recipient,
IN UCHAR Request,
IN USHORT Value,
IN USHORT Index,
IN OUT PVOID Buffer,
IN OUT PULONG BufferSize,
IN BOOLEAN Read,
IN LONG MillisecondsTimeout,
IN PIO_REMOVE_LOCK RemoveLock,
IN ULONG RemLockSize)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PURB urb = NULL;
ULONG size;
ULONG length;
USHORT function;
__try
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBClassRequest\n"));
// do some parameter checking before going too far
if(LowerDevObj == NULL || MillisecondsTimeout < 0)
{
DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBClassRequest: Invalid paramemter passed in\n"));
ntStatus = STATUS_INVALID_PARAMETER;
__leave;
}
// length of buffer passed in
length = BufferSize ? *BufferSize : 0;
// set the buffer length to 0 in case of error
if(BufferSize)
{
*BufferSize = 0;
}
size = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST);
// allocate memory for the Urb
urb = ALLOC_MEM(NonPagedPool, size, USBLIB_TAG);
// check to see if we allocated a urb
if(!urb)
{
DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBClassRequest: Couldn't allocate URB\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
switch (Recipient) {
case Device:
function = URB_FUNCTION_CLASS_DEVICE;
break;
case Interface:
function = URB_FUNCTION_CLASS_INTERFACE;
break;
case Endpoint:
function = URB_FUNCTION_CLASS_ENDPOINT;
break;
case Other:
function = URB_FUNCTION_CLASS_OTHER;
break;
}
UsbBuildVendorRequest(urb, function,
(USHORT) size,
Read ? USBD_TRANSFER_DIRECTION_IN : USBD_TRANSFER_DIRECTION_OUT,
0, Request, Value, Index, Buffer, NULL, length, NULL);
ntStatus = USBCallSyncEx(LowerDevObj,
urb,
MillisecondsTimeout,
RemoveLock,
RemLockSize);
// get length of buffer
if(BufferSize)
{
*BufferSize = urb->UrbControlVendorClassRequest.TransferBufferLength;
}
}
__finally
{
if(urb)
{
FREE_MEM(urb);
}
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBClassRequest\n"));
}
return ntStatus;
} // USBClassRequest
/************************************************************************/
/* USBInitializeInterruptTransfers */
/************************************************************************/
/* */
/* Routine Description: */
/* */
/* Initialize interrupt read pipe */
/* */
/* Arguments: */
/* */
/* DeviceObject - pointer to the device object */
/* LowerDevObj - pointer to the lower device object */
/* Buffer - pointer to buffer for data from interrupt pipe */
/* BuffSize - size of buffer passed in */
/* InterruptPipe - pipe descriptor */
/* DriverContext - context passed to driver callback routine */
/* DriverCallback - driver routines called on completion */
/* RemoveLock - pointer to remove lock for device */
/* */
/* Return Value: */
/* */
/* USB_WRAPPER_HANDLE */
/* */
/************************************************************************/
USB_WRAPPER_HANDLE
USBInitializeInterruptTransfersEx(IN PDEVICE_OBJECT DeviceObject,
IN PDEVICE_OBJECT LowerDevObj,
IN ULONG MaxTransferSize,
IN PUSBD_PIPE_INFORMATION InterruptPipe,
IN PVOID DriverContext,
IN INTERRUPT_CALLBACK DriverCallback,
IN ULONG NotificationTypes,
IN ULONG PingPongCount,
IN PIO_REMOVE_LOCK RemoveLock,
IN ULONG RemLockSize)
{
PUSB_WRAPPER_EXTENSION pUsbWrapperExtension = NULL;
ULONG size;
NTSTATUS status;
BOOLEAN error = FALSE;
PAGED_CODE();
__try
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBInitializeInterruptTransfers\n"));
//
// Parameter Checking
//
if ((LowerDevObj == NULL) || (InterruptPipe == NULL) || (RemoveLock == NULL)) {
DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBInitializeInterruptTransfers: Invalid paramemter passed in\n"));
error = TRUE;
__leave;
}
//
// Allocate UsbWrapperExtension
//
pUsbWrapperExtension = ALLOC_MEM(NonPagedPool,
sizeof(USB_WRAPPER_EXTENSION),
USBLIB_TAG);
if(!pUsbWrapperExtension)
{
DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBInitializeInterruptTransfers: Couldn't allocate Wrapper Extension\n"));
error = TRUE;
__leave;
}
//
// Initialize UsbWrapperExtension
//
pUsbWrapperExtension->DeviceObject = DeviceObject;
pUsbWrapperExtension->LowerDeviceObject = LowerDevObj;
pUsbWrapperExtension->RemoveLock = RemoveLock;
pUsbWrapperExtension->RemLockSize = RemLockSize;
//
//Initialize Interrupt Read Wrap
//
UsbWrapInitializeInterruptReadData(
pUsbWrapperExtension,
InterruptPipe,
DriverCallback,
DriverContext,
MaxTransferSize,
NotificationTypes,
PingPongCount);
InterlockedExchange(&pUsbWrapperExtension->IntReadWrap.HandlingError, 0);
//
// Init ping-pong stuff
//
status = UsbWrapInitializePingPongIrps(pUsbWrapperExtension);
if(!NT_SUCCESS(status)) {
DBGPRINT(DBG_USBUTIL_USB_ERROR, ("USBInitializeInterruptTransfers: Couldn't initialize ping pong irps\n"));
error = TRUE;
__leave;
}
__leave;
}
__finally
{
if (error && pUsbWrapperExtension) {
if (pUsbWrapperExtension->IntReadWrap.PingPongs) {
UsbWrapDestroyPingPongs(pUsbWrapperExtension);
}
FREE_MEM(pUsbWrapperExtension);
}
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBInitializeInterruptTransfers\n"));
}
return (USB_WRAPPER_HANDLE) pUsbWrapperExtension;
} // USBInitializeInterruptTransfers
/************************************************************************/
/* USBStartInterruptTransfers */
/************************************************************************/
/* */
/* Routine Description: */
/* */
/* Start transfers on interrupt pipe */
/* */
/* Arguments: */
/* */
/* WrapperHandle - pointer to wrapper handle from Init call */
/* */
/* Return Value: */
/* */
/* NTSTATUS */
/* */
/************************************************************************/
NTSTATUS
USBStartInterruptTransfers(IN USB_WRAPPER_HANDLE WrapperHandle)
{
PUSB_WRAPPER_EXTENSION wrapExt = (PUSB_WRAPPER_EXTENSION) WrapperHandle;
NTSTATUS status;
__try
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBStartInterruptTransfers\n"));
if (!wrapExt) {
status = STATUS_INVALID_PARAMETER;
__leave;
}
ASSERT(IsListEmpty(&wrapExt->IntReadWrap.IncomingQueue));
status = UsbWrapStartAllPingPongs(wrapExt);
}
__finally
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBStartInterruptTransfers\n"));
}
return status;
}
/************************************************************************/
/* USBStopInterruptTransfers */
/************************************************************************/
/* */
/* Routine Description: */
/* */
/* Stop transfers on interrupt pipe and free resources */
/* */
/* Arguments: */
/* */
/* WrapperHandle - pointer to wrapper handle from Init call */
/* */
/* Return Value: */
/* */
/* NTSTATUS */
/* */
/************************************************************************/
NTSTATUS
USBStopInterruptTransfers(IN USB_WRAPPER_HANDLE WrapperHandle)
{
PUSB_WRAPPER_EXTENSION wrapExt = WrapperHandle;
NTSTATUS status = STATUS_SUCCESS;
PAGED_CODE();
__try
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBStopInterruptTransfers\n"));
if (!WrapperHandle) {
status = STATUS_INVALID_PARAMETER;
__leave;
}
InterlockedExchange(&wrapExt->IntReadWrap.PumpState,
PUMP_STOPPED);
UsbWrapCancelAllPingPongIrps(wrapExt);
UsbWrapEmptyQueue(wrapExt,
&wrapExt->IntReadWrap.IncomingQueue);
}
__finally
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBStopInterruptTransfers\n"));
}
return STATUS_SUCCESS;
} // USBStopInterruptTransfers
/************************************************************************/
/* USBReleaseInterruptTransfers */
/************************************************************************/
/* */
/* Routine Description: */
/* */
/* Frees all resources allocated in */
/* USBInitializeInterruptTransfers */
/* */
/* Arguments: */
/* */
/* WrapperHandle - pointer to wrapper handle from Init call */
/* */
/* Return Value: */
/* */
/* NTSTATUS */
/* */
/************************************************************************/
NTSTATUS
USBReleaseInterruptTransfers(IN USB_WRAPPER_HANDLE WrapperHandle)
{
PUSB_WRAPPER_EXTENSION wrapExt = (PUSB_WRAPPER_EXTENSION) WrapperHandle;
NTSTATUS status = STATUS_SUCCESS;
__try
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBReleaseInterruptTransfers\n"));
if (!wrapExt) {
status = STATUS_INVALID_PARAMETER;
__leave;
}
UsbWrapDestroyPingPongs(wrapExt);
UsbWrapEmptyQueue(wrapExt, &wrapExt->IntReadWrap.IncomingQueue);
UsbWrapEmptyQueue(wrapExt, &wrapExt->IntReadWrap.SavedQueue);
FREE_MEM(wrapExt);
wrapExt = NULL;
}
__finally
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBReleaseInterruptTransfers\n"));
}
return status;
}
/************************************************************************/
/* USBStartSelectiveSuspend */
/************************************************************************/
/* */
/* Routine Description: */
/* */
/* Start selective suspend support for device */
/* */
/* Arguments: */
/* */
/* LowerDevObj - pointer to device object */
/* */
/* Return Value: */
/* */
/* USB_WRAPPER_HANDLE */
/* */
/************************************************************************/
USB_WRAPPER_HANDLE
USBStartSelectiveSuspend(IN PDEVICE_OBJECT LowerDevObj)
{
PAGED_CODE();
__try
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBStartSelectiveSuspend\n"));
}
__finally
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBStartSelectiveSuspend\n"));
}
return NULL;
} // USBStartSelectiveSuspend
/************************************************************************/
/* USBStopSelectiveSuspend */
/************************************************************************/
/* */
/* Routine Description: */
/* */
/* Stop selective suspend support for device */
/* */
/* Arguments: */
/* */
/* WrapperHandle - wrapper handle returned by start routine */
/* */
/* Return Value: */
/* */
/* NTSTATUS */
/* */
/************************************************************************/
NTSTATUS
USBStopSelectiveSuspend(IN USB_WRAPPER_HANDLE WrapperHandle)
{
PAGED_CODE();
__try
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBStopSelectiveSuspend\n"));
}
__finally
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBStopSelectiveSuspend\n"));
}
return STATUS_SUCCESS;
} // USBStopSelectiveSuspend
/************************************************************************/
/* USBRequestIdle */
/************************************************************************/
/* */
/* Routine Description: */
/* */
/* Idle request for device */
/* */
/* Arguments: */
/* */
/* WrapperHandle - wrapper handle returned by start routine */
/* */
/* Return Value: */
/* */
/* NTSTATUS */
/* */
/************************************************************************/
NTSTATUS
USBRequestIdle(IN USB_WRAPPER_HANDLE WrapperHandle)
{
PAGED_CODE();
__try
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBRequestIdle\n"));
}
__finally
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBRequestIdle\n"));
}
return STATUS_SUCCESS;
} // USBRequestIdle
/************************************************************************/
/* USBRequestWake */
/************************************************************************/
/* */
/* Routine Description: */
/* */
/* Wake request for device */
/* */
/* Arguments: */
/* */
/* WrapperHandle - wrapper handle returned by start routine */
/* */
/* Return Value: */
/* */
/* NTSTATUS */
/* */
/************************************************************************/
NTSTATUS
USBRequestWake(IN USB_WRAPPER_HANDLE WrapperHandle)
{
PAGED_CODE();
__try
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Enter: USBRequestWake\n"));
}
__finally
{
DBGPRINT(DBG_USBUTIL_ENTRY_EXIT, ("Exit: USBRequestWake\n"));
}
return STATUS_SUCCESS;
} // USBRequestWake