📄 umss.c
字号:
/*++
Copyright (c) 1999-2001 Microsoft Corporation
Module Name:
UMSS.c
Abstract:
USB device driver for USB storage device
Main module
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) 1999-2001 Microsoft Corporation. All Rights Reserved.
Revision History:
01/13/99: MRB Adapted from BULKUSB DDK sample.
--*/
#define GLOBAL_VARS
#include "wdm.h"
#include "stdarg.h"
#include "stdio.h"
#include "usbdi.h"
#include "usbdlib.h"
#include "umss.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
--*/
{
#if DBG
// should be done before any debug output is done.
// read our debug verbosity level from the registry
UMSS_GetRegistryDword( UMSS_REGISTRY_PARAMETERS_PATH, //absolute registry path
L"DebugLevel", // REG_DWORD ValueName
&UMSS_DebugLevel ); // Value receiver
#endif
ENTER(DriverEntry);
UMSS_KdPrint(DBGLVL_DEFAULT, ("RegistryPath=\n %ws\n", RegistryPath->Buffer ));
// Remember our driver object, for when we create our child PDO
UMSSDriverObject = DriverObject;
// Create dispatch points for create, close, unload
DriverObject->MajorFunction[IRP_MJ_CREATE] = UMSS_DispatchIrp;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = UMSS_DispatchIrp;
DriverObject->DriverUnload = UMSS_Unload;
// User mode DeviceIoControl() calls will be routed here
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = UMSS_DispatchIrp;
// User mode ReadFile()/WriteFile() calls will be routed here
DriverObject->MajorFunction[IRP_MJ_WRITE] = UMSS_DispatchIrp;
DriverObject->MajorFunction[IRP_MJ_READ] = UMSS_DispatchIrp;
// routines for handling system PNP and power management requests
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = UMSS_DispatchIrp;
DriverObject->MajorFunction[IRP_MJ_PNP] = UMSS_DispatchIrp;
DriverObject->MajorFunction[IRP_MJ_POWER] = UMSS_DispatchIrp;
// The Functional Device Object (FDO) will not be created for PNP devices until
// this routine is called upon device plug-in.
DriverObject->DriverExtension->AddDevice = UMSS_PnPAddDevice;
RETURN(STATUS_SUCCESS, DriverEntry);
}
NTSTATUS
UMSS_DispatchIrp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
IRP dispatch routine.
Arguments:
DeviceObject - pointer to our FDO (Functional Device Object)
Irp - pointer to an I/O Request Packet
Return Value:
NT status code
--*/
{
PIO_STACK_LOCATION IrpStack;
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_EXTENSION DeviceExtension;
ENTER(UMSS_DispatchIrp);
DeviceExtension = DeviceObject->DeviceExtension;
IrpStack = IoGetCurrentIrpStackLocation (Irp);
if (DO_FDO == DeviceExtension->DeviceObjectType)
{
switch (IrpStack->MajorFunction)
{
case IRP_MJ_SYSTEM_CONTROL:
ntStatus = UMSS_ProcessSysControlIrp(DeviceObject, Irp);
break;
case IRP_MJ_PNP:
ntStatus = UMSS_ProcessPnPIrp(DeviceObject, Irp);
break;
case IRP_MJ_POWER:
ntStatus = UMSS_ProcessPowerIrp(DeviceObject, Irp);
break;
}
}
else if (DO_PDO == DeviceExtension->DeviceObjectType)
{
switch (IrpStack->MajorFunction)
{
case IRP_MJ_PNP:
ntStatus = UMSS_PdoProcessPnPIrp(DeviceObject, Irp);
break;
case IRP_MJ_POWER:
ntStatus = UMSS_PdoProcessPowerIrp(DeviceObject, Irp);
break;
}
Irp->IoStatus.Status = ntStatus;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
RETURN(ntStatus, UMSS_DispatchIrp);
}
NTSTATUS
UMSS_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;
ENTER(UMSS_ProcessSysControlIrp);
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;
UMSS_IncrementIoCount(DeviceObject);
UMSS_ASSERT( IRP_MJ_SYSTEM_CONTROL == irpStack->MajorFunction );
IoCopyCurrentIrpStackLocationToNext(Irp);
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
UMSS_DecrementIoCount(DeviceObject);
RETURN(ntStatus, UMSS_ProcessSysControlIrp);
}
VOID
UMSS_Unload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
Free all the allocated resources, etc.
Arguments:
DriverObject - pointer to a driver object
Return Value:
NONE
--*/
{
ENTER(UMSS_Unload);
//
// 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:
//
UMSS_ASSERT( gExAllocCount == 0 );
EXIT(UMSS_Unload);
}
NTSTATUS
UMSS_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;
PDEVICE_EXTENSION deviceExtension;
USHORT i;
ENTER(UMSS_CreateDeviceObject);
ntStatus = IoCreateDevice(
DriverObject,
sizeof (DEVICE_EXTENSION),
NULL,
FILE_DEVICE_UNKNOWN,
FILE_AUTOGENERATED_DEVICE_NAME,
FALSE,
DeviceObject
);
if (NT_SUCCESS(ntStatus))
{
deviceExtension = (PDEVICE_EXTENSION) ((*DeviceObject)->DeviceExtension);
}
UMSS_KdPrintCond(
DBGLVL_DEFAULT,
(!(NT_SUCCESS(ntStatus))),
("UMSS_CreateDeviceObject() IoCreateDevice() FAILED\n"));
if (!NT_SUCCESS(ntStatus))
{
RETURN(ntStatus, UMSS_CreateDeviceObject);
}
deviceExtension->DeviceObjectType = DO_FDO;
//default maximum transfer size per io request
deviceExtension->MaximumTransferSize = UMSS_MAX_TRANSFER_SIZE ;
// 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);
RETURN(ntStatus, UMSS_CreateDeviceObject);
}
NTSTATUS
UMSS_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.
Arguments:
DeviceObject - pointer to the physical device object (PDO)
Urb - pointer to an already-formatted Urb request block
Return Value:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -