win版助手改为使用url-protocol方式,不再启动本地http服务了。

feature/assist-websocket
Apex Liu 2022-05-14 19:11:13 +08:00
parent f71d9fa1b1
commit c701a90670
34 changed files with 1603 additions and 2731 deletions

View File

@ -124,15 +124,13 @@ class Env(object):
if warn_miss_tool:
cc.w(' - can not locate `perl`, so I can not build openssl.')
self.visual_studio_path = self._get_visual_studio_path()
if self.visual_studio_path is None or not os.path.exists(self.visual_studio_path):
if warn_miss_tool:
cc.w(' - can not locate Visual Studio installation, so I can build nothing.')
# self.visual_studio_path = self._get_visual_studio_path()
# if self.visual_studio_path is None or not os.path.exists(self.visual_studio_path):
# if warn_miss_tool:
# cc.w(' - can not locate Visual Studio installation, so I can build nothing.')
if 'msbuild' in _tmp:
self.msbuild = _tmp['msbuild']
else:
self.msbuild = self._get_msbuild()
if self.msbuild is None or not os.path.exists(self.msbuild):
if warn_miss_tool:
@ -250,15 +248,15 @@ class Env(object):
# return p[0] if p is not None else None
def _get_visual_studio_path(self):
p = self._winreg_read(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7', r'15.0')
return p[0] if p is not None else None
def _get_msbuild(self):
vs2017 = self._get_visual_studio_path()
if vs2017 is None:
return None
return os.path.join(vs2017, 'MSBuild', '15.0', 'Bin', 'MSBuild.exe')
# def _get_visual_studio_path(self):
# p = self._winreg_read(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\WOW6432Node\Microsoft\VisualStudio\SxS\VS7', r'15.0')
# return p[0] if p is not None else None
#
# def _get_msbuild(self):
# vs2017 = self._get_visual_studio_path()
# if vs2017 is None:
# return None
# return os.path.join(vs2017, 'MSBuild', '15.0', 'Bin', 'MSBuild.exe')
def _get_perl(self):
p = self._winreg_read(winreg.HKEY_LOCAL_MACHINE, r'SOFTWARE\perl', 'BinDir')

View File

@ -1,21 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDhDCCAmygAwIBAgIBADANBgkqhkiG9w0BAQsFADAzMQswCQYDVQQGEwJDTjEN
MAsGA1UEChMEdHA0YTEVMBMGA1UEAxMMVFA0QSBSb290IENBMCAXDTIxMDcwMzA1
NTA0N1oYDzIxMjEwNjA5MDU1MDQ3WjAzMQswCQYDVQQGEwJDTjENMAsGA1UEChME
dHA0YTEVMBMGA1UEAxMMVFA0QSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEArk1q4RZGBRJwJPYjEVUskFiFadz6trJC5430DFxwLVCEvMHh
KlgTb/a1jC53DmGsbJHlNs9yd7ja08AUITsbcUnST976LFpOe+ck6E2x1rhlWrXP
rN1B+xzfFy1AMNubr97MHoCfrdErWxKzaRUX55GRXbWMsugcfsvr7t8JQh3xbo91
0Xcq0QvC7t5PoDQ6VX6Uc0Utx7lbW4OoA7wU4d2JjUcvBlQHQsu/qZLojzXyEl2Q
AwfILypiapl01iBM2XPpaPpXC58//Etx/ul3oHsLsPEUzxbiCptx8xjE9IWaKqf6
GlnjhpZzw8W24h2CvWyy9EYw3QdUI4EBQhVZtwIDAQABo4GgMIGdMB0GA1UdDgQW
BBR7wuXeCTbB+3mfLFcwm3anZ2C4UDBbBgNVHSMEVDBSgBR7wuXeCTbB+3mfLFcw
m3anZ2C4UKE3pDUwMzELMAkGA1UEBhMCQ04xDTALBgNVBAoTBHRwNGExFTATBgNV
BAMTDFRQNEEgUm9vdCBDQYIBADAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
AwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAfd12+QaYrtM/KfZnSqDLwvGksuOZ1OOX
8xApJo35GPpFLlFTdkwQ9Z3unWXIfJGFYGAiRpy83ghraOaxqGDngqJdr1hT0RTQ
KqVlBZufbB010Dhl/6TcetZTeXLa3Xjw9d9jc79Prmc/485pa6lh2QSodHJwfz7J
zzUe5g09hzLdqrurIGdsMzFRMRwo2KpXMhx4jEqk4IMTD9rQnzCxBWS8rPbsnDTm
f0/kW3R70JbUFN5Dnd669g6t1L923+ICysR6q+Ep7cGhY1b9iMCn4Ia8r4VwgYuH
PAvw0ajzvj7RRW0M9Szo2jaWXHz6XeKmK3t8TW2x4gOn+irOenItEg==
-----END CERTIFICATE-----

View File

@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDf3tDR3kM5solf
OA9AKlM+DzFgG9G0RzR8b91KdIwWzIk+WyyqOHEkyXX3QmykKWqE74ZTB1/iWpWk
5Z73LonGgdc9alfkP/esAUPbF1030Z7AO9Kswt9ZRFv4qEMCFkPdz5bJ5EFble2z
OVmkLcJJpvDvuB82Sja4gfVaG+Lt++om9CxSL93bvn9cWs8EMC9ClbgPqu3N5Gnb
mulQDFwsnJDTkMhn8QvkXWkoQrI43vSqdQpGzqGCKcdpDhYbLzd/Vmf9bZTIvYZb
n1TYT8o+zGcpwQyT0HDhT9LlwRgh0jbYy63wSil0pLnA1DruZyZIgp8sQXKh6IU6
h9g4tC2jAgMBAAECggEAL1hMCVZcGUOs0bplX0iUOje0VYMMone8neR6hFiJl/jB
vbJCi+1L4F/K1vPxTfaEVIDjg4O3v4MwyqLVL6lj8dtbzd1DoT31/yZ1V0xlpnxq
enUsZOUBnztZyAitwy86Qxq35RKkz92xW4nxb0tOH41yvv/NegnP8M1rOhdTssiC
nX8KQgdZLuVI3Q5PeJpycKTthXIsxqQufZJZAyYrXZsR6gkGaNlOV/7eNFrh6PPS
pStHHQYWPyjyUZREHzo371ZKawXaC5pJZY7b4s76mCPOxpL8VjFuXKAdW61po6XV
Ff4wAd/eutyaur6ZgriY8oRX+10FnyYiwRo3QUv+4QKBgQD9PNGvN6BqKxhWM3Su
HGpcp/fyNMidoKdP1maFEtisMUIhNm+i1CSsn1dn006bv/6igSmVNI4FdyCU8dP/
tbWUWl0r3fTRnlduJxkvZmoVXqW78BXx4ejnKDZfTNtUNWT/4h1nKTYQh42O/WXC
Wzl/LB154dDMMUIp+KEnOFQhdwKBgQDiT/yqcoYVYCV2nk/q2BML8/NvhHK1+Hgv
oqGKe2zmNxQcCH/H70TjWJRojxQJZe4311MP2Qu5RvgHfmtotb3Fi2gGYv6dwS9n
VdcFILjoiQAMe8KLfZBGAmsN3bQ9g2BrbD1sFjVCUsOT1c2zI4ESQXW5Dz4F5Fpe
9zBYR1DANQKBgF15mLDDqLvnwmj3P2eRZ5ViDvzhjPfaOEgZDOisBzywRge6b0S8
Z/ksK/hQIGEPYq+bW70OlCniSi2Qgj+OVEM5g9DQcjD58K3hUsOTWy8eK7EOsxsA
15aT2lYdKYyQ1QI69b2BkcpSLueME4bFY5jUsOCvgQIOYKzbcKjoeu2LAoGAFl3L
XdkVsVUgPrnkshQKxdqlS3cukxdsYWDUUEhkedglr6OTZWIbT9C4UiEZ3NfrFC++
sMlFpFkEOFFhMicMC1L8w+zStyqZkb/lEUernqezjohIsNqHALRKekNYBeBPDi7T
XzROrTBazeiKfNLcdb5scQ61lYV8/Pe3GnJp46UCgYEAmI8xIBGBNWcXY1V4ismY
FM/8anrOFSPrgmyp9NcUu7mXxIWTPg+3vIykwV+uqkWh0BgSnGitQ9BKIHgJU3sz
K8ft7edhwgKq3x8y0Gs8+1JOm2TvKhavZoKcSOi6/2xeGunMbEpL/zsOcEMOmp+V
a/PsyIEsETicUZJmFZxAiGs=
-----END PRIVATE KEY-----

View File

@ -1,22 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIDkzCCAnugAwIBAgIGAhNQQY0BMA0GCSqGSIb3DQEBCwUAMDMxCzAJBgNVBAYT
AkNOMQ0wCwYDVQQKEwR0cDRhMRUwEwYDVQQDEwxUUDRBIFJvb3QgQ0EwHhcNMjEw
NzAzMDU1MDU0WhcNMjIwNzAzMDU1MDU0WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3Qw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDf3tDR3kM5solfOA9AKlM+
DzFgG9G0RzR8b91KdIwWzIk+WyyqOHEkyXX3QmykKWqE74ZTB1/iWpWk5Z73LonG
gdc9alfkP/esAUPbF1030Z7AO9Kswt9ZRFv4qEMCFkPdz5bJ5EFble2zOVmkLcJJ
pvDvuB82Sja4gfVaG+Lt++om9CxSL93bvn9cWs8EMC9ClbgPqu3N5GnbmulQDFws
nJDTkMhn8QvkXWkoQrI43vSqdQpGzqGCKcdpDhYbLzd/Vmf9bZTIvYZbn1TYT8o+
zGcpwQyT0HDhT9LlwRgh0jbYy63wSil0pLnA1DruZyZIgp8sQXKh6IU6h9g4tC2j
AgMBAAGjgcswgcgwHQYDVR0OBBYEFBKWKx7CKoM7m5kaK5uN5woCrFFCMFsGA1Ud
IwRUMFKAFHvC5d4JNsH7eZ8sVzCbdqdnYLhQoTekNTAzMQswCQYDVQQGEwJDTjEN
MAsGA1UEChMEdHA0YTEVMBMGA1UEAxMMVFA0QSBSb290IENBggEAMAwGA1UdEwEB
/wQCMAAwCwYDVR0PBAQDAgXgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMBoGA1UdEQQT
MBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAeM48uhEnkmdw
viwmdErYx/aYjl4Cs1woFAalkrhX42Ogld3B/LhIuBePiuKrPmrCOtM03qUXFKq4
Fg0A4eZnUiPHxTUzToa4yipY2xlxTh5oxy/MmXRyKfCO10mq7gTqtU7iUYy3fPvE
eDfL5ZIaCT+G8a/UI/EQjfhu00C37zRIvfhYkqCho+NoM087oADVQ9CGStWy4aHs
hh2fkKBZEYgOFSm6jPotEiqGJr2KHZ7pLi9f8zGsW2Srdpc7IC1aYD2QzHMqptzt
YEAFsMw2OvK+7zJGkJkNnejlcr9gc6j2JWkYYTuCI2D+rh0nFDkmMnDchzyYJyOQ
6U4OOh97yg==
-----END CERTIFICATE-----

View File

@ -1,45 +1,52 @@
{
"file_version": 3,
"ssh": {
"selected": "putty",
"available": [{
"name": "putty",
"display": "PuTTY内置",
"app": "{assist_tools_path}\\putty\\putty.exe",
"cmdline": "-ssh -pw **** -P {host_port} -l {user_name} {host_ip}"
"cmdline": "-ssh -pw **** -P {host_port} -l {user_name} {host_ip}",
"desc": []
},
{
"name": "crt",
"display": "SecureCRT",
"app": "",
"cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /P {host_port} /PASSWORD **** {user_name}@{host_ip}"
"cmdline": "/T /N \"TP#ssh://{real_ip}\" /SSH2 /P {host_port} /PASSWORD **** {user_name}@{host_ip}",
"desc": []
},
{
"name": "xshell",
"display": "Xshell",
"app": "",
"cmdline": "-newtab \"TP#ssh://{real_ip}\" -url ssh://{user_name}:****@{host_ip}:{host_port}"
"cmdline": "-newtab \"TP#ssh://{real_ip}\" -url ssh://{user_name}:****@{host_ip}:{host_port}",
"desc": []
},
{
"name": "other",
"display": "自定义",
"app": "",
"cmdline": ""
"cmdline": "",
"desc": []
}
]
},
"scp": {
"sftp": {
"selected": "winscp",
"available": [{
"name": "winscp",
"display": "WinSCP内置",
"app": "{assist_tools_path}\\winscp\\winscp.exe",
"cmdline": "/sessionname=\"TP#{real_ip}\" {user_name}:****@{host_ip}:{host_port}"
"cmdline": "/sessionname=\"TP#{real_ip}\" {user_name}:****@{host_ip}:{host_port}",
"desc": []
},
{
"name": "other",
"display": "自定义",
"app": "",
"cmdline": ""
"cmdline": "",
"desc": []
}
]
},
@ -49,19 +56,22 @@
"name": "putty",
"display": "PuTTY内置",
"app": "{assist_tools_path}\\putty\\putty.exe",
"cmdline": "telnet://{user_name}@{host_ip}:{host_port}"
"cmdline": "telnet://{user_name}@{host_ip}:{host_port}",
"desc": []
},
{
"name": "crt",
"display": "SecureCRT",
"app": "",
"cmdline": "/T /N \"TP#telnet://{real_ip}\" /ARG {user_name} /SCRIPT \"{assist_tools_path}\\securecrt-telnet.vbs\" /TELNET {host_ip} {host_port}"
},
"cmdline": "/T /N \"TP#telnet://{real_ip}\" /ARG {user_name} /SCRIPT \"{assist_tools_path}\\securecrt-telnet.vbs\" /TELNET {host_ip} {host_port}",
"desc": []
},
{
"name": "other",
"display": "自定义",
"app": "",
"cmdline": ""
"cmdline": "",
"desc": []
}
]
},
@ -70,13 +80,15 @@
"app": "mstsc.exe",
"cmdline": "\"{tmp_rdp_file}\"",
"display": "微软RDP客户端系统自带",
"name": "mstsc"
"name": "mstsc",
"desc": []
},
{
"app": "{assist_tools_path}\\tprdp\\wfreerdp.exe",
"cmdline": "/v:{host_ip}:{host_port} /u:{user_name} /t:\"TP#{real_ip}\"",
"display": "FreeRDP内置",
"name": "freerdp"
"name": "freerdp",
"desc": []
}
],
"selected": "mstsc"

View File

@ -117,23 +117,12 @@ bool TsCfg::_parse_app(const Json::Value& m_root, const ex_astr& str_app, APP_CO
break;
}
// if (cfg.application.empty() || cfg.cmdline.empty()) {
// EXLOGE("invalid config, error 6.\n");
// return false;
// }
return true;
}
bool TsCfg::_load(const ex_astr& str_json) {
// Json::Reader jreader;
//
// if (!jreader.parse(str_json.c_str(), m_root)) {
// EXLOGE("can not parse new config data, not in json format?\n");
// return false;
// }
Json::CharReaderBuilder jcrb;
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
const char *str_json_begin = str_json.c_str();
@ -145,7 +134,7 @@ bool TsCfg::_load(const ex_astr& str_json) {
}
//===================================
// check ssh config
// check config
//===================================
if(!_parse_app(m_root, "ssh", ssh))
return false;
@ -156,330 +145,5 @@ bool TsCfg::_load(const ex_astr& str_json) {
if(!_parse_app(m_root, "rdp", rdp))
return false;
#if 0
if (!m_root["ssh"].isObject()) {
EXLOGE("invalid config, error 1.\n");
return false;
}
if (!m_root["ssh"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
sel_name = m_root["ssh"]["selected"].asCString();
if (!m_root["ssh"]["available"].isArray() || m_root["ssh"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
for (i = 0; i < m_root["ssh"]["available"].size(); ++i) {
if (
!m_root["ssh"]["available"][i]["name"].isString()
|| !m_root["ssh"]["available"][i]["app"].isString()
|| !m_root["ssh"]["available"][i]["cmdline"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if (m_root["ssh"]["available"][i]["display"].isNull()) {
m_root["ssh"]["available"][i]["display"] = m_root["ssh"]["available"][i]["name"];
}
if (m_root["ssh"]["available"][i]["name"].asCString() != sel_name)
continue;
ssh_app = m_root["ssh"]["available"][i]["app"].asCString();
ssh_cmdline = m_root["ssh"]["available"][i]["cmdline"].asCString();
break;
}
if (ssh_app.length() == 0 || ssh_cmdline.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
//===================================
// check sftp config
//===================================
if (!m_root["scp"].isObject()) {
EXLOGE("invalid config, error 1.\n");
return false;
}
if (!m_root["scp"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
sel_name = m_root["scp"]["selected"].asCString();
if (!m_root["scp"]["available"].isArray() || m_root["scp"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
for (i = 0; i < m_root["sftp"]["available"].size(); ++i) {
if (
!m_root["sftp"]["available"][i]["name"].isString()
|| !m_root["sftp"]["available"][i]["app"].isString()
|| !m_root["sftp"]["available"][i]["cmdline"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if (m_root["scp"]["available"][i]["display"].isNull()) {
m_root["scp"]["available"][i]["display"] = m_root["scp"]["available"][i]["name"];
}
if (m_root["scp"]["available"][i]["name"].asCString() != sel_name)
continue;
// tmp = m_root["scp"]["available"][i]["app"].asCString();
// ex_astr2wstr(tmp, scp_app, EX_CODEPAGE_UTF8);
scp_app = m_root["scp"]["available"][i]["app"].asCString();
// tmp = m_root["scp"]["available"][i]["cmdline"].asCString();
// ex_astr2wstr(tmp, scp_cmdline, EX_CODEPAGE_UTF8);
scp_cmdline = m_root["scp"]["available"][i]["cmdline"].asCString();
break;
}
if (scp_app.length() == 0 || scp_cmdline.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
//===================================
// check telnet config
//===================================
if (!m_root["telnet"].isObject()) {
EXLOGE("invalid config, error 1.\n");
return false;
}
if (!m_root["telnet"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
sel_name = m_root["telnet"]["selected"].asCString();
if (!m_root["telnet"]["available"].isArray() || m_root["telnet"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
for (i = 0; i < m_root["telnet"]["available"].size(); ++i) {
if (
!m_root["telnet"]["available"][i]["name"].isString()
|| !m_root["telnet"]["available"][i]["app"].isString()
|| !m_root["telnet"]["available"][i]["cmdline"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if (m_root["telnet"]["available"][i]["display"].isNull()) {
m_root["telnet"]["available"][i]["display"] = m_root["telnet"]["available"][i]["name"];
}
if (m_root["telnet"]["available"][i]["name"].asCString() != sel_name)
continue;
// tmp = m_root["telnet"]["available"][i]["app"].asCString();
// ex_astr2wstr(tmp, telnet_app, EX_CODEPAGE_UTF8);
// tmp = m_root["telnet"]["available"][i]["cmdline"].asCString();
// ex_astr2wstr(tmp, telnet_cmdline, EX_CODEPAGE_UTF8);
telnet_app = m_root["telnet"]["available"][i]["app"].asCString();
telnet_cmdline = m_root["telnet"]["available"][i]["cmdline"].asCString();
break;
}
if (telnet_app.length() == 0 || telnet_cmdline.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
//===================================
// check rdp config
//===================================
if (!m_root["rdp"].isObject()) {
EXLOGE("invalid config, error 1.\n");
return false;
}
if (!m_root["rdp"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
sel_name = m_root["rdp"]["selected"].asCString();
if (!m_root["rdp"]["available"].isArray() || m_root["rdp"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
for (i = 0; i < m_root["rdp"]["available"].size(); ++i) {
if (
!m_root["rdp"]["available"][i]["name"].isString()
|| !m_root["rdp"]["available"][i]["app"].isString()
|| !m_root["rdp"]["available"][i]["cmdline"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if (m_root["rdp"]["available"][i]["display"].isNull()) {
m_root["rdp"]["available"][i]["display"] = m_root["rdp"]["available"][i]["name"];
}
if (m_root["rdp"]["available"][i]["name"].asCString() != sel_name)
continue;
// tmp = m_root["rdp"]["available"][i]["app"].asCString();
// ex_astr2wstr(tmp, rdp_app, EX_CODEPAGE_UTF8);
// tmp = m_root["rdp"]["available"][i]["cmdline"].asCString();
// ex_astr2wstr(tmp, rdp_cmdline, EX_CODEPAGE_UTF8);
// tmp = m_root["rdp"]["available"][i]["name"].asCString();
// ex_astr2wstr(tmp, rdp_name, EX_CODEPAGE_UTF8);
rdp_app = m_root["rdp"]["available"][i]["app"].asCString();
rdp_cmdline = m_root["rdp"]["available"][i]["cmdline"].asCString();
rdp_name = m_root["rdp"]["available"][i]["name"].asCString();
break;
}
if (rdp_app.length() == 0 || rdp_cmdline.length() == 0 || rdp_name.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
#endif
#if 0
// ------------ term ---------------------
if (!m_root["term"].isObject()) {
EXLOGE("invalid config, error 1.\n");
return false;
}
if( !m_root["term"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
term_name = m_root["term"]["selected"].asCString();
if(!m_root["term"]["available"].isArray() || m_root["term"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
int i = 0;
for (i = 0; i < m_root["term"]["available"].size(); ++i) {
if(
!m_root["term"]["available"][i]["name"].isString()
|| !m_root["term"]["available"][i]["app"].isString()
|| !m_root["term"]["available"][i]["profile"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if(m_root["term"]["available"][i]["name"].asCString() != term_name)
continue;
if(m_root["term"]["available"][i]["disp"].isString()) {
term_display = m_root["term"]["available"][i]["display"].asCString();
} else if(m_root["term"]["available"][i]["disp"].isNull()) {
m_root["term"]["available"][i]["disp"] = term_name;
term_display = term_name;
} else {
EXLOGE("invalid config, error 5.\n");
return false;
}
term_app = m_root["term"]["available"][i]["app"].asCString();
term_profile = m_root["term"]["available"][i]["profile"].asCString();
break;
}
if(term_name.length() == 0 || term_app.length() == 0 || term_profile.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
// ------------ RDP ---------------------
if (!m_root["rdp"].isObject()) {
EXLOGE("invalid config, error 1.\n");
return false;
}
if( !m_root["rdp"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
rdp_name = m_root["rdp"]["selected"].asCString();
if(!m_root["rdp"]["available"].isArray() || m_root["rdp"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
for (i = 0; i < m_root["rdp"]["available"].size(); ++i) {
if(
!m_root["rdp"]["available"][i]["name"].isString()
|| !m_root["rdp"]["available"][i]["app"].isString()
//|| !m_root["rdp"]["available"][i]["profile"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if(m_root["rdp"]["available"][i]["name"].asCString() != rdp_name)
continue;
if(m_root["rdp"]["available"][i]["disp"].isString()) {
rdp_display = m_root["term"]["available"][i]["display"].asCString();
} else if(m_root["rdp"]["available"][i]["disp"].isNull()) {
m_root["rdp"]["available"][i]["disp"] = rdp_name;
rdp_display = rdp_name;
} else {
EXLOGE("invalid config, error 5.\n");
return false;
}
rdp_app = m_root["rdp"]["available"][i]["app"].asCString();
//rdp_profile = m_root["rdp"]["available"][i]["profile"].asCString();
break;
}
if(rdp_name.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
#endif
return true;
}

View File

@ -94,12 +94,6 @@ INT_PTR CALLBACK eomDlgMainProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARA
return TRUE;
}break;
case IDM_OPEN_CONFIG:
{
ShellExecute(nullptr, _T("open"), _T("http://127.0.0.1:50022/config"), nullptr, nullptr, SW_SHOW);
return TRUE;
}break;
default:
break;
}

Binary file not shown.

View File

@ -4,7 +4,7 @@
#include <ex.h>
#include "ts_network.h"
// #include "ts_network.h"
//#include "ts_log.h"
//#include "ts_ini.h"
#include "ts_env.h"

View File

@ -3,10 +3,11 @@
#include <fcntl.h>
#include "resource.h"
#include "dlg_main.h"
#include "ts_http_rpc.h"
//#include "ts_http_rpc.h"
#include "ts_ws_client.h"
#ifdef _DEBUG
# include <vld.h>
// # include <vld.h>
#endif
#pragma comment(lib, "shlwapi.lib")
@ -22,224 +23,252 @@ static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void failed(const char* msg);
void failed(const wchar_t* msg);
static HANDLE g_SingleInstanceMutexHandle=NULL;
static HANDLE g_SingleInstanceMutexHandle = NULL;
HINSTANCE g_hInstance=NULL;
ULONG g_ulSingleInstanceMsgId=0;
static TCHAR szKernalName[MAX_PATH]={ 0 };
HINSTANCE g_hInstance = NULL;
ULONG g_ulSingleInstanceMsgId = 0;
static TCHAR szKernalName[MAX_PATH] = { 0 };
HWND g_hwndBase=NULL;
int g_argc=0;
wchar_t** g_argv=NULL;
HWND g_hwndBase = NULL;
int g_argc = 0;
wchar_t** g_argv = NULL;
#define EOM_ASSIST_GUID _T("A6EFE1250C5F4416BFA819FE92CBD4B4")
#define EOM_ASSIST_INSTANCE _T("TS_ASSIST_SINGLE_INSTANCE")
#define EOM_ASSIST_WIN_CLASS _T("TS_ASSIST_WINDOW_CLASS")
#define MAKEDWORD(low, high) ((DWORD)(((WORD)(((DWORD_PTR)(low)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(high)) & 0xffff))) << 16))
ex_astr g_url_protocol;
DWORD WINAPI HttpServerThreadProc(LPVOID lpParam) {
http_rpc_main_loop(false);
return 0;
}
#define TP_ASSIST_GUID _T("A6EFE1250C5F4416BFA819FE92CBD4B4")
#define TP_ASSIST_INSTANCE _T("TS_ASSIST_SINGLE_INSTANCE")
#define TP_ASSIST_WIN_CLASS _T("TS_ASSIST_WINDOW_CLASS")
#define MAKEDWORD(low, high) ((DWORD)(((WORD)(((DWORD_PTR)(low)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(high)) & 0xffff))) << 16))
DWORD WINAPI HttpsServerThreadProc(LPVOID lpParam) {
http_rpc_main_loop(true);
return 0;
}
//DWORD WINAPI HttpServerThreadProc(LPVOID lpParam) {
// http_rpc_main_loop(false);
// return 0;
//}
//
//DWORD WINAPI HttpsServerThreadProc(LPVOID lpParam) {
// http_rpc_main_loop(true);
// return 0;
//}
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd) {
EXLOG_USE_LOGGER(&g_ex_logger);
EXLOG_USE_LOGGER(&g_ex_logger);
WORD wVersionRequested;
WSADATA wsaData;
int err;
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested=MAKEWORD(1, 1);
wVersionRequested = MAKEWORD(1, 1);
err=WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
return 0;
}
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
return 0;
}
if (LOBYTE(wsaData.wVersion) != 1 ||
HIBYTE(wsaData.wVersion) != 1) {
WSACleanup();
return 0;
}
if (LOBYTE(wsaData.wVersion) != 1 ||
HIBYTE(wsaData.wVersion) != 1) {
WSACleanup();
return 0;
}
g_env.init();
g_env.init();
#ifdef EX_DEBUG
EXLOG_LEVEL(EX_LOG_LEVEL_DEBUG);
EXLOG_LEVEL(EX_LOG_LEVEL_DEBUG);
#else
EXLOG_LEVEL(EX_LOG_LEVEL_INFO);
EXLOG_LEVEL(EX_LOG_LEVEL_INFO);
#endif
EXLOG_FILE(L"tp_assist.log", g_env.m_log_path.c_str(), EX_LOG_FILE_MAX_SIZE, EX_LOG_FILE_MAX_COUNT);
EXLOG_FILE(L"tp_assist.log", g_env.m_log_path.c_str(), EX_LOG_FILE_MAX_SIZE, EX_LOG_FILE_MAX_COUNT);
// g_cfgSSH.init();
// g_cfgScp.init();
// g_cfgTelnet.init();
g_cfg.init();
if (!g_cfg.init()) {
MessageBox(NULL, _T("无法加载助手配置文件!"), _T("错误"), MB_OK | MB_ICONERROR);
return FALSE;
}
g_hInstance=hInstance;
_stprintf_s(szKernalName, MAX_PATH, _T("%s_%s"), EOM_ASSIST_GUID, EOM_ASSIST_INSTANCE);
g_ulSingleInstanceMsgId=RegisterWindowMessage(szKernalName);
if (0 == g_ulSingleInstanceMsgId)
return FALSE;
g_hInstance = hInstance;
_stprintf_s(szKernalName, MAX_PATH, _T("%s_%s"), TP_ASSIST_GUID, TP_ASSIST_INSTANCE);
g_ulSingleInstanceMsgId = RegisterWindowMessage(szKernalName);
if (0 == g_ulSingleInstanceMsgId)
return FALSE;
LPWSTR szCmdLine=(LPWSTR)::GetCommandLineW(); //获取命令行参数;
g_argv=CommandLineToArgvW(szCmdLine, &g_argc); //拆分命令行参数字符串;
std::wstring arg;
for (int i=0; i < g_argc; ++i) {
arg = g_argv[i];
if (0 == lstrcmp(g_argv[i], _T("--stop"))) {
PostMessage(HWND_BROADCAST, g_ulSingleInstanceMsgId, WMU_INSTANCE_EXIT, 0);
LocalFree(g_argv);
g_argv=NULL;
return -1;
}else if (arg.find(L"teleport_ip",0) !=std::wstring::npos && arg.find(L"teleport_port") != std::wstring::npos && arg.find(L"remote_host_ip") != std::wstring::npos && arg.find(L"session_id") != std::wstring::npos) {
//把wchar_t **转换为std::string
size_t len = wcslen(g_argv[i]) + 1;
size_t converted = 0;
char *CStr;
CStr = (char*)malloc(len * sizeof(char));
wcstombs_s(&converted, CStr, len, g_argv[i], _TRUNCATE);
std::string func_args = CStr;
//调用TsHttpRpc类里的_rpc_func_run_client启动客户端
TsHttpRpc ts_http_rpc;
ex_astr buf;
ts_http_rpc._rpc_func_url_protocol(func_args, buf);
free(CStr);
LPWSTR szCmdLine = (LPWSTR)::GetCommandLineW(); //获取命令行参数;
g_argv = CommandLineToArgvW(szCmdLine, &g_argc); //拆分命令行参数字符串;
for (int i = 0; i < g_argc; ++i) {
ex_wstr arg = g_argv[i];
if (0 == lstrcmp(g_argv[i], _T("--stop"))) {
PostMessage(HWND_BROADCAST, g_ulSingleInstanceMsgId, WMU_INSTANCE_EXIT, 0);
LocalFree(g_argv);
g_argv = NULL;
return 0;
return -1;
}
}
else if (arg.find(L"teleport://", 0) == 0) {
// url-protocol
// teleport://register?param={"ws_url":"ws://127.0.0.1:7190/ws/assist/","assist_id":1234,"session_id":"tp_5678"}
// make sure run single instance.
_stprintf_s(szKernalName, MAX_PATH, _T("%s_%s"), EOM_ASSIST_GUID, EOM_ASSIST_INSTANCE);
g_SingleInstanceMutexHandle=CreateMutex(NULL, FALSE, szKernalName);
if (GetLastError() == ERROR_ALREADY_EXISTS) {
PostMessage(HWND_BROADCAST, g_ulSingleInstanceMsgId, WMU_SHOW_EXIST_DLGUI, 0);
CloseHandle(g_SingleInstanceMutexHandle);
LocalFree(g_argv);
g_argv=NULL;
return 0;
}
EXLOGV(L"url-protocol: %s\n", arg.c_str());
ex_wstr2astr(arg, g_url_protocol);
break;
}
}
// make sure run single instance.
_stprintf_s(szKernalName, MAX_PATH, _T("%s_%s"), TP_ASSIST_GUID, TP_ASSIST_INSTANCE);
g_SingleInstanceMutexHandle = CreateMutex(NULL, FALSE, szKernalName);
if (GetLastError() == ERROR_ALREADY_EXISTS) {
// if we got url-protocol, send it by WM_COPYDATA, else just bring running instance to front.
if (g_url_protocol.empty())
{
PostMessage(HWND_BROADCAST, g_ulSingleInstanceMsgId, WMU_SHOW_EXIST_DLGUI, 0);
}
else
{
HWND hwnd = FindWindow(TP_ASSIST_WIN_CLASS, NULL);
if (hwnd == NULL) {
MessageBoxW(NULL, _T("助手已经运行了,但无法定位!"), _T("错误"), MB_OK | MB_ICONERROR);
}
else
{
COPYDATASTRUCT data;
data.dwData = NULL;
data.cbData = g_url_protocol.length() + 1; // include zero end.
data.lpData = (void*)g_url_protocol.c_str();
SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)&data);
}
}
CloseHandle(g_SingleInstanceMutexHandle);
LocalFree(g_argv);
g_argv = NULL;
return 0;
}
// create dialog-box window.
MyRegisterClass();
// create dialog-box window.
MyRegisterClass();
// Perform application initialization:
if (!InitInstance()) {
CloseHandle(g_SingleInstanceMutexHandle);
LocalFree(g_argv);
g_argv=NULL;
return FALSE;
}
// Perform application initialization:
if (!InitInstance()) {
CloseHandle(g_SingleInstanceMutexHandle);
LocalFree(g_argv);
g_argv = NULL;
return FALSE;
}
HANDLE hThreadHttpServer=NULL;
DWORD dwThreadId=0;
hThreadHttpServer=CreateThread(NULL, 0, HttpServerThreadProc, NULL, 0, &dwThreadId);
//HANDLE hThreadHttpServer=NULL;
//DWORD dwThreadId=0;
//hThreadHttpServer=CreateThread(NULL, 0, HttpServerThreadProc, NULL, 0, &dwThreadId);
HANDLE hThreadHttpsServer=NULL;
dwThreadId=0;
hThreadHttpsServer=CreateThread(NULL, 0, HttpsServerThreadProc, NULL, 0, &dwThreadId);
//HANDLE hThreadHttpsServer=NULL;
//dwThreadId=0;
//hThreadHttpsServer=CreateThread(NULL, 0, HttpsServerThreadProc, NULL, 0, &dwThreadId);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
http_rpc_stop(false);
WaitForSingleObject(hThreadHttpServer, INFINITE);
//http_rpc_stop(false);
//WaitForSingleObject(hThreadHttpServer, INFINITE);
http_rpc_stop(true);
WaitForSingleObject(hThreadHttpsServer, INFINITE);
//http_rpc_stop(true);
//WaitForSingleObject(hThreadHttpsServer, INFINITE);
CloseHandle(g_SingleInstanceMutexHandle);
CloseHandle(g_SingleInstanceMutexHandle);
LocalFree(g_argv);
g_argv=NULL;
return 0;
LocalFree(g_argv);
g_argv = NULL;
return 0;
}
void failed(const char* msg) {
OutputDebugStringA(msg);
OutputDebugStringA(msg);
}
void failed(const wchar_t* msg) {
OutputDebugStringW(msg);
OutputDebugStringW(msg);
}
ATOM MyRegisterClass() {
WNDCLASSEX wcex;
WNDCLASSEX wcex;
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style=CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc=WndProc;
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=g_hInstance;
wcex.hIcon=LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_NORMAL_BIG));
wcex.hCursor=LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName=MAKEINTRESOURCE(IDR_ASSIST);
wcex.lpszClassName=EOM_ASSIST_WIN_CLASS;
wcex.hIconSm=LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_NORMAL_SMALL));
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = g_hInstance;
wcex.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_NORMAL_BIG));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = MAKEINTRESOURCE(IDR_ASSIST);
wcex.lpszClassName = TP_ASSIST_WIN_CLASS;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_NORMAL_SMALL));
return RegisterClassEx(&wcex);
return RegisterClassEx(&wcex);
}
BOOL InitInstance(void) {
g_hwndBase=CreateWindow(EOM_ASSIST_WIN_CLASS, _T(""), WS_OVERLAPPEDWINDOW, 8, 0, 8, 0, NULL, NULL, g_hInstance, NULL);
if (!g_hwndBase)
return FALSE;
g_hwndBase = CreateWindow(TP_ASSIST_WIN_CLASS, _T(""), WS_OVERLAPPEDWINDOW, 8, 0, 8, 0, NULL, NULL, g_hInstance, NULL);
if (!g_hwndBase)
return FALSE;
ShowWindow(g_hwndBase, SW_HIDE);
ShowWindow(g_hwndBase, SW_HIDE);
return TRUE;
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
if (g_ulSingleInstanceMsgId == message) {
if (WMU_INSTANCE_EXIT == wParam) {
PostMessage(g_hDlgMain, WM_COMMAND, MAKEDWORD(IDCANCEL, 0), NULL);
return 0;
} else if (WMU_SHOW_EXIST_DLGUI == wParam) {
ShowWindow(g_hDlgMain, SW_SHOW);
SetWindowPos(g_hDlgMain, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
SetActiveWindow(g_hDlgMain);
BringWindowToTop(g_hDlgMain);
SetWindowPos(g_hDlgMain, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
return 0;
}
}
if (g_ulSingleInstanceMsgId == message) {
if (WMU_INSTANCE_EXIT == wParam) {
PostMessage(g_hDlgMain, WM_COMMAND, MAKEDWORD(IDCANCEL, 0), NULL);
return 0;
}
else if (WMU_SHOW_EXIST_DLGUI == wParam) {
ShowWindow(g_hDlgMain, SW_SHOW);
SetWindowPos(g_hDlgMain, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
SetActiveWindow(g_hDlgMain);
BringWindowToTop(g_hDlgMain);
SetWindowPos(g_hDlgMain, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
return 0;
}
}
switch (message) {
case WM_CREATE:
PostMessage(hWnd, WM_COMMAND, MAKEDWORD(IDM_MAIN, 0), NULL);
return DefWindowProc(hWnd, message, wParam, lParam);
break;
case WM_COMMAND:
switch (message) {
case WM_CREATE:
PostMessage(hWnd, WM_COMMAND, MAKEDWORD(IDM_MAIN, 0), NULL);
if (IDM_MAIN == LOWORD(wParam)) {
CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_DLG_MAIN), hWnd, eomDlgMainProc);
ShowWindow(g_hDlgMain, SW_HIDE);
}
break;
case WM_DESTROY:
SendMessage(g_hDlgMain, WMU_DLG_MAIN_EXIT, NULL, NULL);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
if (!g_url_protocol.empty())
{
TsWsClient::url_scheme_handler(g_url_protocol);
}
return DefWindowProc(hWnd, message, wParam, lParam);
break;
case WM_COMMAND:
if (IDM_MAIN == LOWORD(wParam)) {
CreateDialog(g_hInstance, MAKEINTRESOURCE(IDD_DLG_MAIN), hWnd, eomDlgMainProc);
ShowWindow(g_hDlgMain, SW_HIDE);
}
break;
case WM_DESTROY:
TsWsClient::stop_all_client();
SendMessage(g_hDlgMain, WMU_DLG_MAIN_EXIT, NULL, NULL);
PostQuitMessage(0);
break;
case WM_COPYDATA:
{
COPYDATASTRUCT* data = (COPYDATASTRUCT*)lParam;
ex_astr url_protocol((char*)data->lpData);
// MessageBoxA(hWnd, url_protocol.c_str(), "url-protocol", MB_OK);
TsWsClient::url_scheme_handler(url_protocol);
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

Binary file not shown.

View File

@ -15,19 +15,19 @@
<Keyword>Win32Proj</Keyword>
<RootNamespace>tp_assist</RootNamespace>
<ProjectName>tp_assist</ProjectName>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>false</UseOfMfc>
@ -106,7 +106,6 @@
<ClInclude Include="..\..\common\teleport\teleport_const.h" />
<ClInclude Include="..\..\external\mongoose\mongoose.h" />
<ClInclude Include="dlg_main.h" />
<ClInclude Include="msocketx.h" />
<ClInclude Include="Resource.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
@ -114,9 +113,9 @@
<ClInclude Include="ts_cfg.h" />
<ClInclude Include="ts_const.h" />
<ClInclude Include="ts_env.h" />
<ClInclude Include="ts_http_rpc.h" />
<ClInclude Include="ts_network.h" />
<ClInclude Include="ts_utils.h" />
<ClInclude Include="ts_ver.h" />
<ClInclude Include="ts_ws_client.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\common\libex\src\ex_ini.cpp">
@ -160,7 +159,6 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="dlg_main.cpp" />
<ClCompile Include="msocketx.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
@ -168,8 +166,14 @@
<ClCompile Include="tp_assist.cpp" />
<ClCompile Include="ts_cfg.cpp" />
<ClCompile Include="ts_env.cpp" />
<ClCompile Include="ts_http_rpc.cpp" />
<ClCompile Include="ts_network.cpp" />
<ClCompile Include="ts_utils.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="ts_ws_client.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="tp_assist.rc" />

View File

@ -1,180 +1,174 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="dlg_main.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="tp_assist.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="ts_http_rpc.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="ts_network.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="msocketx.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="ts_env.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="ts_cfg.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="..\..\external\jsoncpp\src\lib_json\json_reader.cpp">
<Filter>jsoncpp</Filter>
</ClCompile>
<ClCompile Include="..\..\external\jsoncpp\src\lib_json\json_value.cpp">
<Filter>jsoncpp</Filter>
</ClCompile>
<ClCompile Include="..\..\external\jsoncpp\src\lib_json\json_writer.cpp">
<Filter>jsoncpp</Filter>
</ClCompile>
<ClCompile Include="..\..\external\mongoose\mongoose.c">
<Filter>mongoose</Filter>
</ClCompile>
<ClCompile Include="..\..\common\libex\src\ex_str.cpp">
<Filter>libex\src</Filter>
</ClCompile>
<ClCompile Include="..\..\common\libex\src\ex_util.cpp">
<Filter>libex\src</Filter>
</ClCompile>
<ClCompile Include="..\..\common\libex\src\ex_path.cpp">
<Filter>libex\src</Filter>
</ClCompile>
<ClCompile Include="..\..\common\libex\src\ex_ini.cpp">
<Filter>libex\src</Filter>
</ClCompile>
<ClCompile Include="..\..\common\libex\src\ex_log.cpp">
<Filter>libex\src</Filter>
</ClCompile>
<ClCompile Include="..\..\common\libex\src\ex_thread.cpp">
<Filter>libex\src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Resource.h">
<Filter>resource</Filter>
</ClInclude>
<ClInclude Include="dlg_main.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="tp_assist.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="ts_http_rpc.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="ts_network.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="ts_env.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="ts_cfg.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="..\..\external\mongoose\mongoose.h">
<Filter>mongoose</Filter>
</ClInclude>
<ClInclude Include="msocketx.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_const.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_path.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_platform.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_str.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_types.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_util.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="ts_const.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="ts_ver.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_ini.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_log.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_thread.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\teleport\teleport_const.h">
<Filter>teleport</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="res\tp.ico">
<Filter>resource</Filter>
</Image>
<Image Include="res\tp_small.ico">
<Filter>resource</Filter>
</Image>
<Image Include="res\tray_normal.ico">
<Filter>resource</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<Filter Include="resource">
<UniqueIdentifier>{52b425b1-8aa9-4e08-acbd-c88387350530}</UniqueIdentifier>
</Filter>
<Filter Include="jsoncpp">
<UniqueIdentifier>{adabe93d-3938-4b11-9352-5b67a1efd7e3}</UniqueIdentifier>
</Filter>
<Filter Include="mongoose">
<UniqueIdentifier>{35a345a0-6147-4c87-97c9-3b0b2a57e348}</UniqueIdentifier>
</Filter>
<Filter Include="main app">
<UniqueIdentifier>{0942cec3-67df-4d19-bbc1-e962145e496f}</UniqueIdentifier>
</Filter>
<Filter Include="libex">
<UniqueIdentifier>{a88e05d3-51f4-463f-84cc-c3bc86f07aac}</UniqueIdentifier>
</Filter>
<Filter Include="libex\header">
<UniqueIdentifier>{e3e7a811-5905-4ad5-86a7-9721af5d015a}</UniqueIdentifier>
</Filter>
<Filter Include="libex\src">
<UniqueIdentifier>{d7d49fa4-5192-42c5-bc70-5584d9d646c6}</UniqueIdentifier>
</Filter>
<Filter Include="teleport">
<UniqueIdentifier>{1291a5cf-cb08-4ad6-8a86-8a0486297c63}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="tp_assist.rc">
<Filter>resource</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\external\jsoncpp\src\lib_json\json_valueiterator.inl">
<Filter>jsoncpp</Filter>
</None>
</ItemGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="dlg_main.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="tp_assist.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="ts_env.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="ts_cfg.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="..\..\external\jsoncpp\src\lib_json\json_reader.cpp">
<Filter>jsoncpp</Filter>
</ClCompile>
<ClCompile Include="..\..\external\jsoncpp\src\lib_json\json_value.cpp">
<Filter>jsoncpp</Filter>
</ClCompile>
<ClCompile Include="..\..\external\jsoncpp\src\lib_json\json_writer.cpp">
<Filter>jsoncpp</Filter>
</ClCompile>
<ClCompile Include="..\..\external\mongoose\mongoose.c">
<Filter>mongoose</Filter>
</ClCompile>
<ClCompile Include="..\..\common\libex\src\ex_str.cpp">
<Filter>libex\src</Filter>
</ClCompile>
<ClCompile Include="..\..\common\libex\src\ex_util.cpp">
<Filter>libex\src</Filter>
</ClCompile>
<ClCompile Include="..\..\common\libex\src\ex_path.cpp">
<Filter>libex\src</Filter>
</ClCompile>
<ClCompile Include="..\..\common\libex\src\ex_ini.cpp">
<Filter>libex\src</Filter>
</ClCompile>
<ClCompile Include="..\..\common\libex\src\ex_log.cpp">
<Filter>libex\src</Filter>
</ClCompile>
<ClCompile Include="..\..\common\libex\src\ex_thread.cpp">
<Filter>libex\src</Filter>
</ClCompile>
<ClCompile Include="ts_ws_client.cpp">
<Filter>main app</Filter>
</ClCompile>
<ClCompile Include="ts_utils.cpp">
<Filter>main app</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Resource.h">
<Filter>resource</Filter>
</ClInclude>
<ClInclude Include="dlg_main.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="tp_assist.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="ts_env.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="ts_cfg.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="..\..\external\mongoose\mongoose.h">
<Filter>mongoose</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_const.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_path.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_platform.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_str.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_types.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_util.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="ts_const.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="ts_ver.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_ini.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_log.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\libex\include\ex\ex_thread.h">
<Filter>libex\header</Filter>
</ClInclude>
<ClInclude Include="..\..\common\teleport\teleport_const.h">
<Filter>teleport</Filter>
</ClInclude>
<ClInclude Include="ts_ws_client.h">
<Filter>main app</Filter>
</ClInclude>
<ClInclude Include="ts_utils.h">
<Filter>main app</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="res\tp.ico">
<Filter>resource</Filter>
</Image>
<Image Include="res\tp_small.ico">
<Filter>resource</Filter>
</Image>
<Image Include="res\tray_normal.ico">
<Filter>resource</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<Filter Include="resource">
<UniqueIdentifier>{52b425b1-8aa9-4e08-acbd-c88387350530}</UniqueIdentifier>
</Filter>
<Filter Include="jsoncpp">
<UniqueIdentifier>{adabe93d-3938-4b11-9352-5b67a1efd7e3}</UniqueIdentifier>
</Filter>
<Filter Include="mongoose">
<UniqueIdentifier>{35a345a0-6147-4c87-97c9-3b0b2a57e348}</UniqueIdentifier>
</Filter>
<Filter Include="main app">
<UniqueIdentifier>{0942cec3-67df-4d19-bbc1-e962145e496f}</UniqueIdentifier>
</Filter>
<Filter Include="libex">
<UniqueIdentifier>{a88e05d3-51f4-463f-84cc-c3bc86f07aac}</UniqueIdentifier>
</Filter>
<Filter Include="libex\header">
<UniqueIdentifier>{e3e7a811-5905-4ad5-86a7-9721af5d015a}</UniqueIdentifier>
</Filter>
<Filter Include="libex\src">
<UniqueIdentifier>{d7d49fa4-5192-42c5-bc70-5584d9d646c6}</UniqueIdentifier>
</Filter>
<Filter Include="teleport">
<UniqueIdentifier>{1291a5cf-cb08-4ad6-8a86-8a0486297c63}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="tp_assist.rc">
<Filter>resource</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\external\jsoncpp\src\lib_json\json_valueiterator.inl">
<Filter>jsoncpp</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -21,6 +21,20 @@ bool TsCfg::init(void) {
if (!_load(file_content))
return false;
if (!m_root.isObject()) {
EXLOGE("invalid config file, not in json format?\n");
return false;
}
if (m_root["file_version"].isNull()) {
EXLOGE("invalid config file, maybe need create new one?\n");
return false;
}
if (!m_root["file_version"].isInt()) {
}
return true;
}
@ -29,8 +43,9 @@ bool TsCfg::save(const ex_astr& new_value)
if (!_load(new_value))
return false;
//Json::StyledWriter jwriter;
Json::StreamWriterBuilder jwb;
jwb["indentation"] = " ";
jwb["emitUTF8"] = true;
std::unique_ptr<Json::StreamWriter> jwriter(jwb.newStreamWriter());
ex_aoss os;
jwriter->write(m_root, &os);
@ -44,8 +59,78 @@ bool TsCfg::save(const ex_astr& new_value)
return true;
}
bool TsCfg::_parse_app(const Json::Value& m_root, const ex_astr& str_app, APP_CONFIG& cfg) {
const Json::Value& jApp = m_root[str_app.c_str()];
if (!jApp.isObject())
return false;
if (!jApp["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
ex_astr _selected = jApp["selected"].asCString();;
if (!jApp["available"].isArray() || jApp["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
const Json::Value& jAppList = jApp["available"];
ex_astr tmp_val;
for (size_t i = 0; i < jAppList.size(); ++i) {
if (
!jAppList[i]["name"].isString()
|| !jAppList[i]["app"].isString()
|| !jAppList[i]["cmdline"].isString()
|| !jAppList[i]["desc"].isArray()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if (jAppList[i]["name"].asString().empty()) {
EXLOGE("invalid config, need name.\n");
return false;
}
if (jAppList[i]["display"].isNull() || jAppList[i]["display"].asString().empty()) {
tmp_val = jAppList[i]["name"].asString();
}
else
tmp_val = jAppList[i]["display"].asString();
ex_astr2wstr(tmp_val, cfg.display);
if (jAppList[i]["name"].asString() != _selected)
continue;
tmp_val = jAppList[i]["name"].asString();
ex_astr2wstr(tmp_val, cfg.name);
// cfg.display = jAppList[i]["display"].asCString();
tmp_val = jAppList[i]["app"].asCString();
ex_astr2wstr(tmp_val, cfg.application);
tmp_val = jAppList[i]["cmdline"].asCString();
ex_astr2wstr(tmp_val, cfg.cmdline);
if (jAppList[i]["desc"].size() > 0) {
const Json::Value& jAppDescList = jAppList[i]["desc"];
for (size_t j = 0; j < jAppDescList.size(); ++j) {
if (!jAppDescList[j].isString())
return false;
ex_wstr w_tmp;
ex_astr2wstr(jAppDescList[j].asString(), w_tmp);
cfg.description.push_back(w_tmp);
}
}
break;
}
return true;
}
bool TsCfg::_load(const ex_astr& str_json) {
//Json::Reader jreader;
Json::CharReaderBuilder jcrb;
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
const char *str_json_begin = str_json.c_str();
@ -56,219 +141,17 @@ bool TsCfg::_load(const ex_astr& str_json) {
return false;
}
ex_astr sel_name;
size_t i = 0;
ex_astr tmp;
//===================================
// check ssh config
// check config
//===================================
if (!m_root["ssh"].isObject()) {
EXLOGE("invalid config, error 1.\n");
if (!_parse_app(m_root, "ssh", ssh))
return false;
}
if (!m_root["ssh"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
if (!_parse_app(m_root, "sftp", sftp))
return false;
}
sel_name = m_root["ssh"]["selected"].asCString();
if (!m_root["ssh"]["available"].isArray() || m_root["ssh"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
if(!_parse_app(m_root, "telnet", telnet))
return false;
if (!_parse_app(m_root, "rdp", rdp))
return false;
}
for (i = 0; i < m_root["ssh"]["available"].size(); ++i) {
if (
!m_root["ssh"]["available"][i]["name"].isString()
|| !m_root["ssh"]["available"][i]["app"].isString()
|| !m_root["ssh"]["available"][i]["cmdline"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if (m_root["ssh"]["available"][i]["display"].isNull()) {
m_root["ssh"]["available"][i]["display"] = m_root["ssh"]["available"][i]["name"];
}
if (m_root["ssh"]["available"][i]["name"].asCString() != sel_name)
continue;
tmp = m_root["ssh"]["available"][i]["app"].asCString();
ex_astr2wstr(tmp, ssh_app, EX_CODEPAGE_UTF8);
tmp = m_root["ssh"]["available"][i]["cmdline"].asCString();
ex_astr2wstr(tmp, ssh_cmdline, EX_CODEPAGE_UTF8);
break;
}
if (ssh_app.length() == 0 || ssh_cmdline.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
//===================================
// check sftp config
//===================================
if (!m_root["scp"].isObject()) {
EXLOGE("invalid config, error 1.\n");
return false;
}
if (!m_root["scp"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
sel_name = m_root["scp"]["selected"].asCString();
if (!m_root["scp"]["available"].isArray() || m_root["scp"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
for (i = 0; i < m_root["scp"]["available"].size(); ++i) {
if (
!m_root["scp"]["available"][i]["name"].isString()
|| !m_root["scp"]["available"][i]["app"].isString()
|| !m_root["scp"]["available"][i]["cmdline"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if (m_root["scp"]["available"][i]["display"].isNull()) {
m_root["scp"]["available"][i]["display"] = m_root["scp"]["available"][i]["name"];
}
if (m_root["scp"]["available"][i]["name"].asCString() != sel_name)
continue;
tmp = m_root["scp"]["available"][i]["app"].asCString();
ex_astr2wstr(tmp, scp_app, EX_CODEPAGE_UTF8);
tmp = m_root["scp"]["available"][i]["cmdline"].asCString();
ex_astr2wstr(tmp, scp_cmdline, EX_CODEPAGE_UTF8);
break;
}
if (scp_app.length() == 0 || scp_cmdline.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
//===================================
// check telnet config
//===================================
if (!m_root["telnet"].isObject()) {
EXLOGE("invalid config, error 1.\n");
return false;
}
if (!m_root["telnet"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
sel_name = m_root["telnet"]["selected"].asCString();
if (!m_root["telnet"]["available"].isArray() || m_root["telnet"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
for (i = 0; i < m_root["telnet"]["available"].size(); ++i) {
if (
!m_root["telnet"]["available"][i]["name"].isString()
|| !m_root["telnet"]["available"][i]["app"].isString()
|| !m_root["telnet"]["available"][i]["cmdline"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if (m_root["telnet"]["available"][i]["display"].isNull()) {
m_root["telnet"]["available"][i]["display"] = m_root["telnet"]["available"][i]["name"];
}
if (m_root["telnet"]["available"][i]["name"].asCString() != sel_name)
continue;
tmp = m_root["telnet"]["available"][i]["app"].asCString();
ex_astr2wstr(tmp, telnet_app, EX_CODEPAGE_UTF8);
tmp = m_root["telnet"]["available"][i]["cmdline"].asCString();
ex_astr2wstr(tmp, telnet_cmdline, EX_CODEPAGE_UTF8);
break;
}
if (telnet_app.length() == 0 || telnet_cmdline.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
//===================================
// check rdp config
//===================================
if (!m_root["rdp"].isObject()) {
EXLOGE("invalid config, error 1.\n");
return false;
}
if (!m_root["rdp"]["selected"].isString()) {
EXLOGE("invalid config, error 2.\n");
return false;
}
sel_name = m_root["rdp"]["selected"].asCString();
if (!m_root["rdp"]["available"].isArray() || m_root["rdp"]["available"].size() == 0) {
EXLOGE("invalid config, error 3.\n");
return false;
}
for (i = 0; i < m_root["rdp"]["available"].size(); ++i) {
if (
!m_root["rdp"]["available"][i]["name"].isString()
|| !m_root["rdp"]["available"][i]["app"].isString()
|| !m_root["rdp"]["available"][i]["cmdline"].isString()
) {
EXLOGE("invalid config, error 4.\n");
return false;
}
if (m_root["rdp"]["available"][i]["display"].isNull()) {
m_root["rdp"]["available"][i]["display"] = m_root["rdp"]["available"][i]["name"];
}
if (m_root["rdp"]["available"][i]["name"].asCString() != sel_name)
continue;
tmp = m_root["rdp"]["available"][i]["app"].asCString();
ex_astr2wstr(tmp, rdp_app, EX_CODEPAGE_UTF8);
tmp = m_root["rdp"]["available"][i]["cmdline"].asCString();
ex_astr2wstr(tmp, rdp_cmdline, EX_CODEPAGE_UTF8);
tmp = m_root["rdp"]["available"][i]["name"].asCString();
ex_astr2wstr(tmp, rdp_name, EX_CODEPAGE_UTF8);
break;
}
if (rdp_app.length() == 0 || rdp_cmdline.length() == 0 || rdp_name.length() == 0) {
EXLOGE("invalid config, error 6.\n");
return false;
}
return true;
}

View File

@ -6,6 +6,14 @@
#include <json/json.h>
typedef struct APP_CONFIG {
ex_wstr name;
ex_wstr display;
ex_wstr application;
ex_wstr cmdline;
ex_wstrs description;
}APP_CONFIG;
class TsCfg
{
public:
@ -17,19 +25,14 @@ public:
Json::Value& get_root() { return m_root; }
ex_wstr ssh_app;
ex_wstr ssh_cmdline;
ex_wstr scp_app;
ex_wstr scp_cmdline;
ex_wstr telnet_app;
ex_wstr telnet_cmdline;
ex_wstr rdp_name;
ex_wstr rdp_app;
ex_wstr rdp_cmdline;
APP_CONFIG ssh;
APP_CONFIG sftp;
APP_CONFIG telnet;
APP_CONFIG rdp;
protected:
bool _load(const ex_astr& str_json);
bool _parse_app(const Json::Value& m_root, const ex_astr& str_app, APP_CONFIG& cfg);
protected:
Json::Value m_root;

View File

@ -4,7 +4,7 @@
#define TS_WEB_URL L"https://tp4a.com/"
#define TS_TRAY_MSG L"Teleport助手正常工作中"
#define TS_HTTP_RPC_PORT 50022
#define TS_HTTPS_RPC_PORT 50023
//#define TS_HTTP_RPC_PORT 50022
//#define TS_HTTPS_RPC_PORT 50023
#endif // __TS_CONST_H__

View File

@ -37,22 +37,10 @@ bool TsEnv::init(void)
ex_wstr cfg_default;
#ifdef _DEBUG
m_site_path = m_exec_path;
ex_path_join(m_site_path, true, L"..", L"..", L"..", L"..", L"client", L"tp_assist_win", L"site", NULL);
// m_tools_path = m_exec_path;
// ex_path_join(m_tools_path, true, L"..", L"..", L"..", L"..", L"client", L"tools", NULL);
cfg_default = m_exec_path;
ex_path_join(cfg_default, true, L"..", L"..", L"..", L"..", L"client", L"tp_assist_win", L"cfg", L"tp-assist.default.json", NULL);
#else
m_site_path = m_exec_path;
ex_path_join(m_site_path, false, L"site", NULL);
// m_tools_path = m_exec_path;
// ex_path_join(m_tools_path, false, L"tools", NULL);
cfg_default = m_exec_path;
ex_path_join(cfg_default, false, L"tp-assist.default.json", NULL);
#endif

View File

@ -14,15 +14,8 @@ public:
public:
ex_wstr m_exec_file;
ex_wstr m_exec_path;
ex_wstr m_cfg_file;
// ex_wstr m_res_path;
// ex_wstr m_ssh_client_conf_file;
// ex_wstr m_scp_client_conf_file;
// ex_wstr m_telnet_client_conf_file;
ex_wstr m_cfg_file;
ex_wstr m_log_path;
ex_wstr m_site_path;
ex_wstr m_tools_path;
};

File diff suppressed because it is too large Load Diff

View File

@ -1,94 +0,0 @@
#ifndef __TS_HTTP_RPC_H__
#define __TS_HTTP_RPC_H__
#include "../../external/mongoose/mongoose.h"
#include "ts_const.h"
#include <vector>
#include <string>
#include <map>
#include <ex.h>
#include <json/json.h>
/*
//=================================================================
使
127.0.0.1:50022http
GET
http://127.0.0.1:50022/method/json_param
json_param使url_encodejson
POST
http://127.0.0.1:50022/method
postjson_param
URI
method
json_param
json
{"code":0,"data":varb}
code0datadata
*/
void http_rpc_main_loop(bool is_https);
void http_rpc_stop(bool is_https);
typedef std::map<ex_astr, ex_astr> content_type_map;
// for https server, see
// http://www.xiaovdiy.cn/?post=284
class TsHttpRpc {
public:
TsHttpRpc();
~TsHttpRpc();
bool init_http();
bool init_https();
void run(void);
void stop(void);
void _rpc_func_url_protocol(const ex_astr& func_args, ex_astr& buf);
ex_astr get_content_type(ex_astr file_suffix) {
content_type_map::iterator it=m_content_type_map.find(file_suffix);
if (it != m_content_type_map.end()) {
return it->second;
} else {
return "application/octet-stream";
}
};
private:
bool _on_init();
int _parse_request(struct http_message* req, ex_astr& func_cmd, ex_astr& func_args);
void _process_js_request(const ex_astr& func_cmd, const ex_astr& func_args, ex_astr& buf);
void _create_json_ret(ex_astr& buf, int errcode);
void _create_json_ret(ex_astr& buf, Json::Value& jr_root);
void _rpc_func_run_client(const ex_astr& func_args, ex_astr& buf);
// void _rpc_func_check(const ex_astr& func_args, ex_astr& buf);
void _rpc_func_rdp_play(const ex_astr& func_args, ex_astr& buf);
void _rpc_func_get_config(const ex_astr& func_args, ex_astr& buf);
void _rpc_func_set_config(const ex_astr& func_args, ex_astr& buf);
void _rpc_func_file_action(const ex_astr& func_args, ex_astr& buf);
void _rpc_func_get_version(const ex_astr& func_args, ex_astr& buf);
static void _mg_event_handler(struct mg_connection *nc, int ev, void *ev_data);
private:
content_type_map m_content_type_map;
struct mg_mgr m_mg_mgr;
bool m_stop;
};
#endif // __TS_HTTP_RPC_H__

View File

@ -1,346 +0,0 @@
#include "stdafx.h"
#include "msocketx.h"
#include "ts_network.h"
#include <iostream>
using namespace std;
unsigned short CalcChecksum(char *pBuffer, int nLen)
{
//Checksum for ICMP is calculated in the same way as for
//IP header
//This code was taken from: http://www.netfor2.com/ipsum.htm
unsigned short nWord;
unsigned int nSum = 0;
int i;
//Make 16 bit words out of every two adjacent 8 bit words in the packet
//and add them up
for (i = 0; i < nLen; i = i + 2)
{
nWord = ((pBuffer[i] << 8) & 0xFF00) + (pBuffer[i + 1] & 0xFF);
nSum = nSum + (unsigned int)nWord;
}
//Take only 16 bits out of the 32 bit sum and add up the carries
while (nSum >> 16)
{
nSum = (nSum & 0xFFFF) + (nSum >> 16);
}
//One's complement the result
nSum = ~nSum;
return ((unsigned short)nSum);
}
bool ValidateChecksum(char *pBuffer, int nLen)
{
unsigned short nWord;
unsigned int nSum = 0;
int i;
//Make 16 bit words out of every two adjacent 8 bit words in the packet
//and add them up
for (i = 0; i < nLen; i = i + 2)
{
nWord = ((pBuffer[i] << 8) & 0xFF00) + (pBuffer[i + 1] & 0xFF);
nSum = nSum + (unsigned int)nWord;
}
//Take only 16 bits out of the 32 bit sum and add up the carries
while (nSum >> 16)
{
nSum = (nSum & 0xFFFF) + (nSum >> 16);
}
//To validate the checksum on the received message we don't complement the sum
//of one's complement
//One's complement the result
//nSum = ~nSum;
//The sum of one's complement should be 0xFFFF
return ((unsigned short)nSum == 0xFFFF);
}
int ICMPSendTo(ICMPheaderRet* pICMPheaderRet, char* pszRemoteIP, int nMessageSize, int nCount)
{
int nTimeOut = 500; //Request time out for echo request (in milliseconds)
ICMPheader sendHdr;
//char *pSendBuffer = NULL;
SOCKET sock;
sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); //Create a raw socket which will use ICMP
if (sock == INVALID_SOCKET)
{
return -1;
}
SOCKADDR_IN dest; //Dest address to send the ICMP request
memset(&dest, 0, sizeof(0));
dest.sin_addr.S_un.S_addr = inet_addr(pszRemoteIP);
dest.sin_family = AF_INET;
//dest.sin_port = rand (); //Pick a random port
int nResult = 0;
int nTry = 0;
int nSequence = 0;
fd_set fdRead;
//SYSTEMTIME timeSend, timeRecv;
unsigned long timeTick = 0;
int nTotalRoundTripTime = 0, nMaxRoundTripTime = 0, nMinRoundTripTime = -1, nRoundTripTime = 0;
int nPacketsSent = 0, nPacketsReceived = 0;
timeval timeInterval = { 0, 0 };
timeInterval.tv_usec = nTimeOut * 1000;
sendHdr.nId = htons(rand()); //Set the transaction Id
while (nPacketsSent < nCount)
{
//Create the message buffer, which is big enough to store the header and the message data
///pSendBuffer = new char [sizeof (ICMPheader) + nMessageSize];
char Sendbuf[1024] = { 0 };
int len = (sizeof(ICMPheader) + nMessageSize);
sendHdr.byCode = 0; //Zero for ICMP echo and reply messages
sendHdr.nSequence = htons(nSequence++);
sendHdr.byType = 8; //Eight for ICMP echo message
sendHdr.nChecksum = 0; //Checksum is calculated later on
memcpy_s(Sendbuf, sizeof(ICMPheader), &sendHdr, sizeof(ICMPheader)); //Copy the message header in the buffer
memset(Sendbuf + sizeof(ICMPheader), 'x', nMessageSize); //Fill the message with some arbitary value
//Calculate checksum over ICMP header and message data
sendHdr.nChecksum = htons(CalcChecksum(Sendbuf, sizeof(ICMPheader) + nMessageSize));
//Copy the message header back into the buffer
memcpy_s(Sendbuf, sizeof(ICMPheader), &sendHdr, sizeof(ICMPheader));
//::GetSystemTime (&timeSend);
timeTick = GetTickCount();
nResult = sendto(sock, Sendbuf, sizeof(ICMPheader) + nMessageSize, 0, (SOCKADDR *)&dest, sizeof(SOCKADDR_IN));
//Save the time at which the ICMP echo message was sent
++nPacketsSent;
if (nResult == SOCKET_ERROR)
{
cerr << endl << "An error occured in sendto operation: " << "WSAGetLastError () = " << WSAGetLastError() << endl;
//UnInitialize ();
closesocket(sock);
return -1;
}
next:
FD_ZERO(&fdRead);
FD_SET(sock, &fdRead);
if ((nResult = select(0, &fdRead, NULL, NULL, &timeInterval))
== SOCKET_ERROR)
{
cerr << endl << "An error occured in select operation: " << "WSAGetLastError () = " <<
WSAGetLastError() << endl;
closesocket(sock);
//delete []pSendBuffer;
return -2;
}
//printf("FD_ISSET Enter --- 0\n");
if (nResult > 0 && FD_ISSET(sock, &fdRead))
{
//printf("FD_ISSET Enter --- 1\n");
//Allocate a large buffer to store the response
char buf[1500] = { 0 };
struct sockaddr_in addr;
int addr_len = sizeof(struct sockaddr_in);
memset(&addr, 0, sizeof(sockaddr_in));
if ((nResult = recvfrom(sock, buf, 1500, 0, (struct sockaddr *)&addr, &addr_len))
== SOCKET_ERROR)
{
cerr << endl << "An error occured in recvfrom operation: " << "WSAGetLastError () = " <<
WSAGetLastError() << endl;
//UnInitialize ();
//delete []pSendBuffer;
closesocket(sock);
return -3;
}
//printf("FD_ISSET Enter --- 2 IP%s\n",inet_ntoa(addr.sin_addr));
string strIP = inet_ntoa(addr.sin_addr);
if (strIP.compare(pszRemoteIP) == 0)
{
//Get the time at which response is received
//::GetSystemTime (&timeRecv);
//We got a response so we construct the ICMP header and message out of it
ICMPheader recvHdr;
char *pICMPbuffer = NULL;
//The response includes the IP header as well, so we move 20 bytes ahead to read the ICMP header
pICMPbuffer = buf + sizeof(IPheader);
//ICMP message length is calculated by subtracting the IP header size from the
//total bytes received
int nICMPMsgLen = nResult - sizeof(IPheader);
//Construct the ICMP header
memcpy_s(&recvHdr, sizeof(recvHdr), pICMPbuffer, sizeof(recvHdr));
//Construct the IP header from the response
IPheader ipHdr;
memcpy_s(&ipHdr, sizeof(ipHdr), buf, sizeof(ipHdr));
recvHdr.nId = recvHdr.nId;
recvHdr.nSequence = recvHdr.nSequence;
recvHdr.nChecksum = ntohs(recvHdr.nChecksum);
if (recvHdr.byType == 0 &&
recvHdr.nId == sendHdr.nId &&
recvHdr.nSequence == sendHdr.nSequence &&
ValidateChecksum(pICMPbuffer, nICMPMsgLen) &&
memcmp(Sendbuf + sizeof(ICMPheader), buf + sizeof(ICMPheader) + sizeof(IPheader),
nResult - sizeof(ICMPheader) - sizeof(IPheader)) == 0)
{
printf("FD_ISSET Enter --- 3\n");
int nRoundTripTime = 0;
nRoundTripTime = (GetTickCount() - timeTick);
nTotalRoundTripTime = nTotalRoundTripTime + nRoundTripTime;
if (nMinRoundTripTime == -1)
{
nMinRoundTripTime = nRoundTripTime;
nMaxRoundTripTime = nRoundTripTime;
}
else if (nRoundTripTime < nMinRoundTripTime)
{
nMinRoundTripTime = nRoundTripTime;
}
else if (nRoundTripTime > nMaxRoundTripTime)
{
nMaxRoundTripTime = nRoundTripTime;
}
++nPacketsReceived;
}
else
{
cout << "The echo reply is not correct! Type : " << recvHdr.byType << endl;
}
}
else
{
goto next;
}
//Check if the response is an echo reply, transaction ID and sequence number are same
//as for the request, and that the checksum is correct
//if (recvHdr.byType == 0 &&
// recvHdr.nId == sendHdr.nId &&
// recvHdr.nSequence == sendHdr.nSequence &&
// ValidateChecksum (pICMPbuffer, nICMPMsgLen) &&
// memcmp (pSendBuffer + sizeof(ICMPheader), pRecvBuffer + sizeof (ICMPheader) + sizeof(IPheader),
// nResult - sizeof (ICMPheader) - sizeof(IPheader)) == 0)
//{
// printf("FD_ISSET Enter --- 3\n");
// int nRoundTripTime = 0;
// nRoundTripTime = (GetTickCount() - timeTick);
// nTotalRoundTripTime = nTotalRoundTripTime + nRoundTripTime;
// if (nMinRoundTripTime == -1)
// {
// nMinRoundTripTime = nRoundTripTime;
// nMaxRoundTripTime = nRoundTripTime;
// }
// else if (nRoundTripTime < nMinRoundTripTime)
// {
// nMinRoundTripTime = nRoundTripTime;
// }
// else if (nRoundTripTime > nMaxRoundTripTime)
// {
// nMaxRoundTripTime = nRoundTripTime;
// }
// ++nPacketsReceived;
//}
//else
//{
// cout << "The echo reply is not correct!" << endl;
//}
//delete []pRecvBuffer;
}
else
{
cout << "Request timed out. Tick : " << GetTickCount() << endl;
}
}
cout << endl << "Ping statistics for " << pszRemoteIP << ":" << endl << '\t' << "Packets: Sent = " << nPacketsSent << ", Received = " <<
nPacketsReceived << ", Lost = " << (nPacketsSent - nPacketsReceived) << " (" <<
((nPacketsSent - nPacketsReceived) / (float)nPacketsSent) * 100 << "% loss)" << endl << '\t';
pICMPheaderRet->nPacketsSent = nPacketsSent;
pICMPheaderRet->nPacketsReceived = nPacketsReceived;
if (nPacketsReceived > 0)
{
// cout << "\rApproximate round trip times in milli-seconds:" << endl << '\t' << "Minimum = " << nMinRoundTripTime <<
// "ms, Maximum = " << nMaxRoundTripTime << "ms, Average = " << nTotalRoundTripTime / (float)nPacketsReceived << "ms" << endl;
pICMPheaderRet->nMinRoundTripTime = nMinRoundTripTime;
pICMPheaderRet->nMaxRoundTripTime = nMaxRoundTripTime;
pICMPheaderRet->nAverageRoundTripTime = (int)(nTotalRoundTripTime / (float)nPacketsReceived);
}
else
{
pICMPheaderRet->nMinRoundTripTime = -1;
pICMPheaderRet->nMaxRoundTripTime = -1;
pICMPheaderRet->nAverageRoundTripTime = -1;
//getchar();
}
closesocket(sock);
//cout << '\r' << endl;
return 0;
}
bool TestTCPPort(const ex_astr& strServerIP, int port)
{
int icount = 0;
unsigned int uibegconn = GetTickCount();
unsigned int uicostconn = 0;
msocketx sock;
sock.create(SOCK_STREAM, IPPROTO_TCP);
sock.setsocktime(1000);
int iconn = sock.connect(strServerIP.c_str(), port, false);
bool bFailed = true;
while (++icount <= 2)
{
int nRet = sock.wait(1000, CAN_CONNECTX);
if (nRet < 0)
{
continue;
}
if ((nRet & CAN_CONNECTX) == CAN_CONNECTX)
{
return true;
}
else
{
continue;
}
}
return false;
}

View File

@ -1,43 +0,0 @@
#pragma once
#include <map>
struct ICMPheaderRet
{
unsigned int ulSrcServerIP; //IP地址
unsigned int ulDesServerIP; //IP地址
int nPacketsSent; //发送的包
int nPacketsReceived; //收到的包
int nMinRoundTripTime; //最大时间
int nMaxRoundTripTime; //最短时间
int nAverageRoundTripTime; //平均时间
int nSesssionID; //sessionId
};
typedef std::map<unsigned int, ICMPheaderRet>ICMPheaderRetMap;
struct ICMPheader
{
unsigned char byType;
unsigned char byCode;
unsigned short nChecksum;
unsigned short nId;
unsigned short nSequence;
unsigned int Tick;
};
struct IPheader
{
unsigned char byVerLen;
unsigned char byTos;
unsigned short nTotalLength;
unsigned short nId;
unsigned short nOffset;
unsigned char byTtl;
unsigned char byProtocol;
unsigned short nChecksum;
unsigned int nSrcAddr;
unsigned int nDestAddr;
};
bool TestTCPPort(const ex_astr& strServerIP, int port);
int ICMPSendTo(ICMPheaderRet* pICMPheaderRet, char* pszRemoteIP, int nMessageSize, int nCount);

View File

@ -0,0 +1,39 @@
// #include <unistd.h>
#include "ts_utils.h"
#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')
int ts_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded)
{
int i, j, a, b;
for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++)
{
if (src[i] == '%')
{
if (i < src_len - 2 && isxdigit(*(const unsigned char *)(src + i + 1)) &&
isxdigit(*(const unsigned char *)(src + i + 2))) {
a = tolower(*(const unsigned char *)(src + i + 1));
b = tolower(*(const unsigned char *)(src + i + 2));
dst[j] = (char)((HEXTOI(a) << 4) | HEXTOI(b));
i += 2;
}
else
{
return -1;
}
}
else if (is_form_url_encoded && src[i] == '+')
{
dst[j] = ' ';
}
else
{
dst[j] = src[i];
}
}
dst[j] = '\0'; /* Null-terminate the destination */
return i >= src_len ? j : -1;
}

View File

@ -0,0 +1,8 @@
#ifndef __TS_UTILS_H__
#define __TS_UTILS_H__
#include <ex.h>
int ts_url_decode(const char *src, int src_len, char *dst, int dst_len, int is_form_url_encoded);
#endif // __TS_UTILS_H__

View File

@ -0,0 +1,923 @@
#include "stdafx.h"
#pragma warning(disable:4091)
#include <commdlg.h>
#include <ShlObj.h>
#include <WinCrypt.h>
#pragma comment(lib, "Crypt32.lib")
#include <teleport_const.h>
//#ifndef MAX_PATH
//# define MAX_PATH 1024
//#endif
// #include "../AppDelegate-C-Interface.h"
#include "ts_ws_client.h"
#include "ts_ver.h"
#include "ts_env.h"
#include "ts_cfg.h"
#include "ts_utils.h"
//#ifdef RDP_CLIENT_SYSTEM_BUILTIN
//connect to console:i:%d
//compression:i:1
//bitmapcachepersistenable:i:1
std::string rdp_content = "\
administrative session:i:%d\n\
screen mode id:i:%d\n\
use multimon:i:0\n\
desktopwidth:i:%d\n\
desktopheight:i:%d\n\
session bpp:i:16\n\
winposstr:s:0,1,%d,%d,%d,%d\n\
bitmapcachepersistenable:i:1\n\
bitmapcachesize:i:32000\n\
compression:i:1\n\
keyboardhook:i:2\n\
audiocapturemode:i:0\n\
videoplaybackmode:i:1\n\
connection type:i:7\n\
networkautodetect:i:1\n\
bandwidthautodetect:i:1\n\
disableclipboardredirection:i:0\n\
displayconnectionbar:i:1\n\
enableworkspacereconnect:i:0\n\
disable wallpaper:i:1\n\
allow font smoothing:i:0\n\
allow desktop composition:i:0\n\
disable full window drag:i:1\n\
disable menu anims:i:1\n\
disable themes:i:1\n\
disable cursor setting:i:1\n\
full address:s:%s:%d\n\
audiomode:i:0\n\
redirectprinters:i:0\n\
redirectcomports:i:0\n\
redirectsmartcards:i:0\n\
redirectclipboard:i:%d\n\
redirectposdevices:i:0\n\
autoreconnection enabled:i:0\n\
authentication level:i:2\n\
prompt for credentials:i:0\n\
negotiate security layer:i:1\n\
remoteapplicationmode:i:0\n\
alternate shell:s:\n\
shell working directory:s:\n\
gatewayhostname:s:\n\
gatewayusagemethod:i:4\n\
gatewaycredentialssource:i:4\n\
gatewayprofileusagemethod:i:0\n\
promptcredentialonce:i:0\n\
gatewaybrokeringtype:i:0\n\
use redirection server name:i:0\n\
rdgiskdcproxy:i:0\n\
kdcproxyname:s:\n\
drivestoredirect:s:%s\n\
username:s:%s\n\
password 51:b:%s\n\
";
// https://www.donkz.nl/overview-rdp-file-settings/
//
// authentication level:i:2\n
//
//
// negotiate security layer:i:1\n
// 0 = negotiation is not enabled and the session is started by using Secure Sockets Layer (SSL).
// 1 = negotiation is enabled and the session is started by using x.224 encryption.
//redirectdirectx:i:0\n\
//prompt for credentials on client:i:0\n\
//#endif
TsWsClient g_ws_client;
TsWsClient g_wss_client;
void* g_app = NULL;
bool calc_psw51b(const char* password, std::string& ret) {
DATA_BLOB DataIn;
DATA_BLOB DataOut;
ex_wstr w_pswd;
ex_astr2wstr(password, w_pswd, EX_CODEPAGE_ACP);
DataIn.cbData = w_pswd.length() * sizeof(wchar_t);
DataIn.pbData = (BYTE*)w_pswd.c_str();
if (!CryptProtectData(&DataIn, L"psw", nullptr, nullptr, nullptr, 0, &DataOut))
return false;
char szRet[5] = { 0 };
for (DWORD i = 0; i < DataOut.cbData; ++i) {
sprintf_s(szRet, 5, "%02X", DataOut.pbData[i]);
ret += szRet;
}
LocalFree(DataOut.pbData);
return true;
}
// static
void TsWsClient::init_app(void* app)
{
g_app = app;
}
void TsWsClient::stop_all_client()
{
g_ws_client.stop();
g_wss_client.stop();
}
// ============================================================================
// static
void TsWsClient::url_scheme_handler(const std::string& url)
{
// from command line:
// teleport://register?param={"ws_url":"ws://127.0.0.1:7190/ws/assist/","assist_id":1234,"session_id":"tp_5678"}
// from system-url-protocol handler. why Windows add extra '/' for me???
// teleport://register/?param={"ws_url":"ws://127.0.0.1:7190/ws/assist/","assist_id":1234,"session_id":"tp_5678"}
std::string protocol;
std::string method;
std::string param;
std::string::size_type pos_protocol = url.find("://");
if (pos_protocol == std::string::npos)
{
EXLOGE("[ws] invalid url: %s\n", url.c_str());
return;
}
std::string::size_type pos_method = url.find('?');
if (pos_method == std::string::npos)
{
EXLOGE("[ws] invalid url: %s\n", url.c_str());
return;
}
protocol.assign(url, 0, pos_protocol);
if (protocol != "teleport")
{
EXLOGE("[ws] invalid protocol: %s\n", protocol.c_str());
return;
}
// now we support 'register' method only.
method.assign(url, pos_protocol + 3, pos_method - pos_protocol - 3);
if (method[method.length() - 1] == '/')
method.erase(method.length() - 1, 1);
if (method != "register")
{
EXLOGE("[ws] unknown method: %s\n", method.c_str());
return;
}
param.assign(url, pos_method + 7); // ?param=
if (param.empty())
{
EXLOGE("[ws] invalid protocol: %s\n", protocol.c_str());
return;
}
// decode param with url-decode.
size_t len = param.length() * 2;
ex_chars sztmp;
sztmp.resize(len);
memset(&sztmp[0], 0, len);
if (-1 == ts_url_decode(param.c_str(), (int)param.length(), &sztmp[0], (int)len, 0))
{
EXLOGE("[ws] url-decode param failed: %s\n", param.c_str());
return;
}
param = &sztmp[0];
EXLOGV("[rpc] method=%s, json_param=%s\n", method.c_str(), param.c_str());
Json::CharReaderBuilder jcrb;
std::unique_ptr<Json::CharReader> const jreader(jcrb.newCharReader());
const char* str_json_begin = param.c_str();
Json::Value js_root;
ex_astr err;
if (!jreader->parse(str_json_begin, str_json_begin + param.length(), &js_root, &err))
{
EXLOGE("[ws] param not in json format: %s\n", param.c_str());
return;
}
if (!js_root.isObject())
{
EXLOGE("[ws] invalid param, need json object: %s\n", param.c_str());
return;
}
// now we support 'register' method only.
_process_register(param, js_root);
}
// static
void TsWsClient::_process_register(const std::string& param, Json::Value& js_root)
{
// {"ws_url":"ws://127.0.0.1:7190/ws/assist/","assist_id":1234,"session_id":"tp_5678"}
// check param
if (!js_root["ws_url"].isString() || !js_root["assist_id"].isNumeric() || !js_root["session_id"].isString())
{
EXLOGE("[ws] invalid param: %s\n", param.c_str());
return;
}
std::string ws_url = js_root["ws_url"].asCString();
uint32_t assist_id = js_root["assist_id"].asUInt();
std::string session_id = js_root["session_id"].asCString();
std::string protocol;
protocol.assign(ws_url, 0, 3);
if (protocol == "ws:")
{
g_ws_client._register(ws_url, assist_id, session_id);
}
else if (protocol == "wss")
{
g_wss_client._register(ws_url, assist_id, session_id);
}
else
{
EXLOGE("[ws] invalid ws_url: %s\n", ws_url.c_str());
return;
}
}
// ============================================================================
TsWsClient::TsWsClient() :
ExThreadBase("ws-client-thread"),
m_nc(NULL),
m_assist_id(0)
{
mg_mgr_init(&m_mg_mgr, NULL);
}
TsWsClient::~TsWsClient()
{
mg_mgr_free(&m_mg_mgr);
}
void TsWsClient::_thread_loop(void)
{
while (!m_need_stop)
{
mg_mgr_poll(&m_mg_mgr, 500);
}
EXLOGV("[ws] main loop end.\n");
}
void TsWsClient::_register(const std::string& ws_url, uint32_t assist_id, const std::string& session_id)
{
if (m_assist_id == 0)
m_assist_id = assist_id;
ex_wstr w_ver(TP_ASSIST_VER);
ex_astr a_ver;
ex_wstr2astr(w_ver, a_ver);
//
char msg[256] = { 0 };
ex_strformat(
msg, 256, "{\"type\":0,\"method\":\"register\",\"param\":{\"client\":\"assist\",\"sid\":\"%s\",\"request_assist_id\":%u,\"assist_id\":%u,\"assist_ver\":\"%s\"}}",
session_id.c_str(), assist_id, m_assist_id, a_ver.c_str());
if (!m_is_running)
{
// not start yet.
std::string url = ws_url;
url += msg;
m_nc = mg_connect_ws(&m_mg_mgr, _mg_event_handler, url.c_str(), NULL, NULL);
if (!m_nc)
{
EXLOGE("[ws] TsWsClient::init failed: %s\n", url.c_str());
return;
}
m_nc->user_data = this;
start();
return;
}
EXLOGV("[ws] send: %s\n", msg);
mg_send_websocket_frame(m_nc, WEBSOCKET_OP_TEXT, msg, strlen(msg));
}
// static
void TsWsClient::_mg_event_handler(struct mg_connection* nc, int ev, void* ev_data)
{
auto* _this = (TsWsClient*)nc->user_data;
if (NULL == _this)
{
EXLOGE("[ERROR] invalid request.\n");
return;
}
switch (ev)
{
case MG_EV_CONNECT:
{
int status = *((int*)ev_data);
if (status != 0)
{
EXLOGE("[ERROR] -- connect to ws server failed: %d\n", status);
}
break;
}
case MG_EV_WEBSOCKET_HANDSHAKE_DONE:
{
auto* hm = (struct http_message*)ev_data;
if (hm->resp_code == 101)
{
EXLOGV("-- ws server connected\n");
}
else
{
EXLOGE("[ERROR] -- connect to ws server failed, HTTP code: %d\n", hm->resp_code);
}
break;
}
case MG_EV_WEBSOCKET_FRAME:
{
// on_message().
auto* wm = (struct websocket_message*)ev_data;
// EXLOGV("%d: %s\n", wm->size, wm->data);
std::string message;
message.assign((const char*)wm->data, wm->size);
std::string buf;
_this->_on_message(message, buf);
if (!buf.empty())
{
mg_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, buf.c_str(), buf.length());
}
break;
}
case MG_EV_CLOSE:
{
EXLOGV("-- ws server disconnected\n");
_this->m_need_stop = true;
break;
}
}
}
void TsWsClient::_create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code)
{
Json::Value js_data(Json::objectValue);
_create_response(buf, msg_ret, err_code, L"", js_data);
}
void TsWsClient::_create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code, const ex_wstr& message)
{
Json::Value js_data(Json::objectValue);
_create_response(buf, msg_ret, err_code, message, js_data);
}
void TsWsClient::_create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code, const ex_wstr& message, Json::Value& data)
{
ex_astr _message;
// ex_wstr2astr(message, _message, EX_CODEPAGE_UTF8);
ex_wstr2astr(message, _message);
Json::Value js_ret;
js_ret["type"] = MESSAGE_TYPE_RESPONSE;
js_ret["command_id"] = msg_ret.command_id;
js_ret["method"] = msg_ret.method;
js_ret["code"] = err_code;
js_ret["message"] = _message;
js_ret["data"] = data;
Json::StreamWriterBuilder jwb;
// jwb["emitUTF8"] = true;
jwb["indentation"] = ""; // 压缩格式,没有换行和不必要的空白字符
std::unique_ptr<Json::StreamWriter> js_writer(jwb.newStreamWriter());
ex_aoss os;
js_writer->write(js_ret, &os);
buf = os.str();
}
void TsWsClient::_on_message(const std::string& message, std::string& buf)
{
// {
// "type":0,
// "method":"run",
// "param":{
// "teleport_ip":"127.0.0.1","teleport_port":52189,"remote_host_ip":"39.97.125.170",
// "remote_host_name":"tp4a.com","session_id":"9DE744","protocol_type":2,
// "protocol_sub_type":200,"protocol_flag":4294967295
// }
// }
AssistMessage msg_req;
Json::CharReaderBuilder jrb;
std::unique_ptr<Json::CharReader> const js_reader(jrb.newCharReader());
const char* str_json_begin = message.c_str();
Json::Value js_root;
ex_astr err;
if (!js_reader->parse(str_json_begin, str_json_begin + message.length(), &js_root, &err))
{
_create_response(buf, msg_req, TPE_JSON_FORMAT);
return;
}
if (!js_root.isObject())
{
_create_response(buf, msg_req, TPE_PARAM);
return;
}
if (js_root["type"].isNull() || !js_root["type"].isInt())
{
_create_response(buf, msg_req, TPE_PARAM);
return;
}
int cmd_type = js_root["type"].asInt();
if (!(cmd_type == MESSAGE_TYPE_REQUEST || cmd_type == MESSAGE_TYPE_RESPONSE))
{
_create_response(buf, msg_req, TPE_PARAM);
return;
}
// 收到的信息已经是“返回值”了,说明已经是一条命令的结束了,不用继续处理
// todo: 可能需要记录日志,或者展示结果。
//if (cmd_type == MESSAGE_TYPE_RESPONSE)
//{
// char msg[129] = { 0 };
// _snprintf_s(msg, 128, "%d %d", cmd_type, MESSAGE_TYPE_RESPONSE);
// MessageBoxA(NULL, msg, "INFO", MB_OK);
// return;
//}
if (js_root["method"].isNull() || !js_root["method"].isString() || js_root["command_id"].isNull() || !js_root["command_id"].isInt())
{
_create_response(buf, msg_req, TPE_PARAM);
return;
}
msg_req.command_id = js_root["command_id"].asInt();
msg_req.method = js_root["method"].asString();
if (msg_req.command_id == 0 || msg_req.method.empty())
{
_create_response(buf, msg_req, TPE_PARAM);
return;
}
if (msg_req.method == "run")
{
_rpc_func_run_client(buf, msg_req, js_root);
}
else if (msg_req.method == "get_config")
{
_rpc_func_get_config(buf, msg_req, js_root);
}
else if (msg_req.method == "set_config")
{
_rpc_func_set_config(buf, msg_req, js_root);
}
else if (msg_req.method == "select_file")
{
_rpc_func_select_file(buf, msg_req, js_root);
}
else
{
EXLOGE("[ws] got unknown command: %s\n", msg_req.method.c_str());
_create_response(buf, msg_req, TPE_UNKNOWN_CMD);
}
}
void TsWsClient::_rpc_func_get_config(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root)
{
Json::Value& ret = g_cfg.get_root();
ret["os_type"] = "windows";
_create_response(buf, msg_req, TPE_OK, L"", ret);
}
void TsWsClient::_rpc_func_set_config(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root)
{
if (js_root["param"].isNull() || !js_root["param"].isObject())
{
_create_response(buf, msg_req, TPE_PARAM);
return;
}
Json::Value& js_param = js_root["param"];
Json::StreamWriterBuilder jwb;
std::unique_ptr<Json::StreamWriter> js_writer(jwb.newStreamWriter());
ex_aoss os;
js_writer->write(js_param, &os);
if (!g_cfg.save(os.str()))
_create_response(buf, msg_req, TPE_FAILED);
else
_create_response(buf, msg_req, TPE_OK);
}
void TsWsClient::_rpc_func_select_file(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root)
{
// _create_response(buf, msg_req, TPE_FAILED, L"尚不支持在macOS平台选择应用请手动填写应用程序路径");
// _create_response(buf, msg_req, TPE_FAILED, L"尚不支持选择应用,请手动填写应用程序路径!");
if (js_root["param"].isNull() || !js_root["param"].isObject() || js_root["param"]["app_type"].isNull())
{
_create_response(buf, msg_req, TPE_PARAM);
return;
}
// Json::Value& js_param = js_root["param"];
HWND hParent = GetForegroundWindow();
if (NULL == hParent)
hParent = NULL;
BOOL ret = FALSE;
wchar_t wszReturnPath[MAX_PATH] = _T("");
OPENFILENAME ofn;
ex_wstr wsDefaultName;
ex_wstr wsDefaultPath;
StringCchCopy(wszReturnPath, MAX_PATH, wsDefaultName.c_str());
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.lpstrTitle = NULL;// L"Select application execute file";
ofn.hwndOwner = hParent;
ofn.lpstrFilter = L"Execute file (*.exe)\0*.exe\0";
ofn.lpstrFile = wszReturnPath;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrInitialDir = wsDefaultPath.c_str();
ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST;
ofn.Flags |= OFN_FILEMUSTEXIST;
ret = GetOpenFileNameW(&ofn);
if (!ret)
{
_create_response(buf, msg_req, TPE_FAILED, L"用户取消了选择操作!");
return;
}
ex_astr utf8_path;
ex_wstr2astr(wszReturnPath, utf8_path, EX_CODEPAGE_UTF8);
Json::Value js_ret;
js_ret["app_type"] = js_root["param"]["app_type"];
js_ret["app_path"] = utf8_path;
_create_response(buf, msg_req, TPE_OK, L"", js_ret);
}
void TsWsClient::_rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root) {
// {
// "method":"run",
// "param":{
// "teleport_ip":"127.0.0.1","teleport_port":52189,"remote_host_ip":"39.97.125.170",
// "remote_host_name":"tp4a.com","session_id":"9DE744","protocol_type":2,
// "protocol_sub_type":200,"protocol_flag":4294967295
// }
// }
// 判断参数是否正确
if (js_root["param"].isNull() || !js_root["param"].isObject())
{
_create_response(buf, msg_req, TPE_PARAM);
return;
}
Json::Value& js_param = js_root["param"];
if (!js_param["teleport_ip"].isString()
|| !js_param["teleport_port"].isNumeric() || !js_param["remote_host_ip"].isString()
|| !js_param["session_id"].isString() || !js_param["protocol_type"].isNumeric() || !js_param["protocol_sub_type"].isNumeric()
|| !js_param["protocol_flag"].isNumeric()
)
{
_create_response(buf, msg_req, TPE_PARAM);
return;
}
int pro_type = js_param["protocol_type"].asUInt();
int pro_sub = js_param["protocol_sub_type"].asInt();
ex_u32 protocol_flag = js_param["protocol_flag"].asUInt();
ex_astr teleport_ip = js_param["teleport_ip"].asCString();
int teleport_port = js_param["teleport_port"].asUInt();
ex_astr real_host_ip = js_param["remote_host_ip"].asCString();
ex_astr remote_host_name = js_param["remote_host_name"].asCString();
ex_astr sid = js_param["session_id"].asCString();
ex_wstr w_exe_path;
WCHAR w_szCommandLine[MAX_PATH] = { 0 };
ex_wstr w_sid;
ex_astr2wstr(sid, w_sid);
ex_wstr w_teleport_ip;
ex_astr2wstr(teleport_ip, w_teleport_ip);
ex_wstr w_real_host_ip;
ex_astr2wstr(real_host_ip, w_real_host_ip);
ex_wstr w_remote_host_name;
ex_astr2wstr(remote_host_name, w_remote_host_name);
WCHAR w_port[32] = { 0 };
swprintf_s(w_port, _T("%d"), teleport_port);
ex_wstr tmp_rdp_file; // for .rdp file
if (pro_type == TP_PROTOCOL_TYPE_RDP) {
//==============================================
// RDP
//==============================================
bool flag_clipboard = ((protocol_flag & TP_FLAG_RDP_CLIPBOARD) == TP_FLAG_RDP_CLIPBOARD);
bool flag_disk = ((protocol_flag & TP_FLAG_RDP_DISK) == TP_FLAG_RDP_DISK);
bool flag_console = ((protocol_flag & TP_FLAG_RDP_CONSOLE) == TP_FLAG_RDP_CONSOLE);
int rdp_w = 800;
int rdp_h = 640;
bool rdp_console = false;
if (!js_param["rdp_width"].isNull()) {
if (js_param["rdp_width"].isNumeric()) {
rdp_w = js_param["rdp_width"].asUInt();
}
else {
_create_response(buf, msg_req, TPE_PARAM);
return;
}
}
if (!js_param["rdp_height"].isNull()) {
if (js_param["rdp_height"].isNumeric()) {
rdp_h = js_param["rdp_height"].asUInt();
}
else {
_create_response(buf, msg_req, TPE_PARAM);
return;
}
}
if (!js_param["rdp_console"].isNull()) {
if (js_param["rdp_console"].isBool()) {
rdp_console = js_param["rdp_console"].asBool();
}
else {
_create_response(buf, msg_req, TPE_PARAM);
return;
}
}
if (!flag_console)
rdp_console = false;
int split_pos = sid.length() - 2;
ex_astr real_sid = sid.substr(0, split_pos);
ex_astr str_pwd_len = sid.substr(split_pos, sid.length());
int n_pwd_len = strtol(str_pwd_len.c_str(), nullptr, 16);
n_pwd_len -= real_sid.length();
n_pwd_len -= 2;
char szPwd[256] = { 0 };
for (int i = 0; i < n_pwd_len; i++) {
szPwd[i] = '*';
}
ex_astr2wstr(real_sid, w_sid);
w_exe_path = _T("\"");
w_exe_path += g_cfg.rdp.application + _T("\" ");
ex_wstr rdp_name = g_cfg.rdp.name;
if (rdp_name == L"mstsc") {
w_exe_path += g_cfg.rdp.cmdline;
int width = 0;
int higth = 0;
int cx = 0;
int cy = 0;
int display = 1;
int iWidth = GetSystemMetrics(SM_CXSCREEN);
int iHeight = GetSystemMetrics(SM_CYSCREEN);
if (rdp_w == 0 || rdp_h == 0) {
//全屏
width = iWidth;
higth = iHeight;
display = 2;
}
else {
width = rdp_w;
higth = rdp_h;
display = 1;
}
cx = (iWidth - width) / 2;
cy = (iHeight - higth) / 2;
if (cx < 0) {
cx = 0;
}
if (cy < 0) {
cy = 0;
}
// int console_mode = 0;
// if (rdp_console)
// console_mode = 1;
std::string psw51b;
if (!calc_psw51b(szPwd, psw51b)) {
EXLOGE("calc password failed.\n");
_create_response(buf, msg_req, TPE_PARAM);
return;
}
real_sid = "01" + real_sid;
char sz_rdp_file_content[4096] = { 0 };
sprintf_s(sz_rdp_file_content, 4096, rdp_content.c_str()
, (flag_console && rdp_console) ? 1 : 0
, display, width, higth
, cx, cy, cx + width + 100, cy + higth + 100
, teleport_ip.c_str(), teleport_port
, flag_clipboard ? 1 : 0
, flag_disk ? "*" : ""
, real_sid.c_str()
, psw51b.c_str()
);
char sz_file_name[MAX_PATH] = { 0 };
char temp_path[MAX_PATH] = { 0 };
DWORD ret = GetTempPathA(MAX_PATH, temp_path);
if (ret <= 0) {
EXLOGE("fopen failed (%d).\n", GetLastError());
_create_response(buf, msg_req, TPE_FAILED);
return;
}
ex_astr temp_host_ip = real_host_ip;
ex_replace_all(temp_host_ip, ".", "-");
sprintf_s(sz_file_name, MAX_PATH, ("%s%s.rdp"), temp_path, temp_host_ip.c_str());
FILE* f = NULL;
if (fopen_s(&f, sz_file_name, "wt") != 0) {
EXLOGE("fopen failed (%d).\n", GetLastError());
_create_response(buf, msg_req, TPE_OPENFILE);
return;
}
// Write a string into the file.
fwrite(sz_rdp_file_content, strlen(sz_rdp_file_content), 1, f);
fclose(f);
ex_astr2wstr(sz_file_name, tmp_rdp_file);
// 变量替换
ex_replace_all(w_exe_path, _T("{tmp_rdp_file}"), tmp_rdp_file);
}
else if (g_cfg.rdp.name == L"freerdp") {
w_exe_path += L"{size} {console} {clipboard} {drives} ";
w_exe_path += g_cfg.rdp.cmdline;
ex_wstr w_screen;
if (rdp_w == 0 || rdp_h == 0) {
//全屏
w_screen = _T("/f");
}
else {
char sz_size[64] = { 0 };
ex_strformat(sz_size, 63, "/size:%dx%d", rdp_w, rdp_h);
ex_astr2wstr(sz_size, w_screen);
}
// wchar_t* w_console = NULL;
//
// if (flag_console && rdp_console)
// {
// w_console = L"/admin";
// }
// else
// {
// w_console = L"";
// }
ex_wstr w_password;
ex_astr2wstr(szPwd, w_password);
w_exe_path += L" /p:";
w_exe_path += w_password;
w_sid = L"02" + w_sid;
w_exe_path += L" /gdi:sw"; // 使用软件渲染gdi:hw使用硬件加速但是会出现很多黑块录像回放时又是正常的
w_exe_path += L" -grab-keyboard"; // [new style] 防止启动FreeRDP后失去本地键盘响应必须得先最小化一下FreeRDP窗口不过貌似不起作用
// 变量替换
ex_replace_all(w_exe_path, _T("{size}"), w_screen);
if (flag_console && rdp_console)
ex_replace_all(w_exe_path, _T("{console}"), L"/admin");
else
ex_replace_all(w_exe_path, _T("{console}"), L"");
//ex_replace_all(w_exe_path, _T("{clipboard}"), L"+clipboard");
if (flag_clipboard)
ex_replace_all(w_exe_path, _T("{clipboard}"), L"/clipboard");
else
ex_replace_all(w_exe_path, _T("{clipboard}"), L"-clipboard");
if (flag_disk)
ex_replace_all(w_exe_path, _T("{drives}"), L"/drives");
else
ex_replace_all(w_exe_path, _T("{drives}"), L"-drives");
}
else {
_create_response(buf, msg_req, TPE_FAILED);
return;
}
}
else if (pro_type == TP_PROTOCOL_TYPE_SSH) {
//==============================================
// SSH
//==============================================
if (pro_sub == TP_PROTOCOL_TYPE_SSH_SHELL) {
w_exe_path = _T("\"");
w_exe_path += g_cfg.ssh.application + _T("\" ");
w_exe_path += g_cfg.ssh.cmdline;
}
else {
w_exe_path = _T("\"");
w_exe_path += g_cfg.sftp.application + _T("\" ");
w_exe_path += g_cfg.sftp.cmdline;
}
}
else if (pro_type == TP_PROTOCOL_TYPE_TELNET) {
//==============================================
// TELNET
//==============================================
w_exe_path = _T("\"");
w_exe_path += g_cfg.telnet.application + _T("\" ");
w_exe_path += g_cfg.telnet.cmdline;
}
ex_replace_all(w_exe_path, _T("{host_ip}"), w_teleport_ip.c_str());
ex_replace_all(w_exe_path, _T("{host_port}"), w_port);
ex_replace_all(w_exe_path, _T("{user_name}"), w_sid.c_str());
ex_replace_all(w_exe_path, _T("{host_name}"), w_remote_host_name.c_str());
ex_replace_all(w_exe_path, _T("{real_ip}"), w_real_host_ip.c_str());
ex_replace_all(w_exe_path, _T("{assist_tools_path}"), g_env.m_tools_path.c_str());
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
Json::Value js_data;
ex_astr utf8_path;
ex_wstr2astr(w_exe_path, utf8_path, EX_CODEPAGE_UTF8);
js_data["path"] = utf8_path;
if (!CreateProcess(NULL, (wchar_t*)w_exe_path.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
EXLOGE(_T("CreateProcess() failed. Error=0x%08X.\n %s\n"), GetLastError(), w_exe_path.c_str());
_create_response(buf, msg_req, TPE_START_CLIENT);
return;
}
_create_response(buf, msg_req, TPE_OK, L"", js_data);
}

View File

@ -0,0 +1,82 @@
#ifndef __TS_WS_CLIENT_H__
#define __TS_WS_CLIENT_H__
#include "ts_const.h"
#include <vector>
#include <string>
#include <map>
#include <ex.h>
#include <json/json.h>
#include <teleport_const.h>
#include "../../external/mongoose/mongoose.h"
#define MESSAGE_TYPE_REQUEST 0
#define MESSAGE_TYPE_RESPONSE 1
typedef struct AssistMessage
{
int command_id;
std::string method;
AssistMessage() :
command_id(0),
method("UNKNOWN") {}
} AssistMessage;
class TsWsClient : public ExThreadBase
{
public:
TsWsClient();
~TsWsClient();
static void init_app(void* app);
static void stop_all_client();
static void url_scheme_handler(const std::string& url);
protected:
void _thread_loop(void);
// bool _on_init();
private:
void _register(const std::string& ws_url, uint32_t assist_id, const std::string& session_id);
void _on_message(const std::string& message, std::string& buf);
void _rpc_func_run_client(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root);
void _rpc_func_get_config(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root);
void _rpc_func_set_config(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root);
void _rpc_func_select_file(ex_astr& buf, AssistMessage& msg_req, Json::Value& js_root);
void _create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code);
void _create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code, const ex_wstr& message);
void _create_response(ex_astr& buf, const AssistMessage& msg_ret, int err_code, const ex_wstr& message, Json::Value& data);
// void _rpc_func_check(const ex_astr& func_args, ex_astr& buf);
// void _rpc_func_rdp_play(const ex_astr& func_args, ex_astr& buf);
// void _rpc_func_file_action(const ex_astr& func_args, ex_astr& buf);
// void _rpc_func_get_version(const ex_astr& func_args, ex_astr& buf);
static void _mg_event_handler(struct mg_connection* nc, int ev, void* ev_data);
static void _process_register(const std::string& param, Json::Value& js_root);
private:
struct mg_mgr m_mg_mgr;
struct mg_connection* m_nc;
uint32_t m_assist_id;
};
#endif // __TS_WS_CLIENT_H__

View File

@ -177,8 +177,8 @@ EX_BOOL ex_is_file_exists(const wchar_t* in_file)
EX_BOOL ex_is_file_exists(const char* in_file)
{
#ifdef EX_OS_WIN32
ex_wstr _in_path;
ex_astr2wstr(in_path, _in_path);
ex_wstr _in_file;
ex_astr2wstr(in_file, _in_file);
if (!PathFileExists(_in_file.c_str()))
return EX_FALSE;
if (PathIsDirectory(_in_file.c_str()))

View File

@ -17,6 +17,7 @@
"#.toolchain.example.windows": {
"qt_path": "C:\\Qt\\Qt5.15.2\\5.15.2\\msvc2017",
"cmake": "C:\\Program Files(x86)\\CMake\\bin\\cmake.exe",
"msbuild": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\MSBuild\\Current\\Bin\\MSBuild.exe",
"wget": "",
"7z": "",
"nsis": ""

Binary file not shown.

12
make.sh
View File

@ -7,7 +7,8 @@ PATH_ROOT=$(cd "$(dirname "$0")"; pwd)
# environment if you want to build teleport components for such
# platforms.
# =================================================================
PY_EXEC_WINDOWS="C:\\apps\\py37-x86\\python.exe"
# PY_EXEC_WINDOWS="C:\\apps\\py37-x86\\python.exe"
PY_EXEC_WINDOWS="C:\\apps\\py39-x64\\python.exe"
PY_EXEC_MACOS="/usr/local/bin/python3"
set -e
@ -54,10 +55,10 @@ function build_win
on_error "Sorry, need x86 version of Python 3.7 or above."
fi
# and must be x86 version.
$("${pyexec}" -c "import platform;import sys;ret=0 if platform.architecture()[0]=='32bit' else 1;sys.exit(ret)")
if [ $? -ne 0 ]; then
on_error "Sorry, need x86 version of Python 3.7 or above."
fi
# ret=$("${pyexec}" -c "import platform;import sys;ret=0 if platform.architecture()[0]=='32bit' else 1;print(ret)")
# if [ $ret -ne 0 ]; then
# on_error "Sorry, need x86 version of Python 3.7 or above."
# fi
${pyexec} -B "${PATH_ROOT}/build/build.py" $@
}
@ -151,6 +152,7 @@ elif [ ${SYS_NAME} = "Darw" ] ; then
build_macos $@
elif [ ${SYS_NAME} == "MSYS" ] ; then
export CFG_FILE=config.windows.json
echo $CFG_FILE
build_win $@
else
on_error_begin "Unsupported platform."

View File

@ -190,7 +190,7 @@ int app_main_(int argc, wchar_t** argv)
#ifdef EX_OS_WIN32
#ifdef EX_DEBUG
#include <vld.h>
//#include <vld.h>
#endif
static SERVICE_STATUS g_ServiceStatus = { 0 };
@ -210,7 +210,7 @@ int main()
int _argc = 0;
wchar_t** _argv = ::CommandLineToArgvW(szCmdLine, &_argc); //拆分命令行参数字符串;
ret = _app_main(_argc, _argv);
ret = app_main_(_argc, _argv);
LocalFree(_argv);
_argv = nullptr;
@ -218,7 +218,7 @@ int main()
return ret;
}
static bool _run_daemon(void)
static bool run_daemon_(void)
{
SERVICE_TABLE_ENTRY DispatchTable[2];
DispatchTable[0].lpServiceName = EOM_CORE_SERVICE_NAME;
@ -238,7 +238,7 @@ static bool _run_daemon(void)
static DWORD WINAPI service_thread_func(LPVOID lpParam)
{
int ret = _main_loop();
int ret = main_loop_();
// 更新服务状态(如果服务还在运行,将其设置为停止状态)
g_ServiceStatus.dwWin32ExitCode = 0;

View File

@ -15,13 +15,13 @@
<Keyword>Win32Proj</Keyword>
<RootNamespace>tp_core</RootNamespace>
<ProjectName>tp_core</ProjectName>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@ -29,7 +29,7 @@
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">

View File

@ -14,20 +14,20 @@
<ProjectGuid>{FDA16D20-09B7-45AF-ADF1-DAF3EF2C0531}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>tpssh</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>tpssh</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@ -90,7 +90,7 @@ $app.init_dom_event = function (cb_stack) {
$app._on_type_change($app.cfg.rdp, $app.dom.rdp_type, $app.dom.rdp_app, $app.dom.rdp_cmdline, $app.dom.rdp_desc);
});
$app.dom.ssh_select_app.click(function () {
$assist.select_local_file('ssg');
$assist.select_local_file('ssh');
});
$app.dom.sftp_select_app.click(function () {
$assist.select_local_file('sftp');