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

📄 smcioctl.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++


Module Name:

    smcioctl.c

Abstract:

    This module handles all IOCTL requests to the smart card reader.

Environment:

    Kernel mode only.

--*/

#define _ISO_TABLES_

#ifndef SMCLIB_VXD
#ifndef SMCLIB_CE
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <ntddk.h>
#endif
#endif

#include "smclib.h"
#define	ZQ 1

#define IOCTL_SMARTCARD_DEBUG        SCARD_CTL_CODE(98) 

#define CheckUserBuffer(_len_) \
	if (SmartcardExtension->IoRequest.ReplyBuffer == NULL || \
		SmartcardExtension->IoRequest.ReplyBufferLength < (_len_)) { \
		status = STATUS_BUFFER_TOO_SMALL; \
		break; \
	}
#define CheckMinCardStatus(_status_) \
	if (SmartcardExtension->ReaderCapabilities.CurrentState < (_status_)) { \
		status = STATUS_INVALID_DEVICE_STATE; \
		break; \
	}
#define ReturnULong(_value_) \
	{ \
		CheckUserBuffer(sizeof(ULONG)) \
		*(PULONG) SmartcardExtension->IoRequest.ReplyBuffer = (_value_); \
		*SmartcardExtension->IoRequest.Information = sizeof(ULONG); \
	}
#define ReturnUChar(_value_) \
	{ \
		CheckUserBuffer(sizeof(UCHAR)) \
		*(PUCHAR) SmartcardExtension->IoRequest.ReplyBuffer = (_value_); \
		*SmartcardExtension->IoRequest.Information = sizeof(UCHAR); \
    }

#define DIM(_array_) (sizeof(_array_) / sizeof(_array_[0]))

#if (DBG || DEBUG)
PTCHAR 
MapIoControlCodeToString(
    ULONG IoControlCode
    )
{
    ULONG i;

    static struct {

        ULONG   IoControlCode;
        PTCHAR  String;

    } IoControlList[] = {
     	
        IOCTL_SMARTCARD_POWER,          TEXT("POWER"),
        IOCTL_SMARTCARD_GET_ATTRIBUTE,  TEXT("GET_ATTRIBUTE"),
        IOCTL_SMARTCARD_SET_ATTRIBUTE,  TEXT("SET_ATTRIBUTE"),
        IOCTL_SMARTCARD_CONFISCATE,     TEXT("CONFISCATE"),
        IOCTL_SMARTCARD_TRANSMIT,       TEXT("TRANSMIT"),
        IOCTL_SMARTCARD_EJECT,          TEXT("EJECT"),
        IOCTL_SMARTCARD_SWALLOW,        TEXT("SWALLOW"),       
        IOCTL_SMARTCARD_IS_PRESENT,     TEXT("IS_PRESENT"),
        IOCTL_SMARTCARD_IS_ABSENT,      TEXT("IS_ABSENT"),
        IOCTL_SMARTCARD_SET_PROTOCOL,   TEXT("SET_PROTOCOL"),
        IOCTL_SMARTCARD_GET_STATE,      TEXT("GET_STATE"),
        IOCTL_SMARTCARD_GET_LAST_ERROR, TEXT("GET_LAST_ERROR")
    };

    for (i = 0; i < DIM(IoControlList); i++) {

        if (IoControlCode == IoControlList[i].IoControlCode) {

            return IoControlList[i].String;
        }
    }

    return TEXT("*** UNKNOWN ***");
}
#endif

NTSTATUS
SMCDeviceIoControl(
    PSMARTCARD_EXTENSION SmartcardExtension
    )
/*++

Routine Description:
	
    This routine handles the smart card lib specific io control requests.
    The driver has to call the function from the driver's io control request.
    It checks the parameters of the call and depending on the type of 
    the call returns the requested value or calls the driver in order
    to perform an operation like POWER or TRANSMIT.

    NOTE: This function is used by Windows NT and VxD driver

Arguments:

    SmartcardExtension - The pointer to the smart card data struct

Return Value:

    NTSTATUS value 

--*/
{
    NTSTATUS status = STATUS_SUCCESS;
	int i=0;
#ifndef SMCLIB_VXD
#ifndef SMCLIB_CE
    KIRQL Irql;
#endif
#endif

    switch (SmartcardExtension->MajorIoControlCode) {

#if DBG
        ULONG CurrentDebugLevel;
#endif
        PSCARD_IO_REQUEST scardIoRequest;
DEBUGMSG(ZQ,(TEXT("==>>SMCDeviceIoControl( )\r\n")));
//IOCTL_SMARTCARD_GET_ATTRIBUTE////////////////////////////////////////////////
        case IOCTL_SMARTCARD_GET_ATTRIBUTE:
	DEBUGMSG(ZQ,(TEXT("==>>OCTL_SMARTCARD_GET_ATTRIBUTE\r\n")));


               ///////////////////////////////////////////////////////////////////////////////ZQ TEST

DEBUGMSG(1,(TEXT("smcioctl 0x%2x    0x%2x   0x%2x   0x%2x   0x%2x   0x%2x        \n"),
		 	*(SmartcardExtension->IoRequest.RequestBuffer),*(SmartcardExtension->IoRequest.RequestBuffer+1),
		 	*(SmartcardExtension->IoRequest.RequestBuffer+2),*(SmartcardExtension->IoRequest.RequestBuffer+3),
		 	*(SmartcardExtension->IoRequest.RequestBuffer+4),*(SmartcardExtension->IoRequest.RequestBuffer+5)));
		
	
///////////////////////////////////////////////////////////////////////  
			//
			// Please refer to the Interoperrability standard for ICC
			//
			switch (SmartcardExtension->MinorIoControlCode) {

				case SCARD_ATTR_VENDOR_NAME:
					CheckUserBuffer(SmartcardExtension->VendorAttr.VendorName.Length);

					RtlCopyMemory(
						SmartcardExtension->IoRequest.ReplyBuffer,
						SmartcardExtension->VendorAttr.VendorName.Buffer,
						SmartcardExtension->VendorAttr.VendorName.Length
						);
		DEBUGMSG(ZQ,(TEXT("SmartcardExtension->IoRequest.ReplyBuffer = %s\r\n"),SmartcardExtension->IoRequest.ReplyBuffer));			
		            *SmartcardExtension->IoRequest.Information = 
		            	SmartcardExtension->VendorAttr.VendorName.Length;
					break;

				case SCARD_ATTR_VENDOR_IFD_TYPE:
					CheckUserBuffer(SmartcardExtension->VendorAttr.VendorName.Length);

					RtlCopyMemory(
						SmartcardExtension->IoRequest.ReplyBuffer,
						SmartcardExtension->VendorAttr.IfdType.Buffer,
						SmartcardExtension->VendorAttr.IfdType.Length
						);
		            *SmartcardExtension->IoRequest.Information = 
		            	SmartcardExtension->VendorAttr.IfdType.Length;
					break;

                case SCARD_ATTR_VENDOR_IFD_VERSION:
                    ReturnULong(
                        SmartcardExtension->VendorAttr.IfdVersion.BuildNumber | 
                        SmartcardExtension->VendorAttr.IfdVersion.VersionMinor << 16 | 
                        SmartcardExtension->VendorAttr.IfdVersion.VersionMajor << 24 
                        );
                	break;

                case SCARD_ATTR_VENDOR_IFD_SERIAL_NO:
                    if (SmartcardExtension->VendorAttr.IfdSerialNo.Length == 0) {

                        status = STATUS_NOT_SUPPORTED;
                     	
                    } else {
                     	
					    CheckUserBuffer(SmartcardExtension->VendorAttr.IfdSerialNo.Length);

					    RtlCopyMemory(
						    SmartcardExtension->IoRequest.ReplyBuffer,
						    SmartcardExtension->VendorAttr.IfdSerialNo.Buffer,
						    SmartcardExtension->VendorAttr.IfdSerialNo.Length
						    );
		                *SmartcardExtension->IoRequest.Information = 
		            	    SmartcardExtension->VendorAttr.IfdSerialNo.Length;
                    }

                	break;

				case SCARD_ATTR_DEVICE_UNIT:
					// Return the unit number of this device
					ReturnULong(SmartcardExtension->VendorAttr.UnitNo);
					break;

				case SCARD_ATTR_CHANNEL_ID:
					//
					// Return reader type / channel id in form
					// 0xDDDDCCCC where D is reader type and C is channel number
					//
					ReturnULong(
						SmartcardExtension->ReaderCapabilities.ReaderType << 16l |
						SmartcardExtension->ReaderCapabilities.Channel
						);
					break;

				case SCARD_ATTR_CHARACTERISTICS:
					// Return mechanical characteristics of the reader
					ReturnULong(
						SmartcardExtension->ReaderCapabilities.MechProperties
						)
					break;

				case SCARD_ATTR_CURRENT_PROTOCOL_TYPE:
					// Return the currently selected protocol
					CheckMinCardStatus(SCARD_NEGOTIABLE);

					ReturnULong(
						SmartcardExtension->CardCapabilities.Protocol.Selected
						);
					break;

				case SCARD_ATTR_CURRENT_CLK:
					//
					// Return the current ICC clock freq. encoded as little
					// endian integer value (3.58 MHZ is 3580)
					//
					CheckMinCardStatus(SCARD_NEGOTIABLE);

                      ASSERT(SmartcardExtension->CardCapabilities.Fl < 
                        DIM(ClockRateConversion));

					ReturnULong(
						SmartcardExtension->CardCapabilities.ClockRateConversion[
							SmartcardExtension->CardCapabilities.Fl
							].fs / 1000l
						);
					break;

				case SCARD_ATTR_CURRENT_F:
					// Return the current F value encoded as little endian integer
					CheckMinCardStatus(SCARD_NEGOTIABLE);

                      ASSERT(SmartcardExtension->CardCapabilities.Fl < 
                        DIM(ClockRateConversion));

					ReturnULong(
						SmartcardExtension->CardCapabilities.ClockRateConversion[
							SmartcardExtension->CardCapabilities.Fl
							].F
						);
					break;

				case SCARD_ATTR_CURRENT_D:
					//
					// Return the current D value encoded as little endian integer
					// in units of 1/64. So return 1 if D is 1/64.
					//
					CheckMinCardStatus(SCARD_NEGOTIABLE);

                   ASSERT(
                        SmartcardExtension->CardCapabilities.Dl < 
                        DIM(BitRateAdjustment)
                     );

                      ASSERT(
                        SmartcardExtension->CardCapabilities.BitRateAdjustment[
							SmartcardExtension->CardCapabilities.Dl
							].DDivisor != 0
                       );

                    //
                    // Check the current value of Dl.
                    // It should definitely not be greater than the array bounds
                    // and the value in the array is not allowed to be zero
                    //
                    if (SmartcardExtension->CardCapabilities.Dl >=
                        DIM(BitRateAdjustment) ||                        
                        SmartcardExtension->CardCapabilities.BitRateAdjustment[
							SmartcardExtension->CardCapabilities.Dl
							].DDivisor == 0) {

                        status = STATUS_UNRECOGNIZED_MEDIA;
                        break;                             	
                    }

					ReturnULong(
						64 * 
						SmartcardExtension->CardCapabilities.BitRateAdjustment[
							SmartcardExtension->CardCapabilities.Dl
							].DNumerator /
						SmartcardExtension->CardCapabilities.BitRateAdjustment[
							SmartcardExtension->CardCapabilities.Dl
							].DDivisor
						);
					break;

				case SCARD_ATTR_CURRENT_W:
					// Return the work waiting time (integer) for T=0
					CheckMinCardStatus(SCARD_NEGOTIABLE);
					ReturnULong(SmartcardExtension->CardCapabilities.T0.WI);
					break;

                case SCARD_ATTR_CURRENT_N:
					// Return extra guard time
					CheckMinCardStatus(SCARD_NEGOTIABLE);
					ReturnULong(SmartcardExtension->CardCapabilities.N);
                	break;

				case SCARD_ATTR_CURRENT_IFSC:
					// Return the current information field size card
					CheckMinCardStatus(SCARD_NEGOTIABLE);
					ReturnULong(SmartcardExtension->T1.IFSC);
					break;

				case SCARD_ATTR_CURRENT_IFSD:
					// Return the current information field size card
					CheckMinCardStatus(SCARD_NEGOTIABLE);
					ReturnULong(SmartcardExtension->T1.IFSD);
					break;

				case SCARD_ATTR_CURRENT_BWT:
					// Return the current block waiting time for T=1
					CheckMinCardStatus(SCARD_NEGOTIABLE);
					ReturnULong(SmartcardExtension->CardCapabilities.T1.BWI);
					break;

				case SCARD_ATTR_CURRENT_CWT:
					// Return the current character waiting time for T=1
					CheckMinCardStatus(SCARD_NEGOTIABLE);
					ReturnULong(SmartcardExtension->CardCapabilities.T1.CWI);
					break;

				case SCARD_ATTR_CURRENT_EBC_ENCODING:
					// Return the current error checking method
					CheckMinCardStatus(SCARD_NEGOTIABLE);
					ReturnULong(SmartcardExtension->CardCapabilities.T1.EDC);
					break;

                case SCARD_ATTR_DEFAULT_CLK:
                    ReturnULong(
                        SmartcardExtension->ReaderCapabilities.CLKFrequency.Default
                        );
                	break;

                case SCARD_ATTR_MAX_CLK:
                    ReturnULong(
                        SmartcardExtension->ReaderCapabilities.CLKFrequency.Max
                        );
                	break;

                case SCARD_ATTR_DEFAULT_DATA_RATE:
                    ReturnULong(
                        SmartcardExtension->ReaderCapabilities.DataRate.Default
                        );
                	break;

                case SCARD_ATTR_MAX_DATA_RATE:
                    ReturnULong(
                        SmartcardExtension->ReaderCapabilities.DataRate.Max
                        );
                	break;

				case SCARD_ATTR_ATR_STRING:
					// Return ATR of currently inserted card
					CheckUserBuffer(SmartcardExtension->CardCapabilities.ATR.Length);
					CheckMinCardStatus(SCARD_NEGOTIABLE);
					RtlCopyMemory(
						SmartcardExtension->IoRequest.ReplyBuffer,
						SmartcardExtension->CardCapabilities.ATR.Buffer,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -