Ntag 424 DNA写入URI网址配置开启动态UID计数器镜像C#源码

本示例使用的发卡器:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.1d292c1bhY3wRa&ft=t&id=615391857885

一、函数声明

cs 复制代码
//外部函数声明:让设备发出声响--------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "pcdbeep", CallingConvention = CallingConvention.StdCall)]
static extern byte pcdbeep(Int32 xms);//xms单位为毫秒 

//读取设备编号,可做为软件加密狗用,也可以根据此编号在公司网站上查询保修期限-----------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "pcdgetdevicenumber", CallingConvention = CallingConvention.StdCall)]
static extern byte pcdgetdevicenumber(byte[] devicenumber);//devicenumber用于返回编号 

//获取IC卡芯片型号---------------------------------------------------------------------------------------------------------------------------------------- 
[DllImport("OUR_MIFARE.dll", EntryPoint = "getmifareversion")]
static extern byte getmifareversion(byte[] cardtypestr, byte[] AtqaSak, byte[] versionbuf, byte[] versionlen, byte[] retsw);

//激活Desfire卡、CPU卡------------------------------------------------------------------------------------------------------------------------------------ 
[DllImport("OUR_MIFARE.dll", EntryPoint = "cpurequest1")]
static extern byte cpurequest1(byte[] mypiccserial, byte[] myparam, byte[] myver, byte[] mycode, byte[] AtqaSak);

//CPU卡发送接收调试--------------------------------------------------------------------------------------------------------------------------------------- 
[DllImport("OUR_MIFARE.dll", EntryPoint = "cpuisoapdu")]
static extern byte cpuisoapdu(byte[] sendbuf, Int32 datalen, byte[] revbuf, byte[] revlen);

//EV2密钥认证---------------------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "desfireauthkeyev2")]
static extern byte desfireauthkeyev2(byte[] keybuf, byte keyid, byte authmode, byte[] retsw);

//更改卡密钥---------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "ntagchangkey")]
static extern byte ntagchangkey(byte[] newkeybuf, byte keyid, byte onecode, byte[] oldkeybuf, byte[] retsw);

//更改随机UID---------------------------------------------------------------------------------------------------------------------------------
[DllImport("OUR_MIFARE.dll", EntryPoint = "ntagsetconfiguration")]
static extern byte ntagsetconfiguration(byte ctr, byte[] setbuf, byte beflen,  byte[] retsw);

//------------------------------------------------------------------------------------------------------------------------------------------------------    
//清空ForumType4类标签NDEF数据缓冲
[DllImport("OUR_MIFARE.dll", EntryPoint = "tagbuf_forumtype4_clear", CallingConvention = CallingConvention.StdCall)]
static extern byte tagbuf_forumtype4_clear();//

//------------------------------------------------------------------------------------------------------------------------------------------------------    
//生成NDEF URI数据缓冲
[DllImport("OUR_MIFARE.dll", EntryPoint = "tagbuf_adduri", CallingConvention = CallingConvention.StdCall)]
static extern byte tagbuf_adduri(string languagecodestr, int languagecodestrlen, string titlestr, int titlestrlen, int uriheaderindex, string uristr, int uristrlen);

//------------------------------------------------------------------------------------------------------------------------------------------------------    
//将NDEF数据缓冲写入ForumType4标签 
[DllImport("OUR_MIFARE.dll", EntryPoint = "forumtype4_write_ndeftag", CallingConvention = CallingConvention.StdCall)]
static extern byte forumtype4_write_ndeftag(byte ctrlword, byte[] serial, byte[] seriallen, byte[] ndefwritekey);

//------------------------------------------------------------------------------------------------------------------------------------------------------    
//读取ForumType4标签内的NDEF信息
[DllImport("OUR_MIFARE.dll", EntryPoint = "forumtype4_read_ndeftag", CallingConvention = CallingConvention.StdCall)]
static extern byte forumtype4_read_ndeftag(byte ctrlword, byte[] serial, byte[] seriallen, byte[] ndefwritekey);

//------------------------------------------------------------------------------------------------------------------------------------------------------    
//解析数据缓冲中的NDEF信息
[DllImport("OUR_MIFARE.dll", EntryPoint = "tagbuf_read", CallingConvention = CallingConvention.StdCall)]
static extern byte tagbuf_read(byte[] revstr, byte[] revstrlen, byte[] recordnumber);

//------------------------------------------------------------------------------------------------------------------------------------------------------    
//修改424卡配置信息
[DllImport("OUR_MIFARE.dll", EntryPoint = "ntagchangefilesettings", CallingConvention = CallingConvention.StdCall)]
static extern byte ntagchangefilesettings(byte commmode, byte fileno, byte[] settingsbuf, int settingslen, byte[] retsw);

//------------------------------------------------------------------------------------------------------------------------------------------------------    
//读取424卡配置信息
[DllImport("OUR_MIFARE.dll", EntryPoint = "ntagreadfilesettings", CallingConvention = CallingConvention.StdCall)]
static extern byte ntagreadfilesettings(byte commmode, byte fileno, byte[] settingsbuf, byte[] revbuflen, byte[] retsw);

二、写入URI网址

cs 复制代码
private void button11_Click(object sender, EventArgs e)
{
	byte myctrlword=0x00;
	byte[] picckey = new byte[200];     //需要认证的密码

	if (checkBox6.Checked)      //AES-128密文+MAC模式
	{
		byte[] keybuff = new byte[200];
		if (checkhexstr(textBox8.Text.Trim(), 16, keybuff) == false)
		{
			MessageBox.Show("十六进制认证密钥输入错误,请输入16字节认证密钥!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
			textBox8.Select();
			return;
		}

		switch (comboBox13.SelectedIndex)
		{
			case 0:
				myctrlword = 0x40;
				break;
			case 1:
				myctrlword = 0x41;
				break;
			case 2:
				myctrlword = 0x43;
				break;
		}

		picckey[0] = 4;     //AES,用71指令认证
		picckey[1] =(byte) numericUpDown_keyid.Value ;
		for (int j = 0; j < 16; j++)
		{
			picckey[j + 2] = keybuff[j];
		}                
	}

	string languagecodestr = "en";  //语言编码,英文为en,中文为zh
	int languagecodestrlen = languagecodestr.Length;

	string titlestr = textBox4.Text.Trim(); //标题
	int titlestrlen = System.Text.Encoding.GetEncoding(936).GetBytes(titlestr).Length; //标题长度

	int uriheaderindex = comboBox4.SelectedIndex;   //前缀

	string uristr = textBox5.Text.Trim();   //uri
	int uristrlen = System.Text.Encoding.GetEncoding(936).GetBytes(uristr).Length; //uri长度

	tagbuf_forumtype4_clear(); //清空标签数据缓冲
	byte status = tagbuf_adduri(languagecodestr, languagecodestrlen, titlestr, titlestrlen, uriheaderindex, uristr, uristrlen); //可以用此方法写入多条记录
	if (status > 0)
	{
		MessageBox.Show("将写卡信息加入写卡缓冲时返回错误代码:" + status.ToString("D") , "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
		return;
	}
	byte[] mypiccserial = new byte[7];
	byte[] mypiccseriallen = new byte[1];
	status = forumtype4_write_ndeftag(myctrlword, mypiccserial, mypiccseriallen, picckey);
	if (status == 0)
	{
		pcdbeep(38);
		string carduid = "ForumType4UID:";
		for (int i = 0; i < mypiccseriallen[0]; i++)
		{
			carduid = carduid + mypiccserial[i].ToString("X02");
		}
		MessageBox.Show(carduid + ",URI网址写入成功!!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
	}
	else { MessageDispInfo(status); }
}

三、修改卡片配置开启动态UID、计数器镜像

cs 复制代码
private void button14_Click(object sender, EventArgs e)
{
	byte[] settingsbuf = new byte[32];      //卡数据缓冲:1+2+1+2+3*8=30
	byte[] retsw = new byte[2];             //返回值

	switch (comboBox7.SelectedIndex)
	{
		case 0:
			settingsbuf[0] = 0;   //明文
			break;
		case 1:
			settingsbuf[0] = 1;   //MAC保护
			break;
		default:
			settingsbuf[0] = 3;     //密文 MAC保护
			break;
	}

	if (checkBox_SDM.Checked) { settingsbuf[0] = (byte)(settingsbuf[0] + 0x40); }   //启用SDM镜像

	//文件访问权限
	if (comboBox11.SelectedIndex < 5)    
	{
		settingsbuf[1] = (byte)comboBox11.SelectedIndex;        //更改指令 需要先认证的密码
	} 
	else 
	{
		if (comboBox11.SelectedIndex == 5)
		{
			settingsbuf[1] = 0x0e;     //无需密码,直接用明文
		}
		else
		{
			settingsbuf[1] = 0x0f;    //禁止该指令
		}
	}


	if (comboBox10.SelectedIndex < 5)    
	{
		settingsbuf[1] = (byte)(settingsbuf[1] + comboBox10.SelectedIndex * 16);        //读写指令 需要先认证的密码
	}
	else
	{
		if (comboBox10.SelectedIndex == 5)
		{
			settingsbuf[1] =(byte)(settingsbuf[1]+ 0xe0);     //无需密码,直接用明文
		}
		else
		{
			settingsbuf[1] =(byte)(settingsbuf[1] + 0xf0);    //禁止该指令
		}
	}

	if (comboBox9.SelectedIndex < 5)    
	{
		settingsbuf[2] = (byte)comboBox9.SelectedIndex;        //只写指令 需要先认证的密码
	}
	else
	{
		if (comboBox9.SelectedIndex == 5)
		{
			settingsbuf[2] = 0x0e;     //无需密码,直接用明文
		}
		else
		{
			settingsbuf[2] = 0x0f;    //禁止该指令
		}
	}

	if (comboBox8.SelectedIndex < 5)
	{
		settingsbuf[2] = (byte)(settingsbuf[2] + comboBox8.SelectedIndex * 16);        //只读指令 需要先认证的密码
	}
	else
	{
		if (comboBox8.SelectedIndex == 5)
		{
			settingsbuf[2] = (byte)(settingsbuf[2] + 0xe0);     //无需密码,直接用明文
		}
		else
		{
			settingsbuf[2] =(byte)(settingsbuf[2] +  0xf0);    //禁止该指令
		}
	}

	int j = 3;

	if ((settingsbuf[0] & 0x40) > 0)        //已经启用SDM镜像
	{
		//SDMOptions
		settingsbuf[3] = 1;     //Encoding mode默认为ASCII
		if (checkBox_UID.Checked)
		{
			settingsbuf[3] = (byte)(settingsbuf[3] + 0x80);      //启用UID镜像
		}

		if (checkBox_CounterMirror.Checked)
		{
			settingsbuf[3] = (byte)(settingsbuf[3] + 0x40);       //启用计数器镜像
		}

		if (checkBox_CounterLimit.Checked)
		{
			settingsbuf[3] = (byte)(settingsbuf[3] + 0x20);       //计数器限额
		}

		if (checkBox_SDMNCF.Checked)
		{
			settingsbuf[3] = (byte)(settingsbuf[3] + 0x10);       //SDMENCFileData
		}

		//SDMAccessRights
		settingsbuf[4] = 0xf0;      //Bit 7-4默认为F,暂无使用

		//计数器访问 需要先认证的密码 comboBox_counterkey
		if (comboBox_counterkey.SelectedIndex < 5)
		{
			settingsbuf[4] = (byte)(settingsbuf[4] + comboBox_counterkey.SelectedIndex );        
		}
		else
		{
			if (comboBox_counterkey.SelectedIndex == 5)
			{
				settingsbuf[4] =(byte)(settingsbuf[4] + 0x0e);     //无需密码,直接用明文
			}
			else
			{
				settingsbuf[4] = (byte)(settingsbuf[4] +0x0f);    //禁止该指令
			}
		}

		//SDMMetaRead access right
		if (comboBox_SdmPower.SelectedIndex < 5)
		{
			settingsbuf[5] = (byte)(comboBox_SdmPower.SelectedIndex * 16);        //只读指令 需要先认证的密码
		}
		else
		{
			if (comboBox_SdmPower.SelectedIndex == 5)
			{
				settingsbuf[5] = 0xe0;     //无需密码,直接用明文
			}
			else
			{
				settingsbuf[5] = 0xf0;    //禁止该指令
			}
		}

		j = j + 1;

		//SDMFileRead access right
		if (comboBox_cmackey.SelectedIndex < 5)
		{
			settingsbuf[5] = (byte)(settingsbuf[5] + comboBox_cmackey.SelectedIndex);        //无需密码,直接用明文
		}
		else
		{
			settingsbuf[5] = (byte)(settingsbuf[5] + 0x0f);    //禁止该指令
		}

		j = 6;
		byte[] bytearray = new byte[3];

		//-----------------------------------------------------------------------------------------------------
		if ((settingsbuf[5] & 0xf0) == 0xe0)
		{
			if ((settingsbuf[3] & 0x80) > 0)   //UID镜像位置
			{
				if (Get3Byte((long)numericUpDown1.Value, bytearray))
				{
					settingsbuf[6] = bytearray[0];
					settingsbuf[7] = bytearray[1];
					settingsbuf[8] = bytearray[2];
				}
			   
				j = 9;
			}

			if ((settingsbuf[3] & 0x40) > 0)   //计数器镜像
			{
				if (Get3Byte((long)numericUpDown5.Value, bytearray))
				{
					settingsbuf[j] = bytearray[0];
					settingsbuf[j+1] = bytearray[1];
					settingsbuf[j+2] = bytearray[2];
					j = j + 3;
				}
				else
				{
					MessageBox.Show("计数器数据位置输入错误!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}                             
			}
		}
		else
		{
			if ((settingsbuf[5] & 0xf0) < 0x50)
			{
				if (Get3Byte((long)numericUpDown3.Value, bytearray))   //ENCPICCDataOffset(UID和随机数加密后的数据位置)
				{
					settingsbuf[6] = bytearray[0];
					settingsbuf[7] = bytearray[1];
					settingsbuf[8] = bytearray[2];
					j = 9;
				}
				else
				{
					MessageBox.Show("PICCDataOffset输入错误!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}    
			}
		}
		//----------------------------------------------------------------------------------------------------------------

		if ((settingsbuf[5] & 0x0f) != 0x0f)
		{
			if (Get3Byte((long)numericUpDown2.Value, bytearray))    //SDMMACInputOffset
			{
				settingsbuf[j] = bytearray[0];
				settingsbuf[j + 1] = bytearray[1];
				settingsbuf[j + 2] = bytearray[2];
				j = j + 3;
			}
			else
			{
				MessageBox.Show("SDMMACInputOffset输入错误!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}

			if ((settingsbuf[3] & 0x10) > 0)  
			{
				if (Get3Byte((long)numericUpDown7.Value, bytearray))        //SDMENCOffset
				{
					settingsbuf[j] = bytearray[0];
					settingsbuf[j + 1] = bytearray[1];
					settingsbuf[j + 2] = bytearray[2];
					j = j + 3;
				}
				else
				{
					MessageBox.Show("SDMENCOffset输入错误!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}

				if (Get3Byte((long)numericUpDown8.Value, bytearray))        //SDMENCLength
				{
					settingsbuf[j] = bytearray[0];
					settingsbuf[j + 1] = bytearray[1];
					settingsbuf[j + 2] = bytearray[2];
					j = j + 3;
				}
				else
				{
					MessageBox.Show("SDMENCLength输入错误!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}    
			}

			if (Get3Byte((long)numericUpDown4.Value, bytearray))        //SDMMACOffset
			{
				settingsbuf[j] = bytearray[0];
				settingsbuf[j + 1] = bytearray[1];
				settingsbuf[j + 2] = bytearray[2];
				j = j + 3;
			}
			else
			{
				MessageBox.Show("SDMENCOffset输入错误!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
		}

		if ((settingsbuf[3] & 0x20) > 0)  //计数器限额值
		{
			if (Get3Byte((long)numericUpDown6.Value, bytearray))        //计数器限额值
			{
				settingsbuf[j] = bytearray[0];
				settingsbuf[j + 1] = bytearray[1];
				settingsbuf[j + 2] = bytearray[2];
				j = j + 3;
			}
			else
			{
				MessageBox.Show("计数器限额值输入错误!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
		}
	}

	//参数设定规则校验--------------------------------------------------------------------------------------
	if ((settingsbuf[3] & 0x40) > 0)        //已经启用SDM镜像
	{
		if ((settingsbuf[3] & 0xC0) == 0)
		{
			MessageBox.Show("当开启SDM镜像时,必须开启UID镜像或计数器镜像!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
			return;
		}

		if ((settingsbuf[3] & 0x80) > 0)       //已经启用UID镜像
		{
			if ((settingsbuf[5] & 0xF0) == 0xf0)
			{
				MessageBox.Show("当启用UID镜像时,SDM元数据读取访问权限不能为禁止!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
		}
		else
		{
			if ((settingsbuf[5] & 0xF0) < 0xf0)
			{
				MessageBox.Show("当不开启UID镜像时,SDM元数据读取访问权限只能为禁止!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
		}

		if ((settingsbuf[3] & 0x40) == 0)       //当不开启计数器镜像时
		{
			if ((settingsbuf[4] & 0x0f) <0x0f)
			{
				MessageBox.Show("当不开启计数器镜像时,SDM计数器检索密钥只能为禁止!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
		}

		int i;
		if ((settingsbuf[3] & 0x80) > 0 || (settingsbuf[5] & 0xF0) < 0x50)
		{
			i = 9;      //存在UIDOffset或PICCDataOffset'
		}
		else
		{
			i = 6;
		}

		if (settingsbuf[5] == 0xe0)
		{
			i = i + 3;    //SDMReadCtrOffset存在
		}

		long SDMMACInputOffset=0;
		long SDMENCOffset=0;
		long SDMENCLength=0;
		long SDMMACOffset=0;
		if ((settingsbuf[5] & 0x0f) < 0x05)  //SDMFileRead access right
		{
			SDMMACInputOffset = settingsbuf[i] + settingsbuf[i + 1] * 256 + settingsbuf[i + 2] * 65536;
			i = i + 3;

			if ((settingsbuf[3] & 0x10) > 0)        //SDMENCFileData
			{
				SDMENCOffset = settingsbuf[i] + settingsbuf[i + 1] * 256 + settingsbuf[i + 2] * 65536;
				i = i + 3;

				SDMENCLength = settingsbuf[i] + settingsbuf[i + 1] * 256 + settingsbuf[i + 2] * 65536;
				i = i + 3;
			}

			SDMMACOffset = settingsbuf[i] + settingsbuf[i + 1] * 256 + settingsbuf[i + 2] * 65536;
			i = i + 3;

			if ((settingsbuf[3] & 0x10) > 0)        //SDMENCFileData
			{
				if (SDMENCOffset < SDMMACInputOffset){
					MessageBox.Show("SDMENCOffset不能小于SDMMACInputOffset!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}

				if (SDMENCLength < 32)
				{
					MessageBox.Show("SDMENCLength不能小于32!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}

				if (SDMMACOffset < (SDMENCOffset + SDMENCLength))
				{
					MessageBox.Show("SDMMACOffset不能小于(SDMENCOffset + SDMENCLength)!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}
			}
			else
			{
				if (SDMMACOffset < SDMMACInputOffset)
				{
					MessageBox.Show("SDMMACOffset不能小于SDMMACInputOffset!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
					return;
				}
			}
		}
	}

	string strls = "";
	for (int i = 0; i < j; i++)
	{
		strls = strls + settingsbuf[i].ToString("X02");
	}
	textBox9.Text = strls;

	byte status = ntagchangefilesettings((byte)comboBox5.SelectedIndex, 2, settingsbuf, j, retsw);
	strls = retsw[0].ToString("X02") + retsw[1].ToString("X02");
	if (strls == "9100")
	{
		pcdbeep(50);
		MessageBox.Show("更改配置成功!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
	}
	else
	{
		if (strls == "91AE")
		{
			if (comboBox5.SelectedIndex == 1)
			{
				MessageBox.Show("卡片返回错误代码:" + strls + ",更改指令被禁止或密码未认证或密码不对,请先用正确的密码号进行认证再试!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			else
			{
				MessageBox.Show("卡片返回错误代码:" + strls + ",更改指令被禁止或不支持明文操作,请先用正确的密码号进行认证并且选择"密文+MAC保护的通信模式"再试!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}
		else
		{
			MessageBox.Show("卡片返回错误代码:" + strls + "说明:" + RetTextFromStr(strls), "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
		}
	}

}

四、认证AES密钥

cs 复制代码
private void button18_Click(object sender, EventArgs e)
{
	byte[] authkeybuf = new byte[24];
	byte[] retsw = new byte[2];
	string retstr;
	int keylen = 16;

	if (checkhexstr(textBox6.Text.Trim(), keylen, authkeybuf) == false)
	{
		MessageBox.Show("十六进制认证密钥输入错误,请输入 " + keylen.ToString("D") + " 字节的16进制认证密钥!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
		return;
	}
	byte status = desfireauthkeyev2(authkeybuf, Convert.ToByte(keyid.Value), Convert.ToByte(comboBox14.SelectedIndex), retsw);
	retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");

	if (status > 0)
	{
		MessageBox.Show("认证密码操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
	}
	else
	{
		MessageBox.Show("认证密码操作,卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
	}
}

五、更改卡片密钥

cs 复制代码
private void button6_Click(object sender, EventArgs e)
{
	byte[] newkeybuf = new byte[24];
	byte[] oldkeybuf = new byte[24];
	byte[] retsw = new byte[2];
	string retstr;
	int keylen = 16;

	if (checkhexstr(textBox3.Text.Trim(), keylen, newkeybuf) == false)
	{
		MessageBox.Show("十六进制新密钥输入错误,请输入 " + keylen.ToString("D") + " 字节的16进制新密钥!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
		return;
	}

	if (checkhexstr(textBox6.Text.Trim(), keylen, oldkeybuf) == false)
	{
		MessageBox.Show("十六进制旧密钥输入错误,请输入 " + keylen.ToString("D") + " 字节的16进制旧密钥!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
		return;
	}


	byte status = ntagchangkey(newkeybuf, Convert.ToByte(editkeyid.Value), 1, oldkeybuf, retsw);
	retstr = retsw[0].ToString("X2") + retsw[1].ToString("X2");

	if (status > 0)
	{
		MessageBox.Show("更改卡密钥操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
	}
	else
	{
		if (retstr == "91AE")
		{
			MessageBox.Show("更改卡密钥操作返回异常:" + status.ToString("D") + ",卡片返回代码:" + retstr + ",说明:更改密码指令被禁止或密码未认证或密码不对,请先用0号密码认证后再试!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
		}
		else
		{
			MessageBox.Show("更改卡密钥操作,卡片返回代码:" + retstr + ",说明:" + RetTextFromStr(retstr), "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
		}
	}
}
相关推荐
万19995 小时前
asp.net core webapi------3.AutoMapper的使用
c#·.netcore
唐青枫5 小时前
C#.NET 路由机制深入解析:从传统路由到 Endpoint Routing
c#·.net
hixiong12316 小时前
C# OpenCVSharp使用 读光-票证检测矫正模型
人工智能·opencv·c#
霜绛16 小时前
C#知识补充(二)——命名空间、泛型、委托和事件
开发语言·学习·unity·c#
好望角雾眠16 小时前
第四阶段C#通讯开发-6:Socket之UDP
开发语言·笔记·学习·udp·c#
霜绛17 小时前
C#知识补充(一)——ref和out、成员属性、万物之父和装箱拆箱、抽象类和抽象方法、接口
开发语言·笔记·学习·c#
爱编程的鱼18 小时前
C# var 关键字详解:从入门到精通
开发语言·c#·solr
玩泥巴的19 小时前
解放双手!使用Roslyn生成代码让你的 HTTP 客户端开发变得如此简单
c#·.net·代码生成·roslyn
星释20 小时前
Rust 练习册 :Pig Latin与语言游戏
游戏·rust·c#