www.pudn.com > ntshell.rar > maindlg.cpp
// maindlg.cpp : implementation of the CMainDlg class
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "common.h"
#include "ntshell.h"
#include "aboutdlg.h"
#include "config.h"
#include "inputdlg.h"
#include "md5.h"
#include "maindlg.h"
extern USHORT LocalListenPort;
BOOL CMainDlg::PreTranslateMessage(MSG* pMsg)
{
return IsDialogMessage(pMsg);
}
BOOL CMainDlg::OnIdle()
{
return FALSE;
}
LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
// center the dialog on the screen
CenterWindow();
m_host = NULL;
m_nWaiting = 0;
m_nSessionTotal = 0;
CLocalConfig::LoadConfig(); //读取配置文件
// set icons
HICON hIcon = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME),
IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
SetIcon(hIcon, TRUE);
HICON hIconSmall = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME),
IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
SetIcon(hIconSmall, FALSE);
m_hWndList.Attach(GetDlgItem(IDC_HOSTLIST));
m_hWndList.InsertColumn(0, "主机IP", LVCFMT_LEFT, 100, 0);
m_hWndList.InsertColumn(1, "主机名", LVCFMT_LEFT, 120, 0);
m_hWndList.InsertColumn(2, "连上时间", LVCFMT_LEFT, 60, 0);
m_hWndList.InsertColumn(3, "状态", LVCFMT_LEFT, 80, 0);
m_hWndStatusBar.Attach(GetDlgItem(IDC_STATUSBAR));
DWORD dwStyle = m_hWndList.GetExtendedListViewStyle();
dwStyle |= LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP;
m_hWndList.SetExtendedListViewStyle(dwStyle);
OpenListenSock(); //打开服务端口
SetTimer(WM_TIMER, 500); //设置定时器用于检测连接是否超时
// register object for message filtering and idle updates
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter(this);
pLoop->AddIdleHandler(this);
UIAddChildWindowContainer(m_hWnd);
return TRUE;
}
LRESULT CMainDlg::OnTimer(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
for (int i = 0; i < m_nWaiting; i++)
{
if (GetTickCount() - connmgr[i].dwReqTime > 5000) //连接超时检测
{
if (connmgr[i].funBack != NULL)
connmgr[i].funBack(INVALID_SOCKET, connmgr[i].lpParam);
else if (::IsWindow(connmgr[i].hAcceptWnd))
::PostMessage(connmgr[i].hAcceptWnd, WM_CONNECT_TIMEOUT, INVALID_SOCKET, (LPARAM)connmgr[i].lpParam);
connmgr[i] = connmgr[--m_nWaiting];
}
}
return 0;
}
LRESULT CMainDlg::OnSockConnEvent(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
SOCKET slave_sock = (SOCKET)wParam;
struct sockaddr_in slave;
int temp = 0, iAddrSize = sizeof(slave);
CString message;
if (WSAGETSELECTERROR(lParam))
{
closesocket(slave_sock);
return 0;
}
switch (WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
slave_sock = accept(m_ListenSock, (struct sockaddr *)&slave, &iAddrSize);
WSAAsyncSelect(slave_sock, this->m_hWnd, WM_SOCKET_CONN, FD_READ | FD_WRITE | FD_CLOSE);
message.Format("%s 连接到本机", inet_ntoa(slave.sin_addr));
m_hWndStatusBar.SetWindowText(message);
break;
case FD_READ:
recv(slave_sock, (char *)&temp, sizeof(temp), 0);
switch (temp)
{
case CONN1_SLAVE_ASK:
temp = CONN1_MASTER_ANSWER;
send(slave_sock, (char *)&temp, sizeof(temp), 0);
break;
case CONN2_SLAVE_ASK:
temp = CONN2_MASTER_ANSWER;
send(slave_sock, (char *)&temp, sizeof(temp), 0);
break;
case CONN1_SLAVE_OK:
AddHost(slave_sock, 0); //添加到主机列表中
break;
case CONN2_SLAVE_OK:
WSAAsyncSelect(slave_sock, m_hWnd, WM_SOCKET_CTRL, FD_READ | FD_CLOSE);
SendRequest(slave_sock);
break;
case CONN3_SLAVE_OK:
AddHost(slave_sock, 1); //添加到主机列表中
break;
case CONN4_SLAVE_OK:
WSAAsyncSelect(slave_sock, m_hWnd, WM_SOCKET_CTRL, FD_READ | FD_CLOSE);
SendRequest(slave_sock);
break;
default:
closesocket(slave_sock);
break;
}
break;
case FD_CLOSE:
getpeername(slave_sock, (struct sockaddr *)&slave, &iAddrSize);
message.Format("与 %s 的连接已关闭", inet_ntoa(slave.sin_addr));
m_hWndStatusBar.SetWindowText(message);
closesocket(slave_sock);
break;
}
return 0;
}
LRESULT CMainDlg::OnSockCtrlEvent(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
{
SOCKET slave_sock = (SOCKET)wParam;
if (WSAGETSELECTERROR(lParam))
{
RemoveHost(slave_sock);
return 0;
}
switch (WSAGETSELECTEVENT(lParam))
{
case FD_READ:
TestCanRead(slave_sock);
break;
case FD_CLOSE:
RemoveHost(slave_sock);
break;
}
return 0;
}
void CMainDlg::TestCanRead(SOCKET s)
{
PHOST_LIST_LINK p, p1;
LV_FINDINFO FindInfo;
struct sockaddr_in host;
int iAddrSize = sizeof(host);
CString msg;
char *buf = SimplyRecvPack(s);
if (buf == NULL)
return;
getpeername(s, (struct sockaddr *)&host, &iAddrSize);
switch (*(ULONG *)buf)
{
case CONNECT_NEED_PWD:
for (p = m_host; p != NULL; p = p->Next)
{
if (p->Sock == s)
break;
}
if (p != NULL)
{
if (p->Password[0] != 0)
p1 = p;
else
{
for (p1 = m_host; p1 != NULL; p1 = p1->Next)
{
if (p1 != p && p->Address.S_un.S_addr == p1->Address.S_un.S_addr)
break;
}
if (p1 == NULL)
p1 = p;
}
SimplySendPack(s, (char *)p1->Password, sizeof(p1->Password));
FindInfo.flags = LVFI_PARAM;
FindInfo.lParam = (LPARAM)p;
int nItem = m_hWndList.FindItem(&FindInfo, -1);
if (nItem != -1)
{
m_hWndList.SetItemText(nItem, 3, "需要密码"); //记录控制连接状态
}
}
else
{
for (p = m_host; p != NULL; p = p->Next)
{
if (p->Address.S_un.S_addr == host.sin_addr.S_un.S_addr && p->Password[0] != 0)
break;
}
if (p != NULL)
SimplySendPack(s, (char *)p->Password, sizeof(p->Password));
else
SimplySendPack(s, "", 1); //无可用的密码
}
msg.Format("主机 %s 要求身份认证", inet_ntoa(host.sin_addr));
m_hWndStatusBar.SetWindowText(msg);
delete [] buf;
return;
case CONNECT_INVALID_PWD:
for (p = m_host; p != NULL; p = p->Next)
{
if (p->Sock == s)
{
p->Lock = LOCKED_STATUS_NEEDPWD;
break;
}
}
msg.Format("用于连接 %s 的密码错误", inet_ntoa(host.sin_addr));
m_hWndStatusBar.SetWindowText(msg);
delete [] buf;
return;
case CONTROL_QUERYINFO:
msg.Format("与 %s 建立通信", inet_ntoa(host.sin_addr));
m_hWndStatusBar.SetWindowText(msg);
break;
default:
msg.Format("与 %s 建立通信", inet_ntoa(host.sin_addr));
m_hWndStatusBar.SetWindowText(msg);
WSAAsyncSelect(s, m_hWnd, 0, 0);
CompleteRequest(s, *(ULONG *)buf);
delete [] buf;
return;
}
for (p = m_host; p != NULL; p = p->Next)
{
if (p->Sock == s)
break;
}
if (p == NULL)
return;
if (p->Lock == LOCKED_STATUS_NONE) //判断是否该处理收到的数据
return;
if (p->Lock == LOCKED_STATUS_QUERY)
{
//PNTSHELL_RESULTSET rs1 = (PNTSHELL_RESULTSET)buf;
//WriteHostInformation(&(p->Info), rs1->ResultSet);
WriteHostInformation(&(p->Info), buf + sizeof(ULONG));
}
FindInfo.flags = LVFI_PARAM;
FindInfo.lParam = (LPARAM)p;
int nItem = m_hWndList.FindItem(&FindInfo, -1);
if (nItem != -1)
{
char *pHostName = "";
if (p->Info->OffsetOfComputerName != 0)
{
pHostName = (char *)(p->Info) + p->Info->OffsetOfComputerName;
}
m_hWndList.SetItemText(nItem, 1, pHostName); //记录主机名
if (p->Info->ServerVersion != NTSHELL_VERSION)
m_hWndList.SetItemText(nItem, 3, "版本不支持"); //记录控制连接状态
else
{
if (p->Type == 0)
m_hWndList.SetItemText(nItem, 3, "就绪"); //记录控制连接状态
else
m_hWndList.SetItemText(nItem, 3, "静态主机");
}
if (p->Info->OffsetOfSystemName != 0)
SetDlgItemText(IDC_SYSTEMNAME, (char *)(p->Info) + p->Info->OffsetOfSystemName);
if (p->Info->OffsetOfMemorySize != 0)
SetDlgItemText(IDC_PHYSMEMORYSIZE, (char *)(p->Info) + p->Info->OffsetOfMemorySize);
if (p->Info->OffsetOfProcessorName != 0)
SetDlgItemText(IDC_PROCESSORNAME, (char *)(p->Info) + p->Info->OffsetOfProcessorName);
if (p->Info->OffsetOfCurrentUserName != 0)
SetDlgItemText(IDC_CURRENTUSER, (char *)(p->Info) + p->Info->OffsetOfCurrentUserName);
if (p->Info->OffsetOfRootDirectory != 0)
SetDlgItemText(IDC_SYSTEMROOT, (char *)(p->Info) + p->Info->OffsetOfRootDirectory);
}
if (p->Info->ServerVersion != NTSHELL_VERSION)
p->Lock = LOCKED_STATUS_NONSUPPORT;
else
p->Lock = LOCKED_STATUS_NONE;
delete [] buf;
}
void CMainDlg::WriteHostInformation(PHOST_INFORMATION *info, PVOID infoArray)
{
POSVERSIONINFOEX posvi;
int buflen = 0x1000, pointer = sizeof(HOST_INFORMATION);
char *buf = new char[buflen];
PQUERY_RESULTSET rs = (PQUERY_RESULTSET)infoArray;
if (buf == NULL)
return;
*info = (PHOST_INFORMATION)buf;
ZeroMemory(*info, sizeof(HOST_INFORMATION));
for (;;)
{
switch (rs->InformationClass)
{
case QUERY_PROCESSORNAME:
(*info)->OffsetOfProcessorName = pointer;
{
char *p = (char *)(rs->Information);
for (int i = 0; i < rs->InformationLength && *p == ' '; i++, p++);
memcpy(buf + pointer, p, rs->InformationLength - i);
pointer += rs->InformationLength - i;
}
break;
case QUERY_PROCESSORMHZ:
(*info)->OffsetOfProcessorMHZ = pointer;
memcpy(buf + pointer, rs->Information, rs->InformationLength);
pointer += rs->InformationLength;
break;
case QUERY_PHYSMEMORYSIZE:
(*info)->OffsetOfMemorySize = pointer;
wsprintf(buf + pointer, "%dK", *((DWORD *)(rs->Information)) / 1024);
pointer += strlen(buf + pointer) + 1;
break;
case QUERY_SYSTEMVERSION:
(*info)->OffsetOfSystemName = pointer;
posvi = (POSVERSIONINFOEX)(rs->Information);
switch (posvi->dwBuildNumber)
{
case 2195:
strcpy(buf + pointer, "Windows 2000");
break;
case 2600:
strcpy(buf + pointer, "Windows XP");
break;
case 3790:
strcpy(buf + pointer, "Windows 2003");
break;
default:
strcpy(buf + pointer, "Unknow");
break;
}
pointer += strlen(buf + pointer) + 1;
break;
case QUERY_COMPUTERNAME:
(*info)->OffsetOfComputerName = pointer;
memcpy(buf + pointer, rs->Information, rs->InformationLength);
pointer += rs->InformationLength;
break;
case QUERY_CURRENTUSERNAME:
(*info)->OffsetOfCurrentUserName = pointer;
memcpy(buf + pointer, rs->Information, rs->InformationLength);
pointer += rs->InformationLength;
break;
case QUERY_SYSTEMROOT:
(*info)->OffsetOfRootDirectory = pointer;
memcpy(buf + pointer, rs->Information, rs->InformationLength);
pointer += rs->InformationLength;
break;
case QUERY_NTSHELLVERSION:
(*info)->ServerVersion = *(WORD *)(rs->Information);
break;
case QUERY_ENDQUERY:
default:
return;
}
rs = (PQUERY_RESULTSET)((char *)rs + sizeof(QUERY_RESULTSET) + rs->InformationLength);
}
}
bool CMainDlg::TestLockedStatus(int lock)
{
if (lock == LOCKED_STATUS_NONSUPPORT)
{
MessageBox("服务端版本不支持,请点击[升级服务端]进行升级", "错误", MB_ICONERROR);
return false;
}
if (lock == LOCKED_STATUS_NEEDPWD)
{
BOOL bHandled = FALSE;
OnSetPassword(0, 0, NULL, bHandled);
return false;
}
if (lock != LOCKED_STATUS_NONE)
{
MessageBox("控制端口占用中,请稍候……", "错误", MB_ICONERROR);
return false;
}
return true;
}
LRESULT CMainDlg::OnOK(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nItem = m_hWndList.GetSelectedIndex();
if (nItem == -1)
{
MessageBox("选择要连接的主机", "提示", MB_ICONINFORMATION);
return 0;
}
PHOST_LIST_LINK p = (PHOST_LIST_LINK)m_hWndList.GetItemData(nItem);
if (TestLockedStatus(p->Lock) == false)
return 0;
PWND_INIT_PARAM pwip = new WND_INIT_PARAM;
pwip->lpCtrlHandle = p;
pwip->hConnMgrWnd = m_hWnd;
PostThreadMessage(_Module.m_dwMainThreadID, WM_USER, 0, (LPARAM)pwip);
return 0;
}
LRESULT CMainDlg::OnCancel(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CloseDialog(wID);
return 0;
}
LRESULT CMainDlg::OnAddHost(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CInputDlg dlg;
TCHAR ip[INPUT_BUFFER_SIZE];
USHORT port = 24704;
static TCHAR szLastAddHost[INPUT_BUFFER_SIZE] = "127.0.0.1:24704";
if (dlg.DoModal(m_hWnd, (LPARAM)szLastAddHost) == TRUE)
{
strcpy(ip, szLastAddHost);
char *p = strchr(ip, ':');
if (p != NULL)
{
*p = '\0';
port = atoi(p + 1);
}
AddHost(ip, port);
}
return 0;
}
LRESULT CMainDlg::OnSetPassword(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nItem = m_hWndList.GetSelectedIndex();
if (nItem == -1)
{
MessageBox("选择要[设置密码]的主机", "提示", MB_ICONINFORMATION);
return 0;
}
CInputDlg dlg;
TCHAR pwd[INPUT_BUFFER_SIZE] = "";
if (dlg.DoModal(m_hWnd, (LPARAM)pwd) == FALSE)
return 0;
PHOST_LIST_LINK p = (PHOST_LIST_LINK)m_hWndList.GetItemData(nItem);
memset(p->Password, 0, sizeof(p->Password));
MD5_CTX context;
MD5Init(&context);
MD5Update(&context, (BYTE *)pwd, strlen(pwd));
MD5Final((BYTE *)p->Password, &context);
p->Password[0] = 86;
p->Password[4] = 29;
p->Password[8] = 91;
if (p->Type == 1 && p->Sock == INVALID_SOCKET)
ConnectSlave(p->Address, p->Port, 1);
else
{
int temp = CONTROL_QUERYINFO;
SimplySendPack(p->Sock, (char *)&temp, sizeof(temp));
p->Lock = LOCKED_STATUS_QUERY;
}
return 0;
}
LRESULT CMainDlg::OnExitService(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nItem = m_hWndList.GetSelectedIndex();
if (nItem == -1)
{
MessageBox("选择要[关闭服务端]的主机", "提示", MB_ICONINFORMATION);
return 0;
}
PHOST_LIST_LINK p = (PHOST_LIST_LINK)m_hWndList.GetItemData(nItem);
if (TestLockedStatus(p->Lock) == false)
return 0;
CString msg, str = "";
if (p->Info->OffsetOfComputerName != 0)
str.Format(" (%s)", (char *)(p->Info) + p->Info->OffsetOfComputerName);
msg.Format("确定要关闭主机 %s%s 的服务端吗?", inet_ntoa(p->Address), str);
if (MessageBox(msg, "警告", MB_ICONWARNING | MB_YESNO) != IDYES)
return 0;
if (p->Type == 1 && p->Sock == INVALID_SOCKET)
{
REQUEST_CONNECT rc;
rc.dwWorkType = CONTROL_EXIT;
rc.funBack = CloseContrlSock;
rc.lpParam = NULL;
rc.hAcceptWnd = NULL;
rc.lpCtrlHandle = p;
SendMessage(WM_REQUEST_CONNECT, 0, (LPARAM)&rc);
}
else
{
int temp = CONTROL_EXIT;
SimplySendPack(p->Sock, (char *)&temp, sizeof(temp));
}
return 0;
}
LRESULT CMainDlg::OnShutdown(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nItem = m_hWndList.GetSelectedIndex();
if (nItem == -1)
{
MessageBox("选择要[关闭]的主机", "提示", MB_ICONINFORMATION);
return 0;
}
PHOST_LIST_LINK p = (PHOST_LIST_LINK)m_hWndList.GetItemData(nItem);
if (TestLockedStatus(p->Lock) == false)
return 0;
CString msg, str = "";
if (p->Info->OffsetOfComputerName != 0)
str.Format(" (%s)", (char *)(p->Info) + p->Info->OffsetOfComputerName);
msg.Format("确定要[关闭]主机 %s%s ?", inet_ntoa(p->Address), str);
if (MessageBox(msg, "警告", MB_ICONWARNING | MB_YESNO) != IDYES)
return 0;
if (p->Type == 1 && p->Sock == INVALID_SOCKET)
{
REQUEST_CONNECT rc;
rc.dwWorkType = CONTROL_SHUTDOWN;
rc.funBack = CloseContrlSock;
rc.lpParam = NULL;
rc.hAcceptWnd = NULL;
rc.lpCtrlHandle = p;
SendMessage(WM_REQUEST_CONNECT, 0, (LPARAM)&rc);
}
else
{
int temp = CONTROL_SHUTDOWN;
SimplySendPack(p->Sock, (char *)&temp, sizeof(temp));
}
return 0;
}
LRESULT CMainDlg::OnReboot(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nItem = m_hWndList.GetSelectedIndex();
if (nItem == -1)
{
MessageBox("选择要[重启]的主机", "提示", MB_ICONINFORMATION);
return 0;
}
PHOST_LIST_LINK p = (PHOST_LIST_LINK)m_hWndList.GetItemData(nItem);
if (TestLockedStatus(p->Lock) == false)
return 0;
CString msg, str = "";
if (p->Info->OffsetOfComputerName != 0)
str.Format(" (%s)", (char *)(p->Info) + p->Info->OffsetOfComputerName);
msg.Format("确定要[重启]主机 %s%s ?", inet_ntoa(p->Address), str);
if (MessageBox(msg, "警告", MB_ICONWARNING | MB_YESNO) != IDYES)
return 0;
if (p->Type == 1 && p->Sock == INVALID_SOCKET)
{
REQUEST_CONNECT rc;
rc.dwWorkType = CONTROL_REBOOT;
rc.funBack = CloseContrlSock;
rc.lpParam = NULL;
rc.hAcceptWnd = NULL;
rc.lpCtrlHandle = p;
SendMessage(WM_REQUEST_CONNECT, 0, (LPARAM)&rc);
}
else
{
int temp = CONTROL_REBOOT;
SimplySendPack(p->Sock, (char *)&temp, sizeof(temp));
}
return 0;
}
LRESULT CMainDlg::OnUpdate(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nItem = m_hWndList.GetSelectedIndex();
if (nItem == -1)
{
MessageBox("选择要[更新服务端]的主机", "提示", MB_ICONINFORMATION);
return 0;
}
PHOST_LIST_LINK p = (PHOST_LIST_LINK)m_hWndList.GetItemData(nItem);
if (TestLockedStatus(p->Lock) == false)
return 0;
MessageBox("这个功能还没做好呢!", "提示", MB_ICONINFORMATION);
return 0;
}
LRESULT CMainDlg::OnUninstall(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
int nItem = m_hWndList.GetSelectedIndex();
if (nItem == -1)
{
MessageBox("选择要[卸载服务端]的主机", "提示", MB_ICONINFORMATION);
return 0;
}
PHOST_LIST_LINK p = (PHOST_LIST_LINK)m_hWndList.GetItemData(nItem);
if (TestLockedStatus(p->Lock) == false)
return 0;
MessageBox("不要乱点呀!", "提示", MB_ICONINFORMATION);
return 0;
}
LRESULT CMainDlg::OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CAboutDlg dlg;
dlg.DoModal();
return 0;
}
LRESULT CMainDlg::OnServerConfig(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CServerConfig dlg;
dlg.DoModal();
return 0;
}
LRESULT CMainDlg::OnLocalConfig(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
CLocalConfig dlg;
dlg.DoModal();
return 0;
}
void CMainDlg::CloseDialog(int nVal)
{
DestroyWindow();
::PostQuitMessage(nVal);
while (m_host != NULL)
{
PHOST_LIST_LINK p = m_host;
m_host = m_host->Next;
if (p->Sock != INVALID_SOCKET)
closesocket(p->Sock);
if (p->Info != NULL)
delete [] p->Info;
delete p;
}
}
LRESULT CMainDlg::OnHostList(int /*wParam*/, LPNMHDR pNMHDR, BOOL& /*bHandled*/)
{
NMLISTVIEW *pNMListView = (NMLISTVIEW *)pNMHDR;
PHOST_LIST_LINK p;
int nItem = pNMListView->iItem;
switch (pNMHDR->code)
{
case NM_DBLCLK:
if (nItem >= 0 && nItem < m_hWndList.GetItemCount())
{
p = (PHOST_LIST_LINK)m_hWndList.GetItemData(nItem);
if (TestLockedStatus(p->Lock) == false)
break;
PWND_INIT_PARAM pwip = new WND_INIT_PARAM;
pwip->lpCtrlHandle = p;
pwip->hConnMgrWnd = m_hWnd;
PostThreadMessage(_Module.m_dwMainThreadID, WM_USER, 0, (LPARAM)pwip);
}
break;
case LVN_ITEMCHANGED:
if (nItem == -1)
{
SetDlgItemText(IDC_SYSTEMNAME, "n/a");
SetDlgItemText(IDC_PHYSMEMORYSIZE, "n/a");
SetDlgItemText(IDC_PROCESSORNAME, "n/a");
SetDlgItemText(IDC_CURRENTUSER, "n/a");
SetDlgItemText(IDC_SYSTEMROOT, "n/a");
}
else
{
p = (PHOST_LIST_LINK)m_hWndList.GetItemData(nItem);
if (p->Info != NULL)
{
if (p->Info->OffsetOfSystemName != 0)
SetDlgItemText(IDC_SYSTEMNAME, (char *)(p->Info) + p->Info->OffsetOfSystemName);
if (p->Info->OffsetOfMemorySize != 0)
SetDlgItemText(IDC_PHYSMEMORYSIZE, (char *)(p->Info) + p->Info->OffsetOfMemorySize);
if (p->Info->OffsetOfProcessorName != 0)
SetDlgItemText(IDC_PROCESSORNAME, (char *)(p->Info) + p->Info->OffsetOfProcessorName);
if (p->Info->OffsetOfCurrentUserName != 0)
SetDlgItemText(IDC_CURRENTUSER, (char *)(p->Info) + p->Info->OffsetOfCurrentUserName);
if (p->Info->OffsetOfRootDirectory != 0)
SetDlgItemText(IDC_SYSTEMROOT, (char *)(p->Info) + p->Info->OffsetOfRootDirectory);
}
else
{
SetDlgItemText(IDC_SYSTEMNAME, "n/a");
SetDlgItemText(IDC_PHYSMEMORYSIZE, "n/a");
SetDlgItemText(IDC_PROCESSORNAME, "n/a");
SetDlgItemText(IDC_CURRENTUSER, "n/a");
SetDlgItemText(IDC_SYSTEMROOT, "n/a");
}
}
break;
}
return 0;
}
bool CMainDlg::OpenListenSock()
{
m_ListenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_ListenSock == INVALID_SOCKET)
{
MessageBox("socket() failed");
return false;
}
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(LocalListenPort);
local.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(m_ListenSock, (SOCKADDR *)&local, sizeof(local)) == SOCKET_ERROR)
{
m_hWndStatusBar.SetWindowText("bind() failed");
closesocket(m_ListenSock);
return false;
}
if (listen(m_ListenSock, MAX_CONNECT) == SOCKET_ERROR) //最大连接数量
{
m_hWndStatusBar.SetWindowText("listen() failed");
closesocket(m_ListenSock);
return false;
}
if (WSAAsyncSelect(m_ListenSock, m_hWnd, WM_SOCKET_CONN, FD_ACCEPT) == SOCKET_ERROR)
{
m_hWndStatusBar.SetWindowText("WSAAsyncSelect() failed");
closesocket(m_ListenSock);
return false;
}
CString text;
text.Format("开始监听端口 %d", LocalListenPort);
m_hWndStatusBar.SetWindowText(text);
return true;
}
void CMainDlg::AddHost(SOCKET s, CHAR HostType)
{
struct sockaddr_in host;
int iAddrSize = sizeof(host);
CString message;
PHOST_LIST_LINK p = NULL;
getpeername(s, (struct sockaddr *)&host, &iAddrSize);
if (HostType == 1)
{
for (p = m_host; p != NULL; p = p->Next)
{
if (p->Address.S_un.S_addr == host.sin_addr.S_un.S_addr && p->Type == 1) //静态主机不重复添加
break;
}
}
if (p == NULL)
{
p = new HOST_LIST_LINK;
if (p == NULL)
{
closesocket(s);
return;
}
p->Sock = INVALID_SOCKET;
p->Address = host.sin_addr;
p->Port = host.sin_port;
p->CreateTime = GetTickCount();
p->Sid = m_nSessionTotal++;
p->Lock = LOCKED_STATUS_NONE;
p->Type = HostType; //被动连接为0,主动连接为1
p->Info = NULL;
p->Password[0] = 0;
p->Next = m_host; //放入主机链表中
m_host = p;
int nItem = m_hWndList.GetItemCount();
m_hWndList.InsertItem(LVIF_TEXT | LVIF_PARAM, nItem, inet_ntoa(host.sin_addr), 0, 0, 0, (LPARAM)p);
SYSTEMTIME stime;
GetLocalTime(&stime);
message.Format("%02d:%02d:%02d", stime.wHour, stime.wMinute, stime.wSecond);
m_hWndList.SetItemText(nItem, 2, message); //记录连上时间
m_hWndList.SetItemText(nItem, 3, "读取信息中"); //记录控制连接状态
}
if (p->Sock != INVALID_SOCKET)
closesocket(p->Sock);
p->Sock = s;
WSAAsyncSelect(s, m_hWnd, WM_SOCKET_CTRL, FD_READ | FD_CLOSE); //与被控端进入通信状态
int temp = CONTROL_QUERYINFO;
SimplySendPack(s, (char *)&temp, sizeof(temp));
p->Lock = LOCKED_STATUS_QUERY;
}
void CMainDlg::AddHost(char *host, int port)
{
struct in_addr address;
struct hostent *host1;
address.S_un.S_addr = inet_addr(host);
if (address.S_un.S_addr == INADDR_NONE)
{
host1 = gethostbyname(host); //解析主机域名
if (host1 == NULL)
{
return;
}
else
{
address.S_un.S_addr = *(DWORD *)(host1->h_addr_list[0]);
}
}
SOCKET s = ConnectSlave(address, htons(port), 1);
}
void CMainDlg::RemoveHost(SOCKET s)
{
PHOST_LIST_LINK *pp = &m_host;
while (*pp != NULL)
{
if ((*pp)->Sock == s) //取出主机记录
break;
pp = &(*pp)->Next;
}
if (*pp == NULL)
{
closesocket(s);
return;
}
if ((*pp)->Type == 1) //忽略静态主机
{
if ((*pp)->Sock != INVALID_SOCKET)
closesocket((*pp)->Sock);
(*pp)->Sock = INVALID_SOCKET;
return;
}
LV_FINDINFO FindInfo;
FindInfo.flags = LVFI_PARAM;
FindInfo.lParam = (LPARAM)*pp;
int nItem = m_hWndList.FindItem(&FindInfo, -1);
if (nItem != -1)
{
m_hWndList.DeleteItem(nItem); //从列表控件中移除
CString message;
message.Format("远程主机 %s 关闭了现有的控制连接", inet_ntoa((*pp)->Address));
m_hWndStatusBar.SetWindowText(message);
}
closesocket((*pp)->Sock);
PHOST_LIST_LINK p = *pp;
*pp = (*pp)->Next; //从主机链表中移除
if (p->Info != NULL)
delete [] p->Info;
delete p;
}
LRESULT CMainDlg::OnRequestConnect(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
PREQUEST_CONNECT prc = (PREQUEST_CONNECT)lParam;
PHOST_LIST_LINK p = (PHOST_LIST_LINK)prc->lpCtrlHandle;
if (m_nWaiting >= sizeof(connmgr) / sizeof(CONNECT_SOCK_MGR))
{
::PostMessage(prc->hAcceptWnd, WM_CONNECT_TIMEOUT, INVALID_SOCKET, (LPARAM)prc->lpParam);
return 0;
}
//添加一个连接请求到连接等待列表中
connmgr[m_nWaiting].hAcceptWnd = prc->hAcceptWnd;
connmgr[m_nWaiting].funBack = prc->funBack;
connmgr[m_nWaiting].lpParam = prc->lpParam;
connmgr[m_nWaiting].bRequestSended = FALSE;
connmgr[m_nWaiting].dwWorkType = prc->dwWorkType;
connmgr[m_nWaiting].dwHost = p->Address.S_un.S_addr;
connmgr[m_nWaiting++].dwReqTime = GetTickCount();
if (p->Type == 0)
{
DWORD temp = CONTROL_NEWCONNECT; //要求被控端创建一个新的连接
SimplySendPack(p->Sock, (char *)&temp, sizeof(temp));
}
else
{
ConnectSlave(p->Address, p->Port, 2);
}
return 0;
}
LRESULT CMainDlg::OnCancelRequest(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
PREQUEST_CONNECT prc = (PREQUEST_CONNECT)lParam;
for (int i = 0; i < m_nWaiting; i++)
{
if (connmgr[i].dwHost == ((PHOST_LIST_LINK)prc->lpCtrlHandle)->Address.S_un.S_addr)
{
connmgr[i] = connmgr[--m_nWaiting];
return 0;
}
}
return 0;
}
void CMainDlg::SendRequest(SOCKET s)
{
struct sockaddr_in host;
int iAddrSize = sizeof(host);
getpeername(s, (struct sockaddr *)&host, &iAddrSize);
for (int i = 0; i < m_nWaiting; i++)
{
//取出一个未发送的请求
if (connmgr[i].dwHost == host.sin_addr.S_un.S_addr && connmgr[i].bRequestSended == FALSE)
{
connmgr[i].bRequestSended = TRUE;
SimplySendPack(s, (char *)&connmgr[i].dwWorkType, sizeof(connmgr[i].dwWorkType));
return;
}
}
closesocket(s);
}
void CMainDlg::CompleteRequest(SOCKET s, DWORD work)
{
struct sockaddr_in host;
int iAddrSize = sizeof(host);
int xhost = -1;
getpeername(s, (struct sockaddr *)&host, &iAddrSize);
for (int i = 0; i < m_nWaiting; i++)
{
if (connmgr[i].dwHost == host.sin_addr.S_un.S_addr && connmgr[i].dwWorkType == work)
{
if (connmgr[i].bRequestSended == TRUE)
{
if (connmgr[i].funBack != NULL)
{
connmgr[i].funBack(s, connmgr[i].lpParam);
connmgr[i] = connmgr[--m_nWaiting];
return;
}
else if (::IsWindow(connmgr[i].hAcceptWnd))
{
::PostMessage(connmgr[i].hAcceptWnd, WM_CONNECT_COMPLETE, s, (LPARAM)connmgr[i].lpParam);
connmgr[i] = connmgr[--m_nWaiting];
return;
}
else
{
//无法返回结果给调用者
connmgr[i] = connmgr[--m_nWaiting];
closesocket(s);
return;
}
}
else
{
if (xhost == -1)
xhost = i;
}
}
}
if (xhost != -1)
{
if (connmgr[xhost].funBack != NULL)
{
connmgr[xhost].funBack(s, connmgr[xhost].lpParam);
connmgr[xhost] = connmgr[--m_nWaiting];
return;
}
else if (::IsWindow(connmgr[xhost].hAcceptWnd))
{
::PostMessage(connmgr[xhost].hAcceptWnd, WM_CONNECT_COMPLETE, s, (LPARAM)connmgr[xhost].lpParam);
connmgr[xhost] = connmgr[--m_nWaiting];
return;
}
else
{
//无法返回结果给调用者
connmgr[xhost] = connmgr[--m_nWaiting];
closesocket(s);
return;
}
}
//连接主机无等待记录,丢弃该连接
closesocket(s);
}
void CMainDlg::CloseContrlSock(SOCKET s, LPVOID lpParam)
{
closesocket(s);
}
void CMainDlg::UpdateHostInfo(SOCKET s)
{
PHOST_LIST_LINK p = NULL;
for (p = m_host; p != NULL; p = p->Next)
{
if (p->Type == 1) //更新静态主机信息
{
if (p->Sock == INVALID_SOCKET)
ConnectSlave(p->Address, p->Port, 1);
else
AddHost(p->Sock, 1);
}
}
}
SOCKET CMainDlg::ConnectSlave(struct in_addr address, int port, int type)
{
struct sockaddr_in slave;
long temp, ret;
SOCKET slave_sock;
slave.sin_family = AF_INET;
slave.sin_port = port;
slave.sin_addr = address;
slave_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (slave_sock == INVALID_SOCKET)
return INVALID_SOCKET;
if (connect(slave_sock, (struct sockaddr *)&slave, sizeof(slave)) == SOCKET_ERROR)
{
closesocket(slave_sock);
return INVALID_SOCKET;
}
CString message;
message.Format("连接到主机 %s", inet_ntoa(slave.sin_addr));
m_hWndStatusBar.SetWindowText(message);
if (type == 1)
temp = CONN3_MASTER_ANSWER;
else
temp = CONN4_MASTER_ANSWER;
ret = send(slave_sock, (char *)&temp, sizeof(temp), 0);
if (ret != sizeof(temp))
{
closesocket(slave_sock);
return INVALID_SOCKET;
}
WSAAsyncSelect(slave_sock, this->m_hWnd, WM_SOCKET_CONN, FD_READ | FD_WRITE | FD_CLOSE);
// ret = recv(slave_sock, (char *)&temp, sizeof(temp), 0);
// if (ret != sizeof(temp) || temp != CONN3_SLAVE_OK)
// {
// closesocket(slave_sock);
// return INVALID_SOCKET;
// }
return slave_sock;
}
char *CMainDlg::SimplyRecvPack(SOCKET s)
{
PACK_TYPE_1 pack;
int ret = recv(s, (char *)&pack, sizeof(PACK_TYPE_1), MSG_PEEK); //读取包头部
if (ret != sizeof(PACK_TYPE_1))
return NULL;
if (pack.dwPackType != 0)
return NULL;
char *buf = new char[sizeof(PACK_TYPE_1) + pack.nPackSize];
if (buf == NULL)
return NULL;
ret = recv(s, buf, sizeof(PACK_TYPE_1) + pack.nPackSize, MSG_PEEK); //尝试读取全部数据
if (ret != (int)(sizeof(PACK_TYPE_1) + pack.nPackSize))
{
delete [] buf;
return NULL;
}
ret = recv(s, (char *)&pack, sizeof(PACK_TYPE_1), 0);
ret = recv(s, buf, pack.nPackSize, 0); //等待数据包全部到达系统缓冲区再读取
return buf;
}
void CMainDlg::SimplySendPack(SOCKET s, char *p, int l)
{
PPACK_TYPE_1 pack = (PPACK_TYPE_1)new char[sizeof(PACK_TYPE_1) + l];
pack->dwPackType = 0;
pack->nPackSize = l;
memcpy(pack->bPackData, p, l);
send(s, (char *)pack, sizeof(PACK_TYPE_1) + l, 0);
delete [] pack;
}