private void Init()
        {
            byte[] codyMasterSeed = Encoding.Unicode.GetBytes("CodyMasterRockeySeed");

            ushort pCount = 0;
            var    pt     = RockeyArmHelper.EnumRockeyArm(out pCount);

            if (pCount > 1)
            {
                throw new Exception("加密锁不止一个!");
            }
            else if (pCount == 0)
            {
                throw new Exception("没有找到加密锁!");
            }
            else
            {
                DONGLE_INFO pDongleInfo = (DONGLE_INFO)Marshal.PtrToStructure((IntPtr)(UInt32)pt, typeof(DONGLE_INFO));
                if (pDongleInfo.m_PID != DefaultPid)
                {
                    throw new Exception("加密锁已被初始化!");
                }
            }

            uint hDongle = 0;

            RockeyArmHelper.OpenRockey(ref hDongle, 0);
            RockeyArmHelper.VerifyPIN(hDongle, DefaultAdminPin);
            RockeyArmHelper.GenUniqueKey(hDongle, codyMasterSeed);

            RockeyArmHelper.CloseRockey(hDongle);
        }
        private DONGLE_INFO WriteData(byte[] datas)
        {
            DONGLE_INFO pDongleInfo;

            ushort pCount = 0;
            IntPtr pt     = RockeyArmHelper.EnumRockeyArm(out pCount);

            if (pCount > 1)
            {
                throw new Exception("加密锁不止一个!");
            }
            else if (pCount == 0)
            {
                throw new Exception("没有找到加密锁!");
            }
            else
            {
                pDongleInfo = (DONGLE_INFO)Marshal.PtrToStructure((IntPtr)(UInt32)pt, typeof(DONGLE_INFO));
                if (pDongleInfo.m_PID != CodyMasterPid)
                {
                    this.Init();
                }
            }

            uint hDongle = 0;

            RockeyArmHelper.OpenRockey(ref hDongle, 0);
            RockeyArmHelper.VerifyPIN(hDongle, CodyMasterPin);
            RockeyArmHelper.WriteData(hDongle, datas);

            RockeyArmHelper.CloseRockey(hDongle);
            return(pDongleInfo);
        }
        public static void RFS(uint hDongle)
        {
            uint ret = RockeyArmHelper.Dongle_RFS(hDongle);

            if (ret != 0)
            {
                throw new Exception(RockeyArmHelper.GetErrorInfo(ret));
            }
        }
        public static void OpenRockey(ref uint hDongle, int index)
        {
            uint ret = RockeyArmHelper.Dongle_Open(ref hDongle, index);

            if (ret != 0)
            {
                throw new Exception(RockeyArmHelper.GetErrorInfo(ret));
            }
        }
        public static void VerifyPIN(uint hDongle, byte[] sPin)
        {
            int  uiRemainCount = 0;
            uint ret           = RockeyArmHelper.Dongle_VerifyPIN(hDongle, DongleDef.FLAG_ADMINPIN, sPin, out uiRemainCount);

            if (ret != 0)
            {
                throw new Exception(RockeyArmHelper.GetErrorInfo(ret));
            }
        }
        public static void GenUniqueKey(uint hDongle, byte[] seed)
        {
            byte[] cPid      = new byte[9];
            byte[] cAdminPin = new byte[17];
            var    ret       = RockeyArmHelper.Dongle_GenUniqueKey(hDongle, seed.Length, seed, cPid, cAdminPin);

            if (ret != 0)
            {
                throw new Exception(RockeyArmHelper.GetErrorInfo(ret));
            }
        }
        public static IntPtr EnumRockeyArm(out ushort pCount)
        {
            IntPtr pt  = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(DONGLE_INFO)) * 64);
            uint   ret = Dongle_Enum(pt, out pCount);

            if (ret != 0)
            {
                throw new Exception(RockeyArmHelper.GetErrorInfo(ret));
            }

            return(pt);
        }
        public static byte[] ReadData(uint hDongle, int index, int length)
        {
            //写数据区,匿名和用户权限可写前4k(0~4095),开发商有所有8k的写权限
            byte[] datas = new byte[length];//数据区总大小8k
            uint   ret   = RockeyArmHelper.Dongle_ReadData(hDongle, 4096 + index, datas, length);

            if (ret != 0)
            {
                throw new Exception(RockeyArmHelper.GetErrorInfo(ret));
            }

            return(datas);
        }
        public PQEXCustomerInfo ReadCustomerInfo(out string error)
        {
            var result = this.ReadCustomerInfo((int)CodySystemTypeEnum.PQEX, out error);
            CodyPQEXRockeyArm codyPQEXRockeyArm = SmartSerializeHelper.DeserializeObject <CodyPQEXRockeyArm>(result.ObjDatas, CodyPQEXRockeyArm.LoadObj);

            return(new PQEXCustomerInfo()
            {
                CustomerKey = codyPQEXRockeyArm.CustomerKey,
                CustomerName = codyPQEXRockeyArm.CustomerName,
                CodySystemType = (int)CodySystemTypeEnum.PQEX,
                EmpowerDate = codyPQEXRockeyArm.EmpowerDate,
                HId = RockeyArmHelper.GetHIdStr(result.PDongleInfo)
            });
        }
        public static void WriteData(uint hDongle, byte[] datas)
        {
            if (datas.Length > 4096)
            {
                throw new Exception("写入的内容字节长度不能超过4096!");
            }

            uint ret = RockeyArmHelper.Dongle_WriteData(hDongle, 4096, datas, datas.Length);

            if (ret != 0)
            {
                throw new Exception(RockeyArmHelper.GetErrorInfo(ret));
            }
        }
        /// <summary>
        /// 读取指定Cody系统类型的加密锁
        /// </summary>
        internal ReadCustomerInfoResult ReadCustomerInfo(int codySystemType, out string error)
        {
            try
            {
                ushort pCount = 0;
                var    pt     = RockeyArmHelper.EnumRockeyArm(out pCount);

                for (int i = 0; i < pCount; i++)
                {
                    DONGLE_INFO pDongleInfo = (DONGLE_INFO)Marshal.PtrToStructure((IntPtr)((UInt32)pt + i * Marshal.SizeOf(typeof(DONGLE_INFO))), typeof(DONGLE_INFO));

                    if (pDongleInfo.m_PID == CodyMasterPid)//只读取CodyMaster初始化过的加密锁
                    {
                        uint hDongle = 0;
                        RockeyArmHelper.OpenRockey(ref hDongle, i);
                        byte[] datas      = RockeyArmHelper.ReadData(hDongle, 0, 4);
                        int    systemType = BitConverter.ToInt32(datas, 0);

                        if (systemType == codySystemType)
                        {
                            byte[] objDatas = RockeyArmHelper.ReadData(hDongle, 4);

                            error = string.Empty;
                            RockeyArmHelper.CloseRockey(hDongle);
                            return(new ReadCustomerInfoResult()
                            {
                                PDongleInfo = pDongleInfo,
                                ObjDatas = objDatas
                            });
                        }
                        else
                        {
                            RockeyArmHelper.CloseRockey(hDongle);
                        }
                    }
                }

                error = "没有找到针对此系统的加密锁!";
                return(null);
            }
            catch (Exception ex)
            {
                error = ex.Message;
                return(null);
            }
        }
        public static string ReadCustomerInfoStr(out string error)
        {
            try
            {
                ushort pCount = 0;
                var    pt     = RockeyArmHelper.EnumRockeyArm(out pCount);

                string strInfo = string.Format("共找到{0}个加密锁.", pCount);
                for (int i = 0; i < pCount; i++)
                {
                    DONGLE_INFO pDongleInfo = (DONGLE_INFO)Marshal.PtrToStructure((IntPtr)((UInt32)pt + i * Marshal.SizeOf(typeof(DONGLE_INFO))), typeof(DONGLE_INFO));

                    if (pDongleInfo.m_PID == CodyMasterPid)//只读取CodyMaster初始化过的加密锁
                    {
                        uint hDongle = 0;
                        RockeyArmHelper.OpenRockey(ref hDongle, i);
                        byte[] datas      = RockeyArmHelper.ReadData(hDongle, 0, 4);
                        int    systemType = BitConverter.ToInt32(datas, 0);

                        byte[] objDatas = RockeyArmHelper.ReadData(hDongle, 4);

                        if (systemType == (int)CodySystemTypeEnum.PQ)
                        {
                            var rockeyArm = SmartSerializeHelper.DeserializeObject <CodyPQRockeyArm>(objDatas, CodyPQRockeyArm.LoadObj);
                            strInfo += string.Format("\r\n----------第{0}个----------\r\n{1}", i + 1, rockeyArm.GetInfo());
                        }
                        else if (systemType == (int)CodySystemTypeEnum.Cert)
                        {
                            var rockeyArm = SmartSerializeHelper.DeserializeObject <CodyCertRockeyArm>(objDatas, CodyCertRockeyArm.LoadObj);
                            strInfo += string.Format("\r\n----------第{0}个----------\r\n{1}", i + 1, rockeyArm.GetInfo());
                        }

                        RockeyArmHelper.CloseRockey(hDongle);
                    }
                }

                error = string.Empty;
                return(strInfo);
            }
            catch (Exception ex)
            {
                error = ex.Message;
                return(null);
            }
        }
        public CertCustomerInfo ReadCustomerInfo(out string error)
        {
            var result = this.ReadCustomerInfo((int)CodySystemTypeEnum.Cert, out error);

            if (!string.IsNullOrEmpty(error))
            {
                return(null);
            }

            var rockeyArm = SmartSerializeHelper.DeserializeObject <CodyCertRockeyArm>(result.ObjDatas, CodyCertRockeyArm.LoadObj);

            return(new CertCustomerInfo()
            {
                CustomerKey = rockeyArm.CustomerKey,
                CustomerName = rockeyArm.CustomerName,
                CodySystemType = (int)CodySystemTypeEnum.Cert,
                EmpowerDate = rockeyArm.EmpowerDate,
                HId = RockeyArmHelper.GetHIdStr(result.PDongleInfo),
                OperatorLimit = rockeyArm.OperatorLimit
            });
        }
        public static byte[] ReadData(uint hDongle, int index)
        {
            //写数据区,匿名和用户权限可写前4k(0~4095),开发商有所有8k的写权限
            byte[] dataLengthBytes = new byte[4];//数据区总大小8k
            uint   ret1            = RockeyArmHelper.Dongle_ReadData(hDongle, 4096 + index, dataLengthBytes, 4);

            if (ret1 != 0)
            {
                throw new Exception(RockeyArmHelper.GetErrorInfo(ret1));
            }
            int dataLength = BitConverter.ToInt32(dataLengthBytes, 0);

            byte[] datas = new byte[dataLength];//数据区总大小8k
            uint   ret2  = RockeyArmHelper.Dongle_ReadData(hDongle, 4100 + index, datas, datas.Length);

            if (ret2 != 0)
            {
                throw new Exception(RockeyArmHelper.GetErrorInfo(ret2));
            }

            return(datas);
        }
        public string WriteCustomerInfo(int codySystemType, byte[] infoBytes, out string error)
        {
            //byte[] datas = SmartSerializeHelper.SerializeObject(obj, CodyPQRockeyArm.LoadBytes, false);
            List <byte> byteList = new List <byte>();

            byteList.AddRange(BitConverter.GetBytes(codySystemType));
            byteList.AddRange(BitConverter.GetBytes(infoBytes.Length));
            byteList.AddRange(infoBytes);

            try
            {
                DONGLE_INFO pDongleInfo = this.WriteData(byteList.ToArray());
                string      hId         = RockeyArmHelper.GetHIdStr(pDongleInfo);//回写设备Id

                error = string.Empty;
                return(hId);
            }
            catch (Exception ex)
            {
                error = ex.Message;
                return(string.Empty);
            }
        }