In a couple of previous articles I presented a .NET API and a simple XML framework to write smart card application for the .NET environment. When I first developed this framework I also made a version for the Compact Framework and specially for the PocketPC. As I had some request from readers regarding the CE version I have decided to write this short article about it. I recommend that you first read my to other articles, A .NET API for PC/SC and An XML framework for Smart card application, because I describe only the main differences of the CF version compared to a full .NET 2.0 version.
A simple Smart card Framework
The CF version of the smart card classes is very similar to the one I intorduced previously. You can find below the interface and the base classes that are used to manage the card communication and the command format.
public interface ICard
void Connect(string Reader, SHARE ShareMode,
void Disconnect(DISCONNECT Disposition);
APDUResponse Transmit(APDUCommand ApduCmd);
APDUResponse are used to send the command and get the response from the card.
DISCONNECT are enumerations of constants used by PC/SC.
public class APDUCommand
public APDUCommand(byte bCla, byte bIns, byte bP1, byte bP2,
byte baData, byte bLe);
public void Update(APDUParam apduParam);
public override string ToString();
public byte Class;
public byte Ins;
public byte P1;
public byte P2;
public byte Data;
public byte Le;
public class APDUResponse
public APDUResponse(byte baData);
public byte Data;
public byte SW1;
public byte SW2;
public ushort Status;
public override string ToString();
The PocketPC version doesn't provide any event management and unlike the PC version there is no implementation using the a COM version of PC/SC, because it doesn't exist on CE and also because there is no COM interop support with the Compact Framework.
So the only implementation of the ICard interface is a
NativeCard class that use the native interop of .NET.
CardNative: A native interoperability implementation class using P/Invoke
The Platform Invoke mechanism (P/Invoke) is a very powerful mechanism that gives a total access to the Win32 platform API. The .NET framework provides a complete set of classes that you can use to achieve every marshaling operation necessary to call Win32 functions from .NET. Those classes are defined in the
System.Runtime.InteropServices assembly that you just need to import in your program. The P/Invoke mechanism even if it is a bit complex is far more convenient than the JNI mechanism of Java. All the atomic types like int, byte, long, etc... are automatically marshaled by the compiler itself. The byte is also automatically marshaled as input or output parameter. When you have to deal with more complex parameters like strings, structure or pointers to structure, .NET provides a set of marshaling classes that can be used as attributes or object in you program when marshaling parameters. To develop the
CardNative class I didn't have to develop any extra code to use the PC/SC API, all the code is in the source CardNative.cs. When you want to use a Win32 API C function you need to declare the function in your class using the interoperabilty attributes provided by the
System.Runtime.InteropServices assembly. Once you have declared the function you can just use it as any C# method in your class. The following code sample illustrates this mechanism.
The main differences between the PC version and the PocketPC version is that the PC/SC functions are not located in the same DLL and that parameters passed using a pointer, except for the byte array are not automatically marshaled. There are also some memory allocation functions that are not provided by the Compact Framework and you need to use the C native functions.
Memory functions that you need to import.
internal static extern IntPtr LocalAlloc(UInt32 uFlags, UInt32 uBytes);
internal static extern IntPtr LocalFree(IntPtr hMem);
Declaration of the PC/SC native functions
[DllImport("scardce.dll", SetLastError=true, CharSet=CharSet.Auto )]
internal static extern int SGCardListReaders(UInt32 hContext,
IntPtr mszReaders, out UInt32 pcchReaders);
internal static extern int SGCardEstablishContext(UInt32 dwScope,
internal static extern int SGCardReleaseContext(UInt32 hContext);
[DllImport("scardce.dll", SetLastError=true, CharSet=CharSet.Auto)]
internal static extern int SGCardConnect(UInt32 hContext,
internal static extern int SGCardDisconnect(UInt32 hCard,
internal static extern int SGCardTransmit(UInt32 hCard,
[In] ref SCard_IO_Request pioSendPci,
[Out] byte pbRecvBuffer,
out UInt32 pcbRecvLength);
If you have a look to the declaration of the PC/SC functions you will notice some differences with the PC declaration. For example there is no automatic marshalling of the strings and you need to handle them as an array of bytes. For the rest the declaration is the same.
The following code shows how to pass a string to the PC/SC function
public void Connect(string Reader, SHARE ShareMode,
IntPtr hCard = IntPtr.Zero;
IntPtr pProtocol = IntPtr.Zero;
if (m_hContext == 0)
hCard = LocalAlloc(0, (UInt32) Marshal.SizeOf(m_hCard));
pProtocol = LocalAlloc(0, (UInt32) Marshal.SizeOf(m_nProtocol));
byte baReader = Encoding.Unicode.GetBytes(Reader);
m_nLastError = SGCardConnect(m_hContext,
if (m_nLastError != 0)
string msg = "SCardConnect error: " + m_nLastError;
throw new Exception(msg);
m_hCard = (uint) Marshal.ReadInt32(hCard);
m_nProtocol = (uint) Marshal.ReadInt32(pProtocol);
This code is very interesting because it shows all the differences that there are between the PC and the PocketPC version. In addition to the string management you can see that to get the card handle (
m_hCard) and the protocol (
pProtocol) you first need to allocate the memory to get them using the native allocation functions. On the exit of the function, if it worked you then need to get the data from the memory the same way you would do with the PC version.
Demo application: An Exchange APDU application for the PocketPC
When it comes to use the
ICard interface in an application there is strictly no difference with the PC except with the limitation that exist with the .NET Compact Framework.
I designed a simple exchange APDU application that uses an older version of my APDUList.xml (there are few differences in the declaration of the APDU). The only problem that you may have is that there are not a lot of smart card readers available in the market. I developed this application using a smart card embedded in a SD card and a small smart card reader that you plug on a SD card slot. I know that there is also an extension for iPaq where you can plug a PCI smart card reader.
This is a screen shot done with the Visual Studio emulator which unfortunately cannot connect the smart card reader of the PC.
Points of Interest
This short article demonstrates the differences that there can be when you develop the same kind of application on a PC or a PocketPC. Even if the differences are less than when using a language like C++, as the CF is a subset of the .NET framework and that support for interoperability is not totally implemented it can be quite difficult to achieve the same level of functionalities.