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

📄 tlp3nt.c

📁 SmardCard Windows驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (C) 1997, 98 Microsoft Corporation

Module Name:

    bulltlp3.c

Abstract:

    Smart card driver for Bull TLP3 reader

Author:

    Klaus U. Schutz

Environment:

    Kernel mode

Revision History :

    Nov. 1997 - 1.0 Release
    Jan. 1998 - Fix for vendor defined IOCTLs
                TLP3SerialIo now writes the whole data packet if GT is 0
                Support for higher data rates added
    Feb. 1998 - PnP version

--*/

#include <stdio.h>
#include "bulltlp3.h"

#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGEABLE, TLP3CreateAndStartDevice)
#pragma alloc_text(PAGEABLE, TLP3StartSerialEventTracking)
#pragma alloc_text(PAGEABLE, TLP3AddDevice)
#pragma alloc_text(PAGEABLE, TLP3CreateDevice)
#pragma alloc_text(PAGEABLE, TLP3RemoveDevice)
#pragma alloc_text(PAGEABLE, TLP3DriverUnload)

#if DBG
#pragma optimize ("", off)
#endif

#ifdef SIMULATION
PWSTR DriverKey;
#endif

NTSTATUS
DriverEntry(
    IN  PDRIVER_OBJECT  DriverObject,
    IN  PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    This routine is called at system initialization time to initialize
    this driver.

Arguments:

    DriverObject    - Supplies the driver object.
    RegistryPath    - Supplies the registry path for this driver.

Return Value:

    STATUS_SUCCESS          - We could initialize at least one device.
    STATUS_NO_SUCH_DEVICE   - We could not initialize even one device.

--*/
{
   NTSTATUS status = STATUS_SUCCESS;
   ULONG device;

    SmartcardDebug(
        DEBUG_INFO,
       ("%s!DriverEntry: Enter - %s %s\n",
        DRIVER_NAME,
        __DATE__,
        __TIME__)
        )

    //
    // we do some stuff in this driver that
    // assumes a single digit port number
    //
    ASSERT(MAXIMUM_SERIAL_READERS < 10);

    // Initialize the Driver Object with driver's entry points
    DriverObject->DriverUnload = TLP3DriverUnload;
    DriverObject->MajorFunction[IRP_MJ_CREATE] = TLP3CreateClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = TLP3CreateClose;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TLP3Cleanup;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TLP3DeviceControl;
    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = TLP3SystemControl;
   DriverObject->MajorFunction[IRP_MJ_PNP]   = TLP3PnP;
   DriverObject->MajorFunction[IRP_MJ_POWER] = TLP3Power;
    DriverObject->DriverExtension->AddDevice = TLP3AddDevice;

#ifdef SIMULATION
   DriverKey = ExAllocatePool(PagedPool, RegistryPath->Length + sizeof(L""));

   if (DriverKey) {

      RtlZeroMemory(
         DriverKey,
         RegistryPath->Length + sizeof(L"")
         );

      RtlCopyMemory(
         DriverKey,
         RegistryPath->Buffer,
         RegistryPath->Length
         );
   }
#endif

    return status;
}

NTSTATUS
TLP3AddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
/*++

Routine Description:

    This routine creates an object for the physical device specified and
    sets up the deviceExtension.

--*/
{
    PDEVICE_EXTENSION deviceExtension;
   NTSTATUS status = STATUS_SUCCESS;
   PREADER_EXTENSION readerExtension;
    PSMARTCARD_EXTENSION smartcardExtension;
   ULONG deviceInstance;
   HANDLE regKey = NULL;
   PDEVICE_OBJECT DeviceObject = NULL;

    // this is a list of our supported data rates
    static ULONG dataRatesSupported[] = { 9600, 19200, 38400, 57600, 115200 };


   SmartcardDebug(
      DEBUG_TRACE,
      ( "%s!TLP3AddDevice: Enter\n",
        DRIVER_NAME)
      );

    PAGED_CODE();

   __try {

      // Create the device object
      status = IoCreateDevice(
         DriverObject,
         sizeof(DEVICE_EXTENSION),
         NULL,
         FILE_DEVICE_SMARTCARD,
         0,
         TRUE,
         &DeviceObject
         );

      if (status != STATUS_SUCCESS) {

         SmartcardLogError(
            DriverObject,
            TLP3_CANT_CREATE_DEVICE,
            NULL,
            0
            );

         __leave;
      }

      SmartcardDebug(
         DEBUG_TRACE,
         ( "%s!TLP3CreateDevice: Device created\n",
         DRIVER_NAME)
         );

      // set up the device extension.
      deviceExtension = DeviceObject->DeviceExtension;
      smartcardExtension = &deviceExtension->SmartcardExtension;

      deviceExtension->CloseSerial = IoAllocateWorkItem(
         DeviceObject
         );

      // Used for stop / start notification
      KeInitializeEvent(
         &deviceExtension->ReaderStarted,
         NotificationEvent,
         FALSE
         );

      // Used to keep track of open close calls
      deviceExtension->ReaderOpen = FALSE;

      KeInitializeSpinLock(&deviceExtension->SpinLock);

      // Allocate data struct space for smart card reader
      smartcardExtension->ReaderExtension = ExAllocatePool(
         NonPagedPool,
         sizeof(READER_EXTENSION)
         );

      if (smartcardExtension->ReaderExtension == NULL) {

         SmartcardLogError(
            DriverObject,
            TLP3_NO_MEMORY,
            NULL,
            0
            );

         status = STATUS_INSUFFICIENT_RESOURCES;
         __leave;
      }

      readerExtension = smartcardExtension->ReaderExtension;
      RtlZeroMemory(readerExtension, sizeof(READER_EXTENSION));

      // Write the version of the lib we use to the smartcard extension
      smartcardExtension->Version = SMCLIB_VERSION;
      smartcardExtension->SmartcardRequest.BufferSize =
      smartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;

      //
      // Now let the lib allocate the buffer for data transmission
      // We can either tell the lib how big the buffer should be
      // by assigning a value to BufferSize or let the lib
      // allocate the default size
      //
      status = SmartcardInitialize(smartcardExtension);

      if (status != STATUS_SUCCESS) {

         SmartcardLogError(
            DriverObject,
            (smartcardExtension->OsData ? TLP3_WRONG_LIB_VERSION : TLP3_NO_MEMORY),
            NULL,
            0
            );

         __leave;
      }

      // Save deviceObject
      smartcardExtension->OsData->DeviceObject = DeviceObject;

      // Set up call back functions
      smartcardExtension->ReaderFunction[RDF_TRANSMIT] = TLP3Transmit;
      smartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] = TLP3SetProtocol;
      smartcardExtension->ReaderFunction[RDF_CARD_POWER] = TLP3ReaderPower;
      smartcardExtension->ReaderFunction[RDF_CARD_TRACKING] = TLP3CardTracking;
      smartcardExtension->ReaderFunction[RDF_IOCTL_VENDOR] = TLP3VendorIoctl;

      // This event signals that the serial driver has been closed
      KeInitializeEvent(
         &READER_EXTENSION_L(SerialCloseDone),
         NotificationEvent,
         TRUE
         );

      //
      // Set the vendor information
      //
      strcpy(smartcardExtension->VendorAttr.VendorName.Buffer, "Bull");

      smartcardExtension->VendorAttr.VendorName.Length =
         (USHORT) strlen(deviceExtension->SmartcardExtension.VendorAttr.VendorName.Buffer);

      strcpy(smartcardExtension->VendorAttr.IfdType.Buffer, "SmarTLP");

      smartcardExtension->VendorAttr.IfdType.Length =
            (USHORT) strlen(smartcardExtension->VendorAttr.IfdType.Buffer);

      smartcardExtension->VendorAttr.UnitNo = MAXULONG;

      for (deviceInstance = 0; deviceInstance < MAXULONG; deviceInstance++) {

         PDEVICE_OBJECT devObj;

         for (devObj = DeviceObject;
             devObj != NULL;
             devObj = devObj->NextDevice) {

             PDEVICE_EXTENSION devExt = devObj->DeviceExtension;
             PSMARTCARD_EXTENSION smcExt = &devExt->SmartcardExtension;

             if (deviceInstance == smcExt->VendorAttr.UnitNo) {

                break;
             }
         }
         if (devObj == NULL) {

            smartcardExtension->VendorAttr.UnitNo = deviceInstance;
            break;
         }
      }

      //
      // Set the reader capabilities
      //

      // Clk frequency in KHz encoded as little endian integer
      smartcardExtension->ReaderCapabilities.CLKFrequency.Default = 3571;
      smartcardExtension->ReaderCapabilities.CLKFrequency.Max = 3571;

      smartcardExtension->ReaderCapabilities.DataRate.Default =
      smartcardExtension->ReaderCapabilities.DataRate.Max =
         dataRatesSupported[0];

      // reader could support higher data rates
      smartcardExtension->ReaderCapabilities.DataRatesSupported.List =
         dataRatesSupported;
      smartcardExtension->ReaderCapabilities.DataRatesSupported.Entries =
         sizeof(dataRatesSupported) / sizeof(dataRatesSupported[0]);

      smartcardExtension->ReaderCapabilities.MaxIFSD = 254;

      // Now setup information in our deviceExtension
      smartcardExtension->ReaderCapabilities.CurrentState =
         (ULONG) SCARD_UNKNOWN;

      // This reader supports T=0 and T=1
      smartcardExtension->ReaderCapabilities.SupportedProtocols =
         SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;

      smartcardExtension->ReaderCapabilities.MechProperties = 0;

      //
      // Set serial configuration parameters
      //
      readerExtension->SerialConfigData.BaudRate.BaudRate = 9600;

      readerExtension->SerialConfigData.LineControl.StopBits =
         STOP_BITS_2;
      readerExtension->SerialConfigData.LineControl.Parity =
         EVEN_PARITY;
      readerExtension->SerialConfigData.LineControl.WordLength =
         SERIAL_DATABITS_8;

      // set timeouts
      readerExtension->SerialConfigData.Timeouts.ReadIntervalTimeout =
         READ_INTERVAL_TIMEOUT_DEFAULT;
      readerExtension->SerialConfigData.Timeouts.ReadTotalTimeoutConstant =
         READ_TOTAL_TIMEOUT_CONSTANT_DEFAULT;
      readerExtension->SerialConfigData.Timeouts.ReadTotalTimeoutMultiplier = 0;

      // set special characters
      readerExtension->SerialConfigData.SerialChars.ErrorChar = 0;
      readerExtension->SerialConfigData.SerialChars.EofChar = 0;
      readerExtension->SerialConfigData.SerialChars.EventChar = 0;
      readerExtension->SerialConfigData.SerialChars.XonChar = 0;
      readerExtension->SerialConfigData.SerialChars.XoffChar = 0;
      readerExtension->SerialConfigData.SerialChars.BreakChar = 0xFF;

      // Set handflow
      readerExtension->SerialConfigData.HandFlow.XonLimit = 0;
      readerExtension->SerialConfigData.HandFlow.XoffLimit = 0;
      readerExtension->SerialConfigData.HandFlow.ControlHandShake = 0;
      readerExtension->SerialConfigData.HandFlow.FlowReplace =
         SERIAL_XOFF_CONTINUE;
#if defined (DEBUG) && defined (DETECT_SERIAL_OVERRUNS)
      readerExtension->SerialConfigData.HandFlow.ControlHandShake =
         SERIAL_ERROR_ABORT;
#endif

      // save the current power state of the reader
      readerExtension->ReaderPowerState = PowerReaderWorking;

        // and attach to the PDO
      ATTACHED_DEVICE_OBJECT =
            IoAttachDeviceToDeviceStack(
            DeviceObject,
            PhysicalDeviceObject
            );

        ASSERT(ATTACHED_DEVICE_OBJECT != NULL);

        if (ATTACHED_DEVICE_OBJECT == NULL) {

           SmartcardLogError(
              DriverObject,
              TLP3_CANT_CONNECT_TO_ASSIGNED_PORT,
              NULL,
              status
              );

            status = STATUS_UNSUCCESSFUL;
            __leave;
        }

        // register our new device
        status = IoRegisterDeviceInterface(
            PhysicalDeviceObject,
            &SmartCardReaderGuid,
            NULL,
            &deviceExtension->PnPDeviceName
            );
        ASSERT(status == STATUS_SUCCESS);

      DeviceObject->Flags |= DO_BUFFERED_IO;
      DeviceObject->Flags |= DO_POWER_PAGABLE;
      DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

   }
   __finally {

      if (regKey) {

         ZwClose(regKey);
      }

        if (status != STATUS_SUCCESS) {

            TLP3RemoveDevice(DeviceObject);
        }

      SmartcardDebug(
         DEBUG_TRACE,
         ( "%s!TLP3AddDevice: Exit %x\n",
         DRIVER_NAME,
         status)
         );
   }
   return status;
}

NTSTATUS
TLP3StartDevice(
    IN PDEVICE_OBJECT DeviceObject
    )
/*++

Routine Description:
   Open the serial device, start card tracking and register our
    device interface. If any of the calls here fails we don't care
    to rollback since a stop will be called later which we then
    use to clean up.

--*/
{
    NTSTATUS status;
    PIRP irp;
      PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
   PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;

   SmartcardDebug(
      DEBUG_TRACE,
      ( "%s!TLP3StartDevice: Enter\n",
        DRIVER_NAME)
      );

    irp = IoAllocateIrp(
        (CCHAR) (DeviceObject->StackSize + 1),
        FALSE
        );

    ASSERT(irp != NULL);

    if (irp == NULL) {

        return STATUS_NO_MEMORY;
    }

    _try {

        PIO_STACK_LOCATION irpStack;
        HANDLE handle = 0;
        IO_STATUS_BLOCK ioStatusBlock;

        //
        // Open the underlying serial driver.
        // This is necessary for two reasons:

⌨️ 快捷键说明

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