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