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

📄 tlp3ce.c

📁 基于windows ce环境下对smart card 基于pc/sc架构下驱动例程
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// 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:

    tlp3ce.c

Abstract:

    Smart Card Reader Driver for Windows CE.

--*/
#include <stdio.h>
#include <smclib.h>
#include <devload.h>
#include <tchar.h>

#include "TLP3CE.h"
#include "BullTLP3.h"                            
// prototypes 
BOOL TLP3UpdateReaderState(PSMARTCARD_EXTENSION SmartcardExtension);

const TCHAR szDriverName[] = TEXT("Bull TLP3 ");

// Used to synchronize access to global driver data structures
CRITICAL_SECTION g_DriverCritSect;

#ifdef DEBUG

#define DEBUG_INIT      0x00000040
#define DEBUG_SERIAL    0x00000080
#define DEBUG_THREAD    0x00000200


DBGPARAM dpCurSettings = {
    TEXT("BULLTLP3"), {
    TEXT("Ioctl"), TEXT("ATR"), TEXT("Protocol"), TEXT("Driver"),
    TEXT("Trace"),TEXT("Error"), TEXT("Initialization"),TEXT("Serial"),
    TEXT(" I/O"),TEXT("Thread"),TEXT(""),TEXT(""),
    TEXT(""),TEXT(""),TEXT(""),TEXT("Break On Open") },
    0x00000020          // DEBUG_ERROR
};
#endif  // DEBUG


// allow upto MAX_PSCR_DEVICES
PSMARTCARD_EXTENSION DeviceSlot[MAXIMUM_SERIAL_READERS];

BOOL AddDevice(PSMARTCARD_EXTENSION pDevice)
{
    int i;
    EnterCriticalSection(&g_DriverCritSect);
    for (i=0; i< MAXIMUM_SERIAL_READERS; i++)
    {
        if (DeviceSlot[i] == NULL)
        {
            DeviceSlot[i] = pDevice;
            break;
        }
    }
    LeaveCriticalSection(&g_DriverCritSect);
    return (i < MAXIMUM_SERIAL_READERS);
}

BOOL RemoveDevice(PSMARTCARD_EXTENSION pDevice)
{
    int i;
    EnterCriticalSection(&g_DriverCritSect);
    for (i=0; i< MAXIMUM_SERIAL_READERS; i++)
    {
        if (DeviceSlot[i] == pDevice)
        {
            DeviceSlot[i] = NULL;
            break;
        }
    }
    LeaveCriticalSection(&g_DriverCritSect);

    return (i < MAXIMUM_SERIAL_READERS);
}

BOOL ValidateAndEnterDevice(PSMARTCARD_EXTENSION pDevice)
{
    int i;
    EnterCriticalSection(&g_DriverCritSect);
    
    for (i=0; i< MAXIMUM_SERIAL_READERS; i++)
    {
        if (DeviceSlot[i] == pDevice)
        {
            EnterDevice(pDevice);
            break;
        }
    }
    LeaveCriticalSection(&g_DriverCritSect);
#ifdef DEBUG
    if (i >= MAXIMUM_SERIAL_READERS)
    {
        SmartcardDebug(DEBUG_ERROR,(TEXT("%s:ValidateDevice - Invalid Object %x\n"),szDriverName,pDevice));
    }
#endif
    return (i < MAXIMUM_SERIAL_READERS);
}


//
// DLL entry
//
BOOL WINAPI
DllEntry(HINSTANCE DllInstance, INT Reason, LPVOID Reserved)
{
    switch(Reason) {
    case DLL_PROCESS_ATTACH:
        DEBUGREGISTER(DllInstance);
        SmartcardDebug(DEBUG_INIT, (TEXT("%s: DLL_PROCESS_ATTACH\r\n"), szDriverName));
        InitializeCriticalSection(&g_DriverCritSect);
        memset(DeviceSlot,0,sizeof(DeviceSlot));
	DisableThreadLibraryCalls((HMODULE) DllInstance);
        break;
   
    case DLL_PROCESS_DETACH:
        SmartcardDebug(DEBUG_INIT, (TEXT("%s: DLL_PROCESS_DETACH\r\n"), szDriverName));
        DeleteCriticalSection(&g_DriverCritSect);
        break;
    }
    return TRUE;
}


//
// File system device entrypoints (DEV_????)
//

//
// Returns context data (PDISK) for this Init instance or 0 for failure.
//
// Arguments:
//      dwContext - registry path for this device's active key
//
DWORD
SCR_Init(
    DWORD dwContext
    )
{
    PSMARTCARD_EXTENSION   pSmartcardExtension;
    LPTSTR ActiveKey = (LPTSTR)dwContext;

    if (pSmartcardExtension=TLP3LoadDevice(ActiveKey)) {
        if (AddDevice(pSmartcardExtension)) // check for device overflow
        {
            TCHAR szDeviceName[DEVNAME_LEN];
            TCHAR szFriendlyName[MAXIMUM_ATTR_STRING_LENGTH+DEVNAME_LEN+5];
            DWORD status;
            // 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]
            status = GetDeviceName(pSmartcardExtension->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)
                    pSmartcardExtension->VendorAttr.UnitNo = *pch - '0';
                // Attempt to register a friendly name for this device 
                // for the benefit of the resource manager. 
                // The friendly name has the format "PRODUCTNAME [UNITNO]"
                // For example, "SCM SwapSmart [1]"
                //
                MakeFriendlyName(pSmartcardExtension, szFriendlyName);
                SmartcardCreateLink(szFriendlyName,szDeviceName); 
            }
            return (DWORD)pSmartcardExtension;
        }
        else {
            SmartcardDebug(DEBUG_INIT|DEBUG_ERROR,
                (TEXT("%s: TLP_Init Device Overflow error\r\n"),szDriverName));
            TLP3UnloadDevice(pSmartcardExtension);
            ASSERT(FALSE);
        };

    }
    return (DWORD)NULL;
    // insert call to detection function if one is defined
    //
    // do device initialization
}
//
// Device deinit - devices are expected to close down.
// The device manager does not check the return code.
//
BOOL
SCR_Deinit(
    DWORD dwContext     // pointer to the per device structure
    )
{
    SmartcardDebug(DEBUG_INIT|DEBUG_TRACE,
        (TEXT("%s: TLP_DeInit\r\n"),szDriverName));
    SCR_Close(dwContext);
    TLP3UnloadDevice((PSMARTCARD_EXTENSION)dwContext);
    return TRUE;
}

//
// Returns handle value for the open instance.
// we only allow one open at a time because this is an inherently state-ful device
//
DWORD
SCR_Open(
    DWORD dwData,
    DWORD dwAccess,
    DWORD dwShareMode
    )
{
    PSMARTCARD_EXTENSION   pSmartcardExtension = (PSMARTCARD_EXTENSION) dwData;
    PREADER_EXTENSION readerExtension = pSmartcardExtension->ReaderExtension;
    
    SmartcardDebug(DEBUG_TRACE,(TEXT("%s: Open(%x) - entered\n"),szDriverName,dwData));
#ifdef DEBUG
    if (DEBUGZONE(15))
        DebugBreak();
#endif

    if (!ValidateAndEnterDevice(pSmartcardExtension))
    {
        SetLastError(ERROR_BAD_DEVICE);
        ASSERT(FALSE);
        return 0;
    }

    if (readerExtension->d_uReaderState != STATE_CLOSED)
    {
    
        SmartcardDebug(DEBUG_ERROR,(TEXT("%s: Open - invalid state %d\n"), szDriverName,
            readerExtension->d_uReaderState
            ));
        dwData = 0;
        SetLastError(ERROR_SHARING_VIOLATION);
        ASSERT(FALSE);
    }
    else
    {
        // clear card state
        memset(&pSmartcardExtension->CardCapabilities, 0, sizeof(SCARD_CARD_CAPABILITIES));
        // clear reader state
        pSmartcardExtension->ReaderCapabilities.CurrentState = SCARD_UNKNOWN;
        if (TLP3CreateSerialPort(pSmartcardExtension)) 
        {
            BOOLEAN bStatus;
            DWORD status;

            // ReadExtension
            // Set serial configuration parameters for read extention
            // Initial DCB
            bStatus=GetCommState(readerExtension->hSerialPort,
                &(readerExtension->SerialConfigData.SerialControlBlock));
            ASSERT(bStatus);

             readerExtension->SerialConfigData.SerialControlBlock.BaudRate=CBR_9600;
            readerExtension->SerialConfigData.SerialControlBlock.StopBits=ONESTOPBIT;//STOPBITS_20;
            readerExtension->SerialConfigData.SerialControlBlock.fParity=0; // Even Pariry check
            readerExtension->SerialConfigData.SerialControlBlock.Parity=NOPARITY;//PARITY_EVEN;
//            readerExtension->SerialConfigData.SerialControlBlock.fBinary=1; // Skip EOF; 8-bit binary data.
            readerExtension->SerialConfigData.SerialControlBlock.ByteSize=DATABITS_8;

            readerExtension->SerialConfigData.SerialControlBlock.fTXContinueOnXoff=1;
            readerExtension->SerialConfigData.SerialControlBlock.fOutX =0;
            readerExtension->SerialConfigData.SerialControlBlock.fInX =0;

            // DTR RTS always on.
/*			
            readerExtension->SerialConfigData.SerialControlBlock.fDtrControl=DTR_CONTROL_DISABLE;
//            readerExtension->SerialConfigData.SerialControlBlock.fDtrControl=DTR_CONTROL_ENABLE;
            readerExtension->SerialConfigData.SerialControlBlock.fRtsControl=RTS_CONTROL_DISABLE;
            // Ingore CTS and DSR for output
            readerExtension->SerialConfigData.SerialControlBlock.fOutxCtsFlow=0;
            readerExtension->SerialConfigData.SerialControlBlock.fOutxDsrFlow=0;

            //Data only valid when DSR On
            readerExtension->SerialConfigData.SerialControlBlock.fDsrSensitivity=0;
*/
            // Time out set.
            readerExtension->SerialConfigData.Timeouts.ReadIntervalTimeout=READ_INTERVAL_TIMEOUT_DEFAULT;
            readerExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant=
                READ_TOTAL_TIMEOUT_CONSTANT_DEFAULT;
            readerExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier=
                readerExtension->SerialConfigData.Timeouts.WriteTotalTimeoutMultiplier=0;

            // save the current power state of the reader
            readerExtension->ReaderPowerState = PowerReaderWorking;
            status = TLP3ConfigureSerialPort(pSmartcardExtension);
            // TEST only
            readerExtension->SerialConfigData.SerialControlBlock.fRtsControl=RTS_CONTROL_ENABLE;
            ASSERT(status==STATUS_SUCCESS);
            if (status == STATUS_SUCCESS)
            {
                // We seem to need a delay before the serial control lines can be
                // be correctly read.
                Sleep(500);
                if (TLP3UpdateReaderState(pSmartcardExtension))
                {
                    // Create Backgroud thread for monitoring serial state changes
                    ASSERT(!readerExtension->hBackgroundThread);
                    readerExtension->hBackgroundThread=
                    CreateThread(NULL,
                                0,
                                TLP3SerialEvent,
                                pSmartcardExtension,
                                CREATE_SUSPENDED,
                                &(readerExtension->dwThreadID));

                    ASSERT(readerExtension->hBackgroundThread);
                    if (readerExtension->hBackgroundThread)
                    {
                        readerExtension->d_uReaderState = STATE_OPENED;
                        ResumeThread(readerExtension->hBackgroundThread);
                    }
                }
            }
        }
        else
        { // cannot open comm port
            SmartcardDebug(DEBUG_INIT|DEBUG_ERROR,(TEXT("%s: SmartcardInitialize failed to open %s\n"),
                        szDriverName,
                        readerExtension->d_SerialPort));
        }
        
        if (readerExtension->d_uReaderState != STATE_OPENED)
        {
            // cleanup
               dwData = 0;
               // close serial port if it was opened
            TLP3CloseSerialPort(pSmartcardExtension);
        }
    }
    LeaveDevice(pSmartcardExtension);

    return dwData;
}

BOOL
SCR_Close(
    DWORD Handle
    )
{
    BOOL fRet;
    PSMARTCARD_EXTENSION   pSmartcardExtension = (PSMARTCARD_EXTENSION) Handle;

    SmartcardDebug(DEBUG_TRACE,(TEXT("%s: Close(%x) - entered\n"),szDriverName,Handle));
    if (!ValidateAndEnterDevice(pSmartcardExtension))
    {
        SetLastError(ERROR_BAD_DEVICE);
        return FALSE;
    }
    if (pSmartcardExtension->ReaderExtension->d_uReaderState != STATE_OPENED)
    {
        fRet = FALSE;
        SetLastError(ERROR_BAD_DEVICE);
        ASSERT(FALSE);
    }
    else
    {
        DWORD retry = 0;
        pSmartcardExtension->ReaderExtension->d_uReaderState = STATE_CLOSED;
        while (pSmartcardExtension->ReaderExtension->d_RefCount > 1 && ++retry < 3)
        {
            // cancel any outstanding blocking calls
             SmartcardDebug(DEBUG_TRACE,(TEXT("%s: Close - waiting for %d threads to exit\n"),
             szDriverName, pSmartcardExtension->ReaderExtension->d_RefCount -1
            ));
            SmartcardDeviceControl(pSmartcardExtension, IOCTL_SMARTCARD_CANCEL_BLOCKING,

⌨️ 快捷键说明

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