📄 uscrusb.c
字号:
/*++
Copyright (c) 2004 QWY MicroSystem Inc.
Module Name:
uscrusb.c
Abstract:
USB SmartCard Reader driver for CCID/lsCCID compatible device.
Environment:
kernel mode only
Notes:
Revision History:
4/24/2005: Adapted from BULKUSB DDK sample.
--*/
#include "uscr.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
USCR_GetRegistryDword( USCR_REGISTRY_PARAMETERS_PATH, //absolute registry path
L"DebugLevel", // REG_DWORD ValueName
&gDebugLevel ); // Value receiver
#endif
USCR_KdPrint( DBGLVL_MINIMUM ,("Entering DriverEntry(), RegistryPath=\n %ws\n", RegistryPath->Buffer ));
//
// Create dispatch points for create, close, unload
DriverObject->MajorFunction[IRP_MJ_CREATE] = USCR_Create;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = USCR_Close;
DriverObject->MajorFunction[IRP_MJ_CLEANUP]= USCR_Cleanup;
DriverObject->DriverUnload = USCR_Unload;
// User mode DeviceIoControl() calls will be routed here
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = USCR_ProcessIOCTL;
// routines for handling system PNP and power management requests
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = USCR_ProcessSysControlIrp;
DriverObject->MajorFunction[IRP_MJ_PNP] = USCR_ProcessPnPIrp;
DriverObject->MajorFunction[IRP_MJ_POWER] = USCR_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 = USCR_PnPAddDevice;
USCR_KdPrint( DBGLVL_DEFAULT,("exiting DriverEntry (%x)\n", ntStatus));
return ntStatus;
}
NTSTATUS
USCR_Close(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the dispatch table routine for IRP_MJ_CLOSE.
It handles user mode CloseHandle() calls for a pipe
It closes the File Object for the pipe handle it represents.
Arguments:
DeviceObject - pointer to our FDO (Functional Device Object )
Return Value:
NT status code
--*/
{
NTSTATUS ntStatus;
NTSTATUS actStat;
PFILE_OBJECT fileObject;
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
PUSBD_PIPE_INFORMATION pipeHandle = NULL;
USCR_KdPrint( DBGLVL_DEFAULT,("entering USCR_Close\n"));
USCR_IncrementIoCount(DeviceObject);
deviceExtension = DeviceObject->DeviceExtension;
irpStack = IoGetCurrentIrpStackLocation (Irp);
deviceExtension->bFileOpened = FALSE;
deviceExtension->OpenPipeCount = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
ntStatus = Irp->IoStatus.Status;
IoCompleteRequest (Irp,
IO_NO_INCREMENT
);
// try to power down device if this is the last pipe
actStat = USCR_SelfSuspendOrActivate( DeviceObject, TRUE );
USCR_DecrementIoCount(DeviceObject);
USCR_KdPrint( DBGLVL_DEFAULT,("exit USCR_Close status %x\n",ntStatus));
return ntStatus;
}
NTSTATUS
USCR_Create(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This is the dispatch table routine for IRP_MJ_CREATE.
It's the entry point for CreateFile() calls
user mode apps may open "<name genned fron GUID>.\yy"
where yy is the internal pipe id
Arguments:
DeviceObject - pointer to our FDO ( Functional Device Object )
Return Value:
NT status code
--*/
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PFILE_OBJECT fileObject;
PIO_STACK_LOCATION irpStack;
PDEVICE_EXTENSION deviceExtension;
ULONG i, ix;
NTSTATUS actStat;
PUSBD_INTERFACE_INFORMATION interface;
PUSBD_PIPE_INFORMATION PipeInfo;
deviceExtension = DeviceObject->DeviceExtension;
interface = deviceExtension->UsbInterface;
USCR_KdPrint( DBGLVL_DEFAULT,("entering USCR_Create\n"));
USCR_IncrementIoCount(DeviceObject);
// Can't accept a new io request if:
// 1) device is removed,
// 2) has never been started,
// 3) is stopped,
// 4) has a remove request pending,
// 5) has a stop device pending
if ( !USCR_CanAcceptIoRequests( DeviceObject ) ) {
ntStatus = STATUS_DELETE_PENDING;
USCR_KdPrint( DBGLVL_DEFAULT,("ABORTING USCR_Create\n"));
goto done;
}
irpStack = IoGetCurrentIrpStackLocation (Irp);
// test if the device has been opened already
//In order to not exclusive open by smart card service. yanglq 2005-6-25
#ifdef EXCLUSIVE_OPEN
if (InterlockedCompareExchange(
&deviceExtension->bFileOpened,
TRUE,
FALSE) == FALSE) {
#endif
USCR_KdPrint( DBGLVL_DEFAULT,("USCR_Create.\n"));
deviceExtension->OpenPipeCount = interface->NumberOfPipes;
// try to power up device if its not in D0
actStat = USCR_SelfSuspendOrActivate( DeviceObject, FALSE );
#ifdef EXCLUSIVE_OPEN
} else {
// the device is already in use
ntStatus = STATUS_UNSUCCESSFUL;
}
#endif
done:
Irp->IoStatus.Status = ntStatus;
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp,
IO_NO_INCREMENT
);
USCR_DecrementIoCount(DeviceObject);
USCR_KdPrint( DBGLVL_DEFAULT,("exit USCR_Create %x\n", ntStatus));
return ntStatus;
}
NTSTATUS
USCR_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;
USCR_KdPrint( DBGLVL_HIGH, ( "enter USCR_ProcessSysControlIrp()\n") );
USCR_IncrementIoCount(DeviceObject);
USCR_ASSERT( IRP_MJ_SYSTEM_CONTROL == irpStack->MajorFunction );
IoCopyCurrentIrpStackLocationToNext(Irp);
ntStatus = IoCallDriver(stackDeviceObject,
Irp);
USCR_DecrementIoCount(DeviceObject);
USCR_KdPrint( DBGLVL_HIGH,("USCR_ProcessSysControlIrp() Exit USCR_ProcessSysControlIrp %x\n", ntStatus));
return ntStatus;
}
VOID
USCR_Unload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
Free all the allocated resources, etc.
Arguments:
DriverObject - pointer to a driver object
Return Value:
--*/
{
USCR_KdPrint( DBGLVL_DEFAULT,("enter USCR_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:
//
USCR_ASSERT( gExAllocCount == 0 );
USCR_KdPrint( DBGLVL_DEFAULT,("exit USCR_Unload\n"));
}
NTSTATUS
USCR_SymbolicLink(
IN PDEVICE_OBJECT DeviceObject,
IN OUT PUNICODE_STRING deviceLinkUnicodeString
)
/*++
Routine Description:
This routine is called to create and initialize
a GUID-based symbolic link to our device to be used to open/create
instances of us from user mode.
Called from USCR_CreateDeviceObject() to create the link.
Arguments:
DeviceObject - pointer to our Physical Device Object ( PDO )
deviceLinkUnicodeString - Points to a unicode string structure allocated by the caller.
If this routine is successful, it initializes the unicode string and allocates
the string buffer containing the kernel-mode path to the symbolic link for this
device interface.
Return Value:
STATUS_SUCCESS if successful,
STATUS_UNSUCCESSFUL otherwise
--*/{
NTSTATUS ntStatus = STATUS_SUCCESS;
// Create the symbolic link
// IoRegisterDeviceInterface registers device functionality (a device interface)
// that a driver will enable for use by applications or other system components.
ntStatus = IoRegisterDeviceInterface(
DeviceObject,
(LPGUID)&SmartCardReaderGuid,
NULL,
deviceLinkUnicodeString);
USCR_KdPrintCond( DBGLVL_MEDIUM, (!(NT_SUCCESS(ntStatus))),
("FAILED to IoRegisterDeviceInterface()\n"));
if (NT_SUCCESS(ntStatus)) {
// IoSetDeviceInterfaceState enables or disables a previously
// registered device interface. Applications and other system components
// can open only interfaces that are enabled.
ntStatus = IoSetDeviceInterfaceState(deviceLinkUnicodeString, TRUE);
USCR_KdPrintCond( DBGLVL_MEDIUM,
(!(NT_SUCCESS(ntStatus))),
("FAILED to IoSetDeviceInterfaceState()\n"));
USCR_KdPrintCond( DBGLVL_MEDIUM,
((NT_SUCCESS(ntStatus))),
("SUCCEEDED IoSetDeviceInterfaceState()\n"));
}
return ntStatus;
}
NTSTATUS
USCR_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;
UNICODE_STRING deviceLinkUnicodeString;
PDEVICE_EXTENSION deviceExtension;
USHORT i;
USCR_KdPrint( DBGLVL_DEFAULT,("enter USCR_CreateDeviceObject() \n"));
ntStatus = USCR_SymbolicLink( PhysicalDeviceObject, &deviceLinkUnicodeString );
USCR_KdPrintCond( DBGLVL_DEFAULT,
(NT_SUCCESS(ntStatus)),
("USCR_CreateDeviceObject() SUCCESS Create GUID_CLASS_USCR_BULK-based Device name\n %ws\n Length decimal %d, MaximumLength decimal %d\n",
deviceLinkUnicodeString.Buffer,
deviceLinkUnicodeString.Length,
deviceLinkUnicodeString.MaximumLength));
USCR_KdPrintCond( DBGLVL_DEFAULT,
(!(NT_SUCCESS(ntStatus))),
("USCR_CreateDeviceObject() FAILED to Create GUID_CLASS_USCR_BULK-based Device name\n"));
if (NT_SUCCESS(ntStatus)) {
ntStatus = IoCreateDevice (DriverObject,
sizeof (DEVICE_EXTENSION),
NULL,
FILE_DEVICE_SMARTCARD,
FILE_AUTOGENERATED_DEVICE_NAME,
FALSE,
DeviceObject);
if (NT_SUCCESS(ntStatus)) {
deviceExtension = (PDEVICE_EXTENSION) ((*DeviceObject)->DeviceExtension);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -