From: abc on
Hi ,

I have a USB smart card reader device for which i am writing the
driver in KMDF , The driver gets installed properly as a smart card
reader driver.

But the problem is i am not getting any ioCTL calls from the resource
manager ...can any body tell me the reason behind it why is this
happening???


The code looks as below


#include "phNfc4Win_PcscDriver.h"

#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGEABLE, phNfc4Win_EvtDeviceAdd)
#pragma alloc_text(PAGEABLE, phNfc4Win_RegisterWithSmcLib)
#pragma alloc_text(PAGEABLE, phNfc4Win_EvtDevicePrepareHardware)
#pragma alloc_text(PAGEABLE, phNfc4Win_EvtDeviceD0Entry)
#pragma alloc_text(PAGEABLE, phNfc4Win_EvtDeviceD0Exit )

NTSTATUS
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath
)

{
NTSTATUS status = STATUS_SUCCESS;
WDF_DRIVER_CONFIG config;

SmartcardDebug(DEBUG_TRACE,
( "PSCR!DriverEntry: Enter - KMDF Version Built %s %s
\n",
__DATE__, __TIME__ ));

WDF_DRIVER_CONFIG_INIT(&config, phNfc4Win_EvtDeviceAdd);


status = WdfDriverCreate(DriverObject,
RegistryPath,
WDF_NO_OBJECT_ATTRIBUTES, // Driver Attributes
&config, // Driver Config Info
WDF_NO_HANDLE
);

if (!NT_SUCCESS(status)) {
KdPrint( ("WdfDriverCreate failed with status 0x%x\n",
status));
}

SmartcardDebug(DEBUG_TRACE,
("PSCR!DriverEntry: Exit %x\n",
status)
);

return status;
}

#if 0
NTSTATUS phNfc4Win_EvtDeviceAdd( IN WDFDRIVER Driver,
IN PWDFDEVICE_INIT DeviceInit)
{

NTSTATUS status;
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
WDF_OBJECT_ATTRIBUTES attributes;
WDFDEVICE device;
PDEVICE_CONTEXT pDevContext;
WDF_IO_QUEUE_CONFIG ioQueueConfig;
WDF_FILEOBJECT_CONFIG fileobjectConfig;

UNREFERENCED_PARAMETER(Driver);

PAGED_CODE();

SmartcardDebug(
DEBUG_TRACE,
( "PSCR!PscrAddDevice: Enter\n" )
);

WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_SMARTCARD);

WdfDeviceInitSetExclusive(DeviceInit, TRUE);

//WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);

WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);

pnpPowerCallbacks.EvtDevicePrepareHardware =
phNfc4Win_EvtDevicePrepareHardware;

WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit,
&pnpPowerCallbacks);

/*pnpPowerCallbacks.EvtDeviceD0Entry = phNfc4Win_EvtDeviceD0Entry;
pnpPowerCallbacks.EvtDeviceD0Exit = phNfc4Win_EvtDeviceD0Exit;

WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit,
&pnpPowerCallbacks);*/

/*WDF_FILEOBJECT_CONFIG_INIT(
&fileobjectConfig,
WDF_NO_EVENT_CALLBACK, // Create
WDF_NO_EVENT_CALLBACK, // Close
phNfc4Win_EvtFileCleanup // Cleanup
);

WdfDeviceInitSetFileObjectConfig(
DeviceInit,
&fileobjectConfig,
WDF_NO_OBJECT_ATTRIBUTES
);*/


WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
//attributes.EvtCleanupCallback =
phNfc4Win_EvtDeviceContextCleanup;


status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
if (!NT_SUCCESS(status)) {
SmartcardLogError(
WdfDriverWdmGetDriverObject(WdfGetDriver()),
STATUS_INSUFFICIENT_RESOURCES,
NULL,
0
);
return status;
}
pDevContext = GetDeviceContext(device);

pDevContext->Device = device;

InterlockedIncrement((PLONG)&pDevContext->DeviceInstanceNo);

// Add an extra stack location to the IRP dispatched to our device so
// that we can use that to workaround the problem of scmlib
completing
// ioctl IRPs.

WdfDeviceWdmGetDeviceObject(pDevContext->Device)->StackSize++;


status =
WdfDeviceCreateDeviceInterface(device,&SmartCardReaderGuid,NULL);

if (!NT_SUCCESS (status))
{
SmartcardLogError(WdfDriverWdmGetDriverObject(WdfGetDriver()),
STATUS_INSUFFICIENT_RESOURCES,
NULL,
0);
return status;
}

//
// Create a parallel queue for dispatching ioctl requests.
//


WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueueDispatchParallel);

ioQueueConfig.EvtIoDeviceControl = phNfc4Win_EvtIoDeviceControl;


status = WdfIoQueueCreate (device,
&ioQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&pDevContext->IoctlQueue
);

if(!NT_SUCCESS (status))
{
return status;
}

status = phNfc4Win_RegisterWithSmcLib(pDevContext);

if (!NT_SUCCESS (status))
{
return status;
}

KdPrint(("phNfc4Win_RegisterWithSmcLib exited\n"));
return status;


}

NTSTATUS phNfc4Win_RegisterWithSmcLib (PDEVICE_CONTEXT pDevContext)
{
PREADER_EXTENSION ReaderExtension;
PSMARTCARD_EXTENSION SmartCardExtension;
UNICODE_STRING vendorNameU, ifdTypeU;
ANSI_STRING vendorNameA, ifdTypeA;
WDFSTRING vendorNameStr, ifdTypeStr;
NTSTATUS status;

PAGED_CODE();

vendorNameStr = NULL;
ifdTypeStr = NULL;
RtlZeroMemory(&vendorNameA, sizeof(vendorNameA));
RtlZeroMemory(&ifdTypeA, sizeof(ifdTypeA));

SmartCardExtension = &pDevContext->SmartCardExtension;

// allocate the reader extension
ReaderExtension = ExAllocatePoolWithTag(
NonPagedPool,
sizeof( READER_EXTENSION ),
SMARTCARD_POOL_TAG
);

if ( ReaderExtension == NULL ) {
SmartcardLogError(
WdfDriverWdmGetDriverObject(WdfGetDriver()),
STATUS_INSUFFICIENT_RESOURCES,
NULL,
0
);
status = STATUS_INSUFFICIENT_RESOURCES;
return status;
}

RtlZeroMemory( ReaderExtension, sizeof( READER_EXTENSION ));

SmartCardExtension->ReaderExtension = ReaderExtension;
SmartCardExtension->ReaderFunction[RDF_CARD_TRACKING] =
phNfc4Win_ScardTracking;
SmartCardExtension->ReaderFunction[RDF_TRANSMIT] =
phNfc4Win_ScardTransmit;
SmartCardExtension->ReaderFunction[RDF_SET_PROTOCOL] =
phNfc4Win_ScardSetProtocol;
SmartCardExtension->ReaderFunction[RDF_CARD_POWER] =
phNfc4Win_ScardPower;


KdPrint(("register callbacks completed \n"));

KdPrint(("vendor attribute started \n"));
strcpy(((char*)SmartCardExtension->VendorAttr.VendorName.Buffer),
"NXP");
SmartCardExtension->VendorAttr.VendorName.Length =
(USHORT) strlen((char*)pDevContext-
>SmartCardExtension.VendorAttr.VendorName.Buffer);
strcpy((char *)SmartCardExtension->VendorAttr.IfdType.Buffer, "NFC
CARD READER");
SmartCardExtension->VendorAttr.IfdType.Length =
(USHORT) strlen((char *)SmartCardExtension-
>VendorAttr.IfdType.Buffer);
SmartCardExtension->VendorAttr.UnitNo = MAXULONG;
SmartCardExtension->VendorAttr.UnitNo = 0;
KdPrint(("vendor attribute completed \n"));

SmartCardExtension->VendorAttr.UnitNo = pDevContext-
>DeviceInstanceNo;

SmartCardExtension->VendorAttr.IfdVersion.BuildNumber = 0;

// store firmware revision in ifd version
SmartCardExtension->VendorAttr.IfdVersion.VersionMajor = 1;
//ReaderExtension->FirmwareMajor;
SmartCardExtension->VendorAttr.IfdVersion.VersionMinor = 1;
//ReaderExtension->FirmwareMinor;
SmartCardExtension->VendorAttr.IfdSerialNo.Length = 0;

KdPrint(("Reader capabilites started \n"));
SmartCardExtension->ReaderCapabilities.SupportedProtocols =
SCARD_PROTOCOL_RAW;
SmartCardExtension->ReaderCapabilities.ReaderType =
SCARD_READER_TYPE_USB;
SmartCardExtension->ReaderCapabilities.MechProperties = 0x8;
SmartCardExtension->ReaderCapabilities.CurrentState =
SCARD_UNKNOWN;
SmartCardExtension->ReaderCapabilities.Channel = 0x200000;
SmartCardExtension->ReaderCapabilities.CLKFrequency.Default = 13560;
SmartCardExtension->ReaderCapabilities.CLKFrequency.Max = 13560;
SmartCardExtension->ReaderCapabilities.DataRate.Default = 10600;//
dataRatesSupported[0];
SmartCardExtension->ReaderCapabilities.DataRate.Max = 10600;//
dataRatesSupported[2];
SmartCardExtension->ReaderCapabilities.MaxIFSD =
254;
SmartCardExtension->ReaderCapabilities.PowerMgmtSupport = 0;
SmartCardExtension->ReaderCapabilities.CardConfiscated = FALSE;

/*SmartCardExtension->ReaderCapabilities.DataRatesSupported.List =
dataRatesSupported;
SmartCardExtension->ReaderCapabilities.DataRatesSupported.Entries =
sizeof(dataRatesSupported) / sizeof(dataRatesSupported);
SmartCardExtension-
>ReaderCapabilities.CLKFrequenciesSupported.List = Clkfrequencies;
SmartCardExtension-
>ReaderCapabilities.CLKFrequenciesSupported.Entries =
sizeof(Clkfrequencies) / sizeof(Clkfrequencies)*/
KdPrint(("Reader capabilites end \n"));



// enter correct version of the lib
SmartCardExtension->Version = SMCLIB_VERSION;
SmartCardExtension->SmartcardRequest.BufferSize =
MIN_BUFFER_SIZE;
SmartCardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;

SmartCardExtension->ReaderExtension->ReaderPowerState =
PowerReaderWorking;

status = SmartcardInitialize(SmartCardExtension);

if (status != STATUS_SUCCESS) {

SmartcardLogError(
WdfDriverWdmGetDriverObject(WdfGetDriver()),
STATUS_INSUFFICIENT_RESOURCES,
NULL,
0
);
return status;
}

SmartCardExtension->OsData->DeviceObject =
WdfDeviceWdmGetDeviceObject(pDevContext->Device);
KdPrint(("Assigned device object \n"));
return status;
}
#endif

NTSTATUS phNfc4Win_EvtDeviceAdd( IN WDFDRIVER Driver,
IN PWDFDEVICE_INIT DeviceInit)
{
NTSTATUS status;
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
WDF_OBJECT_ATTRIBUTES attributes;
WDFDEVICE device;
PDEVICE_CONTEXT pDevContext;
WDF_IO_QUEUE_CONFIG ioQueueConfig;
UNICODE_STRING DeviceName;
UNICODE_STRING LinkName;
PSMARTCARD_EXTENSION smartcardExtension;
PREADER_EXTENSION pReaderExtension = NULL;
ULONG dataRatesSupported = 10600;
ULONG Clkfrequencies = 10600;



KdPrint(("RtlInitUnicodeString called\n"));
RtlInitUnicodeString(&DeviceName, L"\\??\\NFC CARD READER0");
pReaderExtension= ExAllocatePoolWithTag(
NonPagedPool,
sizeof( READER_EXTENSION ),
SMARTCARD_POOL_TAG
);

if ( pReaderExtension == NULL ) {
KdPrint(("pReaderExtension allocation sucessful\n"));
status = STATUS_INSUFFICIENT_RESOURCES;
return status;
}

WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_SMARTCARD);
//WdfDeviceInitSetExclusive(DeviceInit, TRUE);

WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoBuffered);
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
pnpPowerCallbacks.EvtDevicePrepareHardware =
phNfc4Win_EvtDevicePrepareHardware;

WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit,
&pnpPowerCallbacks);

WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);


status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
if (!NT_SUCCESS(status)) {

return status;
}
pDevContext = GetDeviceContext(device);

pDevContext->Device = device;

smartcardExtension = &pDevContext->SmartCardExtension;

smartcardExtension->Version = SMCLIB_VERSION;
smartcardExtension->SmartcardRequest.BufferSize =
MIN_BUFFER_SIZE;
smartcardExtension->SmartcardReply.BufferSize = MIN_BUFFER_SIZE;
KdPrint(("SmartcardInitialize\n"));
status = SmartcardInitialize(smartcardExtension);
KdPrint((" SmartcardExtension->SmartcardRequest.BufferSize = 0x%x
\n",smartcardExtension->SmartcardRequest.BufferSize));
KdPrint((" smartcardExtension->SmartcardReply.BufferSize = 0x%x
\n",smartcardExtension->SmartcardReply.BufferSize));
KdPrint((" status = SmartcardInitialize(smartcardExtension); \n"));
if(status == STATUS_INSUFFICIENT_RESOURCES)
{
KdPrint(("STATUS_INSUFFICIENT_RESOURCES \n"));
status = STATUS_UNSUCCESSFUL;
}
else if (status != STATUS_SUCCESS)
{
KdPrint(("SmartcardInitialize failed \n"));
status = STATUS_UNSUCCESSFUL;
return status;
}
KdPrint(("register callbacks \n"));

smartcardExtension->ReaderFunction[RDF_TRANSMIT] =
phNfc4Win_ScardTransmit;
smartcardExtension->ReaderFunction[RDF_SET_PROTOCOL] =
phNfc4Win_ScardSetProtocol;
smartcardExtension->ReaderFunction[RDF_CARD_POWER] =
phNfc4Win_ScardPower;
smartcardExtension->ReaderFunction[RDF_CARD_TRACKING] =
phNfc4Win_ScardTracking;


KdPrint(("register callbacks completed \n"));

KdPrint(("vendor attribute started \n"));
KdPrint(("strcpy smartcardExtension->VendorAttr.VendorName.Buffer);
\n"));
strcpy(((char*)smartcardExtension->VendorAttr.VendorName.Buffer),
"NXP");
KdPrint(("smartcardExtension->VendorAttr.VendorName.Length\n"));

smartcardExtension->VendorAttr.VendorName.Length =
(USHORT) strlen((char*)pDevContext-
>SmartCardExtension.VendorAttr.VendorName.Buffer);

KdPrint(("smartcardExtension->VendorAttr.IfdType.Buffer, ;\n"));
strcpy((char *)smartcardExtension->VendorAttr.IfdType.Buffer, "NFC
CARD READER");

KdPrint(("smartcardExtension->VendorAttr.IfdType.Length\n"));
smartcardExtension->VendorAttr.IfdType.Length =
(USHORT) strlen((char *)smartcardExtension-
>VendorAttr.IfdType.Buffer);

KdPrint(("vendor attribute completed \n"));

smartcardExtension->VendorAttr.UnitNo = MAXULONG;

smartcardExtension->VendorAttr.UnitNo = 0;
KdPrint(("smartcardExtension->VendorAttr.UnitNo 0x%x",
smartcardExtension->VendorAttr.UnitNo));
//
// Set the reader capabilities
//
KdPrint(("Reader capabilites started \n"));
smartcardExtension->ReaderCapabilities.SupportedProtocols =
SCARD_PROTOCOL_RAW | SCARD_PROTOCOL_T0 |SCARD_PROTOCOL_T1;
smartcardExtension->ReaderCapabilities.ReaderType =
SCARD_READER_TYPE_USB;
smartcardExtension->ReaderCapabilities.MechProperties = 0x8;
smartcardExtension->ReaderCapabilities.CurrentState =
SCARD_ABSENT;
smartcardExtension->ReaderCapabilities.Channel = 0x200000;
smartcardExtension->ReaderCapabilities.CLKFrequency.Default = 13560;
smartcardExtension->ReaderCapabilities.CLKFrequency.Max = 13560;
smartcardExtension->ReaderCapabilities.DataRate.Default = 10600;//
dataRatesSupported[0];
smartcardExtension->ReaderCapabilities.DataRate.Max = 10600;//
dataRatesSupported[2];
smartcardExtension->ReaderCapabilities.MaxIFSD =
254;
smartcardExtension->ReaderCapabilities.PowerMgmtSupport = 0;
smartcardExtension->ReaderCapabilities.CardConfiscated = FALSE;

KdPrint(("Reader capabilites end \n"));

smartcardExtension->ReaderExtension = pReaderExtension;

pDevContext->Device = device;

//WdfDeviceWdmGetDeviceObject(pDevContext->Device)->StackSize++;

status =
WdfDeviceCreateDeviceInterface(device,&SmartCardReaderGuid,NULL);

smartcardExtension->OsData->DeviceObject =
WdfDeviceWdmGetDeviceObject(pDevContext->Device);

status = SmartcardCreateLink(&LinkName, &DeviceName);
if(!NT_SUCCESS(status))
{
return status;
}
//
// Create a parallel queue for dispatching ioctl requests.
//


WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueueDispatchParallel);

ioQueueConfig.EvtIoDeviceControl = phNfc4Win_EvtIoDeviceControl;


status = WdfIoQueueCreate (device,
&ioQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&pDevContext->IoctlQueue
);

if (!NT_SUCCESS(status)) {
KdPrint(("WdfIoQueueCreate failed %!STATUS!\n", status));
return status;
}

return status;
}

NTSTATUS
phNfc4Win_EvtDevicePrepareHardware (
WDFDEVICE Device,
WDFCMRESLIST Resources,
WDFCMRESLIST ResourcesTranslated
)

{
PDEVICE_CONTEXT pDevContext = GetDeviceContext(Device);
PSMARTCARD_EXTENSION SmartcardExtension = &pDevContext-
>SmartCardExtension;
PREADER_EXTENSION ReaderExtension = SmartcardExtension-
>ReaderExtension;
NTSTATUS status = STATUS_SUCCESS;

BYTE count = 0, i = 0,numberConfiguredPipes =0 ;
WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
WDF_USB_PIPE_INFORMATION pipeinfo;
WDFUSBPIPE TempHandle;
KdPrint(("EvtDevicePrepareHardware called \n"));

//pDevContext = GetDeviceContext(Device);
KdPrint(("WdfUsbTargetDeviceCreate called \n"));
status = WdfUsbTargetDeviceCreate(Device,
WDF_NO_OBJECT_ATTRIBUTES,
&pDevContext->UsbDevice);
if (!NT_SUCCESS(status)) {
KdPrint(("WdfUsbTargetDeviceCreate failed 0x%x\n",
status));
return status;
}


WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);
KdPrint(("WdfUsbTargetDeviceSelectConfig called \n"));

status = WdfUsbTargetDeviceSelectConfig(pDevContext->UsbDevice,
WDF_NO_OBJECT_ATTRIBUTES,
&configParams);
if(!NT_SUCCESS(status)) {
KdPrint(("WdfUsbTargetDeviceSelectConfig failed 0x%x\n",
status));
return status;
}

pDevContext->UsbInterface =

configParams.Types.SingleInterface.ConfiguredUsbInterface;

numberConfiguredPipes =
configParams.Types.SingleInterface.NumberConfiguredPipes;

KdPrint(("WdfUsbInterfaceGetConfiguredPipe1 called \n"));
KdPrint(("numberConfiguredPipes =0x%x \n",numberConfiguredPipes));

for( i=0; i< numberConfiguredPipes ; i++)
{
KdPrint(("for loop entered\n "));

WDF_USB_PIPE_INFORMATION_INIT(&pipeinfo);
TempHandle = WdfUsbInterfaceGetConfiguredPipe(
pDevContext->UsbInterface,
i, //PipeIndex,
&pipeinfo
);
WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(TempHandle);

if(WdfUsbPipeTypeBulk == pipeinfo.PipeType &&
WdfUsbTargetPipeIsInEndpoint(TempHandle)) {
KdPrint(("The address is BulkReadPipe \n"));
pDevContext->BulkReadPipe = TempHandle;
}

if(WdfUsbPipeTypeBulk == pipeinfo.PipeType &&
WdfUsbTargetPipeIsOutEndpoint(TempHandle)) {
KdPrint(("The address is BulkWritePipe \n"));
pDevContext->BulkWritePipe = TempHandle;
}
KdPrint(("The loop is entered\n"));
}
ASSERT(status == STATUS_SUCCESS);
return status;

}

NTSTATUS
phNfc4Win_EvtDeviceD0Entry(
IN WDFDEVICE Device,
IN WDF_POWER_DEVICE_STATE PreviousState
)
{
return STATUS_SUCCESS;
}

NTSTATUS
phNfc4Win_EvtDeviceD0Exit(
IN WDFDEVICE Device,
IN WDF_POWER_DEVICE_STATE TargetState
)
{
return STATUS_SUCCESS;
}

NTSTATUS
phNfc4Win_EvtFileCleanup(IN WDFFILEOBJECT FileObject)
{
return STATUS_SUCCESS;
}


VOID phNfc4Win_EvtIoDeviceControl( IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
)
{
PDEVICE_CONTEXT pDevContext;
PIRP irp;
NTSTATUS status ;

UNREFERENCED_PARAMETER(OutputBufferLength);
UNREFERENCED_PARAMETER(InputBufferLength);
UNREFERENCED_PARAMETER(IoControlCode);


KdPrint((" phNfc4Win_EvtIoDeviceControl is called\n"));

pDevContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));

//
// Since smart card library expects an IRP, we will get the
underlying
// irp.
//
irp = WdfRequestWdmGetIrp(Request);

//
// We will store the Request handle in the IRP DriverContext field
so
// that we can get the handle back in vendor-ioctl callback
routine.
//
SET_REQUEST_IN_IRP(irp, Request);

//
// To workaround the problem of smart card completing the IRP we
provided.
// we will use the extra stack location to set a completion
routine so that
// when it completes the IRP, our completion routine will be
called, where
// we can interrupt the completion and complete the actual
WDFREQUEST.
//
KdPrint((" SET_REQUEST_IN_IRP is called\n"));
IoCopyCurrentIrpStackLocationToNext(irp);
KdPrint((" IoSetCompletionRoutine is called\n"));
IoSetCompletionRoutine (irp,
phNfc4Win_SmcLibComplete,
Request,
TRUE,
TRUE,
TRUE
);
KdPrint((" IoSetNextIrpStackLocation is called\n"));

IoSetNextIrpStackLocation(irp);

//
// Ignore the return value because framework has marked the irp
pending
// and will return status-pending when we return from this
routine.
//

KdPrint((" phNfc4Win_SmartCardIoControl is getting called\n"));
status = phNfc4Win_SmartCardIoControl( Queue,
Request,
OutputBufferLength,
InputBufferLength,
IoControlCode);
//(VOID) SmartcardDeviceControl(&(pDevContext-
>SmartCardExtension), irp);

return;

}

VOID
phNfc4Win_EvtDeviceContextCleanup (
WDFDEVICE Device
)
{
PDEVICE_CONTEXT pDevContext;

pDevContext = GetDeviceContext(Device);

InterlockedDecrement((PLONG)&pDevContext->DeviceInstanceNo);

if (pDevContext->SmartCardExtension.ReaderExtension != NULL)
{

ExFreePoolWithTag(pDevContext-
>SmartCardExtension.ReaderExtension,
SMARTCARD_POOL_TAG);

pDevContext->SmartCardExtension.ReaderExtension = NULL;
}
}

NTSTATUS phNfc4Win_ScardTransmit (PSMARTCARD_EXTENSION
SmartcardExtension)
{
//phNfc4Win_eStatusCodes_t instatus;
NTSTATUS status = STATUS_SUCCESS;
//NRB Nrb;
PDEVICE_CONTEXT pDevContext;


pDevContext =
GetDeviceContext(WdfWdmDeviceGetWdfDeviceHandle(SmartcardExtension-
>OsData->DeviceObject));
if ((status = SmartcardAcquireRemoveLock(SmartcardExtension)) !=
STATUS_SUCCESS)
{
SmartcardExtension->IoRequest.Information = 0;
}
else
{
SmartcardReleaseRemoveLock(SmartcardExtension);
}
return status;

}
NTSTATUS phNfc4Win_ScardSetProtocol (PSMARTCARD_EXTENSION
SmartcardExtension)
{
return STATUS_SUCCESS;
}
NTSTATUS phNfc4Win_ScardTracking (PSMARTCARD_EXTENSION
SmartcardExtension)
{
KIRQL CancelIrql;
PDEVICE_CONTEXT pDevContext;
NTSTATUS status = STATUS_SUCCESS;

pDevContext =
GetDeviceContext(WdfWdmDeviceGetWdfDeviceHandle(SmartcardExtension-
>OsData->DeviceObject));

KdPrint(("%s phNfc4Win_ScardTracking is called\n"));
KdPrint(("%s -------------------------------------------\n"));
KdPrint(("%s phNfc4Win_ScardTracking is called \n"));

if(NT_SUCCESS(status))
{
IoAcquireCancelSpinLock(&CancelIrql);
IoSetCancelRoutine(SmartcardExtension->OsData->NotificationIrp,
phNfc4Win_TamaCancel);
IoReleaseCancelSpinLock(CancelIrql);
}
return STATUS_PENDING;

}
NTSTATUS phNfc4Win_ScardPower (PSMARTCARD_EXTENSION
SmartcardExtension)
{
return STATUS_SUCCESS;
}

VOID
phNfc4Win_EvtIoCanceledOnQueue(
IN WDFQUEUE Queue,
IN WDFREQUEST Request
)
{
PDEVICE_CONTEXT pDevContext;
PSMARTCARD_EXTENSION smartcardExtension;

pDevContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
smartcardExtension = (PSMARTCARD_EXTENSION) &pDevContext-
>SmartCardExtension;


InterlockedExchangePointer(
&(smartcardExtension->OsData-
>NotificationIrp),
NULL
);

WdfRequestComplete(Request, STATUS_CANCELLED);
}


NTSTATUS phNfc4Win_TamaCancel(IN PDEVICE_OBJECT DeviceObject, IN PIRP
Irp)
{

PDEVICE_CONTEXT pDevContext;
PSMARTCARD_EXTENSION smartcardExtension;
pDevContext = GetDeviceContext(DeviceObject);
smartcardExtension = &pDevContext->SmartCardExtension;

ASSERT(Irp == smartcardExtension->OsData->NotificationIrp);

smartcardExtension->OsData->NotificationIrp = NULL;

Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_CANCELLED;

IoReleaseCancelSpinLock(Irp->CancelIrql);

IoCompleteRequest(Irp,IO_NO_INCREMENT);

return STATUS_CANCELLED;
}


NTSTATUS
phNfc4Win_SmcLibComplete (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
/*++

Routine Description:

Completion routine is called when the IRP is completed by the
smclib.
We will interrupt the completion of the IRP, and inturn complete
the
WDFREQUEST given to us by the framework.

--*/
{
UNREFERENCED_PARAMETER(DeviceObject);

//KdPrint(("<-- PscrSmcLibComplete called %x Request %x\n",
// Irp->IoStatus.Status, Context));

WdfRequestComplete((WDFREQUEST)Context, Irp->IoStatus.Status);

return STATUS_MORE_PROCESSING_REQUIRED;
}


NTSTATUS phNfc4Win_SmartCardIoControl(IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t OutputBufferLength,
IN size_t InputBufferLength,
IN ULONG IoControlCode
)
{
NTSTATUS status;
WDFDEVICE device;
PDEVICE_CONTEXT pDevContext;
PIRP Irp;

device = WdfIoQueueGetDevice(Queue);
pDevContext = GetDeviceContext(device);


status = SmartcardAcquireRemoveLock(&pDevContext-
>SmartCardExtension);
KdPrint((" phNfc4Win_SmartCardIoControl is called\n"));
if(status != STATUS_SUCCESS)
{
KdPrint((" phNfc4Win_SmartCardIoControl status != STATUS_SUCCESS
\n"));
WdfRequestCompleteWithInformation(Request, status, 0);
}
else
{
KdPrint((" Else entered\n"));
Irp = WdfRequestWdmGetIrp(Request);
KdPrint((" The value of IRP = 0x%x",Irp));
KdPrint((" The value of SMART CARD EXTENSION = 0x%x",&pDevContext-
>SmartCardExtension));

switch (IoControlCode)
{
case IOCTL_SMARTCARD_POWER:
KdPrint((" SmartcardDeviceControl is called\n"));
status = SmartcardDeviceControl(&pDevContext->SmartCardExtension,
Irp);
KdPrint(("IOCTL_SMARTCARD_POWER\n"));
break;
case IOCTL_SMARTCARD_GET_ATTRIBUTE:
KdPrint(("IOCTL_SMARTCARD_GET_ATTRIBUTE\n"));
KdPrint((" SmartcardDeviceControl is called\n"));
status = SmartcardDeviceControl(&pDevContext->SmartCardExtension,
Irp);
break;
case IOCTL_SMARTCARD_SET_ATTRIBUTE:
KdPrint(("IOCTL_SMARTCARD_SET_ATTRIBUTE\n"));
KdPrint((" SmartcardDeviceControl is called\n"));
status = SmartcardDeviceControl(&pDevContext->SmartCardExtension,
Irp);
break;
case IOCTL_SMARTCARD_CONFISCATE:
KdPrint((" SmartcardDeviceControl is called\n"));
status = SmartcardDeviceControl(&pDevContext->SmartCardExtension,
Irp);
KdPrint(("IOCTL_SMARTCARD_CONFISCATE\n"));
break;
case IOCTL_SMARTCARD_TRANSMIT:
KdPrint((" SmartcardDeviceControl is called\n"));
status = SmartcardDeviceControl(&pDevContext->SmartCardExtension,
Irp);
KdPrint(("IOCTL_SMARTCARD_TRANSMIT\n"));
break;
case IOCTL_SMARTCARD_EJECT:
KdPrint((" SmartcardDeviceControl is called\n"));
status = SmartcardDeviceControl(&pDevContext->SmartCardExtension,
Irp);
KdPrint(("IOCTL_SMARTCARD_EJECT\n"));
break;
case IOCTL_SMARTCARD_SWALLOW:
KdPrint(("IOCTL_SMARTCARD_SWALLOW\n"));
break;
case IOCTL_SMARTCARD_IS_PRESENT:
KdPrint((" SmartcardDeviceControl is called\n"));
status = SmartcardDeviceControl(&pDevContext->SmartCardExtension,
Irp);
KdPrint(("IOCTL_SMARTCARD_IS_PRESENT\n"));
break;
case IOCTL_SMARTCARD_IS_ABSENT:
KdPrint((" SmartcardDeviceControl is called\n"));
status = SmartcardDeviceControl(&pDevContext->SmartCardExtension,
Irp);
KdPrint(("IOCTL_SMARTCARD_IS_ABSENT\n"));
break;
case IOCTL_SMARTCARD_SET_PROTOCOL:
KdPrint((" SmartcardDeviceControl is called\n"));
status = SmartcardDeviceControl(&pDevContext->SmartCardExtension,
Irp);
KdPrint(("IOCTL_SMARTCARD_SET_PROTOCOL\n"));
break;
case IOCTL_SMARTCARD_GET_STATE:
KdPrint((" SmartcardDeviceControl is called\n"));
status = SmartcardDeviceControl(&pDevContext->SmartCardExtension,
Irp);
KdPrint(("IOCTL_SMARTCARD_GET_STATE\n"));
break;
case IOCTL_SMARTCARD_GET_LAST_ERROR:
KdPrint((" SmartcardDeviceControl is called\n"));
status = SmartcardDeviceControl(&pDevContext->SmartCardExtension,
Irp);
KdPrint(("IOCTL_SMARTCARD_GET_LAST_ERROR\n"));
break;
default:
KdPrint(("UNKNOWN IOCTL\n"));
}
KdPrint((" Else exit\n"));
KdPrint((" SmartcardReleaseRemoveLock is calledwill be made next
\n"));
SmartcardReleaseRemoveLock(&pDevContext->SmartCardExtension);
}
return status;
}

thanks
Jagadish

From: Eliyas Yakub [MSFT] on
You are not getting ioctls because the queue is not created properly. You
should either create a default queue or configure the queue to automatically
receive requests as shown below.

To create a default queue:

WDF_IO_QUEUE_CONFIG_INIT_DEFAULT(&ioQueueConfig,WdfIoQueueDispatchParallel);
<-- Not the word default in the macro.
ioQueueConfig.EvtIoDeviceControl = phNfc4Win_EvtIoDeviceControl;

status = WdfIoQueueCreate (device,
&ioQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&pDevContext->IoctlQueue
);

Or you can do the following. Both the approaches produce same results.

WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueueDispatchParallel);
ioQueueConfig.EvtIoDeviceControl = phNfc4Win_EvtIoDeviceControl;

status = WdfIoQueueCreate (device,
&ioQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&pDevContext->IoctlQueue
);

status = WdfDeviceConfigureRequestDispatching(
Device,
pDevContext->IoctlQueue,
WdfRequestTypeDeviceControl
);
-Eliyas