?? share.cpp
字號:
static char *share_id =
"@(#)Copyright (C) H.Shirouzu 2002 share.cpp Ver2.00";
/* ========================================================================
Project Name : IP Messenger for Win32
Module Name : File Share
Create : 2002-04-14(Sun)
Update : 2002-11-03(Sun)
Copyright : H.Shirouzu
Reference :
======================================================================== */
#include "tlib.h"
#include "resource.h"
#include "ipmsg.h"
#include "msgstr.h"
#define BIG_ALLOC 5
/*
岞奐僼傽僀儖娗棟
*/
ShareMng::ShareMng(Cfg *_cfg)
{
top = (ShareInfo *)&_top; // 斣暫
top->prior = top->next = top;
cfg = _cfg;
statDlg = NULL;
}
ShareInfo *ShareMng::CreateShare(int packetNo)
{
if (Search(packetNo) != NULL)
return FALSE;
ShareInfo *info = new ShareInfo(packetNo);
info->LinkList(top);
return info;
}
BOOL ShareMng::AddFileShare(ShareInfo *info, char *fname)
{
for (int cnt=0; cnt < info->fileCnt; cnt++)
if (strcmp(fname, info->fileInfo[cnt]->Fname()) == 0)
return FALSE;
FileInfo *fileInfo = new FileInfo;
if (SetFileInfo(fname, fileInfo) == FALSE)
return FALSE;
if ((info->fileCnt % BIG_ALLOC) == 0)
info->fileInfo = (FileInfo **)realloc(info->fileInfo, (info->fileCnt + BIG_ALLOC) * sizeof(FileInfo *));
info->fileInfo[info->fileCnt] = fileInfo;
info->fileCnt++;
return TRUE;
}
BOOL ShareMng::DelFileShare(ShareInfo *info, int fileNo)
{
if (fileNo >= info->fileCnt)
return FALSE;
memmove(info->fileInfo + fileNo, info->fileInfo + fileNo +1, (--info->fileCnt - fileNo) * sizeof(FileInfo *));
statDlg->Refresh();
return TRUE;
}
BOOL ShareMng::SetFileInfo(char *fname, FileInfo *info)
{
WIN32_FIND_DATA fdat;
if (GetFileInfomation(fname, &fdat) != TRUE)
return FALSE;
UINT attr = (fdat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? IPMSG_FILE_DIR : IPMSG_FILE_REGULAR;
attr |= (fdat.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? IPMSG_FILE_RONLYOPT : 0;
attr |= (fdat.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? IPMSG_FILE_SYSTEMOPT : 0;
info->SetAttr(attr);
info->SetFname(fname);
if (GET_MODE(info->Attr()) == IPMSG_FILE_DIR)
{
info->SetSize(0);
strncpyz(cfg->lastOpenDir, fname, MAX_PATH);
}
else {
info->SetSize((_int64)fdat.nFileSizeHigh << 32 | fdat.nFileSizeLow);
PathToDir(fname, cfg->lastOpenDir);
}
info->SetMtime(FileTime2UnixTime(&fdat.ftLastWriteTime));
return TRUE;
}
BOOL ShareMng::AddHostShare(ShareInfo *info, SendEntry *entry, int entryNum)
{
info->host = new Host *[info->hostCnt = entryNum];
info->transStat = new char [info->hostCnt * info->fileCnt];
memset(info->transStat, TRANS_INIT, info->hostCnt * info->fileCnt);
for (int cnt=0; cnt < entryNum; cnt++)
{
info->host[cnt] = (Host *)cfg->fileHosts.GetHostByNameAddr(&entry[cnt].Host()->hostSub);
if (info->host[cnt] == NULL)
{
info->host[cnt] = new Host;
info->host[cnt]->hostSub = entry[cnt].Host()->hostSub;
strncpyz(info->host[cnt]->nickName, entry[cnt].Host()->nickName, MAX_NAMEBUF);
cfg->fileHosts.AddHost(info->host[cnt]);
}
else info->host[cnt]->RefCnt(1);
}
SYSTEMTIME st;
::GetSystemTime(&st);
::SystemTimeToFileTime(&st, &info->attachTime);
statDlg->Refresh();
return TRUE;
}
int ShareMng::GetFileInfoNo(ShareInfo *info, FileInfo *fileInfo)
{
for (int target=0; info->fileCnt; target++)
if (info->fileInfo[target] == fileInfo)
return target;
return -1;
}
BOOL ShareMng::EndHostShare(int packetNo, HostSub *hostSub, FileInfo *fileInfo, BOOL done)
{
ShareInfo *info = Search(packetNo);
if (info == NULL)
return FALSE;
for (int cnt=0; cnt < info->hostCnt; cnt++)
{
if (IsSameHostEx(&info->host[cnt]->hostSub, hostSub))
{
if (fileInfo)
{
info->transStat[info->fileCnt * cnt + GetFileInfoNo(info, fileInfo)] = done ? TRANS_DONE : TRANS_INIT;
if (done == FALSE)
return statDlg->Refresh(), TRUE;
for (int cnt2=0; cnt2 < info->fileCnt; cnt2++)
if (info->transStat[info->fileCnt * cnt + cnt2] != TRANS_DONE)
return statDlg->Refresh(), TRUE;
}
if (info->host[cnt]->RefCnt(-1) == 0)
{
cfg->fileHosts.DelHost(info->host[cnt]);
delete info->host[cnt];
}
memmove(info->host + cnt, info->host + cnt + 1, (--info->hostCnt - cnt) * sizeof(Host *));
memmove(info->transStat + info->fileCnt * cnt, info->transStat + info->fileCnt * (cnt + 1), (info->hostCnt - cnt) * info->fileCnt);
if (info->hostCnt == 0)
DestroyShare(info);
return statDlg->Refresh(), TRUE;
}
}
return FALSE;
}
void ShareMng::DestroyShare(ShareInfo *info)
{
info->next->prior = info->prior;
info->prior->next = info->next;
while (info->hostCnt-- > 0)
{
if (info->host[info->hostCnt]->RefCnt(-1) == 0)
{
cfg->fileHosts.DelHost(info->host[info->hostCnt]);
delete info->host[info->hostCnt];
}
}
delete [] info->host;
delete [] info->transStat;
while (info->fileCnt-- > 0)
delete info->fileInfo[info->fileCnt];
free(info->fileInfo);
statDlg->Refresh();
}
ShareInfo *ShareMng::Search(int packetNo)
{
for (ShareInfo *info=Top(); info; info=Next(info))
if (info->packetNo == packetNo)
return info;
return NULL;
}
BOOL ShareMng::GetShareCntInfo(ShareCntInfo *cntInfo, ShareInfo *shareInfo)
{
memset(cntInfo, 0, sizeof(ShareCntInfo));
for (ShareInfo *info = shareInfo ? shareInfo : Top(); info; info=Next(info))
{
if (info->hostCnt)
{
cntInfo->packetCnt++;
cntInfo->hostCnt += info->hostCnt;
for (int cnt=info->fileCnt * info->hostCnt -1; cnt >= 0; cnt--)
{
cntInfo->fileCnt++;
switch (info->transStat[cnt]) {
case TRANS_INIT: break;
case TRANS_BUSY: cntInfo->transferCnt++; break;
case TRANS_DONE: cntInfo->doneCnt++; break;
}
}
for (cnt=0; cnt < info->fileCnt; cnt++)
{
if (GET_MODE(info->fileInfo[cnt]->Attr()) == IPMSG_FILE_DIR)
cntInfo->dirCnt++;
cntInfo->totalSize += info->fileInfo[cnt]->Size();
}
}
if (shareInfo)
return TRUE;
}
return TRUE;
}
BOOL ShareMng::GetAcceptableFileInfo(ConnectInfo *info, char *buf, AcceptFileInfo *fileInfo)
{
// 杮摉偼偙傫側偲偙傠偱僨僐乕僪偣偢丄msgmng 偵傗傜偣傞傋偒偩偑...
char *tok, *p;
int targetID;
ShareInfo *shareInfo;
HostSub hostSub = { "", "", info->addr, info->port };
if ((tok = separate_token(buf, ':', &p)) == NULL || atoi(tok) != IPMSG_VERSION)
return FALSE;
if ((tok = separate_token(NULL, ':', &p)) == NULL) // packet no
return FALSE;
if ((tok = separate_token(NULL, ':', &p)) == NULL)
return FALSE;
strncpyz(hostSub.userName, tok, MAX_NAMEBUF);
if ((tok = separate_token(NULL, ':', &p)) == NULL)
return FALSE;
strncpyz(hostSub.hostName, tok, MAX_NAMEBUF);
if ((tok = separate_token(NULL, ':', &p)) == NULL) // command
return FALSE;
fileInfo->command = atoi(tok);
if ((tok = separate_token(NULL, ':', &p)) == NULL)
return FALSE;
fileInfo->packetNo = strtol(tok, 0, 16);
if ((tok = separate_token(NULL, ':', &p)) == NULL)
return FALSE;
targetID = strtol(tok, 0, 16);
if (GET_MODE(fileInfo->command) == IPMSG_GETFILEDATA)
{
if ((tok = separate_token(NULL, ':', &p)) == NULL)
return FALSE;
fileInfo->offset = hex2ll(tok);
}
else if (GET_MODE(fileInfo->command) == IPMSG_GETDIRFILES)
fileInfo->offset = 0;
else return FALSE;
if ((shareInfo = Search(fileInfo->packetNo)) == NULL)
return FALSE;
int host_cnt, file_cnt;
for (host_cnt=0; host_cnt < shareInfo->hostCnt; host_cnt++)
{
if (IsSameHostEx(&shareInfo->host[host_cnt]->hostSub, &hostSub))
{
fileInfo->host = shareInfo->host[host_cnt];
break;
}
}
if (host_cnt == shareInfo->hostCnt)
return FALSE;
for (file_cnt=0; file_cnt < shareInfo->fileCnt; file_cnt++)
{
if (shareInfo->fileInfo[file_cnt]->Id() == targetID)
{
fileInfo->fileInfo = shareInfo->fileInfo[file_cnt];
if (shareInfo->transStat[shareInfo->fileCnt * host_cnt + file_cnt] != TRANS_INIT)
return FALSE; // download 嵪傒乮or 嵟拞乯
if (GET_MODE(fileInfo->command) != IPMSG_GETDIRFILES && GET_MODE(fileInfo->fileInfo->Attr()) == IPMSG_FILE_DIR) // dir 偵懳偟偰 IPMSG_GETDIRFILES 埲奜偼擣傔側偄
return FALSE;
fileInfo->attachTime = shareInfo->attachTime;
shareInfo->transStat[shareInfo->fileCnt * host_cnt + file_cnt] = TRANS_BUSY;
statDlg->Refresh();
return TRUE;
}
}
return FALSE;
}
/* ShareDlg */
TShareDlg::TShareDlg(ShareMng *_shareMng, ShareInfo *_shareInfo, Cfg *_cfg, TWin *_parent) : TDlg(FILE_DIALOG, _parent), shareListView(this)
{
shareMng = _shareMng;
shareInfo = _shareInfo;
cfg = _cfg;
}
TShareDlg::~TShareDlg()
{
SendDlgItemMessage(FILE_LIST, LVM_DELETEALLITEMS, 0, 0);
}
BOOL TShareDlg::EvCreate(LPARAM lParam)
{
SendDlgItemMessage(FILE_LIST, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, parent->SendDlgItemMessage(HOST_LIST, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0) & ~LVS_EX_HEADERDRAGDROP);
LV_COLUMN lvC;
memset(&lvC, 0, sizeof(lvC));
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
char *title[] = { FILENAME_MSGSTR, SIZE_MSGSTR, LOCATION_MSGSTR, NULL };
int size[] = { 120, 70, 180 };
int fmt[] = { LVCFMT_LEFT, LVCFMT_RIGHT, LVCFMT_LEFT, LVCFMT_LEFT };
for (lvC.iSubItem = 0; title[lvC.iSubItem]; lvC.iSubItem++)
{
lvC.pszText = title[lvC.iSubItem];
lvC.fmt = fmt[lvC.iSubItem];
lvC.cx = size[lvC.iSubItem];
SendDlgItemMessage(FILE_LIST, LVM_INSERTCOLUMN, lvC.iSubItem, (LPARAM)&lvC);
}
for (int cnt=0; cnt < shareInfo->fileCnt; cnt++)
AddList(cnt);
shareListView.CreateByWnd(GetDlgItem(FILE_LIST));
if (rect.left == CW_USEDEFAULT)
{
GetWindowRect(&rect);
int xsize = rect.right - rect.left, ysize = rect.bottom - rect.top;
int cx = ::GetSystemMetrics(SM_CXFULLSCREEN), cy = ::GetSystemMetrics(SM_CYFULLSCREEN);
int x = (cx - xsize)/2;
int y = (cy - ysize)/2;
MoveWindow((x < 0) ? 0 : x % (cx - xsize), (y < 0) ? 0 : y % (cy - ysize), xsize, ysize, FALSE);
}
else
MoveWindow(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, FALSE);
Show();
::SetFocus(shareListView.hWnd);
return TRUE;
}
BOOL TShareDlg::AddList(int cnt)
{
LV_ITEM lvi;
memset(&lvi, 0, sizeof(lvi));
lvi.mask = LVIF_TEXT|LVIF_PARAM;
lvi.iItem = cnt;
lvi.pszText = LPSTR_TEXTCALLBACK;
lvi.lParam = 0;
return SendDlgItemMessage(FILE_LIST, LVM_INSERTITEM, 0, (LPARAM)&lvi);
}
BOOL TShareDlg::DelList(int cnt)
{
SendDlgItemMessage(FILE_LIST, LVM_DELETEITEM, cnt, 0);
shareMng->DelFileShare(shareInfo, cnt);
return TRUE;
}
BOOL TShareDlg::EvNotify(UINT ctlID, NMHDR *pNmHdr)
{
if (pNmHdr->code == LVN_GETDISPINFO)
{
LV_DISPINFO *dispInfo = (LV_DISPINFO *)pNmHdr;
const char *fname = shareInfo->fileInfo[dispInfo->item.iItem]->Fname();
dispInfo->item.pszText = lvBuf;
switch (dispInfo->item.iSubItem) {
case 0: ForcePathToFname(fname, lvBuf);
break;
case 1: if (GET_MODE(shareInfo->fileInfo[dispInfo->item.iItem]->Attr()) == IPMSG_FILE_DIR)
strcpy(lvBuf, "(DIR)");
else
MakeSizeString(lvBuf, shareInfo->fileInfo[dispInfo->item.iItem]->Size(), MSS_SPACE);
break;
case 2: PathToDir(fname, lvBuf);
break;
default: return FALSE;
}
return TRUE;
}
return FALSE;
}
BOOL TShareDlg::EvDropFiles(HDROP hDrop)
{
int lastFileCnt = shareInfo->fileCnt;
parent->EvDropFiles(hDrop);
while (lastFileCnt < shareInfo->fileCnt)
AddList(lastFileCnt++);
return TRUE;
}
BOOL TShareDlg::EvCommand(WORD wNotifyCode, WORD wID, LPARAM hWndCtl)
{
switch (wID)
{
case IDOK: EndDialog(TRUE); break;
case IDCANCEL: EndDialog(FALSE); break;
case FILE_BUTTON:
{
int cnt = shareInfo->fileCnt;
if (FileAddDlg(this, shareMng, shareInfo, cfg))
for (cnt; cnt < shareInfo->fileCnt; cnt++)
AddList(cnt);
}
break;
case FOLDER_BUTTON:
if (BrowseDirDlg(this, FOLDERATTACH_MSGSTR, cfg->lastOpenDir, cfg->lastOpenDir))
{
if (shareMng->AddFileShare(shareInfo, cfg->lastOpenDir))
{
AddList(shareInfo->fileCnt -1);
cfg->WriteRegistry(CFG_GENERAL);
}
}
break;
case DEL_BUTTON:
{
for (int cnt=shareInfo->fileCnt-1; cnt >= 0; cnt--)
{
if ((SendDlgItemMessage(FILE_LIST, LVM_GETITEMSTATE, cnt, LVIS_SELECTED) & LVIS_SELECTED) == 0)
continue;
DelList(cnt);
}
}
break;
default: break;
}
return TRUE;
}
BOOL TShareDlg::FileAddDlg(TDlg *dlg, ShareMng *shareMng, ShareInfo *shareInfo, Cfg *cfg)
{
char buf[MAX_BUF] = "", path[MAX_BUF];
if (OpenFileDlg(dlg, OpenFileDlg::MULTI_OPEN).Exec(buf, ADDFILE_MSGSTR, OPENFILEALL_MSGSTR, cfg->lastOpenDir) != TRUE)
return FALSE;
cfg->WriteRegistry(CFG_GENERAL);
int dirlen = strlen(cfg->lastOpenDir);
if (buf[dirlen])
return shareMng->AddFileShare(shareInfo, buf);
for (char *fname=buf+dirlen+1; *fname; fname += strlen(fname) +1)
{
if (MakePath(path, buf, fname) >= MAX_PATH)
continue;
shareMng->AddFileShare(shareInfo, path);
}
return TRUE;
}
/* TShareStatDlg */
TShareStatDlg::TShareStatDlg(ShareMng *_shareMng, Cfg *_cfg, TWin *_parent) : TDlg(SHARE_DIALOG, _parent), shareListView(this)
{
shareMng = _shareMng;
cfg = _cfg;
shareMng->RegistShareStatDlg(this);
}
TShareStatDlg::~TShareStatDlg()
{
SendDlgItemMessage(SHARE_LIST, LVM_DELETEALLITEMS, 0, 0);
}
BOOL TShareStatDlg::EvCreate(LPARAM lParam)
{
SendDlgItemMessage(SHARE_LIST, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, SendDlgItemMessage(SHARE_LIST, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0) | LVS_EX_FULLROWSELECT | (cfg->GlidLineCheck ? LVS_EX_GRIDLINES : 0));
LV_COLUMN lvC;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -