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

📄 pcsc_drv.cpp

📁 Skeleton for implementing a Windows PC/SC Smartcard Reader.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// =====[pcsc_drv.cpp]=======================================================================
//  Description:        Source file (pcsc_drv.cpp)
//  Compiled:           MS-VC++
//  Version:            .NET
//  Revisions:
//  REV         DATE                BY           DESCRIPTION
//  ------  --------------      ----------    --------------------------------------
//  1.01      2001/01/01           BDS           Initial version.
//    
//  This source file (pcsc_drv.cpp) is  Copyright(c) 2001 Dmitry Basko. 
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that: 
//  1.  source code distributions retain the above copyright notice and this 
//      paragraph in its entirety;
//  2.  distributions including binary code include the above copyright notice
//      and this paragraph in its entirety in the documentation or other materials
//      provided with the distribution;
//  3.  all advertising materials mentioning features or use of this software 
//      display the following acknowledgement;
//  "This product includes software developed by Dmitry Basko."
//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
//  WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
//  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// ========================================================================================= 
#pragma once
#ifndef DRIVER_CPP
#define DRIVER_CPP
// This programm is compiled ONLY for WIN32 and M_IX86 processor
#if defined(_WIN32) && defined(_M_IX86)
#include   "pcsc_drv.h"
#pragma warning(push, 3)
#pragma warning(disable : 4514)

BYTE bATR[13] = {0x3b, 0x89, 0x40, 0x14, 0x47, 0x47, 0x32, 0x34, 0x4d, 0x35, 0x32, 0x38, 0x30};
UCHAR ATRLength = 13;
static ULONG dataRatesSupported[] = { 9600, 19200, 38400, 57600, 115200 };

//<summary>
//  ======================================================================
//<newpara>	Author :BD		Date : 01-01-2001		</newpara>
//  ======================================================================
//<newpara>	Function :		DriverEntry</newpara>
//<newpara>	Comments :										</newpara>
//</summary>
//Parameters :
//	<param name="DriverObject">             				       </param>
//	<param name="RegistryPath">             				       </param>
//<returns> </returns>
// ======================================================================
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    NTSTATUS            status              = STATUS_SUCCESS;
    PDEVICE_OBJECT      pDeviceObject       = NULL;
    PDEVICE_EXTENSION   pDeviceExtension    = NULL;
    KdPrint(("%sDriverEntry\n",HEAD));
#ifdef MAX_DEBUG_LEVEL
    SmartcardSetDebugLevel(DEBUG_ALL);
#endif
#ifdef USE_EVENT_LOG
        InitializeEventLog(DriverObject);
#endif
        // tell the system our entry points
        DriverObject->MajorFunction[IRP_MJ_CREATE] = VdCreate;
        DriverObject->MajorFunction[IRP_MJ_CLOSE] = VdClose;
        DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VdCleanUp;
        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VdDeviceControl;
        DriverObject->DriverUnload = VdDriverUnload;
        if ((status = VdCreateDevice(DriverObject)) == STATUS_SUCCESS)
        {
#ifdef USE_SYSTEM_THREAD
            pDeviceObject = (PDEVICE_OBJECT)DriverObject->DeviceObject;
            pDeviceExtension = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;
            // Let's prepare for launch SYSTEM THREAD
            if ((pDeviceExtension->_PIO_WORKITEM = (PIO_WORKITEM) IoAllocateWorkItem(pDeviceObject)) != NULL)
            {
                if ((pDeviceExtension->pMemory_Buf = (PUCHAR)ExAllocatePool(NonPagedPool, MEMORY_BUF_SIZE)) != NULL)
                {
                    RtlFillMemory(pDeviceExtension->pMemory_Buf, MEMORY_BUF_SIZE, 0xAA);
                    pDeviceExtension->uSizeOfData = MEMORY_BUF_SIZE;
                    // Let's read memory from file
                    IoQueueWorkItem(pDeviceExtension->_PIO_WORKITEM, (PIO_WORKITEM_ROUTINE)Work_SystemThread,
                        DelayedWorkQueue , pDeviceExtension->pMemory_Buf);
                }
                else
                {
                    KdPrint(("\t%sMEMORY BUF was not allocated\n",HEAD));
                    if (pDeviceExtension->DeviceName.Buffer != NULL)
                        // disble our device so no one can open it
                        IoSetDeviceInterfaceState(&pDeviceExtension->DeviceName, FALSE);
                    // Wait until we can safely unload the device
                    SmartcardExit(&pDeviceExtension->SmartcardExtension);
                    //	delete the symbolic link
                    if (pDeviceExtension->DeviceName.Buffer != NULL)
                    {
                        RtlFreeUnicodeString(&pDeviceExtension->DeviceName);
                        pDeviceExtension->DeviceName.Buffer = NULL;
                    }
                    if (pDeviceExtension->SmartcardExtension.ReaderExtension != NULL)
                    {
                        ExFreePool(pDeviceExtension->SmartcardExtension.ReaderExtension);
                        pDeviceExtension->SmartcardExtension.ReaderExtension = NULL;
                    }
                    //	delete the device object
                    IoDeleteDevice(pDeviceObject);
                    status =  (STATUS_INSUFFICIENT_RESOURCES);
                }
            }
            else
            {
                KdPrint(("\t%sPIO_WORKITEM was not allocated\n",HEAD));
                if (pDeviceExtension->DeviceName.Buffer != NULL)
                    // disble our device so no one can open it
                    IoSetDeviceInterfaceState(&DeviceExtension->DeviceName, FALSE);
                // Wait until we can safely unload the device
                SmartcardExit(&pDeviceExtension->SmartcardExtension);
                //	delete the symbolic link
                if (pDeviceExtension->DeviceName.Buffer != NULL)
                {
                    RtlFreeUnicodeString(&pDeviceExtension->DeviceName);
                    pDeviceExtension->DeviceName.Buffer = NULL;
                }
                if (pDeviceExtension->SmartcardExtension.ReaderExtension != NULL)
                {
                    ExFreePool(pDeviceExtension->SmartcardExtension.ReaderExtension);
                    pDeviceExtension->SmartcardExtension.ReaderExtension = NULL;
                }
                //	delete the device object
                IoDeleteDevice(pDeviceObject);
                status = (STATUS_INSUFFICIENT_RESOURCES);
            }
#endif   
        }
#ifdef USE_EVENT_LOG
        (!status)? (ReportEvent(LOG_LEVEL_DEBUG,MSG_DRIVER_STARTING,ERRORLOG_DRIVERENTRY,(PVOID)DriverObject,
            NULL,NULL, 0,NULL, 0 )):(ReportEvent(LOG_LEVEL_DEBUG,MSG_DRIVER_STARTING_FAULT,ERRORLOG_DRIVERENTRY_FAULT,(PVOID)DriverObject,
            NULL,(ULONG*)status, 1,NULL, 0 ));
#endif
    return status;
}

//<summary>
//  ======================================================================
//<newpara>	Author :BD		Date : 01-01-2001		</newpara>
//  ======================================================================
//<newpara>	Function :		VdCreateDevice</newpara>
//<newpara>	Comments :										</newpara>
//</summary>
//Parameters :
//	<param name="DriverObject">             				       </param>
//<returns> </returns>
// ======================================================================
NTSTATUS VdCreateDevice(IN  PDRIVER_OBJECT DriverObject)
{
    PDEVICE_OBJECT          pDeviceObject       = NULL;
    NTSTATUS                status              = STATUS_SUCCESS;
    PDEVICE_EXTENSION       pDeviceExtension    = NULL;
    PSMARTCARD_EXTENSION    pSmartcardExtension = NULL;
    PREADER_EXTENSION       pReaderExtension    = NULL;
    UNICODE_STRING          UniDeviceName;
    UNICODE_STRING          LinkName;
    KdPrint(("%sVdCreateDevice\n",HEAD));
    RtlInitUnicodeString(&UniDeviceName, L"\\Device\\InesSUDP");
    // Create the device object
    if ((status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &UniDeviceName, FILE_DEVICE_SMARTCARD,
        0, FALSE, &pDeviceObject)) == STATUS_SUCCESS)
    {
        pDeviceExtension = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;
        RtlZeroMemory(pDeviceExtension, sizeof(DEVICE_EXTENSION));
        pSmartcardExtension = &pDeviceExtension->SmartcardExtension;;
        //	allocate the reader extension
        if ((pReaderExtension = (PREADER_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(READER_EXTENSION))) != NULL)
        {
            RtlZeroMemory(pReaderExtension, sizeof(READER_EXTENSION));
            pSmartcardExtension->ReaderExtension = pReaderExtension;
            // Let's keep callback address to pDeviceExtension
            pSmartcardExtension->ReaderExtension->pDeviceExtension = pDeviceExtension;
            pSmartcardExtension->Version = SMCLIB_VERSION;
            pSmartcardExtension->SmartcardRequest.BufferSize = MIN_BUFFER_SIZE;
            pSmartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
            if ((status = SmartcardInitialize(pSmartcardExtension)) == STATUS_SUCCESS)
            {
                DEVICE_READER_EXTENSION(uStateOfCard) = true; // the card is inserted
                pSmartcardExtension->ReaderFunction[RDF_CARD_POWER]    = VdPowerReader;
                pSmartcardExtension->ReaderFunction[RDF_SET_PROTOCOL]  = VdSetProtocol;
                pSmartcardExtension->ReaderFunction[RDF_TRANSMIT]      = VdTransmit;
                pSmartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = VdCardTracking;
                pSmartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR]  = VdVendorIOCTL;

                strcpy((char *)pSmartcardExtension->VendorAttr.VendorName.Buffer, (char *) "COMRAD");
                pSmartcardExtension->VendorAttr.VendorName.Length =
                    (USHORT) strlen((char*)pSmartcardExtension->VendorAttr.VendorName.Buffer);
                strcpy((char *)pSmartcardExtension->VendorAttr.IfdType.Buffer, (char *) "000001");
                pSmartcardExtension->VendorAttr.IfdType.Length =
                    (USHORT)strlen((char *)pSmartcardExtension->VendorAttr.IfdType.Buffer);
                pSmartcardExtension->VendorAttr.UnitNo = 0;
                pSmartcardExtension->VendorAttr.IfdVersion.BuildNumber = 1;
                pSmartcardExtension->VendorAttr.IfdVersion.VersionMinor = 2;
                pSmartcardExtension->VendorAttr.IfdVersion.VersionMajor = 3;
                pSmartcardExtension->VendorAttr.IfdSerialNo.Length = 0;
                // Set the reader capabilities
                // Clk frequency in KHz encoded as little endian integer
                pSmartcardExtension->ReaderCapabilities.CLKFrequency.Default = 3571;
                pSmartcardExtension->ReaderCapabilities.CLKFrequency.Max = 3571;
                // 4000;
                pSmartcardExtension->ReaderCapabilities.DataRate.Default =
                    pSmartcardExtension->ReaderCapabilities.DataRate.Max = // 10750;
                    dataRatesSupported[0];
                // reader could support higher data rates
                pSmartcardExtension->ReaderCapabilities.DataRatesSupported.List = dataRatesSupported;
                pSmartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
                    sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);
                pSmartcardExtension->ReaderCapabilities.MaxIFSD = 254;
                // This reader supports T=0
                pSmartcardExtension->ReaderCapabilities.SupportedProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
                pSmartcardExtension->ReaderCapabilities.MechProperties = 0;
                pSmartcardExtension->ReaderCapabilities.Channel = 0;
                // Reader type 
                pSmartcardExtension->ReaderCapabilities.ReaderType =  SCARD_READER_TYPE_VENDOR;
                // Now setup information in our deviceExtension
                pSmartcardExtension->ReaderCapabilities.CurrentState = SCARD_PRESENT;
                // SCARD_ABSENT;
                if ((status = SmartcardCreateLink(&LinkName, &UniDeviceName)) == STATUS_SUCCESS)
                {
                    pSmartcardExtension->OsData->DeviceObject = (pDeviceObject);
                    pDeviceObject->Flags |= DO_BUFFERED_IO;
                    pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;    
                    //KdPrint(("SmartcardUpdateCardCapabilities %#X",SmartcardUpdateCardCapabilities(pSmartcardExtension)));            
                }
                else
                {
                    KdPrint(("\t%sCreateDevice SmartCardCreateLink  FAILED\n",HEAD, (ULONG) status));
                    IoDeleteDevice(pDeviceObject);
                    KdPrint(("%sLink was not created\n",HEAD));
                }
            }
            else
            {
                KdPrint(("\t%sCreateDevice SMARTCARDINITIALISE FAILED\n",HEAD, (ULONG) status));
                IoDeleteDevice(pDeviceObject);
            }
        }
        else
            status = STATUS_INSUFFICIENT_RESOURCES;     	
    }
    else
    {
        KdPrint(("\t%sCreateDevice IOCREATEDEVICE FAILED status %#X",HEAD, (ULONG)status));
        if (status == STATUS_OBJECT_NAME_EXISTS)
        {
            KdPrint(("\t%sCreateDevice IOCREATEDEVICE %#X", HEAD, STATUS_OBJECT_NAME_EXISTS));
        }
        if (status == STATUS_OBJECT_NAME_COLLISION)
        {
            KdPrint(("\t%sCreateDevice IOCREATEDEVICE %#X", HEAD, STATUS_OBJECT_NAME_COLLISION));
        }
        if (status == STATUS_INSUFFICIENT_RESOURCES)
        {
            KdPrint(("\t%sCreateDevice IOCREATEDEVICE %#X", HEAD, STATUS_INSUFFICIENT_RESOURCES));
        }
        if (status == STATUS_OBJECT_NAME_INVALID)
        {
            KdPrint(("\t%sCreateDevice IOCREATEDEVICE %#X", HEAD, STATUS_OBJECT_NAME_INVALID));
        }
    }
    KdPrint(("\t%sCreateDevice status %#X", HEAD, status));
    return status;
}

//<summary>
//  ======================================================================
//<newpara>	Author :BD		Date : 01-01-2001		</newpara>
//  ======================================================================
//<newpara>	Function :		VdCreate</newpara>
//<newpara>	Comments :										</newpara>
//</summary>
//Parameters :
//	<param name="DeviceObject">             				       </param>
//	<param name="pIrp">                     				       </param>
//<returns> </returns>
// ======================================================================
NTSTATUS VdCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp)
{
    NTSTATUS status = STATUS_SUCCESS;
    KdPrint(("%sVdCreate\n",HEAD));
    ReportEvent(LOG_LEVEL_DEBUG,MSG_OPENING_HANDLE,ERRORLOG_OPENING_HANDLE,
        (PVOID)DeviceObject,pIrp,NULL, 0,NULL, 0 );
    pIrp->IoStatus.Status = status;
    pIrp->IoStatus.Information = 0;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    return status;
}

//<summary>
//  ======================================================================
//<newpara>	Author :BD		Date : 01-01-2001		</newpara>
//  ======================================================================
//<newpara>	Function :		VdClose</newpara>
//<newpara>	Comments :										</newpara>
//</summary>
//Parameters :
//	<param name="DeviceObject">             				       </param>
//	<param name="pIrp">                     				       </param>
//<returns> </returns>
// ======================================================================
NTSTATUS VdClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp)
{
    KdPrint(("%sVdClose\n",HEAD));
    ReportEvent(LOG_LEVEL_DEBUG,MSG_CLOSING_HANDLE,ERRORLOG_CLOSING_HANDLE,
        (PVOID)DeviceObject,pIrp,NULL, 0,NULL, 0 );
    pIrp->IoStatus.Status = STATUS_SUCCESS;
    pIrp->IoStatus.Information = 0;
    IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    return STATUS_SUCCESS;
}


//<summary>
//  ======================================================================
//<newpara>	Author :BD		Date : 01-01-2001		</newpara>
//  ======================================================================
//<newpara>	Function :		VdDeviceControl</newpara>
//<newpara>	Comments :										</newpara>
//</summary>
//Parameters :
//	<param name="DeviceObject">             				       </param>
//	<param name="pIrp">                     				       </param>
//<returns> </returns>
// ======================================================================
NTSTATUS VdDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP pIrp)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -