using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Reflection ;
using System.IO;


namespace ICCard
{
public class clsICCard
{
   //首先,声明通用接口
   [DllImport("sdtapi.dll")]
   public static extern int SDT_OpenPort(int iPortID);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_ClosePort(int iPortID);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_PowerManagerBegin(int iPortID, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_AddSAMUser(int iPortID, string pcUserName, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_SAMLogin(int iPortID, string pcUserName, string pcPasswd, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_SAMLogout(int iPortID, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_UserManagerOK(int iPortID, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_ChangeOwnPwd(int iPortID, string pcOldPasswd, string pcNewPasswd, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_ChangeOtherPwd(int iPortID, string pcUserName, string pcNewPasswd, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_DeleteSAMUser(int iPortID, string pcUserName, int iIfOpen);

   [DllImport("sdtapi.dll")]
   public static extern int SDT_StartFindIDCard(int iPortID, ref int pucIIN, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_SelectIDCard(int iPortID, ref int pucSN, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_ReadBaseMsg(int iPortID, string pucCHMsg, ref int puiCHMsgLen, string pucPHMsg, ref int puiPHMsgLen, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_ReadBaseMsgToFile(int iPortID, string fileName1, ref int puiCHMsgLen, string fileName2, ref int puiPHMsgLen, int iIfOpen);

   [DllImport("sdtapi.dll")]
   public static extern int SDT_WriteAppMsg(int iPortID, ref byte pucSendData, int uiSendLen, ref byte pucRecvData, ref int puiRecvLen, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_WriteAppMsgOK(int iPortID, ref byte pucData, int uiLen, int iIfOpen);

   [DllImport("sdtapi.dll")]
   public static extern int SDT_CancelWriteAppMsg(int iPortID, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_ReadNewAppMsg(int iPortID, ref byte pucAppMsg, ref int puiAppMsgLen, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_ReadAllAppMsg(int iPortID, ref byte pucAppMsg, ref int puiAppMsgLen, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_UsableAppMsg(int iPortID, ref byte ucByte, int iIfOpen);

   [DllImport("sdtapi.dll")]
   public static extern int SDT_GetUnlockMsg(int iPortID, ref byte strMsg, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_GetSAMID(int iPortID, ref byte StrSAMID, int iIfOpen);

   [DllImport("sdtapi.dll")]
   public static extern int SDT_SetMaxRFByte(int iPortID, byte ucByte, int iIfOpen);
   [DllImport("sdtapi.dll")]
   public static extern int SDT_ResetSAM(int iPortID, int iIfOpen);

   [DllImport("WltRS.dll")]
   public static extern int GetBmp(string file_name, int intf);

   public delegate void De_ReadICCardComplete(clsEDZ objEDZ);
   public event De_ReadICCardComplete ReadICCardComplete;
   private clsEDZ objEDZ = new clsEDZ();
   private int EdziIfOpen = 1;                //自动开关串口
   int EdziPortID;        
   public clsICCard()
   {

   }
   public bool ReadICCard()
   {           
    bool bUsbPort = false;
    int intOpenPortRtn = 0;
    int rtnTemp = 0;
    int pucIIN = 0;
    int pucSN = 0;
    int puiCHMsgLen = 0;
    int puiPHMsgLen = 0;

    objEDZ = new clsEDZ();
    //检测usb口的机具连接,必须先检测usb
    for (int iPort = 1001; iPort <= 1016; iPort++)
    {
     intOpenPortRtn = SDT_OpenPort(iPort);
     if (intOpenPortRtn == 144)
     {
      EdziPortID = iPort;
      bUsbPort = true;
      break;
     }
    }
    //检测串口的机具连接
    if (!bUsbPort)
    {
     for (int iPort = 1; iPort <= 2; iPort++)
     {
      intOpenPortRtn = SDT_OpenPort(iPort);
      if (intOpenPortRtn == 144)
      {
       EdziPortID = iPort;
       bUsbPort = false;
       break;
      }
     }
    }
    if (intOpenPortRtn != 144)
    {                             
     MessageBox.Show("端口打开失败,请检测相应的端口或者重新连接读卡器!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
     return false;
    }
    //在这里,如果您想下一次不用再耗费检查端口的检查的过程,您可以把 EdziPortID 保存下来,可以保存在注册表中,也可以保存在配置文件中,我就不多写了,但是,
    //您要考虑机具连接端口被用户改变的情况哦

    //下面找卡
    rtnTemp = SDT_StartFindIDCard(EdziPortID, ref pucIIN, EdziIfOpen);
    if (rtnTemp != 159)
    {
     rtnTemp = SDT_StartFindIDCard(EdziPortID, ref pucIIN, EdziIfOpen);   //再找卡
     if (rtnTemp != 159)
     {                                   
      rtnTemp = SDT_ClosePort(EdziPortID);
      MessageBox.Show("未放卡或者卡未放好,请重新放卡!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
      return false;
     }
    }
    //选卡
    rtnTemp = SDT_SelectIDCard(EdziPortID, ref pucSN, EdziIfOpen);
    if (rtnTemp != 144)
    {
     rtnTemp = SDT_SelectIDCard(EdziPortID, ref pucSN, EdziIfOpen);   //再选卡
     if (rtnTemp != 144)
     {                                      
      rtnTemp = SDT_ClosePort(EdziPortID);
      MessageBox.Show("读卡失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
      return false;
     }
    }
    //注意,在这里,用户必须有应用程序当前目录的读写权限
    FileInfo objFile = new FileInfo("wz.txt");
    if (objFile.Exists)
    {
     objFile.Attributes = FileAttributes.Normal;
     objFile.Delete();
    }
    objFile = new FileInfo("zp.bmp");
    if (objFile.Exists)
    {
     objFile.Attributes = FileAttributes.Normal;
     objFile.Delete();
    }
    objFile = new FileInfo("zp.wlt");
    if (objFile.Exists)
    {
     objFile.Attributes = FileAttributes.Normal;
     objFile.Delete();
    }
    rtnTemp = SDT_ReadBaseMsgToFile(EdziPortID, "wz.txt", ref puiCHMsgLen, "zp.wlt", ref puiPHMsgLen, EdziIfOpen);
    if (rtnTemp != 144)
    {                        
     rtnTemp = SDT_ClosePort(EdziPortID);
     MessageBox.Show("读卡失败!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
     return false;
    }
    //下面解析照片,注意,如果在C盘根目录下没有机具厂商的授权文件Termb.Lic,照片解析将会失败
    if (bUsbPort)
     rtnTemp = GetBmp("zp.wlt", 2);
    else
     rtnTemp = GetBmp("zp.wlt", 1);
    switch (rtnTemp)
    {
     case 0:
      MessageBox.Show("调用sdtapi.dll错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
      break;
     case 1:    //正常
      break;
     case -1:
      MessageBox.Show("相片解码错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
      break;
     case -2:
      MessageBox.Show("wlt文件后缀错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
      break;
     case -3:
      MessageBox.Show("wlt文件打开错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
      break;
     case -4:
      MessageBox.Show("wlt文件格式错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
      break;
     case -5:
      MessageBox.Show("软件未授权!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
      break;
     case -6:
      MessageBox.Show("设备连接错误!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
      break;
    }
    rtnTemp = SDT_ClosePort(EdziPortID);
    FileInfo f = new FileInfo("wz.txt");
    FileStream fs = f.OpenRead();
    byte[] bt = new byte[fs.Length];
    fs.Read(bt, 0, (int)fs.Length);
    fs.Close();

    string str = System.Text.UnicodeEncoding.Unicode.GetString(bt);

    objEDZ.Name = System.Text.UnicodeEncoding.Unicode.GetString(bt, 0, 30).Trim();
    objEDZ.Sex_Code = System.Text.UnicodeEncoding.Unicode.GetString(bt, 30, 2).Trim();
    objEDZ.NATION_Code = System.Text.UnicodeEncoding.Unicode.GetString(bt, 32, 4).Trim();
    string strBird = System.Text.UnicodeEncoding.Unicode.GetString(bt, 36, 16).Trim();
    objEDZ.BIRTH = Convert.ToDateTime(strBird.Substring(0, 4) + "年" + strBird.Substring(4, 2) + "月" + strBird.Substring(6) + "日");
    objEDZ.ADDRESS = System.Text.UnicodeEncoding.Unicode.GetString(bt, 52, 70).Trim();
    objEDZ.IDC = System.Text.UnicodeEncoding.Unicode.GetString(bt, 122, 36).Trim();
    objEDZ.REGORG = System.Text.UnicodeEncoding.Unicode.GetString(bt, 158, 30).Trim();
    string strTem = System.Text.UnicodeEncoding.Unicode.GetString(bt, 188, bt.GetLength(0) - 188).Trim();
    objEDZ.STARTDATE = Convert.ToDateTime(strTem.Substring(0, 4) + "年" + strTem.Substring(4, 2) + "月" + strTem.Substring(6, 2) + "日");
    strTem = strTem.Substring(8);
    if (strTem.Trim() != "长期")
    {
     objEDZ.ENDDATE = Convert.ToDateTime(strTem.Substring(0, 4) + "年" + strTem.Substring(4, 2) + "月" + strTem.Substring(6, 2) + "日");
    }
    else
    {
     objEDZ.ENDDATE = DateTime.MaxValue;
    }
    objFile = new FileInfo("zp.bmp");
    if (objFile.Exists)
    {
     Image img = Image.FromFile("zp.bmp");
     objEDZ.PIC_Image=(Image)img.Clone();
     System.IO.MemoryStream m = new MemoryStream();
     img.Save(m, System.Drawing.Imaging.ImageFormat.Jpeg);
     objEDZ.PIC_Byte = m.ToArray();
     img.Dispose();
     img = null;
    }
    ReadICCardComplete(objEDZ);           
    return true;
   }


}
public class clsEDZ
{
   private System.Collections.SortedList lstMZ = new SortedList();
   private string _Name;    //姓名
   private string _Sex_Code;    //性别代码
   private string _Sex_CName;    //性别
   private string _IDC;       //身份证号码
   private string _NATION_Code;    //民族代码
   private string _NATION_CName;    //民族
   private DateTime _BIRTH;      //出生日期
   private string _ADDRESS;     //住址
   private string _REGORG;      //签发机关
   private DateTime _STARTDATE;     //身份证有效起始日期
   private DateTime _ENDDATE;     //身份证有效截至日期
   private string _Period_Of_Validity_Code;    //有效期限代码,许多原来系统上面为了一代证考虑,常常存在这样的字段,二代证中已经没有了
   private string _Period_Of_Validity_CName;    //有效期限
   private byte[] _PIC_Byte;     //照片二进制
   private Image _PIC_Image;    //照片

   public clsEDZ()
   {
    lstMZ.Add("01", "汉族");
    lstMZ.Add("02", "蒙古族");
    lstMZ.Add("03", "回族");
    lstMZ.Add("04", "藏族");
    lstMZ.Add("05", "维吾尔族");
    lstMZ.Add("06", "苗族");
    lstMZ.Add("07", "彝族");
    lstMZ.Add("08", "壮族");
    lstMZ.Add("09", "布依族");
    lstMZ.Add("10", "朝鲜族");
    lstMZ.Add("11", "满族");
    lstMZ.Add("12", "侗族");
    lstMZ.Add("13", "瑶族");
    lstMZ.Add("14", "白族");
    lstMZ.Add("15", "土家族");
    lstMZ.Add("16", "哈尼族");
    lstMZ.Add("17", "哈萨克族");
    lstMZ.Add("18", "傣族");
    lstMZ.Add("19", "黎族");
    lstMZ.Add("20", "傈僳族");
    lstMZ.Add("21", "佤族");
    lstMZ.Add("22", "畲族");
    lstMZ.Add("23", "高山族");
    lstMZ.Add("24", "拉祜族");
    lstMZ.Add("25", "水族");
    lstMZ.Add("26", "东乡族");
    lstMZ.Add("27", "纳西族");
    lstMZ.Add("28", "景颇族");
    lstMZ.Add("29", "柯尔克孜族");
    lstMZ.Add("30", "土族");
    lstMZ.Add("31", "达翰尔族");
    lstMZ.Add("32", "仫佬族");
    lstMZ.Add("33", "羌族");
    lstMZ.Add("34", "布朗族");
    lstMZ.Add("35", "撒拉族");
    lstMZ.Add("36", "毛南族");
    lstMZ.Add("37", "仡佬族");
    lstMZ.Add("38", "锡伯族");
    lstMZ.Add("39", "阿昌族");
    lstMZ.Add("40", "普米族");
    lstMZ.Add("41", "塔吉克族");
    lstMZ.Add("42", "怒族");
    lstMZ.Add("43", "乌孜别克族");
    lstMZ.Add("44", "俄罗斯族");
    lstMZ.Add("45", "鄂温克族");
    lstMZ.Add("46", "德昂族");
    lstMZ.Add("47", "保安族");
    lstMZ.Add("48", "裕固族");
    lstMZ.Add("49", "京族");
    lstMZ.Add("50", "塔塔尔族");
    lstMZ.Add("51", "独龙族");
    lstMZ.Add("52", "鄂伦春族");
    lstMZ.Add("53", "赫哲族");
    lstMZ.Add("54", "门巴族");
    lstMZ.Add("55", "珞巴族");
    lstMZ.Add("56", "基诺族");
    lstMZ.Add("57", "其它");
    lstMZ.Add("98", "外国人入籍");
   }

   public string Name
   {
    get { return _Name; }
    set { _Name = value; }
   }
   public string Sex_Code
   {
    get { return _Sex_Code; }
    set
    {
     _Sex_Code = value;
     switch (value)
     {
      case "1":
       Sex_CName = "男";
       break;
      case "2":
       Sex_CName = "女";
       break;
     }
    }
   }
   public string Sex_CName
   {
    get { return _Sex_CName; }
    set { _Sex_CName = value; }
   }
   public string IDC
   {
    get { return _IDC; }
    set { _IDC = value; }
   }
   public string NATION_Code
   {
    get { return _NATION_Code; }
    set
    {
     _NATION_Code = value;
     if (lstMZ.Contains(value))
      NATION_CName = lstMZ[value].ToString();
    }
   }
   public string NATION_CName
   {
    get { return _NATION_CName; }
    set { _NATION_CName = value; }
   }
   public DateTime BIRTH
   {
    get { return _BIRTH; }
    set { _BIRTH = value; }
   }
   public string ADDRESS
   {
    get { return _ADDRESS; }
    set { _ADDRESS = value; }
   }
   public string REGORG
   {
    get { return _REGORG; }
    set { _REGORG = value; }
   }
   public DateTime STARTDATE
   {
    get { return _STARTDATE; }
    set { _STARTDATE = value; }
   }
   public DateTime ENDDATE
   {
    get { return _ENDDATE; }
    set
    {
     _ENDDATE = value;
     if (_ENDDATE == DateTime.MaxValue)
     {
      _Period_Of_Validity_Code = "3";
      _Period_Of_Validity_CName = "长期";
     }
     else
     {
      if (_STARTDATE != DateTime.MinValue)
      {
       switch (value.AddDays(1).Year - _STARTDATE.Year)
       {
        case 5:
         _Period_Of_Validity_Code = "4";
         _Period_Of_Validity_CName = "5年";
         break;
        case 10:
         _Period_Of_Validity_Code = "1";
         _Period_Of_Validity_CName = "10年";
         break;
        case 20:
         _Period_Of_Validity_Code = "2";
         _Period_Of_Validity_CName = "20年";
         break;
       }
      }
     }

    }
   }
   public string Period_Of_Validity_Code
   {
    get { return _Period_Of_Validity_Code; }
    set { _Period_Of_Validity_Code = value; }
   }
   public string Period_Of_Validity_CName
   {
    get { return _Period_Of_Validity_CName; }
    set { _Period_Of_Validity_CName = value; }
   }
   public byte[] PIC_Byte
   {
    get { return _PIC_Byte; }
    set { _PIC_Byte = value; }
   }
   public Image PIC_Image
   {
    get { return _PIC_Image; }
    set { _PIC_Image = value; }
   }

}
}