📄 afunc.cpp
字号:
// =====[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 + -