⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smcce.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 + -