?? usb.c
字號:
/*++
Copyright (c) 2005-2006 E0 Technology,Inc.
Module Name:
usb.h
Abstract:
Virtual Com Port Driver for USB to RS232 Converter of E0 Technology,Inc.
Environment:
Kernel mode
Notes:
Revision History:
2006/3/1 : Adapted from the BulkUsb DDK sample.
--*/
#include "usb2com.h"
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
Installable driver initialization entry point.
This entry point is called directly by the I/O system.
Arguments:
DriverObject - pointer to the driver object
RegistryPath - pointer to a unicode string representing the path
to driver-specific key in the registry
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_OBJECT deviceObject = NULL;
BOOLEAN fRes;
#if DBG
// should be done before any debug output is done.
// read our debug verbosity level from the registry
USB2COM_GetRegistryDword( USB2COM_REGISTRY_PARAMETERS_PATH, //absolute registry path
L"DebugLevel", // REG_DWORD ValueName
&gDebugLevel ); // Value receiver
#endif
USB2COM_KdPrint( DBGLVL_MINIMUM ,("Entering DriverEntry(), RegistryPath=\n %ws\n", RegistryPath->Buffer ));
USB2COM_KdPrint( DBGLVL_DEFAULT ,("Build Date %s %s\n", __DATE__,__TIME__));
//
// Create dispatch points for create, close, unload
DriverObject->MajorFunction[IRP_MJ_CREATE] = USB2COM_Create;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USB2COM_Close;
DriverObject->DriverUnload = USB2COM_Unload;
// User mode DeviceIoControl() calls will be routed here
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USB2COM_ProcessIOCTL;
// User mode ReadFile()/WriteFile() calls will be routed here
DriverObject->MajorFunction[IRP_MJ_WRITE] = USB2COM_Write;
DriverObject->MajorFunction[IRP_MJ_READ] = USB2COM_Read;
// routines for handling system PNP and power management requests
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = USB2COM_ProcessSysControlIrp;
DriverObject->MajorFunction[IRP_MJ_PNP] = USB2COM_ProcessPnPIrp;
DriverObject->MajorFunction[IRP_MJ_POWER] = USB2COM_ProcessPowerIrp;
// The Functional Device Object (FDO) will not be created for PNP devices until
// this routine is called upon device plug-in.
DriverObject->DriverExtension->AddDevice = USB2COM_PnPAddDevice;
USB2COM_KdPrint( DBGLVL_DEFAULT,("exiting DriverEntry (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
USB2COM_ProcessSysControlIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Main dispatch table routine for IRP_MJ_SYSTEM_CONTROL
We basically just pass these down to the PDO
Arguments:
DeviceObject - pointer to FDO device object
Irp - pointer to an I/O Request Packet
Return Value:
Status returned from lower driver
--*/
{
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
NTSTATUS ntStatus = STATUS_SUCCESS;
NTSTATUS waitStatus;
PDEVICE_OBJECT stackDeviceObject;
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);
//
// Get a pointer to the device extension
//
deviceExtension = DeviceObject->DeviceExtension;
stackDeviceObject = deviceExtension->TopOfStackDeviceObject;
USB2COM_KdPrint( DBGLVL_HIGH, ( "enter USB2COM_ProcessSysControlIrp()\n") );
USB2COM_IncrementIoCount(DeviceObject);
USB2COM_ASSERT( IRP_MJ_SYSTEM_CONTROL == irpStack->MajorFunction );
IoCopyCurrentIrpStackLocationToNext(Irp);
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
USB2COM_DecrementIoCount(DeviceObject);
USB2COM_KdPrint( DBGLVL_HIGH,("USB2COM_ProcessSysControlIrp() Exit USB2COM_ProcessSysControlIrp %x\n", ntStatus));
return ntStatus;
}
VOID
USB2COM_Unload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
Free all the allocated resources, etc.
Arguments:
DriverObject - pointer to a driver object
Return Value:
--*/
{
USB2COM_KdPrint( DBGLVL_HIGH,("enter USB2COM_Unload\n"));
//
// Free any global resources allocated
// in DriverEntry.
// We have few or none because for a PNP device, almost all
// allocation is done in PnpAddDevice() and all freeing
// while handling IRP_MN_REMOVE_DEVICE:
//
USB2COM_ASSERT( gExAllocCount == 0 );
USB2COM_KdPrint( DBGLVL_DEFAULT,("exit USB2COM_Unload\n"));
}
NTSTATUS
USB2COM_CreateDeviceObject(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject,
IN PDEVICE_OBJECT *DeviceObject
)
/*++
Routine Description:
Creates a Functional DeviceObject
Arguments:
DriverObject - pointer to the driver object for device
DeviceObject - pointer to DeviceObject pointer to return
created device object.
Instance - instance of the device create.
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
UNICODE_STRING deviceObjName;
WCHAR wszDeviceName[128];
static ULONG currentInstance = 0;
PDEVICE_EXTENSION deviceExtension;
USHORT i;
USB2COM_KdPrint( DBGLVL_DEFAULT,("enter USB2COM_CreateDeviceObject() \n"));
RtlZeroMemory(wszDeviceName,sizeof(wszDeviceName));
RtlZeroMemory(&deviceObjName, sizeof(UNICODE_STRING));
if (NT_SUCCESS(ntStatus)) {
for(i=0; i<1000; i++)
{
swprintf(wszDeviceName,L"\\Device\\Serial%d",currentInstance++);
RtlInitUnicodeString(&deviceObjName, wszDeviceName);
ntStatus = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION),
&deviceObjName, FILE_DEVICE_SERIAL_PORT,
FILE_DEVICE_SECURE_OPEN, TRUE, DeviceObject);
if (ntStatus != STATUS_OBJECT_NAME_EXISTS &&
ntStatus != STATUS_OBJECT_NAME_COLLISION)
break;
}
if (NT_SUCCESS(ntStatus)) {
deviceExtension = (PDEVICE_EXTENSION) ((*DeviceObject)->DeviceExtension);
RtlZeroMemory(&deviceExtension->DeviceName, sizeof(UNICODE_STRING));
deviceExtension->DeviceName.MaximumLength = deviceObjName.Length + sizeof(WCHAR);
deviceExtension->DeviceName.Buffer = USB2COM_ExAllocatePool(NonPagedPool, deviceObjName.Length + sizeof(WCHAR));
RtlZeroMemory(deviceExtension->DeviceName.Buffer,
deviceObjName.Length+sizeof(WCHAR));
RtlAppendUnicodeStringToString(&deviceExtension->DeviceName, &deviceObjName);
//RtlCopyMemory(deviceExtension->DeviceName.Buffer,
// deviceObjName.Buffer,deviceObjName.Length);
//deviceExtension->DeviceName.Length = deviceObjName.Length;
//USB2COM_KdPrint( DBGLVL_DEFAULT,("deviceObjName: %wZ, DeviceName: %wZ\n",
// deviceObjName,deviceExtension->DeviceName));
USB2COM_KdPrint( DBGLVL_DEFAULT,("deviceObjName: %ws, DeviceName: %ws\n",
deviceExtension->DeviceName.Buffer,deviceObjName.Buffer));
}
USB2COM_KdPrintCond( DBGLVL_DEFAULT,
(!(NT_SUCCESS(ntStatus))),
("USB2COM_CreateDeviceObject() IoCreateDevice() FAILED\n"));
if (!NT_SUCCESS(ntStatus)) {
return ntStatus;
}
deviceExtension->DeviceObject = *DeviceObject;
// this event is triggered when there is no pending io of any kind and device is removed
KeInitializeEvent(&deviceExtension->RemoveEvent, NotificationEvent, FALSE);
// this event is triggered when self-requested power irps complete
KeInitializeEvent(&deviceExtension->SelfRequestedPowerIrpEvent, NotificationEvent, FALSE);
// this event is triggered when there is no pending io (pending io count == 1 )
KeInitializeEvent(&deviceExtension->NoPendingIoEvent, NotificationEvent, FALSE);
// spinlock used to protect inc/dec iocount logic
KeInitializeSpinLock (&deviceExtension->IoCountSpinLock);
deviceExtension->BaudRate = 19200;
/* Set line control */
deviceExtension->SerialLineControl.StopBits = STOP_BIT_1;
deviceExtension->SerialLineControl.Parity = NO_PARITY;
deviceExtension->SerialLineControl.WordLength = 8;
deviceExtension->SpecialChars.XonChar = SERIAL_DEF_XON;
deviceExtension->SpecialChars.XoffChar = SERIAL_DEF_XOFF;
deviceExtension->HandFlow.ControlHandShake = SERIAL_DTR_CONTROL;
deviceExtension->HandFlow.FlowReplace = SERIAL_RTS_CONTROL;
deviceExtension->HandFlow.XoffLimit = 300;
deviceExtension->HandFlow.XonLimit = 100;
InitializeCircularBuffer(&deviceExtension->InputBuffer, 512);
InitializeCircularBuffer(&deviceExtension->OutputBuffer, 512);
KeInitializeSpinLock(&deviceExtension->InputBufferLock);
KeInitializeSpinLock(&deviceExtension->OutputBufferLock);
InitializeListHead(&deviceExtension->ReadQueue);
KeInitializeSpinLock(&deviceExtension->ReadQueueSpinLock);
InitializeListHead(&deviceExtension->WriteQueue);
KeInitializeSpinLock(&deviceExtension->WriteQueueSpinLock);
InitializeListHead(&deviceExtension->PurgeQueue);
KeInitializeSpinLock(&deviceExtension->PurgeQueueSpinLock);
}
return ntStatus;
}
NTSTATUS
USB2COM_CallUSBD(
IN PDEVICE_OBJECT DeviceObject,
IN PURB Urb
)
/*++
Routine Description:
Passes a URB to the USBD class driver
The client device driver passes USB request block (URB) structures
to the class driver as a parameter in an IRP with Irp->MajorFunction
set to IRP_MJ_INTERNAL_DEVICE_CONTROL and the next IRP stack location
Parameters.DeviceIoControl.IoControlCode field set to
IOCTL_INTERNAL_USB_SUBMIT_URB.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -