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; 
}