using Newtonsoft.Json.Linq;
using PTMedicalInsurance.Entity;
using PTMedicalInsurance.Helper;
using PTMedicalInsurance.Variables;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace PTMedicalInsurance.Common
{
class CardReaderNew
{
const string DllPath = @"SSCard.dll";
private bool initilaized = false;
[DllImport("SSCard.dll", EntryPoint = "Init", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
static extern int Init(IntPtr pURL, IntPtr pUser);
[DllImport("SSCard.dll", EntryPoint = "ReadCardBas", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
private static extern int ReadCardBas(IntPtr pOutBuff, int nOutBuffLen, IntPtr pSignBuff, int nSignBuffLen);
[DllImport("SSCard.dll", EntryPoint = "VerifyPIN", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
static extern int VerifyPIN(StringBuilder pOutBuff, int nOutBuffLen);
[DllImport("SSCard.dll", EntryPoint = "ChangePIN", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
static extern int ChangePIN(StringBuilder pOutBuff, int nOutBuffLen);
[DllImport("SSCard.dll", EntryPoint = "ReadSFZ", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
static extern int ReadSFZ(StringBuilder pOutBuff, int nOutBuffLen, StringBuilder pSignBuff, int nSignBuffLen);
[DllImport("SSCard.dll", EntryPoint = "GetQRBase", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
static extern int GetQRBase(int nTimeout, StringBuilder pOutBuff, int nOutBuffLen, StringBuilder pSignBuff, int nSignBuffLen);
//电子凭证
[DllImport("NationECCode.dll", EntryPoint = "NationEcTrans", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
static extern IntPtr NationEcTrans(StringBuilder strUrl, StringBuilder InData, StringBuilder OutData);
private string URL;
private string User;
public CardReaderNew(string URL, string User)
{
this.URL = URL;
this.User = User;
// 获取当前线程
Thread currentThread = Thread.CurrentThread;
Global.writeLog($"Current threadID: {currentThread.ManagedThreadId}");
//Global.writeLog($"Is this the main thread? {currentThread.IsBackground == false && currentThread.Name == null}");
//Global.writeLog($"Thread name: {currentThread.Name ?? "Unnamed"}");
}
public int Init()
{
if (initilaized) return 0;
string errMsg = "";
int result = -1;
Global.writeLog(string.Format("读卡初始化:{0},{1}", URL, User));
// 将托管字符串转换为 ANSI 编码的字节数组
byte[] urlBytes = Encoding.ASCII.GetBytes(URL + '\0'); // 添加终止符
byte[] userBytes = Encoding.ASCII.GetBytes(User + '\0'); // 添加终止符
//// 分配非托管内存并复制字符串数据
//IntPtr pUrl = Marshal.AllocCoTaskMem(urlBytes.Length);
//IntPtr pUser = Marshal.AllocCoTaskMem(userBytes.Length);
// 分配全局非托管内存并复制字符串数据
IntPtr pUrl = Marshal.AllocHGlobal(urlBytes.Length);
IntPtr pUser = Marshal.AllocHGlobal(userBytes.Length);
try
{
// 将托管字节数组复制到非托管内存
Marshal.Copy(urlBytes, 0, pUrl, urlBytes.Length);
Marshal.Copy(userBytes, 0, pUser, userBytes.Length);
result = Init(pUrl, pUser);
initilaized = true;
return result;
}
catch (Exception ex)
{
errMsg = ex.Message;
return result;
}
finally
{
Global.writeLog("初始化", "", result.ToString() + ":" + errMsg);
//// 显式释放非托管内存
//if (pUrl != IntPtr.Zero) Marshal.FreeCoTaskMem(pUrl);
//if (pUser != IntPtr.Zero) Marshal.FreeCoTaskMem(pUser);
// 显式释放全局非托管内存
if (pUrl != IntPtr.Zero) Marshal.FreeHGlobal(pUrl);
if (pUser != IntPtr.Zero) Marshal.FreeHGlobal(pUser);
}
}
///
/// 读社保卡
///
///
///
public int ReadCardBas(out string basInfo)
{
basInfo = "";
int rtn = -1;
// 分配非托管内存
//IntPtr pOutBuff = Marshal.AllocCoTaskMem(1024);
//IntPtr pSignBuff = Marshal.AllocCoTaskMem(8192);
// 分配全局非托管内存
IntPtr pOutBuff = Marshal.AllocHGlobal(1024);
IntPtr pSignBuff = Marshal.AllocHGlobal(8192);
try
{
rtn = ReadCardBas(pOutBuff, 1024, pSignBuff, 8192);
if (rtn == 0)
{
// 解析返回读卡信息
string outString = Marshal.PtrToStringAnsi(pOutBuff);
string signString = Marshal.PtrToStringAnsi(pSignBuff);
basInfo = parseCardInfo(outString, 0);
Global.pat.card.BusinessCode = signString;
}
else
{
string outString = Marshal.PtrToStringAnsi(pOutBuff);
basInfo = outString;
}
return rtn;
}
catch (Exception ex)
{
basInfo = "ReadCardBas异常:" + ex.Message;
return rtn;
}
finally
{
Global.writeLog("读社保卡", "", basInfo);
//// 显式释放非托管内存
//Marshal.FreeCoTaskMem(pOutBuff);
//Marshal.FreeCoTaskMem(pSignBuff);
// 显式释放非托管内存
Marshal.FreeHGlobal(pOutBuff);
Marshal.FreeHGlobal(pSignBuff);
}
}
///
/// 读身份证
///
///
///
public int ReadSFZ(out string OutBuff)
{
OutBuff = "";
int rtn = -1;
try
{
StringBuilder sbOutBuff = new StringBuilder(1024);
StringBuilder sbBusiCardBuff = new StringBuilder(1024);
rtn = ReadSFZ(sbOutBuff, 1024, sbBusiCardBuff, 1024);
// 解析返回读卡信息
OutBuff = parseCardInfo(sbOutBuff.ToString(), 0);
Global.pat.card.BusinessCode = sbBusiCardBuff.ToString();
return rtn;
}
catch (Exception ex)
{
OutBuff = "ReadSFZ 异常:" + ex.Message;
return rtn;
}
}
public int ReadECToken(string URL, string inputParam, out string sOutPar)
{
sOutPar = "";
StringBuilder sbURL = new StringBuilder(URL);
StringBuilder sbInput = new StringBuilder(inputParam);
StringBuilder sbOut = new StringBuilder(40960);
IntPtr pInt = CardReaderNew.NationEcTrans(sbURL, sbInput, sbOut);
string outputData = sbOut.ToString();
//sOutPar = parseECTokenOutput(outputData);
sOutPar = outputData;
if (JsonHelper.getDestValue(JObject.Parse(outputData), "code") != "0")
{
return -1;
}
return 0;
}
public static string parseECTokenOutput(string data)
{
JObject joRtn = JObject.Parse(data);
Global.pat.ecToken = JsonHelper.getDestValue(joRtn, "data.ecToken");
Global.pat.certNO = JsonHelper.getDestValue(joRtn, "data.idNo"); //身份证
Global.pat.name = JsonHelper.getDestValue(joRtn, "data.userName");
Global.pat.certType = JsonHelper.getDestValue(joRtn, "data.idType");
Global.pat.insuplc_admdvs = JsonHelper.getDestValue(joRtn, "data.insuOrg");
// 令牌
Global.pat.mdtrtcertNO = Global.pat.ecToken;
return data;
}
///
/// 解析读卡结果
///
///
///
private string parseCardInfo(string inBuff, int startIndex = 1)
{
// 360100 | 362502198603060820 | B04D4C6B2 | 360100D156000005B04D4C6BF99AC1BD | 李凌 | 0081544C9386841907267A0FD6 | 2.00 | 20200612 | 20300612 | 369900906440 ||
string[] data = inBuff.Split("|".ToCharArray());
CardInfo card = new CardInfo();
card.certno = data[startIndex + 1];
card.cardno = data[startIndex + 2];
card.card_sn = data[startIndex + 3];
card.psn_name = data[startIndex + 4];
Global.pat.insuplc_admdvs = data[startIndex]; //行政区划
Global.pat.card.SN = card.card_sn;
Global.pat.certType = "01";
Global.pat.certNO = card.certno;
Global.pat.name = card.psn_name;
Global.pat.card.NO = card.cardno;
Global.pat.mdtrtcertNO = card.certno;
string outParam = JsonHelper.toJsonString(card);
Global.writeLog("读卡返回:", inBuff, outParam);
return outParam;
}
}
}