📄 mainwin.cpp
字号:
return len;
}
/*
僼傽僀儖憲庴怣
*/
BOOL TMainWin::SendDirFile(SendFileObj *obj)
{
BOOL find = FALSE;
if (obj->status == FS_OPENINFO)
{
char buf[MAX_BUF];
if (obj->dirCnt == 0)
strncpyz(buf, obj->fileInfo->Fname(), MAX_PATH);
else if (MakePath(buf, obj->path, *obj->fdata.cAlternateFileName ? obj->fdata.cAlternateFileName : obj->fdata.cFileName) >= MAX_PATH)
return FALSE;
strncpyz(obj->path, buf, MAX_PATH);
obj->dirCnt++;
obj->status = FS_FIRSTINFO;
}
if (obj->status == FS_FIRSTINFO || obj->status == FS_NEXTINFO)
{
if (obj->status == FS_FIRSTINFO)
{
char buf[MAX_BUF];
MakePath(buf, obj->path, "*");
find = (obj->hDir[obj->dirCnt -1] = ::FindFirstFile(buf, &obj->fdata)) == INVALID_HANDLE_VALUE ? FALSE : TRUE;
}
else find = ::FindNextFile(obj->hDir[obj->dirCnt -1], &obj->fdata);
while (find && (strcmp(obj->fdata.cFileName, ".") == 0 || strcmp(obj->fdata.cFileName, "..") == 0))
find = ::FindNextFile(obj->hDir[obj->dirCnt -1], &obj->fdata);
obj->status = FS_MAKEINFO;
}
if (obj->status == FS_DIRFILESTART || obj->status == FS_MAKEINFO)
{
if (obj->status == FS_DIRFILESTART)
find = TRUE;
if (find && (obj->dirCnt > 0 || obj->isDir == FALSE) && (obj->fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
char buf[MAX_BUF];
int len = MakePath(buf, obj->path, *obj->fdata.cAlternateFileName ? obj->fdata.cAlternateFileName : obj->fdata.cFileName);
BOOL modifyCheck = (cfg->fileTransOpt & FT_STRICTDATE) && *(_int64 *)&obj->fdata.ftLastWriteTime > *(_int64 *)&obj->attachTime;
if (len >= MAX_PATH || modifyCheck || OpenSendFile(buf, obj) == FALSE)
{
len = strlen(obj->fdata.cFileName);
strncpyz(obj->fdata.cFileName + len, " (Can't open)", MAX_PATH - len);
obj->fdata.nFileSizeHigh = obj->fdata.nFileSizeLow = 0;
}
}
if (find == FALSE && obj->isDir)
GetFileInfomation(obj->path, &obj->fdata);
obj->headerOffset = 0;
obj->headerLen = MakeDirHeader(obj, find);
if (find == FALSE)
{
if (--obj->dirCnt >= 0 && obj->isDir)
{
::FindClose(obj->hDir[obj->dirCnt]);
if (PathToDir(obj->path, obj->path) != TRUE && obj->dirCnt > 0)
return FALSE;
}
if (obj->dirCnt <= 0)
obj->dirCnt--; // 廔椆
}
obj->status = FS_TRANSINFO;
}
if (obj->status == FS_TRANSINFO)
{
int size = ::send(obj->conInfo->sd, obj->header + obj->headerOffset, obj->headerLen - obj->headerOffset, 0);
if (size < 0)
return FALSE;
else {
if ((obj->headerOffset += size) < obj->headerLen)
return TRUE;
obj->status = obj->dirCnt < 0 ? FS_COMPLETE : find == FALSE ? FS_NEXTINFO : (obj->fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? FS_OPENINFO : FS_TRANSFILE;
}
}
if (obj->status == FS_TRANSFILE)
{
if (obj->mapAddr && SendFile(obj) != TRUE)
{
CloseSendFile(obj);
return FALSE;
}
else if (obj->mapAddr == NULL || obj->status == FS_ENDFILE)
{
CloseSendFile(obj);
obj->status = obj->isDir ? FS_NEXTINFO : FS_MAKEINFO;
}
}
return TRUE;
}
/*
僼傽僀儖憲庴怣
*/
BOOL TMainWin::SendFile(SendFileObj *obj)
{
if (obj == NULL || obj->hFile == INVALID_HANDLE_VALUE)
return FALSE;
int size = 0;
_int64 remain = obj->fileSize - obj->offset;
if (remain > 0 && (size = ::send(obj->conInfo->sd, obj->mapAddr + (obj->offset % cfg->ViewMax), remain > cfg->TransMax ? cfg->TransMax : (int)remain, 0)) < 0)
return FALSE;
obj->offset += size;
if (obj->offset == obj->fileSize)
obj->status = obj->command == IPMSG_GETDIRFILES ? FS_ENDFILE : FS_COMPLETE;
else if ((obj->offset % cfg->ViewMax) == 0) // 嵞儅僢僾偺昁梫
{
::UnmapViewOfFile(obj->mapAddr);
remain = obj->fileSize - obj->offset;
obj->mapAddr = (char *)::MapViewOfFile(obj->hMap, FILE_MAP_READ, (int)(obj->offset >> 32), (int)obj->offset, (int)(remain > cfg->ViewMax ? cfg->ViewMax : remain));
}
obj->conInfo->lastTick = ::GetTickCount();
return TRUE;
}
BOOL TMainWin::EndSendFile(SendFileObj *obj)
{
if (obj == NULL)
return FALSE;
if (obj->hThread)
{
HANDLE hThread = obj->hThread;
obj->hThread = 0; // 拞抐偺崌恾
::WaitForSingleObject(hThread, INFINITE);
::CloseHandle(hThread);
}
if (::closesocket(obj->conInfo->sd) != 0)
obj->status = FS_ERROR; // error 埖偄偵偡傞
CloseSendFile(obj);
if (obj->isDir)
free(obj->hDir);
shareMng->EndHostShare(obj->packetNo, &obj->host->hostSub, obj->fileInfo, obj->status == FS_COMPLETE ? TRUE : FALSE);
sendFileList.DelObj(obj);
delete obj->conInfo;
delete obj;
return TRUE;
}
/*
Entry Packet庴怣張棟
*/
void TMainWin::MsgBrEntry(MsgBuf *msg)
{
AddrObj *obj = (AddrObj *)ansList->GetObj(FREE_LIST);
if (obj) {
obj->addr = msg->hostSub.addr;
obj->portNo = msg->hostSub.portNo;
ansList->PutObj(USED_LIST, obj);
}
if (obj == NULL || SetAnswerQueue(obj) != TRUE)
msgMng->Send(&msg->hostSub, IPMSG_ANSENTRY|HostStatus(), GetNickNameEx(), cfg->GroupNameStr);
AddHost(&msg->hostSub, msg->command, msg->msgBuf, msg->msgBuf + msg->exOffset);
}
BOOL TMainWin::SetAnswerQueue(AddrObj *obj)
{
if (ansTimerID)
return TRUE;
int hostCnt = hosts.HostCnt(), spawn;
if (hostCnt < 50 || ((msgMng->GetLocalHost()->addr ^ obj->addr) << 8) == 0)
spawn = 1023 & rand();
else if (hostCnt < 300)
spawn = 2047 & rand();
else
spawn = 4095 & rand();
if ((ansTimerID = ::SetTimer(hWnd, IPMSG_ANS_TIMER, spawn, NULL)) == 0)
return FALSE;
return TRUE;
}
void TMainWin::ExecuteAnsQueue(void)
{
AddrObj *obj;
while ((obj = (AddrObj *)ansList->GetObj(USED_LIST)) != NULL) {
msgMng->Send(obj->addr, obj->portNo, IPMSG_ANSENTRY|HostStatus(), GetNickNameEx(), cfg->GroupNameStr);
ansList->PutObj(FREE_LIST, obj);
}
}
/*
Exit Packet庴怣張棟
*/
void TMainWin::MsgBrExit(MsgBuf *msg)
{
Host *host = cfg->priorityHosts.GetHostByName(&msg->hostSub);
if (host != NULL)
host->updateTime = Time();
DelHost(&msg->hostSub);
for (ShareInfo *info=shareMng->Top(),*next; info; info = next)
{
next = shareMng->Next(info);
shareMng->EndHostShare(info->packetNo, &msg->hostSub);
}
}
/*
AnsEntry Packet庴怣張棟
*/
void TMainWin::MsgAnsEntry(MsgBuf *msg)
{
AddHost(&msg->hostSub, msg->command, msg->msgBuf, msg->msgBuf + msg->exOffset);
}
/*
Absence Packet庴怣張棟
*/
void TMainWin::MsgBrAbsence(MsgBuf *msg)
{
AddHost(&msg->hostSub, msg->command, msg->msgBuf, msg->msgBuf + msg->exOffset);
}
/*
Send Packet庴怣張棟
*/
void TMainWin::MsgSendMsg(MsgBuf *msg)
{
TRecvDlg *recvDlg;
if (TRecvDlg::GetCreateCnt() >= cfg->RecvMax)
return;
for (recvDlg = (TRecvDlg *)recvList.TopObj(); recvDlg != NULL; recvDlg = (TRecvDlg *)recvList.NextObj(recvDlg))
if (recvDlg->IsSamePacket(msg))
break;
if (recvDlg != NULL || IsLastPacket(msg))
{
if ((msg->command & IPMSG_SENDCHECKOPT) != 0 && (msg->command & (IPMSG_BROADCASTOPT | IPMSG_AUTORETOPT)) == 0)
msgMng->Send(&msg->hostSub, IPMSG_RECVMSG, msg->packetNo);
return;
}
if ((msg->command & IPMSG_BROADCASTOPT) == 0 && (msg->command & IPMSG_AUTORETOPT) == 0)
{
if ((msg->command & IPMSG_SENDCHECKOPT) != 0)
msgMng->Send(&msg->hostSub, IPMSG_RECVMSG, msg->packetNo);
if (cfg->AbsenceCheck == TRUE && *cfg->AbsenceStr[cfg->AbsenceChoice])
msgMng->Send(&msg->hostSub, IPMSG_SENDMSG|IPMSG_AUTORETOPT, cfg->AbsenceStr[cfg->AbsenceChoice]);
if ((msg->command & IPMSG_NOADDLISTOPT) == 0 && hosts.GetHostByAddr(&msg->hostSub) == NULL)
BroadcastEntrySub(&msg->hostSub, IPMSG_BR_ENTRY);
}
RecvDlgOpen(msg);
}
/*
Recv Packet庴怣張棟
*/
void TMainWin::MsgRecvMsg(MsgBuf *msg)
{
MsgInfoSub(msg);
}
/*
Read Packet庴怣張棟
*/
void TMainWin::MsgReadMsg(MsgBuf *msg)
{
MsgInfoSub(msg);
}
/*
HostList 憲弌壜擻栤崌偣 Packet庴怣張棟
*/
void TMainWin::MsgBrIsGetList(MsgBuf *msg)
{
if (cfg->AllowSendList
&& (entryStartTime + ((ULONG)cfg->ListGetMSec / 1000) < (ULONG)Time())
&& (cfg->ListGet == FALSE || (IPMSG_RETRYOPT & msg->command)))
msgMng->Send(&msg->hostSub, IPMSG_OKGETLIST);
}
/*
HostList 憲弌壜擻捠抦 Packet庴怣張棟
*/
void TMainWin::MsgOkGetList(MsgBuf *msg)
{
if (entryStartTime != IPMSG_GETLIST_FINISH)
msgMng->Send(&msg->hostSub, IPMSG_GETLIST);
}
/*
HostList 憲弌梫媮 Packet庴怣張棟
*/
void TMainWin::MsgGetList(MsgBuf *msg)
{
if (cfg->AllowSendList)
SendHostList(msg);
}
/*
HostList 憲弌 Packet庴怣張棟
*/
void TMainWin::MsgAnsList(MsgBuf *msg)
{
if (entryStartTime != IPMSG_GETLIST_FINISH)
AddHostList(msg);
}
/*
Version Information 梫媮 Packet庴怣張棟
*/
void TMainWin::MsgGetInfo(MsgBuf *msg)
{
char buf[MAX_LISTBUF];
wsprintf(buf, WIN32EDITION_MSGSTR, GetVerionStr());
msgMng->Send(&msg->hostSub, IPMSG_SENDINFO, buf);
}
/*
Version Information 捠抦 Packet庴怣張棟
*/
void TMainWin::MsgSendInfo(MsgBuf *msg)
{
MsgInfoSub(msg);
}
/*
Public Key 梫媮 Packet庴怣張棟
*/
void TMainWin::MsgGetPubKey(MsgBuf *msg)
{
int capa = strtoul(msg->msgBuf, 0, 16);
if ((capa &= cfg->smallPubKey.Capa()) == 0)
return;
PubKey *pubKey = (capa & IPMSG_RSA_1024) ? &cfg->pubKey : &cfg->smallPubKey;
char buf[MAX_BUF];
wsprintf(buf, "%X:%X-", cfg->smallPubKey.Capa(), pubKey->Exponent());
bin2hexstr_bigendian(pubKey->Key(), pubKey->KeyLen(), buf + strlen(buf));
msgMng->Send(&msg->hostSub, IPMSG_ANSPUBKEY, buf);
}
/*
Public Key 憲怣 Packet庴怣張棟
*/
void TMainWin::MsgAnsPubKey(MsgBuf *msg)
{
if (cfg->pubKey.Key() == NULL && cfg->smallPubKey.Key() == NULL)
return;
BYTE key[MAX_BUF];
int key_len, e, capa;
char *capa_hex, *e_hex, *key_hex, *p;
if ((capa_hex = separate_token(msg->msgBuf, ':', &p)) == NULL)
return;
if ((e_hex = separate_token(NULL, '-', &p)) == NULL)
return;
if ((key_hex = separate_token(NULL, ':', &p)) == NULL)
return;
capa = strtoul(capa_hex, 0, 16);
e = strtoul(e_hex, 0, 16);
hexstr2bin_bigendian(key_hex, key, sizeof(key), &key_len);
for (TSendDlg *sendDlg = (TSendDlg *)sendList.TopObj(); sendDlg != NULL; sendDlg = (TSendDlg *)sendList.NextObj(sendDlg))
if (sendDlg->SendPubKeyNotify(&msg->hostSub, key, key_len, e, capa))
break;
}
/*
Information 捠抦張棟
*/
void TMainWin::MsgInfoSub(MsgBuf *msg)
{
int cmd = GET_MODE(msg->command);
if (cmd == IPMSG_READMSG)
{
if (GET_OPT(msg->command) & IPMSG_READCHECKOPT)
msgMng->Send(&msg->hostSub, IPMSG_ANSREADMSG, msg->packetNo);
}
else {
long packet_no = (cmd == IPMSG_RECVMSG || cmd == IPMSG_ANSREADMSG) ? atol(msg->msgBuf) : 0;
if (cmd == IPMSG_ANSREADMSG) {
for (TRecvDlg *recvDlg = (TRecvDlg *)recvList.TopObj(); recvDlg != NULL; recvDlg = (TRecvDlg *)recvList.NextObj(recvDlg))
if (recvDlg->SendFinishNotify(&msg->hostSub, packet_no))
break;
return;
}
for (TSendDlg *sendDlg = (TSendDlg *)sendList.TopObj(); sendDlg != NULL; sendDlg = (TSendDlg *)sendList.NextObj(sendDlg))
if (sendDlg->SendFinishNotify(&msg->hostSub, packet_no))
break;
if (sendDlg == NULL)
return;
}
if (IsLastPacket(msg)) //廳暋僠僃僢僋
return;
char title[MAX_LISTBUF], *msg_text = msg->msgBuf, *p;
int show_mode = cfg->MsgMinimize ? SW_MINIMIZE : SW_SHOW;
MakeListString(cfg, &msg->hostSub, &hosts, title);
separate_token(title, '(', &p);
switch (cmd)
{
case IPMSG_READMSG:
if (cfg->OpenCheck == FALSE)
return;
{
char *str = Ctime();
str = separate_token(str, ' ', &p);
str = separate_token(NULL, 0, &p);
*strrchr(str, ':') = 0;
wsprintf(msg_text, "%s\r\n(%s)", OPENFIN_MSGSTR, str);
}
break;
case IPMSG_SENDINFO:
case IPMSG_SENDABSENCEINFO:
show_mode = SW_SHOW;
break;
default:
return;
}
if (cmd == IPMSG_SENDABSENCEINFO) { //彨棃揑偵偼 TMsgDlg偱張棟
static int msg_cnt = 0; // TMsgDlg 壔偟偨屻偼 TMsgDlg::createCnt 偵堏峴
if (msg_cnt >= cfg->RecvMax)
return;
msg_cnt++;
MessageBox(msg_text, title);
msg_cnt--;
}
else {
if (TMsgDlg::GetCreateCnt() >= cfg->RecvMax * 4)
return;
TMsgDlg *msgDlg = new TMsgDlg(IsNewShell() ? this : 0);
msgDlg->Create(msg_text, title, show_mode);
if (cmd == IPMSG_SENDINFO || cmd == IPMSG_SENDABSENCEINFO)
ActiveDlg(msgDlg);
msgList.AddObj(msgDlg);
}
}
/*
晄嵼捠抦 Information 梫媮 Packet庴怣張棟
*/
void TMainWin::MsgGetAbsenceInfo(MsgBuf *msg)
{
msgMng->Send(&msg->hostSub, IPMSG_SENDABSENCEINFO, cfg->AbsenceCheck ? cfg->AbsenceStr[cfg->AbsenceChoice] : NOTABSENCE_MSGSTR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -