📄 otherfunctions.cpp
字号:
{
_STRVAL(OP_EMULEINFO),
_STRVAL(OP_EMULEINFOANSWER),
_STRVAL(OP_COMPRESSEDPART),
_STRVAL(OP_QUEUERANKING),
_STRVAL(OP_FILEDESC),
_STRVAL(OP_REQUESTSOURCES),
_STRVAL(OP_ANSWERSOURCES),
_STRVAL(OP_PUBLICKEY),
_STRVAL(OP_SIGNATURE),
_STRVAL(OP_SECIDENTSTATE),
_STRVAL(OP_REQUESTPREVIEW),
_STRVAL(OP_PREVIEWANSWER),
_STRVAL(OP_MULTIPACKET),
_STRVAL(OP_MULTIPACKETANSWER),
_STRVAL(OP_PEERCACHE_QUERY),
_STRVAL(OP_PEERCACHE_ANSWER),
_STRVAL(OP_PEERCACHE_ACK),
_STRVAL(OP_PUBLICIP_ANSWER),
_STRVAL(OP_PUBLICIP_REQ)
};
for (int i = 0; i < ARRSIZE(_aOpcodes); i++)
{
if (_aOpcodes[i].uOpcode == opcode)
return _aOpcodes[i].pszOpcode;
}
CString strOpcode;
strOpcode.Format(_T("0x%02x"), opcode);
return strOpcode;
}
#undef _STRVAL
CString DbgGetClientTCPPacket(UINT protocol, UINT opcode, UINT size)
{
CString str;
if (protocol == OP_EDONKEYPROT)
str.Format(_T("protocol=eDonkey opcode=%s size=%u"), DbgGetDonkeyClientTCPOpcode(opcode), size);
else if (protocol == OP_PACKEDPROT)
str.Format(_T("protocol=Packed opcode=%s size=%u"), DbgGetMuleClientTCPOpcode(opcode), size);
else if (protocol == OP_EMULEPROT)
str.Format(_T("protocol=eMule opcode=%s size=%u"), DbgGetMuleClientTCPOpcode(opcode), size);
else
str.Format(_T("protocol=0x%02x opcode=0x%02x size=%u"), protocol, opcode, size);
return str;
}
CString DbgGetClientTCPOpcode(UINT protocol, UINT opcode)
{
CString str;
if (protocol == OP_EDONKEYPROT)
str.Format(_T("%s"), DbgGetDonkeyClientTCPOpcode(opcode));
else if (protocol == OP_PACKEDPROT)
str.Format(_T("%s"), DbgGetMuleClientTCPOpcode(opcode));
else if (protocol == OP_EMULEPROT)
str.Format(_T("%s"), DbgGetMuleClientTCPOpcode(opcode));
else
str.Format(_T("protocol=0x%02x opcode=0x%02x"), protocol, opcode);
return str;
}
void DebugRecv(LPCSTR pszMsg, const CUpDownClient* client, const char* packet, uint32 nIP)
{
// 111.222.333.444 = 15 chars
if (client){
if (client != NULL && packet != NULL)
Debug(_T("%-24hs from %s; %s\n"), pszMsg, client->DbgGetClientInfo(true), DbgGetFileInfo((uchar*)packet));
else if (client != NULL && packet == NULL)
Debug(_T("%-24hs from %s\n"), pszMsg, client->DbgGetClientInfo(true));
else if (client == NULL && packet != NULL)
Debug(_T("%-24hs; %s\n"), pszMsg, DbgGetFileInfo((uchar*)packet));
else
Debug(_T("%-24hs\n"), pszMsg);
}
else{
if (nIP != 0 && packet != NULL)
Debug(_T("%-24hs from %-15s; %s\n"), pszMsg, ipstr(nIP), DbgGetFileInfo((uchar*)packet));
else if (nIP != 0 && packet == NULL)
Debug(_T("%-24hs from %-15s\n"), pszMsg, ipstr(nIP));
else if (nIP == 0 && packet != NULL)
Debug(_T("%-24hs; %s\n"), pszMsg, DbgGetFileInfo((uchar*)packet));
else
Debug(_T("%-24hs\n"), pszMsg);
}
}
void DebugSend(LPCSTR pszMsg, const CUpDownClient* client, const char* packet)
{
if (client != NULL && packet != NULL)
Debug(_T(">>> %-20hs to %s; %s\n"), pszMsg, client->DbgGetClientInfo(true), DbgGetFileInfo((uchar*)packet));
else if (client != NULL && packet == NULL)
Debug(_T(">>> %-20hs to %s\n"), pszMsg, client->DbgGetClientInfo(true));
else if (client == NULL && packet != NULL)
Debug(_T(">>> %-20hs; %s\n"), pszMsg, DbgGetFileInfo((uchar*)packet));
else
Debug(_T(">>> %-20hs\n"), pszMsg);
}
void DebugSend(LPCSTR pszOpcode, uint32 ip, uint16 port)
{
Debug(_T(">>> %-20hs to %-15s:%u\n"), pszOpcode, ipstr(ntohl(ip)), port);
}
void DebugSendF(LPCSTR pszOpcode, uint32 ip, uint16 port, LPCTSTR pszMsg, ...)
{
va_list args;
va_start(args, pszMsg);
CString str;
str.Format(_T(">>> %-20hs to %-15s:%-5u; "), pszOpcode, ipstr(ntohl(ip)), port);
str.AppendFormatV(pszMsg, args);
va_end(args);
Debug(_T("%s\n"), str);
}
void DebugRecv(LPCSTR pszOpcode, uint32 ip, uint16 port)
{
Debug(_T("%-24hs from %-15s:%u\n"), pszOpcode, ipstr(ntohl(ip)), port);
}
void DebugHttpHeaders(const CStringAArray& astrHeaders)
{
for (int i = 0; i < astrHeaders.GetCount(); i++)
{
const CStringA& rstrHdr = astrHeaders.GetAt(i);
Debug(_T("<%hs\n"), rstrHdr);
}
}
ULONGLONG GetDiskFileSize(LPCTSTR pszFilePath)
{
static BOOL _bInitialized = FALSE;
static DWORD (WINAPI *_pfnGetCompressedFileSize)(LPCTSTR, LPDWORD) = NULL;
if (!_bInitialized){
_bInitialized = TRUE;
(FARPROC&)_pfnGetCompressedFileSize = GetProcAddress(GetModuleHandle(_T("kernel32.dll")), _TWINAPI("GetCompressedFileSize"));
}
// If the file is not compressed nor sparse, 'GetCompressedFileSize' returns the 'normal' file size.
if (_pfnGetCompressedFileSize)
{
ULONGLONG ullCompFileSize;
LPDWORD pdwCompFileSize = (LPDWORD)&ullCompFileSize;
pdwCompFileSize[0] = (*_pfnGetCompressedFileSize)(pszFilePath, &pdwCompFileSize[1]);
if (pdwCompFileSize[0] != INVALID_FILE_SIZE || GetLastError() == NO_ERROR)
return ullCompFileSize;
}
// If 'GetCompressedFileSize' failed or is not available, use the default function
WIN32_FIND_DATA fd;
HANDLE hFind = FindFirstFile(pszFilePath, &fd);
if (hFind == INVALID_HANDLE_VALUE)
return 0;
FindClose(hFind);
return (ULONGLONG)fd.nFileSizeHigh << 32 | (ULONGLONG)fd.nFileSizeLow;
}
// Listview helper function
void GetPopupMenuPos(CListCtrl& lv, CPoint& point)
{
// If the context menu was not opened using the right mouse button,
// but the keyboard (Shift+F10), get a useful position for the context menu.
if (point.x == -1 && point.y == -1)
{
int iIdxItem = lv.GetNextItem(-1, LVNI_SELECTED | LVNI_FOCUSED);
if (iIdxItem != -1)
{
CRect rc;
if (lv.GetItemRect(iIdxItem, &rc, LVIR_BOUNDS))
{
point.x = rc.left + lv.GetColumnWidth(0) / 2;
point.y = rc.top + rc.Height() / 2;
lv.ClientToScreen(&point);
}
}
else
{
point.x = 16;
point.y = 32;
lv.ClientToScreen(&point);
}
}
}
void GetPopupMenuPos(CTreeCtrl& tv, CPoint& point)
{
// If the context menu was not opened using the right mouse button,
// but the keyboard (Shift+F10), get a useful position for the context menu.
if (point.x == -1 && point.y == -1)
{
HTREEITEM hSel = tv.GetNextItem(TVI_ROOT, TVGN_CARET);
if (hSel)
{
CRect rcItem;
if (tv.GetItemRect(hSel, &rcItem, TRUE))
{
point.x = rcItem.left;
point.y = rcItem.top;
tv.ClientToScreen(&point);
}
}
else
{
point.x = 16;
point.y = 32;
tv.ClientToScreen(&point);
}
}
}
time_t safe_mktime(struct tm* ptm)
{
if (ptm == NULL)
return -1;
return mktime(ptm);
}
CString StripInvalidFilenameChars(CString strText, bool bKeepSpaces)
{
LPTSTR pszBuffer = strText.GetBuffer();
LPTSTR pszSource = pszBuffer;
LPTSTR pszDest = pszBuffer;
while (*pszSource != '\0')
{
if (!((*pszSource <= 31 && *pszSource >= 0) || // lots of invalid chars for filenames in windows :=)
*pszSource == '\"' || *pszSource == '*' || *pszSource == '<' || *pszSource == '>' ||
*pszSource == '?' || *pszSource == '|' || *pszSource == '\\' || *pszSource == '/' ||
*pszSource == ':') )
{
if (!bKeepSpaces && *pszSource == ' ')
*pszDest = '.';
*pszDest = *pszSource;
pszDest++;
}
pszSource++;
}
*pszDest = '\0';
strText.ReleaseBuffer();
return strText;
}
CString CreateED2kLink(const CAbstractFile* f)
{
CString strLink;
strLink.Format(_T("ed2k://|file|%s|%u|%s|/"),
StripInvalidFilenameChars(f->GetFileName(), false), // spaces to dots
f->GetFileSize(),
EncodeBase16(f->GetFileHash(),16)
);
return strLink;
}
CString CreateED2kHashsetLink(const CKnownFile* pFile)
{
CString strLink;
strLink.Format(_T("ed2k://|file|%s|%u|%s|"),
StripInvalidFilenameChars(pFile->GetFileName(), false), // spaces to dots
pFile->GetFileSize(),
EncodeBase16(pFile->GetFileHash(),16));
if (pFile->GetHashCount() > 0 && pFile->GetHashCount() == pFile->GetED2KPartHashCount())
{
strLink += _T("p=");
for (int i = 0; i < pFile->GetHashCount(); i++)
{
if (i > 0)
strLink += _T(':');
strLink += EncodeBase16(pFile->GetPartHash(i), 16);
}
strLink += _T('|');
}
strLink += _T('/');
return strLink;
}
CString CreateHTMLED2kLink(const CAbstractFile* f)
{
CString strCode = _T("<a href=\"") + CreateED2kLink(f) + _T("\">") + StripInvalidFilenameChars(f->GetFileName(), true) + _T("</a>");
return strCode;
}
bool operator==(const CCKey& k1,const CCKey& k2)
{
return !md4cmp(k1.m_key, k2.m_key);
}
bool operator==(const CSKey& k1,const CSKey& k2)
{
return !md4cmp(k1.m_key, k2.m_key);
}
CString ipstr(uint32 nIP)
{
// following gives the same string as 'inet_ntoa(*(in_addr*)&nIP)' but is not restricted to ASCII strings
const BYTE* pucIP = (BYTE*)&nIP;
CString strIP;
strIP.ReleaseBuffer(_stprintf(strIP.GetBuffer(3+1+3+1+3+1+3), _T("%u.%u.%u.%u"), pucIP[0], pucIP[1], pucIP[2], pucIP[3]));
return strIP;
}
CStringA ipstrA(uint32 nIP)
{
// following gives the same string as 'inet_ntoa(*(in_addr*)&nIP)' but is not restricted to ASCII strings
const BYTE* pucIP = (BYTE*)&nIP;
CStringA strIP;
strIP.ReleaseBuffer(sprintf(strIP.GetBuffer(3+1+3+1+3+1+3), "%u.%u.%u.%u", pucIP[0], pucIP[1], pucIP[2], pucIP[3]));
return strIP;
}
bool IsDaylightSavingTimeActive(LONG& rlDaylightBias)
{
TIME_ZONE_INFORMATION tzi;
if (GetTimeZoneInformation(&tzi) != TIME_ZONE_ID_DAYLIGHT)
return false;
rlDaylightBias = tzi.DaylightBias;
return true;
}
bool IsNTFSVolume(LPCTSTR pszVolume)
{
DWORD dwMaximumComponentLength = 0;
DWORD dwFileSystemFlags = 0;
TCHAR szFileSystemNameBuffer[128];
if (!GetVolumeInformation(pszVolume, NULL, 0, NULL, &dwMaximumComponentLength, &dwFileSystemFlags, szFileSystemNameBuffer, 128))
return false;
return (_tcscmp(szFileSystemNameBuffer, _T("NTFS")) == 0);
}
bool IsFileOnNTFSVolume(LPCTSTR pszFilePath)
{
CString strRootPath(pszFilePath);
BOOL bResult = PathStripToRoot(strRootPath.GetBuffer());
strRootPath.ReleaseBuffer();
if (!bResult)
return false;
PathAddBackslash(strRootPath.GetBuffer());
strRootPath.ReleaseBuffer();
return IsNTFSVolume(strRootPath);
}
bool IsAutoDaylightTimeSetActive()
{
CRegKey key;
if (key.Open(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation"), KEY_READ) == ERROR_SUCCESS)
{
DWORD dwDisableAutoDaylightTimeSet = 0;
if (key.QueryDWORDValue(_T("DisableAutoDaylightTimeSet"), dwDisableAutoDaylightTimeSet) == ERROR_SUCCESS)
{
if (dwDisableAutoDaylightTimeSet)
return false;
}
}
return true; // default to 'Automatically adjust clock for daylight saving changes'
}
bool AdjustNTFSDaylightFileTime(uint32& ruFileDate, LPCTSTR pszFilePath)
{
if (!thePrefs.GetAdjustNTFSDaylightFileTime())
return false;
if (ruFileDate == 0 || ruFileDate == -1)
return false;
// See also KB 129574
LONG lDaylightBias = 0;
if (IsDaylightSavingTimeActive(lDaylightBias))
{
if (IsAutoDaylightTimeSetActive())
{
if (IsFileOnNTFSVolume(pszFilePath))
{
ruFileDate += lDaylightBias*60;
return true;
}
}
else
{
// If 'Automatically adjust clock for daylight saving changes' is disabled and
// if the file's date is within DST period, we get again a wrong file date.
//
// If 'Automatically adjust clock for daylight saving changes' is disabled,
// Windows always reports 'Active DST'(!!) with a bias of '0' although there is no
// DST specified. This means also, that there is no chance to determine if a date is
// within any DST.
// Following code might be correct, but because we don't have a DST and because we don't have a bias,
// the code won't do anything useful.
/*struct tm* ptm = localtime((time_t*)&ruFileDate);
bool bFileDateInDST = (ptm && ptm->tm_isdst == 1);
if (bFileDateInDST)
{
ruFileDate += lDaylightBias*60;
return true;
}*/
}
}
return false;
}
bool ExpandEnvironmentStrings(CString& rstrStrings)
{
DWORD dwSize = ExpandEnvironmentStrings(rstrStrings, NULL, 0);
if (dwSize == 0)
return false;
CString strExpanded;
DWORD dwCount = ExpandEnvironmentStrings(rstrStrings, strExpanded.GetBuffer(dwSize-1), dwSize);
#ifdef _UNICODE
if (dwCount == 0 || dwCount != dwSize){
#else
if (dwCount == 0 || dwCount != dwSize-1){
#endif
ASSERT(0);
return false;
}
strExpanded.ReleaseBuffer(dwCount-1);
rstrStrings = strExpanded;
return true;
}
uint16 GetRandomUInt16()
{
#if RAND_MAX == 0x7fff
// get 2 random numbers
UINT uRand0 = rand();
UINT uRand1 = rand();
// NOTE: if that assert fires, you have most likely called that function *without* calling 'srand' first.
// NOTE: each spawned thread HAS to call 'srand' for itself to get real random numbers.
ASSERT( !(uRand0 == 41 && uRand1 == 18467) );
return uRand0 | ((uRand1 >= RAND_MAX/2) ? 0x8000 : 0x0000);
#else
#error "Implement it!"
#endif
}
uint32 GetRandomUInt32()
{
#if RAND_MAX == 0x7fff
//return ((uint32)GetRandomUInt16() << 16) | (uint32)GetRandomUInt16();
// this would give the receiver the following information:
// random number N
// random number N+1 is below or greater/equal than 0x8000
// random number N+2
// random number N+3 is below or greater/equal than 0x8000
uint32 uRand0 = GetRandomUInt16();
srand(GetTickCount());
uint32 uRand1 = GetRandomUInt16();
r
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -