For those who need to control or access PC/SC Smart Card Reader by using ANSI C compiler, it's suitable article for you. I'll show you how to invoke WinSCard.dll file provided by Microsoft Windows. We'll use Pelles C compiler to make it easier because you don't need to configure your compiler and connect it with Windows SDK (Software Development Kit). The reason is the compiler contains all Windows library and configure it automatically for you. All you have to do is just download it from trusted site and install it. And don't worry, the source code you've created will run properly in C++ and C++/CLI as well.

OK, let's start our coding. Firstly, you need to invoke SCardEstablishContext function to establish the resource manager context (the scope) within which database operations are performed. We can use SCARD_SCOPE_USER or SCARD_SCOPE_SYSTEM as database operations. If the return value of this performance is SCARD_S_SUCCESS, we're able to continue invoking SCardListReaders function to obtain all PC/SC readers which are connected to you computer and store the readers list in TCHAR string variable.

Now it's time to establish a connection to your smart card reader. Select one of reader from your readers list, then invoke SCardConnect function. By invoking this function, you'll get Card Handle name and Communication Active Protocol which will use to transmit command to the card. Use the two parameters to invoke SCardTransmit function and a service request will send to the card, then you will obtain response and status word after invoking this function (if no error occurs certainly). You can invoke SCardTransmit as many times as you want, as long as you still have the Card Handle.

And, after you've got all you need from invoking SCardTransmit, it's better to release the memory and the smart card context. To do so, consecutively invoke SCardFreeMemory function to release TCHAR string variable which is used to store readers list and SCardReleaseContext function to close an established smart card context, freeing any resources allocated under that context, including Card Handle objects and memory allocated using the SCARD_AUTOALLOCATE length designator.

Here is the complete source code to access your smart card reader.

Source Code:

Don't forget to configure two additional setting before you compile the source code unless you want to get Compile-Time error message. In Pelles C IDE, select Project menu then Project options. In Compiler tab, check "Enable Microsoft extentions" option and in Linker tab, you'll find Library and object files. Add "winscard.lib" to the text box. After configuring it, you should start compiling your source code.

If compiling is succeed and you run the exe file, you will see this on your console screen:
Reader: OMNIKEY CardMan 3x21 0
Active protocol T0
Select MF.
Response: 9F 16
Select EF ICCID.
Response: 9F 0F
Read EF ICCID.
Response: 12 34 56 78 90 12 34 56 78 23 90 00
Press any key to continue...
Of course your console screen will show distinct output value comparing with above, but if you're shown the reader name and 10 bytes character followed by 9000 response after transmitting Read EF ICCID command, now you can congratulate yourself. Yes, it's just what we need so far. If you want to gain the ability of this code, I suggest you to create "Smart Card Return Value Interpreter" based on Authentication Return Values list from MSDN. I bet you won't be confused anymore with the extraneous number in variable lReturn.

Last but not least, did you hear that I talk about Microsoft Visual C++ so far? Yes, I have to admit, VC++ is the best compiler for invoking their own library including winscard.dll. But I believe that nothing's in vain. Someday you will find how Pelles C is very useful in ANSI C coding, especially in WIN32 Programming.