Files
envi-code/SourceCode/Code2026/EarthWormMain/CheckLock.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

478 lines
11 KiB
C++

#include "stdafx.h"
#include "CheckLock.h"
#include "Base64.h"
#include "LockReadWriteTool.h"
#include "comdef.h"
#include "LockSrvIPDlg.h"
#include "WaitEventDlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#endif
extern HINSTANCE _hdllInstance;
typedef enum ClientEvent
{
kLogin = 1, //登录
kLogout = 2, //退出
kPassok = 3, //许可
kAccessError = 4,//超出节点数
kAskforLogin = 5,//请求登录
kProError = 6, //请求登陆产品不对
}CLIENTEVENT;
typedef struct ClientMsg
{
SOCKET sock;
char szMsg[MAX_PATH];
}SOCKMSG;
CWaitEventDlg g_wndEventDlg;
#ifndef WM_CLIENTMSG
#define WM_CLIENTMSG (WM_USER+0x1002)
#endif
CCheckLock::CCheckLock()
{
m_theSocket = 0;
m_bAutocadExit = false;
memset(m_szBuf,0,MAX_PATH);
}
CCheckLock::~CCheckLock()
{
}
bool CCheckLock::CheckLock()
{
//1.查本地 license.lc 文件
TCHAR szFullPath[MAX_PATH];
GetModuleFileName(_hdllInstance,szFullPath,MAX_PATH);
TCHAR drive[_MAX_DRIVE] = _T(""),
dir[_MAX_DIR] = _T(""),
fname[_MAX_FNAME] = _T(""),
ext[_MAX_EXT] = _T("");
//e:\,program files\autodesk\,acad,exe
_tsplitpath(szFullPath, drive, dir, fname, ext);
CString sDir = dir;
sDir.MakeLower();
sDir.TrimRight(_T('\\'));
CString sDirMep = sDir;
int nPos = sDir.ReverseFind(_T('\\'));
if (nPos != -1)
{
sDirMep = sDir.Mid(0,nPos);
}
CString sIniFile;
sIniFile.Format(_T("%s%s\\sys\\license.ini"),drive,sDirMep);
CFileFind find;
if (!find.FindFile(sIniFile))
{
//acedGetAcadFrame()->MessageBox();
acedGetAcadFrame()->MessageBox(_T("软件授权文件丢失!请确认软件是否正确安装!"),_T("提示"),MB_OK | MB_ICONERROR);
return false;
}
//读取本地授权信息
memset(&m_proInfo,0,sizeof(ProductInfo));
/*
[Product]
PName=
PCode=密
Version=密
Mode=
TryDayStop=密
Server=
Ports=
*/
/*
typedef struct ProductInfo
{
char szProName[11]; //产品名称 五个汉字 1
char szProCode[7]; //产品代号 2
DWORD dwVersion; //产品版本2012,2013 可组合. 3
char bLockType; //111 单机锁 121 网络锁 100 试用版 4
__int64 tTryDayStop; //试用截止时间 5
char szServer[17]; //服务端ip地址
int nPort[5]; //端口号,固定端口号 6
}PRODUCTINFO;
*/
//PName
_bstr_t bst((LPCTSTR)sIniFile);
const char* pszIniFile = (const char*)bst;
GetPrivateProfileStringA("Product","PName","",m_proInfo.szProName,11,pszIniFile);
//PCode
char szCode[32];
GetPrivateProfileStringA("Product","PCode","",szCode,32,pszIniFile);
std::string sCode;
sCode.assign(szCode);
sCode = Base64::Decode(sCode);
strcpy(m_proInfo.szProCode,sCode.c_str());
//Version
GetPrivateProfileStringA("Product","Version","",szCode,32,pszIniFile);
sCode.assign(szCode);
sCode = Base64::Decode(sCode);
m_proInfo.dwVersion = atoi(sCode.c_str());//12,13
//Mode
m_proInfo.bLockType = GetPrivateProfileIntA("Product","Mode",111,pszIniFile);
//TryDayStop
GetPrivateProfileStringA("Product","TryDayStop","",szCode,32,pszIniFile);
sCode.assign(szCode);
sCode = Base64::Decode(sCode);
//2013-8-31
m_proInfo.tTryDayStop = CTime(2020,1,1,0,0,0,0).GetTime();
CStringArray arItems;
_bstr_t bst2(sCode.c_str());
CString sText = (LPCTSTR)bst2;
ParaseText(sText,_T('-'),arItems);
if (arItems.GetSize() >= 3)
{
m_proInfo.tTryDayStop = CTime(_ttoi(arItems.GetAt(0)),_ttoi(arItems.GetAt(1)),_ttoi(arItems.GetAt(2)),0,0,0,0).GetTime();
}
//Server
GetPrivateProfileStringA("Product","Server","",m_proInfo.szServer,32,pszIniFile);
//Ports
GetPrivateProfileStringA("Product","Ports","",szCode,32,pszIniFile);
sCode.assign(szCode);
arItems.RemoveAll();
sText = (LPCTSTR)_bstr_t(sCode.c_str());
ParaseText(sText,_T(','),arItems);
if (arItems.GetSize() >= 5)
{
for (int i = 0;i < 5;i++)
{
m_proInfo.nPort[i] = _ttoi(arItems.GetAt(i));
}
}
//如果是网络版, 网络IP 地址没有配置
if (m_proInfo.bLockType == 121)
{
if (strlen(m_proInfo.szServer) == 0)
{
//配置网络锁服务器
CLockSrvIPDlg lockSrvDlg;
int nRes = (int)lockSrvDlg.DoModal();
if (nRes == IDOK)
{
sprintf(m_proInfo.szServer,"%d.%d.%d.%d",
lockSrvDlg.m_nField0,
lockSrvDlg.m_nField1,
lockSrvDlg.m_nField2,
lockSrvDlg.m_nField3);
}
else
{
acedGetAcadFrame()->MessageBox(_T("没用确认输入网络锁ip地址!检查锁失败!"));
return false;
}
}
}
//进行验证
if (m_proInfo.bLockType == 121)//网络版
{
if ( !CheckServerLock(&m_proInfo) )
{
//按单机版验证
return CheckSingleLock(&m_proInfo);
}
return true;
}
else if (m_proInfo.bLockType == 111)//单机版
{
return CheckSingleLock(&m_proInfo);
}
else
{
if ( CheckSingleLock(&m_proInfo) )
{
m_proInfo.bLockType = 111;
return true;
}
}
m_bAutocadExit = true;
return false;
}
bool CCheckLock::CheckServerLock(ProductInfo* pProInfo)
{
CAcModuleResourceOverride myResources;
g_wndEventDlg.SetCheckLock(this);
int nRes = (int)g_wndEventDlg.DoModal();
if (nRes == IDOK)
{
if (g_wndEventDlg.m_bCheckSrvOk)
return g_wndEventDlg.m_bCheckSrvOk;
}
return false;
}
INT_PTR CCheckLock::ParaseText(CString& sText,TCHAR ch,CStringArray& arFields)
{
CString sTemp;
for (int i = 0;i < sText.GetLength();i++)
{
if (sText.GetAt(i) == ch )
{
arFields.Add(sTemp);
sTemp = _T("");
}
else
{
sTemp += sText.GetAt(i);
if (i == sText.GetLength() - 1)
{
arFields.Add(sTemp);
}
}
}
return arFields.GetSize();
}
CTime CCheckLock::FormatTime(CString& sDate)
{
if (sDate.IsEmpty())
return CTime::GetCurrentTime();
//%Y-%m-%d %H:%M
CTime t1 = CTime::GetCurrentTime();
sDate.TrimLeft();
sDate.TrimRight();
sDate.TrimLeft(_T('['));
int nPos = sDate.Find(_T(' '));
if (nPos != -1)
{
CString sLeft = sDate.Mid(0,nPos);
CString sRight = sDate.Mid(nPos + 1);
CStringArray arPros;
ParaseText(sLeft,_T('-'),arPros);
CStringArray armH;
ParaseText(sRight,_T(':'),armH);
//CTime( int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec,
//int nDST = -1 );
if (arPros.GetSize() >= 3 && armH.GetSize() >= 2)
{
int nYear = _ttoi(arPros.GetAt(0));
int nMonth = _ttoi(arPros.GetAt(1));
int nDay = _ttoi(arPros.GetAt(2));
int nHour = _ttoi(armH.GetAt(0));
int nMin = _ttoi(armH.GetAt(1));
int nSec = 0;
t1 = CTime(nYear,nMonth,nDay,nHour,nMin,0);
}
}
return t1;
}
bool CCheckLock::CheckSingleLock(ProductInfo* pProInfo)
{
//1.判断锁内内容是否一致
ASSERT(pProInfo != NULL);
std::string strData,sInfo2;
if ( !CLockReadWriteTool::ReadLock(strData) )
{
return false;
}
//{[%s][%s][%d][%d][%d][%s][%s]}
sInfo2 = Base64::Decode(strData);
CStringArray arPros,arFields;
CString sText = sInfo2.c_str();
ParaseText(sText,_T('}'),arPros);
CString sLine,sItem,sRev,sDate;
for(int i = 0;i < arPros.GetSize();i++)
{
sLine = arPros.GetAt(i);
sLine.TrimLeft(_T('{'));
arFields.RemoveAll();
ParaseText(sLine,_T(']'),arFields);
//内容
if (arFields.GetSize() >= 9)
{
//name
sItem = arFields.GetAt(0);
sItem.TrimLeft(_T('['));
//code
sItem = arFields.GetAt(1);
sItem.TrimLeft(_T('['));
//time
//%Y-%m-%d %H:%M
sDate = arFields.GetAt(6);
//revers 1:180
sRev = arFields.GetAt(7);
sRev.TrimLeft(_T('['));
//if (sRev.CompareNoCase(_T("1:180")) == 0)
if (sRev.Find(_T("1:")) != -1)
{
CTime tFrom = FormatTime(sDate);
CTime tCur = CTime::GetCurrentTime();
int nPos = sRev.Find(_T(':'));
int nDays = _ttoi(sRev.Mid(nPos + 1));
CTimeSpan tSpan = tCur - tFrom;
if ( tSpan.GetDays() > nDays)
{
acedGetAcadFrame()->MessageBox(_T("试用锁时间到期!"));
return false;
}
}
//产品代号,版本一致
_bstr_t bst((LPCTSTR)sItem);
const char* pszProcode = (const char*)bst;
if (strcmp(pszProcode,pProInfo->szProCode) == 0)
{
//version
sItem = arFields.GetAt(2);
sItem.TrimLeft(_T('['));
DWORD dwVersion = _ttoi((LPCTSTR)sItem);
WORD wHi1 = HIWORD(dwVersion);
WORD wLo1 = LOWORD(dwVersion);
WORD wHi2 = HIWORD(pProInfo->dwVersion);
WORD wLo2 = LOWORD(pProInfo->dwVersion);
if (wHi1 == wHi2 ||
wLo1 == wLo2 ||
wHi1 == wLo2 ||
wLo1 == wHi2)
{
return true;
}
}
}
}
return false;
}
bool CCheckLock::CheckTryversion(ProductInfo* pProInfo)
{
return false;
}
void CCheckLock::SendLogoutMessage()
{
static int nDone = 0;
if(nDone == 1)
return;
nDone = 1;
//1.网络通讯
WORD nVersion; //used to store the socket version
WSADATA wsaData; //used to store info about socket
//get the version of socket
nVersion = MAKEWORD(1,1);
//The Windows Sockets WSAStartup function initiates use of WS2_32.DLL by a process
int nRes = WSAStartup(nVersion,(LPWSADATA)&wsaData);
static char szBuf[MAX_PATH];
memset(szBuf,0,MAX_PATH);
//获取本地ip 地址
char szHost[64],sHostIP[64];
gethostname(szHost,64);
struct hostent* phe = gethostbyname(szHost);
if (phe != NULL)
{
struct in_addr addr;
memcpy(&addr,phe->h_addr_list[0],sizeof(struct in_addr));
sprintf(sHostIP,"%s-%s",inet_ntoa(addr),szHost);
}
else
{
sprintf(sHostIP,"%s",szHost);
}
memset(szBuf,0,MAX_PATH);
#if (ARX <=15)
sprintf(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2000;",sHostIP,m_proInfo.szProCode,m_proInfo.dwVersion,kLogout);
#elif (ARX<=16)
sprintf(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2004;",sHostIP,m_proInfo.szProCode,m_proInfo.dwVersion,kLogout);
#elif (ARX<=17)
sprintf_s(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2008;",sHostIP,m_proInfo.szProCode,m_proInfo.dwVersion,kLogout);
#elif (ARX<=18)
sprintf_s(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2010;",sHostIP,m_proInfo.szProCode,m_proInfo.dwVersion,kLogout);
#elif (ARX<=19)
sprintf_s(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2013;",sHostIP,m_proInfo.szProCode,m_proInfo.dwVersion,kLogout);
#elif (ARX<=20)
sprintf_s(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2016;",sHostIP,m_proInfo.szProCode,m_proInfo.dwVersion,kLogout);
#elif (ARX<=21)
sprintf_s(szBuf,"ip=%s;pro=%s;ver=%d;evn=%d;cad=AutoCAD2019;",sHostIP,m_proInfo.szProCode,m_proInfo.dwVersion,kLogout);
#endif
//strcpy(szBuf,"ip=10.0.2.15;pro=Mep2012;ver=2012;evn=2;cad=AutoCAD2008;");
//Send the data to the server
//设置发送超时
//int nNetTimeout = 1000;//1秒,
//setsockopt(m_theSocket,SOL_SOCKET,SO_SNDTIMEO,(char *)&nNetTimeout,sizeof(int));
try
{
strcpy(m_szBuf,szBuf);
nRes = send(m_theSocket, m_szBuf, MAX_PATH, 0);//固定长度
if(nRes == SOCKET_ERROR)
{
//再发一次
nRes = send(m_theSocket, m_szBuf, MAX_PATH, 0);//固定长度
}
if (nRes == MAX_PATH)
{
//closesocket(m_theSocket);
//Sleep(5000);
struct linger liner;
liner.l_onoff = 0;
setsockopt(m_theSocket, SOL_SOCKET,SO_LINGER,(char*)&liner,sizeof(liner));
shutdown(m_theSocket,2);
closesocket(m_theSocket);
Sleep(5000);
m_bAutocadExit = true;
}
}
catch (...)
{
}
WSACleanup();
}