From: Pedro Duarte on
Hi,

It's the first time I try to code for a smart card reader on a windows
mobile 6 device and my experience with p'invoke is also very limited.

I couldn't find any example for it at the Windows Mobile 6 SDK. I only
found the winscard.h and winscard.lib but no code example. There are
some code samples over the Web but none targets the mobile just the PC
Windows and the code seems to need modifications.

I gathered/changed some code but I'm having a lot of trouble to make
the SCardConnect call.
I'm getting a "One or more of the supplied parameters values could not
be properly interpreted" error message for the call with the supplied
parameters.

I played with various possibilities at the MarshalAs for the string
szReader but I get "NotsupportedException".

This is the code I'm using. Do you spot any problems? Thanks.


[DllImport("winscard.dll", SetLastError=true)]
internal static extern int SCardEstablishContext(UInt32 dwScope,
IntPtr pvReserved1,
IntPtr pvReserved2,
IntPtr phContext);

[DllImport("winscard.dll", EntryPoint = "SCardConnect", SetLastError =
true, CharSet = CharSet.Unicode)]
internal static extern int SCardConnectW(UInt32 hContext,
[MarshalAs(UnmanagedType.LPWStr)] string szReader,
UInt32 dwShareMode,
UInt32 dwPreferredProtocols,
IntPtr phCard,
IntPtr pdwActiveProtocol);

public enum SCOPE { User, Terminal, System }
private UInt32 m_hContext = 0;
private int m_nLastError = 0;
private UInt32 m_hCard = 0;
private UInt32 m_nProtocol = (uint) PROTOCOL.T0;


usage:

///EstablishContext
IntPtr hContext = Marshal.AllocHGlobal(Marshal.SizeOf(m_
m_nLastError = SCardEstablishContext((uint) SCOPE.User,
IntPtr.Zero, IntPtr.Zero, hContext);
if (m_nLastError != 0)
{
string msg = "SCardEstablishContext error: " + m_nLastError;
MessageBox.Show(msg);
Marshal.FreeHGlobal(hContext);
throw new Exception(msg);
}
m_hContext = (uint) Marshal.ReadInt32(hContext);
Marshal.FreeHGlobal(hContext);


///Connect
string[] readers = new string[1];
readers[0] = "OMNIKEY Card";
string reader = readers[0];

IntPtr hCard = Marshal.AllocHGlobal(Marshal.SizeOf(m_hCard));
IntPtr pProtocol =
Marshal.AllocHGlobal(Marshal.SizeOf(m_nProtocol));
try
{
m_nLastError = SCardConnectW(m_hContext, reader,
(uint)SHARE.Direct, (uint)PROTOCOL.T0orT1,
hCard, pProtocol);

if (m_nLastError != 0)
{
MessageBox.Show("SCardConnectW error = " +
m_nLastError.ToString());
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}


public enum PROTOCOL
{
Undefined = 0x00000000,
T0 = 0x00000001,
T1 = 0x00000002,
Raw = 0x00010000,
Default = unchecked ((int) 0x80000000), // Use implicit PTS.
T0orT1 = T0 | T1
}


From: Wolfgang Rolke on
>I couldn't find any example for it at the Windows Mobile 6 SDK. I only
>found the winscard.h and winscard.lib but no code example. There are
>some code samples over the Web but none targets the mobile just the PC
>Windows and the code seems to need modifications.

No. The SCard API functions under Windows CE / Windows Mobile exacly like
on the desktop PC.

Ther is only one difference: The Flag SCARD_SHARE_SHARED is not supported under CE.

I use the same source for the PC and CE version of my SmardCard viewer:
http://www.wolfgang-rolke.de/sysinfo/#smartcard (only with german UI)
http://www.wolfgang-rolke.de/wince/#smartcard (designed for HP Jornada 720)