mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
chg:
This commit is contained in:
parent
c0f91ddd09
commit
5f87b24493
2 changed files with 83 additions and 66 deletions
|
@ -1,6 +1,6 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 2017 Merlok
|
// Copyright (C) 2017 Merlok
|
||||||
//
|
// modified 2017 iceman
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
// the license.
|
// the license.
|
||||||
|
@ -12,8 +12,8 @@
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
int UsageCmdHFEMVSelect(void) {
|
int usage_emv_select(void) {
|
||||||
PrintAndLog("HELP : Executes select applet command:\n");
|
PrintAndLog("Executes select applet command:\n");
|
||||||
PrintAndLog("Usage: hf emv select [-s][-k][-a][-t] <HEX applet AID>\n");
|
PrintAndLog("Usage: hf emv select [-s][-k][-a][-t] <HEX applet AID>\n");
|
||||||
PrintAndLog(" Options:");
|
PrintAndLog(" Options:");
|
||||||
PrintAndLog(" -s : select card");
|
PrintAndLog(" -s : select card");
|
||||||
|
@ -21,8 +21,8 @@ int UsageCmdHFEMVSelect(void) {
|
||||||
PrintAndLog(" -a : show APDU reqests and responses\n");
|
PrintAndLog(" -a : show APDU reqests and responses\n");
|
||||||
PrintAndLog(" -t : TLV decode results\n");
|
PrintAndLog(" -t : TLV decode results\n");
|
||||||
PrintAndLog("Samples:");
|
PrintAndLog("Samples:");
|
||||||
PrintAndLog(" hf emv select -s a00000000101 -> select card, select applet");
|
PrintAndLog(" hf emv select -s a00000000101 -> select card, select applet");
|
||||||
PrintAndLog(" hf emv select -s -t a00000000101 -> select card, select applet, show result in TLV");
|
PrintAndLog(" hf emv select -s -t a00000000101 -> select card, select applet, show result in TLV");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,10 +33,8 @@ int CmdHFEMVSelect(const char *cmd) {
|
||||||
bool leaveSignalON = false;
|
bool leaveSignalON = false;
|
||||||
bool decodeTLV = false;
|
bool decodeTLV = false;
|
||||||
|
|
||||||
if (strlen(cmd) < 1) {
|
if (strlen(cmd) < 1)
|
||||||
UsageCmdHFEMVSelect();
|
return usage_emv_select();
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetAPDULogging(false);
|
SetAPDULogging(false);
|
||||||
|
|
||||||
|
@ -47,8 +45,7 @@ int CmdHFEMVSelect(const char *cmd) {
|
||||||
switch (param_getchar_indx(cmd, 1, cmdp)) {
|
switch (param_getchar_indx(cmd, 1, cmdp)) {
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'H':
|
case 'H':
|
||||||
UsageCmdHFEMVSelect();
|
return usage_emv_select();
|
||||||
return 0;
|
|
||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
case 'S':
|
||||||
activateField = true;
|
activateField = true;
|
||||||
|
@ -86,8 +83,6 @@ int CmdHFEMVSelect(const char *cmd) {
|
||||||
// we get all the hex to end of line with spaces
|
// we get all the hex to end of line with spaces
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cmdp++;
|
cmdp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,8 +104,8 @@ int CmdHFEMVSelect(const char *cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UsageCmdHFEMVSearch(void) {
|
int usage_emv_search(void) {
|
||||||
PrintAndLog("HELP : Tries to select all applets from applet list:\n");
|
PrintAndLog("Tries to select all applets from applet list:\n");
|
||||||
PrintAndLog("Usage: hf emv search [-s][-k][-a][-t]\n");
|
PrintAndLog("Usage: hf emv search [-s][-k][-a][-t]\n");
|
||||||
PrintAndLog(" Options:");
|
PrintAndLog(" Options:");
|
||||||
PrintAndLog(" -s : select card");
|
PrintAndLog(" -s : select card");
|
||||||
|
@ -118,8 +113,8 @@ int UsageCmdHFEMVSearch(void) {
|
||||||
PrintAndLog(" -a : show APDU reqests and responses\n");
|
PrintAndLog(" -a : show APDU reqests and responses\n");
|
||||||
PrintAndLog(" -t : TLV decode results of selected applets\n");
|
PrintAndLog(" -t : TLV decode results of selected applets\n");
|
||||||
PrintAndLog("Samples:");
|
PrintAndLog("Samples:");
|
||||||
PrintAndLog(" hf emv search -s -> select card and search");
|
PrintAndLog(" hf emv search -s -> select card and search");
|
||||||
PrintAndLog(" hf emv search -s -t -> select card, search and show result in TLV");
|
PrintAndLog(" hf emv search -s -t -> select card, search and show result in TLV");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,10 +124,8 @@ int CmdHFEMVSearch(const char *cmd) {
|
||||||
bool leaveSignalON = false;
|
bool leaveSignalON = false;
|
||||||
bool decodeTLV = false;
|
bool decodeTLV = false;
|
||||||
|
|
||||||
if (strlen(cmd) < 1) {
|
if (strlen(cmd) < 1)
|
||||||
UsageCmdHFEMVSearch();
|
return usage_emv_search();
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetAPDULogging(false);
|
SetAPDULogging(false);
|
||||||
|
|
||||||
|
@ -143,8 +136,7 @@ int CmdHFEMVSearch(const char *cmd) {
|
||||||
switch (param_getchar_indx(cmd, 1, cmdp)) {
|
switch (param_getchar_indx(cmd, 1, cmdp)) {
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'H':
|
case 'H':
|
||||||
UsageCmdHFEMVSearch();
|
return usage_emv_search();
|
||||||
return 0;
|
|
||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
case 'S':
|
||||||
activateField = true;
|
activateField = true;
|
||||||
|
@ -189,8 +181,8 @@ int CmdHFEMVSearch(const char *cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UsageCmdHFEMVPPSE(void) {
|
int usage_emv_ppse(void) {
|
||||||
PrintAndLog("HELP : Executes PSE/PPSE select command. It returns list of applet on the card:\n");
|
PrintAndLog("Executes PSE/PPSE select command. It returns list of applet on the card:\n");
|
||||||
PrintAndLog("Usage: hf emv pse [-s][-k][-1][-2][-a][-t]\n");
|
PrintAndLog("Usage: hf emv pse [-s][-k][-1][-2][-a][-t]\n");
|
||||||
PrintAndLog(" Options:");
|
PrintAndLog(" Options:");
|
||||||
PrintAndLog(" -s : select card");
|
PrintAndLog(" -s : select card");
|
||||||
|
@ -200,9 +192,9 @@ int UsageCmdHFEMVPPSE(void) {
|
||||||
PrintAndLog(" -a : show APDU reqests and responses\n");
|
PrintAndLog(" -a : show APDU reqests and responses\n");
|
||||||
PrintAndLog(" -t : TLV decode results\n");
|
PrintAndLog(" -t : TLV decode results\n");
|
||||||
PrintAndLog("Samples:");
|
PrintAndLog("Samples:");
|
||||||
PrintAndLog(" hf emv pse -s -1 -> select, get pse");
|
PrintAndLog(" hf emv pse -s -1 -> select, get pse");
|
||||||
PrintAndLog(" hf emv pse -s -k -2 -> select, get ppse, keep field");
|
PrintAndLog(" hf emv pse -s -k -2 -> select, get ppse, keep field");
|
||||||
PrintAndLog(" hf emv pse -s -t -2 -> select, get ppse, show result in TLV");
|
PrintAndLog(" hf emv pse -s -t -2 -> select, get ppse, show result in TLV");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,10 +205,8 @@ int CmdHFEMVPPSE(const char *cmd) {
|
||||||
bool leaveSignalON = false;
|
bool leaveSignalON = false;
|
||||||
bool decodeTLV = false;
|
bool decodeTLV = false;
|
||||||
|
|
||||||
if (strlen(cmd) < 1) {
|
if (strlen(cmd) < 1)
|
||||||
UsageCmdHFEMVPPSE();
|
return usage_emv_ppse();
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetAPDULogging(false);
|
SetAPDULogging(false);
|
||||||
|
|
||||||
|
@ -227,8 +217,7 @@ int CmdHFEMVPPSE(const char *cmd) {
|
||||||
switch (param_getchar_indx(cmd, 1, cmdp)) {
|
switch (param_getchar_indx(cmd, 1, cmdp)) {
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'H':
|
case 'H':
|
||||||
UsageCmdHFEMVPPSE();
|
return usage_emv_ppse();
|
||||||
return 0;
|
|
||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
case 'S':
|
||||||
activateField = true;
|
activateField = true;
|
||||||
|
@ -270,15 +259,14 @@ int CmdHFEMVPPSE(const char *cmd) {
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
|
||||||
if (decodeTLV)
|
if (decodeTLV)
|
||||||
TLVPrintFromBuffer(buf, len);
|
TLVPrintFromBuffer(buf, len);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int UsageCmdHFEMVExec(void) {
|
int usage_emv_exec(void) {
|
||||||
PrintAndLog("HELP : Executes EMV contactless transaction:\n");
|
PrintAndLog("Executes EMV contactless transaction:\n");
|
||||||
PrintAndLog("Usage: hf emv exec [-s][-a][-t]\n");
|
PrintAndLog("Usage: hf emv exec [-s][-a][-t]\n");
|
||||||
PrintAndLog(" Options:");
|
PrintAndLog(" Options:");
|
||||||
PrintAndLog(" -s : select card");
|
PrintAndLog(" -s : select card");
|
||||||
|
@ -290,8 +278,8 @@ int UsageCmdHFEMVExec(void) {
|
||||||
PrintAndLog(" -x : transaction type - VSDC. For test only. Not a standart behavior.\n");
|
PrintAndLog(" -x : transaction type - VSDC. For test only. Not a standart behavior.\n");
|
||||||
PrintAndLog("By default : transaction type - MSD.\n");
|
PrintAndLog("By default : transaction type - MSD.\n");
|
||||||
PrintAndLog("Samples:");
|
PrintAndLog("Samples:");
|
||||||
PrintAndLog(" hf emv pse -s -> select card");
|
PrintAndLog(" hf emv pse -s -> select card");
|
||||||
PrintAndLog(" hf emv pse -s -t -a -> select card, show responses in TLV, show APDU");
|
PrintAndLog(" hf emv pse -s -t -a -> select card, show responses in TLV, show APDU");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,10 +298,8 @@ int CmdHFEMVExec(const char *cmd) {
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (strlen(cmd) < 1) {
|
if (strlen(cmd) < 1)
|
||||||
UsageCmdHFEMVExec();
|
return usage_emv_exec();
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cmdp = 0;
|
int cmdp = 0;
|
||||||
while(param_getchar(cmd, cmdp) != 0x00) {
|
while(param_getchar(cmd, cmdp) != 0x00) {
|
||||||
|
@ -322,8 +308,7 @@ int CmdHFEMVExec(const char *cmd) {
|
||||||
switch (param_getchar_indx(cmd, 1, cmdp)) {
|
switch (param_getchar_indx(cmd, 1, cmdp)) {
|
||||||
case 'h':
|
case 'h':
|
||||||
case 'H':
|
case 'H':
|
||||||
UsageCmdHFEMVExec();
|
return usage_emv_exec();
|
||||||
return 0;
|
|
||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
case 'S':
|
||||||
activateField = true;
|
activateField = true;
|
||||||
|
@ -359,7 +344,6 @@ int CmdHFEMVExec(const char *cmd) {
|
||||||
cmdp++;
|
cmdp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// init applets list tree
|
// init applets list tree
|
||||||
struct tlvdb *tlvSelect = NULL;
|
struct tlvdb *tlvSelect = NULL;
|
||||||
const char *al = "Applets list";
|
const char *al = "Applets list";
|
||||||
|
@ -417,14 +401,14 @@ int CmdHFEMVExec(const char *cmd) {
|
||||||
|
|
||||||
if (decodeTLV)
|
if (decodeTLV)
|
||||||
TLVPrintFromBuffer(buf, len);
|
TLVPrintFromBuffer(buf, len);
|
||||||
PrintAndLog("* Selected.");
|
|
||||||
|
|
||||||
|
PrintAndLog("* Selected.");
|
||||||
PrintAndLog("\n* Init transaction parameters.");
|
PrintAndLog("\n* Init transaction parameters.");
|
||||||
|
|
||||||
//9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
|
//9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
|
||||||
switch(TrType) {
|
switch(TrType) {
|
||||||
case TT_MSD:
|
case TT_MSD:
|
||||||
TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD
|
TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD
|
||||||
break;
|
break;
|
||||||
// not standart for contactless. just for test.
|
// not standart for contactless. just for test.
|
||||||
case TT_VSDC:
|
case TT_VSDC:
|
||||||
|
@ -493,7 +477,7 @@ int CmdHFEMVExec(const char *cmd) {
|
||||||
|
|
||||||
if (len < 4 || (len - 4) % 4) {
|
if (len < 4 || (len - 4) % 4) {
|
||||||
PrintAndLog("ERROR: GPO response format1 parsing error. length=%d", len);
|
PrintAndLog("ERROR: GPO response format1 parsing error. length=%d", len);
|
||||||
} else {
|
} else {
|
||||||
// AIP
|
// AIP
|
||||||
struct tlvdb * f1AIP = tlvdb_fixed(0x82, 2, buf + 2);
|
struct tlvdb * f1AIP = tlvdb_fixed(0x82, 2, buf + 2);
|
||||||
tlvdb_add(tlvRoot, f1AIP);
|
tlvdb_add(tlvRoot, f1AIP);
|
||||||
|
@ -531,11 +515,11 @@ int CmdHFEMVExec(const char *cmd) {
|
||||||
|
|
||||||
PrintAndLog("\n* Read records from AFL.");
|
PrintAndLog("\n* Read records from AFL.");
|
||||||
const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL);
|
const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL);
|
||||||
if (!AFL || !AFL->len) {
|
|
||||||
PrintAndLog("WARNING: AFL not found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
while(AFL && AFL->len) {
|
if (!AFL || !AFL->len)
|
||||||
|
PrintAndLog("WARNING: AFL not found.");
|
||||||
|
|
||||||
|
while (AFL && AFL->len) {
|
||||||
if (AFL->len % 4) {
|
if (AFL->len % 4) {
|
||||||
PrintAndLog("ERROR: Wrong AFL length: %d", AFL->len);
|
PrintAndLog("ERROR: Wrong AFL length: %d", AFL->len);
|
||||||
break;
|
break;
|
||||||
|
@ -553,7 +537,7 @@ int CmdHFEMVExec(const char *cmd) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int n = SFIstart; n <= SFIend; n++) {
|
for (int n = SFIstart; n <= SFIend; n++) {
|
||||||
PrintAndLog("* * * SFI[%02x] %d", SFI, n);
|
PrintAndLog("* * * SFI[%02x] %d", SFI, n);
|
||||||
|
|
||||||
res = EMVReadRecord(true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot);
|
res = EMVReadRecord(true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot);
|
||||||
|
@ -573,7 +557,6 @@ int CmdHFEMVExec(const char *cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,9 +574,7 @@ int CmdHFEMVExec(const char *cmd) {
|
||||||
// DDA
|
// DDA
|
||||||
if (AIP & 0x0020) {
|
if (AIP & 0x0020) {
|
||||||
PrintAndLog("\n* DDA");
|
PrintAndLog("\n* DDA");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// transaction check
|
// transaction check
|
||||||
|
|
||||||
// qVSDC
|
// qVSDC
|
||||||
|
@ -760,14 +741,12 @@ int CmdHFEMVExec(const char *cmd) {
|
||||||
TLVPrintFromBuffer(buf, len);
|
TLVPrintFromBuffer(buf, len);
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLog("ERROR MSD: Track2 data not found.");
|
PrintAndLog("ERROR MSD: Track2 data not found.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DropField
|
|
||||||
DropField();
|
DropField();
|
||||||
|
|
||||||
// Destroy TLV's
|
// Destroy TLV's
|
||||||
|
@ -775,16 +754,47 @@ int CmdHFEMVExec(const char *cmd) {
|
||||||
tlvdb_free(tlvRoot);
|
tlvdb_free(tlvRoot);
|
||||||
|
|
||||||
PrintAndLog("\n* Transaction completed.");
|
PrintAndLog("\n* Transaction completed.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int usage_emv_getrnd(void){
|
||||||
|
PrintAndLog("retrieve the UN number from a terminal");
|
||||||
|
PrintAndLog("Usage: hf emv getrnd [h]");
|
||||||
|
PrintAndLog("Options:");
|
||||||
|
PrintAndLog(" h : this help");
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog("Samples:");
|
||||||
|
PrintAndLog(" hf emv getrnd");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//retrieve the UN number from a terminal
|
||||||
|
int CmdHfEMVGetrng(const char *Cmd) {
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
if ( cmdp == 'h' || cmdp == 'H') return usage_emv_getrnd();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CmdHfEMVList(const char *Cmd) {
|
||||||
|
return CmdHFList("7816");
|
||||||
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"exec", CmdHFEMVExec, 0, "Executes EMV contactless transaction."},
|
{"exec", CmdHFEMVExec, 0, "Executes EMV contactless transaction."},
|
||||||
{"pse", CmdHFEMVPPSE, 0, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."},
|
{"pse", CmdHFEMVPPSE, 0, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."},
|
||||||
{"search", CmdHFEMVSearch, 0, "Try to select all applets from applets list and print installed applets."},
|
{"search", CmdHFEMVSearch, 0, "Try to select all applets from applets list and print installed applets."},
|
||||||
{"select", CmdHFEMVSelect, 0, "Select applet."},
|
{"select", CmdHFEMVSelect, 0, "Select applet."},
|
||||||
|
|
||||||
|
/*
|
||||||
|
{"getrng", CmdHfEMVGetrng, 0, "get random number from terminal"},
|
||||||
|
{"eload", CmdHfEmvELoad, 0, "load EMV tag into device"},
|
||||||
|
{"dump", CmdHfEmvDump, 0, "dump EMV tag values"},
|
||||||
|
{"sim", CmdHfEmvSim, 0, "simulate EMV tag"},
|
||||||
|
{"clone", CmdHfEmvClone, 0, "clone an EMV tag"},
|
||||||
|
*/
|
||||||
|
{"list", CmdHfEMVList, 0, "[Deprecated] List ISO7816 history"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 2017 Merlok
|
// Copyright (C) 2017 Merlok
|
||||||
//
|
// modified 2017 iceman
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
// the license.
|
// the license.
|
||||||
|
@ -26,8 +26,15 @@
|
||||||
#include "emvcore.h"
|
#include "emvcore.h"
|
||||||
#include "apduinfo.h"
|
#include "apduinfo.h"
|
||||||
|
|
||||||
int CmdHFEMV(const char *Cmd);
|
|
||||||
|
|
||||||
#define TLV_ADD(tag, value)( tlvdb_add(tlvRoot, tlvdb_fixed(tag, sizeof(value) - 1, (const unsigned char *)value)) )
|
#define TLV_ADD(tag, value)( tlvdb_add(tlvRoot, tlvdb_fixed(tag, sizeof(value) - 1, (const unsigned char *)value)) )
|
||||||
|
|
||||||
|
int CmdHFEMV(const char *Cmd);
|
||||||
|
|
||||||
|
extern int CmdHFEMVSelect(const char *cmd);
|
||||||
|
extern int CmdHFEMVSearch(const char *cmd);
|
||||||
|
extern int CmdHFEMVPPSE(const char *cmd);
|
||||||
|
extern int CmdHFEMVExec(const char *cmd);
|
||||||
|
extern int CmdHfEMVGetrng(const char *Cmd);
|
||||||
|
extern int CmdHfEMVList(const char *Cmd);
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Add table
Add a link
Reference in a new issue