umss.c
来自「winNT技术操作系统,国外开放的原代码和LIUX一样」· C语言 代码 · 共 1,933 行 · 第 1/5 页
C
1,933 行
/**
* umss.c - USB driver stack project for Windows NT 4.0
*
* Copyright (c) 2002-2004 Zhiming mypublic99@yahoo.com
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program (in the main directory of the distribution, the file
* COPYING); if not, write to the Free Software Foundation,Inc., 59 Temple
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "usbdriver.h"
#include <srb.h>
#include <ntddscsi.h>
#include <scsi.h>
#define UMSS_EXIT_DISPATCH( dev_OBJ, staTUS, iRp ) \
{\
iRp->IoStatus.Status = staTUS;\
if( staTUS != STATUS_PENDING)\
{\
IoCompleteRequest( iRp, IO_NO_INCREMENT);\
return staTUS;\
}\
IoMarkIrpPending( iRp );\
IoStartPacket( dev_OBJ, iRp, NULL, NULL ); \
return STATUS_PENDING;\
}
#define UMSS_COMPLETE_START_IO( dev_OBJ, staTUS, iRP ) \
{\
iRP->IoStatus.Status = staTUS;\
if( staTUS != STATUS_PENDING )\
{\
IoStartNextPacket( dev_OBJ, FALSE );\
IoCompleteRequest( iRP, IO_NO_INCREMENT );\
}\
return;\
}
extern VOID gendrv_startio(IN PDEVICE_OBJECT dev_obj, IN PIRP irp);
NTSYSAPI NTSTATUS NTAPI ZwLoadDriver(IN PUNICODE_STRING DriverServiceName);
NTSYSAPI
NTSTATUS
NTAPI
ObOpenObjectByName(IN POBJECT_ATTRIBUTES ObjectAttributes,
IN POBJECT_TYPE ObjectType OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
IN OUT PACCESS_STATE AccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess OPTIONAL,
IN OUT PVOID ParseContext OPTIONAL, OUT PHANDLE Handle);
VOID NTAPI umss_start_io(IN PDEVICE_OBJECT dev_obj, IN PIRP irp);
NTSTATUS umss_port_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp);
BOOLEAN umss_connect(PDEV_CONNECT_DATA dev_mgr, DEV_HANDLE dev_handle);
BOOLEAN umss_disconnect(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
BOOLEAN umss_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
NTSTATUS umss_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp);
VOID umss_set_cfg_completion(PURB purb, PVOID pcontext);
VOID NTAPI umss_start_create_device(IN PVOID Parameter);
BOOLEAN umss_delete_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdrvr, PDEVICE_OBJECT dev_obj, BOOLEAN is_if);
BOOLEAN umss_stop(PUSB_DEV_MANAGER dev_mgr, DEV_HANDLE dev_handle);
NTSTATUS umss_process_srb(PDEVICE_OBJECT dev_obj, PIRP irp);
VOID umss_load_class_driver(PVOID context);
BOOLEAN umss_tsc_to_sff(PIO_PACKET io_packet);
VOID umss_fix_sff_result(PIO_PACKET io_packet, SCSI_REQUEST_BLOCK * srb);
PDEVICE_OBJECT
umss_create_port_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
{
// currently a port device is a connection point
// and upper driver use this to register itself
// with umss driver for future notification of
// pnp event. 2004-03-22 23:12:41
CHAR dev_name[64];
STRING string;
NTSTATUS status;
PDEVICE_OBJECT pdev;
UNICODE_STRING name_string, symb_link;
PUMSS_PORT_DEV_EXT pdev_ext;
sprintf(dev_name, "\\Device\\usbPort_%d", (int)0);
RtlInitString(&string, dev_name);
RtlAnsiStringToUnicodeString(&name_string, &string, TRUE);
pdev = NULL;
status = IoCreateDevice(dev_mgr->usb_driver_obj,
sizeof(UMSS_PORT_DEV_EXT), &name_string, FILE_USB_DEV_TYPE, 0, TRUE, &pdev);
if (status == STATUS_SUCCESS)
{
//
// We do buffered io
//
pdev->Flags |= DO_BUFFERED_IO;
pdev->Flags &= ~DO_DEVICE_INITIALIZING;
pdev->StackSize = 2; //one for fdo, one for file device obj
pdev_ext = (PUMSS_PORT_DEV_EXT) pdev->DeviceExtension;
pdev_ext->dev_ext_hdr.type = NTDEV_TYPE_CLIENT_DEV;
pdev_ext->dev_ext_hdr.dispatch = umss_port_dispatch_routine;
pdev_ext->dev_ext_hdr.start_io = NULL;
pdev_ext->dev_ext_hdr.dev_mgr = dev_mgr;
pdev_ext->pdriver = pdriver;
sprintf(dev_name, "\\DosDevices\\usbPort%d", (int)0);
RtlInitString(&string, dev_name);
RtlAnsiStringToUnicodeString(&symb_link, &string, TRUE);
IoCreateSymbolicLink(&symb_link, &name_string);
RtlFreeUnicodeString(&symb_link);
}
RtlFreeUnicodeString(&name_string);
return pdev;
}
BOOLEAN
umss_delete_port_device(PDEVICE_OBJECT dev_obj)
{
CHAR dev_name[64];
STRING string;
UNICODE_STRING symb_link;
if (dev_obj == NULL)
return FALSE;
// remove the symbolic link
sprintf(dev_name, "\\DosDevices\\usbPort%d", (int)0);
RtlInitString(&string, dev_name);
RtlAnsiStringToUnicodeString(&symb_link, &string, TRUE);
IoDeleteSymbolicLink(&symb_link);
RtlFreeUnicodeString(&symb_link);
if (dev_obj->ReferenceCount == 0)
{
IoDeleteDevice(dev_obj);
usb_dbg_print(DBGLVL_MAXIMUM, ("umss_delete_port_device(): port device object is removed\n"));
}
return TRUE;
}
// FIXME!!! there can not be sent IOCTL_SUBMIT_URB_XXX while
// the IOCTL_SUBMIT_CDB_XXX are active. may confuse the device.
// not resolved yet.
// 2004-03-22 23:12:26
NTSTATUS
umss_port_dispatch_routine(PDEVICE_OBJECT pdev_obj, PIRP irp)
{
ULONG ctrl_code;
NTSTATUS status;
PIO_STACK_LOCATION irp_stack;
PUMSS_PORT_DEV_EXT pdev_ext;
PUMSS_DRVR_EXTENSION pdrvr_ext;
if (pdev_obj == NULL || irp == NULL)
return STATUS_INVALID_PARAMETER;
status = STATUS_SUCCESS;
irp_stack = IoGetCurrentIrpStackLocation(irp);
ctrl_code = irp_stack->Parameters.DeviceIoControl.IoControlCode;
pdev_ext = (PUMSS_PORT_DEV_EXT) pdev_obj->DeviceExtension;
switch (irp_stack->MajorFunction)
{
case IRP_MJ_INTERNAL_DEVICE_CONTROL:
{
switch (ctrl_code)
{
case IOCTL_REGISTER_DRIVER:
{
PCLASS_DRV_REG_INFO pcdri;
if (irp_stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CLASS_DRV_REG_INFO))
{
EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
}
pcdri = irp->AssociatedIrp.SystemBuffer;
if (pcdri->fdo_driver == NULL || pcdri->add_device == NULL || pcdri->pnp_dispatch == NULL)
{
EXIT_DISPATCH(STATUS_INVALID_PARAMETER, irp);
}
pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdev_ext->pdriver->driver_ext;
pdrvr_ext->class_driver_info.fdo_driver = pcdri->fdo_driver;
pdrvr_ext->class_driver_info.add_device = pcdri->add_device;
pdrvr_ext->class_driver_info.pnp_dispatch = pcdri->pnp_dispatch;
EXIT_DISPATCH(STATUS_SUCCESS, irp);
}
case IOCTL_REVOKE_DRIVER:
{
pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdev_ext->pdriver->driver_ext;
pdrvr_ext->class_driver_info.fdo_driver = NULL;
pdrvr_ext->class_driver_info.add_device = NULL;
pdrvr_ext->class_driver_info.pnp_dispatch = NULL;
EXIT_DISPATCH(STATUS_SUCCESS, irp);
}
}
}
case IRP_MJ_CREATE:
case IRP_MJ_CLOSE:
{
EXIT_DISPATCH(STATUS_SUCCESS, irp);
}
}
EXIT_DISPATCH(STATUS_INVALID_DEVICE_REQUEST, irp);
}
BOOLEAN
umss_driver_init(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
{
PUMSS_DRVR_EXTENSION pdrvr_ext;
if (dev_mgr == NULL || pdriver == NULL)
return FALSE;
//init driver structure, no PNP table functions
pdriver->driver_desc.flags = USB_DRIVER_FLAG_DEV_CAPABLE;
pdriver->driver_desc.vendor_id = 0x0dd8; // USB Vendor ID
pdriver->driver_desc.product_id = 0x0003; // USB Product ID.
pdriver->driver_desc.release_num = 0x100; // Release Number of Device
pdriver->driver_desc.config_val = 1; // Configuration Value
pdriver->driver_desc.if_num = 1; // Interface Number
pdriver->driver_desc.if_class = USB_CLASS_MASS_STORAGE; // Interface Class
pdriver->driver_desc.if_sub_class = 0; // Interface SubClass
pdriver->driver_desc.if_protocol = 0; // Interface Protocol
pdriver->driver_desc.driver_name = "USB Mass Storage driver"; // Driver name for Name Registry
pdriver->driver_desc.dev_class = USB_CLASS_MASS_STORAGE;
pdriver->driver_desc.dev_sub_class = 0; // Device Subclass
pdriver->driver_desc.dev_protocol = 0; // Protocol Info.
pdriver->driver_ext = usb_alloc_mem(NonPagedPool, sizeof(UMSS_DRVR_EXTENSION));
pdriver->driver_ext_size = sizeof(UMSS_DRVR_EXTENSION);
RtlZeroMemory(pdriver->driver_ext, sizeof(UMSS_DRVR_EXTENSION));
pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdriver->driver_ext;
pdrvr_ext->dev_count = 0;
InitializeListHead(&pdrvr_ext->dev_list);
ExInitializeFastMutex(&pdrvr_ext->dev_list_mutex);
pdriver->disp_tbl.version = 1;
pdriver->disp_tbl.dev_connect = umss_connect;
pdriver->disp_tbl.dev_disconnect = umss_disconnect;
pdriver->disp_tbl.dev_stop = umss_stop;
pdriver->disp_tbl.dev_reserved = NULL;
if ((pdrvr_ext->port_dev_obj = umss_create_port_device(dev_mgr, pdriver)) == NULL)
{
usb_free_mem(pdriver->driver_ext);
pdriver->driver_ext = NULL;
pdriver->driver_ext_size = 0;
pdriver->disp_tbl.dev_connect = NULL;
pdriver->disp_tbl.dev_stop = NULL;
pdriver->disp_tbl.dev_disconnect = NULL;
return FALSE;
}
umss_load_class_driver(NULL);
// umss_schedule_workitem( NULL, umss_load_class_driver, NULL, 0 );
usb_dbg_print(DBGLVL_MAXIMUM, ("umss_driver_init(): umss driver is initialized\n"));
return TRUE;
}
BOOLEAN
umss_driver_destroy(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER pdriver)
{
PUMSS_DRVR_EXTENSION pdrvr_ext;
if (dev_mgr == NULL || pdriver == NULL)
return FALSE;
pdrvr_ext = (PUMSS_DRVR_EXTENSION) pdriver->driver_ext;
umss_delete_port_device(pdrvr_ext->port_dev_obj);
pdrvr_ext->port_dev_obj = NULL;
ASSERT(IsListEmpty(&pdrvr_ext->dev_list) == TRUE);
usb_free_mem(pdriver->driver_ext);
pdriver->driver_ext = NULL;
pdriver->driver_ext_size = 0;
usb_dbg_print(DBGLVL_MAXIMUM, ("umss_driver_destroy(): umss driver is destroyed\n"));
return TRUE;
}
PDEVICE_OBJECT
umss_create_device(PUSB_DEV_MANAGER dev_mgr, PUSB_DRIVER umss_drvr, DEV_HANDLE dev_handle, BOOLEAN is_if)
{
CHAR dev_name[64], dev_id;
STRING string;
NTSTATUS status;
PDEVICE_OBJECT pdev;
UNICODE_STRING name_string, symb_link;
PUMSS_DRVR_EXTENSION pdrvr_ext;
PUMSS_DEVICE_EXTENSION pdev_ext;
usb_dbg_print(DBGLVL_MAXIMUM, ("umss_create_device(): entering...\n"));
pdrvr_ext = (PUMSS_DRVR_EXTENSION) umss_drvr->driver_ext;
dev_id = (UCHAR) dev_id_from_handle(dev_handle); // pdrvr_ext->dev_count;
if (is_if == FALSE)
sprintf(dev_name, "\\Device\\umssdev_%d", (int)dev_id);
else
sprintf(dev_name, "\\Device\\umssifdev_%d", (int)dev_id);
RtlInitString(&string, dev_name);
RtlAnsiStringToUnicodeString(&name_string, &string, TRUE);
pdev = NULL;
status = IoCreateDevice(dev_mgr->usb_driver_obj,
sizeof(UMSS_DEVICE_EXTENSION),
&name_string,
FILE_USB_DEV_TYPE,
0,
TRUE,
&pdev);
if (status == STATUS_SUCCESS)
{
//
// We do direct io
//
pdev->Flags |= DO_DIRECT_IO;
pdev->Flags &= ~DO_DEVICE_INITIALIZING;
pdev->StackSize = 2; //one for fdo, one for file device obj
pdev_ext = (PUMSS_DEVICE_EXTENSION) pdev->DeviceExtension;
//may be accessed by other thread
ExAcquireFastMutex(&pdrvr_ext->dev_list_mutex);
InsertTailList(&pdrvr_ext->dev_list, &pdev_ext->dev_obj_link);
pdrvr_ext->dev_count++;
ExReleaseFastMutex(&pdrvr_ext->dev_list_mutex);
if (is_if)
pdev_ext->flags |= UMSS_DEV_FLAG_IF_DEV;
pdev_ext->umss_dev_id = dev_id;
pdev_ext->pdo = pdev;
pdev_ext->dev_handle = dev_handle;
pdev_ext->dev_mgr = dev_mgr;
pdev_ext->pdriver = umss_drvr;
pdev_ext->dev_ext_hdr.type = NTDEV_TYPE_CLIENT_DEV;
pdev_ext->dev_ext_hdr.dispatch = umss_dispatch_routine;
pdev_ext->dev_ext_hdr.start_io = umss_start_io;
pdev_ext->dev_ext_hdr.dev_mgr = dev_mgr;
if (is_if == FALSE)
sprintf(dev_name, "\\DosDevices\\umssdev%d", (int)dev_id);
else
sprintf(dev_name, "\\DosDevices\\umssifdev%d", (int)dev_id);
RtlInitString(&string, dev_name);
RtlAnsiStringToUnicodeString(&symb_link, &string, TRUE);
IoCreateSymbolicLink(&symb_link, &name_string);
RtlFreeUnicodeString(&symb_link);
KeInitializeEvent(&pdev_ext->sync_event, SynchronizationEvent, FALSE);
KeInitializeSpinLock(&pdev_ext->dev_lock);
}
RtlFreeUnicodeString(&name_string);
return pdev;
}
BOOLEAN
umss_connect(PDEV_CONNECT_DATA param, DEV_HANDLE dev_handle)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?