none
When does device can accept the IOCTL_SMARTCARD_SET_PROTOCOL code in UMDF RRS feed

  • Question

  • if (ControlCode==IOCTL_SMARTCARD_GET_ATTRIBUTE) {
    IoSmartCardGetAttribute(pRequest,inBufSize,outBufSize);
    return;
    }
    else if (ControlCode==IOCTL_SMARTCARD_IS_PRESENT) { 
    IoSmartCardIsPresent(pRequest,inBufSize,outBufSize);
    return;
    }
    else if (ControlCode==IOCTL_SMARTCARD_GET_STATE) {
    IoSmartCardGetState(pRequest,inBufSize,outBufSize);
    return;
    }
    else if (ControlCode==IOCTL_SMARTCARD_IS_ABSENT) {
    IoSmartCardIsAbsent(pRequest,inBufSize,outBufSize);
    return;
    }
    else if (ControlCode==IOCTL_SMARTCARD_POWER) {
    IoSmartCardPower(pRequest,inBufSize,outBufSize);
    return;
    }
    else if (ControlCode==IOCTL_SMARTCARD_SET_ATTRIBUTE) {
    IoSmartCardSetAttribute(pRequest,inBufSize,outBufSize);
    return;
    }
    else if (ControlCode==IOCTL_SMARTCARD_TRANSMIT) {
    IoSmartCardTransmit(pRequest,inBufSize,outBufSize);
    return;
    }
    else if (ControlCode==IOCTL_SMARTCARD_SWALLOW) {//读卡器中已经插入卡片,且到达可以使用的位置,但是还没有上电。
    OutputDebugString(L"IOCTL_SMARTCARD_SWALLOW");
    }
    else if ( ControlCode == IOCTL_SMARTCARD_SET_PROTOCOL ) {
    OutputDebugString(L"IOCTL_SMARTCARD_SWALLOW");
    return;
    I never found the  "IOCTL_SMARTCARD_SWALLOW" that was printed in DebugView.

    Monday, August 26, 2013 2:32 AM

Answers

  • Your driver needs to respond to IOCTL_SMARTCARD_GET_STATE requests with the latest state of the reader. Please see the possible states here: http://msdn.microsoft.com/en-us/library/windows/hardware/ff548904(v=vs.85).aspx. Your driver should eventually end up at SCARD_NEGOTIABLE. Once that state is received by the smart card service, it will send IOCTL_SMARTCARD_SET_PROTOCOL with the dwPreferredProtocols value. Your driver should then be in the SCARD_SPECIFIC state.

    Jeff Shipman [MSFT] -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Monday, August 26, 2013 6:26 PM
  • What does the driver give as a response when asked for SCARD_ATTR_CURRENT_PROTOCOL_TYPE? If it is not SCARD_PROTOCOL_UNDEFINED, then it will not send a request IOCTL_SMARTCARD_SET_PROTOCOL since a specific one is already set. It's important that this sequence takes place:

    1. Reader reports state is SCARD_NEGOTIABLE

    2. Reader reports protocol is SCARD_PROTOCOL_UNDEFINED

    3. Reader is told to set protocol via IOCTL_SMARTCARD_SET_PROTOCOL

    4. Reader reports state is SCARD_SPECIFIC.

    Having a specific protocol returned by SCARD_ATTR_CURRENT_PROTOCOL_TYPE, but the reader state is still SCARD_NEGOTIABLE will cause problems later on.


    Jeff Shipman [MSFT] -- This posting is provided "AS IS" with no warranties, and confers no rights.

    • Proposed as answer by Jeff Shipman - MSFT Tuesday, August 27, 2013 4:58 PM
    • Marked as answer by 夸父 Tuesday, August 27, 2013 6:05 PM
    Tuesday, August 27, 2013 4:58 PM

All replies

  • the title says set protocol  but you print a different value. why confuse the output for both IOCtl codes? you don't say what codes you do see and how you are responding to them.

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Monday, August 26, 2013 6:36 AM
  • I'm sorry for that set protocol but print a differnt value. 

    I'm working on a UMDF card-reader driver which connects to a software based SmartCard simulator thus allowing any PC/SC compliant application to interface to the SmartCard simulator.

    Implementation based on Fabio Ottavi's project here: http://www.codeproject.com/KB/system/BixVReader.aspx

     Fabio Ottavi's project  can only supported T1. But I want to make it suppoeted T1 and T0 both.

     

       If  I connect virtual  reader with api SCardConnect,then how I can get the value of  dwPreferredProtocols  in virutal card reader. I think about that maybe I can get it when OnDeviceIoControl  method is called  and the IOCTL  code is IOCTL_SMARTCARD_SET_PROTOCOL.

       So I add some code in the OnDeviceIoControl  method .I can't see that the info of IOCTL_SMARTCARD_SET_PROTOCOL  has been pirnted.

       Sorry for My poor English.

      I am very grateful for your help and comments on the issue



    • Edited by 夸父 Tuesday, August 27, 2013 12:05 AM
    Monday, August 26, 2013 9:50 AM
  • Your driver needs to respond to IOCTL_SMARTCARD_GET_STATE requests with the latest state of the reader. Please see the possible states here: http://msdn.microsoft.com/en-us/library/windows/hardware/ff548904(v=vs.85).aspx. Your driver should eventually end up at SCARD_NEGOTIABLE. Once that state is received by the smart card service, it will send IOCTL_SMARTCARD_SET_PROTOCOL with the dwPreferredProtocols value. Your driver should then be in the SCARD_SPECIFIC state.

    Jeff Shipman [MSFT] -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Monday, August 26, 2013 6:26 PM
  •   I try to solve the problem  with your recommend. But It didn't work .I don't  know why . I have made the last state of the  reader is SCARD_NEGOTIBLE .But I couldn't receive  IOCTL_SMARTCARD_SET_PROTOCOL  code in  OnDeviceIoControl.

     And I show  the  information that get when i debug the driver  below.

    00000019	16.56008530	[6204] Pipe connected	
    00000020	16.56170654	[6204] [IOCT]IOCTL 00310038 - In 0 Out 4	
    00000021	16.56174850	[6204] [GSTA]IoSmartCardGetState State:00000005	
    00000022	16.56208229	[6204] [IOCT]IOCTL 00310008 - In 4 Out 36	
    00000023	16.56214333	[6204] [GATT]SCARD_ATTR_ATR_STRING	
    00000024	16.56243134	[6204] [setBuffer]inSize:00000006	
    00000025	16.56263351	[6204] [IOCT]IOCTL 0031000C - In 8 Out 0	
    00000026	16.56277847	[6204] [SATT]IOCTL_SMARTCARD_SET_ATTRIBUTE	
    00000027	16.56280136	[6204] [SATT]SCARD_ATTR_DEVICE_IN_USE	
    00000028	16.56302834	[6204] [IOCT]IOCTL 0031002C - In 0 Out 0	
    00000029	16.56324577	[6204] [IABS]IOCTL_SMARTCARD_IS_ABSENT	
    
    00000044	31.56277275	[6204] [IOCT]IOCTL 00310004 - In 4 Out 0	
    00000045	31.56279182	[6204] [POWR]IOCTL_SMARTCARD_POWER	
    00000046	31.56284332	[6204] [POWR]SCARD_POWER_DOWN	
    00000047	32.00084686	[2732] Service Started!!! -end	
    00000048	32.00089645	[2732] In Service while	
    00000049	33.28258133	[6204] [IOCT]IOCTL 00310038 - In 0 Out 4	
    00000050	33.28264999	[6204] [GSTA]IoSmartCardGetState State:00000005	
    00000051	33.28288269	[6204] [IOCT]IOCTL 00310038 - In 0 Out 4	
    00000052	33.28313828	[6204] [GSTA]IoSmartCardGetState State:00000005	
    00000053	33.28327560	[6204] [IOCT]IOCTL 0031000C - In 8 Out 0	
    00000054	33.28329468	[6204] [SATT]IOCTL_SMARTCARD_SET_ATTRIBUTE	
    00000055	33.28334808	[6204] [SATT]SCARD_ATTR_DEVICE_IN_USE	
    00000056	33.28353500	[6204] [IOCT]IOCTL 00310008 - In 4 Out 4	
    00000057	33.28362656	[6204] [GATT]SCARD_ATTR_CURRENT_PROTOCOL_TYPE	
    00000058	33.28853607	[6204] [IOCT]IOCTL 00310038 - In 0 Out 4	
    00000059	33.28866577	[6204] [GSTA]IoSmartCardGetState State:00000005	
    00000060	33.28891373	[6204] [IOCT]IOCTL 00310038 - In 0 Out 4	
    00000061	33.28899765	[6204] [GSTA]IoSmartCardGetState State:00000005	
    00000062	33.29024887	[6204] [IOCT]IOCTL 00310038 - In 0 Out 4	
    00000063	33.29035187	[6204] [GSTA]IoSmartCardGetState State:00000005	
    00000064	33.29055405	[6204] [IOCT]IOCTL 00310038 - In 0 Out 4	
    00000065	33.29073715	[6204] [GSTA]IoSmartCardGetState State:00000005	
    00000066	33.29262924	[6204] [IOCT]IOCTL 00310038 - In 0 Out 4	
    00000067	33.29273224	[6204] [GSTA]IoSmartCardGetState State:00000005	
    00000068	33.29291534	[6204] [IOCT]IOCTL 00310038 - In 0 Out 4	
    00000069	33.29298782	[6204] [GSTA]IoSmartCardGetState State:00000005	

    the main code in driver is 

    void CMyDevice::ProcessIoControl(__in IWDFIoQueue*     pQueue,
    	__in IWDFIoRequest*   pRequest,
    	__in ULONG            ControlCode,
    	SIZE_T           inBufSize,
    	SIZE_T           outBufSize)
    {
    	inFunc
    		UNREFERENCED_PARAMETER(pQueue);
    	wchar_t log[300];
    	swprintf(log,L"[IOCT]IOCTL %08X - In %i Out %i",ControlCode,inBufSize,outBufSize);
    	OutputDebugString(log);
    
    	switch ( ControlCode )
    	{	
    
    
    		case  IOCTL_SMARTCARD_SET_PROTOCOL :
    			IoSmartCardSetProtocol(pRequest,inBufSize,outBufSize);
    			return;
    
    		case IOCTL_SMARTCARD_GET_ATTRIBUTE:
    			IoSmartCardGetAttribute(pRequest,inBufSize,outBufSize);
    			return;
    
    		case IOCTL_SMARTCARD_SET_ATTRIBUTE :
    			IoSmartCardSetAttribute(pRequest,inBufSize,outBufSize);
    			return;
    
    		case IOCTL_SMARTCARD_IS_PRESENT :
    			IoSmartCardIsPresent(pRequest,inBufSize,outBufSize);
    			return;
    
    		case IOCTL_SMARTCARD_IS_ABSENT :
    			IoSmartCardIsAbsent(pRequest,inBufSize,outBufSize);
    			return;
    
    		case IOCTL_SMARTCARD_GET_STATE :
    			IoSmartCardGetState(pRequest,inBufSize,outBufSize);
    			return;
    
    
    		case IOCTL_SMARTCARD_POWER :
    			IoSmartCardPower(pRequest,inBufSize,outBufSize);
    			return;
    	
    	
    		case IOCTL_SMARTCARD_TRANSMIT :
    			IoSmartCardTransmit(pRequest,inBufSize,outBufSize);
    			return;
    
    		case IOCTL_SMARTCARD_SWALLOW: //读卡器中已经插入卡片,且到达可以使用的位置,但是还没有上电。
    			OutputDebugString(L"IOCTL_SMARTCARD_SWALLOW");
    	
    		default:
    			swprintf(log,L"[IOCT]ERROR_NOT_SUPPORTED:%08X",ControlCode);
    			OutputDebugString(log);
    			pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0);
    			return;
    	}
    }
    
    void CMyDevice::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
    	UNREFERENCED_PARAMETER(inBufSize);
    	UNREFERENCED_PARAMETER(outBufSize);
    	OutputDebugString(L"[SATPRO]IOCTL_SMARTCARD_SET_PROTOCOL");
    
    	IWDFMemory *inmem=NULL;
    	pRequest->GetInputMemory(&inmem);
    
    	SIZE_T size;
    	BYTE *data=(BYTE *)inmem->GetDataBuffer(&size);
    
    	DWORD MinorIoControlCode=*(DWORD*)(data);
    	bool handled=false;
    
    	if (MinorIoControlCode & SCARD_PROTOCOL_Tx)// We only check the ATR when the user selects T=0 or T=1   
    	{
    		if (MinorIoControlCode == SCARD_PROTOCOL_T1 && m_atrInfo.t1_supported){   
    
    			dwCurRentProtocol = SCARD_PROTOCOL_T1;
    			handled = true;
    		} 
    		else if (MinorIoControlCode == SCARD_PROTOCOL_T0 && m_atrInfo.t0_supported){
    
    			dwCurRentProtocol = SCARD_PROTOCOL_T0;
    			handled = true;
    
    		}
    		else if (MinorIoControlCode == SCARD_PROTOCOL_Tx){
    			if (m_atrInfo.t1_supported)
    			{
    				dwCurRentProtocol = SCARD_PROTOCOL_T1;
    				handled = true;
    			}
    			else if (m_atrInfo.t0_supported)
    			{
    				dwCurRentProtocol = SCARD_PROTOCOL_T0;
    				handled = true;
    			}
    			
    
    		}
        if (handled)
        {
    		dwCurRentState = SCARD_SPECIFIC;
    		//setInt(pRequest,SCARD_SPECIFIC);
    		pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
        }
    	
    
    	}
    	inmem->Release();
    	
    
    	if (!handled) {
    		wchar_t log[300];
    		swprintf(log,L"[SATPRO]ERROR_NOT_SUPPORTED:%08X",dwCurRentProtocol);
    		OutputDebugString(log);
    		pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0);
    	}
    }
    


    Tuesday, August 27, 2013 2:01 AM
  • I can connect to the  Reader . but when I connect to the card with api ScardConnect , I didn't found the info "[SATPRO]IOCTL_SMARTCARD_SET_PROTOCOL" that  has been printed.
    Tuesday, August 27, 2013 2:06 AM
  • #define SCARD_NEGOTIABLE  5   // This value implies the card has been
                                  // reset and is awaiting PTS negotiation.
    00000052	33.28313828	[6204] [GSTA]IoSmartCardGetState State:00000005	

    Tuesday, August 27, 2013 2:11 AM
  • What does the driver give as a response when asked for SCARD_ATTR_CURRENT_PROTOCOL_TYPE? If it is not SCARD_PROTOCOL_UNDEFINED, then it will not send a request IOCTL_SMARTCARD_SET_PROTOCOL since a specific one is already set. It's important that this sequence takes place:

    1. Reader reports state is SCARD_NEGOTIABLE

    2. Reader reports protocol is SCARD_PROTOCOL_UNDEFINED

    3. Reader is told to set protocol via IOCTL_SMARTCARD_SET_PROTOCOL

    4. Reader reports state is SCARD_SPECIFIC.

    Having a specific protocol returned by SCARD_ATTR_CURRENT_PROTOCOL_TYPE, but the reader state is still SCARD_NEGOTIABLE will cause problems later on.


    Jeff Shipman [MSFT] -- This posting is provided "AS IS" with no warranties, and confers no rights.

    • Proposed as answer by Jeff Shipman - MSFT Tuesday, August 27, 2013 4:58 PM
    • Marked as answer by 夸父 Tuesday, August 27, 2013 6:05 PM
    Tuesday, August 27, 2013 4:58 PM
  •     Thank your very much.Your reply is very helpful.I have google all day. I read very word that i found ,and try very possible scenarios .But I do not to set SCARD_PROTOCOL_UNDEFINED .  I  have ever confused that  why do we need SCARD_PROTOCOL_UNDEFINED .Thanks again.I think I could sleep well tonight.


    夸父

    Tuesday, August 27, 2013 5:56 PM