mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1386 lines
45 KiB
1386 lines
45 KiB
/*******************************************************************************
|
|
* Copyright (c) 1997-1998 Gemplus Development
|
|
*
|
|
* Name : GNTSCR09.C (Gemplus NT Smart Card Reader module 09)
|
|
*
|
|
* Description : This is the main module which holds:
|
|
* - the main functions for a standard NT driver
|
|
*
|
|
* Compiler : Microsoft DDK for Windows NT
|
|
*
|
|
* Host : IBM PC and compatible machines under Windows NT
|
|
*
|
|
* Release : 1.00.003
|
|
*
|
|
* Last Modif : 24/01/98: V1.00.003 (Gilles PAUZIE)
|
|
* - Modifiy GDDKNT_09CreateDevice function. The IoCreateDevice
|
|
* function is now always called with FALSE parameters for the
|
|
* both compilator mode free and checked. This resolves the
|
|
* problem of the IO pending for the free mode.
|
|
* 22/12/97: V1.00.002 (Thierry Fabre)
|
|
* - Modifiy GDDKNT_Cleanup function to abort a pending io-
|
|
* request (wait for insertion/removal card).
|
|
* 22/06/97: V1.00.001 (Gilles Pauzie)
|
|
* - Start of development.
|
|
*
|
|
********************************************************************************
|
|
*
|
|
* Warning :
|
|
*
|
|
* Remark :
|
|
*
|
|
*******************************************************************************/
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Include section:
|
|
- stdio.h: standards definitons.
|
|
- ntddk.h: DDK Windows NT general definitons.
|
|
- ntddser.h: DDK Windows NT serial management definitons.
|
|
------------------------------------------------------------------------------*/
|
|
#include <stdio.h>
|
|
#include <ntddk.h>
|
|
#include <ntddser.h>
|
|
/*------------------------------------------------------------------------------
|
|
- smclib.h: smart card library definitions.
|
|
------------------------------------------------------------------------------*/
|
|
#define SMARTCARD_POOL_TAG 'cGCS'
|
|
#include <smclib.h>
|
|
/*------------------------------------------------------------------------------
|
|
- gemlog.h: Gemplus error log file definitions.
|
|
- gioctl09.h: public interface definition for the IOCTL functions.
|
|
- gntscr09.h: public interface definition for this module.
|
|
- gntser.h: public interface definition for serial management
|
|
------------------------------------------------------------------------------*/
|
|
#include "gemlog.h"
|
|
#include "gemcore.h"
|
|
#include "gioctl09.h"
|
|
#include "gntscr09.h"
|
|
#include "gntser.h"
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Compiler Directives:
|
|
------------------------------------------------------------------------------*/
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text(INIT, DriverEntry)
|
|
#pragma alloc_text(INIT, GDDKNT_09AddDevice)
|
|
#pragma alloc_text(INIT, GDDKNT_09CreateDevice)
|
|
#endif // ALLOC_PRAGMA
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Constant section:
|
|
- SC_DRIVER_VERSION defines the version of the driver
|
|
- IFD_STANDARD_BAUD_RATE defines the standard baud rate for the reader (9600)
|
|
- MAX_DEVICES is the maximum number of devices (and instances) we want
|
|
to support
|
|
- POLLING_TIMEOUT is the polling timeout for detection insertion/removal card
|
|
in milliseconds (1000 ms)
|
|
------------------------------------------------------------------------------*/
|
|
#define SC_DRIVER_VERSION 0x090
|
|
#define IFD_STANDARD_BAUD_RATE 9600
|
|
#define MAX_DEVICES 16
|
|
#define POLLING_TIMEOUT 1000
|
|
|
|
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Function definition section:
|
|
------------------------------------------------------------------------------*/
|
|
|
|
/*******************************************************************************
|
|
* NTSTATUS DriverEntry
|
|
* (
|
|
* IN PDRIVER_OBJECT DriverObject,
|
|
* IN PUNICODE_STRING RegistryPath
|
|
* )
|
|
* Description :
|
|
* -------------
|
|
* This routine is called at system initialization time to initialize
|
|
* this driver.
|
|
*
|
|
* Remarks :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* In :
|
|
* -------------
|
|
* - DriverObject supplies the driver object.
|
|
* - RegistryPath supplies the registry path for this driver.
|
|
*
|
|
* Out :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* Responses :
|
|
* -------------
|
|
* STATUS_SUCCESS - We could initialize at least one device.
|
|
* STATUS_NO_SUCH_DEVICE - We could not initialize even one device.
|
|
*******************************************************************************/
|
|
NTSTATUS DriverEntry
|
|
(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPath
|
|
)
|
|
{
|
|
ULONG
|
|
serialNumber,
|
|
ifdNumber,
|
|
noOfDevices = 0,
|
|
maxBaudRate,
|
|
maximalIFD,
|
|
IFDOption,
|
|
i;
|
|
NTSTATUS
|
|
status;
|
|
PSMARTCARD_EXTENSION
|
|
previousDeviceExt = NULL;
|
|
RTL_QUERY_REGISTRY_TABLE
|
|
paramTable[4];
|
|
UNICODE_STRING
|
|
driverPath;
|
|
WCHAR
|
|
buffer[MAXIMUM_FILENAME_LENGTH];
|
|
INT16
|
|
response;
|
|
USHORT
|
|
rlen;
|
|
BYTE
|
|
rbuff[HOR3GLL_BUFFER_SIZE],
|
|
sbuff[HOR3GLL_BUFFER_SIZE];
|
|
|
|
#if DBG
|
|
/*------------------------------------------------------------------------------
|
|
Initialize the debug level.
|
|
------------------------------------------------------------------------------*/
|
|
SmartcardSetDebugLevel(DEBUG_ALL);
|
|
#endif
|
|
/*------------------------------------------------------------------------------
|
|
Initialize the Driver Object with driver's entry points
|
|
------------------------------------------------------------------------------*/
|
|
DriverObject->DriverUnload = GDDKNT_09Unload;
|
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = GDDKNT_09CreateClose;
|
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = GDDKNT_09CreateClose;
|
|
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = GDDKNT_09Cleanup;
|
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = GDDKNT_09DeviceControl;
|
|
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Read in the the driver registry path:
|
|
- "MaximalBaudRate" is the maximal speed specified for the reader.
|
|
- "MaximalIFD" is the maximal number of security modules for the reader.
|
|
- "IFDOption" is the options for the reader.
|
|
------------------------------------------------------------------------------*/
|
|
maxBaudRate = 0;
|
|
RtlZeroMemory(paramTable,sizeof(paramTable));
|
|
paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
paramTable[0].Name = L"MaximalBaudRate";
|
|
paramTable[0].EntryContext = &maxBaudRate;
|
|
paramTable[0].DefaultType = REG_DWORD;
|
|
paramTable[0].DefaultData = &maxBaudRate;
|
|
paramTable[0].DefaultLength = sizeof(ULONG);
|
|
|
|
maximalIFD = 0;
|
|
paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
paramTable[1].Name = L"MaximalIFD";
|
|
paramTable[1].EntryContext = &maximalIFD;
|
|
paramTable[1].DefaultType = REG_DWORD;
|
|
paramTable[1].DefaultData = &maximalIFD;
|
|
paramTable[1].DefaultLength = sizeof(ULONG);
|
|
|
|
IFDOption = 0;
|
|
paramTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
|
|
paramTable[2].Name = L"IFDOption";
|
|
paramTable[2].EntryContext = &IFDOption;
|
|
paramTable[2].DefaultType = REG_DWORD;
|
|
paramTable[2].DefaultData = &IFDOption;
|
|
paramTable[2].DefaultLength = sizeof(ULONG);
|
|
|
|
driverPath.Buffer = buffer;
|
|
driverPath.MaximumLength = sizeof(buffer);
|
|
driverPath.Length = 0;
|
|
|
|
RtlCopyUnicodeString(&driverPath,RegistryPath);
|
|
|
|
status =
|
|
RtlQueryRegistryValues(
|
|
RTL_REGISTRY_ABSOLUTE,
|
|
driverPath.Buffer,
|
|
¶mTable[0],
|
|
NULL,
|
|
NULL
|
|
);
|
|
if ((maxBaudRate != 9600lu) && (maxBaudRate != 19200lu) &&
|
|
(maxBaudRate != 38400lu) && (maxBaudRate != 76800lu)
|
|
)
|
|
{
|
|
maxBaudRate = IFD_STANDARD_BAUD_RATE;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------
|
|
For all the serial ports we search if a Gemplus Oros Based reader is
|
|
connected. If we found a reader, we create 1 device by IFD in the reader.
|
|
For example we can have 2 devices for a GCR500 (1 for the main reader,
|
|
1 for the Security Access Module).
|
|
------------------------------------------------------------------------------*/
|
|
for (serialNumber = 0;
|
|
(serialNumber < HGTSER_MAX_PORT) && (noOfDevices < MAX_DEVICES);
|
|
serialNumber++)
|
|
{
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Build a string like \Device\SerialN (N is the 0 based device number)
|
|
------------------------------------------------------------------------------*/
|
|
UNICODE_STRING
|
|
serialDeviceName, deviceNo, device;
|
|
WCHAR
|
|
buffer[32];
|
|
|
|
serialDeviceName.Buffer = buffer;
|
|
serialDeviceName.MaximumLength = sizeof(buffer);
|
|
serialDeviceName.Length = 0;
|
|
|
|
RtlInitUnicodeString(&device,L"\\Device\\Serial");
|
|
|
|
RtlCopyUnicodeString(&serialDeviceName,&device);
|
|
|
|
deviceNo.Buffer =
|
|
serialDeviceName.Buffer +
|
|
serialDeviceName.Length / sizeof(WCHAR);
|
|
|
|
deviceNo.MaximumLength = 2 * sizeof(WCHAR);
|
|
deviceNo.Length = 0;
|
|
|
|
RtlIntegerToUnicodeString(serialNumber,10,&deviceNo);
|
|
|
|
serialDeviceName.Length += deviceNo.Length;
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Try to create a device for all the IFD availables in the reader
|
|
------------------------------------------------------------------------------*/
|
|
for (ifdNumber=0;
|
|
(ifdNumber<maximalIFD) && (ifdNumber<MAX_IFD_BY_READER);
|
|
ifdNumber++)
|
|
{
|
|
status = GDDKNT_09AddDevice(
|
|
DriverObject,
|
|
&serialDeviceName,
|
|
noOfDevices,
|
|
serialNumber,
|
|
ifdNumber,
|
|
previousDeviceExt,
|
|
maxBaudRate
|
|
);
|
|
|
|
if (status == STATUS_SUCCESS)
|
|
{
|
|
// We have successfully created a device
|
|
PDEVICE_OBJECT deviceObject =
|
|
DriverObject->DeviceObject;
|
|
PDEVICE_EXTENSION deviceExtension =
|
|
deviceObject->DeviceExtension;
|
|
PSMARTCARD_EXTENSION smartcardExtension =
|
|
&deviceExtension->SmartcardExtension;
|
|
|
|
ASSERT(deviceObject != NULL);
|
|
ASSERT(deviceExtension != NULL);
|
|
ASSERT(smartcardExtension != NULL);
|
|
|
|
smartcardExtension->ReaderExtension->MaximalIFD = maximalIFD;
|
|
smartcardExtension->ReaderExtension->IFDOption = IFDOption;
|
|
|
|
noOfDevices++;
|
|
|
|
/*------------------------------------------------------------------------------
|
|
If is the first IFD for the reader
|
|
Save the DeviceObject for the next IFD.
|
|
Read the type of the reader
|
|
If the reader type is GCR410
|
|
No more IFD available on this port
|
|
------------------------------------------------------------------------------*/
|
|
if (ifdNumber == 0)
|
|
{
|
|
previousDeviceExt = smartcardExtension;
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Read the type of the reader
|
|
------------------------------------------------------------------------------*/
|
|
sbuff[0] = HOR3GLL_IFD_CMD_INFO;
|
|
sbuff[1] = 0x01;
|
|
rlen = HOR3GLL_BUFFER_SIZE;
|
|
response = G_Oros3Exchange
|
|
(
|
|
(INT16)(noOfDevices-1),
|
|
HOR3GLL_DEFAULT_TIME,
|
|
(const WORD16)2,
|
|
(const BYTE *)sbuff,
|
|
&rlen,
|
|
rbuff
|
|
);
|
|
/*------------------------------------------------------------------------------
|
|
If the reader type is GCR410
|
|
Then
|
|
No more IFD available on this port
|
|
------------------------------------------------------------------------------*/
|
|
if ((response != G_OK) || (rlen != 2) || (rbuff[0] != 0) || (rbuff[1] == 0x01))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------
|
|
If we haven't found any reader on the serial, then we write a message in the
|
|
event log file.
|
|
------------------------------------------------------------------------------*/
|
|
if (noOfDevices == 0)
|
|
{
|
|
SmartcardLogError(
|
|
DriverObject,
|
|
GEM_NO_SUCH_DEVICE,
|
|
NULL,
|
|
status
|
|
);
|
|
return STATUS_NO_SUCH_DEVICE;
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* NTSTATUS GDDKNT_09AddDevice
|
|
* (
|
|
* IN PDRIVER_OBJECT DriverObject,
|
|
* IN PUNICODE_STRING SerialDeviceName,
|
|
* IN ULONG DeviceNumber,
|
|
* IN ULONG SerialNumber,
|
|
* IN ULONG IFDNumber,
|
|
* IN PSMARTCARD_EXTENSION PreviousDeviceExt,
|
|
* IN ULONG MaximalBaudRate
|
|
* )
|
|
*
|
|
* Description :
|
|
* -------------
|
|
* This is the add-device routine.
|
|
*
|
|
* Remarks :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* In :
|
|
* -------------
|
|
* - DriverObject is a pointer to the driver object for this device.
|
|
* - SerialDeviceName holds the device name of the serial port to attach to.
|
|
* - DeviceNumber holds an ascending device number starting with 0.
|
|
* - SerialNumber holds the serial port number (0 to 3).
|
|
* - IFDNumber holds the numero of the IFD in
|
|
* the reader (0 to MAX_IFD_BY_READER).
|
|
* - PreviousDeviceExt holds the previous smart card object. It is used to
|
|
* know the serial device object.
|
|
* - MaximalBaudRate holds the maximal speed specified for the reader.
|
|
* Out :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* Responses :
|
|
* -------------
|
|
* STATUS_SUCCESS Device created.
|
|
*******************************************************************************/
|
|
NTSTATUS GDDKNT_09AddDevice
|
|
(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING SerialDeviceName,
|
|
IN ULONG DeviceNumber,
|
|
IN ULONG SerialNumber,
|
|
IN ULONG IFDNumber,
|
|
IN PSMARTCARD_EXTENSION PreviousDeviceExt,
|
|
IN ULONG MaximalBaudRate
|
|
)
|
|
{
|
|
UNICODE_STRING
|
|
smartcardDeviceName, deviceNo, device;
|
|
WCHAR
|
|
buffer[64];
|
|
NTSTATUS
|
|
status;
|
|
|
|
ASSERT(DriverObject != NULL);
|
|
ASSERT(SerialDeviceName != NULL);
|
|
ASSERT(DeviceNumber >= 0);
|
|
ASSERT(SerialNumber >= 0);
|
|
ASSERT(IFDNumber >= 0);
|
|
/*------------------------------------------------------------------------------
|
|
Build a device name for the smart card reader
|
|
\Device\GemSCR09pi: p (0 to 3) is the port number,
|
|
i (0 to MAX_IFD_BY_READER) is the 0 based IFD number
|
|
------------------------------------------------------------------------------*/
|
|
smartcardDeviceName.Buffer = buffer;
|
|
smartcardDeviceName.MaximumLength = sizeof(buffer);
|
|
smartcardDeviceName.Length = 0;
|
|
|
|
RtlInitUnicodeString(&device,L"\\Device\\GemSCR09");
|
|
|
|
RtlCopyUnicodeString(&smartcardDeviceName,&device);
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Add the port serial number
|
|
------------------------------------------------------------------------------*/
|
|
deviceNo.Buffer =
|
|
smartcardDeviceName.Buffer + smartcardDeviceName.Length / sizeof(WCHAR);
|
|
|
|
deviceNo.MaximumLength = 2 * sizeof(WCHAR);
|
|
deviceNo.Length = 0;
|
|
|
|
RtlIntegerToUnicodeString(SerialNumber,16,&deviceNo);
|
|
|
|
smartcardDeviceName.Length += deviceNo.Length;
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Add the ifd number
|
|
------------------------------------------------------------------------------*/
|
|
deviceNo.Buffer =
|
|
smartcardDeviceName.Buffer + smartcardDeviceName.Length / sizeof(WCHAR);
|
|
|
|
deviceNo.MaximumLength = 2 * sizeof(WCHAR);
|
|
deviceNo.Length = 0;
|
|
|
|
RtlIntegerToUnicodeString(IFDNumber,16,&deviceNo);
|
|
|
|
smartcardDeviceName.Length += deviceNo.Length;
|
|
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Try to create a device with the just created device name
|
|
It is possible that a smart card device with this name
|
|
already exists from a previous call.
|
|
------------------------------------------------------------------------------*/
|
|
status = GDDKNT_09CreateDevice(
|
|
DriverObject,
|
|
&smartcardDeviceName,
|
|
SerialDeviceName,
|
|
DeviceNumber,
|
|
SerialNumber,
|
|
IFDNumber,
|
|
PreviousDeviceExt,
|
|
MaximalBaudRate
|
|
);
|
|
|
|
if (status == STATUS_SUCCESS)
|
|
{
|
|
|
|
PDEVICE_OBJECT
|
|
deviceObject = DriverObject->DeviceObject;
|
|
PDEVICE_EXTENSION
|
|
deviceExtension = deviceObject->DeviceExtension;
|
|
PSMARTCARD_EXTENSION
|
|
smartcardExtension = &deviceExtension->SmartcardExtension;
|
|
|
|
ASSERT(deviceObject != NULL);
|
|
ASSERT(deviceExtension != NULL);
|
|
ASSERT(smartcardExtension != NULL);
|
|
|
|
}
|
|
if (status != STATUS_OBJECT_NAME_COLLISION)
|
|
{
|
|
/*------------------------------------------------------------------------------
|
|
The corresponding serial port is already in use
|
|
So don't try to create a smart card device with a different name
|
|
------------------------------------------------------------------------------*/
|
|
return status;
|
|
}
|
|
return status;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* NTSTATUS GDDKNT_09CreateDevice
|
|
* (
|
|
* IN PDRIVER_OBJECT DriverObject,
|
|
* IN PUNICODE_STRING SmartcardDeviceName,
|
|
* IN PUNICODE_STRING SerialDeviceName,
|
|
* IN ULONG DeviceNumber,
|
|
* IN ULONG SerialNumber,
|
|
* IN ULONG IFDNumber,
|
|
* IN PSMARTCARD_EXTENSION PreviousDeviceExt,
|
|
* IN ULONG MaximalBaudRate
|
|
* )
|
|
*
|
|
* Description :
|
|
* -------------
|
|
* This routine creates an object for the physical device specified and
|
|
* sets up the deviceExtension.
|
|
*
|
|
* Remarks :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* In :
|
|
* -------------
|
|
* - DriverObject is a pointer to the driver object for this device.
|
|
* - SmartcardDeviceName holds the device name for this new device.
|
|
* - SerialDeviceName holds the device name of the serial port to attach to.
|
|
* - SerialNumber holds the serial port number (0 to 3).
|
|
* - IFDNumber holds the numero of the IFD in the reader (0 to MAX_IFD_BY_READER).
|
|
* - PreviousDeviceExt holds the previous smart card object. It is used to know the serial
|
|
* device object.
|
|
* - MaximalBaudRate holds the maximal speed specified for the reader.
|
|
* Out :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* Responses :
|
|
* -------------
|
|
* STATUS_SUCCESS Device created.
|
|
*******************************************************************************/
|
|
NTSTATUS GDDKNT_09CreateDevice
|
|
(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING SmartcardDeviceName,
|
|
IN PUNICODE_STRING SerialDeviceName,
|
|
IN ULONG DeviceNumber,
|
|
IN ULONG SerialNumber,
|
|
IN ULONG IFDNumber,
|
|
IN PSMARTCARD_EXTENSION PreviousDeviceExt,
|
|
IN ULONG MaximalBaudRate
|
|
)
|
|
{
|
|
PFILE_OBJECT
|
|
serialFileObject;
|
|
PDEVICE_OBJECT
|
|
deviceObject, serialDeviceObject;
|
|
PDEVICE_EXTENSION
|
|
deviceExtension;
|
|
NTSTATUS
|
|
status = STATUS_SUCCESS;
|
|
ULONG
|
|
i;
|
|
|
|
ASSERT(DriverObject != NULL);
|
|
ASSERT(SmartcardDeviceName != NULL);
|
|
ASSERT(SerialDeviceName != NULL);
|
|
ASSERT(DeviceNumber >= 0);
|
|
ASSERT(SerialNumber >= 0);
|
|
ASSERT(IFDNumber >= 0);
|
|
|
|
SmartcardDebug(
|
|
DEBUG_DRIVER,
|
|
("GEMSCR09!GDDKNT_09CreateDevice: DeviceNumber=%ld IFDNumber=%ld SerialDeviceName=%ws\n",
|
|
DeviceNumber,
|
|
IFDNumber,
|
|
SerialDeviceName->Buffer)
|
|
);
|
|
|
|
/*------------------------------------------------------------------------------
|
|
For the first IFD in the reader we try to get a pointer on the serial driver
|
|
If we can't have a pointer on the serial object, perhaps the serial port
|
|
is already used by an other device.
|
|
------------------------------------------------------------------------------*/
|
|
if (IFDNumber == 0)
|
|
{
|
|
status = IoGetDeviceObjectPointer(
|
|
SerialDeviceName,
|
|
FILE_ALL_ACCESS,
|
|
&serialFileObject,
|
|
&serialDeviceObject
|
|
);
|
|
SmartcardDebug(
|
|
DEBUG_DRIVER,
|
|
("GEMSCR09!GDDKNT_09CreateDevice: IoGetDeviceObjectPointer=%lX\n",status)
|
|
);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
return status;
|
|
}
|
|
ASSERT(serialFileObject != NULL);
|
|
ASSERT(serialDeviceObject != NULL);
|
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Try to create a new device smart card object
|
|
------------------------------------------------------------------------------*/
|
|
status = IoCreateDevice(
|
|
DriverObject,
|
|
sizeof(DEVICE_EXTENSION),
|
|
SmartcardDeviceName,
|
|
FILE_DEVICE_SMARTCARD,
|
|
0,
|
|
FALSE,
|
|
&deviceObject
|
|
);
|
|
SmartcardDebug(
|
|
DEBUG_DRIVER,
|
|
("GEMSCR09!GDDKNT_09CreateDevice: IoCreateDevice=%lX\n",status)
|
|
);
|
|
/*------------------------------------------------------------------------------
|
|
If we have failed to create a new device, then we write a message in the
|
|
event log file.
|
|
------------------------------------------------------------------------------*/
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
if (IFDNumber == 0)
|
|
{
|
|
ObDereferenceObject(serialFileObject);
|
|
}
|
|
SmartcardLogError(
|
|
DriverObject,
|
|
GEM_CANT_CREATE_DEVICE,
|
|
SmartcardDeviceName,
|
|
status
|
|
);
|
|
return status;
|
|
}
|
|
ASSERT(deviceObject != NULL);
|
|
/*------------------------------------------------------------------------------
|
|
Now we have a pointer on the new device and we try to allocate memory for
|
|
the ReaderExtension struct.
|
|
------------------------------------------------------------------------------*/
|
|
deviceExtension = deviceObject->DeviceExtension;
|
|
ASSERT(deviceExtension != NULL);
|
|
|
|
deviceObject->Flags = deviceObject->Flags | DO_BUFFERED_IO;
|
|
|
|
RtlZeroMemory(deviceExtension,sizeof(PDEVICE_EXTENSION));
|
|
|
|
deviceExtension->SmartcardExtension.ReaderExtension =
|
|
ExAllocatePool(
|
|
NonPagedPool,
|
|
sizeof(READER_EXTENSION)
|
|
);
|
|
|
|
if (deviceExtension->SmartcardExtension.ReaderExtension == NULL)
|
|
{
|
|
SmartcardLogError(
|
|
DriverObject,
|
|
GEM_NO_MEMORY_FOR_READER_EXTENSION,
|
|
SmartcardDeviceName,
|
|
0
|
|
);
|
|
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
if (status == STATUS_SUCCESS)
|
|
{
|
|
|
|
SmartcardDebug(
|
|
DEBUG_DRIVER,
|
|
("GEMSCR09!GDDKNT_09CreateDevice: SmartcardExtension=%lX\n",
|
|
&(deviceExtension->SmartcardExtension))
|
|
);
|
|
/*------------------------------------------------------------------------------
|
|
Write the version of the lib we use to the smartcard extension
|
|
------------------------------------------------------------------------------*/
|
|
(deviceExtension->SmartcardExtension).Version = SMCLIB_VERSION;
|
|
|
|
/*------------------------------------------------------------------------------
|
|
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
|
|
------------------------------------------------------------------------------*/
|
|
deviceExtension->SmartcardExtension.SmartcardRequest.BufferSize =
|
|
MIN_BUFFER_SIZE;
|
|
deviceExtension->SmartcardExtension.SmartcardReply.BufferSize =
|
|
MIN_BUFFER_SIZE;
|
|
status = SmartcardInitialize(&deviceExtension->SmartcardExtension);
|
|
SmartcardDebug(
|
|
DEBUG_DRIVER,
|
|
("GEMSCR09!GDDKNT_09CreateDevice: SmartcardInitialize=%lX\n",status)
|
|
);
|
|
if (status != STATUS_SUCCESS)
|
|
{
|
|
SmartcardLogError(
|
|
DriverObject,
|
|
GEM_CANT_INITIALIZE_SMCLIB,
|
|
SmartcardDeviceName,
|
|
status
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------
|
|
If SmartCardInitialize success
|
|
We flush the ReaderExtension struct
|
|
------------------------------------------------------------------------------*/
|
|
if (status == STATUS_SUCCESS)
|
|
{
|
|
RtlZeroMemory(
|
|
deviceExtension->SmartcardExtension.ReaderExtension,
|
|
sizeof(READER_EXTENSION)
|
|
);
|
|
/*------------------------------------------------------------------------------
|
|
Save the deviceObject
|
|
------------------------------------------------------------------------------*/
|
|
deviceExtension->SmartcardExtension.OsData->DeviceObject =
|
|
deviceObject;
|
|
/*------------------------------------------------------------------------------
|
|
Save the deviceObject and the FileObject for the connected serial port
|
|
------------------------------------------------------------------------------*/
|
|
if (IFDNumber == 0)
|
|
{
|
|
deviceExtension->SmartcardExtension.ReaderExtension->ConnectedSerialPort =
|
|
serialDeviceObject;
|
|
deviceExtension->SmartcardExtension.ReaderExtension->SerialFileObject =
|
|
serialFileObject;
|
|
}
|
|
else
|
|
{
|
|
deviceExtension->SmartcardExtension.ReaderExtension->ConnectedSerialPort =
|
|
PreviousDeviceExt->ReaderExtension->ConnectedSerialPort;
|
|
deviceExtension->SmartcardExtension.ReaderExtension->SerialFileObject =
|
|
PreviousDeviceExt->ReaderExtension->SerialFileObject;
|
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Save the serial port number this device is connected to
|
|
------------------------------------------------------------------------------*/
|
|
deviceExtension->SmartcardExtension.ReaderCapabilities.Channel = SerialNumber;
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Now we verify if a GemCore based reader is connected on this serial port.
|
|
------------------------------------------------------------------------------*/
|
|
status = GDDK_09OpenChannel(
|
|
&deviceExtension->SmartcardExtension,
|
|
DeviceNumber,
|
|
SerialNumber,
|
|
IFDNumber,
|
|
MaximalBaudRate
|
|
);
|
|
SmartcardDebug(
|
|
DEBUG_DRIVER,
|
|
("GEMSCR09!GDDKNT_09CreateDevice: GDDK_09OpenChannel=%lX\n",status)
|
|
);
|
|
|
|
/*------------------------------------------------------------------------------
|
|
If we have found a GemCore based reader connected on this serial port.
|
|
Then
|
|
Set up the call back functions
|
|
(nota: RDF_CARD_EJECT and RDF_READER_SWALLOW are not supported)
|
|
------------------------------------------------------------------------------*/
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
deviceExtension->SmartcardExtension.ReaderFunction[RDF_TRANSMIT] =
|
|
GDDK_09Transmit;
|
|
deviceExtension->SmartcardExtension.ReaderFunction[RDF_SET_PROTOCOL] =
|
|
GDDK_09SetProtocol;
|
|
deviceExtension->SmartcardExtension.ReaderFunction[RDF_CARD_POWER] =
|
|
GDDK_09ReaderPower;
|
|
deviceExtension->SmartcardExtension.ReaderFunction[RDF_CARD_TRACKING] =
|
|
GDDK_09CardTracking;
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Create a symbolic link with the SMCLIB for this new device
|
|
------------------------------------------------------------------------------*/
|
|
status = SmartcardCreateLink(
|
|
&deviceExtension->SmartcardExtension.ReaderExtension->DosDeviceName,
|
|
SmartcardDeviceName
|
|
);
|
|
if (status != STATUS_SUCCESS)
|
|
{
|
|
SmartcardLogError(
|
|
DriverObject,
|
|
GEM_CREATE_LINK_FAILED,
|
|
SmartcardDeviceName,
|
|
status
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------------------------------------------
|
|
If we have failed anywhere above, we need to free the memory and the device
|
|
------------------------------------------------------------------------------*/
|
|
if (status != STATUS_SUCCESS)
|
|
{
|
|
ExFreePool(deviceExtension->SmartcardExtension.ReaderExtension);
|
|
SmartcardExit(&deviceExtension->SmartcardExtension);
|
|
IoDeleteDevice(deviceObject);
|
|
if (IFDNumber == 0)
|
|
{
|
|
ObDereferenceObject(serialFileObject);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SmartcardDebug(
|
|
DEBUG_DRIVER,
|
|
("GEMSCR09!GDDKNT_09CreateDevice: Device %ws created\n",
|
|
deviceExtension->SmartcardExtension.ReaderExtension->DosDeviceName.Buffer)
|
|
);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* NTSTATUS GDDKNT_09CreateClose
|
|
* (
|
|
* IN PDEVICE_OBJECT DeviceObject,
|
|
* IN PIRP Irp
|
|
* )
|
|
*
|
|
* Description :
|
|
* -------------
|
|
* This routine is called by the I/O system when the device is opened or closed.
|
|
*
|
|
* Remarks :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* In :
|
|
* -------------
|
|
* - DeviceObject is a pointer to the device.
|
|
* - Irp holds the Irp involved.
|
|
* Out :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* Responses :
|
|
* -------------
|
|
* STATUS_SUCCESS
|
|
*******************************************************************************/
|
|
NTSTATUS GDDKNT_09CreateClose
|
|
(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
)
|
|
{
|
|
NTSTATUS
|
|
status;
|
|
KEVENT
|
|
event;
|
|
LARGE_INTEGER
|
|
timeout;
|
|
PDEVICE_EXTENSION
|
|
deviceExtension = DeviceObject->DeviceExtension;
|
|
PSMARTCARD_EXTENSION
|
|
smartcardExtension = &deviceExtension->SmartcardExtension;
|
|
PIO_STACK_LOCATION
|
|
irpStack = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
ASSERT(deviceExtension != NULL);
|
|
ASSERT(smartcardExtension != NULL);
|
|
ASSERT(irpStack != NULL);
|
|
|
|
if (irpStack->MajorFunction == IRP_MJ_CREATE)
|
|
{
|
|
|
|
SmartcardDebug(
|
|
DEBUG_DRIVER,
|
|
("GEMSCR09!GDDKNT_09CreateClose: Device %ws opened\n",
|
|
smartcardExtension->ReaderExtension->DosDeviceName.Buffer)
|
|
);
|
|
if (smartcardExtension->ReaderExtension->IFDNumber == 0)
|
|
{
|
|
/*------------------------------------------------------------------------------
|
|
Update the current state of reader (card present/removed)
|
|
Initialize the Card Tracking only if the reader can support this function.
|
|
------------------------------------------------------------------------------*/
|
|
GDDK_09UpdateCardStatus(smartcardExtension);
|
|
status = GDDKNT_09InitializeCardTracking(smartcardExtension);
|
|
if (status != STATUS_SUCCESS)
|
|
{
|
|
SmartcardLogError(
|
|
DeviceObject,
|
|
GEM_CREATE_CARD_TRACKING_THREAD,
|
|
&smartcardExtension->ReaderExtension->DosDeviceName,
|
|
status
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SmartcardDebug(
|
|
DEBUG_DRIVER,
|
|
("GEMSCR09!GDDKNT_09CreateClose: Device %ws closed\n",
|
|
smartcardExtension->ReaderExtension->DosDeviceName.Buffer)
|
|
);
|
|
/*------------------------------------------------------------------------------
|
|
Stop the card tracking thread
|
|
------------------------------------------------------------------------------*/
|
|
if ((smartcardExtension->ReaderExtension->IFDNumber == 0) &&
|
|
(smartcardExtension->ReaderExtension->CardStatus.Mode == RUN_IN_PROCESS))
|
|
{
|
|
smartcardExtension->ReaderExtension->CardStatus.Mode = STOP_REQUEST;
|
|
KeInitializeEvent(&event,NotificationEvent,FALSE);
|
|
while (smartcardExtension->ReaderExtension->CardStatus.Mode == STOP_REQUEST)
|
|
{
|
|
timeout.QuadPart = -((LONGLONG)100*10*1000);
|
|
status = KeWaitForSingleObject(&event,
|
|
Suspended,
|
|
KernelMode,
|
|
FALSE,
|
|
&timeout);
|
|
}
|
|
}
|
|
}
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
|
|
SmartcardDebug(DEBUG_DRIVER,("GEMSCR09!GDDKNT_09CreateClose: Exit\n"));
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* NTSTATUS GDDKNT_09Cleanup
|
|
* (
|
|
* IN PDEVICE_OBJECT DeviceObject,
|
|
* IN PIRP Irp
|
|
* )
|
|
*
|
|
* Description :
|
|
* -------------
|
|
* This routine is called by the I/O system when the device is opened or closed.
|
|
*
|
|
* Remarks :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* In :
|
|
* -------------
|
|
* - DeviceObject is a pointer to the device.
|
|
* - Irp holds the Irp involved.
|
|
* Out :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* Responses :
|
|
* -------------
|
|
* STATUS_SUCCESS
|
|
*******************************************************************************/
|
|
NTSTATUS GDDKNT_09Cleanup
|
|
(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
)
|
|
{
|
|
PDEVICE_EXTENSION
|
|
deviceExtension = DeviceObject->DeviceExtension;
|
|
PSMARTCARD_EXTENSION
|
|
smartcardExtension = &deviceExtension->SmartcardExtension;
|
|
NTSTATUS
|
|
status = STATUS_SUCCESS;
|
|
|
|
ASSERT(deviceExtension != NULL);
|
|
ASSERT(smartcardExtension != NULL);
|
|
|
|
SmartcardDebug(DEBUG_DRIVER,("GEMSCR09!GDDKNT_09Cleanup: Enter\n"));
|
|
if (Irp != NULL)
|
|
{
|
|
Irp->IoStatus.Information = 0;
|
|
Irp->IoStatus.Status = STATUS_CANCELLED;
|
|
if (Irp->Cancel == TRUE)
|
|
{
|
|
IoReleaseCancelSpinLock(Irp->CancelIrql);
|
|
}
|
|
else
|
|
{
|
|
Irp->IoStatus.Information = 0;
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
}
|
|
smartcardExtension->OsData->NotificationIrp = NULL;
|
|
SmartcardDebug(DEBUG_DRIVER,("GEMSCR09!GDDKNT_09Cleanup: Wait cancelled\n"));
|
|
|
|
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
|
}
|
|
|
|
SmartcardDebug(DEBUG_DRIVER,("GEMSCR09!GDDKNT_09Cleanup: Exit\n"));
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* VOID GDDKNT_09Unload
|
|
* (
|
|
* IN PDRIVER_OBJECT DriverObject
|
|
* )
|
|
*
|
|
* Description :
|
|
* -------------
|
|
* The driver unload routine. This is called by the I/O system when the
|
|
* device is unloaded from memory.
|
|
*
|
|
* Remarks :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* In :
|
|
* -------------
|
|
* - DriverObject is a pointer to the driver object for this device.
|
|
* Out :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* Responses :
|
|
* -------------
|
|
* Nothing.
|
|
*******************************************************************************/
|
|
VOID GDDKNT_09Unload
|
|
(
|
|
IN PDRIVER_OBJECT DriverObject
|
|
)
|
|
{
|
|
PDEVICE_OBJECT
|
|
deviceObject = DriverObject->DeviceObject;
|
|
NTSTATUS
|
|
status;
|
|
WORD16
|
|
LengthOut = 0;
|
|
KEVENT
|
|
event;
|
|
LARGE_INTEGER
|
|
timeout;
|
|
|
|
ASSERT(deviceObject != NULL);
|
|
SmartcardDebug(DEBUG_DRIVER,("GEMSCR09!GDDKNT_09Unload: Enter\n"));
|
|
do
|
|
{
|
|
PDEVICE_EXTENSION deviceExtension = deviceObject->DeviceExtension;
|
|
PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
|
|
|
|
SmartcardDebug(
|
|
DEBUG_DRIVER,
|
|
("GEMSCR09!GDDKNT_09Unload: Unloading device %ws\n",
|
|
smartcardExtension->ReaderExtension->DosDeviceName.Buffer)
|
|
);
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Close the communication with the reader
|
|
------------------------------------------------------------------------------*/
|
|
GDDK_09CloseChannel(smartcardExtension);
|
|
/*------------------------------------------------------------------------------
|
|
We do not longet need the reference to the serial reader.
|
|
------------------------------------------------------------------------------*/
|
|
ObDereferenceObject(smartcardExtension->ReaderExtension->SerialFileObject);
|
|
/*------------------------------------------------------------------------------
|
|
Delete the symbolic link of the smart card reader
|
|
------------------------------------------------------------------------------*/
|
|
IoDeleteSymbolicLink(&smartcardExtension->ReaderExtension->DosDeviceName);
|
|
/*------------------------------------------------------------------------------
|
|
Let the lib free the send/receive buffers (SmartCardExit)
|
|
------------------------------------------------------------------------------*/
|
|
SmartcardExit(smartcardExtension);
|
|
/*------------------------------------------------------------------------------
|
|
Free all allocated buffer
|
|
------------------------------------------------------------------------------*/
|
|
ExFreePool(smartcardExtension->ReaderExtension->DosDeviceName.Buffer);
|
|
ExFreePool(smartcardExtension->ReaderExtension);
|
|
/*------------------------------------------------------------------------------
|
|
Delete the device from the system
|
|
------------------------------------------------------------------------------*/
|
|
IoDeleteDevice(deviceObject);
|
|
|
|
} while(deviceObject == DriverObject->DeviceObject);
|
|
|
|
SmartcardDebug(DEBUG_DRIVER,("GEMSCR09!GDDKNT_09Unload: Exit\n"));
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* NTSTATUS GDDKNT_09InitializeCardTracking
|
|
* (
|
|
* PSMARTCARD_EXTENSION SmartcardExtension
|
|
* )
|
|
*
|
|
* Description :
|
|
* -------------
|
|
* This routine initialized card tracking. It calls the serial driver to
|
|
* set a wait mask for RING tracking. After that it installs a completion
|
|
* routine to be called when RING changes state.
|
|
*
|
|
* Remarks :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* In :
|
|
* -------------
|
|
* - SmartcardExtension is a pointer on the SmartCardExtension structure of
|
|
* the current device.
|
|
* Out :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* Responses :
|
|
* -------------
|
|
* NTSTATUS
|
|
*******************************************************************************/
|
|
NTSTATUS GDDKNT_09InitializeCardTracking
|
|
(
|
|
PSMARTCARD_EXTENSION SmartcardExtension
|
|
)
|
|
{
|
|
NTSTATUS
|
|
status;
|
|
LARGE_INTEGER
|
|
timeout;
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Create which will check the status of the reader (card absent/present)
|
|
------------------------------------------------------------------------------*/
|
|
SmartcardExtension->ReaderExtension->CardStatus.Mode = RUN_REQUEST;
|
|
status = PsCreateSystemThread(
|
|
&(SmartcardExtension->ReaderExtension->CardStatus.ThreadHandle),
|
|
THREAD_ALL_ACCESS,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
GDDKNT_09UpdateCardStatus,
|
|
SmartcardExtension);
|
|
|
|
SmartcardDebug(
|
|
DEBUG_TRACE,
|
|
("GEMSCR09!GDDKNT_09InitializeCardTracking(%d)\n",status)
|
|
);
|
|
return status;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* VOID GDDKNT_09UpdateCardStatus
|
|
* (
|
|
* IN PKDPC EventDpc,
|
|
* IN PSMARTCARD_EXTENSION SmartcardExtension,
|
|
* IN PVOID SystemArgument1,
|
|
* IN PVOID SystemArgument2
|
|
* )
|
|
*
|
|
* Description :
|
|
* -------------
|
|
* This routine is called as the deferred procedure when RxD changes its status.
|
|
* Calls the serial driver again to start new RxD tracking.
|
|
*
|
|
* Remarks :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* In :
|
|
* -------------
|
|
* - SmartcardExtension is a pointer on the SmartCardExtension structure of
|
|
* the current device.
|
|
* Out :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* Responses :
|
|
* -------------
|
|
* Nothing.
|
|
*******************************************************************************/
|
|
VOID GDDKNT_09UpdateCardStatus
|
|
(
|
|
IN PSMARTCARD_EXTENSION SmartcardExtension
|
|
)
|
|
{
|
|
NTSTATUS
|
|
status;
|
|
KIRQL
|
|
oldIrql;
|
|
KEVENT
|
|
event;
|
|
LARGE_INTEGER
|
|
timeout;
|
|
ULONG
|
|
CurrentState;
|
|
PIRP
|
|
pIrp;
|
|
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Run the update card status while the function is not stopped.
|
|
------------------------------------------------------------------------------*/
|
|
SmartcardExtension->ReaderExtension->CardStatus.Mode = RUN_IN_PROCESS;
|
|
while (SmartcardExtension->ReaderExtension->CardStatus.Mode == RUN_IN_PROCESS)
|
|
{
|
|
KeInitializeEvent(&event,NotificationEvent,FALSE);
|
|
timeout.QuadPart = -((LONGLONG) POLLING_TIMEOUT*10*1000);
|
|
status = KeWaitForSingleObject(&event,
|
|
Suspended,
|
|
KernelMode,
|
|
FALSE,
|
|
&timeout);
|
|
GDDK_09LockExchange(SmartcardExtension);
|
|
/*------------------------------------------------------------------------------
|
|
Save the current state of reader (card present/removed)
|
|
and read the new state
|
|
------------------------------------------------------------------------------*/
|
|
CurrentState = SmartcardExtension->ReaderCapabilities.CurrentState;
|
|
GDDK_09UpdateCardStatus(SmartcardExtension);
|
|
/*------------------------------------------------------------------------------
|
|
Only inform the user of a card insertion/removal event
|
|
if this function isn't called due to a power down - power up cycle
|
|
------------------------------------------------------------------------------*/
|
|
if (
|
|
(((CurrentState != SCARD_ABSENT) && (SmartcardExtension->ReaderCapabilities.CurrentState == SCARD_ABSENT))
|
|
||
|
|
((CurrentState == SCARD_ABSENT) && (SmartcardExtension->ReaderCapabilities.CurrentState != SCARD_ABSENT))
|
|
)
|
|
&&
|
|
(SmartcardExtension->OsData->NotificationIrp)
|
|
)
|
|
{
|
|
/*------------------------------------------------------------------------------
|
|
If the user had setup an irp for event tracking complete that irp now
|
|
------------------------------------------------------------------------------*/
|
|
IoAcquireCancelSpinLock(&oldIrql);
|
|
|
|
IoSetCancelRoutine(SmartcardExtension->OsData->NotificationIrp,NULL);
|
|
|
|
IoReleaseCancelSpinLock(oldIrql);
|
|
|
|
SmartcardExtension->OsData->NotificationIrp->IoStatus.Information = 0;
|
|
SmartcardExtension->OsData->NotificationIrp->IoStatus.Status = STATUS_SUCCESS;
|
|
|
|
SmartcardDebug(
|
|
DEBUG_DRIVER,
|
|
("GEMSCR09!GDDKNT_09UpdateCardStatus: Completing IRP %lx",
|
|
SmartcardExtension->OsData->NotificationIrp)
|
|
);
|
|
|
|
pIrp = SmartcardExtension->OsData->NotificationIrp;
|
|
SmartcardExtension->OsData->NotificationIrp = NULL;
|
|
IoCompleteRequest(
|
|
pIrp,
|
|
IO_NO_INCREMENT
|
|
);
|
|
}
|
|
GDDK_09UnlockExchange(SmartcardExtension);
|
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Stop the update card status
|
|
------------------------------------------------------------------------------*/
|
|
SmartcardDebug(
|
|
DEBUG_TRACE,
|
|
("GEMSCR09!GDDKNT_09UpdateCardStatus: PsTerminateSystemThread\n")
|
|
);
|
|
SmartcardExtension->ReaderExtension->CardStatus.Mode = STOP_IN_PROCESS;
|
|
status = PsTerminateSystemThread(STATUS_SUCCESS);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* NTSTATUS GDDKNT_09DeviceControl
|
|
* (
|
|
* PDEVICE_OBJECT pDeviceObject,
|
|
* PIRP pIrp
|
|
* )
|
|
*
|
|
* Description :
|
|
* -------------
|
|
* This routine is called when a IOCTL_SMARTCARD_ is send to the driver.
|
|
*
|
|
* Remarks :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* In :
|
|
* -------------
|
|
* - pDeviceObject is a pointer to the device.
|
|
* - Irp holds the Irp involved.
|
|
*
|
|
* Out :
|
|
* -------------
|
|
* Nothing.
|
|
*
|
|
* Responses :
|
|
* -------------
|
|
* NTSTATUS
|
|
*******************************************************************************/
|
|
NTSTATUS GDDKNT_09DeviceControl
|
|
(
|
|
PDEVICE_OBJECT pDeviceObject,
|
|
PIRP pIrp
|
|
)
|
|
{
|
|
NTSTATUS
|
|
status = STATUS_SUCCESS;
|
|
ULONG
|
|
ioControlCode;
|
|
PDEVICE_EXTENSION
|
|
deviceExtension = pDeviceObject->DeviceExtension;
|
|
PSMARTCARD_EXTENSION
|
|
smartcardExtension = &deviceExtension->SmartcardExtension;
|
|
PIO_STACK_LOCATION
|
|
irpStack = IoGetCurrentIrpStackLocation(pIrp);
|
|
|
|
ASSERT(deviceExtension != NULL);
|
|
ASSERT(smartcardExtension != NULL);
|
|
ASSERT(irpStack != NULL);
|
|
/*------------------------------------------------------------------------------
|
|
Read the current IOCTL.
|
|
------------------------------------------------------------------------------*/
|
|
ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
|
|
SmartcardDebug(DEBUG_TRACE,("GEMSCR09!GDDKNT_09DeviceControl: IoControlCode=%lX\n",
|
|
ioControlCode));
|
|
/*------------------------------------------------------------------------------
|
|
If the IOCTL > 0x7FFFFFFF
|
|
Then
|
|
Is a Gemplus reader specific IOCTL
|
|
------------------------------------------------------------------------------*/
|
|
if (ioControlCode > 0x7FFFFFFF)
|
|
{
|
|
status =
|
|
GDDK_09SpecificIOCTL(
|
|
smartcardExtension,
|
|
ioControlCode,
|
|
irpStack->Parameters.DeviceIoControl.InputBufferLength,
|
|
pIrp->AssociatedIrp.SystemBuffer,
|
|
irpStack->Parameters.DeviceIoControl.OutputBufferLength,
|
|
pIrp->AssociatedIrp.SystemBuffer,
|
|
smartcardExtension->IoRequest.Information
|
|
);
|
|
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
|
|
pIrp->IoStatus.Status = status;
|
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Else
|
|
Is a standard Smart card IOCTL
|
|
If is a GET_ATTRIBUTE/SET_ATTRIBUTE with a specific Tag
|
|
Then
|
|
Is a Specific vendor Tag
|
|
------------------------------------------------------------------------------*/
|
|
else
|
|
{
|
|
if (
|
|
(
|
|
(ioControlCode == IOCTL_SMARTCARD_GET_ATTRIBUTE) ||
|
|
(ioControlCode == IOCTL_SMARTCARD_SET_ATTRIBUTE)
|
|
)
|
|
&&
|
|
( (ULONG) irpStack->Parameters.DeviceIoControl.InputBufferLength >=
|
|
(ULONG) sizeof(ULONG)
|
|
)
|
|
&&
|
|
( SCARD_CLASS(
|
|
(ULONG) *((PULONG)pIrp->AssociatedIrp.SystemBuffer)
|
|
) == SCARD_CLASS_VENDOR_DEFINED
|
|
)
|
|
)
|
|
{
|
|
status =
|
|
GDDK_09SpecificTag(
|
|
smartcardExtension,
|
|
ioControlCode,
|
|
irpStack->Parameters.DeviceIoControl.InputBufferLength,
|
|
pIrp->AssociatedIrp.SystemBuffer,
|
|
irpStack->Parameters.DeviceIoControl.OutputBufferLength,
|
|
pIrp->AssociatedIrp.SystemBuffer,
|
|
smartcardExtension->IoRequest.Information
|
|
);
|
|
IoCompleteRequest(pIrp,IO_NO_INCREMENT);
|
|
pIrp->IoStatus.Status = status;
|
|
}
|
|
/*------------------------------------------------------------------------------
|
|
Else
|
|
Call the SmartcardDeviceControl
|
|
------------------------------------------------------------------------------*/
|
|
else
|
|
{
|
|
status = SmartcardDeviceControl(smartcardExtension,pIrp);
|
|
}
|
|
}
|
|
SmartcardDebug(DEBUG_DRIVER,
|
|
("GEMSCR09!GDDKNT_09DeviceControl: ioControlCode=%lX status=%lX\n",
|
|
ioControlCode,status
|
|
)
|
|
);
|
|
return status;
|
|
}
|
|
|