📄 tlp3nt.c
字号:
/*++
Copyright (C) 1997, 98 Microsoft Corporation
Module Name:
bulltlp3.c
Abstract:
Smart card driver for Bull TLP3 reader
Author:
Klaus U. Schutz
Environment:
Kernel mode
Revision History :
Nov. 1997 - 1.0 Release
Jan. 1998 - Fix for vendor defined IOCTLs
TLP3SerialIo now writes the whole data packet if GT is 0
Support for higher data rates added
Feb. 1998 - PnP version
--*/
#include <stdio.h>
#include "bulltlp3.h"
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGEABLE, TLP3CreateAndStartDevice)
#pragma alloc_text(PAGEABLE, TLP3StartSerialEventTracking)
#pragma alloc_text(PAGEABLE, TLP3AddDevice)
#pragma alloc_text(PAGEABLE, TLP3CreateDevice)
#pragma alloc_text(PAGEABLE, TLP3RemoveDevice)
#pragma alloc_text(PAGEABLE, TLP3DriverUnload)
#if DBG
#pragma optimize ("", off)
#endif
#ifdef SIMULATION
PWSTR DriverKey;
#endif
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
This routine is called at system initialization time to initialize
this driver.
Arguments:
DriverObject - Supplies the driver object.
RegistryPath - Supplies the registry path for this driver.
Return Value:
STATUS_SUCCESS - We could initialize at least one device.
STATUS_NO_SUCH_DEVICE - We could not initialize even one device.
--*/
{
NTSTATUS status = STATUS_SUCCESS;
ULONG device;
SmartcardDebug(
DEBUG_INFO,
("%s!DriverEntry: Enter - %s %s\n",
DRIVER_NAME,
__DATE__,
__TIME__)
)
//
// we do some stuff in this driver that
// assumes a single digit port number
//
ASSERT(MAXIMUM_SERIAL_READERS < 10);
// Initialize the Driver Object with driver's entry points
DriverObject->DriverUnload = TLP3DriverUnload;
DriverObject->MajorFunction[IRP_MJ_CREATE] = TLP3CreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = TLP3CreateClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TLP3Cleanup;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TLP3DeviceControl;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = TLP3SystemControl;
DriverObject->MajorFunction[IRP_MJ_PNP] = TLP3PnP;
DriverObject->MajorFunction[IRP_MJ_POWER] = TLP3Power;
DriverObject->DriverExtension->AddDevice = TLP3AddDevice;
#ifdef SIMULATION
DriverKey = ExAllocatePool(PagedPool, RegistryPath->Length + sizeof(L""));
if (DriverKey) {
RtlZeroMemory(
DriverKey,
RegistryPath->Length + sizeof(L"")
);
RtlCopyMemory(
DriverKey,
RegistryPath->Buffer,
RegistryPath->Length
);
}
#endif
return status;
}
NTSTATUS
TLP3AddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
/*++
Routine Description:
This routine creates an object for the physical device specified and
sets up the deviceExtension.
--*/
{
PDEVICE_EXTENSION deviceExtension;
NTSTATUS status = STATUS_SUCCESS;
PREADER_EXTENSION readerExtension;
PSMARTCARD_EXTENSION smartcardExtension;
ULONG deviceInstance;
HANDLE regKey = NULL;
PDEVICE_OBJECT DeviceObject = NULL;
// this is a list of our supported data rates
static ULONG dataRatesSupported[] = { 9600, 19200, 38400, 57600, 115200 };
SmartcardDebug(
DEBUG_TRACE,
( "%s!TLP3AddDevice: Enter\n",
DRIVER_NAME)
);
PAGED_CODE();
__try {
// Create the device object
status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_SMARTCARD,
0,
TRUE,
&DeviceObject
);
if (status != STATUS_SUCCESS) {
SmartcardLogError(
DriverObject,
TLP3_CANT_CREATE_DEVICE,
NULL,
0
);
__leave;
}
SmartcardDebug(
DEBUG_TRACE,
( "%s!TLP3CreateDevice: Device created\n",
DRIVER_NAME)
);
// set up the device extension.
deviceExtension = DeviceObject->DeviceExtension;
smartcardExtension = &deviceExtension->SmartcardExtension;
deviceExtension->CloseSerial = IoAllocateWorkItem(
DeviceObject
);
// Used for stop / start notification
KeInitializeEvent(
&deviceExtension->ReaderStarted,
NotificationEvent,
FALSE
);
// Used to keep track of open close calls
deviceExtension->ReaderOpen = FALSE;
KeInitializeSpinLock(&deviceExtension->SpinLock);
// Allocate data struct space for smart card reader
smartcardExtension->ReaderExtension = ExAllocatePool(
NonPagedPool,
sizeof(READER_EXTENSION)
);
if (smartcardExtension->ReaderExtension == NULL) {
SmartcardLogError(
DriverObject,
TLP3_NO_MEMORY,
NULL,
0
);
status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
readerExtension = smartcardExtension->ReaderExtension;
RtlZeroMemory(readerExtension, sizeof(READER_EXTENSION));
// Write the version of the lib we use to the smartcard extension
smartcardExtension->Version = SMCLIB_VERSION;
smartcardExtension->SmartcardRequest.BufferSize =
smartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
//
// Now let the lib allocate the buffer for data transmission
// We can either tell the lib how big the buffer should be
// by assigning a value to BufferSize or let the lib
// allocate the default size
//
status = SmartcardInitialize(smartcardExtension);
if (status != STATUS_SUCCESS) {
SmartcardLogError(
DriverObject,
(smartcardExtension->OsData ? TLP3_WRONG_LIB_VERSION : TLP3_NO_MEMORY),
NULL,
0
);
__leave;
}
// Save deviceObject
smartcardExtension->OsData->DeviceObject = DeviceObject;
// Set up call back functions
smartcardExtension->ReaderFunction[RDF_TRANSMIT] = TLP3Transmit;
smartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] = TLP3SetProtocol;
smartcardExtension->ReaderFunction[RDF_CARD_POWER] = TLP3ReaderPower;
smartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = TLP3CardTracking;
smartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR] = TLP3VendorIoctl;
// This event signals that the serial driver has been closed
KeInitializeEvent(
&READER_EXTENSION_L(SerialCloseDone),
NotificationEvent,
TRUE
);
//
// Set the vendor information
//
strcpy(smartcardExtension->VendorAttr.VendorName.Buffer, "Bull");
smartcardExtension->VendorAttr.VendorName.Length =
(USHORT) strlen(deviceExtension->SmartcardExtension.VendorAttr.VendorName.Buffer);
strcpy(smartcardExtension->VendorAttr.IfdType.Buffer, "SmarTLP");
smartcardExtension->VendorAttr.IfdType.Length =
(USHORT) strlen(smartcardExtension->VendorAttr.IfdType.Buffer);
smartcardExtension->VendorAttr.UnitNo = MAXULONG;
for (deviceInstance = 0; deviceInstance < MAXULONG; deviceInstance++) {
PDEVICE_OBJECT devObj;
for (devObj = DeviceObject;
devObj != NULL;
devObj = devObj->NextDevice) {
PDEVICE_EXTENSION devExt = devObj->DeviceExtension;
PSMARTCARD_EXTENSION smcExt = &devExt->SmartcardExtension;
if (deviceInstance == smcExt->VendorAttr.UnitNo) {
break;
}
}
if (devObj == NULL) {
smartcardExtension->VendorAttr.UnitNo = deviceInstance;
break;
}
}
//
// Set the reader capabilities
//
// Clk frequency in KHz encoded as little endian integer
smartcardExtension->ReaderCapabilities.CLKFrequency.Default = 3571;
smartcardExtension->ReaderCapabilities.CLKFrequency.Max = 3571;
smartcardExtension->ReaderCapabilities.DataRate.Default =
smartcardExtension->ReaderCapabilities.DataRate.Max =
dataRatesSupported[0];
// reader could support higher data rates
smartcardExtension->ReaderCapabilities.DataRatesSupported.List =
dataRatesSupported;
smartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);
smartcardExtension->ReaderCapabilities.MaxIFSD = 254;
// Now setup information in our deviceExtension
smartcardExtension->ReaderCapabilities.CurrentState =
(ULONG) SCARD_UNKNOWN;
// This reader supports T=0 and T=1
smartcardExtension->ReaderCapabilities.SupportedProtocols =
SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
smartcardExtension->ReaderCapabilities.MechProperties = 0;
//
// Set serial configuration parameters
//
readerExtension->SerialConfigData.BaudRate.BaudRate = 9600;
readerExtension->SerialConfigData.LineControl.StopBits =
STOP_BITS_2;
readerExtension->SerialConfigData.LineControl.Parity =
EVEN_PARITY;
readerExtension->SerialConfigData.LineControl.WordLength =
SERIAL_DATABITS_8;
// set timeouts
readerExtension->SerialConfigData.Timeouts.ReadIntervalTimeout =
READ_INTERVAL_TIMEOUT_DEFAULT;
readerExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant =
READ_TOTAL_TIMEOUT_CONSTANT_DEFAULT;
readerExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier = 0;
// set special characters
readerExtension->SerialConfigData.SerialChars.ErrorChar = 0;
readerExtension->SerialConfigData.SerialChars.EofChar = 0;
readerExtension->SerialConfigData.SerialChars.EventChar = 0;
readerExtension->SerialConfigData.SerialChars.XonChar = 0;
readerExtension->SerialConfigData.SerialChars.XoffChar = 0;
readerExtension->SerialConfigData.SerialChars.BreakChar = 0xFF;
// Set handflow
readerExtension->SerialConfigData.HandFlow.XonLimit = 0;
readerExtension->SerialConfigData.HandFlow.XoffLimit = 0;
readerExtension->SerialConfigData.HandFlow.ControlHandShake = 0;
readerExtension->SerialConfigData.HandFlow.FlowReplace =
SERIAL_XOFF_CONTINUE;
#if defined (DEBUG) && defined (DETECT_SERIAL_OVERRUNS)
readerExtension->SerialConfigData.HandFlow.ControlHandShake =
SERIAL_ERROR_ABORT;
#endif
// save the current power state of the reader
readerExtension->ReaderPowerState = PowerReaderWorking;
// and attach to the PDO
ATTACHED_DEVICE_OBJECT =
IoAttachDeviceToDeviceStack(
DeviceObject,
PhysicalDeviceObject
);
ASSERT(ATTACHED_DEVICE_OBJECT != NULL);
if (ATTACHED_DEVICE_OBJECT == NULL) {
SmartcardLogError(
DriverObject,
TLP3_CANT_CONNECT_TO_ASSIGNED_PORT,
NULL,
status
);
status = STATUS_UNSUCCESSFUL;
__leave;
}
// register our new device
status = IoRegisterDeviceInterface(
PhysicalDeviceObject,
&SmartCardReaderGuid,
NULL,
&deviceExtension->PnPDeviceName
);
ASSERT(status == STATUS_SUCCESS);
DeviceObject->Flags |= DO_BUFFERED_IO;
DeviceObject->Flags |= DO_POWER_PAGABLE;
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
}
__finally {
if (regKey) {
ZwClose(regKey);
}
if (status != STATUS_SUCCESS) {
TLP3RemoveDevice(DeviceObject);
}
SmartcardDebug(
DEBUG_TRACE,
( "%s!TLP3AddDevice: Exit %x\n",
DRIVER_NAME,
status)
);
}
return status;
}
NTSTATUS
TLP3StartDevice(
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Open the serial device, start card tracking and register our
device interface. If any of the calls here fails we don't care
to rollback since a stop will be called later which we then
use to clean up.
--*/
{
NTSTATUS status;
PIRP irp;
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
SmartcardDebug(
DEBUG_TRACE,
( "%s!TLP3StartDevice: Enter\n",
DRIVER_NAME)
);
irp = IoAllocateIrp(
(CCHAR) (DeviceObject->StackSize + 1),
FALSE
);
ASSERT(irp != NULL);
if (irp == NULL) {
return STATUS_NO_MEMORY;
}
_try {
PIO_STACK_LOCATION irpStack;
HANDLE handle = 0;
IO_STATUS_BLOCK ioStatusBlock;
//
// Open the underlying serial driver.
// This is necessary for two reasons:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -