Merge pull request #3668 from torusrxxx/patch000000fd
Upgrade _WIN32_WINNT to Windows 7
This commit is contained in:
commit
c84549a8ad
|
@ -442,6 +442,7 @@ target_link_libraries(dbg PRIVATE
|
||||||
Shlwapi
|
Shlwapi
|
||||||
Ws2_32
|
Ws2_32
|
||||||
Wininet
|
Wininet
|
||||||
|
Iphlpapi
|
||||||
)
|
)
|
||||||
|
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4) # x86
|
if(CMAKE_SIZEOF_VOID_P EQUAL 4) # x86
|
||||||
|
|
|
@ -105,6 +105,7 @@ private-link-libraries = [
|
||||||
"Shlwapi",
|
"Shlwapi",
|
||||||
"Ws2_32",
|
"Ws2_32",
|
||||||
"Wininet",
|
"Wininet",
|
||||||
|
"Iphlpapi",
|
||||||
]
|
]
|
||||||
x86.private-link-libraries = [
|
x86.private-link-libraries = [
|
||||||
"src/dbg/dbghelp/dbghelp_x86.lib",
|
"src/dbg/dbghelp/dbghelp_x86.lib",
|
||||||
|
|
|
@ -403,27 +403,14 @@ void WaitForMultipleThreadsTermination(const HANDLE* hThread, int count, DWORD t
|
||||||
duint GetThreadCount()
|
duint GetThreadCount()
|
||||||
{
|
{
|
||||||
duint threadCount = std::thread::hardware_concurrency();
|
duint threadCount = std::thread::hardware_concurrency();
|
||||||
|
|
||||||
typedef BOOL(WINAPI * GetLogicalProcessorInformationEx_t)(
|
|
||||||
LOGICAL_PROCESSOR_RELATIONSHIP,
|
|
||||||
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX,
|
|
||||||
PDWORD
|
|
||||||
);
|
|
||||||
|
|
||||||
static auto p_GetLogicalProcessorInformationEx = (GetLogicalProcessorInformationEx_t)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetLogicalProcessorInformationEx");
|
|
||||||
if(p_GetLogicalProcessorInformationEx == nullptr)
|
|
||||||
{
|
|
||||||
return threadCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD length = 0;
|
DWORD length = 0;
|
||||||
if(p_GetLogicalProcessorInformationEx(RelationAll, nullptr, &length) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
if(GetLogicalProcessorInformationEx(RelationAll, nullptr, &length) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||||
{
|
{
|
||||||
return threadCount;
|
return threadCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> buffer(length);
|
std::vector<uint8_t> buffer(length);
|
||||||
if(!p_GetLogicalProcessorInformationEx(RelationAll, (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)buffer.data(), &length))
|
if(!GetLogicalProcessorInformationEx(RelationAll, (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)buffer.data(), &length))
|
||||||
{
|
{
|
||||||
return threadCount;
|
return threadCount;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef _WIN32_WINNT
|
#ifndef _WIN32_WINNT
|
||||||
#ifdef _WIN64
|
#define _WIN32_WINNT 0x0601 // XP x64 is version 5.2, Vista is version 6.0, Windows 7 is version 6.1
|
||||||
#define _WIN32_WINNT 0x0502 // XP x64 is version 5.2
|
|
||||||
#else
|
|
||||||
#define _WIN32_WINNT 0x0501
|
|
||||||
#endif
|
|
||||||
#endif // _WIN32_WINNT
|
#endif // _WIN32_WINNT
|
||||||
|
|
||||||
#ifdef WINVER // Overwrite WINVER if given on command line
|
#ifdef WINVER // Overwrite WINVER if given on command line
|
||||||
|
@ -14,7 +10,7 @@
|
||||||
#define WINVER _WIN32_WINNT
|
#define WINVER _WIN32_WINNT
|
||||||
|
|
||||||
#ifndef _WIN32_IE
|
#ifndef _WIN32_IE
|
||||||
#define _WIN32_IE 0x0500
|
#define _WIN32_IE _WIN32_IE_WIN7
|
||||||
#endif //_WIN32_IE
|
#endif //_WIN32_IE
|
||||||
|
|
||||||
#include "ntdll/ntdll.h"
|
#include "ntdll/ntdll.h"
|
||||||
|
|
|
@ -76,19 +76,11 @@ class SearchTimer
|
||||||
public:
|
public:
|
||||||
SearchTimer()
|
SearchTimer()
|
||||||
{
|
{
|
||||||
if(!LPFN_GetTickCount64)
|
ticks = GetTickCount64();
|
||||||
LPFN_GetTickCount64 = (ULONGLONG(*)())GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetTickCount64");
|
|
||||||
if(LPFN_GetTickCount64)
|
|
||||||
ticks = LPFN_GetTickCount64();
|
|
||||||
else
|
|
||||||
ticks = GetTickCount();
|
|
||||||
}
|
}
|
||||||
void StopTimer()
|
void StopTimer()
|
||||||
{
|
{
|
||||||
if(LPFN_GetTickCount64)
|
ticks = GetTickCount64() - ticks;
|
||||||
ticks = LPFN_GetTickCount64() - ticks;
|
|
||||||
else
|
|
||||||
ticks = GetTickCount() - ticks;
|
|
||||||
}
|
}
|
||||||
DWORD GetTicks()
|
DWORD GetTicks()
|
||||||
{
|
{
|
||||||
|
@ -96,9 +88,7 @@ public:
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
ULONGLONG ticks;
|
ULONGLONG ticks;
|
||||||
static ULONGLONG(*LPFN_GetTickCount64)();
|
|
||||||
};
|
};
|
||||||
ULONGLONG(*SearchTimer::LPFN_GetTickCount64)() = nullptr;
|
|
||||||
|
|
||||||
bool cbInstrFind(int argc, char* argv[])
|
bool cbInstrFind(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
|
|
@ -468,12 +468,7 @@ namespace Exprfunc
|
||||||
|
|
||||||
duint gettickcount()
|
duint gettickcount()
|
||||||
{
|
{
|
||||||
#ifdef _WIN64
|
return (duint)GetTickCount64();
|
||||||
static auto GTC64 = (ULONGLONG(*)())GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetTickCount64");
|
|
||||||
if(GTC64)
|
|
||||||
return GTC64();
|
|
||||||
#endif //_WIN64
|
|
||||||
return GetTickCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
duint rdtsc()
|
duint rdtsc()
|
||||||
|
|
|
@ -163,36 +163,15 @@ bool HandlesGetName(HANDLE remoteHandle, String & name, String & typeName)
|
||||||
}
|
}
|
||||||
else if(strcmp(typeName.c_str(), "Thread") == 0)
|
else if(strcmp(typeName.c_str(), "Thread") == 0)
|
||||||
{
|
{
|
||||||
auto getTidPid = [](HANDLE hThread, DWORD & TID, DWORD & PID)
|
auto TID = GetThreadId(hLocalHandle);
|
||||||
{
|
auto PID = GetProcessIdOfThread(hLocalHandle);
|
||||||
static auto pGetThreadId = (DWORD(__stdcall*)(HANDLE))GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetThreadId");
|
|
||||||
static auto pGetProcessIdOfThread = (DWORD(__stdcall*)(HANDLE))GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessIdOfThread");
|
|
||||||
if(pGetThreadId != NULL && pGetProcessIdOfThread != NULL) //Vista or Server 2003 only
|
|
||||||
{
|
|
||||||
TID = pGetThreadId(hThread);
|
|
||||||
PID = pGetProcessIdOfThread(hThread);
|
|
||||||
}
|
|
||||||
else //Windows XP
|
|
||||||
{
|
|
||||||
THREAD_BASIC_INFORMATION threadInfo;
|
|
||||||
ULONG threadInfoSize = 0;
|
|
||||||
NTSTATUS isok = NtQueryInformationThread(hThread, ThreadBasicInformation, &threadInfo, sizeof(threadInfo), &threadInfoSize);
|
|
||||||
if(NT_SUCCESS(isok))
|
|
||||||
{
|
|
||||||
TID = (DWORD)(duint)threadInfo.ClientId.UniqueThread;
|
|
||||||
PID = (DWORD)(duint)threadInfo.ClientId.UniqueProcess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
DWORD TID, PID;
|
|
||||||
getTidPid(hLocalHandle, TID, PID);
|
|
||||||
if(TID == 0 || PID == 0) //The first time could fail because the process didn't specify query permissions.
|
if(TID == 0 || PID == 0) //The first time could fail because the process didn't specify query permissions.
|
||||||
{
|
{
|
||||||
HANDLE hLocalQueryHandle;
|
HANDLE hLocalQueryHandle;
|
||||||
if(DuplicateHandle(hProcess, remoteHandle, GetCurrentProcess(), &hLocalQueryHandle, THREAD_QUERY_INFORMATION, FALSE, 0))
|
if(DuplicateHandle(hProcess, remoteHandle, GetCurrentProcess(), &hLocalQueryHandle, THREAD_QUERY_INFORMATION, FALSE, 0))
|
||||||
{
|
{
|
||||||
getTidPid(hLocalQueryHandle, TID, PID);
|
TID = GetThreadId(hLocalQueryHandle);
|
||||||
|
PID = GetProcessIdOfThread(hLocalQueryHandle);
|
||||||
CloseHandle(hLocalQueryHandle);
|
CloseHandle(hLocalQueryHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef _WIN32_WINNT
|
#ifndef _WIN32_WINNT
|
||||||
#ifdef _WIN64
|
#define _WIN32_WINNT 0x0601 // XP x64 is version 5.2, Vista is version 6.0, Windows 7 is version 6.1
|
||||||
#define _WIN32_WINNT 0x0502 // XP x64 is version 5.2
|
|
||||||
#else
|
|
||||||
#define _WIN32_WINNT 0x0501
|
|
||||||
#endif
|
|
||||||
#endif // _WIN32_WINNT
|
#endif // _WIN32_WINNT
|
||||||
|
|
||||||
#ifdef WINVER // Overwrite WINVER if given on command line
|
#ifdef WINVER // Overwrite WINVER if given on command line
|
||||||
|
@ -14,7 +10,7 @@
|
||||||
#define WINVER _WIN32_WINNT
|
#define WINVER _WIN32_WINNT
|
||||||
|
|
||||||
#ifndef _WIN32_IE
|
#ifndef _WIN32_IE
|
||||||
#define _WIN32_IE 0x0500
|
#define _WIN32_IE _WIN32_IE_WIN7
|
||||||
#endif //_WIN32_IE
|
#endif //_WIN32_IE
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -1,195 +1,102 @@
|
||||||
#include "tcpconnections.h"
|
#include "tcpconnections.h"
|
||||||
#include <WS2tcpip.h>
|
#include <WS2tcpip.h>
|
||||||
|
#include <iphlpapi.h>
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
DBG_MIB_TCP_STATE_CLOSED = 1,
|
|
||||||
DBG_MIB_TCP_STATE_LISTEN = 2,
|
|
||||||
DBG_MIB_TCP_STATE_SYN_SENT = 3,
|
|
||||||
DBG_MIB_TCP_STATE_SYN_RCVD = 4,
|
|
||||||
DBG_MIB_TCP_STATE_ESTAB = 5,
|
|
||||||
DBG_MIB_TCP_STATE_FIN_WAIT1 = 6,
|
|
||||||
DBG_MIB_TCP_STATE_FIN_WAIT2 = 7,
|
|
||||||
DBG_MIB_TCP_STATE_CLOSE_WAIT = 8,
|
|
||||||
DBG_MIB_TCP_STATE_CLOSING = 9,
|
|
||||||
DBG_MIB_TCP_STATE_LAST_ACK = 10,
|
|
||||||
DBG_MIB_TCP_STATE_TIME_WAIT = 11,
|
|
||||||
DBG_MIB_TCP_STATE_DELETE_TCB = 12,
|
|
||||||
} DBG_MIB_TCP_STATE;
|
|
||||||
|
|
||||||
static const char* TcpStateToString(unsigned int State)
|
static const char* TcpStateToString(unsigned int State)
|
||||||
{
|
{
|
||||||
switch(State)
|
switch(State)
|
||||||
{
|
{
|
||||||
case DBG_MIB_TCP_STATE_CLOSED:
|
case MIB_TCP_STATE_CLOSED:
|
||||||
return "CLOSED";
|
return "CLOSED";
|
||||||
case DBG_MIB_TCP_STATE_LISTEN:
|
case MIB_TCP_STATE_LISTEN:
|
||||||
return "LISTEN";
|
return "LISTEN";
|
||||||
case DBG_MIB_TCP_STATE_SYN_SENT:
|
case MIB_TCP_STATE_SYN_SENT:
|
||||||
return "SYN-SENT";
|
return "SYN-SENT";
|
||||||
case DBG_MIB_TCP_STATE_SYN_RCVD:
|
case MIB_TCP_STATE_SYN_RCVD:
|
||||||
return "SYN-RECEIVED";
|
return "SYN-RECEIVED";
|
||||||
case DBG_MIB_TCP_STATE_ESTAB:
|
case MIB_TCP_STATE_ESTAB:
|
||||||
return "ESTABLISHED";
|
return "ESTABLISHED";
|
||||||
case DBG_MIB_TCP_STATE_FIN_WAIT1:
|
case MIB_TCP_STATE_FIN_WAIT1:
|
||||||
return "FIN-WAIT-1";
|
return "FIN-WAIT-1";
|
||||||
case DBG_MIB_TCP_STATE_FIN_WAIT2:
|
case MIB_TCP_STATE_FIN_WAIT2:
|
||||||
return "FIN-WAIT-2";
|
return "FIN-WAIT-2";
|
||||||
case DBG_MIB_TCP_STATE_CLOSE_WAIT:
|
case MIB_TCP_STATE_CLOSE_WAIT:
|
||||||
return "CLOSE-WAIT";
|
return "CLOSE-WAIT";
|
||||||
case DBG_MIB_TCP_STATE_CLOSING:
|
case MIB_TCP_STATE_CLOSING:
|
||||||
return "CLOSING";
|
return "CLOSING";
|
||||||
case DBG_MIB_TCP_STATE_LAST_ACK:
|
case MIB_TCP_STATE_LAST_ACK:
|
||||||
return "LAST-ACK";
|
return "LAST-ACK";
|
||||||
case DBG_MIB_TCP_STATE_TIME_WAIT:
|
case MIB_TCP_STATE_TIME_WAIT:
|
||||||
return "TIME-WAIT";
|
return "TIME-WAIT";
|
||||||
case DBG_MIB_TCP_STATE_DELETE_TCB:
|
case MIB_TCP_STATE_DELETE_TCB:
|
||||||
return "DELETE-TCB";
|
return "DELETE-TCB";
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
DbgTcpConnectionOffloadStateInHost,
|
|
||||||
DbgTcpConnectionOffloadStateOffloading,
|
|
||||||
DbgTcpConnectionOffloadStateOffloaded,
|
|
||||||
DbgTcpConnectionOffloadStateUploading,
|
|
||||||
DbgTcpConnectionOffloadStateMax
|
|
||||||
} DBG_TCP_CONNECTION_OFFLOAD_STATE, *PTCP_CONNECTION_OFFLOAD_STATE;
|
|
||||||
|
|
||||||
typedef struct _DBG_MIB_TCPROW2
|
|
||||||
{
|
|
||||||
DWORD dwState;
|
|
||||||
DWORD dwLocalAddr;
|
|
||||||
DWORD dwLocalPort;
|
|
||||||
DWORD dwRemoteAddr;
|
|
||||||
DWORD dwRemotePort;
|
|
||||||
DWORD dwOwningPid;
|
|
||||||
DBG_TCP_CONNECTION_OFFLOAD_STATE dwOffloadState;
|
|
||||||
} DBG_MIB_TCPROW2, *PDBG_MIB_TCPROW2;
|
|
||||||
|
|
||||||
typedef struct _DBG_MIB_TCPTABLE2
|
|
||||||
{
|
|
||||||
DWORD dwNumEntries;
|
|
||||||
DBG_MIB_TCPROW2 table[1];
|
|
||||||
} DBG_MIB_TCPTABLE2, *PDBG_MIB_TCPTABLE2;
|
|
||||||
|
|
||||||
typedef struct _DBG_IN6_ADDR
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
UCHAR Byte[16];
|
|
||||||
USHORT Word[8];
|
|
||||||
} u;
|
|
||||||
} DBG_IN6_ADDR, * PDBG_IN6_ADDR, FAR* LPDBG_IN6_ADDR;
|
|
||||||
|
|
||||||
typedef struct _MIB_TCP6ROW2
|
|
||||||
{
|
|
||||||
DBG_IN6_ADDR LocalAddr;
|
|
||||||
DWORD dwLocalScopeId;
|
|
||||||
DWORD dwLocalPort;
|
|
||||||
DBG_IN6_ADDR RemoteAddr;
|
|
||||||
DWORD dwRemoteScopeId;
|
|
||||||
DWORD dwRemotePort;
|
|
||||||
DWORD State;
|
|
||||||
DWORD dwOwningPid;
|
|
||||||
DBG_TCP_CONNECTION_OFFLOAD_STATE dwOffloadState;
|
|
||||||
} DBG_MIB_TCP6ROW2, *PDBG_MIB_TCP6ROW2;
|
|
||||||
|
|
||||||
typedef struct _DBG_MIB_TCP6TABLE2
|
|
||||||
{
|
|
||||||
DWORD dwNumEntries;
|
|
||||||
DBG_MIB_TCP6ROW2 table[1];
|
|
||||||
} DBG_MIB_TCP6TABLE2, *PDBG_MIB_TCP6TABLE2;
|
|
||||||
|
|
||||||
typedef ULONG(WINAPI* GETTCPTABLE2)(PDBG_MIB_TCPTABLE2 TcpTable, PULONG SizePointer, BOOL Order);
|
|
||||||
typedef ULONG(WINAPI* GETTCP6TABLE2)(PDBG_MIB_TCP6TABLE2 TcpTable, PULONG SizePointer, BOOL Order);
|
|
||||||
typedef PCTSTR(WINAPI* INETNTOPW)(INT Family, PVOID pAddr, wchar_t* pStringBuf, size_t StringBufSize);
|
|
||||||
|
|
||||||
bool TcpEnumConnections(duint pid, std::vector<TCPCONNECTIONINFO> & connections)
|
bool TcpEnumConnections(duint pid, std::vector<TCPCONNECTIONINFO> & connections)
|
||||||
{
|
{
|
||||||
// The following code is modified from code sample at MSDN.GetTcpTable2
|
|
||||||
static auto hIpHlp = LoadLibraryW(L"iphlpapi.dll");
|
|
||||||
if(!hIpHlp)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// To ensure WindowsXP compatibility we won't link them statically
|
|
||||||
static auto pGetTcpTable2 = GETTCPTABLE2(GetProcAddress(hIpHlp, "GetTcpTable2"));
|
|
||||||
static auto pGetTcp6Table2 = GETTCP6TABLE2(GetProcAddress(hIpHlp, "GetTcp6Table2"));
|
|
||||||
static auto pInetNtopW = INETNTOPW(GetProcAddress(GetModuleHandleW(L"ws2_32.dll"), "InetNtopW"));
|
|
||||||
if(!pInetNtopW)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TCPCONNECTIONINFO info;
|
TCPCONNECTIONINFO info;
|
||||||
wchar_t AddrBuffer[TCP_ADDR_SIZE] = L"";
|
wchar_t AddrBuffer[TCP_ADDR_SIZE] = L"";
|
||||||
|
ULONG ulSize = 0;
|
||||||
if(pGetTcpTable2)
|
// Make an initial call to GetTcpTable2 to get the necessary size into the ulSize variable
|
||||||
|
if(GetTcpTable2(nullptr, &ulSize, TRUE) == ERROR_INSUFFICIENT_BUFFER)
|
||||||
{
|
{
|
||||||
ULONG ulSize = 0;
|
Memory<MIB_TCPTABLE2*> pTcpTable(ulSize);
|
||||||
// Make an initial call to GetTcpTable2 to get the necessary size into the ulSize variable
|
// Make a second call to GetTcpTable2 to get the actual data we require
|
||||||
if(pGetTcpTable2(nullptr, &ulSize, TRUE) == ERROR_INSUFFICIENT_BUFFER)
|
if(GetTcpTable2(pTcpTable(), &ulSize, TRUE) == NO_ERROR)
|
||||||
{
|
{
|
||||||
Memory<DBG_MIB_TCPTABLE2*> pTcpTable(ulSize);
|
for(auto i = 0; i < int(pTcpTable()->dwNumEntries); i++)
|
||||||
// Make a second call to GetTcpTable2 to get the actual data we require
|
|
||||||
if(pGetTcpTable2(pTcpTable(), &ulSize, TRUE) == NO_ERROR)
|
|
||||||
{
|
{
|
||||||
for(auto i = 0; i < int(pTcpTable()->dwNumEntries); i++)
|
auto & entry = pTcpTable()->table[i];
|
||||||
{
|
if(entry.dwOwningPid != pid)
|
||||||
auto & entry = pTcpTable()->table[i];
|
continue;
|
||||||
if(entry.dwOwningPid != pid)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
info.State = entry.dwState;
|
info.State = entry.dwState;
|
||||||
strcpy_s(info.StateText, TcpStateToString(info.State));
|
strcpy_s(info.StateText, TcpStateToString(info.State));
|
||||||
|
|
||||||
struct in_addr IpAddr;
|
struct in_addr IpAddr;
|
||||||
IpAddr.S_un.S_addr = u_long(entry.dwLocalAddr);
|
IpAddr.S_un.S_addr = u_long(entry.dwLocalAddr);
|
||||||
pInetNtopW(AF_INET, &IpAddr, AddrBuffer, TCP_ADDR_SIZE);
|
InetNtopW(AF_INET, &IpAddr, AddrBuffer, TCP_ADDR_SIZE);
|
||||||
strcpy_s(info.LocalAddress, StringUtils::Utf16ToUtf8(AddrBuffer).c_str());
|
strcpy_s(info.LocalAddress, StringUtils::Utf16ToUtf8(AddrBuffer).c_str());
|
||||||
info.LocalPort = ntohs(u_short(entry.dwLocalPort));
|
info.LocalPort = ntohs(u_short(entry.dwLocalPort));
|
||||||
|
|
||||||
IpAddr.S_un.S_addr = u_long(entry.dwRemoteAddr);
|
IpAddr.S_un.S_addr = u_long(entry.dwRemoteAddr);
|
||||||
pInetNtopW(AF_INET, &IpAddr, AddrBuffer, TCP_ADDR_SIZE);
|
InetNtopW(AF_INET, &IpAddr, AddrBuffer, TCP_ADDR_SIZE);
|
||||||
strcpy_s(info.RemoteAddress, StringUtils::Utf16ToUtf8(AddrBuffer).c_str());
|
strcpy_s(info.RemoteAddress, StringUtils::Utf16ToUtf8(AddrBuffer).c_str());
|
||||||
info.RemotePort = ntohs(u_short(entry.dwRemotePort));
|
info.RemotePort = ntohs(u_short(entry.dwRemotePort));
|
||||||
|
|
||||||
connections.push_back(info);
|
connections.push_back(info);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ulSize = 0;
|
||||||
if(pGetTcp6Table2)
|
// Make an initial call to GetTcp6Table2 to get the necessary size into the ulSize variable
|
||||||
|
if(GetTcp6Table2(nullptr, &ulSize, TRUE) == ERROR_INSUFFICIENT_BUFFER)
|
||||||
{
|
{
|
||||||
ULONG ulSize = 0;
|
Memory<MIB_TCP6TABLE2*> pTcp6Table(ulSize);
|
||||||
// Make an initial call to GetTcp6Table2 to get the necessary size into the ulSize variable
|
// Make a second call to GetTcpTable2 to get the actual data we require
|
||||||
if(pGetTcp6Table2(nullptr, &ulSize, TRUE) == ERROR_INSUFFICIENT_BUFFER)
|
if(GetTcp6Table2(pTcp6Table(), &ulSize, TRUE) == NO_ERROR)
|
||||||
{
|
{
|
||||||
Memory<DBG_MIB_TCP6TABLE2*> pTcp6Table(ulSize);
|
for(auto i = 0; i < int(pTcp6Table()->dwNumEntries); i++)
|
||||||
// Make a second call to GetTcpTable2 to get the actual data we require
|
|
||||||
if(pGetTcp6Table2(pTcp6Table(), &ulSize, TRUE) == NO_ERROR)
|
|
||||||
{
|
{
|
||||||
for(auto i = 0; i < int(pTcp6Table()->dwNumEntries); i++)
|
auto & entry = pTcp6Table()->table[i];
|
||||||
{
|
if(entry.dwOwningPid != pid)
|
||||||
auto & entry = pTcp6Table()->table[i];
|
continue;
|
||||||
if(entry.dwOwningPid != pid)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
info.State = entry.State;
|
info.State = entry.State;
|
||||||
strcpy_s(info.StateText, TcpStateToString(info.State));
|
strcpy_s(info.StateText, TcpStateToString(info.State));
|
||||||
|
|
||||||
pInetNtopW(AF_INET6, &entry.LocalAddr, AddrBuffer, TCP_ADDR_SIZE);
|
InetNtopW(AF_INET6, &entry.LocalAddr, AddrBuffer, TCP_ADDR_SIZE);
|
||||||
sprintf_s(info.LocalAddress, "[%s]", StringUtils::Utf16ToUtf8(AddrBuffer).c_str());
|
sprintf_s(info.LocalAddress, "[%s]", StringUtils::Utf16ToUtf8(AddrBuffer).c_str());
|
||||||
info.LocalPort = ntohs(u_short(entry.dwLocalPort));
|
info.LocalPort = ntohs(u_short(entry.dwLocalPort));
|
||||||
|
|
||||||
pInetNtopW(AF_INET6, &entry.RemoteAddr, AddrBuffer, TCP_ADDR_SIZE);
|
InetNtopW(AF_INET6, &entry.RemoteAddr, AddrBuffer, TCP_ADDR_SIZE);
|
||||||
sprintf_s(info.RemoteAddress, "[%s]", StringUtils::Utf16ToUtf8(AddrBuffer).c_str());
|
sprintf_s(info.RemoteAddress, "[%s]", StringUtils::Utf16ToUtf8(AddrBuffer).c_str());
|
||||||
info.RemotePort = ntohs(u_short(entry.dwRemotePort));
|
info.RemotePort = ntohs(u_short(entry.dwRemotePort));
|
||||||
|
|
||||||
connections.push_back(info);
|
connections.push_back(info);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,6 @@
|
||||||
static std::unordered_map<DWORD, THREADINFO> threadList;
|
static std::unordered_map<DWORD, THREADINFO> threadList;
|
||||||
static std::unordered_map<DWORD, THREADWAITREASON> threadWaitReasons;
|
static std::unordered_map<DWORD, THREADWAITREASON> threadWaitReasons;
|
||||||
|
|
||||||
// Function pointer for dynamic linking. Do not link statically for Windows XP compatibility.
|
|
||||||
// TODO: move this function definition out of thread.cpp
|
|
||||||
BOOL(WINAPI* pQueryThreadCycleTime)(HANDLE ThreadHandle, PULONG64 CycleTime) = nullptr;
|
|
||||||
|
|
||||||
BOOL WINAPI QueryThreadCycleTimeUnsupported(HANDLE ThreadHandle, PULONG64 CycleTime)
|
|
||||||
{
|
|
||||||
*CycleTime = 0;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread)
|
||||||
{
|
{
|
||||||
THREADINFO curInfo;
|
THREADINFO curInfo;
|
||||||
|
@ -328,9 +318,7 @@ DWORD ThreadGetId(HANDLE Thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wasn't found, check with Windows
|
// Wasn't found, check with Windows
|
||||||
typedef DWORD (WINAPI * GETTHREADID)(HANDLE hThread);
|
return GetThreadId(Thread);
|
||||||
static GETTHREADID _GetThreadId = (GETTHREADID)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetThreadId");
|
|
||||||
return _GetThreadId ? _GetThreadId(Thread) : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ThreadSuspendAll()
|
int ThreadSuspendAll()
|
||||||
|
@ -393,16 +381,9 @@ ULONG64 ThreadQueryCycleTime(HANDLE hThread)
|
||||||
{
|
{
|
||||||
ULONG64 CycleTime;
|
ULONG64 CycleTime;
|
||||||
|
|
||||||
// Initialize function pointer
|
if(!QueryThreadCycleTime(hThread, &CycleTime))
|
||||||
if(pQueryThreadCycleTime == nullptr)
|
|
||||||
{
|
|
||||||
pQueryThreadCycleTime = (BOOL(WINAPI*)(HANDLE, PULONG64))GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "QueryThreadCycleTime");
|
|
||||||
if(pQueryThreadCycleTime == nullptr)
|
|
||||||
pQueryThreadCycleTime = QueryThreadCycleTimeUnsupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!pQueryThreadCycleTime(hThread, &CycleTime))
|
|
||||||
CycleTime = 0;
|
CycleTime = 0;
|
||||||
|
|
||||||
return CycleTime;
|
return CycleTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,18 +50,10 @@ void waitdeinitialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SectionLockerGlobal::m_Initialized = false;
|
bool SectionLockerGlobal::m_Initialized = false;
|
||||||
bool SectionLockerGlobal::m_SRWLocks = false;
|
|
||||||
CacheAligned<SRWLOCK> SectionLockerGlobal::m_srwLocks[SectionLock::LockLast];
|
|
||||||
SectionLockerGlobal::owner_info SectionLockerGlobal::m_exclusiveOwner[SectionLock::LockLast];
|
|
||||||
|
|
||||||
CacheAligned<CRITICAL_SECTION> SectionLockerGlobal::m_crLocks[SectionLock::LockLast];
|
CacheAligned<CRITICAL_SECTION> SectionLockerGlobal::m_crLocks[SectionLock::LockLast];
|
||||||
SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_InitializeSRWLock;
|
CacheAligned<SRWLOCK> SectionLockerGlobal::m_srwLocks[SectionLock::LockLast];
|
||||||
SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_AcquireSRWLockShared;
|
SectionLockerGlobal::owner_info SectionLockerGlobal::m_exclusiveOwner[SectionLock::LockLast];
|
||||||
SectionLockerGlobal::TRYSRWLOCKFUNCTION SectionLockerGlobal::m_TryAcquireSRWLockShared;
|
|
||||||
SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_AcquireSRWLockExclusive;
|
|
||||||
SectionLockerGlobal::TRYSRWLOCKFUNCTION SectionLockerGlobal::m_TryAcquireSRWLockExclusive;
|
|
||||||
SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_ReleaseSRWLockShared;
|
|
||||||
SectionLockerGlobal::SRWLOCKFUNCTION SectionLockerGlobal::m_ReleaseSRWLockExclusive;
|
|
||||||
DWORD SectionLockerGlobal::m_guiMainThreadId;
|
DWORD SectionLockerGlobal::m_guiMainThreadId;
|
||||||
|
|
||||||
void SectionLockerGlobal::Initialize()
|
void SectionLockerGlobal::Initialize()
|
||||||
|
@ -74,40 +66,11 @@ void SectionLockerGlobal::Initialize()
|
||||||
// This gets called on the same thread as the GUI
|
// This gets called on the same thread as the GUI
|
||||||
m_guiMainThreadId = GetCurrentThreadId();
|
m_guiMainThreadId = GetCurrentThreadId();
|
||||||
|
|
||||||
// Attempt to read the SRWLock API
|
// Destroy previous data if any existed
|
||||||
HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll");
|
memset(m_srwLocks, 0, sizeof(m_srwLocks));
|
||||||
m_InitializeSRWLock = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "InitializeSRWLock");
|
|
||||||
m_AcquireSRWLockShared = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "AcquireSRWLockShared");
|
|
||||||
m_TryAcquireSRWLockShared = (TRYSRWLOCKFUNCTION)GetProcAddress(hKernel32, "TryAcquireSRWLockShared");
|
|
||||||
m_AcquireSRWLockExclusive = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "AcquireSRWLockExclusive");
|
|
||||||
m_TryAcquireSRWLockExclusive = (TRYSRWLOCKFUNCTION)GetProcAddress(hKernel32, "TryAcquireSRWLockExclusive");
|
|
||||||
m_ReleaseSRWLockShared = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "ReleaseSRWLockShared");
|
|
||||||
m_ReleaseSRWLockExclusive = (SRWLOCKFUNCTION)GetProcAddress(hKernel32, "ReleaseSRWLockExclusive");
|
|
||||||
|
|
||||||
m_SRWLocks = m_InitializeSRWLock &&
|
for(int i = 0; i < ARRAYSIZE(m_srwLocks); i++)
|
||||||
m_AcquireSRWLockShared &&
|
InitializeSRWLock(&m_srwLocks[i]);
|
||||||
m_TryAcquireSRWLockShared &&
|
|
||||||
m_AcquireSRWLockExclusive &&
|
|
||||||
m_TryAcquireSRWLockExclusive &&
|
|
||||||
m_ReleaseSRWLockShared &&
|
|
||||||
m_ReleaseSRWLockExclusive;
|
|
||||||
|
|
||||||
if(m_SRWLocks) // Prefer SRWLocks
|
|
||||||
{
|
|
||||||
// Destroy previous data if any existed
|
|
||||||
memset(m_srwLocks, 0, sizeof(m_srwLocks));
|
|
||||||
|
|
||||||
for(int i = 0; i < ARRAYSIZE(m_srwLocks); i++)
|
|
||||||
m_InitializeSRWLock(&m_srwLocks[i]);
|
|
||||||
}
|
|
||||||
else // Fall back to critical sections otherwise
|
|
||||||
{
|
|
||||||
// Destroy previous data if any existed
|
|
||||||
memset(m_crLocks, 0, sizeof(m_crLocks));
|
|
||||||
|
|
||||||
for(int i = 0; i < ARRAYSIZE(m_crLocks); i++)
|
|
||||||
InitializeCriticalSection(&m_crLocks[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Initialized = true;
|
m_Initialized = true;
|
||||||
}
|
}
|
||||||
|
@ -117,30 +80,14 @@ void SectionLockerGlobal::Deinitialize()
|
||||||
if(!m_Initialized)
|
if(!m_Initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(m_SRWLocks)
|
for(int i = 0; i < ARRAYSIZE(m_srwLocks); i++)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < ARRAYSIZE(m_srwLocks); i++)
|
// Wait for the lock's ownership to be released
|
||||||
{
|
AcquireSRWLockExclusive(&m_srwLocks[i]);
|
||||||
// Wait for the lock's ownership to be released
|
ReleaseSRWLockExclusive(&m_srwLocks[i]);
|
||||||
m_AcquireSRWLockExclusive(&m_srwLocks[i]);
|
|
||||||
m_ReleaseSRWLockExclusive(&m_srwLocks[i]);
|
|
||||||
|
|
||||||
// Invalidate data
|
// Invalidate data
|
||||||
memset(&m_srwLocks[i], 0, sizeof(SRWLOCK));
|
memset(&m_srwLocks[i], 0, sizeof(SRWLOCK));
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(int i = 0; i < ARRAYSIZE(m_crLocks); i++)
|
|
||||||
{
|
|
||||||
// Wait for the lock's ownership to be released
|
|
||||||
EnterCriticalSection(&m_crLocks[i]);
|
|
||||||
LeaveCriticalSection(&m_crLocks[i]);
|
|
||||||
|
|
||||||
// Delete critical section
|
|
||||||
DeleteCriticalSection(&m_crLocks[i]);
|
|
||||||
memset(&m_crLocks[i], 0, sizeof(CRITICAL_SECTION));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Initialized = false;
|
m_Initialized = false;
|
||||||
|
|
|
@ -104,110 +104,77 @@ private:
|
||||||
static void AcquireLock()
|
static void AcquireLock()
|
||||||
{
|
{
|
||||||
auto threadId = GetCurrentThreadId();
|
auto threadId = GetCurrentThreadId();
|
||||||
if(m_SRWLocks)
|
|
||||||
|
auto srwLock = &m_srwLocks[LockIndex];
|
||||||
|
|
||||||
|
if(Shared)
|
||||||
{
|
{
|
||||||
auto srwLock = &m_srwLocks[LockIndex];
|
|
||||||
|
|
||||||
if(Shared)
|
|
||||||
{
|
|
||||||
if(m_exclusiveOwner[LockIndex].threadId == threadId)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(ProcessGuiEvents && threadId == m_guiMainThreadId)
|
|
||||||
{
|
|
||||||
while(!m_TryAcquireSRWLockShared(srwLock))
|
|
||||||
GuiProcessEvents();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_AcquireSRWLockShared(srwLock);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m_exclusiveOwner[LockIndex].threadId == threadId)
|
if(m_exclusiveOwner[LockIndex].threadId == threadId)
|
||||||
{
|
|
||||||
assert(m_exclusiveOwner[LockIndex].count > 0);
|
|
||||||
m_exclusiveOwner[LockIndex].count++;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if(ProcessGuiEvents && threadId == m_guiMainThreadId)
|
if(ProcessGuiEvents && threadId == m_guiMainThreadId)
|
||||||
{
|
{
|
||||||
while(!m_TryAcquireSRWLockExclusive(srwLock))
|
while(!TryAcquireSRWLockShared(srwLock))
|
||||||
GuiProcessEvents();
|
GuiProcessEvents();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_AcquireSRWLockExclusive(srwLock);
|
AcquireSRWLockShared(srwLock);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
assert(m_exclusiveOwner[LockIndex].threadId == 0);
|
if(m_exclusiveOwner[LockIndex].threadId == threadId)
|
||||||
assert(m_exclusiveOwner[LockIndex].count == 0);
|
{
|
||||||
m_exclusiveOwner[LockIndex].threadId = threadId;
|
assert(m_exclusiveOwner[LockIndex].count > 0);
|
||||||
m_exclusiveOwner[LockIndex].count = 1;
|
m_exclusiveOwner[LockIndex].count++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ProcessGuiEvents && threadId == m_guiMainThreadId)
|
||||||
|
{
|
||||||
|
while(!TryAcquireSRWLockExclusive(srwLock))
|
||||||
|
GuiProcessEvents();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto cr = &m_crLocks[LockIndex];
|
AcquireSRWLockExclusive(srwLock);
|
||||||
if(ProcessGuiEvents && threadId == m_guiMainThreadId)
|
|
||||||
{
|
|
||||||
while(!TryEnterCriticalSection(cr))
|
|
||||||
GuiProcessEvents();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EnterCriticalSection(cr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(m_exclusiveOwner[LockIndex].threadId == 0);
|
||||||
|
assert(m_exclusiveOwner[LockIndex].count == 0);
|
||||||
|
m_exclusiveOwner[LockIndex].threadId = threadId;
|
||||||
|
m_exclusiveOwner[LockIndex].count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<SectionLock LockIndex, bool Shared>
|
template<SectionLock LockIndex, bool Shared>
|
||||||
static void ReleaseLock()
|
static void ReleaseLock()
|
||||||
{
|
{
|
||||||
if(m_SRWLocks)
|
if(Shared)
|
||||||
{
|
{
|
||||||
if(Shared)
|
if(m_exclusiveOwner[LockIndex].threadId == GetCurrentThreadId())
|
||||||
{
|
|
||||||
if(m_exclusiveOwner[LockIndex].threadId == GetCurrentThreadId())
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_ReleaseSRWLockShared(&m_srwLocks[LockIndex]);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
assert(m_exclusiveOwner[LockIndex].count && m_exclusiveOwner[LockIndex].threadId);
|
ReleaseSRWLockShared(&m_srwLocks[LockIndex]);
|
||||||
m_exclusiveOwner[LockIndex].count--;
|
return;
|
||||||
|
|
||||||
if(m_exclusiveOwner[LockIndex].count == 0)
|
|
||||||
{
|
|
||||||
m_exclusiveOwner[LockIndex].threadId = 0;
|
|
||||||
m_ReleaseSRWLockExclusive(&m_srwLocks[LockIndex]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
assert(m_exclusiveOwner[LockIndex].count && m_exclusiveOwner[LockIndex].threadId);
|
||||||
|
m_exclusiveOwner[LockIndex].count--;
|
||||||
|
|
||||||
|
if(m_exclusiveOwner[LockIndex].count == 0)
|
||||||
{
|
{
|
||||||
LeaveCriticalSection(&m_crLocks[LockIndex]);
|
m_exclusiveOwner[LockIndex].threadId = 0;
|
||||||
|
ReleaseSRWLockExclusive(&m_srwLocks[LockIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (WINAPI* SRWLOCKFUNCTION)(PSRWLOCK SWRLock);
|
|
||||||
typedef BOOLEAN(WINAPI* TRYSRWLOCKFUNCTION)(PSRWLOCK SWRLock);
|
|
||||||
|
|
||||||
static bool m_Initialized;
|
static bool m_Initialized;
|
||||||
static bool m_SRWLocks;
|
|
||||||
|
|
||||||
struct DBG_ALIGNAS(64) owner_info { DWORD threadId; size_t count; };
|
struct DBG_ALIGNAS(64) owner_info { DWORD threadId; size_t count; };
|
||||||
static owner_info m_exclusiveOwner[SectionLock::LockLast];
|
static owner_info m_exclusiveOwner[SectionLock::LockLast];
|
||||||
static CacheAligned<SRWLOCK> m_srwLocks[SectionLock::LockLast];
|
static CacheAligned<SRWLOCK> m_srwLocks[SectionLock::LockLast];
|
||||||
static CacheAligned<CRITICAL_SECTION> m_crLocks[SectionLock::LockLast];
|
static CacheAligned<CRITICAL_SECTION> m_crLocks[SectionLock::LockLast];
|
||||||
static SRWLOCKFUNCTION m_InitializeSRWLock;
|
|
||||||
static SRWLOCKFUNCTION m_AcquireSRWLockShared;
|
|
||||||
static TRYSRWLOCKFUNCTION m_TryAcquireSRWLockShared;
|
|
||||||
static SRWLOCKFUNCTION m_AcquireSRWLockExclusive;
|
|
||||||
static TRYSRWLOCKFUNCTION m_TryAcquireSRWLockExclusive;
|
|
||||||
static SRWLOCKFUNCTION m_ReleaseSRWLockShared;
|
|
||||||
static SRWLOCKFUNCTION m_ReleaseSRWLockExclusive;
|
|
||||||
static DWORD m_guiMainThreadId;
|
static DWORD m_guiMainThreadId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -77,10 +77,10 @@ void Bridge::throttleUpdateSlot(GUIMSG msg)
|
||||||
// NOTE: This is running synchronously on the UI thread
|
// NOTE: This is running synchronously on the UI thread
|
||||||
|
|
||||||
auto lastUpdate = mLastUpdates[msg];
|
auto lastUpdate = mLastUpdates[msg];
|
||||||
auto now = GetTickCount();
|
auto now = std::chrono::steady_clock::now();
|
||||||
auto elapsed = now - lastUpdate;
|
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastUpdate);
|
||||||
const auto interval = 100;
|
const auto interval = (std::chrono::milliseconds)100;
|
||||||
if(lastUpdate > 0 && elapsed < interval)
|
if(elapsed < interval)
|
||||||
{
|
{
|
||||||
//qDebug() << "Delay update:" << msg2str(msg);
|
//qDebug() << "Delay update:" << msg2str(msg);
|
||||||
QTimer* timer = mUpdateTimers[msg];
|
QTimer* timer = mUpdateTimers[msg];
|
||||||
|
@ -110,7 +110,7 @@ void Bridge::throttleUpdateSlot(GUIMSG msg)
|
||||||
|
|
||||||
void Bridge::doUpdate(GUIMSG msg)
|
void Bridge::doUpdate(GUIMSG msg)
|
||||||
{
|
{
|
||||||
auto start = GetTickCount();
|
auto start = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
switch(msg)
|
switch(msg)
|
||||||
{
|
{
|
||||||
|
@ -187,9 +187,9 @@ void Bridge::doUpdate(GUIMSG msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log potentially bottlenecked updates
|
// Log potentially bottlenecked updates
|
||||||
auto now = GetTickCount();
|
auto now = std::chrono::steady_clock::now();
|
||||||
auto elapsed = now - start;
|
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start);
|
||||||
if(elapsed > 5)
|
if(elapsed > (std::chrono::milliseconds)5)
|
||||||
{
|
{
|
||||||
//qDebug() << "[DebugMonitor]" << msg2str(msg) << elapsed << "ms";
|
//qDebug() << "[DebugMonitor]" << msg2str(msg) << elapsed << "ms";
|
||||||
}
|
}
|
||||||
|
@ -1132,17 +1132,8 @@ __declspec(dllexport) void* _gui_sendmessage(GUIMSG type, void* param1, void* pa
|
||||||
|
|
||||||
__declspec(dllexport) const char* _gui_translate_text(const char* source)
|
__declspec(dllexport) const char* _gui_translate_text(const char* source)
|
||||||
{
|
{
|
||||||
if(TLS_TranslatedStringMap)
|
QByteArray translatedUtf8 = QCoreApplication::translate("DBG", source).toUtf8();
|
||||||
{
|
TLS_TranslatedString.Data[translatedUtf8.size()] = 0; // Set the string terminator first.
|
||||||
QByteArray translatedUtf8 = QCoreApplication::translate("DBG", source).toUtf8();
|
memcpy(TLS_TranslatedString.Data, translatedUtf8.constData(), std::min((size_t)translatedUtf8.size(), sizeof(TLS_TranslatedString.Data) - 1)); // Then copy the string safely.
|
||||||
// Boom... VS does not support "thread_local"... and cannot use "__declspec(thread)" in a DLL... https://blogs.msdn.microsoft.com/oldnewthing/20101122-00/?p=12233
|
return TLS_TranslatedString.Data; // Don't need to free this memory. But this pointer should be used immediately to reduce race condition.
|
||||||
// Simulating Thread Local Storage with a map...
|
|
||||||
DWORD ThreadId = GetCurrentThreadId();
|
|
||||||
TranslatedStringStorage & TranslatedString = (*TLS_TranslatedStringMap)[ThreadId];
|
|
||||||
TranslatedString.Data[translatedUtf8.size()] = 0; // Set the string terminator first.
|
|
||||||
memcpy(TranslatedString.Data, translatedUtf8.constData(), std::min((size_t)translatedUtf8.size(), sizeof(TranslatedString.Data) - 1)); // Then copy the string safely.
|
|
||||||
return TranslatedString.Data; // Don't need to free this memory. But this pointer should be used immediately to reduce race condition.
|
|
||||||
}
|
|
||||||
else // Translators are not initialized yet.
|
|
||||||
return source;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
@ -202,7 +203,7 @@ private:
|
||||||
duint mBridgeResults[BridgeResult::Last];
|
duint mBridgeResults[BridgeResult::Last];
|
||||||
DWORD mMainThreadId = 0;
|
DWORD mMainThreadId = 0;
|
||||||
volatile bool mDbgStopped = false;
|
volatile bool mDbgStopped = false;
|
||||||
QMap<GUIMSG, DWORD> mLastUpdates;
|
QMap<GUIMSG, std::chrono::steady_clock::time_point> mLastUpdates;
|
||||||
QMap<GUIMSG, QTimer*> mUpdateTimers;
|
QMap<GUIMSG, QTimer*> mUpdateTimers;
|
||||||
QZydis* mDisasm = nullptr;
|
QZydis* mDisasm = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -137,15 +137,6 @@ HandlesView::HandlesView(QWidget* parent) : QWidget(parent)
|
||||||
connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcuts()));
|
connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcuts()));
|
||||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChanged(DBGSTATE)));
|
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChanged(DBGSTATE)));
|
||||||
|
|
||||||
#ifdef _WIN32 // This is only supported on Windows Vista or greater
|
|
||||||
if(!IsWindowsVistaOrGreater())
|
|
||||||
#endif //_WIN32
|
|
||||||
{
|
|
||||||
mTcpConnectionsTable->setRowCount(1);
|
|
||||||
mTcpConnectionsTable->setCellContent(0, 0, tr("TCP Connection enumeration is only available on Windows Vista or greater."));
|
|
||||||
mTcpConnectionsTable->reloadData();
|
|
||||||
}
|
|
||||||
|
|
||||||
mWindowsTable->setAccessibleName(tr("Windows"));
|
mWindowsTable->setAccessibleName(tr("Windows"));
|
||||||
mHandlesTable->setAccessibleName(tr("Handles"));
|
mHandlesTable->setAccessibleName(tr("Handles"));
|
||||||
mTcpConnectionsTable->setAccessibleName(tr("TCP Connections"));
|
mTcpConnectionsTable->setAccessibleName(tr("TCP Connections"));
|
||||||
|
|
|
@ -62,9 +62,8 @@ bool MyApplication::notify(QObject* receiver, QEvent* event)
|
||||||
|
|
||||||
static Configuration* mConfiguration;
|
static Configuration* mConfiguration;
|
||||||
char gCurrentLocale[MAX_SETTING_SIZE] = "";
|
char gCurrentLocale[MAX_SETTING_SIZE] = "";
|
||||||
// Boom... VS does not support "thread_local"... and cannot use "__declspec(thread)" in a DLL... https://blogs.msdn.microsoft.com/oldnewthing/20101122-00/?p=12233
|
|
||||||
// Simulating Thread Local Storage with a map...
|
thread_local TranslatedStringStorage TLS_TranslatedString;
|
||||||
std::map<DWORD, TranslatedStringStorage>* TLS_TranslatedStringMap; //key = Thread Id, value = Translate Buffer
|
|
||||||
|
|
||||||
static bool isValidLocale(const QString & locale)
|
static bool isValidLocale(const QString & locale)
|
||||||
{
|
{
|
||||||
|
@ -168,8 +167,6 @@ int main(int argc, char* argv[])
|
||||||
if(x64dbgTranslator.load(QString("x64dbg_%1").arg(gCurrentLocale), path))
|
if(x64dbgTranslator.load(QString("x64dbg_%1").arg(gCurrentLocale), path))
|
||||||
application.installTranslator(&x64dbgTranslator);
|
application.installTranslator(&x64dbgTranslator);
|
||||||
|
|
||||||
TLS_TranslatedStringMap = new std::map<DWORD, TranslatedStringStorage>();
|
|
||||||
|
|
||||||
// load config file + set config font
|
// load config file + set config font
|
||||||
mConfiguration = new Configuration;
|
mConfiguration = new Configuration;
|
||||||
application.setFont(ConfigFont("Application"));
|
application.setFont(ConfigFont("Application"));
|
||||||
|
@ -230,12 +227,6 @@ int main(int argc, char* argv[])
|
||||||
#endif
|
#endif
|
||||||
delete mainWindow;
|
delete mainWindow;
|
||||||
mConfiguration->save(); //save config on exit
|
mConfiguration->save(); //save config on exit
|
||||||
{
|
|
||||||
//delete tls
|
|
||||||
auto temp = TLS_TranslatedStringMap;
|
|
||||||
TLS_TranslatedStringMap = nullptr;
|
|
||||||
delete temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO free Zydis/config/bridge and prevent use after free.
|
//TODO free Zydis/config/bridge and prevent use after free.
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,8 @@ struct TranslatedStringStorage
|
||||||
{
|
{
|
||||||
char Data[4096];
|
char Data[4096];
|
||||||
};
|
};
|
||||||
extern std::map<DWORD, TranslatedStringStorage>* TLS_TranslatedStringMap;
|
|
||||||
|
extern thread_local TranslatedStringStorage TLS_TranslatedString;
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||||
class MyEventFilter : public QAbstractNativeEventFilter
|
class MyEventFilter : public QAbstractNativeEventFilter
|
||||||
|
|
Loading…
Reference in New Issue