📄 smcce.c
字号:
LocalFree(SmartcardExtension->SmartcardRequest.Buffer);
SmartcardExtension->SmartcardRequest.Buffer = NULL;
}
if (SmartcardExtension->SmartcardReply.Buffer) {
LocalFree(SmartcardExtension->SmartcardReply.Buffer);
SmartcardExtension->SmartcardReply.Buffer = NULL;
}
if (SmartcardExtension->OsData) {
CloseHandle(SmartcardExtension->OsData->hChangeEvent);
CloseHandle(SmartcardExtension->OsData->hCancelEvent);
DeleteCriticalSection(&SmartcardExtension->OsData->CritSect);
LocalFree(SmartcardExtension->OsData);
SmartcardExtension->OsData = NULL;
}
if (SmartcardExtension->T1.ReplyData) {
// free the reply data buffer for T=1 transmissions
LocalFree(SmartcardExtension->T1.ReplyData);
SmartcardExtension->T1.ReplyData = NULL;
}
SmartcardDebug(
DEBUG_TRACE,
(TEXT("%s!SmartcardExit: Exit\n"),
DRIVER_NAME)
);
}
NTSTATUS
SmartcardDeviceControl(
PSMARTCARD_EXTENSION SmartcardExtension,
DWORD dwIoControlCode,
PBYTE pInBuf,
DWORD nInBufSize,
PBYTE pOutBuf,
DWORD nOutBufSize,
PDWORD pBytesReturned
)
{
NTSTATUS status = STATUS_SUCCESS;
ASSERT(SmartcardExtension != NULL);
if (SmartcardExtension == NULL) {
return STATUS_INVALID_PARAMETER;
}
DEBUGMSG(ZQ,(TEXT("nInBufSize=%d , nOutBufSize=%d , \r\n")));
// Check the version that the driver requires
ASSERT(SmartcardExtension->Version >= SMCLIB_VERSION_REQUIRED);
if (SmartcardExtension->Version < SMCLIB_VERSION_REQUIRED) {
return STATUS_INVALID_PARAMETER;
}
SmartcardDebug(
DEBUG_IOCTL,
(TEXT("%s!(SmartcardDeviceControl): Ioctl = %s\n"),
DRIVER_NAME,
MapIoControlCodeToString(dwIoControlCode))
);
// Synchronize access to the driver
SmartcardLockDevice(SmartcardExtension);
if (status == STATUS_SUCCESS) {
if (pBytesReturned) {
// Default number of bytes returned
* pBytesReturned = 0;
}
switch (dwIoControlCode) {
DEBUGMSG(ZQ,(TEXT("dwIoControlCode=0X%X\r\n")));
//
// We have to check for _IS_ABSENT and _IS_PRESENT first,
// since these are (the only allowed) asynchronous requests
//
case IOCTL_SMARTCARD_IS_ABSENT:
case IOCTL_SMARTCARD_IS_PRESENT:
if (SmartcardExtension->ReaderFunction[RDF_CARD_TRACKING] == NULL) {
DEBUGMSG(ZQ,(TEXT("[RDF_CARD_TRACKING] == NULL")));
status = STATUS_NOT_SUPPORTED;
break;
}
// WinCE: only support synchronous version for now
if (dwIoControlCode == IOCTL_SMARTCARD_IS_ABSENT) {
//
// If the card is already (or still) absent, we can return immediatly.
// Otherwise we must statrt event tracking.
//
if (SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT) {
status = SmartcardExtension->ReaderFunction[RDF_CARD_TRACKING](
SmartcardExtension
);
}
} else {
//
// If the card is already (or still) present, we can return immediatly.
// Otherwise we must statrt event tracking.
//
if (SmartcardExtension->ReaderCapabilities.CurrentState <= SCARD_ABSENT) {
status = SmartcardExtension->ReaderFunction[RDF_CARD_TRACKING](
SmartcardExtension
);
}
}
if (status == STATUS_PENDING)
{
// Got to block waiting for an insertion event
DWORD dwWait;
HANDLE hWaitEvents[2];
hWaitEvents[0] = SmartcardExtension->OsData->hChangeEvent;
hWaitEvents[1] = SmartcardExtension->OsData->hCancelEvent;
// Release the lock on the device first
SmartcardUnlockDevice(SmartcardExtension);
dwWait = WaitForMultipleObjects(2, hWaitEvents,FALSE,INFINITE);
SmartcardLockDevice(SmartcardExtension);
DEBUGMSG(ZQ,(TEXT(" if (status == STATUS_PENDING)")));
if (dwWait == WAIT_OBJECT_0)
{
// card insertion event
// should we make sure the state is what we expect?
#ifdef DEBUG
if (SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT
&& dwIoControlCode == IOCTL_SMARTCARD_IS_ABSENT
|| SmartcardExtension->ReaderCapabilities.CurrentState <= SCARD_ABSENT
&& dwIoControlCode == IOCTL_SMARTCARD_IS_PRESENT)
{
SmartcardDebug(
DEBUG_ERROR,
(TEXT("%s!(Completing Ioctl = %s, current state = %d\n"),
DRIVER_NAME,
MapIoControlCodeToString(dwIoControlCode),
SmartcardExtension->ReaderCapabilities.CurrentState)
);
}
#endif
// it's possible (though rare) that the card is inserted and removed
// (or vice versa) before we wake up. Its a good idea to return
// to the caller, rather than go block again and hide the event.
status = STATUS_SUCCESS;
}
else if (dwWait == WAIT_OBJECT_0 + 1)
{
// cancel event
status = STATUS_CANCELLED;
}
else
{
// wait error
status = STATUS_UNSUCCESSFUL;
}
}
break;
case IOCTL_SMARTCARD_CANCEL_BLOCKING:
DEBUGMSG(ZQ,(TEXT(" IOCTL_SMARTCARD_CANCEL_BLOCKING")));
// Abort pending IS_ABSENT and IS_PRESENT calls
if (!PulseEvent(SmartcardExtension->OsData->hCancelEvent))
status = STATUS_UNSUCCESSFUL;
break;
default:
// Check if buffers are properly allocated
ASSERT(SmartcardExtension->SmartcardRequest.Buffer);
ASSERT(SmartcardExtension->SmartcardReply.Buffer);
// Get major io control code
SmartcardExtension->MajorIoControlCode =
dwIoControlCode;
DEBUGMSG(ZQ,(TEXT(" default")));
if (pInBuf) {
//
// Transfer minor io control code, even if it doesn't make sense for
// this particular major code
//
SmartcardExtension->MinorIoControlCode =
(nInBufSize >= sizeof(ULONG)) ? *(PULONG) (pInBuf) : 0;
// Lock memory and save pointer to and length of request buffer
// WinCE: dont need to lock
SmartcardExtension->IoRequest.RequestBuffer = (PUCHAR) pInBuf;
SmartcardExtension->IoRequest.RequestBufferLength =
nInBufSize;
} else {DEBUGMSG(ZQ,(TEXT(" pInBuf=NULL")));
SmartcardExtension->IoRequest.RequestBuffer = NULL;
SmartcardExtension->IoRequest.RequestBufferLength = 0;
}
if (pOutBuf) {
// Lock memory an save pointer to and length of reply buffer
SmartcardExtension->IoRequest.ReplyBuffer = (PUCHAR) pOutBuf;
SmartcardExtension->IoRequest.ReplyBufferLength = nOutBufSize;
} else {
SmartcardExtension->IoRequest.ReplyBuffer = NULL;
SmartcardExtension->IoRequest.ReplyBufferLength = 0;
}
SmartcardExtension->IoRequest.Information = pBytesReturned;
// Process the ioctl-request
status = SMCDeviceIoControl(SmartcardExtension);
ASSERT (status != STATUS_PENDING);
break;
}
}
SmartcardDebug(
DEBUG_IOCTL,
(TEXT("%s!(SmartcardDeviceControl): Exit\n"), DRIVER_NAME)
);
SmartcardUnlockDevice(SmartcardExtension);
if (status != STATUS_SUCCESS)
{
SetLastError(MapNtStatusToWinError(status));
}
DEBUGMSG(ZQ,(TEXT("<<==SmartcardDeviceControl( )\r\n")));
return status;
}
//
// Signal a card insertion or removal event
//
VOID
SmartcardCompleteCardTracking(
PSMARTCARD_EXTENSION SmartcardExtension
)
{DEBUGMSG(ZQ,(TEXT("==>>SmartcardCompleteCardTracking( )\r\n")));
PulseEvent(SmartcardExtension->OsData->hChangeEvent);
}
// Maps NTSTATUS codes to Win32 error codes if possible
// It is limited to mapping NTSTATUS codes in the 0xC000xxxx and 0x8000xxxx range.
// Any other codes are mapped to themselves
ULONG MapNtStatusToWinError(NTSTATUS ntstatus)
{
DWORD dwHiWord = ntstatus & 0xffff0000;
DWORD dwLoWord = ntstatus & 0xffff;
DEBUGMSG(ZQ,(TEXT("==>>MapNtStatusToWinError( )\r\n")));
if (dwHiWord == 0xC0000000
&& dwLoWord < sizeof(NTStatusC000Table)/sizeof(USHORT)
&& NTStatusC000Table[dwLoWord] != 0)
return NTStatusC000Table[dwLoWord];
if (dwHiWord == 0x80000000
&& dwLoWord < sizeof(NTStatus8000Table)/sizeof(USHORT)
&& NTStatus8000Table[dwLoWord] != 0)
return NTStatus8000Table[dwLoWord];
DEBUGMSG(ZQ,(TEXT("<<==MapNtStatusToWinError( )\r\n")));
return (ULONG)ntstatus;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -