Hello all,
I’m a beginner in KMDF device development.
I try to understand the best way for send request to usbTarget from a file object context.
I create 2 device interfaces for each smartcard reader slot (reference String = SLOT_0, SLOT_1).
// DeviceContext Structure
deviceContext
{
USB_DEVICE_DESCRIPTOR UsbDeviceDescriptor;
PUSB_CONFIGURATION_DESCRIPTOR UsbConfigurationDescriptor;
WDFUSBDEVICE WdfUsbTargetDevice;
WDFUSBINTERFACE UsbInterface;
WDFQUEUE IoctlQueue;
}
// FileSlotContext Structure
fileContext // Used for each device interface
{
SMARTCARD_EXTENSION smartcardExtension;
ULONG slotNumber;
UNICODE_STRING slotName; // stored for define the device interface opened
WDFDEVICE Device;
BOOLEAN alreadyOpen;
}
NTSTATUS EvtDeviceAdd( IN WDFDRIVER Driver,
IN PWDFDEVICE_INIT DeviceInit)
{
RtlInitUnicodeString(&DeviceName0, L"SLOT_0");
RtlInitUnicodeString(&DeviceName1, L"SLOT_1");
WDF_FILEOBJECT_CONFIG_INIT(
&fileobjectConfig,
DeviceFileCreate, // Create
DeviceEvtFileClose, // Close
EvtFileCleanup // Cleanup
);
WDF_OBJECT_ATTRIBUTES_INIT(&fileObjectAttributes);
fileObjectAttributes.SynchronizationScope = WdfSynchronizationScopeDevice;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fileObjectAttributes, FILE_SLOT_CONTEXT);
WdfDeviceInitSetFileObjectConfig(
DeviceInit,
&fileobjectConfig,
&fileObjectAttributes //WDF_NO_OBJECT_ATTRIBUTES
);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
if (!NT_SUCCESS(status)) {
KdPrint((" EvtDeviceAdd - WdfDeviceCreate FAILED ( status = 0x%X)\n", status));
return status;
}
// KL 07-02-2011
if (status == STATUS_SUCCESS) {
WdfControlFinishInitializing(
device
);
//deviceObject = WdfDeviceWdmGetDeviceObject(device);
}
pDevContext = GetDeviceContext(device);
pDevContext->wdfDevice = device;
pDevContext->FDO = WdfDeviceWdmGetDeviceObject(device);
pDevContext->PDO = WdfDeviceWdmGetPhysicalDevice(device);
status = WdfDeviceCreateDeviceInterface(
device,
&SmartCardReaderGuid,
&DeviceName0
);
if (!NT_SUCCESS(status)) {
KdPrint((“1) WdfDeviceCreateDeviceInterface failed 0x%X\n”, status));
return status;
}
status = WdfDeviceCreateDeviceInterface(
device,
&SmartCardReaderGuid,
&DeviceName1
);
if (!NT_SUCCESS(status)) {
KdPrint((“2) WdfDeviceCreateDeviceInterface failed 0x%X\n”, status));
return status;
}
//
// Create a parallel queue for dispatching ioctl requests.
//
WDF_IO_QUEUE_CONFIG_INIT(&ioQueueConfig,WdfIoQueueDispatchSequential); // KL 17-02-2011 WdfIoQueueDispatchParallel);
ioQueueConfig.EvtIoDeviceControl = EvtIoDeviceControl;
status = WdfIoQueueCreate (device,
&ioQueueConfig,
WDF_NO_OBJECT_ATTRIBUTES,
&pDevContext->IoctlQueue
);
if (!NT_SUCCESS(status)) {
KdPrint((“WdfIoQueueCreate failed 0x%X\n”, status));
return status;
}
status = WdfDeviceConfigureRequestDispatching(
device,
pDevContext->IoctlQueue,
WdfRequestTypeDeviceControl
);
if (!NT_SUCCESS(status)) {
KdPrint((“WdfDeviceConfigureRequestDispatching failed 0x%X\n”, status));
return status;
}
KdPrint((“<<<=== EvtDeviceAdd \n\n”));
return status;
}
VOID
DeviceFileCreate (
IN WDFDEVICE Device,
IN WDFREQUEST Request,
IN WDFFILEOBJECT FileObject
)
{
…
RtlInitUnicodeString(&DeviceName0, L"\SLOT_0");
RtlInitUnicodeString(&DeviceName1, L"\SLOT_1");
fdoData = GetDeviceContext(Device);
slotContext = GetFileSlotContext(FileObject);
deviceName = WdfFileObjectGetFileName(WdfRequestGetFileObject(Request));
if (RtlCompareUnicodeString(deviceName, &DeviceName0, TRUE) == 0x0)
{
slotContext->slotNumber = 0;
if(!slotContext->alreadyOpen)
{
KdPrint( (" DeviceFileCreate __ SLOT_0 - FIRST CREATE\n"));
slotContext->Device = Device;
status = RegisterWithSmcLib(slotContext);
if(!NT_SUCCESS (status)){
// return status;
KdPrint( (" DeviceFileCreate - RegisterWithSmcLib- failed - status = 0x%X\n", status));
return;
}
slotContext->alreadyOpen = TRUE;
WdfRequestComplete(Request, STATUS_SUCCESS);
}
}
else
{
slotContext->slotNumber = 1;
if(!slotContext->alreadyOpen)
{
KdPrint( (" DeviceFileCreate __ SLOT_1 - FIRST CREATE\n"));
slotContext->Device = Device;
status = RegisterWithSmcLib(slotContext);
if(!NT_SUCCESS (status)){
// return status;
KdPrint( (" DeviceFileCreate - RegisterWithSmcLib- failed - status = 0x%X\n", status));
return;
}
slotContext->alreadyOpen = TRUE;
WdfRequestComplete(Request, STATUS_SUCCESS);
}
}
KdPrint( (“<<<=== DeviceFileCreate \n\n”));
return;
}
// Function used for register smartcardExtension from fileContext with different slot number
NTSTATUS
RegisterWithSmcLib (PFILE_SLOT_CONTEXT fileSlotContext)
{
…
// Callback used for smartcard statement
SmartCardExtension->ReaderFunction[RDF_CARD_POWER] =
Slot_ScardPower;
SmartCardExtension->VendorAttr.UnitNo = fileSlotContext->slotNumber;
…
status = SmartcardInitialize(SmartCardExtension);
if (status != STATUS_SUCCESS) {
SmartcardLogError(
WdfDriverWdmGetDriverObject(WdfGetDriver()),
STATUS_INSUFFICIENT_RESOURCES,
NULL,
0
);
return status;
}
// Function normally used for power on the inserted smartcard , it’s necessary to send some bytes to USB target for read/Write information of the smartcard
NTSTATUS Slot_ScardPower (PSMARTCARD_EXTENSION SmartcardExtension)
{
switch(SmartcardExtension->MinorIoControlCode)
{
case SCARD_WARM_RESET :
KdPrint((“SCARD_WARM_RESET\n”));
status = ccid_powerOn(SmartcardExtension,
&dataOutLength,
dataOut);
break;
default :
KdPrint((“Something else\n”));
status = STATUS_UNSUCCESSFUL;
}
KdPrint((" <<<=== Slot_ScardPower \n\n"));
return status;
}
ccid_powerOn(SmartcardExtension,
&dataOutLength,
dataOut)
{
// Would like to send information to usbTarget from fileContext
}
Now I have a big problem for understand how to proceed for “dialog” with the usbTargetDevice stored in the deviceContext.
I thought to add a queue in the fileContext with an objectAttributes that contains the usbTarget stored in deviceContext.
But I’m not sure if it’s the best way.
Some could help me please, because I really see no way for resolve this problem.
Thanks in advance,
Best regards,