//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// #define DRIVER
//
// Include files needed for WDM driver support
//
#include <wdm.h>
#include "stdarg.h"
#include "stdio.h"
//
// Include files needed for USB support
//
#include "usbdi.h"
#include "usbdlib.h"
//
// Include file for the Ezusb Device
//
#include "ezusbsys.h"
//
// incude file containing driver version
//
#include "version.h"
#ifdef DOWNLOAD_KEIL_MONITOR
extern INTEL_HEX_RECORD mon_ext_sio1_ezusb[];
extern INTEL_HEX_RECORD mon_ext_sio1_fx2[];
extern INTEL_HEX_RECORD loader[];
#endif // ifdef DOWNLOAD_KEIL_MONITOR
void
DumpBuffer(PVOID pvBuffer, ULONG length);
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_OBJECT deviceObject = NULL;
Ezusb_KdPrint (("entering (Ezusb) DriverEntry (Build: %s/%s\n",__DATE__,__TIME__));
DriverObject->MajorFunction[IRP_MJ_CREATE] = Ezusb_Create;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ezusb_Close;
DriverObject->DriverUnload = Ezusb_Unload;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Ezusb_ProcessIOCTL;
DriverObject->MajorFunction[IRP_MJ_PNP] = Ezusb_DispatchPnp;
DriverObject->MajorFunction[IRP_MJ_POWER] = Ezusb_DispatchPower;
DriverObject->DriverExtension->AddDevice = Ezusb_PnPAddDevice;
Ezusb_KdPrint (("exiting (Ezusb) DriverEntry (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
Ezusb_DefaultPnpHandler(
IN PDEVICE_OBJECT fdo,
IN PIRP Irp
)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(pdx->StackDeviceObject, Irp);
}
NTSTATUS
OnRequestComplete(
IN PDEVICE_OBJECT fdo,
IN PIRP Irp,
IN PKEVENT pev
)
{
KeSetEvent(pev, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
ForwardAndWait(
IN PDEVICE_OBJECT fdo,
IN PIRP Irp
)
{
KEVENT event;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
NTSTATUS ntStatus;
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
//
// Initialize a kernel event object to use in waiting for the lower-level
// driver to finish processing the object.
//
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) OnRequestComplete,
(PVOID) &event, TRUE, TRUE, TRUE);
ntStatus = IoCallDriver(pdx->StackDeviceObject, Irp);
if (ntStatus == STATUS_PENDING)
{
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
ntStatus = Irp->IoStatus.Status;
}
return ntStatus;
}
NTSTATUS
CompleteRequest(
IN PIRP Irp,
IN NTSTATUS status,
IN ULONG info
)
{
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS
Ezusb_DispatchPnp(
IN PDEVICE_OBJECT fdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION pdx = fdo->DeviceExtension;
ULONG fcn;
NTSTATUS ntStatus;
Ezusb_KdPrint (("Enter Ezusb_DispatchPnp\n"));
if (!LockDevice(fdo))
return CompleteRequest(Irp, STATUS_DELETE_PENDING, 0);
//
// Get a pointer to the current location in the Irp. This is where
// the function codes and parameters are located.
//
irpStack = IoGetCurrentIrpStackLocation (Irp);
ASSERT(irpStack->MajorFunction == IRP_MJ_PNP);
fcn = irpStack->MinorFunction;
switch (fcn)
{
case IRP_MN_START_DEVICE:
Ezusb_KdPrint (("IRP_MN_START_DEVICE\n"));
ntStatus = Ezusb_HandleStartDevice(fdo,Irp);
if (ntStatus == STATUS_SUCCESS)
{
pdx->Started = TRUE;
}
break; //IRP_MN_START_DEVICE
case IRP_MN_STOP_DEVICE:
Ezusb_KdPrint (("IRP_MN_STOP_DEVICE\n"));
//
// first pass the request down the stack
//
Ezusb_DefaultPnpHandler(fdo,Irp);
ntStatus = Ezusb_StopDevice(fdo);
break; //IRP_MN_STOP_DEVICE
case IRP_MN_REMOVE_DEVICE:
Ezusb_KdPrint (("IRP_MN_REMOVE_DEVICE\n"))
ntStatus = Ezusb_HandleRemoveDevice(fdo,Irp);
break; //IRP_MN_REMOVE_DEVICE
case IRP_MN_QUERY_CAPABILITIES:
{
//
// This code swiped from Walter Oney. Please buy his book!!
//
PDEVICE_CAPABILITIES pdc = irpStack->Parameters.DeviceCapabilities.Capabilities;
Ezusb_KdPrint (("IRP_MN_QUERY_CAPABILITIES\n"))
// Check to be sure we know how to handle this version of the capabilities structure
if (pdc->Version < 1)
{
ntStatus = Ezusb_DefaultPnpHandler(fdo, Irp);
break;
}
ntStatus = ForwardAndWait(fdo, Irp);
if (NT_SUCCESS(ntStatus))
{ // IRP succeeded
pdc = irpStack->Parameters.DeviceCapabilities.Capabilities;
// setting this field prevents NT5 from notifying the user when the
// device is removed.
pdc->SurpriseRemovalOK = TRUE;
} // IRP succeeded
ntStatus = CompleteRequest(Irp, ntStatus, Irp->IoStatus.Information);
}
break; //IRP_MN_QUERY_CAPABILITIES
//
// All other PNP IRP's are just passed down the stack by the default handler
//
default:
Ezusb_KdPrint (("Passing down unhandled PnP IOCTL 0x%x\n", fcn));
ntStatus = Ezusb_DefaultPnpHandler(fdo, Irp);
} // switch MinorFunction
if (fcn != IRP_MN_REMOVE_DEVICE)
UnlockDevice(fdo);
Ezusb_KdPrint (("Exit Ezusb_DispatchPnp %x\n", ntStatus));
return ntStatus;
}//Ezusb_Dispatch
NTSTATUS
Ezusb_DispatchPower(
IN PDEVICE_OBJECT fdo,
IN PIRP Irp
)
{
PIO_STACK_LOCATION irpStack, nextStack;
PDEVICE_EXTENSION pdx = fdo->DeviceExtension;
NTSTATUS ntStatus;
Ezusb_KdPrint (("Enter Ezusb_DispatchPower\n"));
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//
// Get a pointer to the current location in the Irp. This is where
// the function codes and parameters are located.
//
irpStack = IoGetCurrentIrpStackLocation (Irp);
Ezusb_KdPrint (("IRP_MJ_POWER MIN=0x%x Type=0x%x State=0x%x\n",irpStack->MinorFunction,
irpStack->Parameters.Power.Type,
irpStack->Parameters.Power.State.DeviceState));
switch (irpStack->MinorFunction)
{
case IRP_MN_SET_POWER:
switch (irpStack->Parameters.Power.Type)
{
case SystemPowerState:
break; //SystemPowerState
case DevicePowerState:
switch (irpStack->Parameters.Power.State.DeviceState)
{
case PowerDeviceD3:
Ezusb_KdPrint (("IRP_MN_SET_D3\n"));
break;
case PowerDeviceD2:
Ezusb_KdPrint (("IRP_MN_SET_D2\n"));
break;
case PowerDeviceD1:
Ezusb_KdPrint (("IRP_MN_SET_D1\n"));
break;
case PowerDeviceD0:
Ezusb_KdPrint (("IRP_MN_SET_D0\n"));
break;
} // switch on Power.State.DeviceState
break; //DevicePowerState
}// switch on Power.Type
break; //IRP_MN_SET_POWER
case IRP_MN_QUERY_POWER:
// Look at what type of power query this is
switch (irpStack->Parameters.Power.Type)
{
case SystemPowerS
评论0