⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uscrusb.c

📁 usblsccid-0.9.2: ED1x Smart Card Reader Driver
💻 C
📖 第 1 页 / 共 4 页
字号:
/*++

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 + -