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

📄 afunc.cpp

📁 Skeleton for implementing a Windows PC/SC Smartcard Reader.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// =====[afunc.cpp]=======================================================================
//  Description:        Source file (afunc.cpp)
//  Compiled:           MS-VC++
//  Version:            .NET
//  Revisions:
//  REV         DATE                BY           DESCRIPTION
//  ------  --------------      ----------    --------------------------------------
//  1.01      2001/01/01           BDS           Initial version.
//    
//  This source file (afunc.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 ADD_FUN_CPP
#define ADD_FUN_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, 4)
#pragma warning (disable : 4244)
#pragma warning (disable : 4127)
UCHAR RESULT_OK[2]                        = {0x90, 0x00};
UCHAR RESULT_FUNCTION_IS_NOT_SUPPORTED[2] = {0x6A, 0x81};
UCHAR RESULT_LENGTH_IS_NOT_CORRECT[2]     = {0x67, 0x00};
UCHAR RESULT_MEMORY_ERROR[2]              = {0x65, 0x81};
UCHAR RESULT_P1_P2_NOT_CORRECT[2]         = {0x6A, 0x00};
#ifdef USE_EVENT_LOG
static ULONG LogLevel;
#endif

//<summary>
//  ======================================================================
//<newpara>	Author :BD		Date : 04-12-2001		</newpara>
//  ======================================================================
//<newpara>	Function :		WorkWithFile</newpara>
//<newpara>	Comments :										</newpara>
//</summary>
//Parameters :
//	<param name="pData[]">                  				       </param>
//	<param name="uSize">                    				       </param>
//	<param name="bRead">                    				       </param>
//<returns> </returns>
// ======================================================================
NTSTATUS WorkWithFile(IN OUT UCHAR pData[], IN OUT ULONG& uSize, IN bool bRead)
{
    KIRQL                _IRQL                   = KeGetCurrentIrql();
    IO_STATUS_BLOCK      _IO_STATUS_BLOCK;
    OBJECT_ATTRIBUTES    InitializedAttributes;
    UNICODE_STRING       wFileName;
    HANDLE               _handle                 = NULL;
    NTSTATUS             status                  = STATUS_SUCCESS;
    __try
    {   
        if (_IRQL <= PASSIVE_LEVEL)
        {
            RtlInitUnicodeString(&wFileName, FILE_NAME);
            InitializeObjectAttributes(&InitializedAttributes, &wFileName, OBJ_CASE_INSENSITIVE,
                NULL, NULL);
            if ((status = ZwCreateFile(&_handle, FILE_WRITE_DATA | FILE_READ_DATA,
                &InitializedAttributes, &_IO_STATUS_BLOCK, 0, FILE_ATTRIBUTE_NORMAL, 
                FILE_SHARE_WRITE | FILE_SHARE_READ, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0))
                == STATUS_SUCCESS)
            {
                if (!bRead)
                {
                    // Write the data
                    if (!(status = ZwWriteFile(_handle, NULL, NULL, NULL, &_IO_STATUS_BLOCK, pData,
                        uSize, NULL, NULL)))
                        uSize = _IO_STATUS_BLOCK.Information;
                    else 
                        uSize = 0;
                }
                else
                {
                    // Read the data
                    if ((status = ZwReadFile(_handle, NULL, NULL, NULL, &_IO_STATUS_BLOCK, pData,
                        uSize, NULL, NULL)) == STATUS_SUCCESS)
                        uSize = _IO_STATUS_BLOCK.Information;
                    else 
                        uSize = 0;
                }
            }
        }
        else
            // KIRQ > Passive level
            status = STATUS_WRONG_IRQL;
    }
    __finally
    {    
        if (!_handle)
            ZwClose(_handle);
    }
    return status;
}

//<summary>
//  ======================================================================
//<newpara>	Author :BD		Date : 04-12-2001		</newpara>
//  ======================================================================
//<newpara>	Function :		SendCmdReader</newpara>
//<newpara>	Comments :	// This procedure implements Smartcard + SC reader part
//</newpara>
//</summary>
//Parameters :
//	<param name="Request_Buffer[]">         				       </param>
//	<param name="Request_BufferLength">     				       </param>
//	<param name="Reply_Buffer[]">           				       </param>
//	<param name="Reply_BufferLength">       				       </param>
//	<param name="DeviceObject">             				       </param>
//<returns> </returns>
// ======================================================================
NTSTATUS SendCmdReader(UCHAR Request_Buffer[], ULONG Request_BufferLength,
                       UCHAR Reply_Buffer[], ULONG& Reply_BufferLength,
                       IN PDEVICE_OBJECT DeviceObject)
{
    NTSTATUS     status                  = STATUS_SUCCESS;
    BYTE         bTemp[MEMORY_BUF_SIZE]  = {0};
    DWORD        dwTemp                  = MEMORY_BUF_SIZE;
    switch (Request_Buffer[1])
    {
    case 0xA4:
        {
            // SELECT ( ISO 7816 )
            // The command SELECT in it's simplified form
            RtlCopyMemory(Reply_Buffer, RESULT_OK, 2);
            Reply_BufferLength = 2;
            break;
        }
    case 0xB0:

        {  
            // READ_BINARY ( ISO 7816 )
            // The Request_BufferLength = 5, it means we should read Request_Buffer[4] bytes
            // the  offset is stored in P1,P2 accordingly to ISO 7816
            if ((Request_Buffer[4] > MEMORY_BUF_SIZE) ||(Request_Buffer[4] == 0))
            {
                RtlCopyMemory(Reply_Buffer, RESULT_LENGTH_IS_NOT_CORRECT, 2);
                Reply_BufferLength = 2;
                status = STATUS_DEVICE_DATA_ERROR;
                break;
            }
            if ((Request_Buffer[2] + Request_Buffer[3] + Request_Buffer[4] >= MEMORY_BUF_SIZE) ||(Request_Buffer[2] >= MEMORY_BUF_SIZE)
                ||(Request_Buffer[3] >= MEMORY_BUF_SIZE))
            {
                RtlCopyMemory(Reply_Buffer, RESULT_P1_P2_NOT_CORRECT, 2);
                Reply_BufferLength = 2;
                status = STATUS_DEVICE_DATA_ERROR;
                break;
            }
            // Let's read 
            dwTemp = MEMORY_BUF_SIZE;
            if ((WorkWithFile(bTemp, dwTemp)) ||(dwTemp != MEMORY_BUF_SIZE))
            {
                RtlCopyMemory(Reply_Buffer, RESULT_MEMORY_ERROR, 2);
                Reply_BufferLength = 2;
                status = STATUS_DEVICE_DATA_ERROR;
                break;
            }
            else
            {
                // Let's imitate real reading 
                RtlCopyMemory(Reply_Buffer, &bTemp[Request_Buffer[2]], Request_Buffer[4]);
                RtlCopyMemory(&Reply_Buffer[Request_Buffer[4]], RESULT_OK, 2);
                Reply_BufferLength = Request_Buffer[4] + 2;
                ReportEvent(LOG_LEVEL_DEBUG,MSG_READING_DATA,ERRORLOG_READING_DATA,
                    (PVOID)DeviceObject,NULL,(ULONG*)Reply_Buffer, (Request_Buffer[4]+2) / 2,NULL, 0 );
            }
            break;
        }
    case 0xD0:
        {
            // WRITE_BINARY ( ISO 7816 )
            // At first we have to read ALL data from BIN file 
            // The Request_BufferLength = 5, it means we should read Request_Buffer[4] bytes
            // the  offset is stored in P1,P2 accordingly to ISO 7816
            if ((Request_Buffer[4] > MEMORY_BUF_SIZE) ||(Request_Buffer[4] == 0))
            {
                RtlCopyMemory(Reply_Buffer, RESULT_LENGTH_IS_NOT_CORRECT, 2);
                Reply_BufferLength = 2;
                status = STATUS_DEVICE_DATA_ERROR;
                break;
            };
            if ((Request_Buffer[2] + Request_Buffer[3] + Request_Buffer[4] >= MEMORY_BUF_SIZE) ||(Request_Buffer[2] >= MEMORY_BUF_SIZE)
                ||(Request_Buffer[3] >= MEMORY_BUF_SIZE))
            {
                RtlCopyMemory(Reply_Buffer, RESULT_P1_P2_NOT_CORRECT, 2);
                Reply_BufferLength = 2;
                status = STATUS_DEVICE_DATA_ERROR;
                break;
            };

            dwTemp = MEMORY_BUF_SIZE;
            if ((WorkWithFile(bTemp, dwTemp)) ||(dwTemp != MEMORY_BUF_SIZE))
            {
                RtlCopyMemory(Reply_Buffer, RESULT_MEMORY_ERROR, 2);
                Reply_BufferLength = 2;
                status = STATUS_DEVICE_DATA_ERROR;
                break;
            }
            else
            {
                RtlCopyMemory(&bTemp[Request_Buffer[2]], &Request_Buffer[5], Request_Buffer[4]);
                // Let's write modified array to file
                dwTemp = MEMORY_BUF_SIZE;
                if ((WorkWithFile(bTemp, dwTemp, false)) ||(dwTemp != MEMORY_BUF_SIZE))
                {
                    RtlCopyMemory(Reply_Buffer, RESULT_MEMORY_ERROR, 2);
                    Reply_BufferLength = 2;
                    status = STATUS_DEVICE_DATA_ERROR;
                    break;
                }
                else
                {
                    RtlCopyMemory(Reply_Buffer, RESULT_OK, 2);
                    Reply_BufferLength = 2;    
                }
            }
            break;
        }
    default :
        {
            RtlCopyMemory(Reply_Buffer, RESULT_FUNCTION_IS_NOT_SUPPORTED, 2);
            Reply_BufferLength = 2;
        }
    }
    return status;
    UNREFERENCED_PARAMETER(Request_BufferLength);
}
#ifdef USE_WORK_THREAD
//<summary>
//  ======================================================================
//<newpara>	Author :BD		Date : 04-12-2001		</newpara>
//  ======================================================================
//<newpara>	Function :		WorkerThreadMain</newpara>
//<newpara>	Comments :										</newpara>
//</summary>
//Parameters :
//	<param name="pContext">                 				       </param>
//<returns> </returns>
// ======================================================================
void WorkerThreadMain(IN PVOID pContext) 
{
    PDEVICE_EXTENSION      pDevExt                = (PDEVICE_EXTENSION)pContext;
    PSMARTCARD_EXTENSION	pSmartcardExtension    = &pDevExt->SmartcardExtension;
    NTSTATUS               status                 = STATUS_SUCCESS;
    // Worker thread runs at higher priority than user threads - it sets its own priority
    KeSetPriorityThread(KeGetCurrentThread(),LOW_REALTIME_PRIORITY);
    // Now enter the main IRP-processing loop
    while (TRUE)

⌨️ 快捷键说明

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