using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;

namespace Team.Utility
{

    //公共函数说明
    //***查找加密锁 
    //int FindPort(int start, ref string OutKeyPath);

    //查找指定的加密锁(使用普通算法一)
    //int FindPort_2(int start, int in_data, int verf_data, ref string OutKeyPath);

    //***获到锁的版本
    //int NT_GetIDVersion(ref short version,  string KeyPath);

    //获到锁的扩展版本
    //int NT_GetIDVersionEx(ref short version,  string KeyPath);

    //***获到锁的ID
    //int GetID(ref int id_1, ref int id_2, string KeyPath);

    //***从加密锁中读取一批字节
    //int YReadEx(byte[] OutData, short Address, short mylen, string HKey, string LKey, string KeyPath);

    //***从加密锁中读取一个字节数据,一般不使用
    //int YRead(ref byte OutData, short Address,string HKey, string LKey, string KeyPath);

    //***写一批字节到加密锁中
    //int YWriteEx(byte[] InData, short Address, short mylen, string HKey, string LKey, string KeyPath);

    //***写一个字节的数据到加密锁中,一般不使用
    //int YWrite(byte InData, short Address, string HKey, string LKey, string KeyPath);

    //***从加密锁中读字符串
    //int YReadString(ref string outstring, short Address, short mylen, string HKey, string LKey, string KeyPath);

    //***写字符串到加密锁中
    //int YWriteString(string InString, short Address, string HKey, string LKey, string KeyPath);

    //***算法函数
    //int sWriteEx(int in_data , ref int out_data , string KeyPath);
    //int sWrite_2Ex(int in_data , ref int out_data ,string KeyPath);
    //int sRead(ref int in_data, string KeyPath);
    //int sWrite(int out_data, string KeyPath);
    //int sWrite_2(int out_data, string KeyPath);

    //***设置写密码
    //int SetWritePassword(string W_HKey, string W_LKey, string new_HKey, string new_LKey, string KeyPath);

    //***设置读密码
    //int SetReadPassword(string W_HKey, string W_LKey, string new_HKey, string new_LKey, string KeyPath);

    //'设置增强算法密钥一
    //int SetCal_2(string Key , string KeyPath);

    //使用增强算法一对字符串进行加密
    //int EncString(string InString , ref string outstring , string KeyPath);

    //使用增强算法一对二进制数据进行加密
    // int Cal(byte[] InBuf, byte[] OutBuf, string KeyPath);

    //'设置增强算法密钥二
    //int SetCal_New(string Key , string KeyPath);

    //使用增强算法二对字符串进行加密
    //int EncString_New(string InString , ref string outstring , string KeyPath);

    //使用增强算法二对二进制数据进行加密
    // int Cal_New(byte[] InBuf, byte[] OutBuf, string KeyPath);

    //***初始化加密锁函数
    //int ReSet( string Path);

    //***获取字符串长度
    //int lstrlenA(string InString );

    public struct GUID
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public byte[] Data1;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Data2;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
        public byte[] Data3;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] Data4;
    }

    public struct SP_INTERFACE_DEVICE_DATA
    {
        public int cbSize;
        public GUID InterfaceClassGuid;
        public int Flags;
        public IntPtr Reserved;
    }



    public struct SP_DEVINFO_DATA
    {
        public int cbSize;
        public GUID ClassGuid;
        public int DevInst;
        public IntPtr Reserved;
    }


    public struct SP_DEVICE_INTERFACE_DETAIL_DATA
    {
        public int cbSize;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
        public byte[] DevicePath;
    }


    public struct HIDD_ATTRIBUTES
    {
        public int Size;
        public ushort VendorID;
        public ushort ProductID;
        public ushort VersionNumber;
    }


    public struct HIDP_CAPS
    {
        public short Usage;
        public short UsagePage;
        public short InputReportByteLength;
        public short OutputReportByteLength;
        public short FeatureReportByteLength;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public short[] Reserved;

        public short NumberLinkCollectionNodes;
        public short NumberInputButtonCaps;
        public short NumberInputValueCaps;
        public short NumberInputDataIndices;
        public short NumberOutputButtonCaps;
        public short NumberOutputValueCaps;
        public short NumberOutputDataIndices;
        public short NumberFeatureButtonCaps;
        public short NumberFeatureValueCaps;
        public short NumberFeatureDataIndices;
    }

    public class SoftKey
    {
        private const ushort VID = 0x3689;
        private const ushort PID = 0x8762;
        private const ushort PID_NEW = 0X2020;
        private const ushort VID_NEW = 0X3689;
        private const ushort PID_NEW_2 = 0X2020;
        private const ushort VID_NEW_2 = 0X2020;
        private const short DIGCF_PRESENT = 0x2;
        private const short DIGCF_DEVICEINTERFACE = 0x10;
        private const short INVALID_HANDLE_VALUE = (-1);
        private const short ERROR_NO_MORE_ITEMS = 259;

        private const uint GENERIC_READ = 0x80000000;
        private const int GENERIC_WRITE = 0x40000000;
        private const uint FILE_SHARE_READ = 0x1;
        private const uint FILE_SHARE_WRITE = 0x2;
        private const uint OPEN_EXISTING = 3;
        private const uint FILE_ATTRIBUTE_NORMAL = 0x80;
        private const uint INFINITE = 0xFFFF;

        private const short MAX_LEN = 495;

        public const int FAILEDGENKEYPAIR = -21;
        public const int FAILENC = -22;
        public const int FAILDEC = -23;
        public const int FAILPINPWD = -24;
        public const int USBStatusFail = -50; //USB操作失败,可能是没有找到相关的指令

        public const int SM2_ADDBYTE = 97; //加密后的数据会增加的长度
        public const int MAX_ENCLEN = 128; //最大的加密长度分组
        public const int MAX_DECLEN = (MAX_ENCLEN + SM2_ADDBYTE); //最大的解密长度分组
        public const int SM2_USENAME_LEN = 80; // '最大的用户名长度


        public const int ECC_MAXLEN = 32;
        public const int PIN_LEN = 16;

        private const byte GETVERSION = 0x01;
        private const byte GETID = 0x02;
        private const byte GETVEREX = 0x05;
        private const byte CAL_TEA = 0x08;
        private const byte SET_TEAKEY = 0x09;
        private const byte READBYTE = 0x10;
        private const byte WRITEBYTE = 0x11;
        private const byte YTREADBUF = 0x12;
        private const byte YTWRITEBUF = 0x13;
        private const byte MYRESET = 0x20;
        private const byte YTREBOOT = 0x24;
        private const byte SET_ECC_PARA = 0x30;
        private const byte GET_ECC_PARA = 0x31;
        private const byte SET_ECC_KEY = 0x32;
        private const byte GET_ECC_KEY = 0x33;
        private const byte MYENC = 0x34;
        private const byte MYDEC = 0X35;
        private const byte SET_PIN = 0X36;
        private const byte GEN_KEYPAIR = 0x37;
        private const byte YTSIGN = 0x51;
        private const byte YTVERIFY = 0x52;
        private const byte GET_CHIPID = 0x53;
        private const byte YTSIGN_2 = 0x53;

        [DllImport("kernel32.dll")]
        public static extern int lstrlenA(string InString);

        [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
        public static extern void CopyStringToByte(byte[] pDest, string pSourceg, int ByteLenr);

        [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")]
        public static extern void CopyByteToString(StringBuilder pDest, byte[] pSource, int ByteLenr);

        [DllImport("HID.dll")]
        private static extern bool HidD_GetAttributes(IntPtr HidDeviceObject, ref HIDD_ATTRIBUTES Attributes);

        [DllImport("HID.dll")]
        private static extern int HidD_GetHidGuid(ref GUID HidGuid);

        [DllImport("HID.dll")]
        private static extern bool HidD_GetPreparsedData(IntPtr HidDeviceObject, ref IntPtr PreparsedData);

        [DllImport("HID.dll")]
        private static extern int HidP_GetCaps(IntPtr PreparsedData, ref HIDP_CAPS Capabilities);

        [DllImport("HID.dll")]
        private static extern bool HidD_FreePreparsedData(IntPtr PreparsedData);

        [DllImport("HID.dll")]
        private static extern bool HidD_SetFeature(IntPtr HidDeviceObject, byte[] ReportBuffer, int ReportBufferLength);

        [DllImport("HID.dll")]
        private static extern bool HidD_GetFeature(IntPtr HidDeviceObject, byte[] ReportBuffer, int ReportBufferLength);

        [DllImport("SetupApi.dll")]
        private static extern IntPtr
            SetupDiGetClassDevsA(ref GUID ClassGuid, int Enumerator, int hwndParent, int Flags);

        [DllImport("SetupApi.dll")]
        private static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);

        [DllImport("SetupApi.dll")]
        private static extern bool SetupDiGetDeviceInterfaceDetailA(IntPtr DeviceInfoSet,
            ref SP_INTERFACE_DEVICE_DATA DeviceInterfaceData,
            ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData, int DeviceInterfaceDetailDataSize,
            ref int RequiredSize, int DeviceInfoData);

        [DllImport("SetupApi.dll")]
        private static extern bool SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, int DeviceInfoData,
            ref GUID InterfaceClassGuid, int MemberIndex, ref SP_INTERFACE_DEVICE_DATA DeviceInterfaceData);

        [DllImport("kernel32.dll", EntryPoint = "CreateFileA")]
        private static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode,
            uint lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, uint hTemplateFile);

        [DllImport("kernel32.dll")]
        private static extern int CloseHandle(IntPtr hObject);

        [DllImport("kernel32.dll")]
        private static extern int GetLastError();


        [DllImport("kernel32.dll", EntryPoint = "CreateSemaphoreA")]
        private static extern IntPtr CreateSemaphore(int lpSemaphoreAttributes, int lInitialCount, int lMaximumCount,
            string lpName);

        [DllImport("kernel32.dll")]
        private static extern int WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);

        [DllImport("kernel32.dll")]
        private static extern int ReleaseSemaphore(IntPtr hSemaphore, int lReleaseCount, int lpPreviousCount);



        //以下函数用于将字节数组转化为宽字符串
        private static string ByteConvertString(byte[] buffer)
        {
            char[] null_string = {'\0', '\0'};
            System.Text.Encoding encoding = System.Text.Encoding.Default;
            return encoding.GetString(buffer).TrimEnd(null_string);
        }

        //以下用于将16进制字符串转化为无符号长整型
        private uint HexToInt(string s)
        {
            string[] hexch =
            {
                "0", "1", "2", "3", "4", "5", "6", "7",
                "8", "9", "A", "B", "C", "D", "E", "F"
            };
            s = s.ToUpper();
            int i, j;
            int r, n, k;
            string ch;

            k = 1;
            r = 0;
            for (i = s.Length; i > 0; i--)
            {
                ch = s.Substring(i - 1, 1);
                n = 0;
                for (j = 0; j < 16; j++)
                    if (ch == hexch[j])
                        n = j;
                r += (n * k);
                k *= 16;
            }

            return unchecked((uint) r);
        }

        private int HexStringToByteArray(string InString, ref byte[] b)
        {
            int nlen;
            int retutn_len;
            int n, i;
            string temp;
            nlen = InString.Length;
            if (nlen < 16) retutn_len = 16;
            retutn_len = nlen / 2;
            b = new byte[retutn_len];
            i = 0;
            for (n = 0; n < nlen; n = n + 2)
            {
                temp = InString.Substring(n, 2);
                b[i] = (byte) HexToInt(temp);
                i = i + 1;
            }

            return retutn_len;
        }


        public void EnCode(byte[] inb, byte[] outb, string Key)
        {

            uint cnDelta, y, z, a, b, c, d, temp_2;
            uint[] buf = new uint[16];
            int n, i, nlen;
            uint sum;
            //UInt32 temp, temp_1;
            string temp_string;


            cnDelta = 2654435769;
            sum = 0;

            nlen = Key.Length;
            i = 0;
            for (n = 1; n <= nlen; n = n + 2)
            {
                temp_string = Key.Substring(n - 1, 2);
                buf[i] = HexToInt(temp_string);
                i = i + 1;
            }

            a = 0;
            b = 0;
            c = 0;
            d = 0;
            for (n = 0; n <= 3; n++)
            {
                a = (buf[n] << (n * 8)) | a;
                b = (buf[n + 4] << (n * 8)) | b;
                c = (buf[n + 4 + 4] << (n * 8)) | c;
                d = (buf[n + 4 + 4 + 4] << (n * 8)) | d;
            }



            y = 0;
            z = 0;
            for (n = 0; n <= 3; n++)
            {
                temp_2 = inb[n];
                y = (temp_2 << (n * 8)) | y;
                temp_2 = inb[n + 4];
                z = (temp_2 << (n * 8)) | z;
            }


            n = 32;

            while (n > 0)
            {
                sum = cnDelta + sum;

                /*temp = (z << 4) & 0xFFFFFFFF;
                temp = (temp + a) & 0xFFFFFFFF;
                temp_1 = (z + sum) & 0xFFFFFFFF;
                temp = (temp ^ temp_1) & 0xFFFFFFFF;
                temp_1 = (z >> 5) & 0xFFFFFFFF;
                temp_1 = (temp_1 + b) & 0xFFFFFFFF;
                temp = (temp ^ temp_1) & 0xFFFFFFFF;
                temp = (temp + y) & 0xFFFFFFFF;
                y = temp & 0xFFFFFFFF;*/
                y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);

                /*temp = (y << 4) & 0xFFFFFFFF;
                temp = (temp + c) & 0xFFFFFFFF;
                temp_1 = (y + sum) & 0xFFFFFFFF;
                temp = (temp ^ temp_1) & 0xFFFFFFFF;
                temp_1 = (y >> 5) & 0xFFFFFFFF;
                temp_1 = (temp_1 + d) & 0xFFFFFFFF;
                temp = (temp ^ temp_1) & 0xFFFFFFFF;
                temp = (z + temp) & 0xFFFFFFFF;
                z = temp & 0xFFFFFFFF;*/
                z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
                n = n - 1;

            }

            for (n = 0; n <= 3; n++)
            {
                outb[n] = System.Convert.ToByte((y >> (n * 8)) & 255);
                outb[n + 4] = System.Convert.ToByte((z >> (n * 8)) & 255);
            }

        }

        public void DeCode(byte[] inb, byte[] outb, string Key)
        {

            uint cnDelta, y, z, a, b, c, d, temp_2;
            uint[] buf = new uint[16];
            int n, i, nlen;
            uint sum;
            //UInt32 temp, temp_1;
            string temp_string;


            cnDelta = 2654435769;
            sum = 0xC6EF3720;

            nlen = Key.Length;
            i = 0;
            for (n = 1; n <= nlen; n = n + 2)
            {
                temp_string = Key.Substring(n - 1, 2);
                buf[i] = HexToInt(temp_string);
                i = i + 1;
            }

            a = 0;
            b = 0;
            c = 0;
            d = 0;
            for (n = 0; n <= 3; n++)
            {
                a = (buf[n] << (n * 8)) | a;
                b = (buf[n + 4] << (n * 8)) | b;
                c = (buf[n + 4 + 4] << (n * 8)) | c;
                d = (buf[n + 4 + 4 + 4] << (n * 8)) | d;
            }



            y = 0;
            z = 0;
            for (n = 0; n <= 3; n++)
            {
                temp_2 = inb[n];
                y = (temp_2 << (n * 8)) | y;
                temp_2 = inb[n + 4];
                z = (temp_2 << (n * 8)) | z;
            }


            n = 32;

            while (n-- > 0)
            {
                z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
                y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
                sum -= cnDelta;

            }

            for (n = 0; n <= 3; n++)
            {
                outb[n] = System.Convert.ToByte((y >> (n * 8)) & 255);
                outb[n + 4] = System.Convert.ToByte((z >> (n * 8)) & 255);
            }

        }


        public string StrEnc(string inString, string key) //使用增强算法,加密字符串
        {

            byte[] b, outb;
            byte[] temp = new byte[8], outtemp = new byte[8];
            int n, i, nlen, outlen;
            string outstring;


            nlen = lstrlenA(inString) + 1;
            if (nlen < 8)
                outlen = 8;
            else
                outlen = nlen;
            b = new byte[outlen];
            outb = new byte[outlen];

            CopyStringToByte(b, inString, nlen);

            b.CopyTo(outb, 0);

            for (n = 0; n <= outlen - 8; n = n + 8)
            {
                for (i = 0; i < 8; i++) temp[i] = b[i + n];
                EnCode(temp, outtemp, key);
                for (i = 0; i < 8; i++) outb[i + n] = outtemp[i];
            }

            outstring = "";
            for (n = 0; n <= outlen - 1; n++)
            {
                outstring = outstring + outb[n].ToString("X2");
            }

            return outstring;
        }

        public string StrDec(string inString, string key) //使用增强算法,加密字符串
        {
            byte[] b, outb;
            byte[] temp = new byte[8], outtemp = new byte[8];
            int n, i, nlen, outlen;
            string temp_string;
            StringBuilder c_str;


            nlen = inString.Length;
            if (nlen < 16) outlen = 16;
            outlen = nlen / 2;
            b = new byte[outlen];
            outb = new byte[outlen];

            i = 0;
            for (n = 1; n <= nlen; n = n + 2)
            {
                temp_string = inString.Substring(n - 1, 2);
                b[i] = System.Convert.ToByte(HexToInt(temp_string));
                i = i + 1;
            }

            b.CopyTo(outb, 0);

            for (n = 0; n <= outlen - 8; n = n + 8)
            {
                for (i = 0; i < 8; i++) temp[i] = b[i + n];
                DeCode(temp, outtemp, key);
                for (i = 0; i < 8; i++) outb[i + n] = outtemp[i];
            }

            c_str = new StringBuilder("", outlen);
            CopyByteToString(c_str, outb, outlen);
            return c_str.ToString();

        }

        private bool isfindmydevice(int pos, ref int count, ref string OutPath)
        {

            return Subisfindmydevice(pos, ref count, ref OutPath);

        }



        private bool Subisfindmydevice(int pos, ref int count, ref string OutPath)
        {
            IntPtr hardwareDeviceInfo;
            SP_INTERFACE_DEVICE_DATA DeviceInfoData = new SP_INTERFACE_DEVICE_DATA();
            int i;
            GUID HidGuid = new GUID();
            SP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData = new SP_DEVICE_INTERFACE_DETAIL_DATA();
            int requiredLength;
            IntPtr d_handle;
            HIDD_ATTRIBUTES Attributes = new HIDD_ATTRIBUTES();

            i = 0;
            count = 0;
            HidD_GetHidGuid(ref HidGuid);

            hardwareDeviceInfo = SetupDiGetClassDevsA(ref HidGuid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

            if (hardwareDeviceInfo == (IntPtr) INVALID_HANDLE_VALUE) return false;

            DeviceInfoData.cbSize = Marshal.SizeOf(DeviceInfoData);

            while (SetupDiEnumDeviceInterfaces(hardwareDeviceInfo, 0, ref HidGuid, i, ref DeviceInfoData))
            {
                if (GetLastError() == ERROR_NO_MORE_ITEMS) break;
                if (System.IntPtr.Size == 4)
                    functionClassDeviceData.cbSize = Marshal.SizeOf(functionClassDeviceData) - 255; // 5;
                else
                    functionClassDeviceData.cbSize = 8;
                requiredLength = 0;
                if (!SetupDiGetDeviceInterfaceDetailA(hardwareDeviceInfo, ref DeviceInfoData,
                    ref functionClassDeviceData, 300, ref requiredLength, 0))
                {
                    SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
                    return false;
                }

                OutPath = ByteConvertString(functionClassDeviceData.DevicePath);
                d_handle = CreateFile(OutPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
                    OPEN_EXISTING, 0, 0);
                if ((IntPtr) INVALID_HANDLE_VALUE != d_handle)
                {
                    if (HidD_GetAttributes(d_handle, ref Attributes))
                    {
                        if ((Attributes.ProductID == PID) && (Attributes.VendorID == VID) ||
                            (Attributes.ProductID == PID_NEW) && (Attributes.VendorID == VID_NEW) ||
                            (Attributes.ProductID == PID_NEW_2) && (Attributes.VendorID == VID_NEW_2))
                        {
                            if (pos == count)
                            {
                                SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
                                CloseHandle(d_handle);
                                return true;
                            }

                            count = count + 1;
                        }
                    }

                    CloseHandle(d_handle);
                }

                i = i + 1;

            }

            SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
            return false;
        }

        private bool GetFeature(IntPtr hDevice, byte[] array_out, int out_len)
        {

            bool FeatureStatus;
            bool Status;
            int i;
            byte[] FeatureReportBuffer = new byte[512];
            IntPtr Ppd = System.IntPtr.Zero;
            HIDP_CAPS Caps = new HIDP_CAPS();

            if (!HidD_GetPreparsedData(hDevice, ref Ppd)) return false;

            if (HidP_GetCaps(Ppd, ref Caps) <= 0)
            {
                HidD_FreePreparsedData(Ppd);
                return false;
            }

            Status = true;

            FeatureReportBuffer[0] = 1;

            FeatureStatus = HidD_GetFeature(hDevice, FeatureReportBuffer, Caps.FeatureReportByteLength);
            if (FeatureStatus)
            {
                for (i = 0; i < out_len; i++)
                {
                    array_out[i] = FeatureReportBuffer[i];
                }
            }


            Status = Status && FeatureStatus;
            HidD_FreePreparsedData(Ppd);

            return Status;

        }

        private bool SetFeature(IntPtr hDevice, byte[] array_in, int in_len)
        {
            bool FeatureStatus;
            bool Status;
            int i;
            byte[] FeatureReportBuffer = new byte[512];
            IntPtr Ppd = System.IntPtr.Zero;
            HIDP_CAPS Caps = new HIDP_CAPS();

            if (!HidD_GetPreparsedData(hDevice, ref Ppd)) return false;

            if (HidP_GetCaps(Ppd, ref Caps) <= 0)
            {
                HidD_FreePreparsedData(Ppd);
                return false;
            }

            Status = true;

            FeatureReportBuffer[0] = 2;

            for (i = 0; i < in_len; i++)
            {
                FeatureReportBuffer[i + 1] = array_in[i + 1];

            }

            FeatureStatus = HidD_SetFeature(hDevice, FeatureReportBuffer, Caps.FeatureReportByteLength);


            Status = Status && FeatureStatus;
            HidD_FreePreparsedData(Ppd);

            return Status;

        }

        private int NT_FindPort(int start, ref string OutPath)
        {
            int count = 0;
            if (!isfindmydevice(start, ref count, ref OutPath))
            {
                return -92;
            }

            return 0;
        }

        private int NT_FindPort_2(int start, int in_data, int verf_data, ref string OutPath)
        {
            int count = 0;
            int pos;
            int out_data = 0;
            int ret;
            for (pos = start; pos < 256; pos++)
            {
                if (!isfindmydevice(pos, ref count, ref OutPath)) return -92;
                ret = WriteDword(in_data, OutPath);
                if (ret != 0) continue;
                ret = ReadDword(ref out_data, OutPath);
                if (ret != 0) continue;
                if (out_data == verf_data)
                {
                    return 0;
                }
            }

            return (-92);
        }

        private int OpenMydivece(ref IntPtr hUsbDevice, string Path)
        {
            string OutPath;
            bool biao;
            int count = 0;
            if (Path.Length < 1)
            {
                OutPath = "";
                biao = isfindmydevice(0, ref count, ref OutPath);
                if (!biao) return -92;
                hUsbDevice = CreateFile(OutPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
                if (hUsbDevice == (IntPtr) INVALID_HANDLE_VALUE) return -92;
            }
            else
            {
                hUsbDevice = CreateFile(Path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
                if (hUsbDevice == (IntPtr) INVALID_HANDLE_VALUE) return -92;
            }

            return 0;
        }

        private int NT_Read(ref byte ele1, ref byte ele2, ref byte ele3, ref byte ele4, string Path)
        {
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            if (!GetFeature(hUsbDevice, array_out, 5))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            ele1 = array_out[0];
            ele2 = array_out[1];
            ele3 = array_out[2];
            ele4 = array_out[3];
            return 0;
        }

        private int NT_Write(byte ele1, byte ele2, byte ele3, byte ele4, string Path)
        {
            byte[] array_in = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0)
            {
                return -92;
            }

            array_in[1] = 3;
            array_in[2] = ele1;
            array_in[3] = ele2;
            array_in[4] = ele3;
            array_in[5] = ele4;
            if (!SetFeature(hUsbDevice, array_in, 5))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            return 0;
        }

        private int NT_Write_2(byte ele1, byte ele2, byte ele3, byte ele4, string Path)
        {
            byte[] array_in = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 4;
            array_in[2] = ele1;
            array_in[3] = ele2;
            array_in[4] = ele3;
            array_in[5] = ele4;
            if (!SetFeature(hUsbDevice, array_in, 5))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            return 0;
        }

        private int GetIDVersion(ref short Version, string Path)
        {
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 1;
            if (!SetFeature(hUsbDevice, array_in, 1))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 1))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            Version = array_out[0];
            return 0;
        }

        private int NT_GetID(ref int ID_1, ref int ID_2, string Path)
        {
            int[] t = new int[8];
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 2;
            if (!SetFeature(hUsbDevice, array_in, 1))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 8))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            t[0] = array_out[0];
            t[1] = array_out[1];
            t[2] = array_out[2];
            t[3] = array_out[3];
            t[4] = array_out[4];
            t[5] = array_out[5];
            t[6] = array_out[6];
            t[7] = array_out[7];
            ID_1 = t[3] | (t[2] << 8) | (t[1] << 16) | (t[0] << 24);
            ID_2 = t[7] | (t[6] << 8) | (t[5] << 16) | (t[4] << 24);
            return 0;
        }


        private int Y_Read(byte[] OutData, int address, int nlen, byte[] password, string Path, int pos)
        {
            int addr_l;
            int addr_h;
            int n;
            byte[] array_in = new byte[512];
            byte[] array_out = new byte[512];
            if ((address > MAX_LEN) || (address < 0)) return -81;
            if ((nlen > 255)) return -87;
            if ((nlen + address) > MAX_LEN) return -88;
            addr_h = (address >> 8) * 2;
            addr_l = address & 255;
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;

            array_in[1] = 0x12;
            array_in[2] = (byte) addr_h;
            array_in[3] = (byte) addr_l;
            array_in[4] = (byte) nlen;
            for (n = 0; n <= 7; n++)
            {
                array_in[5 + n] = password[n];
            }

            if (!SetFeature(hUsbDevice, array_in, 13))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, nlen + 1))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0)
            {
                return -83;
            }

            for (n = 0; n < nlen; n++)
            {
                OutData[n + pos] = array_out[n + 1];
            }

            return 0;
        }

        private int Y_Write(byte[] indata, int address, int nlen, byte[] password, string Path, int pos)
        {
            int addr_l;
            int addr_h;
            int n;
            byte[] array_in = new byte[512];
            byte[] array_out = new byte[512];
            if ((nlen > 255)) return -87;
            if ((address + nlen - 1) > (MAX_LEN + 17) || (address < 0)) return -81;
            addr_h = (address >> 8) * 2;
            addr_l = address & 255;
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 0x13;
            array_in[2] = (byte) addr_h;
            array_in[3] = (byte) addr_l;
            array_in[4] = (byte) nlen;
            for (n = 0; n <= 7; n++)
            {
                array_in[5 + n] = password[n];
            }

            for (n = 0; n < nlen; n++)
            {
                array_in[13 + n] = indata[n + pos];
            }

            if (!SetFeature(hUsbDevice, array_in, 13 + nlen))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 2))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0)
            {
                return -82;
            }

            return 0;
        }

        private int NT_Cal(byte[] InBuf, byte[] outbuf, string Path, int pos)
        {
            int n;
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 8;
            for (n = 2; n <= 9; n++)
            {
                array_in[n] = InBuf[n - 2 + pos];
            }

            if (!SetFeature(hUsbDevice, array_in, 9))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 9))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            for (n = 0; n < 8; n++)
            {
                outbuf[n + pos] = array_out[n];
            }

            if (array_out[8] != 0x55)
            {
                return -20;
            }

            return 0;
        }

        private int NT_SetCal_2(byte[] indata, byte IsHi, string Path, short pos)
        {

            int n;
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 9;
            array_in[2] = IsHi;
            for (n = 0; n < 8; n++)
            {
                array_in[3 + n] = indata[n + pos];
            }

            if (!SetFeature(hUsbDevice, array_in, 11))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 2))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0)
            {
                return -82;
            }

            return 0;
        }

        private int ReadDword(ref int out_data, string Path)
        {
            byte b1 = 0;
            byte b2 = 0;
            byte b3 = 0;
            byte b4 = 0;
            int t1;
            int t2;
            int t3;
            int t4;
            int ret;
            ret = NT_Read(ref b1, ref b2, ref b3, ref b4, Path);
            t1 = b1;
            t2 = b2;
            t3 = b3;
            t4 = b4;
            out_data = t1 | (t2 << 8) | (t3 << 16) | (t4 << 24);
            return ret;
        }

        private int WriteDword(int in_data, string Path)
        {
            byte b1;
            byte b2;
            byte b3;
            byte b4;
            b1 = (byte) (in_data & 255);
            b2 = (byte) ((in_data >> 8) & 255);
            b3 = (byte) ((in_data >> 16) & 255);
            b4 = (byte) ((in_data >> 24) & 255);
            return NT_Write(b1, b2, b3, b4, Path);
        }

        private int WriteDword_2(int in_data, string Path)
        {
            byte b1;
            byte b2;
            byte b3;
            byte b4;
            b1 = (byte) (in_data & 255);
            b2 = (byte) ((in_data >> 8) & 255);
            b3 = (byte) ((in_data >> 16) & 255);
            b4 = (byte) ((in_data >> 24) & 255);
            return NT_Write_2(b1, b2, b3, b4, Path);
        }

        public int NT_GetIDVersion(ref short Version, string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = GetIDVersion(ref Version, Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int GetID(ref int ID_1, ref int ID_2, string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_GetID(ref ID_1, ref ID_2, Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int sRead(ref int in_data, string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = ReadDword(ref in_data, Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int sWrite(int out_data, string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = WriteDword(out_data, Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int YWriteEx(byte[] indata, int address, int nlen, string HKey, string LKey, string Path)
        {
            int ret = 0;
            IntPtr hsignal;
            byte[] password = new byte[8];
            int n, trashLen = 0;
            int leave;
            int temp_leave;
            if ((address + nlen - 1 > MAX_LEN) || (address < 0)) return -81;

            ret = GetTrashBufLen(Path, ref trashLen);
            if (trashLen < 100) trashLen = 16;
            trashLen = trashLen - 8;
            if (ret != 0) return ret;

            myconvert(HKey, LKey, password);
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            temp_leave = address % trashLen;
            leave = trashLen - temp_leave;
            if (leave > nlen) leave = nlen;
            if (leave > 0)
            {
                for (n = 0; n < leave / trashLen; n++)
                {
                    ret = Y_Write(indata, address + n * trashLen, trashLen, password, Path, trashLen * n);
                    if (ret != 0)
                    {
                        ReleaseSemaphore(hsignal, 1, 0);
                        CloseHandle(hsignal);
                        return sub_YWriteEx(indata, address, nlen, HKey, LKey, Path);
                    }
                }

                if (leave - trashLen * n > 0)
                {
                    ret = Y_Write(indata, address + n * trashLen, leave - n * trashLen, password, Path, trashLen * n);
                    if (ret != 0)
                    {
                        ReleaseSemaphore(hsignal, 1, 0);
                        CloseHandle(hsignal);
                        return sub_YWriteEx(indata, address, nlen, HKey, LKey, Path);
                    }
                }
            }

            nlen = nlen - leave;
            address = address + leave;
            if (nlen > 0)
            {

                for (n = 0; n < nlen / trashLen; n++)
                {
                    ret = Y_Write(indata, address + n * trashLen, trashLen, password, Path, leave + trashLen * n);
                    if (ret != 0)
                    {
                        ReleaseSemaphore(hsignal, 1, 0);
                        CloseHandle(hsignal);
                        return sub_YWriteEx(indata, address, nlen, HKey, LKey, Path);
                    }
                }

                if (nlen - trashLen * n > 0)
                {
                    ret = Y_Write(indata, address + n * trashLen, nlen - n * trashLen, password, Path,
                        leave + trashLen * n);
                    if (ret != 0)
                    {
                        ReleaseSemaphore(hsignal, 1, 0);
                        CloseHandle(hsignal);
                        return sub_YWriteEx(indata, address, nlen, HKey, LKey, Path);
                    }
                }
            }

            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int YReadEx(byte[] OutData, short address, short nlen, string HKey, string LKey, string Path)
        {
            int ret = 0;
            IntPtr hsignal;
            byte[] password = new byte[8];
            int n, trashLen = 0;

            if ((address + nlen - 1 > MAX_LEN) || (address < 0)) return (-81);

            ret = GetTrashBufLen(Path, ref trashLen);
            if (trashLen < 100) trashLen = 16;
            if (ret != 0) return ret;


            myconvert(HKey, LKey, password);
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            for (n = 0; n < nlen / trashLen; n++)
            {
                ret = Y_Read(OutData, address + n * trashLen, trashLen, password, Path, n * trashLen);
                if (ret != 0)
                {
                    ReleaseSemaphore(hsignal, 1, 0);
                    CloseHandle(hsignal);
                    return sub_YReadEx(OutData, address, nlen, HKey, LKey, Path);
                }
            }

            if (nlen - trashLen * n > 0)
            {
                ret = Y_Read(OutData, address + n * trashLen, nlen - trashLen * n, password, Path, trashLen * n);
                if (ret != 0)
                {
                    ReleaseSemaphore(hsignal, 1, 0);
                    CloseHandle(hsignal);
                    return sub_YReadEx(OutData, address, nlen, HKey, LKey, Path);
                }
            }

            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int FindPort_2(int start, int in_data, int verf_data, ref string OutPath)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_FindPort_2(start, in_data, verf_data, ref OutPath);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int FindPort(int start, ref string OutPath)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_FindPort(start, ref OutPath);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            Debug.WriteLine(stopwatch.ElapsedMilliseconds);
            return ret;
        }


        public int sWrite_2(int out_data, string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = WriteDword_2(out_data, Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        private string AddZero(string InKey)
        {
            int nlen;
            int n;
            nlen = InKey.Length;
            for (n = nlen; n <= 7; n++)
            {
                InKey = "0" + InKey;
            }

            return InKey;
        }

        private void myconvert(string HKey, string LKey, byte[] out_data)
        {
            HKey = AddZero(HKey);
            LKey = AddZero(LKey);
            int n;
            for (n = 0; n <= 3; n++)
            {
                out_data[n] = (byte) HexToInt(HKey.Substring(n * 2, 2));
            }

            for (n = 0; n <= 3; n++)
            {
                out_data[n + 4] = (byte) HexToInt(LKey.Substring(n * 2, 2));
            }
        }

        public int YRead(ref byte indata, int address, string HKey, string LKey, string Path)
        {
            int ret;
            IntPtr hsignal;
            byte[] ary1 = new byte[8];

            if ((address > 495) || (address < 0)) return -81;
            myconvert(HKey, LKey, ary1);
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = sub_YRead(ref indata, address, ary1, Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        private int sub_YRead(ref byte OutData, int address, byte[] password, string Path)
        {
            int n;
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            byte opcode;
            if ((address > 495) || (address < 0)) return -81;
            opcode = 128;
            if (address > 255)
            {
                opcode = 160;
                address = address - 256;
            }

            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 16;
            array_in[2] = opcode;
            array_in[3] = (byte) address;
            array_in[4] = (byte) address;
            for (n = 0; n < 8; n++)
            {
                array_in[5 + n] = password[n];
            }

            if (!SetFeature(hUsbDevice, array_in, 13))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 2))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 83)
            {
                return -83;
            }

            OutData = array_out[1];
            return 0;
        }

        public int YWrite(byte indata, int address, string HKey, string LKey, string Path)
        {
            int ret;
            IntPtr hsignal;
            byte[] ary1 = new byte[8];

            if ((address > 495) || (address < 0)) return -81;
            myconvert(HKey, LKey, ary1);
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = sub_YWrite(indata, address, ary1, Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        private int sub_YWrite(byte indata, int address, byte[] password, string Path)
        {
            int n;
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            byte opcode;
            if ((address > 511) || (address < 0)) return -81;
            opcode = 64;
            if (address > 255)
            {
                opcode = 96;
                address = address - 256;
            }

            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 17;
            array_in[2] = opcode;
            array_in[3] = (byte) address;
            array_in[4] = indata;
            for (n = 0; n < 8; n++)
            {
                array_in[5 + n] = password[n];
            }

            if (!SetFeature(hUsbDevice, array_in, 13))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 2))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[1] != 1)
            {
                return -82;
            }

            return 0;
        }

        public int SetReadPassword(string W_HKey, string W_LKey, string new_HKey, string new_LKey, string Path)
        {
            int ret;
            IntPtr hsignal;
            byte[] ary1 = new byte[8];
            byte[] ary2 = new byte[8];
            short address;
            myconvert(W_HKey, W_LKey, ary1);
            myconvert(new_HKey, new_LKey, ary2);
            address = 496;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = Y_Write(ary2, address, 8, ary1, Path, 0);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }


        public int SetWritePassword(string W_HKey, string W_LKey, string new_HKey, string new_LKey, string Path)
        {
            int ret;
            IntPtr hsignal;
            byte[] ary1 = new byte[8];
            byte[] ary2 = new byte[8];
            short address;
            myconvert(W_HKey, W_LKey, ary1);
            myconvert(new_HKey, new_LKey, ary2);
            address = 504;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = Y_Write(ary2, address, 8, ary1, Path, 0);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int YWriteString(string InString, int address, string HKey, string LKey, string Path)
        {
            int ret = 0;
            byte[] ary1 = new byte[8];
            IntPtr hsignal;
            int n, trashLen = 0;
            int outlen;
            int total_len;
            int temp_leave;
            int leave;
            byte[] b;
            if ((address < 0)) return -81;

            ret = GetTrashBufLen(Path, ref trashLen);
            if (trashLen < 100) trashLen = 16;
            trashLen = trashLen - 8;
            if (ret != 0) return ret;

            myconvert(HKey, LKey, ary1);

            outlen = lstrlenA(InString); //注意,这里不写入结束字符串,与原来的兼容,也可以写入结束字符串,与原来的不兼容,写入长度会增加1
            b = new byte[outlen];
            CopyStringToByte(b, InString, outlen);

            total_len = address + outlen;
            if (total_len > MAX_LEN) return -47;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            temp_leave = address % trashLen;
            leave = trashLen - temp_leave;
            if (leave > outlen) leave = outlen;

            if (leave > 0)
            {
                for (n = 0; n < (leave / trashLen); n++)
                {
                    ret = Y_Write(b, address + n * trashLen, trashLen, ary1, Path, n * trashLen);
                    if (ret != 0)
                    {
                        ReleaseSemaphore(hsignal, 1, 0);
                        CloseHandle(hsignal);
                        return sub_YWrite_new((InString), address, HKey, LKey, Path);
                    }
                }

                if (leave - trashLen * n > 0)
                {
                    ret = Y_Write(b, address + n * trashLen, leave - n * trashLen, ary1, Path, trashLen * n);
                    if (ret != 0)
                    {
                        ReleaseSemaphore(hsignal, 1, 0);
                        CloseHandle(hsignal);
                        return sub_YWrite_new((InString), address, HKey, LKey, Path);
                    }
                }
            }

            outlen = outlen - leave;
            address = address + leave;
            if (outlen > 0)
            {
                for (n = 0; n < (outlen / trashLen); n++)
                {
                    ret = Y_Write(b, address + n * trashLen, trashLen, ary1, Path, leave + n * trashLen);
                    if (ret != 0)
                    {
                        ReleaseSemaphore(hsignal, 1, 0);
                        CloseHandle(hsignal);
                        return ret;
                    }
                }

                if (outlen - trashLen * n > 0)
                {
                    ret = Y_Write(b, address + n * trashLen, outlen - n * trashLen, ary1, Path, leave + trashLen * n);
                    if (ret != 0)
                    {
                        ReleaseSemaphore(hsignal, 1, 0);
                        CloseHandle(hsignal);
                        return ret;
                    }
                }
            }

            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int YReadString(ref string OutString, int address, int nlen, string HKey, string LKey, string Path)
        {
            int ret = 0;
            byte[] ary1 = new byte[8];
            IntPtr hsignal;
            int n, trashLen = 0;
            int total_len;
            byte[] outb;
            StringBuilder temp_OutString;
            outb = new byte[nlen];
            myconvert(HKey, LKey, ary1);
            if (address < 0) return -81;

            ret = GetTrashBufLen(Path, ref trashLen);
            if (trashLen < 100) trashLen = 16;
            if (ret != 0) return ret;

            total_len = address + nlen;
            if (total_len > MAX_LEN) return -47;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            for (n = 0; n < (nlen / trashLen); n++)
            {
                ret = Y_Read(outb, address + n * trashLen, trashLen, ary1, Path, n * trashLen);
                if (ret != 0)
                {
                    ReleaseSemaphore(hsignal, 1, 0);
                    CloseHandle(hsignal);
                    return sub_YRead_new(ref OutString, address, nlen, HKey, LKey, Path);
                }
            }

            if (nlen - trashLen * n > 0)
            {
                ret = Y_Read(outb, address + n * trashLen, nlen - trashLen * n, ary1, Path, trashLen * n);
                if (ret != 0)
                {
                    ReleaseSemaphore(hsignal, 1, 0);
                    CloseHandle(hsignal);
                    return sub_YRead_new(ref OutString, address, nlen, HKey, LKey, Path);
                }
            }

            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            temp_OutString = new StringBuilder("", nlen);
            //初始化数据为0,注意,这步一定是需要的
            for (n = 0; n < nlen; n++)
            {
                temp_OutString.Append(0);
            }

            CopyByteToString(temp_OutString, outb, nlen);
            OutString = temp_OutString.ToString();
            return ret;
        }

        public int SetCal_2(string Key, string Path)
        {
            int ret;
            IntPtr hsignal;
            byte[] KeyBuf = new byte[16];
            byte[] inb = new byte[8];
            HexStringToByteArray(Key, ref KeyBuf);
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_SetCal_2(KeyBuf, 0, Path, 8);
            if (ret != 0) goto error1;
            ret = NT_SetCal_2(KeyBuf, 1, Path, 0);
            error1:
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int Cal(byte[] InBuf, byte[] outbuf, string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_Cal(InBuf, outbuf, Path, 0);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int EncString(string InString, ref string OutString, string Path)
        {
            IntPtr hsignal;
            byte[] b;
            byte[] outb;
            int n;
            int nlen, temp_len;
            int ret = 0;

            nlen = lstrlenA(InString) + 1;
            temp_len = nlen;
            if (nlen < 8)
            {
                nlen = 8;
            }


            b = new byte[nlen];
            outb = new byte[nlen];

            CopyStringToByte(b, InString, temp_len);

            b.CopyTo(outb, 0);

            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            for (n = 0; n <= (nlen - 8); n = n + 8)
            {
                ret = NT_Cal(b, outb, Path, n);
                if (ret != 0) break;
            }

            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            OutString = "";
            for (n = 0; n < nlen; n++)
            {
                OutString = OutString + outb[n].ToString("X2");
            }

            return ret;

        }

        public int sWriteEx(int in_data, ref int out_data, string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = WriteDword(in_data, Path);
            if (ret != 0) goto error1;
            ret = ReadDword(ref out_data, Path);
            error1:
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int sWrite_2Ex(int in_data, ref int out_data, string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = WriteDword_2(in_data, Path);
            if (ret != 0) goto error1;
            ret = ReadDword(ref out_data, Path);
            error1:
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int ReSet(string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_ReSet(Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        private int NT_ReSet(string Path)
        {
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 32;
            if (!SetFeature(hUsbDevice, array_in, 2))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 2))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0)
            {
                return -82;
            }

            return 0;
        }

        public int SetCal_New(string Key, string Path)
        {
            int ret;
            IntPtr hsignal;
            byte[] KeyBuf = new byte[16];
            byte[] inb = new byte[8];
            HexStringToByteArray(Key, ref KeyBuf);
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_SetCal_New(KeyBuf, 0, Path, 8);
            if (ret != 0) goto error1;
            ret = NT_SetCal_New(KeyBuf, 1, Path, 0);
            error1:
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int Cal_New(byte[] InBuf, byte[] outbuf, string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_Cal_New(InBuf, outbuf, Path, 0);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int EncString_New(string InString, ref string OutString, string Path)
        {
            IntPtr hsignal;
            byte[] b;
            byte[] outb;
            int n;
            int nlen, temp_len;
            int ret = 0;

            nlen = lstrlenA(InString) + 1;
            temp_len = nlen;
            if (nlen < 8)
            {
                nlen = 8;
            }


            b = new byte[nlen];
            outb = new byte[nlen];

            CopyStringToByte(b, InString, temp_len);

            b.CopyTo(outb, 0);

            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            for (n = 0; n <= (nlen - 8); n = n + 8)
            {
                ret = NT_Cal_New(b, outb, Path, n);
                if (ret != 0) break;
            }

            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            OutString = "";
            for (n = 0; n < nlen; n++)
            {
                OutString = OutString + outb[n].ToString("X2");
            }

            return ret;

        }

        public int NT_GetVersionEx(ref short Version, string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = F_GetVersionEx(ref Version, Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        private int NT_Cal_New(byte[] InBuf, byte[] outbuf, string Path, int pos)
        {
            int n;
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 12;
            for (n = 2; n <= 9; n++)
            {
                array_in[n] = InBuf[n - 2 + pos];
            }

            if (!SetFeature(hUsbDevice, array_in, 9))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 9))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            for (n = 0; n < 8; n++)
            {
                outbuf[n + pos] = array_out[n];
            }

            if (array_out[8] != 0x55)
            {
                return -20;
            }

            return 0;
        }

        private int NT_SetCal_New(byte[] indata, byte IsHi, string Path, short pos)
        {

            int n;
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 13;
            array_in[2] = IsHi;
            for (n = 0; n < 8; n++)
            {
                array_in[3 + n] = indata[n + pos];
            }

            if (!SetFeature(hUsbDevice, array_in, 11))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 2))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0)
            {
                return -82;
            }

            return 0;
        }

        private int F_GetVersionEx(ref short Version, string Path)
        {
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 5;
            if (!SetFeature(hUsbDevice, array_in, 1))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 1))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            Version = array_out[0];
            return 0;
        }


        int sub_YRead_new(ref string OutString, int Address, int nlen, string HKey, string LKey, string Path)
        {
            int n, ret = 0;
            byte[] outb;
            StringBuilder temp_OutString;
            outb = new byte[nlen];
            for (n = 0; n < nlen; n++)
            {
                ret = YRead(ref outb[n], Address + n, HKey, LKey, Path);
                if (ret != 0) return ret;
            }

            temp_OutString = new StringBuilder("", nlen);
            //初始化数据为0,注意,这步一定是需要的
            for (n = 0; n < nlen; n++)
            {
                temp_OutString.Append(0);
            }

            CopyByteToString(temp_OutString, outb, nlen);
            OutString = temp_OutString.ToString();
            return ret;
        }

        int sub_YWrite_new(string InString, int Address, string HKey, string LKey, string Path)
        {
            int n, ret = 0;
            byte[] b;
            int outlen = lstrlenA(InString); //注意,这里不写入结束字符串,与原来的兼容,也可以写入结束字符串,与原来的不兼容,写入长度会增加1
            b = new byte[outlen];
            CopyStringToByte(b, InString, outlen);
            for (n = 0; n < outlen; n++)
            {
                ret = YWrite(b[n], Address + n, HKey, LKey, Path);
                if (ret != 0) return ret;
            }

            return ret;
        }

        int sub_YReadEx(byte[] OutData, int Address, int nlen, string HKey, string LKey, string Path)
        {
            int n, ret = 0;
            for (n = 0; n < nlen; n++)
            {
                ret = YRead(ref OutData[n], Address + n, HKey, LKey, Path);
                if (ret != 0) return ret;
            }

            return ret;
        }

        int sub_YWriteEx(byte[] indata, int Address, int len, string HKey, string LKey, string Path)
        {
            int n, ret = 0;
            for (n = 0; n < len; n++)
            {
                ret = YWrite(indata[n], Address + n, HKey, LKey, Path);
                if (ret != 0) return ret;
            }

            return ret;
        }

        public int SetHidOnly(bool IsHidOnly, string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_SetHidOnly(IsHidOnly, Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        private int NT_SetHidOnly(bool IsHidOnly, string Path)
        {
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 0x55;
            if (IsHidOnly) array_in[2] = 0;
            else array_in[2] = 0xff;
            if (!SetFeature(hUsbDevice, array_in, 3))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 1))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0)
            {
                return -82;
            }

            return 0;
        }

        public int SetUReadOnly(string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_SetUReadOnly(Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        private int NT_SetUReadOnly(string Path)
        {
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 0x56;
            if (!SetFeature(hUsbDevice, array_in, 3))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 1))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0)
            {
                return -82;
            }

            return 0;
        }

        private int sub_GetTrashBufLen(IntPtr hDevice, ref int out_len)
        {

            IntPtr Ppd = System.IntPtr.Zero;
            HIDP_CAPS Caps = new HIDP_CAPS();

            if (!HidD_GetPreparsedData(hDevice, ref Ppd)) return -93;

            if (HidP_GetCaps(Ppd, ref Caps) <= 0)
            {
                HidD_FreePreparsedData(Ppd);
                return -93;
            }

            HidD_FreePreparsedData(Ppd);
            out_len = Caps.FeatureReportByteLength - 5;
            return 0;

        }

        private int GetTrashBufLen(string Path, ref int out_len)
        {

            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            int ret = sub_GetTrashBufLen(hUsbDevice, ref out_len);
            CloseHandle(hUsbDevice);
            return ret;

        }

        private int NT_Set_SM2_KeyPair(byte[] PriKey, byte[] PubKeyX, byte[] PubKeyY, byte[] sm2_UerName, string Path)
        {

            byte[] array_in = new byte[256];
            byte[] array_out = new byte[25];
            int n = 0;
            IntPtr hUsbDevice = IntPtr.Zero;

            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 0x32;
            for (n = 0; n < ECC_MAXLEN; n++)
            {
                array_in[2 + n + ECC_MAXLEN * 0] = PriKey[n];
                array_in[2 + n + ECC_MAXLEN * 1] = PubKeyX[n];
                array_in[2 + n + ECC_MAXLEN * 2] = PubKeyY[n];
            }

            for (n = 0; n < SM2_USENAME_LEN; n++)
            {
                array_in[2 + n + ECC_MAXLEN * 3] = sm2_UerName[n];
            }

            if (!SetFeature(hUsbDevice, array_in, ECC_MAXLEN * 3 + SM2_USENAME_LEN + 2))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 2))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0x20) return USBStatusFail;

            return 0;
        }

        private int NT_GenKeyPair(byte[] PriKey, byte[] PubKey, string Path)
        {

            byte[] array_in = new byte[256];
            byte[] array_out = new byte[256];
            int n = 0;
            IntPtr hUsbDevice = IntPtr.Zero;
            array_out[0] = 0xfb;

            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = GEN_KEYPAIR;
            if (!SetFeature(hUsbDevice, array_in, 2))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, ECC_MAXLEN * 3 + 2))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0x20)
            {

                return FAILEDGENKEYPAIR; //表示读取失败;

            }

            for (n = 0; n < ECC_MAXLEN; n++)
            {
                PriKey[n] = array_out[1 + ECC_MAXLEN * 0 + n];
            }

            for (n = 0; n < (ECC_MAXLEN * 2 + 1); n++)
            {
                PubKey[n] = array_out[1 + ECC_MAXLEN * 1 + n];
            }

            return 0;
        }

        private int NT_GetChipID(byte[] OutChipID, string Path)
        {
            int[] t = new int[8];
            int n;
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = GET_CHIPID;
            if (!SetFeature(hUsbDevice, array_in, 1))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 17))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0x20) return USBStatusFail;
            for (n = 0; n < 16; n++)
            {
                OutChipID[n] = array_out[1 + n];
            }

            return 0;
        }


        private int NT_Get_SM2_PubKey(byte[] KGx, byte[] KGy, byte[] sm2_UerName, string Path)
        {

            byte[] array_in = new byte[256];
            byte[] array_out = new byte[256];
            int n = 0;
            IntPtr hUsbDevice = IntPtr.Zero;

            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 0x33;
            if (!SetFeature(hUsbDevice, array_in, 2))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, ECC_MAXLEN * 2 + SM2_USENAME_LEN + 2))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0x20) return USBStatusFail;

            for (n = 0; n < ECC_MAXLEN; n++)
            {
                KGx[n] = array_out[1 + ECC_MAXLEN * 0 + n];
                KGy[n] = array_out[1 + ECC_MAXLEN * 1 + n];
            }

            for (n = 0; n < SM2_USENAME_LEN; n++)
            {
                sm2_UerName[n] = array_out[1 + ECC_MAXLEN * 2 + n];
            }

            return 0;
        }

        private int NT_Set_Pin(string old_pin, string new_pin, string Path)
        {

            byte[] array_in = new byte[256];
            byte[] array_out = new byte[256];
            int n = 0;
            IntPtr hUsbDevice = IntPtr.Zero;

            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = SET_PIN;
            byte[] b_oldpin = new byte[PIN_LEN];
            CopyStringToByte(b_oldpin, old_pin, PIN_LEN);
            byte[] b_newpin = new byte[PIN_LEN];
            CopyStringToByte(b_newpin, new_pin, PIN_LEN);
            for (n = 0; n < PIN_LEN; n++)
            {
                array_in[2 + PIN_LEN * 0 + n] = b_oldpin[n];
                array_in[2 + PIN_LEN * 1 + n] = b_newpin[n];
            }

            if (!SetFeature(hUsbDevice, array_in, PIN_LEN * 2 + 2))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 2))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0x20) return USBStatusFail;
            if (array_out[1] != 0x20) return FAILPINPWD;
            return 0;
        }


        private int NT_SM2_Enc(byte[] inbuf, byte[] outbuf, byte inlen, string Path)
        {

            byte[] array_in = new byte[256];
            byte[] array_out = new byte[256];
            int n = 0;
            IntPtr hUsbDevice = IntPtr.Zero;

            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = MYENC;
            array_in[2] = inlen;
            for (n = 0; n < inlen; n++)
            {
                array_in[3 + n] = inbuf[n];
            }

            if (!SetFeature(hUsbDevice, array_in, inlen + 1 + 2))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, inlen + SM2_ADDBYTE + 3))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0x20) return USBStatusFail;
            if (array_out[1] == 0) return FAILENC;

            for (n = 0; n < (inlen + SM2_ADDBYTE); n++)
            {
                outbuf[n] = array_out[2 + n];
            }

            return 0;
        }

        private int NT_SM2_Dec(byte[] inbuf, byte[] outbuf, byte inlen, string pin, string Path)
        {

            byte[] array_in = new byte[256];
            byte[] array_out = new byte[256];
            int n = 0;
            IntPtr hUsbDevice = IntPtr.Zero;

            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = MYDEC;
            byte[] b_pin = new byte[PIN_LEN];
            CopyStringToByte(b_pin, pin, PIN_LEN);
            for (n = 0; n < PIN_LEN; n++)
            {
                array_in[2 + PIN_LEN * 0 + n] = b_pin[n];
            }

            array_in[2 + PIN_LEN] = inlen;
            for (n = 0; n < inlen; n++)
            {
                array_in[2 + PIN_LEN + 1 + n] = inbuf[n];
            }

            if (!SetFeature(hUsbDevice, array_in, inlen + 1 + 2 + PIN_LEN))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, inlen - SM2_ADDBYTE + 4))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[2] != 0x20) return FAILPINPWD;
            if (array_out[1] == 0) return FAILENC;
            if (array_out[0] != 0x20) return USBStatusFail;
            for (n = 0; n < (inlen - SM2_ADDBYTE); n++)
            {
                outbuf[n] = array_out[3 + n];
            }

            return 0;
        }

        private int NT_Sign(byte[] inbuf, byte[] outbuf, string pin, string Path)
        {

            byte[] array_in = new byte[256];
            byte[] array_out = new byte[256];
            int n = 0;
            IntPtr hUsbDevice = IntPtr.Zero;

            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = YTSIGN;
            byte[] b_pin = new byte[PIN_LEN];
            CopyStringToByte(b_pin, pin, PIN_LEN);
            for (n = 0; n < PIN_LEN; n++)
            {
                array_in[2 + PIN_LEN * 0 + n] = b_pin[n];
            }

            for (n = 0; n < 32; n++)
            {
                array_in[2 + PIN_LEN + n] = inbuf[n];
            }

            if (!SetFeature(hUsbDevice, array_in, 32 + 2 + PIN_LEN))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 64 + 3))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[1] != 0x20) return FAILPINPWD;
            if (array_out[0] != 0x20) return USBStatusFail;
            for (n = 0; n < 64; n++)
            {
                outbuf[n] = array_out[2 + n];
            }

            return 0;
        }

        private int NT_Sign_2(byte[] inbuf, byte[] outbuf, string pin, string Path)
        {

            byte[] array_in = new byte[256];
            byte[] array_out = new byte[256];
            int n = 0;
            IntPtr hUsbDevice = IntPtr.Zero;

            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = YTSIGN_2;
            byte[] b_pin = new byte[PIN_LEN];
            CopyStringToByte(b_pin, pin, PIN_LEN);
            for (n = 0; n < PIN_LEN; n++)
            {
                array_in[2 + PIN_LEN * 0 + n] = b_pin[n];
            }

            for (n = 0; n < 32; n++)
            {
                array_in[2 + PIN_LEN + n] = inbuf[n];
            }

            if (!SetFeature(hUsbDevice, array_in, 32 + 2 + PIN_LEN))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 64 + 3))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            if (array_out[1] != 0x20) return FAILPINPWD;
            if (array_out[0] != 0x20) return USBStatusFail;
            for (n = 0; n < 64; n++)
            {
                outbuf[n] = array_out[2 + n];
            }

            return 0;
        }


        private int NT_Verfiy(byte[] inbuf, byte[] InSignBuf, ref bool outbiao, string Path)
        {

            byte[] array_in = new byte[256];
            byte[] array_out = new byte[256];
            int n = 0;
            IntPtr hUsbDevice = IntPtr.Zero;

            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = YTVERIFY;
            for (n = 0; n < 32; n++)
            {
                array_in[2 + n] = inbuf[n];
            }

            for (n = 0; n < 64; n++)
            {
                array_in[2 + 32 + n] = InSignBuf[n];
            }

            if (!SetFeature(hUsbDevice, array_in, 32 + 2 + 64))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 3))
            {
                CloseHandle(hUsbDevice);
                return -94;
            }

            CloseHandle(hUsbDevice);
            outbiao = (array_out[1] != 0);
            if (array_out[0] != 0x20) return USBStatusFail;

            return 0;
        }

        private string ByteArrayToHexString(byte[] in_data, int nlen)
        {
            string OutString = "";
            int n;
            for (n = 0; n < nlen; n++)
            {
                OutString = OutString + in_data[n].ToString("X2");
            }

            return OutString;
        }

        public int YT_GenKeyPair(ref string PriKey, ref string PubKeyX, ref string PubKeyY, string InPath)
        {

            int ret, n;
            byte[] b_PriKey = new byte[ECC_MAXLEN], b_PubKey = new byte[ECC_MAXLEN * 2 + 1]; //其中第一个字节是标志位,忽略
            IntPtr hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_GenKeyPair(b_PriKey, b_PubKey, InPath);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            PriKey = ByteArrayToHexString(b_PriKey, ECC_MAXLEN);
            PubKeyX = "";
            PubKeyY = "";
            for (n = 0; n < ECC_MAXLEN; n++)
            {
                PubKeyX = PubKeyX + b_PubKey[n + 1].ToString("X2");
                PubKeyY = PubKeyY + b_PubKey[n + 1 + ECC_MAXLEN].ToString("X2");

            }

            return ret;

        }

        public int Set_SM2_KeyPair(string PriKey, string PubKeyX, string PubKeyY, string SM2_UserName, string InPath)
        {

            int ret;
            byte[] b_PriKey = new byte[ECC_MAXLEN],
                b_PubKeyX = new byte[ECC_MAXLEN],
                b_PubKeyY = new byte[ECC_MAXLEN],
                b_SM2UserName = new byte[SM2_USENAME_LEN];
            HexStringToByteArray(PriKey, ref b_PriKey);
            HexStringToByteArray(PubKeyX, ref b_PubKeyX);
            HexStringToByteArray(PubKeyY, ref b_PubKeyY);
            CopyStringToByte(b_SM2UserName, SM2_UserName, SM2_USENAME_LEN);
            IntPtr hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_Set_SM2_KeyPair(b_PriKey, b_PubKeyX, b_PubKeyY, b_SM2UserName, InPath);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);

            return ret;

        }

        public int Get_SM2_PubKey(ref string PubKeyX, ref string PubKeyY, ref string sm2UserName, string InPath)
        {

            int ret;
            byte[] b_PubKeyX = new byte[ECC_MAXLEN],
                b_PubKeyY = new byte[ECC_MAXLEN],
                b_sm2UserName = new byte[SM2_USENAME_LEN];
            IntPtr hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_Get_SM2_PubKey(b_PubKeyX, b_PubKeyY, b_sm2UserName, InPath);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            PubKeyX = ByteArrayToHexString(b_PubKeyX, ECC_MAXLEN);
            PubKeyY = ByteArrayToHexString(b_PubKeyY, ECC_MAXLEN);
            StringBuilder c_str = new StringBuilder("", SM2_USENAME_LEN);
            CopyByteToString(c_str, b_sm2UserName, SM2_USENAME_LEN);
            sm2UserName = c_str.ToString();
            return ret;

        }

        public int GetChipID(ref string OutChipID, string InPath)
        {

            int ret;
            byte[] b_OutChipID = new byte[16];
            IntPtr hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_GetChipID(b_OutChipID, InPath);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            OutChipID = ByteArrayToHexString(b_OutChipID, 16);
            return ret;

        }

        public int SM2_EncBuf(byte[] InBuf, byte[] OutBuf, int inlen, string InPath)
        {

            int ret = 0, n, temp_inlen, incount = 0, outcount = 0;
            byte[] temp_InBuf = new byte[MAX_ENCLEN + SM2_ADDBYTE], temp_OutBuf = new byte[MAX_ENCLEN + SM2_ADDBYTE];
            IntPtr hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            while (inlen > 0)
            {
                if (inlen > MAX_ENCLEN)
                    temp_inlen = MAX_ENCLEN;
                else
                    temp_inlen = inlen;
                for (n = 0; n < temp_inlen; n++)
                {
                    temp_InBuf[n] = InBuf[incount + n];
                }

                ret = NT_SM2_Enc(temp_InBuf, temp_OutBuf, (byte) temp_inlen, InPath);
                for (n = 0; n < (temp_inlen + SM2_ADDBYTE); n++)
                {
                    OutBuf[outcount + n] = temp_OutBuf[n];
                }

                if (ret != 0) goto err;
                inlen = inlen - MAX_ENCLEN;
                incount = incount + MAX_ENCLEN;
                outcount = outcount + MAX_DECLEN;
            }

            err:
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;

        }

        public int SM2_DecBuf(byte[] InBuf, byte[] OutBuf, int inlen, string pin, string InPath)
        {

            int ret = 0, temp_inlen, n, incount = 0, outcount = 0;
            byte[] temp_InBuf = new byte[MAX_ENCLEN + SM2_ADDBYTE], temp_OutBuf = new byte[MAX_ENCLEN + SM2_ADDBYTE];
            IntPtr hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            while (inlen > 0)
            {
                if (inlen > MAX_DECLEN)
                    temp_inlen = MAX_DECLEN;
                else
                    temp_inlen = inlen;
                for (n = 0; n < temp_inlen; n++)
                {
                    temp_InBuf[n] = InBuf[incount + n];
                }

                ret = NT_SM2_Dec(InBuf, temp_OutBuf, (byte) temp_inlen, pin, InPath);
                for (n = 0; n < (temp_inlen - SM2_ADDBYTE); n++)
                {
                    OutBuf[outcount + n] = temp_OutBuf[n];
                }

                if (ret != 0) goto err;
                inlen = inlen - MAX_DECLEN;
                incount = incount + MAX_DECLEN;
                outcount = outcount + MAX_ENCLEN;
            }

            err:
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;

        }

        public int SM2_EncString(string InString, ref string OutString, string InPath)
        {
            int n, incount = 0, outcount = 0;
            byte[] temp_InBuf = new byte[MAX_ENCLEN + SM2_ADDBYTE], temp_OutBuf = new byte[MAX_ENCLEN + SM2_ADDBYTE];
            int inlen = lstrlenA(InString) + 1;
            int outlen = (inlen / (MAX_ENCLEN) + 1) * SM2_ADDBYTE + inlen;
            byte[] OutBuf = new byte[outlen];
            byte[] InBuf = new byte[inlen];
            CopyStringToByte(InBuf, InString, inlen);
            int ret = 0, temp_inlen;
            IntPtr hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            while (inlen > 0)
            {
                if (inlen > MAX_ENCLEN)
                    temp_inlen = MAX_ENCLEN;
                else
                    temp_inlen = inlen;
                for (n = 0; n < temp_inlen; n++)
                {
                    temp_InBuf[n] = InBuf[incount + n];
                }

                ret = NT_SM2_Enc(temp_InBuf, temp_OutBuf, (byte) temp_inlen, InPath);
                for (n = 0; n < (temp_inlen + SM2_ADDBYTE); n++)
                {
                    OutBuf[outcount + n] = temp_OutBuf[n];
                }

                if (ret != 0) goto err;
                inlen = inlen - MAX_ENCLEN;
                incount = incount + MAX_ENCLEN;
                outcount = outcount + MAX_DECLEN;
            }

            err:
            OutString = ByteArrayToHexString(OutBuf, outlen);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;

        }

        public int SM2_DecString(string InString, ref string OutString, string pin, string InPath)
        {
            int n, incount = 0, outcount = 0;
            byte[] temp_InBuf = new byte[MAX_ENCLEN + SM2_ADDBYTE], temp_OutBuf = new byte[MAX_ENCLEN + SM2_ADDBYTE];
            int inlen = lstrlenA(InString) / 2;
            int outlen = inlen - (inlen / (MAX_DECLEN) + 1) * SM2_ADDBYTE;
            byte[] InBuf = new byte[inlen];
            byte[] OutBuf = new byte[outlen];
            int ret = 0, temp_inlen;
            HexStringToByteArray(InString, ref InBuf);
            IntPtr hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            while (inlen > 0)
            {
                if (inlen > MAX_DECLEN)
                    temp_inlen = MAX_DECLEN;
                else
                    temp_inlen = inlen;
                for (n = 0; n < temp_inlen; n++)
                {
                    temp_InBuf[n] = InBuf[incount + n];
                }

                ret = NT_SM2_Dec(temp_InBuf, temp_OutBuf, (byte) temp_inlen, pin, InPath);
                for (n = 0; n < (temp_inlen - SM2_ADDBYTE); n++)
                {
                    OutBuf[outcount + n] = temp_OutBuf[n];
                }

                if (ret != 0) goto err;
                inlen = inlen - MAX_DECLEN;
                incount = incount + MAX_DECLEN;
                outcount = outcount + MAX_ENCLEN;
            }

            err:
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            StringBuilder c_str = new StringBuilder("", outlen);
            CopyByteToString(c_str, OutBuf, outlen);
            OutString = c_str.ToString();
            return ret;

        }



        public int YtSetPin(string old_pin, string new_pin, string InPath)
        {
            int ret;
            IntPtr hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_Set_Pin(old_pin, new_pin, InPath);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        private int NT_SetID(byte[] InBuf, string Path)
        {
            int n;
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 7;
            for (n = 2; n <= 9; n++)
            {
                array_in[n] = InBuf[n - 2];
            }

            if (!SetFeature(hUsbDevice, array_in, 9))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 9))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0x0)
            {
                return -82;
            }

            return 0;
        }

        public int SetID(string Seed, string Path)
        {
            int ret;
            IntPtr hsignal;
            int n;
            byte[] KeyBuf = new byte[8];
            for (n = 0; n < 8; n++)
            {
                KeyBuf[n] = 0;
            }

            HexStringToByteArray(Seed, ref KeyBuf);
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_SetID(KeyBuf, Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        private int NT_GetProduceDate(ref string OutDate, string Path)
        {
            int n;
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 15;
            if (!SetFeature(hUsbDevice, array_in, 1))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 8))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            OutDate = "";
            for (n = 0; n < 8; n++)
            {
                OutDate = OutDate + array_out[n].ToString("X2");
            }

            return 0;
        }

        //返回锁的出厂编码
        public int GetProduceDate(ref string PDate, string Path)
        {
            int ret;
            IntPtr hsignal;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = NT_GetProduceDate(ref PDate, Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public string SnToProduceDate(string InSn)
        {
            string OutString;
            OutString = (2000 + HexToInt(InSn.Substring(0, 2))).ToString() + "年";
            OutString = OutString + (HexToInt(InSn.Substring(2, 2))).ToString() + "月";
            OutString = OutString + (HexToInt(InSn.Substring(4, 2))).ToString() + "日";
            OutString = OutString + (HexToInt(InSn.Substring(6, 2))).ToString() + "时";
            OutString = OutString + (HexToInt(InSn.Substring(8, 2))).ToString() + "分";
            OutString = OutString + (HexToInt(InSn.Substring(10, 2))).ToString() + "秒--";
            OutString = OutString + "序号:" + HexToInt(InSn.Substring(12, 4)).ToString();
            return OutString;
        }

        private int y_setcal(byte[] indata, int address, int nlen, byte[] password, string Path)
        {
            int n;
            byte[] array_in = new byte[25];
            byte[] array_out = new byte[25];
            IntPtr hUsbDevice = IntPtr.Zero;
            if (nlen > 8) return -87;

            if (OpenMydivece(ref hUsbDevice, Path) != 0) return -92;
            array_in[1] = 6;
            array_in[2] = 0;
            array_in[3] = 0;
            array_in[4] = (byte) nlen;
            for (n = 0; n <= 7; n++)
            {
                array_in[5 + n] = password[n];
            }

            for (n = 0; n < nlen; n++)
            {
                array_in[13 + n] = indata[n];
            }

            if (!SetFeature(hUsbDevice, array_in, 13 + nlen))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            if (!GetFeature(hUsbDevice, array_out, 2))
            {
                CloseHandle(hUsbDevice);
                return -93;
            }

            CloseHandle(hUsbDevice);
            if (array_out[0] != 0)
            {
                return -82;
            }

            return 0;
        }

        public int SetCal(string W_HKey, string W_LKey, string new_HKey, string new_LKey, string Path)
        {
            int ret;
            IntPtr hsignal;
            byte[] ary1 = new byte[8];
            byte[] ary2 = new byte[8];
            short address;
            myconvert(W_HKey, W_LKey, ary1);
            myconvert(new_HKey, new_LKey, ary2);
            address = 0;
            hsignal = CreateSemaphore(0, 1, 1, "ex_sim");
            WaitForSingleObject(hsignal, INFINITE);
            ret = y_setcal(ary2, address, 8, ary1, Path);
            ReleaseSemaphore(hsignal, 1, 0);
            CloseHandle(hsignal);
            return ret;
        }

        public int CheckKeyByFindort_2()
        {
            //使用普通算法一查找指定的加密锁
            string DevicePath = ""; //用于储存加密锁所在的路径
            return FindPort_2(0, 1, -517431188, ref DevicePath);
        }

        //使用带长度的方法从指定的地址读取字符串
        private int ReadStringEx(int addr, ref string outstring, string DevicePath)
        {
            int nlen, ret;
            byte[] buf = new byte[1];
            //先从地址0读到以前写入的字符串的长度
            ret = YReadEx(buf, (short) addr, (short) 1, "54618348", "4776A17F", DevicePath);
            if (ret != 0) return ret;
            nlen = buf[0];
            //再读取相应长度的字符串
            return YReadString(ref outstring, addr + 1, nlen, "54618348", "4776A17F", DevicePath);

        }

        //使用从储存器读取相应数据的方式检查是否存在指定的加密锁
        public int CheckKeyByReadEprom()
        {
            int n, ret;
            string DevicePath = ""; //用于储存加密锁所在的路径
            string outstring = "";
            //@NoUseCode_data return 1;//如果没有使用这个功能,直接返回1
            for (n = 0; n < 255; n++)
            {
                ret = FindPort(n, ref DevicePath);
                
                if (ret != 0) return ret;
                ret = ReadStringEx(0, ref outstring, DevicePath);
                if (ret == 0 && (string.Compare(outstring, "TEAM123", StringComparison.Ordinal) == 0)) return 0;
            }
            
            return -92;
        }

        //使用增强算法一检查加密锁,这个方法可以有效地防止仿真
        public int CheckKeyByEncstring()
        {
            //推荐加密方案:生成随机数,让锁做加密运算,同时在程序中端使用代码做同样的加密运算,然后进行比较判断。

            int n, ret;
            string DevicePath = ""; //用于储存加密锁所在的路径
            string InString;

            //@NoUseKeyEx return 1;//如果没有使用这个功能,直接返回1
            System.Random rnd = new System.Random();

            InString = rnd.Next(0, 32767).ToString("X") + rnd.Next(0, 32767).ToString("X");

            for (n = 0; n < 255; n++)
            {
                ret = FindPort(n, ref DevicePath);
                if (ret != 0) return ret;
                if (Sub_CheckKeyByEncstring(InString, DevicePath) == 0) return 0;
            }

            return -92;
        }

        private int Sub_CheckKeyByEncstring(string InString, string DevicePath)
        {
            //使用增强算法一对字符串进行加密
            int ret;
            string outstring = "";
            string outstring_2;
            ret = EncString(InString, ref outstring, DevicePath);
            if (ret != 0) return ret;
            outstring_2 = StrEnc(InString, "21B6D3E062EB66C48B800EEB08D0F37F");
            if (outstring_2.CompareTo(outstring) == 0) //比较结果是否相符
            {
                ret = 0;
            }
            else
            {
                ret = -92;
            }

            return ret;
        }

        //使用增强算法二检查是否存在对应的加密锁
        public int CheckKeyByEncstring_New()
        {
            int n, ret;
            string DevicePath = ""; //用于储存加密锁所在的路径
            string outstring = "";
            System.Random rnd = new System.Random();
            int myrnd = rnd.Next(0, 500);
            string[] EncInString =
            {
                "14325", "15004", "22868", "16672", "5595", "27472", "2047", "4810", "10216", "16402", "2305", "12781",
                "1029", "7972", "12691", "1758", "14651", "872", "6417", "13196", "10678", "28254", "17139", "5516",
                "1216", "31275", "26837", "26638", "24768", "2960",
                "25712", "1510", "30019", "9198", "14750", "19331", "29939", "21319", "16474", "6393", "1945", "19006",
                "28348", "29689", "25630", "3094", "17151", "18903", "2703", "16558", "19838", "20867", "7699", "9866",
                "23218", "3472", "24308", "9420", "15669", "28206",
                "17567", "32052", "14273", "4915", "14235", "7720", "1840", "11789", "27539", "5287", "3197", "977",
                "22866", "7763", "5824", "3887", "22721", "23406", "19764", "17016", "23274", "8412", "14644", "27041",
                "17399", "27165", "28728", "11323", "25906", "27475",
                "24028", "12152", "5893", "17218", "11738", "22568", "29434", "19786", "22026", "11456", "11708",
                "4974", "16487", "22352", "4372", "24654", "5388", "18315", "5612", "28975", "9265", "29890", "7757",
                "18418", "28721", "16360", "20323", "7448", "22407", "30094",
                "2936", "29123", "24268", "28648", "3060", "16823", "6843", "22726", "7010", "21844", "14892", "2971",
                "28524", "13213", "12314", "6008", "8925", "13363", "32159", "24847", "20382", "12633", "7158", "25779",
                "18616", "23024", "1656", "6231", "29783", "9083",
                "25758", "28042", "17861", "23579", "21508", "29568", "22378", "23700", "21091", "6412", "9425",
                "23110", "18325", "3741", "25764", "22835", "12181", "18503", "687", "15871", "25723", "8124", "14808",
                "32745", "2179", "5710", "20012", "31446", "4102", "14061",
                "26323", "24902", "27517", "6190", "2074", "20060", "20868", "32321", "11624", "30681", "10452", "7417",
                "841", "33", "4680", "31175", "16741", "26674", "4824", "28094", "9352", "8627", "23967", "18320",
                "2203", "16611", "15832", "3471", "8871", "20132",
                "8411", "24492", "23256", "14969", "16420", "31097", "18039", "27779", "27468", "21545", "16878",
                "30598", "29197", "26766", "10952", "27362", "11841", "4378", "14765", "17562", "11747", "3039",
                "31848", "847", "32010", "7309", "28644", "22595", "4085", "20088",
                "14890", "31066", "19705", "22162", "1125", "4885", "13971", "5485", "29916", "23188", "13660", "14650",
                "18685", "16283", "526", "32716", "3919", "16012", "12163", "6293", "382", "21097", "21685", "9894",
                "32338", "1747", "22206", "25265", "9143", "10765",
                "21209", "23818", "2230", "7928", "10335", "24481", "6009", "20247", "8906", "28680", "1866", "15500",
                "17332", "29042", "30355", "13336", "11479", "26289", "9439", "7966", "10765", "21559", "19670",
                "30111", "23376", "16917", "7748", "20543", "32442", "24062",
                "22545", "6718", "23174", "15683", "586", "25470", "18189", "16087", "18453", "21122", "22728", "3404",
                "29119", "13932", "10836", "16595", "32433", "14589", "18023", "8511", "24437", "12440", "12767",
                "2050", "20406", "4671", "5555", "25133", "20541", "916",
                "2303", "21106", "16627", "3287", "31482", "29477", "6885", "27372", "15618", "14390", "19001", "342",
                "11407", "28983", "10301", "27700", "32059", "27484", "5464", "12875", "8896", "13173", "13077", "5883",
                "23288", "30708", "15903", "3142", "22493", "2797",
                "2111", "17615", "2442", "1040", "4702", "26072", "2104", "687", "18056", "22850", "7745", "4029",
                "20966", "16272", "29214", "8139", "7874", "485", "20587", "13581", "28294", "1024", "5601", "8531",
                "5053", "30276", "14682", "26639", "19471", "18357",
                "30160", "16468", "14919", "14323", "5214", "14036", "81", "2369", "22076", "28640", "31027", "21120",
                "32454", "2412", "4890", "28979", "32116", "7431", "18767", "7036", "14307", "25061", "15932", "4637",
                "29641", "28376", "30059", "29302", "24836", "7250",
                "11655", "10380", "17291", "1636", "23129", "256", "15738", "11968", "16074", "23314", "14601", "16058",
                "9958", "31398", "29331", "26945", "16854", "31294", "8852", "27882", "7141", "23804", "18339", "13798",
                "14459", "16546", "4219", "8198", "19491", "12177",
                "26102", "22716", "5768", "4811", "5390", "24859", "23666", "17395", "6366", "12245", "461", "16203",
                "1183", "29499", "17314", "30132", "3498", "29504", "4635", "16050", "13691", "4982", "2690", "27236",
                "5035", "29966", "4417", "29582", "16371", "14555",
                "3043", "20882", "23599", "24910", "15120", "27250", "15961", "21627", "13459", "9424", "14985",
                "32273", "32087", "6636", "3323", "4453", "17253", "26538", "25607", "27494"
            };
            string[] EncOutString =
            {
                "81523BE49203CDDC", "3CB641EA3FF0577E", "2CEBDEA42762FBE1", "F22C6159C1723636", "B8CB9B743D317040",
                "91EBB14366AE02AD", "D34478DF40793EDE", "B57EF295ABB39189", "4D46D7F69BA5D960", "082C74E4F107AF87",
                "DADCF2B97B7AAF25", "7EC98C12C6C24046", "0B7B0A7DF447C3F5", "B3ED50FFA07C6B2E", "0A1CC2400645CA94",
                "A5DC58E618279445", "034C114F0BBC6F78", "D144F87C87FB3FBB", "28E51DFB73C1AA20", "85DA1BD923805040",
                "54F6E08B4B4F20B9", "4071869F278BDA07", "42978249F571F331", "A4B8CFBE3ED86BE3", "F55B0E35451A518D",
                "669A63A14F49C085", "576D002A50BAE78E", "C73406AD9A409E74", "EF1A53B0B23B335A", "34954C54FCB0D03E",
                "85CB7C78CE31F385", "1AD2298DF6C7E67E", "A0A1A5AC679806F8", "9FBF059AA66C2AD7", "E2B6AE62C8C97C56",
                "C260427BC8B642FF", "B34AA659B16287BF", "32F2B71F11C0FEEE", "2227D78F36634562", "172FB9000B2EF10C",
                "5EB0A7ED6BB29432", "6848371CF208EAEE", "4A6FAF220A7A410A", "7C16575BDC3EC20B", "D2946E1D06E2805B",
                "FEE8F83A157AC090", "A3D9C078725181E1", "35C59D4BB42B0532", "D721FC412ED8E16A", "3A959C6CB8C1066A",
                "ECBD5AD3AA734B45", "C343663C4DE1DFE6", "14605989AEAD3C71", "02F1A14972276BA4", "EE8A4F6457399922",
                "408E2646AFBC49F4", "AEC653D3A83D4E82", "575AA99EE0F2CB0B", "C76AB4442781647F", "8FC7D9CE1781EF9D",
                "8FA389063F09452D", "8E8E3B22A4B90D2D", "88061AC1565B782F", "11BF8F9CB819C846", "FD9DE94A18FCD675",
                "876F2E426A0A7342", "D412E08087726A88", "4513F1ACCC5F9705", "AF6C239605E452B5", "41A0B58F92B5E3DB",
                "CFA153542F50C1ED", "8D8E9427FED908FA", "383C8D0CCA05B4A6", "9B71186709B3D6ED", "8B1A2F96D73510CB",
                "F43F462EE7A6A9FF", "9A8A1FB491FD78EE", "CA299EF4FEC8D485", "71943747049CF25E", "505BBB4940D7CB58",
                "63A1BCF252674C4E", "C7511DAFD982D451", "0E49A5117C26070D", "A3E21D54AC60F232", "62449CDB9E65643B",
                "40CB7C0445C1ED09", "36C7CF3615BC5512", "194616AEBECFCDB7", "E6B13C9B2B439CFE", "D75B396ABB65FD32",
                "AFA77639C986097D", "2D1A0DBBDBF7BC5B", "91BBFA9FFC0100FA", "9E80B94D7C9487BD", "E2078F27CC5457D2",
                "1C5321A0920C6D30", "C9136A83E0701149", "7908C991EB75B308", "3B7445996DA2BA56", "933DCDB471DFDFC0",
                "EFC9DE4CC1EDA2AA", "FBB24DD1D5529290", "DA14A0E9F12F1A59", "5DD9F7E3F5E55F72", "D8486DEBBE7EF308",
                "CF604E95E7CFF6AB", "56461C4E59EF83AE", "B8A10DCF7AFA759C", "0798FA796380EF5B", "548A51A1345BB41E",
                "AA54664216843AED", "9D4EE9D0B73F7D41", "ADA379FDC851756D", "7093D58C7A7A16BD", "A22083C0A08AFAA6",
                "F42299BE9E745D80", "36AB3963476B70AA", "C58141E6B5E21CF2", "5C21B78B23377A52", "36BCB65B7DBE1EB0",
                "C463F294CBFD68E7", "651E29F879CAB5A9", "AA8E5E88340BBDE5", "759CE8DF881B903A", "E2300C547456BB19",
                "9C5E13634DE58147", "A105D097C4BEC526", "549D1CC247C82DDB", "1B3E95E395213AEB", "A70AEBFD30CA3202",
                "E6077D73F94670E0", "BBE048ED46B67C5C", "35E8BFD51078B385", "03502D98908C8CEE", "8949A102527CCD28",
                "6042D0DEC2E4EB82", "6CC7980794D5ECA7", "95F5F421F6B1868E", "6F19E9DF75509BA8", "D398EF72E4001004",
                "9421E892DCD4DC36", "763967F59F7EB711", "3483F5EB4B0714D4", "81B85F5573585C35", "B3E42D14238DBC12",
                "AC7343EBEB4716AB", "D66C4A925870193B", "81370808197FAF85", "6C401DFF90A1E174", "947FE8F9B9D0FBD4",
                "0B7FB3385FE6238C", "04C393E30AED5793", "FC84FB08E54335C8", "75A59C5800BF2F66", "378451E5E7FE1EFB",
                "08CF1ECE5B1D2988", "7E81F790FB62116B", "E5A5E6CEC239E2B0", "6F72AC38B48E9BE5", "B265D058D6B5B192",
                "537C2C4693979235", "BAA8A19281814678", "653C94B5847DEDFF", "E931A2ABF3D5FF7C", "5A9BADA9AE3D9F98",
                "22D2B5B23519D581", "777EC40EBC7BFF56", "E8745945283C71E0", "1EEDE0D74FAB92A8", "D4A79CF838427DF9",
                "556433D0F69AAD55", "FBE7E0FE026A1D15", "855F8000CDADF904", "36EE8EE935FAAAC1", "17DFAAA3B6560020",
                "1503DE845ABFECF9", "BB7EE225E1827FEE", "993CD4DBCED9BB0C", "0DAA74F5F5E6C53F", "B6743DA1C6278772",
                "75FB8979B98C0B65", "E3C3CC647E52EF2C", "3DABD4FDC8DB5CA1", "199A8F46DA4CF7E0", "04B18765000678B2",
                "11BF5E172D66F748", "C0F2D99C7B5F8A9E", "C2482B0B9D275F84", "E934FFB6AC45C2A7", "DAAE613BEF6EC022",
                "C19B9C388DA7878C", "ECAD65BF3D59C1DF", "93BF7A19CF2B4EFA", "42A900C673406E6F", "3750D3666BD81174",
                "E5180B2F3B2D0C9B", "F7D83B2CAB92E8FD", "CF16927992131D05", "120DD671A29F5F1D", "FD5A8F3306AA10C5",
                "62D2EA4FF45C15E3", "1ADA3FB680DA495C", "CE7BD6090CB3DE75", "F724AC0F0BD0BCFD", "C2F1449556DDDB12",
                "43C3B7E17AE6B311", "5F6576733B5B5F3D", "1DF28CAE0D1BEEDD", "C5C55009F3E1E55F", "93F1CA6296C33DE1",
                "91D6B5F1BE8EC5FC", "B5C6DFBD98C0158A", "B5584604C2C97223", "12B20C5CF67EE003", "0E01D8E4884EAC03",
                "624D1016458E7228", "24D4813DFE12629A", "4546A408D8C22951", "80A9339C195561CB", "AD364AE98F16D8B3",
                "3BE9F7F954FA729A", "3328C6A173277E21", "AAC8663BD47EDCA3", "A5EA76DCEF97423B", "EF11BC18E72809EE",
                "6172889BB20C9269", "0DDC9BCDD25D8DF3", "BFE17CC8E9E62DB5", "98D8880316C3ECC6", "F2979DC363CECCC3",
                "C9EE9BC534946FB3", "AA3FBD1BC77F7A0F", "5A1C5A3A717208D4", "770E6704C0C53197", "0B0DFBF4516603D2",
                "9FC95C6256DB13D9", "58597AEE41BF56AE", "075AFB63468B3CEF", "F16978E8D1F94EA9", "517BCC68365507EF",
                "9BAA18EF01322E1E", "84A6A24E82A3D8C8", "30AC991A8CC469EB", "09069EC5BFB12087", "EAC41D54B3D3EC89",
                "1890E753A07DF165", "A66E16C21C8274DC", "9D4A3C237EC0B505", "4261F5918251F958", "54AC82F1F1AA475F",
                "CD24D3092D4B2C42", "D2AA408273C5ABD3", "EED1A93584899E51", "4D80BBC0F2E882E6", "73E6B8DEEA6ACEBE",
                "1FCAA9CFFE27E98C", "0A937994088B09B0", "9A772D4014F90109", "39AC44EB20195032", "AE370A95A4965E16",
                "336862ECE271C4A1", "0F93D090DAB342FB", "1D82AD6FF449B0A2", "5CE6CECE7A0416B0", "89879B0BCEF327BB",
                "2FE76976889698E3", "75D7389D0C309C41", "DC0336890E1352A7", "F980DE1E3BDB632C", "C3AE6F36629B639F",
                "37F10A87CB8605DF", "F66D90B1774A5FAD", "605751521989C0BF", "EDA72FF8C1401994", "0910BF65DD64E2C3",
                "41A507FB81165144", "88056785AA082EE3", "3B69AF7076B368FF", "F9DB9773EABCF394", "ABE9143444CFCB4E",
                "834A5F8B20E1082F", "B4075A3F9761653F", "89F39A29CC487D45", "66A48EB6D8B43A34", "F7D41E5F276CACB1",
                "90028E59071C1674", "B63E2C406E1F72F4", "FB2915F817C94EB3", "D96ED4102BC5254D", "7C744CFB7580B3AA",
                "C3AE6F36629B639F", "80BCA18A4442A447", "6680052DEF50B720", "485D7BA34F53FC4D", "2C4AD1D35EE7C4C3",
                "8157DC1EDA128271", "0019CC663A28C57C", "20B34A42316BE69C", "6489B2964CD074E8", "03922631C35FDAC0",
                "03CCDD2196BFF31C", "F91345DC6D48079C", "6D8D588F1727A04B", "7C4506F74DDD6D5A", "38FBC9A9EDA47752",
                "AC5EBEDEA2879D4E", "8F3152319ACD6CFC", "5E07009796B3F1D3", "42E7A16A43454FF2", "A126E29F49BE22FD",
                "B3B09EFF420C32C2", "B19464A630414BAE", "E871B1A478009612", "4F74739DDDC5F494", "A81EC3F160B03C67",
                "A657F28088CEDE79", "30C925FC13D57EE1", "06B90DC484A6AF3C", "5D876D6E347CA177", "961252177EED989C",
                "4944CBD101F680BA", "0B8B8C4FC7E1B149", "71A6308FB43B00BB", "88056E9E5FE61A74", "F6BE5693DBCC69D1",
                "FD2B6E9BED16F951", "DAC2EE09D17ECED4", "B6DE3CDFB0137582", "8092CA85C27343BA", "6EBE40C41E517E8F",
                "624B66116FBED5FA", "A714D3A76859C779", "BD8B8D82C839FE80", "FF691F3DB8D09887", "F4B0613D0898D12D",
                "3AA3C459F35D4CE4", "99B14BB7801F2E58", "43CCD3A5D9FF4A46", "6BCFBE87E050E8B4", "83BF725BD4C3E4D3",
                "D421F68FDE727B81", "CF2411BE18C68F82", "AF674A858EC10D8E", "27E7DC60D5D983F2", "5E41B1C9D6ADC64C",
                "D90B17A4AFD48E40", "E9F186EAF1F10B0D", "51E6C9C9E3F89561", "E0F8FD6364AFC4ED", "0B38833206E14A64",
                "DDB4651CC4CA598C", "74D003DD7CB19B41", "339A157CCB801C1E", "B46ACBA4F76A8DD7", "61B72F57AF0C7911",
                "C6B06725F45E304F", "2E091E74B2C6D54E", "C85A98CD6DFC92C3", "0B7470FBCD0B5CA8", "C4465B2500AF3954",
                "7380D05E1BBDD294", "B7E16B2B3C09E4A1", "8CABC3DD7FF68F83", "57205F99E167C1DD", "598F245229B51FE7",
                "9561FC7ABD756E91", "D772453FFB5E748D", "1EEDE0D74FAB92A8", "07D2C1C1209A7659", "F864DA7FEDFB556C",
                "3D3E11E7C560AAEF", "1900C5FC60B5523B", "29CE902C699D49C8", "FDC66F8D24B9E436", "81819D7A5219A808",
                "1A8D50273B2B98B7", "10512231DAF9CEC7", "6234B44558537B48", "3B7B815D72989E62", "3FD715B420CC9E76",
                "BF6A3AF58D01C71E", "6D8AD54BFC388C1C", "C9D37C9411FD13CE", "39E0BF675E6E4E2C", "212A11B63AA287DA",
                "42CF60C613ADB485", "850895D1DAB78C09", "260F10ADEB254F37", "E75DC0ED75D4D898", "C07251AF19B91319",
                "B49A484CF5600B18", "116C587B04A07CCA", "0BCA8C36AA105779", "F4245674E7DA95D8", "921EE34B1CD8BF7E",
                "C230DEBF480ACB5F", "B3BE00C8224258D4", "D1BBE471ACB13B61", "140C67E566F56F45", "55F187171BE507CC",
                "02F06DB5F74F2959", "D3B4CC00BE953C29", "2E8F814967FF0CE9", "762C26FFDAA34B5D", "3502FB15FB52C57B",
                "056DAFA5E05DCF5A", "B9737E6124ACCD8D", "9A8501FC3E3E2CF9", "8D9EBF2B1A9BCB84", "D869A9D6914A6B7A",
                "7895ED9C52872ED5", "0151A0F1DB298114", "F4E6FD2DE3011785", "6EF9308D4EFCFEE2", "113706A076CBC65F",
                "74DBA2899E54CE4B", "0146180294169F47", "8F047C3EAB91AB06", "4207B4C92AF7C0F2", "C1C01D6E2ED962F6",
                "4930F7E4788BC118", "C3995549A933D069", "CCA9DD8336D9F871", "F5C0DCF135F329EA", "46A5042266F8B5BB",
                "96052C9A937640E6", "44FD8EB770E13A5B", "978277F4FFEC4AFB", "9DC933AFE95710F4", "0B627B13DB8D7D98",
                "250346033B4049A4", "128B05472E455458", "40EE138760A9B7E3", "0744D0C7165C8497", "6C13D761ADD9C1DE",
                "15522950F078A703", "FF4C6F7D3FC84265", "985F04EE678F2D45", "81F170E31AA377C9", "C916204B0BE099D7",
                "8F2FC51B0CAEF611", "2FB07D21C52B1020", "E3E1A2F227CC20DD", "00C5EAFA0305E874", "E61764B98FBACEBB",
                "15D4B14CB43F22A2", "D737A3ECA6EAB2C0", "901B6294BF8FF883", "1BFD7C7A5BF6E554", "531FC4360B4F492B",
                "A8AC6FF7C7EF5B22", "24E7670F56BF5C99", "8E4E9DF917646EAC", "3246F226416FF1D3", "C92CA77D518DD39C",
                "BD5273D303E9B5A9", "A93E963FCC1207C8", "DAEF059AF82D5149", "13C0BD26C4EC09CC", "A18BCC64C189FE49",
                "65EC6600B328ABBC", "4A71841B76A4A95B", "DC9532F6D551BA99", "BB2A097FC166A1DC", "BAE03296F65F9471",
                "3B61B691FCAEAE9F", "AFF505046E63E6D3", "211D1BAA18BCF7B3", "097DDBE93EA61C17", "05E1176E694DC1C0",
                "F6799A243C8EA050", "42D8F4BA026B0344", "1DBC44F85A188E99", "32F671A2E8BABE21", "77C6D82DC131DE35",
                "56A6A3C51BC4960A", "5317665483C82CAB", "3923EBEAD41C10B3", "CC69577EB87DCF53", "749DD598BA5B9532",
                "A759F194DEBC4814", "82C0982B62D9BCE8", "564993B58B3CF419", "97B6182A0843590D", "F6977B98F0E783CD",
                "486E21D382A8806F", "4188A1754C842233", "671013F6E2D489E1", "146B6C03F13E172E", "C3DC60541C9D34F4",
                "426026A17087AB51", "848FCEFEC72F2664", "4794CD385896D78D", "0EE5F1AC44874EA3", "2DC3B113C0487E80",
                "183F2EE9C4291855", "6F3A7CF759BE98B3", "C7FBDEDCA6B69121", "E3864F275A73BC64", "8873D70CFFCAF40C"
            };
            //@NoUseNewKeyEx return 1;//如果没有使用这个功能,直接返回1
            //@NoSupNewKeyEx return 2;//如果该锁不支持这个功能,直接返回2
            for (n = 0; n < 255; n++)
            {
                ret = FindPort(n, ref DevicePath);
                if (ret != 0) return ret;
                ret = EncString_New(EncInString[myrnd], ref outstring, DevicePath);
                if ((ret == 0) && (outstring.CompareTo(EncOutString[myrnd]) == 0)) return 0;
            }

            return -92;
        }
    }
}