#include "Net.h"
#include "Netman.h"
#include "Queue.h"
#include "resource.h"
#include <windowsx.h>
#include "Helpers.h"
#include <shlwapi.h>
struct COLUMN{
int width;
LPTSTR caption;
} cols[]={ {190, TEXT("Resource")},
{50, TEXT("Count")},
{90, TEXT("State")},
{90, TEXT("IP Address")}
};
BOOL CALLBACK NetmanCalcRect(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK NetmanNotify(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK NetmanCmd(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK NetmanCtxMnu(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK NetmanNet(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK TreeListProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int HDHEIGHT = 17; //16
extern Queue *queue;
Network *domains;
DirectScan *ip_scan;
Dialog *netman;
HMENU mnuNet,
mnuTree, mnuList;
HIMAGELIST himl;
void SoundNotify(int id)
{
if (!netman->BtnGetCheck(IDC_CHK_NOSOUND)) {
PlaySound(MAKEINTRESOURCE(id), GetHinstance, SND_RESOURCE | SND_ASYNC);
}
}
Dialog* CreateNetManager(RegKey& root)
{
EVENT_HANDLER
netevent[] = {
{WM_NOTIFY, NetmanNotify},
{WM_COMMAND, NetmanCmd},
{WM_CONTEXTMENU, NetmanCtxMnu},
{MSG_NETNOTIFY, NetmanNet},
{0,NULL}};
// Network initialize
netman = new Dialog(IDD_NETLIST,netevent);
if (netman->Handle()) {
// main window initialization
netman->SetIconFromRes(IDI_NET);
netman->resizer.SetHorz(netman->GetItem(IDC_BTN_STARTENUM), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_BTN_STOPENUM), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_CHK_AUTO), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_STAT_THREADS), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_ED_THREADS), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_SPIN_THREADS), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_STAT_SIZEMIN), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_ED_SIZEMIN), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_SPIN_SIZEMIN), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_STAT_SIZEMAX), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_ED_SIZEMAX), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_SPIN_SIZEMAX), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_IP_FROM), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_IP_TO), ANCHOR_RIGHT);
netman->resizer.SetHorz(netman->GetItem(IDC_HEADER), ANCHOR_BOTH);
netman->resizer.SetBoth(netman->GetItem(IDC_TREE_NET), ANCHOR_BOTH, ANCHOR_TOP, true);
netman->resizer.SetBoth(netman->GetItem(IDC_FOUND), ANCHOR_BOTH, ANCHOR_BOTH, true);
// threads
RegValue regval = root.GetValue(TEXT_OPT_THREADLIMIT);
if (regval.Type == REG_NONE) regval.v.dword = 100;
netman->SpinSetRange(IDC_SPIN_THREADS, 1, 500);
netman->SpinSetValue(IDC_SPIN_THREADS, regval.v.dword);
netman->SpinSetRange(IDC_SPIN_SIZEMIN, 0, 999);
netman->SpinSetRange(IDC_SPIN_SIZEMAX, 0, 999);
HWND hcc = netman->GetItem(IDC_TREE_NET);
RECT rc;
// calculate placement for header
GetClientRect(hcc,&rc);
MapWindowPoints(hcc, netman->Handle(), (LPPOINT)&rc, 2);
himl = ImageList_LoadImage(GetHinstance,MAKEINTRESOURCE(IDB_NETWORK),16, 6,CLR_DEFAULT , IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_LOADTRANSPARENT | LR_SHARED);
TreeView_SetImageList(hcc, himl, TVSIL_NORMAL);
//CreateNetworkRoot;
domains = new Network(hcc);
domains->LoadAsync(NULL);
ip_scan = new DirectScan(hcc);
IN_ADDR from, to;
to.S_un.S_un_b.s_b1 = from.S_un.S_un_b.s_b1 = 132;
to.S_un.S_un_b.s_b2 = from.S_un.S_un_b.s_b2 = 69;
from.S_un.S_un_b.s_b3 = 200;
from.S_un.S_un_b.s_b4 = 1;
to.S_un.S_un_b.s_b3 = 255;
to.S_un.S_un_b.s_b4 = 255;
regval = root.GetValue(TEXT_OPT_RANGE_START);
if (regval.Type == REG_DWORD) from.S_un.S_addr = regval.v.dword;
regval = root.GetValue(TEXT_OPT_RANGE_END);
if (regval.Type == REG_DWORD) to.S_un.S_addr = regval.v.dword;
netman->IP_SetValue(IDC_IP_FROM, REMAKE_IPADDRESS(from.S_un.S_addr));
netman->IP_SetValue(IDC_IP_TO, REMAKE_IPADDRESS(to.S_un.S_addr));
ip_scan->SetScanRange(from, to);
// subclass TreeView and force to recalculate it's client area
DLLVERSIONINFO shver={sizeof(shver)};
DLLGETVERSIONPROC ShellVersion = (DLLGETVERSIONPROC)GetProcAddress(GetModuleHandle(TEXT("Shell32.dll")),"DllGetVersion");
if (ShellVersion) {
ShellVersion(&shver);
if (shver.dwMajorVersion >= 5) HDHEIGHT = HDHEIGHT * 2;
}
netman->SubclassItem(IDC_TREE_NET, TreeListProc);
SetWindowPos(hcc, NULL, 0,0,0,0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
// Place header at calculated place
hcc = netman->GetItem(IDC_HEADER);
SetWindowPos(hcc, HWND_TOP, rc.left, rc.top, rc.right-rc.left, HDHEIGHT, SWP_FRAMECHANGED);
// Insert columns
HDITEM hi={HDI_WIDTH | HDI_FORMAT | HDI_TEXT | HDI_FILTER};
int idx, res;
NMHEADER nmh;
for (idx=0; idx<4; idx++) {
hi.fmt = HDF_STRING | ((idx==1)?HDF_RIGHT:HDF_LEFT);
hi.type = HDFT_HASNOVALUE;
hi.cxy = cols[idx].width;
hi.pszText = cols[idx].caption;
hi.cchTextMax = StrLen(hi.pszText);
res = Header_InsertItem(hcc, idx, &hi);
}
// init ColDefs by sending WM_NOTIFY (HDN_ITEMCHANGE)
nmh.hdr.hwndFrom = hcc;
nmh.hdr.code = HDN_ITEMCHANGED;
SendMessage(netman->Handle(), WM_NOTIFY, IDC_HEADER,(LPARAM) &nmh);
// Load context menus for tree and list
mnuNet = LoadMenu(GetHinstance, MAKEINTRESOURCE(IDR_MENU_NET));
mnuTree = GetSubMenu(mnuNet, 0);
mnuList = GetSubMenu(mnuNet, 1);
}
// Init WINSOCK 2.0
WSADATA wsaData;
WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
//
InitializeCriticalSection(&secLogin);
return netman;
}
void DestroyNetManager(bool terminate)
{
domains->Save(NULL);
DestroyMenu(mnuNet);
netman->SubclassItem(IDC_TREE_NET, NULL);
ShowWindow(netman->Handle(), SW_HIDE);
if (terminate) {
domains->Stop(5000, true);
ip_scan->Stop(1000, true);
}
WSACleanup();
DeletePtr(domains);
DeletePtr(ip_scan);
DeletePtr(netman);
ImageList_Destroy(himl);
CloseHandle(semThreadLimit);
DeleteCriticalSection(&secLogin);
}
void DispFoundRecursive(HWND hList, CWorker* obj)
{
int i;
if (obj->GetType()==NRT_SHARE) {
LPCTSTR str;
for(i = 0 ; (str = (*(Share*)obj)[i]) != NULL; i++) {
SendMessage(hList, LB_ADDSTRING, 0,(LPARAM)str);
}
} else {
CWorker *child;
for(i = 0 ; (child = (*obj)[i]) != NULL; i++) {
DispFoundRecursive(hList, child);
}
}
}
// Callback on TreeView item selection
void ItemSelected(CWorker* obj)
{
HWND hList = netman->GetItem(IDC_FOUND);
SendMessage(hList, LB_RESETCONTENT, 0, 0);
DispFoundRecursive(hList,obj);
}
// All TreeView messages
LRESULT CALLBACK TreeListProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WNDPROC proc = (WNDPROC) GetWindowLong(hwnd, GWL_USERDATA);
if (proc) {
if (uMsg == WM_NCCALCSIZE) {
LPNCCALCSIZE_PARAMS cc = (LPNCCALCSIZE_PARAMS)lParam;
LRESULT r = CallWindowProc(proc, hwnd, uMsg, wParam, lParam);
cc->rgrc[0].top += HDHEIGHT;
//cc->rgrc[0].left += 3;
//cc->rgrc[0].right -=19;
//cc->rgrc[0].bottom -= 3;
return r;
}
return CallWindowProc(proc, hwnd, uMsg, wParam, lParam);
}
return 0; //DefWindowProc(hwnd, uMsg, wParam, lParam);
}
// WM_NOTIFY
BOOL CALLBACK NetmanNotify(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT cdres = 0;
switch (wParam) {
case IDC_HEADER:
case IDC_TREE_NET:
if (domains) {
cdres = domains->OnNotifyMsg(hwndDlg,uMsg, wParam, lParam, ItemSelected);
SetWindowLong(hwndDlg, DWL_MSGRESULT, cdres);
}
break;
case IDC_IP_TO:
case IDC_IP_FROM:
if (((LPNMIPADDRESS) lParam)->hdr.code == IPN_FIELDCHANGED) {
IN_ADDR ip_from, ip_to;
ip_from.S_un.S_addr = netman->IP_GetValue(IDC_IP_FROM, true);
ip_to.S_un.S_addr = netman->IP_GetValue(IDC_IP_TO, true);
ip_scan->SetScanRange(ip_from, ip_to);
}
break;
}
return (cdres!=0);
}
DWORD WINAPI AsyncExec(void * command )
{
OutputDebugString(TEXT("AsynExec issued...\n"));
OutputDebugString((LPCTSTR)command);
ShellExecute(netman->Handle(), NULL, (LPCTSTR)command, NULL, TEXT("."), SW_SHOW);
delete command;
OutputDebugString(TEXT("\nAsynExec finished\n"));
return 0;
}
BOOL GetListText(LPTSTR &text)
{
HWND hList = netman->GetItem(IDC_FOUND);
int idx = ListBox_GetCurSel(hList);
if (idx != LB_ERR) {
if (text==NULL) text = new TCHAR[ListBox_GetTextLen(hList, idx)+1];
if (text) {
ListBox_GetText(hList, idx, text);
return true;
}
}
return false;
}
BOOL NetmanMenu(WORD id)
{
LPTSTR text = NULL;
HTREEITEM ht = TreeView_GetSelection(netman->GetItem(IDC_TREE_NET));
TVITEM tvi={TVIF_HANDLE | TVIF_PARAM, ht};
TreeView_GetItem(netman->GetItem(IDC_TREE_NET), &tvi);
CWorker *wrk = (CWorker*)tvi.lParam;
HWND hList = netman->GetItem(IDC_FOUND);
HANDLE hThread=NULL;
if (wrk==NULL) return FALSE;
switch(id) {
//*******************************************************************************
// TreeView part
case ID_TREE_OPEN:
if (wrk->type == NRT_COMPUTER) {
text = StrDup(wrk->m_Name);
} else if (wrk->type == NRT_SHARE) {
text = ((Share*)tvi.lParam)->FullName();//StrDup(((Share*)tvi.lParam)->);
} else break;
hThread = CreateThread(NULL, 0, AsyncExec, text, 0 , NULL);
break;
case ID_TREE_COPYIP:
if (wrk->type == NRT_COMPUTER && OpenClipboard(netman->Handle())) {
HGLOBAL hgl = GlobalAlloc(GMEM_MOVEABLE, sizeof(TCHAR)*20); // 3*4+3
text = (LPTSTR)GlobalLock(hgl);
((Computer*)tvi.lParam)->GetIPName(text, 20);
GlobalUnlock(hgl);
if (NULL==SetClipboardData(CF_UNICODETEXT, hgl))
OutputDebugString(TEXT("SetClipboardData failed\n"));
CloseClipboard();
GlobalFree(hgl);
}
break;
case ID_TREE_PING:
if (wrk->type == NRT_COMPUTER) {
((Computer*)tvi.lParam)->Ping();
}
break;
case ID_TREE_APPEND:
if (wrk->type == NRT_SHARE) {
text = ((Share*)tvi.lParam)->FullName();
queue->AddItem(text, NULL);
delete text;
}
break;
case ID_TREE_SEARCHSUBTREE:
if (text = netman->GetItemText(IDC_ED_MASK)) {
wrk->Search(text, netman->SpinGetValue(IDC_SPIN_SIZEMIN), netman->SpinGetValue(IDC_SPIN_SIZEMAX));
delete text;
}
break;
case ID_TREE_REFRESH:
case ID_TREE_REFRESHSUBTREE:
if (wrk->type == NRT_COMPUTER) ((Computer*) wrk)->ResolveIP(true, true);
wrk->Start(id == ID_TREE_REFRESHSUBTREE);
break;
case ID_TREE_UNFOLD:
wrk->Unfold();
wrk->Expand();
break;
case ID_TREE_CANCEL:
wrk->Stop(0);
break;
case ID_TREE_REMOVE:
if (wrk->GetParentNode()) {
wrk->GetParentNode()->RemoveItem(wrk);
}
break;
//*******************************************************************************
// List part
case ID_LIST_CLIPCOPY:
if (OpenClipboard(netman->Handle())) {
HGLOBAL hgl = GlobalAlloc(GMEM_MOVEABLE, sizeof(TCHAR)*MAX_PATH);
text = (LPTSTR)GlobalLock(hgl);
GetListText(text);
GlobalUnlock(hgl);
if (NULL==SetClipboardData(CF_UNICODETEXT, hgl))
OutputDebugString(TEXT("SetClipboarddata failed\n"));
CloseClipboard();
GlobalFree(hgl);
}
break;
case ID_LIST_OPEN:
case ID_LIST_OPENCONTAINER:
case ID_LIST_APPEND:
LPTSTR end;
// allocate buffer and copy text
if (!GetListText(text)) return FALSE;
switch(id) {
case ID_LIST_OPENCONTAINER:
end = StrRChar(text, '\\');
if (end) *end = 0;
case ID_LIST_OPEN:
hThread = CreateThread(NULL, 0, AsyncExec, text, 0 , NULL);
break;
case ID_LIST_APPEND:
queue->AddItem(text, NULL);
delete text;
break;
}
break;
default:
return FALSE;
}
if (hThread) CloseHandle(hThread);
return TRUE;
}
// WM_COMMAND
BOOL CALLBACK NetmanCmd(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LPTSTR mask;
long idx;
if (netman==NULL) return FALSE;
switch (LOWORD(wParam)) {
case IDC_BTN_STARTENUM:
domains->Start(true); // do not wait
//CopyScreen(hwndDlg);
break;
case IDC_BTN_STOPENUM:
domains->Stop(0); // do not wait
break;
case IDC_BTN_SEARCH:
if (mask = netman->GetItemText(IDC_ED_MASK)) {
domains->Search(mask, netman->SpinGetValue(IDC_SPIN_SIZEMIN), netman->SpinGetValue(IDC_SPIN_SIZEMAX));
ip_scan->Search(mask, netman->SpinGetValue(IDC_SPIN_SIZEMIN), netman->SpinGetValue(IDC_SPIN_SIZEMAX));
delete mask;
}
break;
case IDC_ED_THREADS:
if (HIWORD(wParam) == EN_CHANGE) {
if (ThreadCount==0) {
if (semThreadLimit) CloseHandle(semThreadLimit);
idx = netman->SpinGetValue(IDC_SPIN_THREADS);
semThreadLimit = CreateSemaphore(NULL, idx, idx, NULL);
} else {
Edit_Undo((HWND)lParam);
}
}
break;
case IDC_IP_FROM:
case IDC_IP_TO:
if (HIWORD(wParam) == EN_CHANGE) {
wParam = wParam;
}
default:
if (HIWORD(wParam)==0) return NetmanMenu(LOWORD(wParam));
return FALSE;
}
return TRUE;
}
// WM_CONTEXTMENU
BOOL CALLBACK NetmanCtxMnu(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
HWND hwndTree = netman->GetItem(IDC_TREE_NET), hwndList = netman->GetItem(IDC_FOUND);
ScreenToClient((HWND) wParam, &pt);
if ((HWND)wParam == hwndTree) {
TVHITTESTINFO tvhti={pt.x, pt.y};
HTREEITEM hti = TreeView_HitTest(hwndTree,&tvhti);
if ((tvhti.flags & TVHT_NOWHERE) == 0) {
TVITEM tvi={TVIF_HANDLE | TVIF_PARAM, hti};
if (hti) {
TreeView_SelectItem(hwndTree, hti);
} else {
tvi.hItem = TreeView_GetSelection(hwndTree);
}
TreeView_GetItem(hwndTree, &tvi);
if (tvi.lParam) {
NetResType type = ((CWorker*)tvi.lParam)->type;
EnableMenuItem(mnuTree, ID_TREE_OPEN, (type == NRT_COMPUTER || type == NRT_SHARE)?MF_ENABLED: MF_DISABLED|MF_GRAYED);
EnableMenuItem(mnuTree, ID_TREE_APPEND, (type == NRT_SHARE)?MF_ENABLED: MF_DISABLED|MF_GRAYED);
EnableMenuItem(mnuTree, ID_TREE_COPYIP, (type == NRT_COMPUTER)?MF_ENABLED: MF_DISABLED|MF_GRAYED);
EnableMenuItem(mnuTree, ID_TREE_REFRESH, (type != NRT_SHARE)?MF_ENABLED: MF_DISABLED|MF_GRAYED);
EnableMenuItem(mnuTree, ID_TREE_REFRESHSUBTREE, (type != NRT_SHARE)?MF_ENABLED: MF_DISABLED|MF_GRAYED);
EnableMenuItem(mnuTree, ID_TREE_REMOVE, (type != NRT_SHARE)?MF_ENABLED: MF_DISABLED|MF_GRAYED);
TrackPopupMenu(mnuTree,TPM_LEFTALIGN, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, hwndDlg, NULL);
}
}
} else if ((HWND)wParam == hwndList) {
int i = 0;
i = SendMessage( hwndList, LB_ITEMFROMPOINT, 0, MAKELPARAM(pt.x, pt.y));
if (HIWORD(i)==0) {
ListBox_SetCurSel(hwndList, LOWORD(i));
TrackPopupMenu(mnuList,TPM_LEFTALIGN, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, hwndDlg, NULL);
}
}
return TRUE;
}
// Notifications sent by Network Tree
BOOL CALLBACK NetmanNet(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
TCHAR text[10];
try{
switch(wParam) {
case NNM_ENUMSTARTED:// fisrt thread started
netman->EnableItem(IDC_ED_THREADS, false);
netman->EnableItem(IDC_SPIN_THREADS, false);
break;
case NNM_ITEMADDED:// new item added elsewhere
if (lParam==NULL) { // this msg was sent by Share -> file found
//PlaySound(MAKEINTRESOURCE(IDR_WAV_ITEM), GetHinstance, SND_RESOURCE | SND_ASYNC);
SoundNotify(IDR_WAV_ITEM);
HWND hTree = netman->GetItem(IDC_TREE_NET);
TVITEM tvi = {TVIF_PARAM | TVIF_HANDLE};
tvi.hItem = TreeView_GetSelection(hTree);
TreeView_GetItem(hTree, &tvi);
if (tvi.lParam) ItemSelected((CWorker*)tvi.lParam);
} else if (((CWorker*)lParam)->GetType() == NRT_SHARE && netman->BtnGetCheck(IDC_CHK_AUTO)) {
LPTSTR mask;
if (mask = netman->GetItemText(IDC_ED_MASK)) {
((Share*)lParam)->Search(mask, netman->SpinGetValue(IDC_SPIN_SIZEMIN), netman->SpinGetValue(IDC_SPIN_SIZEMAX));
delete mask;
}
}
break;
case NNM_ENUMFINISHED:// last thread finished
netman->EnableItem(IDC_ED_THREADS, true);
netman->EnableItem(IDC_SPIN_THREADS, true);
/*
wsprintf(text, TEXT("%d/%d"), ActiveThreads, ThreadCount);
netman->SetItemText(IDC_COUNT,text);
*/
//PlaySound(MAKEINTRESOURCE(IDR_WAV_DONE), GetHinstance, SND_RESOURCE | SND_ASYNC);
SoundNotify(IDR_WAV_DONE);
//domains->Sort(true);
break;
case NNM_THREADCNTCHANGED:
wsprintf(text, TEXT("%d/%d"), LOWORD(lParam), HIWORD(lParam));
netman->SetItemText(IDC_COUNT,text);
break;
case NNM_EMPTYDETECTED: {
// remove empty
CWorker *item = (CWorker*)lParam,
*parent = item->GetParentNode();
if (parent && item->type != NRT_SHARE) {
//MessageBox(hwndDlg, TEXT("Empty entry detected -> press OK to hang :)"), TEXT("Empty detected"), MB_ICONWARNING);
item->DebugWrite(TEXT("Empty detected"));
//DebugBreak();
parent->RemoveItem(item);
}
break;
}
} // switch(wParam) //
} // try block
catch(...){
OutputDebugString(TEXT("Exception in Global::NemanNet\n"));
}
return TRUE;
}