📄 simce.c
字号:
SmartcardDeviceControl(pSmartcardExtension, IOCTL_SMARTCARD_CANCEL_BLOCKING, NULL,0,NULL,0,NULL);
//check whether need this sleep during testing
//Sleep(10);
}
if (pSmartcardExtension->ReaderExtension->hBackgroundThread)
{
DWORD dwWait;
g_TrackingThreadTerminate = TRUE;
dwWait = WaitForSingleObject(pSmartcardExtension->ReaderExtension->hBackgroundThread,10*POLLING_PERIOD);
ASSERT(dwWait != WAIT_TIMEOUT);
CloseHandle(pSmartcardExtension->ReaderExtension->hBackgroundThread);
pSmartcardExtension->ReaderExtension->hBackgroundThread=NULL;
}
fRet = TRUE;
LeaveDevice(pSmartcardExtension);
SIM_Close(pSmartcardExtension->ReaderExtension->pSIMReg);
SmartcardDebug(DEBUG_TRACE,(TEXT("+SCR_Close\n")));
return fRet;
}
//-----------------------------------------------------------------------------
//
// Function: SCR_IOControl
//
// This function responds to info, read and write control codes.
//
// Parameters:
// Handle
// [in] context of call
// dwIoControlCode
// [in] the io control code passed from upper layer
// pInBuf
// [in] IN buffer
// nInBufSize
// [in]/[out] size of IN buffer
// pOutBuf
// [in] OUT buffer
// nOutBufSize
// [in]/[out] size of IN buffer
// pBytesReturned
// [in]/[out] returned bytes
//
// Returns:
// BOOL
//
//-----------------------------------------------------------------------------
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;
SmartcardDebug(DEBUG_TRACE,(TEXT("+SCR_IOControl\n")));
if (!ValidateAndEnterDevice(pSmartcardExtension))
{
SetLastError(ERROR_BAD_DEVICE);
ASSERT(FALSE);
return FALSE;
}
if (pSmartcardExtension->ReaderExtension->d_uReaderState != STATE_OPENED)
{
SmartcardDebug(DEBUG_ERROR,(TEXT("DeviceIOCTL - invalid state %d\n"),
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);
SmartcardDebug(DEBUG_TRACE,(TEXT("-SCR_IOControl\n")));
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("PowerUp() - entered\n")));
}
void SCR_PowerDown(void)
{
SmartcardDebug(DEBUG_TRACE,(TEXT("PowerDown() - entered\n")));
}
//-----------------------------------------------------------------------------
//
// Function: GetIOIndex
//
// This function obtains which port to use and the mode of operation one port mode or
// alternative mode
//
// Parameters:
// void
//
// Returns:
// DWORD iobase address of the SIM module
//
//-----------------------------------------------------------------------------
static DWORD GetIOIndex(void)
{
DWORD ValType;
DWORD ValLen;
HKEY hCardKey;
DWORD status;
DWORD iobase, alt_iobase, index;
DWORD port_select;
// Open active device registry key
status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
TEXT(SIM_REG_PATH),
0,
0,
&hCardKey);
if (status)
{
SmartcardDebug(DEBUG_TRACE|DEBUG_ERROR,
(TEXT("GetIOIndex RegOpenKeyEx returned %d!!!\r\n"), status));
return status;
}
// get our device iobase
ValLen = sizeof(DWORD);
status = RegQueryValueEx(
hCardKey,
SIM_REG_IOBASE_VAL_NAME,
NULL,
&ValType,
(LPBYTE)(&iobase),
&ValLen);
if (status != ERROR_SUCCESS)
{
SmartcardDebug(DEBUG_TRACE|DEBUG_ERROR, (TEXT("GetIOIndex - RegQueryValueEx(%s) returned %d\r\n"),
"IOBase", status));
}
// get our device althernate iobase
ValLen = sizeof(DWORD);
status = RegQueryValueEx(
hCardKey,
SIM_REG_ALTIOBASE_VAL_NAME,
NULL,
&ValType,
(LPBYTE)(&alt_iobase),
&ValLen);
if (status != ERROR_SUCCESS)
{
SmartcardDebug(DEBUG_TRACE|DEBUG_ERROR, (TEXT("GetIOIndex - RegQueryValueEx(%s) returned %d\r\n"),
"AlternateIOBase", status));
}
// get our device index
ValLen = sizeof(DWORD);
status = RegQueryValueEx(
hCardKey,
SIM_REG_INDEX_VAL_NAME,
NULL,
&ValType,
(LPBYTE)(&index),
&ValLen);
if (status != ERROR_SUCCESS)
{
SmartcardDebug(DEBUG_TRACE|DEBUG_ERROR, (TEXT("GetIOIndex - RegQueryValueEx(%s) returned %d\r\n"),
"Index", status));
}
RegCloseKey(hCardKey);
if((alt_iobase) != 0)
{
SmartcardDebug(DEBUG_TRACE, (TEXT("Alternative mode! Not supported in Zeus!\n")));
return 0;
}
else if((index) == 1)
{
port_select =0;
}
else if((index) == 2)
{
port_select =1;
}
SIM_SelectPort(port_select);
return (iobase);
}
//-----------------------------------------------------------------------------
//
// Function: GetDeviceName
//
// This function obtains the device name from registry
//
// Parameters:
// ActivePath
// [in] pointer to the name of the subkey to open
// szDeviceName
// [in] pointer to the buffer that receives value
//
// Returns:
// DWORD status
//
//-----------------------------------------------------------------------------
static DWORD GetDeviceName(LPTSTR ActivePath, LPTSTR szDeviceName)
{
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;
}
// get our device name (eg. SIM1:)
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;
}
//-----------------------------------------------------------------------------
//
// Function: MakeFriendlyName
//
// This function makes the device friendly name
//
// Parameters:
// SmartcardExtension
// [in] context of device
// szFriendlyName
// [in] pointer to the friendly name
//
// Returns:
// void
//
//-----------------------------------------------------------------------------
static void MakeFriendlyName(PSMARTCARD_EXTENSION SmartcardExtension, LPTSTR szFriendlyName)
{
TCHAR szUnitNoPart[] = L" [ ]";
szFriendlyName[0] = 0; // NULL in case IfdType is empty
mbstowcs(szFriendlyName,SmartcardExtension->VendorAttr.IfdType.Buffer, SmartcardExtension->VendorAttr.IfdType.Length);
szUnitNoPart[2] = (WCHAR)(SmartcardExtension->VendorAttr.UnitNo % 10 + '0');
lstrcatW(szFriendlyName,szUnitNoPart);
}
//-----------------------------------------------------------------------------
//
// Function: SIMLoadDevice
//
// This function creates ReaderExtension stucure and calls the hardware to do initialization
//
// Parameters:
// ActiveKey
// [in] active key of device
//
// Returns:
// PSMARTCARD_EXTENSION pointer to new device structure or NULL.
//
//-----------------------------------------------------------------------------
static PSMARTCARD_EXTENSION SIMLoadDevice(LPTSTR ActiveKey)
{
DWORD status;
PREADER_EXTENSION ReaderExtension;
PSMARTCARD_EXTENSION SmartcardExtension;
DWORD iobase;
SmartcardDebug(DEBUG_TRACE,(TEXT("+SIMLoadDevice\n")));
// allocate the device context (including smartcard and reader extension)
SmartcardExtension = LocalAlloc(LPTR, sizeof( SMARTCARD_EXTENSION )+ sizeof(READER_EXTENSION));
if( SmartcardExtension == NULL )
{
status = STATUS_INSUFFICIENT_RESOURCES;
return (NULL);
}
// allocate the reader extension
ReaderExtension = (PREADER_EXTENSION) (SmartcardExtension +1);
if (ReaderExtension->d_ActivePath = LocalAlloc(LPTR, wcslen(ActiveKey)*sizeof(WCHAR)+sizeof(WCHAR)))
{
wcscpy(ReaderExtension->d_ActivePath, ActiveKey);
}
ReaderExtension->d_uReaderState = STATE_CLOSED;
SmartcardExtension->ReaderExtension = ReaderExtension;
// 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] = SIMVendorIoctl;
// setup smartcard extension - vendor attribute
RtlCopyMemory(SmartcardExtension->VendorAttr.VendorName.Buffer, SIM_VENDOR_NAME, sizeof(SIM_VENDOR_NAME));
SmartcardExtension->VendorAttr.VendorName.Length = sizeof(SIM_VENDOR_NAME);
RtlCopyMemory(SmartcardExtension->VendorAttr.IfdType.Buffer, SIM_PRODUCT_NAME, sizeof(SIM_PRODUCT_NAME));
SmartcardExtension->VendorAttr.IfdType.Length = sizeof(SIM_PRODUCT_NAME);
SmartcardExtension->VendorAttr.UnitNo = 0;
SmartcardExtension->VendorAttr.IfdVersion.BuildNumber = 0;
SmartcardExtension->VendorAttr.IfdSerialNo.Length = 0;
// setup smartcard extension - reader capabilities
SmartcardExtension->ReaderCapabilities.SupportedProtocols = SCARD_PROTOCOL_T0;
SmartcardExtension->ReaderCapabilities.MechProperties = 0;
SmartcardExtension->ReaderCapabilities.Channel = 0;
SmartcardExtension->ReaderCapabilities.CLKFrequency.Default = 4000;
SmartcardExtension->ReaderCapabilities.CLKFrequency.Max = 4000;
SmartcardExtension->ReaderCapabilities.DataRate.Default = 10750;
SmartcardExtension->ReaderCapabilities.DataRate.Max = 10750;
// enter correct version of the lib
SmartcardExtension->Version = SMCLIB_VERSION;
SmartcardExtension->SmartcardRequest.BufferSize = MIN_BUFFER_SIZE;
SmartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
SmartcardExtension->ReaderExtension->ReaderPowerState = PowerReaderWorking;
SmartcardExtension->ReaderCapabilities.MaxIFSD = 254;
status = SmartcardInitialize(SmartcardExtension);
if (status != STATUS_SUCCESS)
{
SmartcardDebug(DEBUG_ERROR,(TEXT("SmartcardInitialize failed - %x\n"), status));
SIMUnloadDevice(SmartcardExtension);
SmartcardExtension = NULL;
}
{
// 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]
TCHAR szDeviceName[DEVNAME_LEN];
TCHAR szFriendlyName[MAXIMUM_ATTR_STRING_LENGTH+DEVNAME_LEN+5];
status = GetDeviceName(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)
SmartcardExtension->VendorAttr.UnitNo = *pch - '0';
// Attempt to register a friendly name for this device
// for the benefit of the resource manager.
MakeFriendlyName(SmartcardExtension, szFriendlyName);
SmartcardCreateLink(szFriendlyName,szDeviceName);
}
}
//determine which port to use and the mode of operation
iobase = GetIOIndex();
if (iobase == 0)
{
SmartcardDebug(DEBUG_ERROR,(TEXT("SmartcardInitialize failed - %x\n"), status));
SIMUnloadDevice(SmartcardExtension);
SmartcardExtension = NULL;
}
//map the virtual address for SIM register structure
SmartcardExtension->ReaderExtension->pSIMReg = (PCSP_SIM_REG)SIM_InternalMapRegisterAddresses(iobase);
SmartcardDebug(DEBUG_TRACE, (TEXT("SIMCreateDevice: Exit %x\n"), status ));
SmartcardDebug(DEBUG_TRACE,(TEXT("-SIMLoadDevice\n")));
return SmartcardExtension;
}
//-----------------------------------------------------------------------------
//
// Function: SIMUnloadDevice
//
// This function unloads the device from lib
//
// Parameters:
// SmartcardExtension
// [in]call of context
//
// Returns:
// void
//
//-----------------------------------------------------------------------------
static void SIMUnloadDevice(PSMARTCARD_EXTENSION SmartcardExtension)
{
PREADER_EXTENSION pReader = SmartcardExtension->ReaderExtension;
WCHAR szFriendlyName[MAXIMUM_ATTR_STRING_LENGTH+DEVNAME_LEN+5];
DWORD retry = 0;
SmartcardDebug(DEBUG_TRACE,(TEXT("+SIMUnloadDevice\n")));
// 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("UnloadDevice - waiting for refCount %d to drop to zero\r\n"),
SmartcardExtension->ReaderExtension->d_RefCount));
}
ASSERT(!SmartcardExtension->ReaderExtension->d_RefCount);
// Remove friendly name
MakeFriendlyName(SmartcardExtension, szFriendlyName);
SmartcardDeleteLink(szFriendlyName);
// sign off from SMCLIB
SmartcardExit(SmartcardExtension);
SmartcardDebug(DEBUG_TRACE, (TEXT("%s:UnloadDevice - freeing resources\r\n")));
LocalFree(SmartcardExtension);
SmartcardDebug(DEBUG_TRACE,(TEXT("-SIMUnloadDevice\n")));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -