📄 tlp3ce.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
Module Name:
tlp3ce.c
Abstract:
Smart Card Reader Driver for Windows CE.
--*/
#include <stdio.h>
#include <smclib.h>
#include <devload.h>
#include <tchar.h>
#include "TLP3CE.h"
#include "BullTLP3.h"
// prototypes
BOOL TLP3UpdateReaderState(PSMARTCARD_EXTENSION SmartcardExtension);
const TCHAR szDriverName[] = TEXT("Bull TLP3 ");
// Used to synchronize access to global driver data structures
CRITICAL_SECTION g_DriverCritSect;
#ifdef DEBUG
#define DEBUG_INIT 0x00000040
#define DEBUG_SERIAL 0x00000080
#define DEBUG_THREAD 0x00000200
DBGPARAM dpCurSettings = {
TEXT("BULLTLP3"), {
TEXT("Ioctl"), TEXT("ATR"), TEXT("Protocol"), TEXT("Driver"),
TEXT("Trace"),TEXT("Error"), TEXT("Initialization"),TEXT("Serial"),
TEXT(" I/O"),TEXT("Thread"),TEXT(""),TEXT(""),
TEXT(""),TEXT(""),TEXT(""),TEXT("Break On Open") },
0x00000020 // DEBUG_ERROR
};
#endif // DEBUG
// allow upto MAX_PSCR_DEVICES
PSMARTCARD_EXTENSION DeviceSlot[MAXIMUM_SERIAL_READERS];
BOOL AddDevice(PSMARTCARD_EXTENSION pDevice)
{
int i;
EnterCriticalSection(&g_DriverCritSect);
for (i=0; i< MAXIMUM_SERIAL_READERS; i++)
{
if (DeviceSlot[i] == NULL)
{
DeviceSlot[i] = pDevice;
break;
}
}
LeaveCriticalSection(&g_DriverCritSect);
return (i < MAXIMUM_SERIAL_READERS);
}
BOOL RemoveDevice(PSMARTCARD_EXTENSION pDevice)
{
int i;
EnterCriticalSection(&g_DriverCritSect);
for (i=0; i< MAXIMUM_SERIAL_READERS; i++)
{
if (DeviceSlot[i] == pDevice)
{
DeviceSlot[i] = NULL;
break;
}
}
LeaveCriticalSection(&g_DriverCritSect);
return (i < MAXIMUM_SERIAL_READERS);
}
BOOL ValidateAndEnterDevice(PSMARTCARD_EXTENSION pDevice)
{
int i;
EnterCriticalSection(&g_DriverCritSect);
for (i=0; i< MAXIMUM_SERIAL_READERS; i++)
{
if (DeviceSlot[i] == pDevice)
{
EnterDevice(pDevice);
break;
}
}
LeaveCriticalSection(&g_DriverCritSect);
#ifdef DEBUG
if (i >= MAXIMUM_SERIAL_READERS)
{
SmartcardDebug(DEBUG_ERROR,(TEXT("%s:ValidateDevice - Invalid Object %x\n"),szDriverName,pDevice));
}
#endif
return (i < MAXIMUM_SERIAL_READERS);
}
//
// DLL entry
//
BOOL WINAPI
DllEntry(HINSTANCE DllInstance, INT Reason, LPVOID Reserved)
{
switch(Reason) {
case DLL_PROCESS_ATTACH:
DEBUGREGISTER(DllInstance);
SmartcardDebug(DEBUG_INIT, (TEXT("%s: DLL_PROCESS_ATTACH\r\n"), szDriverName));
InitializeCriticalSection(&g_DriverCritSect);
memset(DeviceSlot,0,sizeof(DeviceSlot));
DisableThreadLibraryCalls((HMODULE) DllInstance);
break;
case DLL_PROCESS_DETACH:
SmartcardDebug(DEBUG_INIT, (TEXT("%s: DLL_PROCESS_DETACH\r\n"), szDriverName));
DeleteCriticalSection(&g_DriverCritSect);
break;
}
return TRUE;
}
//
// File system device entrypoints (DEV_????)
//
//
// Returns context data (PDISK) for this Init instance or 0 for failure.
//
// Arguments:
// dwContext - registry path for this device's active key
//
DWORD
SCR_Init(
DWORD dwContext
)
{
PSMARTCARD_EXTENSION pSmartcardExtension;
LPTSTR ActiveKey = (LPTSTR)dwContext;
if (pSmartcardExtension=TLP3LoadDevice(ActiveKey)) {
if (AddDevice(pSmartcardExtension)) // check for device overflow
{
TCHAR szDeviceName[DEVNAME_LEN];
TCHAR szFriendlyName[MAXIMUM_ATTR_STRING_LENGTH+DEVNAME_LEN+5];
DWORD status;
// The device name should be available from the Active Key
// [On versions prior to CE 3.0, this wont work until the post-init IOCTL]
status = GetDeviceName(pSmartcardExtension->ReaderExtension->d_ActivePath,szDeviceName);
if (status == STATUS_SUCCESS)
{
// figure out the unit number from the device name
PTCHAR pch = szDeviceName;
while (*pch && (*pch < '0' || *pch > '9'))
++pch;
if (*pch)
pSmartcardExtension->VendorAttr.UnitNo = *pch - '0';
// Attempt to register a friendly name for this device
// for the benefit of the resource manager.
// The friendly name has the format "PRODUCTNAME [UNITNO]"
// For example, "SCM SwapSmart [1]"
//
MakeFriendlyName(pSmartcardExtension, szFriendlyName);
SmartcardCreateLink(szFriendlyName,szDeviceName);
}
return (DWORD)pSmartcardExtension;
}
else {
SmartcardDebug(DEBUG_INIT|DEBUG_ERROR,
(TEXT("%s: TLP_Init Device Overflow error\r\n"),szDriverName));
TLP3UnloadDevice(pSmartcardExtension);
ASSERT(FALSE);
};
}
return (DWORD)NULL;
// insert call to detection function if one is defined
//
// do device initialization
}
//
// Device deinit - devices are expected to close down.
// The device manager does not check the return code.
//
BOOL
SCR_Deinit(
DWORD dwContext // pointer to the per device structure
)
{
SmartcardDebug(DEBUG_INIT|DEBUG_TRACE,
(TEXT("%s: TLP_DeInit\r\n"),szDriverName));
SCR_Close(dwContext);
TLP3UnloadDevice((PSMARTCARD_EXTENSION)dwContext);
return TRUE;
}
//
// Returns handle value for the open instance.
// we only allow one open at a time because this is an inherently state-ful device
//
DWORD
SCR_Open(
DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode
)
{
PSMARTCARD_EXTENSION pSmartcardExtension = (PSMARTCARD_EXTENSION) dwData;
PREADER_EXTENSION readerExtension = pSmartcardExtension->ReaderExtension;
SmartcardDebug(DEBUG_TRACE,(TEXT("%s: Open(%x) - entered\n"),szDriverName,dwData));
#ifdef DEBUG
if (DEBUGZONE(15))
DebugBreak();
#endif
if (!ValidateAndEnterDevice(pSmartcardExtension))
{
SetLastError(ERROR_BAD_DEVICE);
ASSERT(FALSE);
return 0;
}
if (readerExtension->d_uReaderState != STATE_CLOSED)
{
SmartcardDebug(DEBUG_ERROR,(TEXT("%s: Open - invalid state %d\n"), szDriverName,
readerExtension->d_uReaderState
));
dwData = 0;
SetLastError(ERROR_SHARING_VIOLATION);
ASSERT(FALSE);
}
else
{
// clear card state
memset(&pSmartcardExtension->CardCapabilities, 0, sizeof(SCARD_CARD_CAPABILITIES));
// clear reader state
pSmartcardExtension->ReaderCapabilities.CurrentState = SCARD_UNKNOWN;
if (TLP3CreateSerialPort(pSmartcardExtension))
{
BOOLEAN bStatus;
DWORD status;
// ReadExtension
// Set serial configuration parameters for read extention
// Initial DCB
bStatus=GetCommState(readerExtension->hSerialPort,
&(readerExtension->SerialConfigData.SerialControlBlock));
ASSERT(bStatus);
readerExtension->SerialConfigData.SerialControlBlock.BaudRate=CBR_9600;
readerExtension->SerialConfigData.SerialControlBlock.StopBits=ONESTOPBIT;//STOPBITS_20;
readerExtension->SerialConfigData.SerialControlBlock.fParity=0; // Even Pariry check
readerExtension->SerialConfigData.SerialControlBlock.Parity=NOPARITY;//PARITY_EVEN;
// readerExtension->SerialConfigData.SerialControlBlock.fBinary=1; // Skip EOF; 8-bit binary data.
readerExtension->SerialConfigData.SerialControlBlock.ByteSize=DATABITS_8;
readerExtension->SerialConfigData.SerialControlBlock.fTXContinueOnXoff=1;
readerExtension->SerialConfigData.SerialControlBlock.fOutX =0;
readerExtension->SerialConfigData.SerialControlBlock.fInX =0;
// DTR RTS always on.
/*
readerExtension->SerialConfigData.SerialControlBlock.fDtrControl=DTR_CONTROL_DISABLE;
// readerExtension->SerialConfigData.SerialControlBlock.fDtrControl=DTR_CONTROL_ENABLE;
readerExtension->SerialConfigData.SerialControlBlock.fRtsControl=RTS_CONTROL_DISABLE;
// Ingore CTS and DSR for output
readerExtension->SerialConfigData.SerialControlBlock.fOutxCtsFlow=0;
readerExtension->SerialConfigData.SerialControlBlock.fOutxDsrFlow=0;
//Data only valid when DSR On
readerExtension->SerialConfigData.SerialControlBlock.fDsrSensitivity=0;
*/
// Time out set.
readerExtension->SerialConfigData.Timeouts.ReadIntervalTimeout=READ_INTERVAL_TIMEOUT_DEFAULT;
readerExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant=
READ_TOTAL_TIMEOUT_CONSTANT_DEFAULT;
readerExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier=
readerExtension->SerialConfigData.Timeouts.WriteTotalTimeoutMultiplier=0;
// save the current power state of the reader
readerExtension->ReaderPowerState = PowerReaderWorking;
status = TLP3ConfigureSerialPort(pSmartcardExtension);
// TEST only
readerExtension->SerialConfigData.SerialControlBlock.fRtsControl=RTS_CONTROL_ENABLE;
ASSERT(status==STATUS_SUCCESS);
if (status == STATUS_SUCCESS)
{
// We seem to need a delay before the serial control lines can be
// be correctly read.
Sleep(500);
if (TLP3UpdateReaderState(pSmartcardExtension))
{
// Create Backgroud thread for monitoring serial state changes
ASSERT(!readerExtension->hBackgroundThread);
readerExtension->hBackgroundThread=
CreateThread(NULL,
0,
TLP3SerialEvent,
pSmartcardExtension,
CREATE_SUSPENDED,
&(readerExtension->dwThreadID));
ASSERT(readerExtension->hBackgroundThread);
if (readerExtension->hBackgroundThread)
{
readerExtension->d_uReaderState = STATE_OPENED;
ResumeThread(readerExtension->hBackgroundThread);
}
}
}
}
else
{ // cannot open comm port
SmartcardDebug(DEBUG_INIT|DEBUG_ERROR,(TEXT("%s: SmartcardInitialize failed to open %s\n"),
szDriverName,
readerExtension->d_SerialPort));
}
if (readerExtension->d_uReaderState != STATE_OPENED)
{
// cleanup
dwData = 0;
// close serial port if it was opened
TLP3CloseSerialPort(pSmartcardExtension);
}
}
LeaveDevice(pSmartcardExtension);
return dwData;
}
BOOL
SCR_Close(
DWORD Handle
)
{
BOOL fRet;
PSMARTCARD_EXTENSION pSmartcardExtension = (PSMARTCARD_EXTENSION) Handle;
SmartcardDebug(DEBUG_TRACE,(TEXT("%s: Close(%x) - entered\n"),szDriverName,Handle));
if (!ValidateAndEnterDevice(pSmartcardExtension))
{
SetLastError(ERROR_BAD_DEVICE);
return FALSE;
}
if (pSmartcardExtension->ReaderExtension->d_uReaderState != STATE_OPENED)
{
fRet = FALSE;
SetLastError(ERROR_BAD_DEVICE);
ASSERT(FALSE);
}
else
{
DWORD retry = 0;
pSmartcardExtension->ReaderExtension->d_uReaderState = STATE_CLOSED;
while (pSmartcardExtension->ReaderExtension->d_RefCount > 1 && ++retry < 3)
{
// cancel any outstanding blocking calls
SmartcardDebug(DEBUG_TRACE,(TEXT("%s: Close - waiting for %d threads to exit\n"),
szDriverName, pSmartcardExtension->ReaderExtension->d_RefCount -1
));
SmartcardDeviceControl(pSmartcardExtension, IOCTL_SMARTCARD_CANCEL_BLOCKING,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -