How can I call API SCardTransmit(........) from C#? I have worked on it for over two weeks.

A

Aaron

SCardTransmit(.....) is an API, you can find it from MSDN, from
"Winscard.dll" that used to send
commands, in bytes, to smart card and get response, also in bytes, from
that smart card, and the following is the way I used to call that API
from C#.

protected byte[] Execute()
{
//Handle the smart card that I have already got.
UIntPtr cardHandle = got card handle ;

//Buffer used to contain the command sent to smart card
//this command is used to change pin1 of sim card.
byte[] sendBuffer = build buffer needed ;

//Length of the buffer above.
int sendBufLen = sendBuffer.Length ;

//Buffer used to store the response info from the
//smart card. In my example, it is always the same,
//and I don't know the reason why.
byte[] recvBuffer = new byte[2] ;

//Length of the response buffer.
int recvBufLen = 2 ;

//The PCI info sent to the smart card,
//I get the address of this PCI from "Winscard.dll",
//and method "GetPciT0()" is defined bellow.
IntPtr sendPci = this.GetPciT0() ;

//The PCI info return back from smart card.
//and the type "Pci" is a struct I defined as bellow,
//and it is the same as its counterpart defined in C
//from MSDN.
//[StructLayout(LayoutKind.Sequential)]
//public struct Pci
//{
// public Pci(int protocol, int length)
// {
// this.protocol = protocol ;
// this.pciLength = length ;
// }
// public int protocol ;
// public int pciLength ;
//}
Pci recvPci = new Pci(0, 0) ;

//Send the command to smart card.
int ret = SCardTransmit(cardHandle, sendPci, sendBufLen,
sendBufLen, recvPci, recvBuffer,
recvBufLen
)
return recvBuffer ;
}

//Get the address of Pci from "Winscard.dll".
private IntPtr GetPciT0()
{
IntPtr handle = LoadLibrary("Winscard.dll") ;
IntPtr pci = GetProcAddress(handle, "g_rgSCardT0Pci") ;
FreeLibrary(handle) ;
return pci ;
}

[DllImport("Winscard.dll")]
private extern static int SCardTransmit
(UIntPtr cardHandle, IntPtr sendPci,
byte[] sendBuffer, int sbLength,
[In, Out] Pci recvPci,
[Out] IntPtr recvBuffer,
[In, Out] int rbLength
) ;

[DllImport("kernel32.dll")]
private extern static IntPtr LoadLibrary(string fileName) ;

[DllImport("kernel32.dll")]
private extern static void FreeLibrary(IntPtr handle) ;

[DllImport("kernel32.dll")]
private extern static IntPtr GetProcAddress(IntPtr handle, string
procName) ;

The API SCardTransmit(....) can be called successfully, because the
return value from that API is "0", and also the pin1 value in smart card
is changed, but the problem is that the value of "recvBuffer" is always
the same, "0200" in hexstyle, and the hope value is "9000" if the pin1
is changed and "9804" if do not have enough rights to change that pin1.
I don't know where the problem is and how I can handle it.
there may be some problem with the transition of "recvBuffer" from
managed code to unmanaged code, I guess.

The card reader I used is "SCM SCR331 0", for other infomation about
SCardTransmit(.....), please refer to MSDN.

Hope your response, best regards.
 
M

Mattias Sjögren

byte[] recvBuffer = new byte[2] ; [...]
int ret = SCardTransmit(cardHandle, sendPci, sendBufLen,
sendBufLen, recvPci, recvBuffer,
recvBufLen
) [...]
[DllImport("Winscard.dll")]
private extern static int SCardTransmit
(UIntPtr cardHandle, IntPtr sendPci,
byte[] sendBuffer, int sbLength,
[In, Out] Pci recvPci,
[Out] IntPtr recvBuffer,
[In, Out] int rbLength
) ;

Your code shouldn't even compile, since

i) You're missing a semicolon on the SCardTransmit call
ii) You're passing a byte[] to the recvBuffer parameter declared as
IntPtr.

It's a lot easier to help you if you post code that actually compiles.

recvPci should be a ref parameter.



Mattias
 
A

Aaron

I forgot the ";", and it should be byte[] in the prototype of
SCardTransmit(.....) ; I did compile it on my computer, I made mistakes
when I pasted the code here.Sorry!
 
A

Aaron

I forgot the ";", and it should be byte[] in the prototype of
SCardTransmit(.....) ; I did compile it on my computer, I made mistakes
when I pasted the code here.Sorry!
 
V

Vishal Singh

I have been able to execute this API successfully.
Thanx to this Forum as it helped me a lot in achieving success.
Im sending the code for it


[DllImport("winscard.dll", CharSet=CharSet.Ansi)]
private static extern int SCardTransmit(uint hCard,IntPtr pioSendPci,
[In] byte[] sendBuffer, uint sendLength, IntPtr piorecvPci,[Out] byte[]
recvBuffer, ref uint recvLength);

[DllImport("kernel32.dll")]
private extern static IntPtr LoadLibrary(string fileName) ;

[DllImport("kernel32.dll")]
private extern static void FreeLibrary(IntPtr handle) ;

[DllImport("kernel32.dll")]
private extern static IntPtr GetProcAddress(IntPtr handle, string
procName);

//Get the address of Pci from "Winscard.dll".
private IntPtr GetPciT0()
{
IntPtr handle = LoadLibrary("Winscard.dll") ;
IntPtr pci = GetProcAddress(handle, "g_rgSCardT0Pci") ;
FreeLibrary(handle) ;
return pci ;
}


public returncodes TransmitApdu (byte[] sbuffer,
int slen,byte[] rbuffer,uint
rlen,int hflag)
{
int retval = 0;
IntPtr sendPci = GetPciT0();
if(hflag == 1 ) // for Perso SAM Card
{
if((retval = SCardTransmit(ghOprCard, sendPci, sbuffer, slen,
IntPtr.Zero, rbuffer, ref rlen)) != 0)
return returncodes.TransmitError;
}
if(hflag == 2 ) // for User Card
{
if((retval = SCardTransmit(ghUsrCard, sendPci, sbuffer, slen,
IntPtr.Zero, rbuffer, ref rlen)) != 0)
return returncodes.TransmitError;
}
if(rlen == 2)
{
if(rbuffer[0] != 0x90 && rbuffer[1] != 0x00 )
{
if(rbuffer[0] != 0x61)
return returncodes.TransmitError;
}
}
if(rlen > 2)
{
if(rbuffer[rlen-2] != 0x90 && rbuffer[rlen-1] != 0x00)
return returncodes.TransmitError;
}

return returncodes.Success;
}
 
Joined
May 5, 2011
Messages
1
Reaction score
0
Hi all,
I use an safenet protectserver HSM "cryptoki.dll". I want to know how get its info via C# application abd its .dll

regards
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top