using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace 加密狗
{
    public enum VikeyType
    {
        ViKeyAPP = 0,                       //实用型加密狗
        ViKeySTD = 1,                       //标准型加密狗
        ViKeyNET = 2,                       //网络型加密狗
        ViKeyPRO = 3,                       //专业型加密狗
        ViKeyWEB = 4,                       //身份认证型加密狗
        ViKeyTIME = 5,                      //时钟型加密狗，内部独立时钟
        ViKeyMultiFunctional = 0x0A,        //多功能加密狗  支持软件加密 支持文档加密
        ViKeyMultiFunctionalTime = 0x0B,    //多功能时钟加密狗
        ViKeyInvalid    //无效类型
    };
    public enum 返回值 : uint
    {
        /// <summary>
        /// 成功
        /// </summary>
        VIKEY_SUCCESS = 0x00000000,
        /// <summary>
        /// 没有找到ViKey加密锁
        /// </summary>
        VIKEY_ERROR_NO_VIKEY = 0x80000001,
        /// <summary>
        /// 密码错误
        /// </summary>
        VIKEY_ERROR_INVALID_PASSWORD = 0x80000002,
        /// <summary>
        /// 请先查找加密锁
        /// </summary>
        VIKEY_ERROR_NEED_FIND = 0x80000003,
        /// <summary>
        /// 无效的句柄
        /// </summary>
        VIKEY_ERROR_INVALID_INDEX = 0x80000004,
        /// <summary>
        /// 数值错误
        /// </summary>
        VIKEY_ERROR_INVALID_VALUE = 0x80000005,
        /// <summary>
        /// 秘钥无效
        /// </summary>
        VIKEY_ERROR_INVALID_KEY = 0x80000006,
        /// <summary>
        /// 读取信息错误
        /// </summary>
        VIKEY_ERROR_GET_VALUE = 0x80000007,
        /// <summary>
        /// 设置信息错误
        /// </summary>
        VIKEY_ERROR_SET_VALUE = 0x80000008,
        /// <summary>
        /// 没有机会
        /// </summary>
        VIKEY_ERROR_NO_CHANCE = 0x80000009,
        /// <summary>
        /// 权限不足
        /// </summary>
        VIKEY_ERROR_NO_TAUTHORITY = 0x8000000A,
        /// <summary>
        /// 地址或长度错误
        /// </summary>
        VIKEY_ERROR_INVALID_ADDR_OR_SIZE = 0x8000000B,
        /// <summary>
        /// 获取随机数错误
        /// </summary>
        VIKEY_ERROR_RANDOM = 0x8000000C,
        /// <summary>
        /// 获取种子错误
        /// </summary>
        VIKEY_ERROR_SEED = 0x8000000D,
        /// <summary>
        /// 通信错误
        /// </summary>
        VIKEY_ERROR_CONNECTION = 0x8000000E,
        /// <summary>
        /// 算法或计算错误
        /// </summary>
        VIKEY_ERROR_CALCULATE = 0x8000000F,
        /// <summary>
        /// 计数器错误
        /// </summary>
        VIKEY_ERROR_MODULE = 0x80000010,
        /// <summary>
        /// 产生密码错误
        /// </summary>
        VIKEY_ERROR_GENERATE_NEW_PASSWORD = 0x80000011,
        /// <summary>
        /// 加密数据错误
        /// </summary>
        VIKEY_ERROR_ENCRYPT_FAILED = 0x80000012,
        /// <summary>
        /// 解密数据错误
        /// </summary>
        VIKEY_ERROR_DECRYPT_FAILED = 0x80000013,
        /// <summary>
        /// ViKey加密锁已经被锁定
        /// </summary>
        VIKEY_ERROR_ALREADY_LOCKED = 0x80000014,
        /// <summary>
        /// 无效的命令
        /// </summary>
        VIKEY_ERROR_UNKNOWN_COMMAND = 0x80000015,
        /// <summary>
        /// 当前ViKey加密锁不支持此功能
        /// </summary>
        VIKEY_ERROR_NO_SUPPORT = 0x80000016,
        /// <summary>
        /// 发生异常
        /// </summary>
        VIKEY_ERROR_CATCH = 0x80000017,
        /// <summary>
        /// 未知错误
        /// </summary>
        VIKEY_ERROR_UNKNOWN_ERROR = 0xFFFFFFFF,
    }

    public class 加密狗API类
    {
        /// <summary>
        /// 查找加密锁。使用其他API前必须先调用次函数。
        /// </summary>
        /// <param name="pdwCount">[out]     如果查找到系统中存在加密狗，返回查找到加密狗的个数</param>
        /// <returns>0表示系统中存在ViKey加密狗。</returns>
        [DllImport("ViKey.dll")]
        public static extern uint VikeyFind(ref uint pdwCount);
        /// <summary>
        /// 获取加密狗的硬件ID,加密狗的硬件ID是加密狗的唯一标识，每个加密狗的硬件ID都不一样。
        /// </summary>
        /// <param name="Index">[in]指定要操作加密狗的序号</param>
        /// <param name="pdwHID">[out]返回加密狗的硬件ID</param>
        /// <returns></returns>
        [DllImport("ViKey.dll")]
        public static extern uint VikeyGetHID(ushort Index, out uint pdwHID);

        /// <summary>
        /// 获取加密狗的当前权限
        /// </summary>
        /// <param name="Index">指定要操作加密狗的序号</param>
        /// <param name="pLevel">返回加密狗的当前权限 0表示加密狗尚未登录  1表示加密狗是用户权限  2表示加密狗是管理员权限</param>
        /// <returns></returns>
        [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern uint VikeyGetLevel(ushort Index, out byte pLevel);

        /// <summary>
        /// 以用户权限登录加密狗
        /// </summary>
        /// <param name="Index"></param>
        /// <param name="pUserPassushort"></param>
        /// <returns></returns>
        [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern uint VikeyUserLogin(ushort Index, Byte[] pUserPassword);
        /// <summary>
        /// 以管理员权限登录加密狗
        /// </summary>
        /// <param name="Index"></param>
        /// <param name="pAdminPassword"></param>
        /// <returns></returns>
        [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern uint VikeyAdminLogin(ushort Index, Byte[] pAdminPassword);
        /// <summary>
        /// 注销登录加密狗 注销后的加密狗权限为0 
        /// </summary>
        /// <param name="Index">[in]指定要操作加密狗的序号</param>
        /// <returns></returns>
        [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern uint VikeyLogoff(ushort Index);

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct SVikeyTime
        {
            public byte cYear;
            public byte cMonth;
            public byte cDay;
            public byte cHour;
            public byte cMinute;
            public byte cSecond;
        }
        /// <summary>
        /// 获取时钟型加密狗中的内部独立时间
        /// </summary>
        /// <param name="Index"></param>
        /// <param name="pTime"></param>
        /// <returns></returns>
        [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern uint VikeyGetTime(ushort Index, out SVikeyTime pTime);
        /// <summary>
        /// 获取时钟型加密狗中的到期时间
        /// </summary>
        /// <param name="Index"></param>
        /// <param name="pTime"></param>
        /// <returns></returns>
        [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern uint VikeyGetValidTime(ushort Index, out SVikeyTime pTime);
        /// <summary>
        /// 检测时钟型加密狗的时钟功能是否到期
        /// </summary>
        /// <param name="Index">[in]指定要操作加密狗的序号</param>
        /// <param name="pIsValid">[out]返回是否到期结果 1表示没有到期   0表示已经到期</param>
        /// <returns></returns>
        [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern uint VikeyCheckValidTime(ushort Index, out byte pIsValid);
        /// <summary>
        /// 从加密狗中的获取4个双字的随机数数据
        /// </summary>
        /// <param name="Index">指定要操作加密狗的序号</param>
        /// <param name="pwRandom1"></param>
        /// <param name="pwRandom2"></param>
        /// <param name="pwRandom3"></param>
        /// <param name="pwRandom4"></param>
        /// <returns></returns>
        [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern uint ViKeyRandom(ushort Index, 
            out ushort pwRandom1, out ushort pwRandom2, out ushort pwRandom3, out ushort pwRandom4);
        [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern uint VikeyReadData(ushort Index, ushort Addr, ushort Length, byte[] buffer);
        [DllImport("ViKey.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern uint VikeyWriteData(ushort Index, ushort Addr, ushort Length, byte[] buffer);

        /// <summary>
        /// // 7.4.6版本(含)以后的加密狗必须在查找加密狗前调用VikeySetUserSN并输入正确的UserSN后面才能查找到所属用户的加密狗
        // 7.4.6版本以前的加密狗可以忽略此函数 不用调用此函数
        // UserSN在ViKey加密管理工具的->帮助中心页面->复制出来
        /// </summary>
        /// <param name="pUserSN"></param>
        /// <returns></returns>
        [DllImport("ViKey")]
        public static extern uint VikeySetUserSN(Byte[] pUserSN);

        /// <summary>
        /// //设置加密狗ApiKey 硬件版本为7.4.5(含)以后的加密狗必须要调用此接口才能登录
			//ApiKey 是由ViKey加密管理工具的->加密狗管理->密钥设置页面  通过Api密钥种子生成的
        /// </summary>
        /// <param name="Index"></param>
        /// <param name="pApiKey"></param>
        /// <returns></returns>
        [DllImport("ViKey")]
        public static extern uint VikeySetApiKey(ushort Index, Byte[] pApiKey);

        [DllImport("ViKey")]
        public static extern uint VikeyUninitialization();

    }
}
