Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results
The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.
Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/
Dear experts,
I am developing a virtual smart card reader but I am sticking on make it visible to Smart Card Resource Manager.
My source code is based on this guide **https://docs.microsoft.com/en-us/windows-hardware/drivers/smartcard/ ** and Windows-driver-samples\smartcrd.
However, I just make it very simple as I can understand.
SmartcardDeviceControl return STATUS_DEVICE_BUSY(0x80000011) for IoControlCode IOCTL_SMARTCARD_IS_ABSENT(0x31002C or 3211308 in decimal) in callback routine EvtIoDeviceControl.
I guess this is a problem prevent my reader visible to Smart Card Resource Manager but I don't know how to fix it.
I am new in this field. Any guidance would be really helpful.
Please check my source code in the first comment.
And this is how I install the driver.
devcon install VPJSCReader.inf root\VPJSCReader Device node created. Install is complete when drivers are installed... Updating drivers for root\VPJSCReader from c:\Users\minh\Downloads\VPJSCReader\VPJSCReader.inf. Drivers installed successfully.
Here is debugger's log.
VPJSCReader!DriverEntry: Enter - KMDF Version Built Oct 14 2019 08:50:44 VPJSCReader!DriverEntry: Exit 0 VPJSCReader!VPJSCReaderEvtDeviceAdd: Enter VPJSCReader!VPJSCReaderEvtDeviceAdd: Exit VPJSCReaderEvtIoDeviceControl Queue 0x00001B78487674E8, Request 0x00001B784F5051D8 OutputBufferLength 4 InputBufferLength 4 IoControlCode 3211272 VPJSCReaderLibComplete called: status 0, Context 00001B784F5051D8 VPJSCReaderEvtIoDeviceControl Queue 0x00001B78487674E8, Request 0x00001B784F5051D8 OutputBufferLength 36 InputBufferLength 4 IoControlCode 3211272 VPJSCReaderLibComplete called: status 0, Context 00001B784F5051D8 VPJSCReaderEvtIoDeviceControl Queue 0x00001B78487674E8, Request 0x00001B784F5051D8 OutputBufferLength 36 InputBufferLength 4 IoControlCode 3211272 VPJSCReaderLibComplete called: status 0, Context 00001B784F5051D8 VPJSCReaderEvtIoDeviceControl Queue 0x00001B78487674E8, Request 0x00001B784F5051D8 OutputBufferLength 4 InputBufferLength 4 IoControlCode 3211272 VPJSCReaderLibComplete called: status 0, Context 00001B784F5051D8 VPJSCReaderEvtIoDeviceControl Queue 0x00001B78487674E8, Request 0x00001B784F5051D8 OutputBufferLength 4 InputBufferLength 4 IoControlCode 3211272 VPJSCReaderLibComplete called: status 0, Context 00001B784F5051D8 VPJSCReaderEvtIoDeviceControl Queue 0x00001B78487674E8, Request 0x00001B784F5051D8 OutputBufferLength 0 InputBufferLength 0 IoControlCode 3211304 VPJSCReader!CBCardTracking: Entry VPJSCReaderLibComplete called: status 0, Context 00001B784F5051D8 VPJSCReaderEvtIoDeviceControl Queue 0x00001B78487674E8, Request 0x00001B784F5051D8 OutputBufferLength 4 InputBufferLength 0 IoControlCode 3211320 VPJSCReaderLibComplete called: status 0, Context 00001B784F5051D8 VPJSCReaderEvtIoDeviceControl Queue 0x00001B78487674E8, Request 0x00001B784F5051D8 OutputBufferLength 0 InputBufferLength 0 IoControlCode 3211308 VPJSCReaderLibComplete called: status 80000011, Context 00001B784F5051D8 VPJSCReaderEvtIoDeviceControl Queue 0x00001B78487674E8, Request 0x00001B784F5051D8 OutputBufferLength 0 InputBufferLength 0 IoControlCode 3211308 VPJSCReaderLibComplete called: status 80000011, Context 00001B784F5051D8 VPJSCReaderEvtIoDeviceControl Queue 0x00001B78487674E8, Request 0x00001B784F5051D8 OutputBufferLength 0 InputBufferLength 0 IoControlCode 3211308 VPJSCReaderLibComplete called: status 80000011, Context 00001B784F5051D8
In the last three IO request, it return status 80000011.
Here is my device manager.
And here is my event viewer.
Upcoming OSR Seminars | ||
---|---|---|
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead! | ||
Kernel Debugging | 13-17 May 2024 | Live, Online |
Developing Minifilters | 1-5 Apr 2024 | Live, Online |
Internals & Software Drivers | 11-15 Mar 2024 | Live, Online |
Writing WDF Drivers | 26 Feb - 1 Mar 2024 | Live, Online |
Comments
My driver source code.
There are a few problems here. Have you done any reading at all about the functions you are calling?
I don't understand why you would use IoSetCompletionRoutine instead of WdfRequestSetCompletionRoutine. When an I/O completion routine is finished with an IRP, as yours is, you need to return the status from the IRP, and not STATUS_MORE_PROCESSING_REQUIRED. WdfRequestSetCompletionRoutine would have handled that for you.
However, at a higher level, the whole completion routine processing is totally wrong. SmartcardDeviceControl is NOT passing the request into another driver. Go look at the documentation page. You do not need to worry about a stack location and a completion routine. That whole routine can be condensed to
deviceExtension = DeviceGetContext...
irp = WdfRequestWdmGetIrp(Request);
return SmartcardDeviceControl(&(deviceExtension->SmartcardExtension), irp);
Are you getting calls to your callbacks? SmartcardDeviceControl handles requests that don't need hardware, but anything that does need hardware has to call into your callbacks.
Why did you SetExclusive on the device object? Did you read that somewhere?
Your InterlockedIncrement of DeviceInstanceNo is silly. That routine will be called exactly once for each device, and each one will get a fresh device context. Thus, that number will never be anything other than 1.
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.
Hi @Tim_Roberts,
Thank you very much for your comments.
My source code is based on some resources such as https://docs.microsoft.com/en-us/windows-hardware/drivers/smartcard and Windows-driver-samples\smartcrd. I know this is not the whole picture and I've just focused on some functions related to smart card, not all of them.
For me, there is a huge amount of knowledge in this filed and I've not understand it clearly.
Yes, as you see in debugger's log, routine CBCardTracking is called. If I change
to
routine CBCardPower is also getting called.
Now, I remove redundant code as your comments and the driver run same as it before changed.
The problem may be in this callback routine CBCardTracking:
Because, I do nothing here, just return success.
I think that I need to do something with SmartcardExtension->OsData->NotificationIrp but I don't know how.
OK, so you've established that the framework is fundamentally correct. Now you have to write the guts of your driver. That's where the real work is.
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.
Is there any one here who implement success a virtual smart card reader?
Please help me, I am still sticking with the problem of my reader is not listed by SCardListReaders.
My Event IO device control routine VPJSCReaderEvtIoDeviceControl is kept the same in above source code.
And here what I receive after SmartcardDeviceControl is called(I am using WinDbg to get these information).
I think this problem here is a cause that prevent my reader listed by SCardListReaders. Any idea is welcome!
I just come back here to update that the problem has been resolved.
Sorry for the late update.
Hi @minhpta ,
Would you mind sharing what the solution was in case someone has the same issue in the future.
Thanks,
Eric
@Eric_Wittmayer
Yes, absolutely. I will share It in a completed topic but not now because eventhought my solution works but not as my expectation.
I have another problem here , It makes my solution is not completed.
Hi @minhpta
How did you solve this problem?
Thanks
Certainly, designing a solid framework is crucial, but the true essence of any driver lies in the implementation details.