📄 stcusbce.c
字号:
if (pSmartcardExtension->ReaderExtension->hBackgroundThread)
{
DWORD dwWait;
dwWait = WaitForSingleObject(pSmartcardExtension->ReaderExtension->hBackgroundThread,10*POLLING_PERIOD);
ASSERT(dwWait != WAIT_TIMEOUT);
CloseHandle(pSmartcardExtension->ReaderExtension->hBackgroundThread);
pSmartcardExtension->ReaderExtension->hBackgroundThread=NULL;
}
status = STCConfigureSTC(pSmartcardExtension->ReaderExtension,STCClose);
SmartcardDebug(DEBUG_TRACE,(TEXT("%s: STCConfigureSTC(STCClose) returned %x\n"),szDriverName,status));
fRet = TRUE;
LeaveDevice(pSmartcardExtension);
return fRet;
}
//
// I/O Control function - responds to info, read and write control codes.
//
BOOL
SCR_IOControl(
DWORD Handle,
DWORD dwIoControlCode,
PBYTE pInBuf,
DWORD nInBufSize,
PBYTE pOutBuf,
DWORD nOutBufSize,
PDWORD pBytesReturned
)
{
NTSTATUS status;
PSMARTCARD_EXTENSION pSmartcardExtension = (PSMARTCARD_EXTENSION) Handle;
if (!ValidateAndEnterDevice(pSmartcardExtension))
{
SetLastError(ERROR_BAD_DEVICE);
ASSERT(FALSE);
return FALSE;
}
if (pSmartcardExtension->ReaderExtension->d_uReaderState != STATE_OPENED)
{
SmartcardDebug(DEBUG_ERROR,(TEXT("%s: DeviceIOCTL - invalid state %d\n"), szDriverName,
pSmartcardExtension->ReaderExtension->d_uReaderState
));
status = ERROR_GEN_FAILURE;
}
else
{
ASSERT(pSmartcardExtension->ReaderExtension->ReaderPowerState ==
PowerReaderWorking);
status = SmartcardDeviceControl(
pSmartcardExtension, dwIoControlCode,
pInBuf, nInBufSize,
pOutBuf, nOutBufSize,
pBytesReturned);
}
LeaveDevice(pSmartcardExtension);
return (status == STATUS_SUCCESS ? TRUE: FALSE);
}
// The function Not supported.
DWORD SCR_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes){return 0;}
DWORD SCR_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes){return 0;}
DWORD SCR_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod){return 0;}
// Power Up and Down Support
void SCR_PowerUp(void)
{
SmartcardDebug(DEBUG_TRACE,(TEXT("%s: PowerUp() - entered\n"),szDriverName));
}
void SCR_PowerDown(void)
{
SmartcardDebug(DEBUG_TRACE,(TEXT("%s: PowerDown() - entered\n"),szDriverName));
}
static DWORD
GetDeviceName(
LPTSTR ActivePath,
LPTSTR szDeviceName, // [OUT] stream device name eg. SCR1:
LPDWORD pdwClientInfo // [OUT, OPTIONAL] clientInfo DWORD
)
{
DWORD ValType;
DWORD ValLen;
HKEY hCardKey;
DWORD status;
//
// Open active device registry key
//
status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
ActivePath,
0,
0,
&hCardKey);
if (status) {
SmartcardDebug(DEBUG_TRACE|DEBUG_ERROR,
(TEXT("GetDeviceName RegOpenKeyEx(HLM\\%s) returned %d!!!\r\n"),
ActivePath, status));
return status;
}
if (pdwClientInfo)
{
// get our client info
ValLen = sizeof(DWORD);
status = RegQueryValueEx(
hCardKey,
DEVLOAD_CLIENTINFO_VALNAME,
NULL,
&ValType,
(PUCHAR)pdwClientInfo,
&ValLen);
if (status != ERROR_SUCCESS) {
SmartcardDebug(DEBUG_TRACE|DEBUG_ERROR,
(TEXT("GetDeviceName - RegQueryValueEx(%s) returned %d\r\n"),
DEVLOAD_CLIENTINFO_VALNAME, status));
}
}
if (szDeviceName)
{
// get our device name (eg. SCR1:)
ValLen = DEVNAME_LEN*sizeof(TCHAR);
status = RegQueryValueEx(
hCardKey,
DEVLOAD_DEVNAME_VALNAME,
NULL,
&ValType,
(PUCHAR)szDeviceName,
&ValLen);
if (status != ERROR_SUCCESS) {
SmartcardDebug(DEBUG_TRACE|DEBUG_ERROR,
(TEXT("GetDeviceName - RegQueryValueEx(%s) returned %d\r\n"),
DEVLOAD_DEVNAME_VALNAME, status));
}
}
RegCloseKey(hCardKey);
return status;
}
void
MakeFriendlyName(PSMARTCARD_EXTENSION SmartcardExtension, LPTSTR szFriendlyName)
{
TCHAR szUnitNoPart[] = L" [ ]";
mbstowcs(szFriendlyName,SmartcardExtension->VendorAttr.IfdType.Buffer,SmartcardExtension->VendorAttr.IfdType.Length);
szUnitNoPart[2] = (WCHAR)(SmartcardExtension->VendorAttr.UnitNo % 10 + '0');
lstrcatW(szFriendlyName,szUnitNoPart);
}
//
// StcUsbLoadDevice:
// 1. Allocate and init the SMARTCARDEXTENSION struct
// 2. Configure Serial Port.
// 3. Create Card Tracking Thread
// 4. Init the device
//
// ActivePath is the registry path to our device's active key under
// HKEY_LOCAL_MACHINE\Drivers\Active
//
// Return pointer to new device structure or NULL.
//
PSMARTCARD_EXTENSION
StcUsbLoadDevice(
LPTSTR ActiveKey
)
{
DWORD status;
PREADER_EXTENSION readerExtension;
PSMARTCARD_EXTENSION smartcardExtension = NULL;
TCHAR szDeviceName[DEVNAME_LEN];
TCHAR szFriendlyName[MAXIMUM_ATTR_STRING_LENGTH+DEVNAME_LEN+5];
static ULONG dataRatesSupported[] = { 9600, 19200, 38400, 57600, 115200 };
// the device context (including smartcard and reader extension) has already
// been allocated in USBDeviceAttach and saved in the clientInfo registry field under the
// ActiveKey
szDeviceName[0] = 0;
GetDeviceName(ActiveKey, szDeviceName , (PDWORD)&smartcardExtension);
if( smartcardExtension == NULL )
return NULL;
// USBDeviceAttach has already initialized the following fields:
// ReaderExtension
// pPipeIn, pPipeOut, pUsbFuncs, hStreamDevice, hUsbDevice
// get pointer to the reader extension
readerExtension = smartcardExtension->ReaderExtension;
PREFAST_ASSERT(readerExtension);
// 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) {
SmartcardDebug(DEBUG_TRACE|DEBUG_ERROR,(TEXT("%s: SmartcardInitialize failed - %x\n"),
szDriverName, status));
return NULL;
}
// setup smartcard extension - callback's
smartcardExtension->ReaderFunction[RDF_CARD_POWER] = CBCardPower;
smartcardExtension->ReaderFunction[RDF_TRANSMIT] = CBTransmit;
smartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = CBCardTracking;
smartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] = CBSetProtocol;
smartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR] = VendorIoctl;
// setup smartcard extension - vendor attribute
RtlCopyMemory(
smartcardExtension->VendorAttr.VendorName.Buffer,
STCUSB_VENDOR_NAME,sizeof( STCUSB_VENDOR_NAME ));
smartcardExtension->VendorAttr.VendorName.Length = sizeof( STCUSB_VENDOR_NAME );
RtlCopyMemory(
smartcardExtension->VendorAttr.IfdType.Buffer,
STCUSB_PRODUCT_NAME,sizeof( STCUSB_PRODUCT_NAME ));
smartcardExtension->VendorAttr.IfdType.Length = sizeof(STCUSB_PRODUCT_NAME );
smartcardExtension->VendorAttr.UnitNo = UnitNo++;
smartcardExtension->VendorAttr.IfdVersion.BuildNumber = 0;
smartcardExtension->VendorAttr.IfdSerialNo.Length = 0;
//
// 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;
smartcardExtension->ReaderCapabilities.Channel = 0;
smartcardExtension->ReaderExtension->ReaderPowerState =
PowerReaderWorking;
// Copy the ActivePath
_tcsncpy(readerExtension->d_ActivePath,ActiveKey,REG_PATH_LEN);
readerExtension->d_ActivePath[REG_PATH_LEN-1]=0;// terminated if overflow.
readerExtension->d_uReaderState = STATE_CLOSED;
readerExtension->ReadTimeout=10000;
readerExtension->Event=CreateEvent(NULL,FALSE,FALSE,NULL);
if (szDeviceName[0]) {
PTCHAR pch = szDeviceName;
while (*pch && (*pch < '0' || *pch > '9'))
++pch;
if (*pch)
smartcardExtension->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(smartcardExtension, szFriendlyName);
SmartcardCreateLink(szFriendlyName,szDeviceName);
}
SmartcardDebug( DEBUG_TRACE,
( TEXT("%s!StcUsbCreateDevice: Device created\n"),szDriverName));
return smartcardExtension;
}
void
StcUsbUnloadDevice(PSMARTCARD_EXTENSION SmartcardExtension)
{
PREADER_EXTENSION pReader = SmartcardExtension->ReaderExtension;
WCHAR szFriendlyName[MAXIMUM_ATTR_STRING_LENGTH+DEVNAME_LEN+5];
DWORD retry = 0;
// remove device from list of active devices managed by this driver
RemoveDevice(SmartcardExtension);
// At this point no other thread should have a reference to this object
// make sure that's the case
while (SmartcardExtension->ReaderExtension->d_RefCount && retry++ < 3)
{
Sleep(retry * 32);
SmartcardDebug(DEBUG_TRACE, (TEXT("%s:UnloadDevice - waiting for refCount %d to drop to zero\r\n"),
szDriverName,SmartcardExtension->ReaderExtension->d_RefCount ));
}
ASSERT(!SmartcardExtension->ReaderExtension->d_RefCount);
// Remove friendly name
MakeFriendlyName(SmartcardExtension, szFriendlyName);
SmartcardDeleteLink(szFriendlyName);
// sign off from SMCLIB
SmartcardExit(SmartcardExtension);
// SmartcardExtension freed in DeviceNotify(USB_CLOSE_DEVICE,..)
//SmartcardDebug(DEBUG_TRACE, (TEXT("%s:UnloadDevice - freeing resources\r\n"),szDriverName));
//LocalFree(SmartcardExtension);
SmartcardDebug(DEBUG_TRACE, (TEXT("%s:UnloadDevice done with 0x%x\r\n"), szDriverName, SmartcardExtension));
}
void
SysDelay(
ULONG Timeout
)
{
Sleep(Timeout);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -