Improvement: Add a popup window to show details

This commit is contained in:
yuanyuanxiang
2025-06-15 16:57:32 +08:00
parent 95f808214c
commit 9f47a908d6
7 changed files with 212 additions and 19 deletions

View File

@@ -198,6 +198,12 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
switch (szBuffer[0])
{
case CMD_AUTHORIZATION: {
#ifndef _DEBUG
HANDLE hMutex = OpenMutex(SYNCHRONIZE, FALSE, "YAMA.EXE");
if (hMutex == NULL) // û<>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>
break;
CloseHandle(hMutex);
#endif
char buf[100] = {}, *passCode = buf + 5;
memcpy(buf, szBuffer, min(sizeof(buf), ulLength));
char path[MAX_PATH] = { 0 };

View File

@@ -179,6 +179,50 @@ std::string getProcessTime() {
return buffer;
}
int getOSBits() {
SYSTEM_INFO si;
GetNativeSystemInfo(&si);
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64) {
return 64;
}
else {
return 32;
}
}
// <20><><EFBFBD><EFBFBD>CPU<50><55><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// SYSTEM_INFO.dwNumberOfProcessors
int GetCPUCores()
{
INT i = 0;
#ifdef _WIN64
// <20><> x64 <20>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫʹ<D2AA><CAB9> `NtQuerySystemInformation`
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
i = sysInfo.dwNumberOfProcessors; // <20><>ȡ CPU <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#else
_asm { // x64<36><34><EFBFBD><EFBFBD>ģʽ<C4A3>²<EFBFBD>֧<EFBFBD><D6A7>__asm<73>Ļ<EFBFBD><C4BB><EFBFBD>Ƕ<EFBFBD><C7B6>
mov eax, dword ptr fs : [0x18] ; // TEB
mov eax, dword ptr ds : [eax + 0x30] ; // PEB
mov eax, dword ptr ds : [eax + 0x64] ;
mov i, eax;
}
#endif
Mprintf("<EFBFBD>˼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CPU<EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %d\n", i);
return i;
}
double GetMemorySizeGB() {
_MEMORYSTATUSEX mst;
mst.dwLength = sizeof(mst);
GlobalMemoryStatusEx(&mst);
double GB = mst.ullTotalPhys / (1024.0 * 1024 * 1024);
Mprintf("<EFBFBD>˼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>: %fGB\n", GB);
return GB;
}
LOGIN_INFOR GetLoginInfo(DWORD dwSpeed, const CONNECT_ADDRESS& conn)
{
LOGIN_INFOR LoginInfor;
@@ -200,10 +244,10 @@ LOGIN_INFOR GetLoginInfo(DWORD dwSpeed, const CONNECT_ADDRESS& conn)
LoginInfor.dwCPUMHz = dwCPUMHz;
LoginInfor.bWebCamIsExist = bWebCamIsExist;
strcpy_s(LoginInfor.szStartTime, getProcessTime().c_str());
sprintf_s(LoginInfor.szReserved, "%s", GetClientType(conn.ClientType()));
LoginInfor.AddReserved("?"); // ϵͳλ<CDB3><CEBB>
LoginInfor.AddReserved("?"); // CPU<50><55><EFBFBD><EFBFBD>
LoginInfor.AddReserved("?"); // ϵͳ<CFB5>ڴ<EFBFBD>
LoginInfor.AddReserved(GetClientType(conn.ClientType())); // <20><><EFBFBD><EFBFBD>
LoginInfor.AddReserved(getOSBits()); // ϵͳλ<CDB3><CEBB>
LoginInfor.AddReserved(GetCPUCores()); // CPU<50><55><EFBFBD><EFBFBD>
LoginInfor.AddReserved(GetMemorySizeGB()); // ϵͳ<CFB5>ڴ<EFBFBD>
char buf[_MAX_PATH] = {};
GetModuleFileNameA(NULL, buf, sizeof(buf));
LoginInfor.AddReserved(buf); // <20>ļ<EFBFBD>·<EFBFBD><C2B7>
@@ -214,13 +258,31 @@ LOGIN_INFOR GetLoginInfo(DWORD dwSpeed, const CONNECT_ADDRESS& conn)
installTime = ToPekingTimeAsString(nullptr);;
WriteAppSettingA("install_time", installTime);
}
LoginInfor.AddReserved(installTime.c_str());
LoginInfor.AddReserved(installTime.c_str()); // <20><>װʱ<D7B0><CAB1>
LoginInfor.AddReserved("?"); // <20><>װ<EFBFBD><D7B0>Ϣ
LoginInfor.AddReserved(sizeof(void*)==4 ? 32 : 64); // <20><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
std::string str;
#ifndef _DEBUG
HANDLE hMutex = OpenMutex(SYNCHRONIZE, FALSE, "YAMA.EXE");
if (hMutex != NULL) {
CloseHandle(hMutex);
#else
{
#endif
GET_FILEPATH(buf, "settings.ini");
char auth[_MAX_PATH] = { 0 };
GetPrivateProfileStringA("settings", "Password", "", auth, sizeof(auth), buf);
str = std::string(auth);
str.erase(std::remove(str.begin(), str.end(), ' '), str.end());
auto list = StringToVector(str, '-', 3);
str = list[1];
}
LoginInfor.AddReserved(str.c_str()); // <20><>Ȩ<EFBFBD><C8A8>Ϣ
bool isDefault = strlen(conn.szFlag) == 0 || strcmp(conn.szFlag, skCrypt(FLAG_GHOST)) == 0 ||
strcmp(conn.szFlag, skCrypt("Happy New Year!")) == 0;
std::string masterHash(skCrypt(MASTER_HASH));
const char* id = isDefault ? masterHash.c_str() : conn.szFlag;
memcpy(LoginInfor.szMasterID, id, min(strlen(id), 16));
return LoginInfor;
}

View File

@@ -600,6 +600,20 @@ inline std::vector<std::string> StringToVector(const std::string& str, char ch,
return result;
}
enum LOGIN_RES {
RES_CLIENT_TYPE = 0, // <20><><EFBFBD><EFBFBD>
RES_SYSTEM_BITS = 1, // ϵͳλ<CDB3><CEBB>
RES_SYSTEM_CPU = 2, // CPU<50><55><EFBFBD><EFBFBD>
RES_SYSTEM_MEM = 3, // ϵͳ<CFB5>ڴ<EFBFBD>
RES_FILE_PATH = 4, // <20>ļ<EFBFBD>·<EFBFBD><C2B7>
RES_RESVERD = 5, // ?
RES_INSTALL_TIME = 6, // <20><>װʱ<D7B0><CAB1>
RES_INSTALL_INFO = 7, // <20><>װ<EFBFBD><D7B0>Ϣ
RES_PROGRAM_BITS = 8, // <20><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
RES_EXPIRED_DATE = 9, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
RES_MAX,
};
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߺ<EFBFBD><DFBA><EFBFBD><EFBFBD>͵ļ<CDB5><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
// <20>˽ṹ<CBBD><E1B9B9>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4BBAF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD>Ŀͻ<C4BF><CDBB><EFBFBD><EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>°<EFBFBD><C2B0><EFBFBD><EFBFBD><EFBFBD>.
// <20>°<EFBFBD><C2B0>ͻ<EFBFBD><CDBB><EFBFBD>Ҳ<EFBFBD>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϰ汾<CFB0><E6B1BE><EFBFBD><EFBFBD><EFBFBD>س<EFBFBD><D8B3><EFBFBD>.

View File

@@ -78,17 +78,20 @@ CMy2015RemoteApp theApp;
// CMy2015RemoteApp <20><>ʼ<EFBFBD><CABC>
std::string GetPwdHash();
BOOL CMy2015RemoteApp::InitInstance()
{
#ifndef _DEBUG
m_Mutex = CreateMutex(NULL, FALSE, "YAMA.EXE");
if (ERROR_ALREADY_EXISTS == GetLastError())
{
CloseHandle(m_Mutex);
m_Mutex = NULL;
return FALSE;
std::string masterHash(skCrypt(MASTER_HASH));
if (GetPwdHash() != masterHash) {
m_Mutex = CreateMutex(NULL, FALSE, "YAMA.EXE");
if (ERROR_ALREADY_EXISTS == GetLastError())
{
CloseHandle(m_Mutex);
m_Mutex = NULL;
return FALSE;
}
}
#endif
SetUnhandledExceptionFilter(&whenbuged);

View File

@@ -44,6 +44,7 @@
#define UM_ICONNOTIFY WM_USER+100
#define TIMER_CHECK 1
#define TIMER_CLOSEWND 2
typedef struct
{
@@ -387,6 +388,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
ON_COMMAND(ID_ONLINE_H264_DESKTOP, &CMy2015RemoteDlg::OnOnlineH264Desktop)
ON_COMMAND(ID_WHAT_IS_THIS, &CMy2015RemoteDlg::OnWhatIsThis)
ON_COMMAND(ID_ONLINE_AUTHORIZE, &CMy2015RemoteDlg::OnOnlineAuthorize)
ON_NOTIFY(NM_CLICK, IDC_ONLINE, &CMy2015RemoteDlg::OnListClick)
END_MESSAGE_MAP()
@@ -518,6 +520,7 @@ VOID CMy2015RemoteDlg::InitControl()
g_Column_Online_Width+=g_Column_Data_Online[i].nWidth;
}
m_CList_Online.ModifyStyle(0, LVS_SHOWSELALWAYS);
m_CList_Online.SetExtendedStyle(style);
for (int i = 0; i < g_Column_Count_Message; ++i)
@@ -572,9 +575,10 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
}
LeaveCriticalSection(&m_cs);
CString install = v[6].empty() ? "?" : v[6].c_str(), path = v[4].empty() ? "?" : v[4].c_str();
CString install = v[RES_INSTALL_TIME].empty() ? "?" : v[RES_INSTALL_TIME].c_str();
CString path = v[RES_FILE_PATH].empty() ? "?" : v[RES_FILE_PATH].c_str();
CString data[ONLINELIST_MAX] = { strIP, strAddr, "", strPCName, strOS, strCPU, strVideo, strPing,
ver, install, startTime, v[0].empty() ? "?" : v[0].c_str(), path };
ver, install, startTime, v[RES_CLIENT_TYPE].empty() ? "?" : v[RES_CLIENT_TYPE].c_str(), path };
auto id = CONTEXT_OBJECT::CalculateID(data);
bool modify = false;
CString loc = GetClientMapData(id, MAP_LOCATION);
@@ -586,7 +590,7 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
}
}
data[ONLINELIST_LOCATION] = loc;
ContextObject->SetClientInfo(data);
ContextObject->SetClientInfo(data, v);
ContextObject->SetID(id);
EnterCriticalSection(&m_cs);
@@ -947,6 +951,22 @@ void CMy2015RemoteDlg::OnTimer(UINT_PTR nIDEvent)
MessageBox("请及时对当前主控程序授权: 在工具菜单中生成口令!", "提示", MB_ICONWARNING);
}
}
if (nIDEvent == TIMER_CLOSEWND) {
DeletePopupWindow();
}
CDialogEx::OnTimer(nIDEvent);
}
void CMy2015RemoteDlg::DeletePopupWindow() {
if (m_pFloatingTip)
{
if (::IsWindow(m_pFloatingTip->GetSafeHwnd()))
m_pFloatingTip->DestroyWindow();
SAFE_DELETE(m_pFloatingTip);
}
KillTimer(TIMER_CLOSEWND);
}
@@ -1933,7 +1953,7 @@ LRESULT CMy2015RemoteDlg::OnUserToOnlineList(WPARAM wParam, LPARAM lParam)
strVideo = m_settings.DetectSoftware ? "" : LoginInfor->bWebCamIsExist ? "" : "";
strAddr.Format("%d", nSocket);
auto v = LoginInfor->ParseReserved(10);
auto v = LoginInfor->ParseReserved(RES_MAX);
AddList(strIP,strAddr,strPCName,strOS,strCPU,strVideo,strPing,LoginInfor->moduleVersion,LoginInfor->szStartTime, v, ContextObject);
delete LoginInfor;
return S_OK;
@@ -2391,6 +2411,20 @@ BOOL CMy2015RemoteDlg::PreTranslateMessage(MSG* pMsg)
return TRUE;
}
if ((pMsg->message == WM_LBUTTONDOWN || pMsg->message == WM_RBUTTONDOWN) && m_pFloatingTip)
{
HWND hTipWnd = m_pFloatingTip->GetSafeHwnd();
if (::IsWindow(hTipWnd))
{
CPoint pt(pMsg->pt);
CRect tipRect;
::GetWindowRect(hTipWnd, &tipRect);
if (!tipRect.PtInRect(pt)){
DeletePopupWindow();
}
}
}
return CDialogEx::PreTranslateMessage(pMsg);
}
@@ -2840,3 +2874,60 @@ void CMy2015RemoteDlg::OnOnlineAuthorize()
memcpy(bToken+1, &days, sizeof(days));
SendSelectedCommand(bToken, sizeof(bToken));
}
void CMy2015RemoteDlg::OnListClick(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMITEMACTIVATE pNMItem = (LPNMITEMACTIVATE)pNMHDR;
if (pNMItem->iItem >= 0)
{
// 获取数据
CONTEXT_OBJECT* ctx = (CONTEXT_OBJECT*)m_CList_Online.GetItemData(pNMItem->iItem);
CString res[RES_MAX];
CString startTime = ctx->GetClientData(ONLINELIST_LOGINTIME);
ctx->GetAdditionalData(res);
// 拼接内容
CString strText;
std::string expired = res[RES_EXPIRED_DATE];
expired = expired.empty() ? "" : " Expired on " + expired;
strText.Format(_T("文件路径: %s%s\r\n系统信息: %s 位 %s 核心 %s GB\r\n启动信息: %s %s"),
res[RES_PROGRAM_BITS].IsEmpty() ? "" : res[RES_PROGRAM_BITS] + "", res[RES_FILE_PATH],
res[RES_SYSTEM_BITS], res[RES_SYSTEM_CPU], res[RES_SYSTEM_MEM], startTime, expired.c_str());
// 获取鼠标位置
CPoint pt;
GetCursorPos(&pt);
// 清理旧提示
DeletePopupWindow();
// 创建提示窗口
m_pFloatingTip = new CWnd();
int width = res[RES_FILE_PATH].GetLength() * 10;
width = min(max(width, 360), 800);
CRect rect(pt.x, pt.y, pt.x + width, pt.y + 50); // 宽度、高度
BOOL bOk = m_pFloatingTip->CreateEx(
WS_EX_TOPMOST | WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE,
_T("STATIC"),
strText,
WS_POPUP | WS_VISIBLE | WS_BORDER | SS_LEFT | SS_NOTIFY,
rect,
this,
0);
if (bOk)
{
m_pFloatingTip->SetFont(GetFont());
m_pFloatingTip->ShowWindow(SW_SHOW);
SetTimer(TIMER_CLOSEWND, 5000, nullptr);
}
else
{
SAFE_DELETE(m_pFloatingTip);
}
}
*pResult = 0;
}

View File

@@ -171,9 +171,12 @@ public:
VOID MessageHandle(CONTEXT_OBJECT* ContextObject);
VOID SendSelectedCommand(PBYTE szBuffer, ULONG ulLength);
// <20><>ʾ<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
CWnd* m_pFloatingTip=nullptr;
CListCtrl m_CList_Online;
CListCtrl m_CList_Message;
void DeletePopupWindow();
CStatusBar m_StatusBar; //״̬<D7B4><CCAC>
CTrueColorToolBar m_ToolBar;
@@ -246,4 +249,5 @@ public:
afx_msg void OnOnlineH264Desktop();
afx_msg void OnWhatIsThis();
afx_msg void OnOnlineAuthorize();
void OnListClick(NMHDR* pNMHDR, LRESULT* pResult);
};

View File

@@ -214,6 +214,7 @@ enum IOType
typedef struct CONTEXT_OBJECT
{
CString sClientInfo[ONLINELIST_MAX];
CString additonalInfo[RES_MAX];
SOCKET sClientSocket;
WSABUF wsaInBuf;
WSABUF wsaOutBuffer;
@@ -245,16 +246,22 @@ typedef struct CONTEXT_OBJECT
for (int i = 0; i < ONLINELIST_MAX; i++) {
sClientInfo[i].Empty();
}
for (int i = 0; i < RES_MAX; i++) {
additonalInfo[i].Empty();
}
CompressMethod = COMPRESS_ZSTD;
Parser.Reset();
bLogin = FALSE;
m_bProxyConnected = FALSE;
}
VOID SetClientInfo(const CString(&s)[ONLINELIST_MAX]){
VOID SetClientInfo(const CString(&s)[ONLINELIST_MAX], const std::vector<std::string>& a = {}) {
for (int i = 0; i < ONLINELIST_MAX; i++)
{
sClientInfo[i] = s[i];
}
for (int i = 0; i < a.size(); i++) {
additonalInfo[i] = a[i].c_str();
}
}
PBYTE GetBuffer(int offset) {
return InDeCompressedBuffer.GetBuffer(offset);
@@ -268,6 +275,12 @@ typedef struct CONTEXT_OBJECT
CString GetClientData(int index) const{
return sClientInfo[index];
}
void GetAdditionalData(CString(&s)[RES_MAX]) const {
for (int i = 0; i < RES_MAX; i++)
{
s[i] = additonalInfo[i];
}
}
void CancelIO() {
SAFE_CANCELIO(sClientSocket);
}