summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsje <sje@4f64403b-2f21-0410-a795-97e2b3489a10>2006-11-01 14:44:34 +0000
committersje <sje@4f64403b-2f21-0410-a795-97e2b3489a10>2006-11-01 14:44:34 +0000
commit49b4d6dd9d4d35adc9f02df4010a1a6b33faba63 (patch)
tree403d0508eed3d1e1c9b336251eff931f3f2511b1
parentb61df7acc1235b3b2a66217d0d7358199c5d37f9 (diff)
git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@12 4f64403b-2f21-0410-a795-97e2b3489a10
-rw-r--r--ping_protocol/StdAfx.cpp8
-rw-r--r--ping_protocol/StdAfx.h28
-rw-r--r--ping_protocol/common.h122
-rw-r--r--ping_protocol/icmp.cpp83
-rw-r--r--ping_protocol/icmp.h66
-rw-r--r--ping_protocol/icon1.icobin0 -> 1078 bytes
-rw-r--r--ping_protocol/log.cpp58
-rw-r--r--ping_protocol/log.h13
-rw-r--r--ping_protocol/menu.cpp96
-rw-r--r--ping_protocol/menu.h10
-rw-r--r--ping_protocol/options.cpp654
-rw-r--r--ping_protocol/options.h23
-rw-r--r--ping_protocol/pinggraph.cpp250
-rw-r--r--ping_protocol/pinggraph.h21
-rw-r--r--ping_protocol/pinglist.cpp249
-rw-r--r--ping_protocol/pinglist.h39
-rw-r--r--ping_protocol/pingproto.cpp468
-rw-r--r--ping_protocol/pingproto.dsp217
-rw-r--r--ping_protocol/pingproto.dsw29
-rw-r--r--ping_protocol/pingproto.h43
-rw-r--r--ping_protocol/pingproto.mdsp117
-rw-r--r--ping_protocol/pingproto.plg80
-rw-r--r--ping_protocol/pingproto.rc226
-rw-r--r--ping_protocol/pingproto.sln20
-rw-r--r--ping_protocol/pingproto.vcproj544
-rw-r--r--ping_protocol/pingthread.cpp309
-rw-r--r--ping_protocol/pingthread.h21
-rw-r--r--ping_protocol/rawping.cpp206
-rw-r--r--ping_protocol/rawping.h61
-rw-r--r--ping_protocol/resource.h65
-rw-r--r--ping_protocol/utils.cpp324
-rw-r--r--ping_protocol/utils.h38
32 files changed, 4488 insertions, 0 deletions
diff --git a/ping_protocol/StdAfx.cpp b/ping_protocol/StdAfx.cpp
new file mode 100644
index 0000000..b9237ff
--- /dev/null
+++ b/ping_protocol/StdAfx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// pingproto.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/ping_protocol/StdAfx.h b/ping_protocol/StdAfx.h
new file mode 100644
index 0000000..826118a
--- /dev/null
+++ b/ping_protocol/StdAfx.h
@@ -0,0 +1,28 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__76631AC9_579A_456F_9BBB_708AF45BA0B8__INCLUDED_)
+#define AFX_STDAFX_H__76631AC9_579A_456F_9BBB_708AF45BA0B8__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#define VC_EXTRALEAN
+
+#define _WIN32_WINNT 0x0400
+#include <windows.h>
+#include <prsht.h>
+#include <winsock2.h>
+#include <winsock.h>
+#include <shellapi.h>
+#include <commdlg.h>
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__76631AC9_579A_456F_9BBB_708AF45BA0B8__INCLUDED_)
diff --git a/ping_protocol/common.h b/ping_protocol/common.h
new file mode 100644
index 0000000..0cf5f60
--- /dev/null
+++ b/ping_protocol/common.h
@@ -0,0 +1,122 @@
+#ifndef _COMMON_H
+#define _COMMON_H
+
+#define MAX_HISTORY (1440) // 12 hrs at 30 sec intervals
+
+#define PROTO "PING"
+
+#define DEFAULT_PING_PERIOD 30
+#define DEFAULT_PING_TIMEOUT 2
+#define DEFAULT_SHOW_POPUP false
+#define DEFAULT_SHOW_POPUP2 false
+#define DEFAULT_BLOCK_REPS true
+#define DEFAULT_LOGGING_ENABLED false
+#define DEFAULT_LOG_FILENAME "ping_log.txt"
+#define DEFAULT_NO_TEST_STATUS true
+#define DEFAULT_HIDE_PROTOCOL false
+#define DEFAULT_USE_STATUS_MESSAGE false
+
+
+#define MAX_PINGADDRESS_STRING_LENGTH 256
+
+#include <stdio.h>
+
+#include "../../include/newpluginapi.h"
+#include "../../include/statusmodes.h"
+#include "../../include/m_options.h"
+#include "../../include/m_langpack.h"
+#include "../../include/m_popup.h"
+#include "../../include/m_system.h"
+#include "../../include/m_skin.h"
+#include "../../include/m_netlib.h"
+#include "../../include/m_database.h"
+#include "../../include/m_protocols.h"
+#include "../../include/m_protomod.h"
+#include "../../include/m_protosvc.h"
+#include "../../include/m_ignore.h"
+#include "../../include/m_clist.h"
+#include "../../include/m_clui.h"
+#include "../../include/m_utils.h"
+
+#include "../updater/m_updater.h"
+
+typedef struct {
+ int ping_period, ping_timeout;
+ bool show_popup, show_popup2, block_reps, logging;
+ char log_filename[MAX_PATH];
+ WORD rstatus, nrstatus, tstatus, off_status;
+ bool no_test_status;
+ bool hide_proto;
+ int retries;
+ bool use_status_msg;
+} PingOptions;
+
+#include <vector>
+// deque of pairs - round trip time and timestamp
+typedef std::vector<std::pair<short, DWORD> > HistoryList;
+
+typedef struct PINGADDRESS_tag {
+
+ /*
+ PINGADDRESS_tag() {
+ pszName[0] = 0;
+ pszLabel[0] = 0;
+ pszProto[0] = 0;
+ pszCommand[0] = 0;
+ pszParams[0] = 0;
+ }
+
+ PINGADDRESS_tag(const PINGADDRESS_tag &src) {
+ }
+ */
+ const PINGADDRESS_tag operator=(const PINGADDRESS_tag &src) {
+ cbSize = src.cbSize;
+ hContact = src.hContact;
+ strcpy(pszName, src.pszName);
+ strcpy(pszLabel, src.pszLabel);
+ responding = src.responding;
+ status = src.status;
+ round_trip_time = src.round_trip_time;
+ miss_count = src.miss_count;
+ port = src.port;
+ strcpy(pszProto, src.pszProto);
+ strcpy(pszCommand, src.pszCommand);
+ strcpy(pszParams, src.pszParams);
+ get_status = src.get_status;
+ set_status = src.set_status;
+ if(src.history.size())
+ history = src.history;
+ else
+ history.clear();
+ index = src.index;
+ strcpy(pszCListGroup, src.pszCListGroup);
+
+ return *this;
+ }
+
+ int cbSize; //size in bytes of this structure
+ HANDLE hContact;
+ char pszName[MAX_PINGADDRESS_STRING_LENGTH]; //IP address or domain name
+ char pszLabel[MAX_PINGADDRESS_STRING_LENGTH];
+ bool responding;
+ int status;
+ short round_trip_time;
+ int miss_count;
+ int port; // -1 for ICMP, non-zero for TCP
+ char pszProto[MAX_PINGADDRESS_STRING_LENGTH];
+ char pszCommand[MAX_PATH];
+ char pszParams[MAX_PATH];
+ unsigned int get_status; // on success, if status equals this
+ unsigned int set_status; // set it to this
+ HistoryList history;
+ int index;
+ char pszCListGroup[MAX_PINGADDRESS_STRING_LENGTH];
+} PINGADDRESS;
+
+extern HANDLE hNetlibUser;
+extern HINSTANCE hInst;
+
+extern int previousMode;
+extern int mcStatus;
+
+#endif
diff --git a/ping_protocol/icmp.cpp b/ping_protocol/icmp.cpp
new file mode 100644
index 0000000..a9cd296
--- /dev/null
+++ b/ping_protocol/icmp.cpp
@@ -0,0 +1,83 @@
+#include "stdafx.h"
+#include "icmp.h"
+
+ICMP ICMP::instance;
+
+ICMP::ICMP():
+ timeout(2000),
+ functions_loaded(false)
+{
+ hDLL = LoadLibrary("ICMP.DLL");
+ if(!hDLL) return;
+
+ pIcmpCreateFile = (pfnHV)GetProcAddress(hDLL, "IcmpCreateFile");
+ pIcmpCloseHandle = (pfnBH)GetProcAddress(hDLL, "IcmpCloseHandle");
+ pIcmpSendEcho = (pfnDHDPWPipPDD)GetProcAddress(hDLL, "IcmpSendEcho");
+ if ((pIcmpCreateFile == 0) || (pIcmpCloseHandle == 0) || (pIcmpSendEcho == 0)) {
+ return;
+ }
+
+ WSAData wsaData;
+ if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
+ WSACleanup();
+ FreeLibrary((HMODULE)hDLL);
+ return;
+ }
+
+ functions_loaded = true;
+}
+
+void ICMP::stop() {
+ if(hIP) {
+ pIcmpCloseHandle(hIP);
+ hIP = 0;
+ }
+}
+
+ICMP::~ICMP() {
+ if(hIP) pIcmpCloseHandle(hIP);
+ WSACleanup();
+ if(hDLL)
+ FreeLibrary(hDLL);
+}
+
+bool ICMP::ping(char *host, IP_ECHO_REPLY &reply) {
+ if(!functions_loaded) return false;
+
+ DWORD address;
+ struct in_addr dest;
+ HOSTENT *rec;
+ IP_OPTION_INFORMATION ipoi;
+
+ hIP = pIcmpCreateFile();
+ if (hIP == INVALID_HANDLE_VALUE) {
+ return false;
+ }
+
+
+ dest.s_addr = inet_addr(host);
+ if (dest.s_addr == INADDR_NONE) {
+ rec = gethostbyname(host);
+ if(rec) address = *(DWORD *)(*rec->h_addr_list);
+ else return false;
+ } else {
+ address = dest.s_addr;
+ }
+
+ ipoi.Ttl = 255;
+ ipoi.Tos = 0;
+ ipoi.Flags = 0;
+ ipoi.OptionsSize = 0;
+ ipoi.OptionsData = 0;
+
+ reply.Status = 0;
+
+ pIcmpSendEcho(hIP, address, (void *)"PINGPONG", 8, &ipoi, &reply, sizeof(reply), timeout);
+
+ if(hIP) {
+ pIcmpCloseHandle(hIP);
+ hIP = 0;
+ }
+
+ return (reply.Status == 0);
+} \ No newline at end of file
diff --git a/ping_protocol/icmp.h b/ping_protocol/icmp.h
new file mode 100644
index 0000000..19aca1d
--- /dev/null
+++ b/ping_protocol/icmp.h
@@ -0,0 +1,66 @@
+// adapted 23/9/2004 from public domain code at http://tangentsoft.net/wskfaq/examples/dllping.html
+
+#ifndef _ICMP_H
+#define _ICMP_H
+
+#include <windows.h>
+
+// Structures required to use functions in ICMP.DLL
+
+typedef struct {
+ unsigned char Ttl; // Time To Live
+ unsigned char Tos; // Type Of Service
+ unsigned char Flags; // IP header flags
+ unsigned char OptionsSize; // Size in bytes of options data
+ unsigned char *OptionsData; // Pointer to options data
+} IP_OPTION_INFORMATION, * PIP_OPTION_INFORMATION;
+
+typedef struct {
+ DWORD Address; // Replying address
+ unsigned long Status; // Reply status
+ unsigned long RoundTripTime; // RTT in milliseconds
+ unsigned short DataSize; // Echo data size
+ unsigned short Reserved; // Reserved for system use
+ void *Data; // Pointer to the echo data
+ IP_OPTION_INFORMATION Options; // Reply options
+ unsigned char ReplyData[8];
+} IP_ECHO_REPLY, * PIP_ECHO_REPLY;
+
+
+typedef HANDLE (WINAPI* pfnHV)(VOID);
+typedef BOOL (WINAPI* pfnBH)(HANDLE);
+typedef DWORD (WINAPI* pfnDHDPWPipPDD)(HANDLE, DWORD, LPVOID, WORD, PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD); // evil, no?
+
+class ICMP {
+protected:
+ pfnHV pIcmpCreateFile;
+ pfnBH pIcmpCloseHandle;
+ pfnDHDPWPipPDD pIcmpSendEcho;
+
+ HMODULE hDLL;
+
+ HANDLE hIP;
+
+ unsigned int timeout;
+ bool functions_loaded;
+
+ // protected constructor - singleton class
+ ICMP();
+ static ICMP instance;
+
+public:
+ ~ICMP();
+ static ICMP *get_instance() {return &instance;}
+
+ bool ping(char *host, IP_ECHO_REPLY &reply);
+
+ void set_timeout(unsigned int t) {
+ timeout = t;
+ }
+
+ void stop();
+
+ unsigned int get_timeout() {return timeout;}
+
+};
+#endif //_ICMP_H \ No newline at end of file
diff --git a/ping_protocol/icon1.ico b/ping_protocol/icon1.ico
new file mode 100644
index 0000000..17ef694
--- /dev/null
+++ b/ping_protocol/icon1.ico
Binary files differ
diff --git a/ping_protocol/log.cpp b/ping_protocol/log.cpp
new file mode 100644
index 0000000..608db44
--- /dev/null
+++ b/ping_protocol/log.cpp
@@ -0,0 +1,58 @@
+#include "stdafx.h"
+#include "log.h"
+
+int Log(WPARAM wParam, LPARAM lParam) {
+
+ char buf[1024];
+ CallService(PROTO "/GetLogFilename", (WPARAM)1024, (LPARAM)buf);
+
+ char TBcapt[255];
+ SYSTEMTIME systime;
+
+ GetLocalTime(&systime);
+
+ wsprintf(TBcapt,"%02d:%02d:%02d",systime.wHour,systime.wMinute,systime.wSecond);
+
+ std::string timestring = TBcapt;
+
+ std::string line = (char *)wParam;
+
+ std::ofstream out(buf, std::ios_base::out | std::ios_base::app);
+ if(out.is_open()) {
+ out << timestring << ": " << line << std::endl;
+ out.close();
+ }
+
+ return 0;
+}
+
+int GetLogFilename(WPARAM wParam, LPARAM lParam) {
+ DBVARIANT dbv;
+ std::string filename;
+ if(DBGetContactSetting(0, PROTO, "LogFilename", &dbv)) {
+ char buf[MAX_PATH];
+ CallService(MS_DB_GETPROFILEPATH, (WPARAM)MAX_PATH, (LPARAM)buf);
+ filename = buf;
+ filename += "\\";
+ filename += "ping_log.txt";
+ } else {
+ filename = dbv.pszVal;
+ }
+
+ strncpy((char *)lParam, filename.c_str(), (size_t)wParam);
+
+ DBFreeVariant(&dbv);
+ return 0;
+}
+
+int SetLogFilename(WPARAM wParam, LPARAM lParam) {
+ DBWriteContactSettingString(0, PROTO, "LogFilename", (char *)lParam);
+ return 0;
+}
+
+int ViewLogData(WPARAM wParam, LPARAM lParam) {
+ char buf[1024];
+ CallService(PROTO "/GetLogFilename", (WPARAM)MAX_PATH, (LPARAM)buf);
+ return (int)ShellExecute((HWND)wParam, "edit", buf, "", "", SW_SHOW);
+}
+
diff --git a/ping_protocol/log.h b/ping_protocol/log.h
new file mode 100644
index 0000000..d19d5c9
--- /dev/null
+++ b/ping_protocol/log.h
@@ -0,0 +1,13 @@
+#ifndef _PING_LOG
+#define _PING_LOG
+
+#include <string>
+#include <fstream>
+#include "common.h"
+
+int Log(WPARAM wParam, LPARAM lParam);
+int GetLogFilename(WPARAM wParam, LPARAM lParam);
+int SetLogFilename(WPARAM wParam, LPARAM lParam);
+int ViewLogData(WPARAM wParam, LPARAM lParam);
+
+#endif \ No newline at end of file
diff --git a/ping_protocol/menu.cpp b/ping_protocol/menu.cpp
new file mode 100644
index 0000000..b05f849
--- /dev/null
+++ b/ping_protocol/menu.cpp
@@ -0,0 +1,96 @@
+#include "stdafx.h"
+#include "menu.h"
+
+HANDLE hMenuDisable, hMenuGraph, hMenuEdit;
+HANDLE hEventMenuBuild;
+
+int MenuBuild(WPARAM wParam, LPARAM lParam) {
+ CLISTMENUITEM menu;
+ ZeroMemory(&menu,sizeof(menu));
+ menu.cbSize=sizeof(menu);
+
+ menu.flags = CMIM_NAME | CMIM_ICON;
+ bool disable = DBGetContactSettingWord((HANDLE)wParam, PROTO, "Status", ID_STATUS_OFFLINE) != options.off_status;
+ if(disable) {
+ menu.hIcon = LoadSkinnedProtoIcon(PROTO, options.off_status);
+ menu.pszName = Translate("Disable");
+ } else {
+ menu.hIcon = LoadSkinnedProtoIcon(PROTO, options.rstatus);
+ menu.pszName = Translate("Enable");
+ }
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuDisable, (LPARAM)&menu);
+
+ // hide graph menu item if window displayed
+ //menu.flags = CMIM_FLAGS | (DBGetContactSettingDword((HANDLE)wParam, PROTO, "WindowHandle", 0) == 0 ? 0 : CMIF_HIDDEN);
+ //CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuGraph, (LPARAM)&menu);
+
+ return 0;
+}
+
+void InitMenus() {
+
+ CLISTMENUITEM menu;
+ ZeroMemory(&menu,sizeof(menu));
+ menu.cbSize=sizeof(menu);
+
+ // main menu
+ menu.flags = 0;
+ menu.popupPosition = 500099900;
+ menu.pszPopupName = Translate( "PING" );
+ menu.cbSize = sizeof( menu );
+ menu.position = 2000060000;
+ menu.hIcon = LoadSkinnedProtoIcon(PROTO, options.rstatus);
+ menu.pszName = Translate( "Enable All Pings" );
+ menu.pszService = PROTO "/EnableAll";
+ CallService( MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&menu );
+
+ menu.flags = 0;
+ menu.popupPosition = 500299901;
+ menu.pszPopupName = Translate( "PING" );
+ menu.cbSize = sizeof( menu );
+ menu.position = 2000060001;
+ menu.popupPosition = 0;
+ menu.hIcon = LoadSkinnedProtoIcon(PROTO, options.off_status);
+ menu.pszName = Translate( "Disable All Pings" );
+ menu.pszService = PROTO "/DisableAll";
+ CallService( MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&menu );
+
+ // contact
+ menu.flags = 0;
+ menu.popupPosition = 0;
+ menu.pszPopupName = 0;
+ menu.cbSize = sizeof( menu );
+ menu.position =-300100;
+ //menu.popupPosition = 0;
+ menu.hIcon = LoadSkinnedProtoIcon(PROTO, options.off_status);
+ menu.pszName = Translate( "Disable" );
+ menu.pszService = PROTO "/ToggleEnabled";
+ menu.pszContactOwner = PROTO;
+ hMenuDisable = (HANDLE)CallService( MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&menu );
+
+ menu.flags = 0;
+ menu.popupPosition = 0;
+ menu.pszPopupName = 0;
+ menu.cbSize = sizeof( menu );
+ menu.position =-300090;
+ //menu.popupPosition = 0;
+ menu.hIcon = LoadSkinnedProtoIcon(PROTO, options.rstatus);
+ menu.pszName = Translate( "Graph" );
+ menu.pszService = PROTO "/ShowGraph";
+ menu.pszContactOwner = PROTO;
+ hMenuGraph = (HANDLE)CallService( MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&menu );
+
+ menu.flags = 0;
+ menu.popupPosition = 0;
+ menu.pszPopupName = 0;
+ menu.cbSize = sizeof( menu );
+ menu.position =-300080;
+ //menu.popupPosition = 0;
+ menu.hIcon = LoadSkinnedProtoIcon(PROTO, options.rstatus);
+ menu.pszName = Translate( "Edit..." );
+ menu.pszService = PROTO "/Edit";
+ menu.pszContactOwner = PROTO;
+ hMenuGraph = (HANDLE)CallService( MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&menu );
+
+ hEventMenuBuild = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, MenuBuild);
+} \ No newline at end of file
diff --git a/ping_protocol/menu.h b/ping_protocol/menu.h
new file mode 100644
index 0000000..f302259
--- /dev/null
+++ b/ping_protocol/menu.h
@@ -0,0 +1,10 @@
+#ifndef _MENU_H
+#define _MENU_H
+
+#include "common.h"
+#include "pinglist.h"
+#include "pinggraph.h"
+
+void InitMenus();
+
+#endif \ No newline at end of file
diff --git a/ping_protocol/options.cpp b/ping_protocol/options.cpp
new file mode 100644
index 0000000..50e1061
--- /dev/null
+++ b/ping_protocol/options.cpp
@@ -0,0 +1,654 @@
+#include "stdafx.h"
+#include "options.h"
+
+PingOptions options;
+
+// main ping options
+static BOOL CALLBACK DlgProcOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ HWND hw;
+ OPENFILENAME ofn = {0};
+ char *strptr;
+
+ switch ( msg ) {
+ case WM_INITDIALOG: {
+ TranslateDialogDefault( hwndDlg );
+
+ SetDlgItemInt(hwndDlg, IDC_PPM, options.ping_period, FALSE);
+ SetDlgItemInt(hwndDlg, IDC_PT, options.ping_timeout, FALSE);
+ CheckDlgButton(hwndDlg, IDC_CHECKPOPUP, options.show_popup);
+ CheckDlgButton(hwndDlg, IDC_CHECKPOPUP2, options.show_popup2);
+ CheckDlgButton(hwndDlg, IDC_CHK_BLOCK, options.block_reps);
+ CheckDlgButton(hwndDlg, IDC_CHK_LOG, options.logging);
+ CheckDlgButton(hwndDlg, IDC_CHK_NOTESTSTATUS, options.no_test_status);
+ CheckDlgButton(hwndDlg, IDC_CHK_HIDEPROTO, options.hide_proto);
+ CheckDlgButton(hwndDlg, IDC_CHK_USESTATUSMSG, options.use_status_msg);
+ hw = GetDlgItem(hwndDlg, IDC_TSTATUS);
+ EnableWindow(hw, options.no_test_status? FALSE : TRUE);
+
+ for(int i = ID_STATUS_OFFLINE; i != ID_STATUS_OUTTOLUNCH; i++) {
+ strptr = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)i, (LPARAM)0);
+ hw = GetDlgItem(hwndDlg, IDC_RSTATUS);
+ SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)strptr);
+ hw = GetDlgItem(hwndDlg, IDC_NRSTATUS);
+ SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)strptr);
+ hw = GetDlgItem(hwndDlg, IDC_TSTATUS);
+ SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)strptr);
+ hw = GetDlgItem(hwndDlg, IDC_DSTATUS);
+ SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)strptr);
+ }
+ hw = GetDlgItem(hwndDlg, IDC_RSTATUS);
+ SendMessage(hw, CB_SETCURSEL, (WPARAM)(options.rstatus - ID_STATUS_OFFLINE), 0);
+ hw = GetDlgItem(hwndDlg, IDC_NRSTATUS);
+ SendMessage(hw, CB_SETCURSEL, (WPARAM)(options.nrstatus - ID_STATUS_OFFLINE), 0);
+ hw = GetDlgItem(hwndDlg, IDC_TSTATUS);
+ SendMessage(hw, CB_SETCURSEL, (WPARAM)(options.tstatus - ID_STATUS_OFFLINE), 0);
+ hw = GetDlgItem(hwndDlg, IDC_DSTATUS);
+ SendMessage(hw, CB_SETCURSEL, (WPARAM)(options.off_status - ID_STATUS_OFFLINE), 0);
+
+ SetDlgItemInt(hwndDlg, IDC_RPT, options.retries, FALSE);
+
+ SetDlgItemText(hwndDlg, IDC_ED_FILENAME, options.log_filename);
+ if(!options.logging) {
+ hw = GetDlgItem(hwndDlg, IDC_ED_FILENAME);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_LOGBROWSE);
+ EnableWindow(hw, FALSE);
+ }
+
+ if(!ServiceExists( MS_POPUP_ADDPOPUP )) {
+ hw = GetDlgItem(hwndDlg, IDC_CHECKPOPUP);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_CHECKPOPUP2);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_CHK_BLOCK);
+ EnableWindow(hw, FALSE);
+ }
+ return TRUE;
+ }
+ case WM_COMMAND:
+ if ( HIWORD( wParam ) == EN_CHANGE && ( HWND )lParam == GetFocus()) {
+ switch( LOWORD( wParam )) {
+ case IDC_PPM:
+ case IDC_PT:
+ case IDC_ED_FILENAME:
+ case IDC_RPT:
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+
+ if (HIWORD( wParam ) == CBN_SELCHANGE) {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+
+ if ( HIWORD( wParam ) == BN_CLICKED ) {
+ switch( LOWORD( wParam )) {
+ case IDC_CHK_LOG:
+ hw = GetDlgItem(hwndDlg, IDC_ED_FILENAME);
+ EnableWindow(hw, IsDlgButtonChecked(hwndDlg, IDC_CHK_LOG));
+ hw = GetDlgItem(hwndDlg, IDC_BTN_LOGBROWSE);
+ EnableWindow(hw, IsDlgButtonChecked(hwndDlg, IDC_CHK_LOG));
+ // drop through
+ case IDC_CHECKPOPUP:
+ case IDC_CHECKPOPUP2:
+ case IDC_CHK_BLOCK:
+ case IDC_CHK_MINMAX:
+ case IDC_CHK_HIDEPROTO:
+ case IDC_CHK_USESTATUSMSG:
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ break;
+ case IDC_BTN_VIEWLOG:
+ CallService(PROTO "/ViewLogData", 0, 0);
+ break;
+ case IDC_BTN_LOGBROWSE:
+ ofn.lStructSize = sizeof(ofn);
+ ofn.lpstrFile = options.log_filename;
+ ofn.hwndOwner = hwndDlg;
+ ofn.Flags = CC_FULLOPEN;
+ //ofn.lpstrFile[0] = '\0';
+ ofn.nMaxFile = sizeof(options.log_filename);
+ ofn.lpstrFilter = "All\0*.*\0Text\0*.TXT\0";
+ ofn.nFilterIndex = 1;
+ ofn.lpstrFileTitle = NULL;
+ ofn.nMaxFileTitle = 0;
+ ofn.lpstrInitialDir = NULL;
+ ofn.Flags = OFN_PATHMUSTEXIST;
+
+ if(GetOpenFileName(&ofn) == TRUE) {
+ SetDlgItemText(hwndDlg, IDC_ED_FILENAME, ofn.lpstrFile);
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ }
+ break;
+ case IDC_CHK_NOTESTSTATUS:
+ hw = GetDlgItem(hwndDlg, IDC_TSTATUS);
+ EnableWindow(hw, IsDlgButtonChecked(hwndDlg, IDC_CHK_NOTESTSTATUS) ? FALSE : TRUE);
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ break;
+ }
+ }
+ break;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->code == PSN_APPLY ) {
+
+ {
+ int sel1, sel2, sel3, sel4;
+
+ hw = GetDlgItem(hwndDlg, IDC_RSTATUS);
+ sel1 = SendMessage(hw, CB_GETCURSEL, 0, 0);
+ hw = GetDlgItem(hwndDlg, IDC_NRSTATUS);
+ sel2 = SendMessage(hw, CB_GETCURSEL, 0, 0);
+ hw = GetDlgItem(hwndDlg, IDC_TSTATUS);
+ sel3 = SendMessage(hw, CB_GETCURSEL, 0, 0);
+ hw = GetDlgItem(hwndDlg, IDC_DSTATUS);
+ sel4 = SendMessage(hw, CB_GETCURSEL, 0, 0);
+
+ if(sel1 == sel4 || sel2 == sel4 || sel3 == sel4) {
+ MessageBox(hwndDlg, Translate("You cannot set any status to the same as 'disabled'"), Translate("Error"), MB_OK | MB_ICONWARNING);
+ SetWindowLong(hwndDlg, DWL_MSGRESULT, PSNRET_INVALID);
+ return TRUE;
+ }
+
+ if(sel1 != -1)
+ options.rstatus = ID_STATUS_OFFLINE + sel1;
+ if(sel2 != -1)
+ options.nrstatus = ID_STATUS_OFFLINE + sel2;
+ if(sel4 != -1)
+ options.off_status = ID_STATUS_OFFLINE + sel4;
+ if(sel3 != -1)
+ options.tstatus = ID_STATUS_OFFLINE + sel3;
+ }
+
+ BOOL trans_success;
+
+ DWORD new_ping_period = GetDlgItemInt( hwndDlg, IDC_PPM, &trans_success, FALSE);
+ if(trans_success) {
+ options.ping_period = new_ping_period;
+ }
+ DWORD new_ping_timeout = GetDlgItemInt( hwndDlg, IDC_PT, &trans_success, FALSE);
+ if(trans_success) {
+ options.ping_timeout = new_ping_timeout;
+ }
+ options.show_popup = IsDlgButtonChecked(hwndDlg, IDC_CHECKPOPUP) == BST_CHECKED;
+ options.show_popup2 = IsDlgButtonChecked(hwndDlg, IDC_CHECKPOPUP2) == BST_CHECKED;
+ options.block_reps = IsDlgButtonChecked(hwndDlg, IDC_CHK_BLOCK) == BST_CHECKED;
+ options.logging = IsDlgButtonChecked(hwndDlg, IDC_CHK_LOG) == BST_CHECKED;
+ GetDlgItemText(hwndDlg, IDC_ED_FILENAME, options.log_filename, MAX_PATH);
+
+ options.no_test_status = IsDlgButtonChecked(hwndDlg, IDC_CHK_NOTESTSTATUS) == BST_CHECKED;
+ options.hide_proto = IsDlgButtonChecked(hwndDlg, IDC_CHK_HIDEPROTO) == BST_CHECKED;
+ options.use_status_msg = IsDlgButtonChecked(hwndDlg, IDC_CHK_USESTATUSMSG) == BST_CHECKED;
+ DWORD new_retries = GetDlgItemInt( hwndDlg, IDC_RPT, &trans_success, FALSE);
+ if(trans_success) {
+ options.retries = new_retries;
+ }
+ SaveOptions();
+
+ if(options.use_status_msg)
+ reset_myhandle();
+
+ if(options.logging) CallService(PROTO "/Log", (WPARAM)"options changed", 0);
+ if(hWakeEvent) SetEvent(hWakeEvent);
+ return TRUE;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+PINGLIST temp_list;
+PINGADDRESS add_edit_addr;
+
+BOOL CALLBACK DlgProcDestEdit(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+ HWND hw;
+ int sel;
+ char *strptr;
+
+ switch ( msg ) {
+ case WM_INITDIALOG:
+ {
+ bool selgroup = false;
+ for(int i = ID_STATUS_OFFLINE; i <= ID_STATUS_OUTTOLUNCH; i++) {
+ strptr = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, (WPARAM)i, (LPARAM)0);
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTSTAT);
+ SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)strptr);
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTSTAT2);
+ SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)strptr);
+ }
+
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTSTAT);
+ SendMessage(hw, CB_SETCURSEL, 1, 0);
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTSTAT2);
+ SendMessage(hw, CB_SETCURSEL, 0, 0);
+
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_GROUP);
+ SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)Translate("<none>"));
+ DBVARIANT dbv;
+ if(!DBGetContactSetting(0, PROTO, "DefaultPingGroup", &dbv))
+ selgroup = true;
+ int gi = 1, selind = -1, selind_defgroup;
+ do {
+ strptr = (char *)CallService(MS_CLIST_GROUPGETNAME2, (WPARAM)gi, 0);
+ if(strptr) {
+ SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)strptr);
+ if(!strncmp(strptr, add_edit_addr.pszCListGroup, MAX_PINGADDRESS_STRING_LENGTH))
+ selind = gi;
+ if(selgroup && !strncmp(strptr, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH))
+ selind_defgroup = gi;
+ }
+ gi++;
+ } while(strptr != 0);
+ if(selgroup) DBFreeVariant(&dbv);
+
+ if(selind != -1) SendMessage(hw, CB_SETCURSEL, (WPARAM)selind, 0);
+ else if(selind_defgroup != -1) SendMessage(hw, CB_SETCURSEL, (WPARAM)selind_defgroup, 0);
+ else SendMessage(hw, CB_SETCURSEL, 0, 0);
+
+ SetDlgItemText(hwndDlg, IDC_ED_DESTADDR, add_edit_addr.pszName);
+ SetDlgItemText(hwndDlg, IDC_ED_DESTLAB, add_edit_addr.pszLabel);
+ SetDlgItemText(hwndDlg, IDC_ED_COMMAND, add_edit_addr.pszCommand);
+ SetDlgItemText(hwndDlg, IDC_ED_PARAMS, add_edit_addr.pszParams);
+
+ CheckDlgButton(hwndDlg, IDC_CHK_DESTTCP, add_edit_addr.port != -1);
+ if(add_edit_addr.port != -1) {
+ hw = GetDlgItem(hwndDlg, IDC_ED_DESTPORT);
+ EnableWindow(hw, TRUE);
+ SetDlgItemInt(hwndDlg, IDC_ED_DESTPORT, add_edit_addr.port, FALSE);
+ }
+ {
+ int num_protocols;
+ PROTOCOLDESCRIPTOR **pppDesc;
+
+ CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&num_protocols, (WPARAM)&pppDesc);
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTPROTO);
+ SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)Translate("<none>"));
+ SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)Translate("<all>"));
+ for(int i = 0; i < num_protocols; i++) {
+ if(pppDesc[i]->type == PROTOTYPE_PROTOCOL)
+ SendMessage(hw, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)pppDesc[i]->szName);
+ }
+
+ if(add_edit_addr.pszProto[0] == '\0') {
+ SendMessage(hw, CB_SETCURSEL, 0, 0);
+ } else {
+ SendMessage(hw, CB_SELECTSTRING, 0, (LPARAM)add_edit_addr.pszProto);
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTSTAT);
+ EnableWindow(hw, TRUE);
+ SendMessage(hw, CB_SETCURSEL, (WPARAM)(add_edit_addr.set_status - ID_STATUS_OFFLINE), 0);
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTSTAT2);
+ EnableWindow(hw, TRUE);
+ SendMessage(hw, CB_SETCURSEL, (WPARAM)(add_edit_addr.get_status - ID_STATUS_OFFLINE), 0);
+ }
+ }
+ // ? doesn't work? ?
+ hw = GetDlgItem(hwndDlg, IDC_ED_DESTADDR);
+ SetFocus(hw);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ if (HIWORD( wParam ) == LBN_SELCHANGE && LOWORD(wParam) == IDC_COMBO_DESTPROTO) {
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTPROTO);
+ sel = SendMessage(hw, CB_GETCURSEL, 0, 0);
+ if(sel != CB_ERR) {
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTSTAT);
+ EnableWindow(hw, sel != 0);
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTSTAT2);
+ EnableWindow(hw, sel != 0);
+ }
+ }
+
+ if ( HIWORD( wParam ) == BN_CLICKED ) {
+ switch( LOWORD( wParam )) {
+ case IDC_CHK_DESTTCP:
+ hw = GetDlgItem(hwndDlg, IDC_ED_DESTPORT);
+ EnableWindow(hw, IsDlgButtonChecked(hwndDlg, IDC_CHK_DESTTCP));
+ break;
+ case IDOK:
+ GetDlgItemText(hwndDlg, IDC_ED_DESTADDR, add_edit_addr.pszName, MAX_PINGADDRESS_STRING_LENGTH);
+ GetDlgItemText(hwndDlg, IDC_ED_DESTLAB, add_edit_addr.pszLabel, MAX_PINGADDRESS_STRING_LENGTH);
+ GetDlgItemText(hwndDlg, IDC_ED_COMMAND, add_edit_addr.pszCommand, MAX_PATH);
+ GetDlgItemText(hwndDlg, IDC_ED_PARAMS, add_edit_addr.pszParams, MAX_PATH);
+
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTPROTO);
+ if(SendMessage(hw, CB_GETCURSEL, 0, 0) != -1) {
+ GetDlgItemText(hwndDlg, IDC_COMBO_DESTPROTO, add_edit_addr.pszProto, MAX_PINGADDRESS_STRING_LENGTH);
+ if(!strcmp(add_edit_addr.pszProto, Translate("<none>"))) add_edit_addr.pszProto[0] = '\0';
+ else {
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTSTAT);
+ sel = SendMessage(hw, CB_GETCURSEL, 0, 0);
+ if(sel != -1)
+ add_edit_addr.set_status = ID_STATUS_OFFLINE + sel;
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_DESTSTAT2);
+ sel = SendMessage(hw, CB_GETCURSEL, 0, 0);
+ if(sel != -1)
+ add_edit_addr.get_status = ID_STATUS_OFFLINE + sel;
+ }
+ } else
+ add_edit_addr.pszProto[0] = '\0';
+
+ hw = GetDlgItem(hwndDlg, IDC_COMBO_GROUP);
+ GetDlgItemText(hwndDlg, IDC_COMBO_GROUP, add_edit_addr.pszCListGroup, MAX_PINGADDRESS_STRING_LENGTH);
+ if(!strcmp(add_edit_addr.pszCListGroup, Translate("<none>"))) add_edit_addr.pszCListGroup[0] = '\0';
+ DBWriteContactSettingString(0, PROTO, "DefaultPingGroup", add_edit_addr.pszCListGroup);
+
+ if(IsDlgButtonChecked(hwndDlg, IDC_CHK_DESTTCP)) {
+ BOOL tr;
+ int port = GetDlgItemInt(hwndDlg, IDC_ED_DESTPORT, &tr, FALSE);
+ if(tr) add_edit_addr.port = port;
+ else add_edit_addr.port = -1;
+ } else
+ add_edit_addr.port = -1;
+
+ EndDialog(hwndDlg, IDOK);
+ break;
+ case IDCANCEL:
+ EndDialog(hwndDlg, IDCANCEL);
+ break;
+ }
+
+ }
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// ping destinations list window
+static BOOL CALLBACK DlgProcOpts2(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ OPENFILENAME ofn = {0};
+ HWND hw;
+ int sel;
+
+ switch ( msg ) {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault( hwndDlg );
+
+ Lock(&data_list_cs, "init options dialog");
+ temp_list = data_list;
+ Unlock(&data_list_cs);
+
+ hw = GetDlgItem(hwndDlg, IDC_LST_DEST);
+ for(PINGLIST::iterator i = temp_list.begin(); i != temp_list.end(); i++) {
+ int index = SendMessage(hw, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)i->pszLabel);
+ }
+
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ if (HIWORD( wParam ) == LBN_SELCHANGE && LOWORD(wParam) == IDC_LST_DEST) {
+ hw = GetDlgItem(hwndDlg, IDC_LST_DEST);
+ sel = SendMessage(hw, LB_GETCURSEL, 0, 0);
+ if(sel != LB_ERR) {
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTREM);
+ EnableWindow(hw, TRUE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTEDIT);
+ EnableWindow(hw, TRUE);
+
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTUP);
+ EnableWindow(hw, (sel > 0));
+ hw = GetDlgItem(hwndDlg, IDC_LST_DEST);
+ int count = SendMessage(hw, LB_GETCOUNT, 0, 0);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTDOWN);
+ EnableWindow(hw, (sel < count - 1));
+ }
+ }
+
+ if ( HIWORD( wParam ) == BN_CLICKED ) {
+ switch( LOWORD( wParam )) {
+ case IDC_BTN_DESTEDIT:
+ hw = GetDlgItem(hwndDlg, IDC_LST_DEST);
+ sel = SendMessage(hw, LB_GETCURSEL, 0, 0);
+ if(sel != LB_ERR) {
+ add_edit_addr = temp_list[sel];
+
+ if(DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG3), hwndDlg, DlgProcDestEdit) == IDOK) {
+
+ temp_list[sel] = add_edit_addr;
+ SendMessage(hw, LB_DELETESTRING, (WPARAM)sel, (LPARAM)0);
+ SendMessage(hw, LB_INSERTSTRING, (WPARAM)sel, (LPARAM)temp_list[sel].pszLabel);
+ SendMessage(hw, LB_SETCURSEL, (WPARAM)sel, 0);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTREM);
+ EnableWindow(hw, TRUE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTEDIT);
+ EnableWindow(hw, TRUE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTUP);
+ EnableWindow(hw, TRUE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTDOWN);
+ EnableWindow(hw, TRUE);
+
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ }
+ }
+ break;
+ case IDC_BTN_DESTADD:
+
+ memset(&add_edit_addr,0,sizeof(add_edit_addr));
+ add_edit_addr.cbSize = sizeof(add_edit_addr);
+ add_edit_addr.port = -1;
+ add_edit_addr.set_status = ID_STATUS_ONLINE;
+ add_edit_addr.get_status = ID_STATUS_OFFLINE;
+ add_edit_addr.status = options.nrstatus;
+
+ if(DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG3), hwndDlg, DlgProcDestEdit) == IDOK) {
+
+ temp_list.push_back(add_edit_addr);
+
+ hw = GetDlgItem(hwndDlg, IDC_LST_DEST);
+ int index = SendMessage(hw, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)add_edit_addr.pszLabel);
+ hw = GetDlgItem(hwndDlg, IDC_LST_DEST);
+ SendMessage(hw, LB_SETCURSEL, (WPARAM)index, 0);
+
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTREM);
+ EnableWindow(hw, TRUE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTEDIT);
+ EnableWindow(hw, TRUE);
+
+ sel = temp_list.size() - 1;
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTUP);
+ EnableWindow(hw, (sel > 0));
+ hw = GetDlgItem(hwndDlg, IDC_LST_DEST);
+ int count = SendMessage(hw, LB_GETCOUNT, 0, 0);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTDOWN);
+ EnableWindow(hw, (sel < count - 1));
+
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ }
+
+ break;
+ case IDC_BTN_DESTREM:
+ hw = GetDlgItem(hwndDlg, IDC_LST_DEST);
+ sel = SendMessage(hw, LB_GETCURSEL, 0, 0);
+ if(sel != LB_ERR) {
+ SendMessage(hw, LB_DELETESTRING, (WPARAM)sel, 0);
+ PINGLIST::iterator i = temp_list.begin();
+ while(sel > 0 && i != temp_list.end()) {
+ sel--;
+ i++;
+ }
+ if(i != temp_list.end())
+ temp_list.erase(i);
+ }
+
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTREM);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTEDIT);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTUP);
+ EnableWindow(hw, FALSE);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTDOWN);
+ EnableWindow(hw, FALSE);
+
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ break;
+ case IDC_BTN_DESTDOWN:
+ {
+ hw = GetDlgItem(hwndDlg, IDC_LST_DEST);
+ int sel2 = SendMessage(hw, LB_GETCURSEL, 0, 0);
+ if(sel2 != LB_ERR) {
+ add_edit_addr = temp_list[sel2];
+ temp_list[sel2] = temp_list[sel2 + 1];
+ temp_list[sel2 + 1] = add_edit_addr;
+
+ SendMessage(hw, LB_DELETESTRING, (WPARAM)sel2, (LPARAM)0);
+ SendMessage(hw, LB_INSERTSTRING, (WPARAM)sel2, (LPARAM)temp_list[sel2].pszLabel);
+ SendMessage(hw, LB_DELETESTRING, (WPARAM)(sel2 + 1), (LPARAM)0);
+ SendMessage(hw, LB_INSERTSTRING, (WPARAM)(sel2 + 1), (LPARAM)temp_list[sel2 + 1].pszLabel);
+ SendMessage(hw, LB_SETCURSEL, (WPARAM)(sel2 + 1), 0);
+
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTUP);
+ EnableWindow(hw, (sel2 + 1 > 0));
+ hw = GetDlgItem(hwndDlg, IDC_LST_DEST);
+ int count = SendMessage(hw, LB_GETCOUNT, 0, 0);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTDOWN);
+ EnableWindow(hw, (sel2 + 1 < count - 1));
+
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ }
+ }
+ break;
+ case IDC_BTN_DESTUP:
+ {
+ hw = GetDlgItem(hwndDlg, IDC_LST_DEST);
+ int sel2 = SendMessage(hw, LB_GETCURSEL, 0, 0);
+ if(sel2 != LB_ERR) {
+ add_edit_addr = temp_list[sel2 - 1];
+ temp_list[sel2 - 1] = temp_list[sel2];
+ temp_list[sel2] = add_edit_addr;
+
+ SendMessage(hw, LB_DELETESTRING, (WPARAM)sel2, (LPARAM)0);
+ SendMessage(hw, LB_INSERTSTRING, (WPARAM)sel2, (LPARAM)temp_list[sel2].pszLabel);
+
+ SendMessage(hw, LB_DELETESTRING, (WPARAM)(sel2 - 1), (LPARAM)0);
+ SendMessage(hw, LB_INSERTSTRING, (WPARAM)(sel2 - 1), (LPARAM)temp_list[sel2 - 1].pszLabel);
+
+ SendMessage(hw, LB_SETCURSEL, (WPARAM)(sel2 - 1), 0);
+
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTUP);
+ EnableWindow(hw, (sel2 - 1 > 0));
+ hw = GetDlgItem(hwndDlg, IDC_LST_DEST);
+ int count = SendMessage(hw, LB_GETCOUNT, 0, 0);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTDOWN);
+ EnableWindow(hw, (sel2 - 1 < count - 1));
+
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ }
+ }
+
+ break;
+ }
+ }
+ break;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->code == PSN_APPLY ) {
+ CallService(PROTO "/SetAndSavePingList", (WPARAM)&temp_list, 0);
+ CallService(PROTO "/GetPingList", 0, (LPARAM)&temp_list);
+ // the following will be affected due to list rebuild event
+ //if(hWakeEvent) SetEvent(hWakeEvent);
+ return TRUE;
+ }
+ break;
+
+ }
+ return FALSE;
+}
+
+int PingOptInit(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp = { 0 };
+ odp.cbSize = sizeof(odp);
+ odp.position = -790000000;
+ odp.hInstance = hInst;
+ odp.pszTemplate = MAKEINTRESOURCE(IDD_DIALOG1);
+ odp.pszTitle = Translate("PING");
+ odp.pszGroup = Translate("Network");
+ odp.flags = ODPF_BOLDGROUPS;
+ odp.nIDBottomSimpleControl = IDC_PPM;
+ odp.pfnDlgProc = DlgProcOpts;
+ CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp );
+
+ OPTIONSDIALOGPAGE odp2 = { 0 };
+ odp2.cbSize = sizeof(odp);
+ odp2.position = -790000100;
+ odp2.hInstance = hInst;
+ odp2.pszTemplate = MAKEINTRESOURCE(IDD_DIALOG2);
+ odp2.pszTitle = Translate("PING Destinations");
+ odp2.pszGroup = Translate("Network");
+ odp2.flags = ODPF_BOLDGROUPS;
+ odp2.nIDBottomSimpleControl = IDC_PPM;
+ odp2.pfnDlgProc = DlgProcOpts2;
+ CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp2 );
+ return 0;
+}
+
+void LoadOptions() {
+ options.ping_period = DBGetContactSettingDword(NULL, PROTO, "PingPeriod", DEFAULT_PING_PERIOD);
+
+ options.ping_timeout = DBGetContactSettingDword(NULL, PROTO, "PingTimeout", DEFAULT_PING_TIMEOUT);
+ //CallService(PROTO "/SetPingTimeout", (WPARAM)options.ping_timeout, 0);
+ options.show_popup = (DBGetContactSettingByte(NULL, PROTO, "ShowPopup", DEFAULT_SHOW_POPUP ? 1 : 0) == 1);
+ options.show_popup2 = (DBGetContactSettingByte(NULL, PROTO, "ShowPopup2", DEFAULT_SHOW_POPUP2 ? 1 : 0) == 1);
+ options.block_reps = (DBGetContactSettingByte(NULL, PROTO, "BlockReps", DEFAULT_BLOCK_REPS ? 1 : 0) == 1);
+ options.logging = (DBGetContactSettingByte(NULL, PROTO, "LoggingEnabled", DEFAULT_LOGGING_ENABLED ? 1 : 0) == 1);
+
+ options.rstatus = DBGetContactSettingWord(NULL, PROTO, "RespondingStatus", ID_STATUS_ONLINE);
+ options.nrstatus = DBGetContactSettingWord(NULL, PROTO, "NotRespondingStatus", ID_STATUS_AWAY);
+ options.tstatus = DBGetContactSettingWord(NULL, PROTO, "TestingStatus", ID_STATUS_OCCUPIED);
+ options.off_status = DBGetContactSettingWord(NULL, PROTO, "DisabledStatus", ID_STATUS_DND);
+
+ if(options.rstatus == options.off_status) {
+ options.rstatus = ID_STATUS_ONLINE;
+ if(options.off_status == ID_STATUS_ONLINE)
+ options.off_status = ID_STATUS_DND;
+ }
+ if(options.nrstatus == options.off_status) {
+ options.rstatus = ID_STATUS_AWAY;
+ if(options.off_status == ID_STATUS_AWAY)
+ options.off_status = ID_STATUS_DND;
+ }
+ if(options.tstatus == options.off_status) {
+ options.tstatus = ID_STATUS_OCCUPIED;
+ if(options.off_status == ID_STATUS_OCCUPIED)
+ options.off_status = ID_STATUS_DND;
+ }
+
+ options.no_test_status = (DBGetContactSettingByte(NULL, PROTO, "NoTestStatus", DEFAULT_NO_TEST_STATUS ? 1 : 0) == 1);
+ options.hide_proto = (DBGetContactSettingByte(NULL, PROTO, "HideProtocol", DEFAULT_HIDE_PROTOCOL ? 1 : 0) == 1);
+ options.use_status_msg = (DBGetContactSettingByte(NULL, PROTO, "UseStatusMessage", DEFAULT_USE_STATUS_MESSAGE ? 1 : 0) == 1);
+
+ options.retries = DBGetContactSettingDword(NULL, PROTO, "Retries", 0);
+
+ CallService(PROTO "/GetLogFilename", (WPARAM)MAX_PATH, (LPARAM)options.log_filename);
+
+ ICMP::get_instance()->set_timeout(options.ping_timeout * 1000);
+
+}
+
+void SaveOptions() {
+ DBWriteContactSettingDword(NULL, PROTO, "PingPeriod", options.ping_period);
+ DBWriteContactSettingDword(NULL, PROTO, "PingTimeout", options.ping_timeout);
+ //CallService(PROTO "/SetPingTimeout", (WPARAM)options.ping_timeout, 0);
+ DBWriteContactSettingByte(NULL, PROTO, "ShowPopup", options.show_popup ? 1 : 0);
+ DBWriteContactSettingByte(NULL, PROTO, "ShowPopup2", options.show_popup2 ? 1 : 0);
+ DBWriteContactSettingByte(NULL, PROTO, "BlockReps", options.block_reps ? 1 : 0);
+ DBWriteContactSettingByte(NULL, PROTO, "LoggingEnabled", options.logging ? 1 : 0);
+
+ DBWriteContactSettingWord(NULL, PROTO, "RespondingStatus", options.rstatus);
+ DBWriteContactSettingWord(NULL, PROTO, "NotRespondingStatus", options.nrstatus);
+ DBWriteContactSettingWord(NULL, PROTO, "TestingStatus", options.tstatus);
+ DBWriteContactSettingWord(NULL, PROTO, "DisabledStatus", options.off_status);
+
+ DBWriteContactSettingByte(NULL, PROTO, "NoTestStatus", options.no_test_status ? 1 : 0);
+ DBWriteContactSettingByte(NULL, PROTO, "HideProtocol", options.hide_proto ? 1 : 0);
+ DBWriteContactSettingByte(NULL, PROTO, "UseStatusMessage", options.use_status_msg ? 1 : 0);
+
+ DBWriteContactSettingDword(NULL, PROTO, "Retries", options.retries);
+
+ CallService(PROTO "/SetLogFilename", (WPARAM)MAX_PATH, (LPARAM)options.log_filename);
+
+ ICMP::get_instance()->set_timeout(options.ping_timeout * 1000);
+}
diff --git a/ping_protocol/options.h b/ping_protocol/options.h
new file mode 100644
index 0000000..0360b47
--- /dev/null
+++ b/ping_protocol/options.h
@@ -0,0 +1,23 @@
+#ifndef _PING_OPTIONS
+#define _PING_OPTIONS
+
+#include "common.h"
+#include "pinglist.h"
+#include "utils.h"
+#include "icmp.h"
+
+#include "resource.h"
+
+// wake event for ping thread
+extern HANDLE hWakeEvent;
+
+extern PingOptions options;
+extern PINGADDRESS add_edit_addr;
+
+BOOL CALLBACK DlgProcDestEdit(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+int PingOptInit(WPARAM wParam,LPARAM lParam);
+void LoadOptions();
+void SaveOptions();
+
+#endif \ No newline at end of file
diff --git a/ping_protocol/pinggraph.cpp b/ping_protocol/pinggraph.cpp
new file mode 100644
index 0000000..f6a9da5
--- /dev/null
+++ b/ping_protocol/pinggraph.cpp
@@ -0,0 +1,250 @@
+#include "stdafx.h"
+#include "pinggraph.h"
+
+#include <map>
+
+#define ID_REPAINT_TIMER 10101
+
+struct WindowData {
+ HANDLE hContact;
+ HistoryList list;
+};
+
+#define WM_REBUILDLIST (WM_USER + 1)
+
+LRESULT CALLBACK GraphWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg) {
+ case WM_REBUILDLIST:
+ {
+ WindowData *wd = (WindowData *)GetWindowLong(hwnd, GWL_USERDATA);
+
+ bool found = false;
+ EnterCriticalSection(&data_list_cs);
+ for(PINGLIST::iterator i = data_list.begin(); i != data_list.end(); i++) {
+ if(i->hContact == wd->hContact) {
+ wd->list = i->history;
+ found = true;
+ break;
+ }
+ }
+ LeaveCriticalSection(&data_list_cs);
+
+ if(!found) {
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
+ return TRUE;
+ }
+
+ InvalidateRect(hwnd, 0, FALSE);
+ }
+ return TRUE;
+ case WM_SHOWWINDOW:
+ if(wParam == TRUE && lParam == 0) {
+ WindowData *wd = (WindowData *)GetWindowLong(hwnd, GWL_USERDATA);
+
+ KillTimer(hwnd, ID_REPAINT_TIMER);
+#ifdef min
+ SetTimer(hwnd, ID_REPAINT_TIMER, min(options.ping_period * 1000, 5000), 0);
+#else
+ SetTimer(hwnd, ID_REPAINT_TIMER, std::min(options.ping_period * 1000, 5000), 0);
+#endif
+
+ SendMessage(hwnd, WM_REBUILDLIST, 0, 0);
+ }
+ break;
+
+ case WM_TIMER:
+ {
+ SendMessage(hwnd, WM_REBUILDLIST, 0, 0);
+ }
+ return TRUE;
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ HDC hdc;
+ RECT r;
+ WindowData *wd = (WindowData *)GetWindowLong(hwnd, GWL_USERDATA);
+ if(hdc = BeginPaint(hwnd, &ps)) {
+ GetClientRect(hwnd, &r);
+ FillRect(hdc, &r, GetSysColorBrush(COLOR_WINDOW));
+
+ short max_value = -1; // this is minimum graph height, in ms
+ for(HistoryList::iterator hli = wd->list.begin(); hli != wd->list.end(); hli++) {
+ if(hli->first > max_value) max_value = hli->first;
+ }
+
+ max_value = (int)(max_value * 1.2f);
+ if(max_value < MIN_GRAPH_HEIGHT) max_value = MIN_GRAPH_HEIGHT;
+
+#ifdef max
+ float unit_width = (r.right - r.left) / (float)max((int)wd->list.size(), MIN_BARS), // space for at least MIN_BARS bars
+#else
+ float unit_width = (r.right - r.left) / (float)std::max((int)wd->list.size(), MIN_BARS), // space for at least MIN_BARS bars
+#endif
+ unit_height = (r.bottom - r.top) / (float)max_value;
+
+ RECT bar;
+ bar.bottom = r.bottom;
+ float x = r.right - (unit_width * wd->list.size() + 0.5f);
+ bar.left = (int)(x + 0.5f);
+ bar.right = (int)(x + unit_width + 0.5f);
+
+ DWORD last_time = 0, time, start_time = 0;
+ if(wd->list.size())
+ start_time = wd->list.begin()->second;
+
+ HPEN hPenOld, hPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DDKSHADOW));
+ hPenOld = (HPEN)SelectObject(hdc, hPen);
+
+ for(HistoryList::iterator hi = wd->list.begin(); hi != wd->list.end(); hi++) {
+ if(hi->first != -1) {
+ bar.top = bar.bottom - (int)(hi->first * unit_height + 0.5f);
+ FillRect(hdc, &bar, GetSysColorBrush(COLOR_HOTLIGHT));
+ }
+
+ time = hi->second - start_time;
+ if(time / MARK_PERIOD != last_time / MARK_PERIOD) {
+ MoveToEx(hdc, bar.left, r.bottom, 0);
+ LineTo(hdc, bar.left, r.top);
+ }
+
+ last_time = time;
+
+ x += unit_width;
+ bar.left = bar.right;
+ bar.right = (int)(x + unit_width + 0.5f);
+ }
+
+ // draw horizontal lines to mark every 100ms
+ for(int li = 0; li < max_value; li += MARK_TIME) {
+ MoveToEx(hdc, r.left, r.bottom - (int)(li * unit_height + 0.5f), 0);
+ LineTo(hdc, r.right, r.bottom - (int)(li * unit_height + 0.5f));
+ }
+
+ SelectObject(hdc, hPenOld);
+ DeleteObject(hPen);
+
+ SetBkMode(hdc, TRANSPARENT);
+ SetTextColor(hdc, GetSysColor(COLOR_3DDKSHADOW));
+ char buff[64];
+ sprintf(buff, "%dms", MARK_TIME);
+ TextOut(hdc, r.left + 10, r.bottom - (int)(unit_height * MARK_TIME + 0.5f), buff, 5);
+
+ EndPaint(hwnd, &ps);
+ }
+ }
+ return TRUE;
+
+ case WM_ERASEBKGND:
+ return TRUE;
+
+ case WM_SIZE:
+ InvalidateRect(hwnd, 0, FALSE);
+ break;
+ case WM_CLOSE:
+ {
+ KillTimer(hwnd, ID_REPAINT_TIMER);
+ WindowData *wd = (WindowData *)GetWindowLong(hwnd, GWL_USERDATA);
+ if(CallService(MS_DB_CONTACT_IS, (WPARAM)wd->hContact, 0))
+ Utils_SaveWindowPosition(hwnd, wd->hContact, PROTO, "pinggraphwnd");
+ }
+ break;
+ case WM_DESTROY:
+ {
+ WindowData *wd = (WindowData *)GetWindowLong(hwnd, GWL_USERDATA);
+ DBDeleteContactSetting(wd->hContact, PROTO, "WindowHandle");
+ delete wd;
+ }
+ // drop through
+ };
+
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+int ShowGraph(WPARAM wParam, LPARAM lParam) {
+ HWND hGraphWnd = (HWND)DBGetContactSettingDword((HANDLE)wParam, PROTO, "WindowHandle", 0);
+ if(hGraphWnd) {
+ ShowWindow(hGraphWnd, SW_SHOW);
+ SetWindowPos(hGraphWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ return 0;
+ }
+
+ WNDCLASS wndclass;
+ wndclass.style = 0;
+ wndclass.lpfnWndProc = GraphWindowProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = hInst;
+ wndclass.hIcon = LoadSkinnedProtoIcon(PROTO, ID_STATUS_ONLINE);
+ wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
+ wndclass.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = PROTO "GraphWindow";
+ RegisterClass(&wndclass);
+
+ DBVARIANT dbv;
+ char title[256];
+ strcpy(title, "Ping Graph");
+ if(!DBGetContactSetting((HANDLE)wParam, PROTO, "Nick", &dbv)) {
+ strcat(title, " - ");
+ strncat(title, dbv.pszVal, 256 - 13);
+ DBFreeVariant(&dbv);
+ }
+
+ HWND parent = 0;
+ hGraphWnd = CreateWindowEx(0, PROTO "GraphWindow", title,
+ (WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN) & ~CS_VREDRAW & ~CS_HREDRAW,
+ 0,0,800,600,parent,NULL,hInst,NULL);
+
+ DBWriteContactSettingDword((HANDLE)wParam, PROTO, "WindowHandle", (DWORD)hGraphWnd);
+
+ WindowData *wd = new WindowData;
+ wd->hContact = (HANDLE)wParam; // wParam is contact handle
+
+ SetWindowLong(hGraphWnd, GWL_USERDATA, (LONG)wd);
+
+ if(CallService(MS_DB_CONTACT_IS, (WPARAM)wd->hContact, 0))
+ Utils_RestoreWindowPosition(hGraphWnd, wd->hContact, PROTO, "pinggraphwnd");
+
+ if(!IsWindowVisible(hGraphWnd))
+ ShowWindow(hGraphWnd, SW_SHOW);
+
+ return 0;
+}
+
+// save window positions, close windows
+void graphs_cleanup() {
+ HWND hwnd;
+ char *proto;
+ HANDLE hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 );
+ while ( hContact != NULL )
+ {
+ proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (proto && lstrcmp( PROTO, proto) == 0) {
+ if((hwnd = (HWND)DBGetContactSettingDword(hContact, PROTO, "WindowHandle", 0)) != 0) {
+ DestroyWindow(hwnd);
+ DBWriteContactSettingByte(hContact, PROTO, "WindowWasOpen", 1);
+ }
+ }
+
+ hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
+ }
+}
+
+// restore windows that were open when cleanup was called last
+void graphs_init() {
+ char *proto;
+ HANDLE hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 );
+ while ( hContact != NULL )
+ {
+ proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (proto && lstrcmp( PROTO, proto) == 0) {
+ if(DBGetContactSettingByte(hContact, PROTO, "WindowWasOpen", 0) != 0) {
+ ShowGraph((WPARAM)hContact, 0);
+ DBWriteContactSettingByte(hContact, PROTO, "WindowWasOpen", 0);
+ }
+ }
+
+ hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
+ }
+}
diff --git a/ping_protocol/pinggraph.h b/ping_protocol/pinggraph.h
new file mode 100644
index 0000000..d38f99f
--- /dev/null
+++ b/ping_protocol/pinggraph.h
@@ -0,0 +1,21 @@
+#ifndef _PINGGRAPH_H
+#define _PINGGRAPH_H
+
+#include "common.h"
+#include "pinglist.h"
+#include "pingthread.h"
+
+#define MIN_GRAPH_HEIGHT 120 // minimum braph height, ms
+#define MIN_BARS 20 // space for at least this many bars
+#define MARK_PERIOD 3600 // vertical lines every this many secs (3600 == 1 hour)
+#define MARK_TIME 100 // horizontal lines every this many ms
+
+int ShowGraph(WPARAM wParam, LPARAM lParam);
+
+// save window positions, close windows
+void graphs_cleanup();
+
+// restore windows that were open when cleanup was called last?
+void graphs_init();
+
+#endif
diff --git a/ping_protocol/pinglist.cpp b/ping_protocol/pinglist.cpp
new file mode 100644
index 0000000..086fb3e
--- /dev/null
+++ b/ping_protocol/pinglist.cpp
@@ -0,0 +1,249 @@
+#include "stdafx.h"
+#include "pinglist.h"
+
+#include "options.h"
+
+PINGLIST list_items;
+CRITICAL_SECTION list_cs;
+HANDLE reload_event_handle;
+
+
+BOOL clist_handle_changing = FALSE;
+
+BOOL changing_clist_handle() {
+ return clist_handle_changing;
+}
+
+void set_changing_clist_handle(BOOL flag) {
+ clist_handle_changing = flag;
+}
+
+// lParam is address of pointer to a std::list<PINGADDRESS>
+// copies data into this structure
+int GetPingList(WPARAM wParam,LPARAM lParam)
+{
+ PINGLIST *pa = (PINGLIST *)lParam;
+
+ EnterCriticalSection(&list_cs);
+ *pa = list_items;
+ LeaveCriticalSection(&list_cs);
+
+ return 0;
+}
+
+void reset_myhandle() {
+ EnterCriticalSection(&list_cs);
+ set_changing_clist_handle(true);
+ for(PINGLIST::iterator i = list_items.begin(); i != list_items.end(); i++) {
+ DBWriteContactSettingString(i->hContact, "CList", "MyHandle", i->pszLabel);
+ }
+ set_changing_clist_handle(false);
+ LeaveCriticalSection(&list_cs);
+}
+
+
+void write_ping_address(PINGADDRESS *i) {
+ bool is_contact = (bool)(CallService(MS_DB_CONTACT_IS, (WPARAM)i->hContact, 0) != 0);
+
+ if(!is_contact) {
+ //MessageBox(0, "Creating contact", "Ping", MB_OK);
+ i->hContact = (HANDLE)CallService(MS_DB_CONTACT_ADD, 0, 0);
+ CallService( MS_PROTO_ADDTOCONTACT, ( WPARAM )i->hContact, ( LPARAM )PROTO );
+ CallService(MS_IGNORE_IGNORE, (WPARAM)i->hContact, (WPARAM)IGNOREEVENT_USERONLINE);
+ }
+ DBWriteContactSettingString(i->hContact, PROTO, "Address", i->pszName);
+ set_changing_clist_handle(TRUE);
+ DBWriteContactSettingString(i->hContact, "CList", "MyHandle", i->pszLabel);
+ set_changing_clist_handle(FALSE);
+ DBWriteContactSettingString(i->hContact, PROTO, "Nick", i->pszLabel);
+ DBWriteContactSettingWord(i->hContact, PROTO, "Status", i->status);
+ DBWriteContactSettingDword(i->hContact, PROTO, "Port", i->port);
+ DBWriteContactSettingString(i->hContact, PROTO, "Proto", i->pszProto);
+ if(strlen(i->pszCommand))
+ DBWriteContactSettingString(i->hContact, PROTO, "Command", i->pszCommand);
+ else
+ DBDeleteContactSetting(i->hContact, PROTO, "Command");
+ if(strlen(i->pszParams))
+ DBWriteContactSettingString(i->hContact, PROTO, "CommandParams", i->pszParams);
+ else
+ DBDeleteContactSetting(i->hContact, PROTO, "CommandParams");
+ DBWriteContactSettingWord(i->hContact, PROTO, "SetStatus", i->set_status);
+ DBWriteContactSettingWord(i->hContact, PROTO, "GetStatus", i->get_status);
+ DBWriteContactSettingWord(i->hContact, PROTO, "Index", i->index);
+ if(strlen(i->pszCListGroup))
+ DBWriteContactSettingString(i->hContact, "CList", "Group", i->pszCListGroup);
+ else
+ DBDeleteContactSetting(i->hContact, "CList", "Group");
+}
+
+// call with list_cs locked
+void write_ping_addresses() {
+ int index = 0;
+ for(PINGLIST::iterator i = list_items.begin(); i != list_items.end(); i++, index++) {
+ i->index = index;
+ write_ping_address(&(*i));
+ }
+}
+
+void read_ping_address(PINGADDRESS &pa) {
+ DBVARIANT dbv;
+ DBGetContactSetting(pa.hContact, PROTO, "Address", &dbv);
+ strncpy(pa.pszName, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ if(!DBGetContactSetting(pa.hContact, PROTO, "Nick", &dbv)) {
+ strncpy(pa.pszLabel, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ set_changing_clist_handle(TRUE);
+ DBWriteContactSettingString(pa.hContact, "CList", "MyHandle", pa.pszLabel);
+ set_changing_clist_handle(FALSE);
+ } else {
+ if(!DBGetContactSetting(pa.hContact, PROTO, "Label", &dbv)) {
+ strncpy(pa.pszLabel, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ set_changing_clist_handle(TRUE);
+ DBWriteContactSettingString(pa.hContact, "CList", "MyHandle", pa.pszLabel);
+ set_changing_clist_handle(FALSE);
+ DBWriteContactSettingString(pa.hContact, PROTO, "Nick", pa.pszLabel);
+ DBDeleteContactSetting(pa.hContact, PROTO, "Label");
+ } else {
+ if(!DBGetContactSetting(pa.hContact, "CList", "MyHandle", &dbv)) {
+ strncpy(pa.pszLabel, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ } else
+ pa.pszLabel[0] = '\0';
+ }
+ }
+
+ pa.status = DBGetContactSettingWord(pa.hContact, PROTO, "Status", options.nrstatus);
+ pa.port = (int)DBGetContactSettingDword(pa.hContact, PROTO, "Port", -1);
+
+ if(!DBGetContactSetting(pa.hContact, PROTO, "Proto", &dbv)) {
+ strncpy(pa.pszProto, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ } else pa.pszProto[0] = '\0';
+
+ if(!DBGetContactSetting(pa.hContact, PROTO, "Command", &dbv)) {
+ strncpy(pa.pszCommand, dbv.pszVal, MAX_PATH);
+ DBFreeVariant(&dbv);
+ } else
+ pa.pszCommand[0] = '\0';
+ if(!DBGetContactSetting(pa.hContact, PROTO, "CommandParams", &dbv)) {
+ strncpy(pa.pszParams, dbv.pszVal, MAX_PATH);
+ DBFreeVariant(&dbv);
+ } else
+ pa.pszParams[0] = '\0';
+
+ pa.set_status = DBGetContactSettingWord(pa.hContact, PROTO, "SetStatus", ID_STATUS_ONLINE);
+ pa.get_status = DBGetContactSettingWord(pa.hContact, PROTO, "GetStatus", ID_STATUS_OFFLINE);
+
+ pa.responding = false;
+ pa.round_trip_time = 0;
+ pa.miss_count = 0;
+ pa.index = DBGetContactSettingWord(pa.hContact, PROTO, "Index", 0);
+
+ if(!DBGetContactSetting(pa.hContact, "CList", "Group", &dbv)) {
+ strncpy(pa.pszCListGroup, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ } else
+ pa.pszCListGroup[0] = '\0';
+}
+
+// call with list_cs locked
+void read_ping_addresses() {
+ HANDLE hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 );
+ PINGADDRESS pa;
+
+ list_items.clear();
+ while ( hContact != NULL ) {
+ char *proto = ( char* )CallService( MS_PROTO_GETCONTACTBASEPROTO, ( WPARAM )hContact,0 );
+ if ( proto && lstrcmp( PROTO, proto) == 0) {
+ pa.hContact = hContact;
+ read_ping_address(pa);
+ list_items.push_back(pa);
+ }
+
+ hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
+ }
+ std::sort(list_items.begin(), list_items.end(), SAscendingSort());
+}
+
+int LoadPingList(WPARAM wParam, LPARAM lParam) {
+ EnterCriticalSection(&list_cs);
+ read_ping_addresses();
+ LeaveCriticalSection(&list_cs);
+ NotifyEventHooks(reload_event_handle, 0, 0);
+ return 0;
+}
+
+// wParam is zero
+// lParam is zero
+int SavePingList(WPARAM wParam, LPARAM lParam) {
+ EnterCriticalSection(&list_cs);
+ write_ping_addresses();
+ LeaveCriticalSection(&list_cs);
+ NotifyEventHooks(reload_event_handle, 0, 0);
+
+ return 0;
+}
+
+// wParam is address of a PINGLIST structure to replace the current one
+// lParam is zero
+int SetPingList(WPARAM wParam, LPARAM lParam) {
+ PINGLIST *pli = (PINGLIST *)wParam;
+
+ EnterCriticalSection(&list_cs);
+ list_items = *pli;
+ LeaveCriticalSection(&list_cs);
+ NotifyEventHooks(reload_event_handle, 0, 0);
+
+ return 0;
+}
+
+// wParam is address of a PINGLIST structure to replace the current one
+// lParam is zero
+int SetAndSavePingList(WPARAM wParam, LPARAM lParam) {
+ PINGLIST *pli = (PINGLIST *)wParam;
+
+ EnterCriticalSection(&list_cs);
+ // delete items that aren't in the new list
+ bool found;
+ for(PINGLIST::iterator i = list_items.begin(); i != list_items.end(); i++) {
+ found = false;
+ for(PINGLIST::iterator j = pli->begin(); j != pli->end(); j++) {
+ if(i->hContact == j->hContact) {
+ found = true;
+ break;
+ }
+
+ }
+ if(!found) {
+ //MessageBox(0, "Deleting contact", "Ping", MB_OK);
+ // remove prot first, so that our contact deleted event handler isn't activated
+ CallService(MS_PROTO_REMOVEFROMCONTACT, (WPARAM)i->hContact, (LPARAM)PROTO);
+ CallService(MS_DB_CONTACT_DELETE, (WPARAM)i->hContact, 0);
+ }
+ }
+
+ // set new list
+ if(pli->size())
+ list_items = *pli;
+ else
+ list_items.clear();
+
+ write_ping_addresses();
+ LeaveCriticalSection(&list_cs);
+
+ NotifyEventHooks(reload_event_handle, 0, 0);
+
+ return 0;
+}
+
+int ClearPingList(WPARAM wParam, LPARAM lParam) {
+ EnterCriticalSection(&list_cs);
+ list_items.clear();
+ LeaveCriticalSection(&list_cs);
+
+ NotifyEventHooks(reload_event_handle, 0, 0);
+ return 0;
+}
+
diff --git a/ping_protocol/pinglist.h b/ping_protocol/pinglist.h
new file mode 100644
index 0000000..fd5bd8a
--- /dev/null
+++ b/ping_protocol/pinglist.h
@@ -0,0 +1,39 @@
+#ifndef _PINGLIST_H
+#define _PINGLIST_H
+
+#include "common.h"
+
+#include <vector>
+typedef std::vector<PINGADDRESS> PINGLIST;
+
+#include <algorithm> // for sort
+
+extern PINGLIST list_items;
+extern HANDLE reload_event_handle;
+extern CRITICAL_SECTION list_cs;
+
+int LoadPingList(WPARAM wParam, LPARAM lParam);
+int GetPingList(WPARAM wParam,LPARAM lParam);
+int SavePingList(WPARAM wParam, LPARAM lParam);
+int SetPingList(WPARAM wParam, LPARAM lParam); // use when you modified db yourself
+int SetAndSavePingList(WPARAM wParam, LPARAM lParam);
+int ClearPingList(WPARAM wParam, LPARAM lParam);
+
+struct SAscendingSort
+{
+ bool operator()(const PINGADDRESS &rpStart, const PINGADDRESS &rpEnd)
+ {
+ return rpStart.index < rpEnd.index;
+ }
+};
+
+// only call with list_cs locked!
+void write_ping_addresses();
+
+
+BOOL changing_clist_handle();
+void set_changing_clist_handle(BOOL flag);
+
+void reset_myhandle();
+
+#endif
diff --git a/ping_protocol/pingproto.cpp b/ping_protocol/pingproto.cpp
new file mode 100644
index 0000000..9412233
--- /dev/null
+++ b/ping_protocol/pingproto.cpp
@@ -0,0 +1,468 @@
+#include "stdafx.h"
+#include "pingproto.h"
+
+HINSTANCE hInst;
+PLUGINLINK *pluginLink;
+
+HANDLE hNetlibUser = 0;
+HANDLE hFillListEvent = 0, hContactDeleted = 0, hContactDblClick = 0, hContactSettingChanged;
+
+#define NUM_SERVICES 22
+HANDLE hServices[NUM_SERVICES] = {0};
+
+int previousMode,
+ mcStatus = ID_STATUS_OFFLINE;
+
+// protocol related services
+int GetCaps(WPARAM wParam,LPARAM lParam)
+{
+ int ret = 0;
+ switch (wParam) {
+ case PFLAGNUM_1:
+ //ret = PF1_IM | PF1_URL | PF1_FILE | PF1_MODEMSG | PF1_AUTHREQ | PF1_ADDED;
+ //ret = PF1_IMSEND | PF1_URLSEND | PF1_FILESEND | PF1_MODEMSGSEND;
+ //ret = 0;
+ break;
+ case PFLAGNUM_2:
+ if(!options.hide_proto) {
+ //ret = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND
+ // | PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE; //}
+ //ret = options.nrstatus | options.off_status | options.rstatus;
+ ret = Proto_Status2Flag(options.rstatus);
+ if(options.off_status != ID_STATUS_OFFLINE)
+ ret |= Proto_Status2Flag(options.off_status);
+ }
+ break;
+ case PFLAGNUM_3:
+ //ret = PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND | PF2_HEAVYDND;
+ //ret = PF2_ONLINE | PF2_LIGHTDND | PF2_HEAVYDND;
+ //ret = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND
+ //| PF2_HEAVYDND | PF2_FREECHAT | PF2_OUTTOLUNCH | PF2_ONTHEPHONE; //}
+ //ret = options.nrstatus | options.off_status | options.rstatus;
+ //ret = Proto_Status2Flag(options.rstatus) | Proto_Status2Flag(options.off_status);
+ break;
+ case PFLAGNUM_4:
+ break;
+ case PFLAG_UNIQUEIDTEXT:
+ ret = (int) Translate(PROTO);
+ break;
+ case PFLAG_MAXLENOFMESSAGE:
+ ret = 2000;
+ break;
+ case PFLAG_UNIQUEIDSETTING:
+ ret = (int) "Address";
+ break;
+ }
+ return ret;
+}
+
+/** Copy the name of the protocole into lParam
+* @param wParam : max size of the name
+* @param lParam : reference to a char *, which will hold the name
+*/
+int GetName(WPARAM wParam,LPARAM lParam)
+{
+ char *name = (char *)Translate(PROTO);
+#ifdef min
+ size_t size = min(strlen(name),wParam-1); // copy only the first size bytes.
+#else
+ size_t size = std::min(strlen(name),wParam-1); // copy only the first size bytes.
+#endif
+ if(strncpy((char *)lParam,name,size)==NULL)
+ return 1;
+ ((char *)lParam)[size]='\0';
+ return 0;
+}
+
+/** Loads the icon corresponding to the status
+* Called by the CList when the status changes.
+* @param wParam : one of the following values : \n
+ <tt>PLI_PROTOCOL | PLI_ONLINE | PLI_OFFLINE</tt>
+* @return an \c HICON in which the icon has been loaded.
+*/
+int LoadIcon(WPARAM wParam,LPARAM lParam)
+{
+
+ UINT id;
+ switch (wParam & 0xFFFF)
+ {
+ case PLI_PROTOCOL:
+ id = IDI_ICON_PROTO;
+ break;
+ case PLI_ONLINE:
+ id = IDI_ICON_PROTO;
+ break;
+ case PLI_OFFLINE:
+ id = IDI_ICON_PROTO;
+ break;
+ default:
+ return (int) (HICON) NULL;
+ }
+
+ return (int) LoadImage(hInst, MAKEINTRESOURCE(id), IMAGE_ICON,
+ GetSystemMetrics(wParam & PLIF_SMALL ? SM_CXSMICON : SM_CXICON),
+ GetSystemMetrics(wParam & PLIF_SMALL ? SM_CYSMICON : SM_CYICON), 0);
+ return 0;
+}
+
+
+/** Changes the status and notifies everybody
+* @param wParam : The new mode
+* @param lParam : Allways set to 0.
+*/
+int SetStatus(WPARAM wParam,LPARAM lParam)
+{
+ int new_status = (int)wParam;
+
+ if(new_status == options.rstatus || options.nrstatus || options.off_status) {
+ previousMode = mcStatus;
+ mcStatus = new_status;
+ ProtoBroadcastAck(PROTO,NULL,ACKTYPE_STATUS,ACKRESULT_SUCCESS, (HANDLE)previousMode, mcStatus);
+
+ if(new_status == options.off_status)
+ PingDisableAll(0, 0);
+ else if(previousMode == options.off_status)
+ PingEnableAll(0, 0);
+ }
+
+ return 0;
+}
+
+/** Returns the current status
+*/
+int GetStatus(WPARAM wParam,LPARAM lParam)
+{
+ return mcStatus;
+}
+
+// plugin stuff
+PLUGININFO pluginInfo={
+ sizeof(PLUGININFO),
+ "Ping Protocol",
+ PLUGIN_MAKE_VERSION(0, 4, 0, 0),
+ "Ping labelled IP addresses or domain names.",
+ "Scott Ellis",
+ "mail@scottellis.com.au",
+ "© 2005 Scott Ellis",
+ "http://www.scottellis.com.au/",
+ 0, //not transient
+ 0 //doesn't replace anything built-in
+};
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ hInst=hinstDLL;
+ return TRUE;
+}
+
+extern "C" PINGPROTO_API PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ return &pluginInfo;
+}
+
+int ContactDeleted(WPARAM wParam, LPARAM lParam) {
+ if ( CallService(MS_PROTO_ISPROTOONCONTACT, wParam, (LPARAM)PROTO) ) {
+ CallService(MS_PROTO_REMOVEFROMCONTACT, wParam, (LPARAM)PROTO);
+ HWND hGraphWnd = (HWND)DBGetContactSettingDword((HANDLE)wParam, PROTO, "WindowHandle", 0);
+ if(hGraphWnd) PostMessage(hGraphWnd, WM_CLOSE, 0, 0);
+ CallService(PROTO "/LoadPingList", 0, 0);
+ }
+
+ return 0;
+}
+
+int ContactSettingChanged(WPARAM wParam, LPARAM lParam) {
+ DBCONTACTWRITESETTING *dcws = (DBCONTACTWRITESETTING *)lParam;
+
+ if ( CallService(MS_PROTO_ISPROTOONCONTACT, wParam, (LPARAM)PROTO) ) {
+ if(!strcmp(dcws->szModule, "CList") && !strcmp(dcws->szSetting, "MyHandle")) {
+ if(!changing_clist_handle()) {
+ if(!dcws->value.type == DBVT_DELETED) {
+ DBWriteContactSettingString((HANDLE)wParam, PROTO, "Nick", dcws->value.pszVal);
+ CallService(PROTO "/LoadPingList", 0, 0);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+//////////////////////////////////////////////////////////
+/// Copied from MSN plugin - sent acks need to be from different thread :(
+//////////////////////////////////////////////////////////
+typedef struct tag_TFakeAckParams
+{
+ HANDLE hEvent;
+ HANDLE hContact;
+} TFakeAckParams;
+
+
+static DWORD CALLBACK sttFakeAckInfoSuccess( LPVOID param )
+{
+ TFakeAckParams *tParam = ( TFakeAckParams* )param;
+ WaitForSingleObject( tParam->hEvent, INFINITE );
+
+ Sleep( 100 );
+ ProtoBroadcastAck(PROTO, tParam->hContact, ACKTYPE_GETINFO, ACKRESULT_SUCCESS, ( HANDLE )1, 0 );
+
+ CloseHandle( tParam->hEvent );
+ free(tParam);
+ return 0;
+}
+
+int GetInfo(WPARAM wParam, LPARAM lParam) {
+ CCSDATA *ccs = (CCSDATA *) lParam;
+ DWORD dwThreadId;
+ HANDLE hEvent;
+ TFakeAckParams *tfap;
+
+ hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
+
+ tfap = (TFakeAckParams *)malloc(sizeof(TFakeAckParams));
+ tfap->hContact = ccs->hContact;
+ tfap->hEvent = hEvent;
+
+ CloseHandle( CreateThread( NULL, 0, sttFakeAckInfoSuccess, tfap, 0, &dwThreadId ));
+ SetEvent( hEvent );
+
+
+ return 0;
+}
+
+void CreatePluginServices() {
+ int i = 0;
+ // protocol
+ hServices[i++] = CreateProtoServiceFunction(PROTO,PS_GETCAPS, GetCaps);
+ hServices[i++] = CreateProtoServiceFunction(PROTO,PS_GETNAME, GetName);
+ hServices[i++] = CreateProtoServiceFunction(PROTO,PS_SETSTATUS, SetStatus);
+ hServices[i++] = CreateProtoServiceFunction(PROTO,PS_GETSTATUS, GetStatus);
+ hServices[i++] = CreateProtoServiceFunction(PROTO,PS_LOADICON,LoadIcon);
+ hServices[i++] = CreateProtoServiceFunction(PROTO,PSS_GETINFO,GetInfo);
+
+ // general
+ hServices[i++] = CreateServiceFunction(PROTO "/Ping", PluginPing);
+
+ // list
+ hServices[i++] = CreateServiceFunction(PROTO "/ClearPingList", ClearPingList);
+ hServices[i++] = CreateServiceFunction(PROTO "/GetPingList", GetPingList);
+ hServices[i++] = CreateServiceFunction(PROTO "/SetPingList", SetPingList);
+ hServices[i++] = CreateServiceFunction(PROTO "/SetAndSavePingList", SetAndSavePingList);
+ hServices[i++] = CreateServiceFunction(PROTO "/LoadPingList", LoadPingList);
+ hServices[i++] = CreateServiceFunction(PROTO "/SavePingList", SavePingList);
+
+ reload_event_handle = CreateHookableEvent(PROTO "/ListReload");
+
+ //log
+ hServices[i++] = CreateServiceFunction(PROTO "/Log", Log);
+ hServices[i++] = CreateServiceFunction(PROTO "/ViewLogData", ViewLogData);
+ hServices[i++] = CreateServiceFunction(PROTO "/GetLogFilename", GetLogFilename);
+ hServices[i++] = CreateServiceFunction(PROTO "/SetLogFilename", SetLogFilename);
+
+ // menu
+ hServices[i++] = CreateServiceFunction(PROTO "/DisableAll", PingDisableAll);
+ hServices[i++] = CreateServiceFunction(PROTO "/EnableAll", PingEnableAll);
+ hServices[i++] = CreateServiceFunction(PROTO "/ToggleEnabled", ToggleEnabled);
+ hServices[i++] = CreateServiceFunction(PROTO "/ShowGraph", ShowGraph);
+ hServices[i++] = CreateServiceFunction(PROTO "/Edit", EditContact);
+
+}
+
+void DestroyPluginServices() {
+ /*
+ DestroyServiceFunction(PROTO PS_GETCAPS);
+ DestroyServiceFunction(PROTO PS_GETNAME);
+ DestroyServiceFunction(PROTO PS_SETSTATUS);
+ DestroyServiceFunction(PROTO PS_GETSTATUS);
+ DestroyServiceFunction(PROTO PS_LOADICON);
+ DestroyServiceFunction(PROTO PSS_GETINFO);
+
+ DestroyServiceFunction(PROTO "/Ping");
+
+ DestroyServiceFunction(PROTO "/ClearPingList");
+ DestroyServiceFunction(PROTO "/GetPingList");
+ DestroyServiceFunction(PROTO "/SetPingList");
+ DestroyServiceFunction(PROTO "/SetAndSavePingList");
+ DestroyServiceFunction(PROTO "/LoadPingList");
+ DestroyServiceFunction(PROTO "/SavePingList");
+
+
+ DestroyServiceFunction(PROTO "/Log");
+ DestroyServiceFunction(PROTO "/ViewLogData");
+ DestroyServiceFunction(PROTO "/GetLogFilename");
+ DestroyServiceFunction(PROTO "/SetLogFilename");
+
+ // menu
+ DestroyServiceFunction(PROTO "/DisableAll");
+ DestroyServiceFunction(PROTO "/EnableAll");
+ DestroyServiceFunction(PROTO "/ToggleEnabled");
+ DestroyServiceFunction(PROTO "/ShowGraph");
+ DestroyServiceFunction(PROTO "/Edit");
+ */
+ for(int i = 0; i < NUM_SERVICES; i++)
+ if(hServices[i]) DestroyServiceFunction(hServices[i]);
+
+ DestroyHookableEvent(reload_event_handle);
+
+}
+
+int OnShutdown(WPARAM wParam, LPARAM lParam) {
+ graphs_cleanup();
+ return 0;
+}
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam) {
+
+ // register for autoupdates
+ CallService(MS_UPDATE_REGISTERFL, (WPARAM)1826, (LPARAM)&pluginInfo);
+
+ NETLIBUSER nl_user = {0};
+ nl_user.cbSize = sizeof(nl_user);
+ nl_user.szSettingsModule = PROTO;
+ //nl_user.flags = NUF_OUTGOING | NUF_HTTPGATEWAY | NUF_NOOPTIONS;
+ //nl_user.flags = NUF_OUTGOING | NUF_NOOPTIONS;
+ nl_user.flags = NUF_OUTGOING | NUF_HTTPCONNS;
+ nl_user.szDescriptiveName = "Ping Protocol Plugin";
+ nl_user.szHttpGatewayHello = 0;
+ nl_user.szHttpGatewayUserAgent = 0;
+ nl_user.pfnHttpGatewayInit = 0;
+ nl_user.pfnHttpGatewayWrapSend = 0;
+ nl_user.pfnHttpGatewayUnwrapRecv = 0;
+
+ hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nl_user);
+
+ InitMenus();
+
+ hFillListEvent = HookEvent(PROTO "/ListReload", FillList);
+
+ if(!DBGetContactSettingByte(0, PROTO, "PingPlugImport", 0)) {
+ if(DBGetContactSettingDword(0, "PingPlug", "NumEntries", 0)) {
+ if(MessageBox(0, Translate("Old PingPlug data detected in database.\nWould you like to import?"), Translate(PROTO "PingPlug Import"), MB_YESNO) == IDYES) {
+ import_ping_addresses();
+ DBWriteContactSettingByte(0, PROTO, "PingPlugImport", 1);
+ } else {
+ if(MessageBox(0, Translate("Should I ask this question again\nnext time you start Miranda?"), Translate(PROTO "PingPlug Import"), MB_YESNO) == IDNO) {
+ DBWriteContactSettingByte(0, PROTO, "PingPlugImport", 1);
+ }
+ }
+ }
+ }
+ CallService(PROTO "/LoadPingList", 0, 0);
+
+ //ignore status for all PING contacts
+ {
+ char *proto;
+ HANDLE hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 );
+ while ( hContact != NULL )
+ {
+ proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if (proto && lstrcmp(PROTO, proto) == 0) {
+ CallService(MS_IGNORE_IGNORE, (WPARAM)hContact, (WPARAM)IGNOREEVENT_USERONLINE);
+ DBDeleteContactSetting(hContact, PROTO, "WindowHandle"); // bugfix - windows left open when miranda closed never open again!
+ }
+
+ hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
+ }
+ }
+
+ hContactDeleted = HookEvent(ME_DB_CONTACT_DELETED, ContactDeleted);
+ hContactSettingChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, ContactSettingChanged);
+
+ hContactDblClick = HookEvent(ME_CLIST_DOUBLECLICKED, ContactDblClick);
+
+ graphs_init();
+
+ start_ping_thread();
+
+ if(options.logging) CallService(PROTO "/Log", (WPARAM)"start", 0);
+
+ return 0;
+}
+
+extern "C" PINGPROTO_API int Load(PLUGINLINK *link)
+{
+ pluginLink=link;
+
+ if(init_raw_ping()) {
+ //MessageBox(0, Translate("Failed to initialize. Plugin disabled."), Translate("PING Protocol"), MB_OK | MB_ICONERROR);
+ //return 1;
+ use_raw_ping = false;
+ }
+ DBWriteContactSettingByte(0, PROTO, "UsingRawSockets", (BYTE)use_raw_ping);
+
+ DuplicateHandle( GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &mainThread, THREAD_SET_CONTEXT, FALSE, 0 );
+ hWakeEvent = CreateEvent(NULL, FALSE, FALSE, "Local\\ThreadWaitEvent");
+
+ previousMode = mcStatus = ID_STATUS_OFFLINE;
+
+ InitializeCriticalSection(&list_cs);
+ InitializeCriticalSection(&thread_finished_cs);
+ InitializeCriticalSection(&list_changed_cs);
+ InitializeCriticalSection(&data_list_cs);
+
+ PROTOCOLDESCRIPTOR pd = {0};
+ pd.cbSize=sizeof(pd);
+ pd.szName=PROTO;
+ pd.type = PROTOTYPE_PROTOCOL;
+ CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd);
+
+ // create services before loading options - so we can have the 'getlogfilename' service!
+ CreatePluginServices();
+
+ LoadOptions();
+
+ //set all contacts to 'not responding' if not 'disabled'
+ {
+ char *proto;
+ HANDLE hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 );
+ while ( hContact != NULL )
+ {
+ proto = ( char* )CallService( MS_PROTO_GETCONTACTBASEPROTO, ( WPARAM )hContact,0 );
+ if ( proto && !lstrcmp( PROTO, proto)) {
+ if(DBGetContactSettingWord( hContact, PROTO, "Status", options.nrstatus) != options.off_status)
+ DBWriteContactSettingWord( hContact, PROTO, "Status", options.nrstatus);
+ }
+
+ hContact = ( HANDLE )CallService( MS_DB_CONTACT_FINDNEXT,( WPARAM )hContact, 0 );
+ }
+ }
+
+ SkinAddNewSound("PingProtoTimeout", "Ping Timout", 0);
+ SkinAddNewSound("PingProtoReply", "Ping Reply", 0);
+
+ HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
+
+ HookEvent(ME_OPT_INITIALISE, PingOptInit );
+
+ //HookEvent(ME_SYSTEM_SHUTDOWN, OnShutdown);
+ HookEvent(ME_SYSTEM_PRESHUTDOWN, OnShutdown);
+
+ return 0;
+}
+
+extern "C" PINGPROTO_API int Unload(void)
+{
+ UnhookEvent(hContactDblClick);
+ UnhookEvent(hFillListEvent);
+ UnhookEvent(hContactDeleted);
+ UnhookEvent(hContactSettingChanged);
+ stop_ping_thread();
+
+ DestroyPluginServices();
+
+ DeleteCriticalSection(&list_cs);
+ DeleteCriticalSection(&thread_finished_cs);
+ DeleteCriticalSection(&list_changed_cs);
+ DeleteCriticalSection(&data_list_cs);
+
+ CloseHandle( mainThread );
+
+ if(use_raw_ping)
+ cleanup_raw_ping();
+ else
+ ICMP::get_instance()->stop();
+
+ if(options.logging) CallService(PROTO "/Log", (WPARAM)"stop", 0);
+
+ return 0;
+}
diff --git a/ping_protocol/pingproto.dsp b/ping_protocol/pingproto.dsp
new file mode 100644
index 0000000..d18a330
--- /dev/null
+++ b/ping_protocol/pingproto.dsp
@@ -0,0 +1,217 @@
+# Microsoft Developer Studio Project File - Name="pingproto" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=pingproto - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "pingproto.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "pingproto.mak" CFG="pingproto - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "pingproto - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "pingproto - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "pingproto - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 2
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PINGPROTO_VC6_EXPORTS" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PINGPROTO_EXPORTS" /D "_WINDLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0xc09 /d "NDEBUG"
+# ADD RSC /l 0xc09 /d "NDEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 ws2_32.lib wsock32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib /nologo /base:"0x22050000" /dll /machine:I386 /out:"../../bin/release/plugins/pingproto.dll"
+# SUBTRACT LINK32 /nodefaultlib
+
+!ELSEIF "$(CFG)" == "pingproto - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 2
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PINGPROTO_VC6_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PINGPROTO_EXPORTS" /D "_WINDLL" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0xc09 /d "_DEBUG"
+# ADD RSC /l 0xc09 /d "_DEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 user32.lib gdi32.lib ws2_32.lib shell32.lib comdlg32.lib /nologo /dll /debug /machine:I386 /out:"../../bin/debug/plugins/pingproto.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "pingproto - Win32 Release"
+# Name "pingproto - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\icmp.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\log.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\menu.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\pinggraph.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\pinglist.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\pingproto.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\pingthread.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\rawping.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\utils.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\common.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\icmp.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\log.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\menu.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\pinggraph.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\pinglist.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\pingproto.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\pingthread.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\rawping.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\utils.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\icon1.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\pingproto.rc
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\cut_code.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\ReadMe.txt
+# End Source File
+# End Target
+# End Project
diff --git a/ping_protocol/pingproto.dsw b/ping_protocol/pingproto.dsw
new file mode 100644
index 0000000..345ac5c
--- /dev/null
+++ b/ping_protocol/pingproto.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "pingproto"=".\pingproto.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/ping_protocol/pingproto.h b/ping_protocol/pingproto.h
new file mode 100644
index 0000000..cb70bd6
--- /dev/null
+++ b/ping_protocol/pingproto.h
@@ -0,0 +1,43 @@
+/*
+Based on the
+Miranda plugin template, originally by Richard Hughes
+http://miranda-icq.sourceforge.net/
+
+© 2004 Scott Ellis
+
+*/
+
+#ifndef _PINGPROTO
+#define _PINGPROTO
+
+
+// The following ifdef block is the standard way of creating macros which make exporting
+// from a DLL simpler. All files within this DLL are compiled with the PINGPROTO_EXPORTS
+// symbol defined on the command line. this symbol should not be defined on any project
+// that uses this DLL. This way any other project whose source files include this file see
+// PINGPROTO_API functions as being imported from a DLL, wheras this DLL sees symbols
+// defined with this macro as being exported.
+#ifdef PINGPROTO_EXPORTS
+#define PINGPROTO_API __declspec(dllexport)
+#else
+#define PINGPROTO_API __declspec(dllimport)
+#endif
+
+#include "common.h"
+#include "utils.h"
+#include "options.h"
+#include "pinglist.h"
+#include "log.h"
+#include "pingthread.h"
+#include "menu.h"
+#include "rawping.h"
+
+// globals
+extern PLUGINLINK *pluginLink;
+extern PLUGININFO pluginInfo;
+
+extern "C" PINGPROTO_API PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion);
+extern "C" PINGPROTO_API int Load(PLUGINLINK *link);
+extern "C" PINGPROTO_API int Unload(void);
+
+#endif
diff --git a/ping_protocol/pingproto.mdsp b/ping_protocol/pingproto.mdsp
new file mode 100644
index 0000000..0396fac
--- /dev/null
+++ b/ping_protocol/pingproto.mdsp
@@ -0,0 +1,117 @@
+[Project]
+name=pingproto
+type=2
+defaultConfig=1
+
+
+[Debug]
+// compiler
+workingDirectory=
+arguments=
+intermediateFilesDirectory=Debug
+outputFilesDirectory=Debug
+compilerPreprocessor=PINGPROTO_EXPORTS
+extraCompilerOptions=
+compilerIncludeDirectory=
+noWarning=0
+defaultWarning=0
+allWarning=1
+extraWarning=0
+isoWarning=0
+warningsAsErrors=0
+debugType=1
+debugLevel=2
+exceptionEnabled=1
+runtimeTypeEnabled=1
+optimizeLevel=0
+
+// linker
+libraryPath=
+outputFilename=Debug\pingproto.dll
+libraries=ws2_32,gdi32,comdlg32
+extraLinkerOptions=
+ignoreStartupFile=0
+ignoreDefaultLibs=0
+stripExecutableFile=0
+
+// archive
+extraArchiveOptions=
+
+//resource
+resourcePreprocessor=
+resourceIncludeDirectory=
+extraResourceOptions=
+
+[Release]
+// compiler
+workingDirectory=
+arguments=
+intermediateFilesDirectory=Release
+outputFilesDirectory=Release
+compilerPreprocessor=PINGPROTO_EXPORTS
+extraCompilerOptions=
+compilerIncludeDirectory=
+noWarning=0
+defaultWarning=0
+allWarning=1
+extraWarning=0
+isoWarning=0
+warningAsErrors=0
+debugType=0
+debugLevel=1
+exceptionEnabled=1
+runtimeTypeEnabled=1
+optimizeLevel=2
+
+// linker
+libraryPath=
+outputFilename=Release\pingproto.dll
+libraries=ws2_32,gdi32,comdlg32
+extraLinkerOptions=
+ignoreStartupFile=0
+ignoreDefaultLibs=0
+stripExecutableFile=1
+
+// archive
+extraArchiveOptions=
+
+//resource
+resourcePreprocessor=
+resourceIncludeDirectory=
+extraResourceOptions=
+
+[Source]
+1=StdAfx.cpp
+2=icmp.cpp
+3=log.cpp
+4=menu.cpp
+5=options.cpp
+6=pinggraph.cpp
+7=pinglist.cpp
+8=pingproto.cpp
+9=pingthread.cpp
+10=rawping.cpp
+11=utils.cpp
+[Header]
+1=StdAfx.h
+2=common.h
+3=icmp.h
+4=log.h
+5=menu.h
+6=options.h
+7=pinggraph.h
+8=pinglist.h
+9=pingproto.h
+10=pingthread.h
+11=rawping.h
+12=resource.h
+13=utils.h
+[Resource]
+1=pingproto.rc
+[Other]
+[History]
+pinglist.h,604
+pinglist.cpp,0
+common.h,2379
+pingproto.h,757
+pingproto.rc,8940
diff --git a/ping_protocol/pingproto.plg b/ping_protocol/pingproto.plg
new file mode 100644
index 0000000..96ec617
--- /dev/null
+++ b/ping_protocol/pingproto.plg
@@ -0,0 +1,80 @@
+<html>
+<body>
+<pre>
+<h1>Build Log</h1>
+<h3>
+--------------------Configuration: pingproto - Win32 Release--------------------
+</h3>
+<h3>Command Lines</h3>
+Creating temporary file "C:\DOCUME~1\sje\LOCALS~1\Temp\RSP4C.tmp" with contents
+[
+/nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PINGPROTO_EXPORTS" /D "_WINDLL" /D "_AFXDLL" /Fp"Release/pingproto.pch" /Yu"stdafx.h" /Fo"Release/" /Fd"Release/" /FD /c
+"C:\Documents and Settings\sje\My Documents\MyProjects\miranda\plugins\pingproto\options.cpp"
+]
+Creating command line "cl.exe @C:\DOCUME~1\sje\LOCALS~1\Temp\RSP4C.tmp"
+Creating temporary file "C:\DOCUME~1\sje\LOCALS~1\Temp\RSP4D.tmp" with contents
+[
+ws2_32.lib wsock32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib /nologo /base:"0x22050000" /dll /incremental:no /pdb:"Release/pingproto.pdb" /machine:I386 /out:"../../bin/release/plugins/pingproto.dll" /implib:"Release/pingproto.lib"
+".\Release\icmp.obj"
+".\Release\log.obj"
+".\Release\menu.obj"
+".\Release\options.obj"
+".\Release\pinggraph.obj"
+".\Release\pinglist.obj"
+".\Release\pingproto.obj"
+".\Release\pingthread.obj"
+".\Release\rawping.obj"
+".\Release\StdAfx.obj"
+".\Release\utils.obj"
+".\Release\pingproto.res"
+]
+Creating command line "link.exe @C:\DOCUME~1\sje\LOCALS~1\Temp\RSP4D.tmp"
+<h3>Output Window</h3>
+Compiling...
+options.cpp
+Linking...
+ Creating library Release/pingproto.lib and object Release/pingproto.exp
+
+
+
+<h3>Results</h3>
+pingproto.dll - 0 error(s), 0 warning(s)
+<h3>
+--------------------Configuration: pingproto - Win32 Debug--------------------
+</h3>
+<h3>Command Lines</h3>
+Creating temporary file "C:\DOCUME~1\sje\LOCALS~1\Temp\RSP51.tmp" with contents
+[
+/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PINGPROTO_EXPORTS" /D "_WINDLL" /D "_AFXDLL" /Fp"Debug/pingproto.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
+"C:\Documents and Settings\sje\My Documents\MyProjects\miranda\plugins\pingproto\options.cpp"
+]
+Creating command line "cl.exe @C:\DOCUME~1\sje\LOCALS~1\Temp\RSP51.tmp"
+Creating temporary file "C:\DOCUME~1\sje\LOCALS~1\Temp\RSP52.tmp" with contents
+[
+user32.lib gdi32.lib ws2_32.lib shell32.lib comdlg32.lib /nologo /dll /incremental:yes /pdb:"Debug/pingproto.pdb" /debug /machine:I386 /out:"../../bin/debug/plugins/pingproto.dll" /implib:"Debug/pingproto.lib" /pdbtype:sept
+".\Debug\icmp.obj"
+".\Debug\log.obj"
+".\Debug\menu.obj"
+".\Debug\options.obj"
+".\Debug\pinggraph.obj"
+".\Debug\pinglist.obj"
+".\Debug\pingproto.obj"
+".\Debug\pingthread.obj"
+".\Debug\rawping.obj"
+".\Debug\StdAfx.obj"
+".\Debug\utils.obj"
+".\Debug\pingproto.res"
+]
+Creating command line "link.exe @C:\DOCUME~1\sje\LOCALS~1\Temp\RSP52.tmp"
+<h3>Output Window</h3>
+Compiling...
+options.cpp
+Linking...
+
+
+
+<h3>Results</h3>
+pingproto.dll - 0 error(s), 0 warning(s)
+</pre>
+</body>
+</html>
diff --git a/ping_protocol/pingproto.rc b/ping_protocol/pingproto.rc
new file mode 100644
index 0000000..670e0fe
--- /dev/null
+++ b/ping_protocol/pingproto.rc
@@ -0,0 +1,226 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON_PROTO ICON "icon1.ico"
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (Australia) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG1 DIALOGEX 0, 0, 313, 183
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ RTEXT "Delay between pings (secs):",IDC_STATIC,12,20,121,8
+ EDITTEXT IDC_PPM,138,16,40,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "Timeout",IDC_CHECKPOPUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,226,21,74,10
+ RTEXT "Ping timeout (secs):",IDC_STATIC,12,36,121,8
+ EDITTEXT IDC_PT,138,34,40,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ GROUPBOX "Logging",IDC_STATIC,7,121,299,55
+ CONTROL "Log to File",IDC_CHK_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,99,134,61,10
+ LTEXT "Log Filename:",IDC_STATIC,17,154,56,8
+ EDITTEXT IDC_ED_FILENAME,77,151,158,14,ES_AUTOHSCROLL
+ GROUPBOX "Network",IDC_STATIC,7,8,211,62
+ GROUPBOX "PopUps",IDC_STATIC,222,8,84,62
+ CONTROL "Reply",IDC_CHECKPOPUP2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,226,35,73,10
+ CONTROL "Block Repetitions",IDC_CHK_BLOCK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,226,53,73,10
+ PUSHBUTTON "View Log",IDC_BTN_VIEWLOG,169,132,59,14
+ PUSHBUTTON "Browse...",IDC_BTN_LOGBROWSE,241,150,54,16
+ GROUPBOX "Status",IDC_STATIC,7,72,299,46
+ CONTROL "Hide in status bar and status menu (requires restart - uncheck to set icons)",IDC_CHK_HIDEPROTO,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,101,272,10
+ RTEXT "Repeats for success/failure:",IDC_STATIC,12,53,121,8
+ EDITTEXT IDC_RPT,138,52,40,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "Put details in status message",IDC_CHK_USESTATUSMSG,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,87,120,10
+END
+
+IDD_DIALOG2 DIALOG 0, 0, 303, 212
+STYLE DS_SETFONT | WS_POPUP
+FONT 8, "MS Sans Serif"
+BEGIN
+ GROUPBOX "Ping Destinations",IDC_STATIC,7,7,289,198
+ PUSHBUTTON "Add",IDC_BTN_DESTADD,38,172,38,15
+ LISTBOX IDC_LST_DEST,37,32,228,128,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Remove",IDC_BTN_DESTREM,132,172,38,15,WS_DISABLED
+ PUSHBUTTON "Edit",IDC_BTN_DESTEDIT,85,172,38,15,WS_DISABLED
+ PUSHBUTTON "Up",IDC_BTN_DESTUP,179,172,38,15,WS_DISABLED
+ PUSHBUTTON "Down",IDC_BTN_DESTDOWN,226,172,38,15,WS_DISABLED
+END
+
+IDD_DIALOG3 DIALOGEX 0, 0, 264, 326
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Ping Destination"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,78,305,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,134,305,50,14
+ RTEXT "Address:",IDC_STATIC,12,34,51,8
+ RTEXT "Label:",IDC_STATIC,16,49,47,8
+ EDITTEXT IDC_ED_DESTADDR,67,30,154,12,ES_AUTOHSCROLL | ES_WANTRETURN
+ EDITTEXT IDC_ED_DESTLAB,67,48,154,12,ES_AUTOHSCROLL | ES_WANTRETURN
+ CONTROL "TCP Connect",IDC_CHK_DESTTCP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,68,69,71,10
+ LTEXT "Port:",IDC_STATIC,147,69,30,8,0,WS_EX_RIGHT
+ EDITTEXT IDC_ED_DESTPORT,181,67,40,12,ES_RIGHT | ES_AUTOHSCROLL | ES_WANTRETURN | ES_NUMBER | WS_DISABLED
+ CTEXT "Add to contact list group:",IDC_STATIC,63,90,138,8
+ COMBOBOX IDC_COMBO_GROUP,70,104,122,148,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ CTEXT "Control Protocol:",IDC_STATIC,84,141,92,8
+ COMBOBOX IDC_COMBO_DESTPROTO,83,154,97,106,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_COMBO_DESTSTAT,156,193,76,83,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Set my status to:",IDC_STATIC,156,179,87,8
+ LTEXT "On success, if my status is:",IDC_STATIC,33,179,111,8
+ COMBOBOX IDC_COMBO_DESTSTAT2,33,193,90,76,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_ED_COMMAND,25,232,213,16,ES_AUTOHSCROLL
+ CTEXT "Execute the following command on double-click:",IDC_STATIC,28,217,207,8
+ GROUPBOX "Contact",IDC_STATIC,7,7,250,119
+ GROUPBOX "Protocols",IDC_STATIC,7,132,250,166
+ EDITTEXT IDC_ED_PARAMS,25,271,213,16,ES_AUTOHSCROLL
+ CTEXT "(Optional) Command Parameters:",IDC_STATIC,27,256,207,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DIALOG1, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 306
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 176
+ END
+
+ IDD_DIALOG2, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 296
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 205
+ END
+
+ IDD_DIALOG3, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 257
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 319
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MENU1 MENU
+BEGIN
+ POPUP "Menu"
+ BEGIN
+ MENUITEM "Disable all pings", ID_MENU_DISABLEALLPINGS
+ MENUITEM "Enable all pings", ID_MENU_ENABLEALLPINGS
+ MENUITEM SEPARATOR
+ MENUITEM "Options...", ID_MENU_OPTIONS
+ MENUITEM "Destinations...", ID_MENU_DESTINATIONS
+ END
+END
+
+#endif // English (Australia) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/ping_protocol/pingproto.sln b/ping_protocol/pingproto.sln
new file mode 100644
index 0000000..80e300a
--- /dev/null
+++ b/ping_protocol/pingproto.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pingproto", "pingproto.vcproj", "{BEA1B271-574A-458C-A284-14F96E5180C4}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BEA1B271-574A-458C-A284-14F96E5180C4}.Debug|Win32.ActiveCfg = Debug|Win32
+ {BEA1B271-574A-458C-A284-14F96E5180C4}.Debug|Win32.Build.0 = Debug|Win32
+ {BEA1B271-574A-458C-A284-14F96E5180C4}.Release|Win32.ActiveCfg = Release|Win32
+ {BEA1B271-574A-458C-A284-14F96E5180C4}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/ping_protocol/pingproto.vcproj b/ping_protocol/pingproto.vcproj
new file mode 100644
index 0000000..d7ff013
--- /dev/null
+++ b/ping_protocol/pingproto.vcproj
@@ -0,0 +1,544 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="pingproto"
+ ProjectGUID="{BEA1B271-574A-458C-A284-14F96E5180C4}"
+ RootNamespace="pingproto"
+ Keyword="MFCProj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="2"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="_DEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/pingproto.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PINGPROTO_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile=".\Debug/pingproto.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="3081"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="user32.lib gdi32.lib ws2_32.lib shell32.lib comdlg32.lib"
+ OutputFile="../../bin/debug/plugins/pingproto.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug/pingproto.pdb"
+ ImportLibrary=".\Debug/pingproto.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Debug/pingproto.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="2"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/pingproto.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="1"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PINGPROTO_EXPORTS"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="stdafx.h"
+ PrecompiledHeaderFile=".\Release/pingproto.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="3081"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib wsock32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib"
+ OutputFile="../../bin/release/plugins/pingproto.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ ProgramDatabaseFile=".\Release/pingproto.pdb"
+ BaseAddress="0x22050000"
+ ImportLibrary=".\Release/pingproto.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ EmbedManifest="false"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release/pingproto.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="icmp.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="log.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="menu.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="options.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="pinggraph.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="pinglist.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="pingproto.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="pingthread.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="rawping.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="StdAfx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="utils.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath="common.h"
+ >
+ </File>
+ <File
+ RelativePath="icmp.h"
+ >
+ </File>
+ <File
+ RelativePath="log.h"
+ >
+ </File>
+ <File
+ RelativePath="menu.h"
+ >
+ </File>
+ <File
+ RelativePath="options.h"
+ >
+ </File>
+ <File
+ RelativePath="pinggraph.h"
+ >
+ </File>
+ <File
+ RelativePath="pinglist.h"
+ >
+ </File>
+ <File
+ RelativePath="pingproto.h"
+ >
+ </File>
+ <File
+ RelativePath="pingthread.h"
+ >
+ </File>
+ <File
+ RelativePath="rawping.h"
+ >
+ </File>
+ <File
+ RelativePath="resource.h"
+ >
+ </File>
+ <File
+ RelativePath="StdAfx.h"
+ >
+ </File>
+ <File
+ RelativePath="utils.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ <File
+ RelativePath="icon1.ico"
+ >
+ </File>
+ <File
+ RelativePath="pingproto.rc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <File
+ RelativePath="cut_code.txt"
+ >
+ </File>
+ <File
+ RelativePath="ReadMe.txt"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/ping_protocol/pingthread.cpp b/ping_protocol/pingthread.cpp
new file mode 100644
index 0000000..c9a5fbd
--- /dev/null
+++ b/ping_protocol/pingthread.cpp
@@ -0,0 +1,309 @@
+#include "stdafx.h"
+#include "pingthread.h"
+
+int upCount, total = 0;
+
+HANDLE mainThread;
+HANDLE hWakeEvent = 0;
+
+// thread protected variables
+CRITICAL_SECTION thread_finished_cs, list_changed_cs, data_list_cs;
+bool thread_finished = false, list_changed = false;
+PINGLIST data_list;
+
+HANDLE status_update_thread = 0;
+
+bool get_thread_finished() {
+ Lock(&thread_finished_cs, "get_thread_finished");
+ bool retval = thread_finished;
+ Unlock(&thread_finished_cs);
+ return retval;
+}
+
+void set_thread_finished(bool f) {
+ Lock(&thread_finished_cs, "set_thread_finished");
+ thread_finished = f;
+ Unlock(&thread_finished_cs);
+}
+
+bool get_list_changed() {
+ Lock(&list_changed_cs, "get_list_changed");
+ bool retval = list_changed;
+ Unlock(&list_changed_cs);
+ return retval;
+}
+
+void set_list_changed(bool f) {
+ Lock(&list_changed_cs, "set_list_changed");
+ list_changed = f;
+ Unlock(&list_changed_cs);
+}
+
+void SetProtoStatus(char *pszLabel, char *pszProto, int if_status, int new_status) {
+ if(strcmp(pszProto, Translate("<all>")) == 0) {
+ int num_protocols;
+ PROTOCOLDESCRIPTOR **pppDesc;
+
+ CallService(MS_PROTO_ENUMPROTOCOLS, (LPARAM)&num_protocols, (WPARAM)&pppDesc);
+ for(int i = 0; i < num_protocols; i++) {
+ if(pppDesc[i]->type == PROTOTYPE_PROTOCOL)
+ SetProtoStatus(pszLabel, pppDesc[i]->szName, if_status, new_status);
+ }
+ } else {
+ std::ostringstream get_status, set_status;
+ get_status << pszProto << PS_GETSTATUS;
+ if(ServiceExists(get_status.str().c_str())) {
+ set_status << pszProto << PS_SETSTATUS;
+
+ if(CallService(get_status.str().c_str(), 0, 0) == if_status) {
+ if(options.logging) {
+ std::ostringstream oss2;
+ oss2 << pszLabel << " - setting status of protocol '" << pszProto << "' (" << new_status << ")";
+ CallService(PROTO "/Log", (WPARAM)oss2.str().c_str(), 0);
+ }
+ CallService(set_status.str().c_str(), new_status, 0);
+ }
+ }
+ }
+}
+
+DWORD WINAPI sttCheckStatusThreadProc( void *vp)
+{
+ clock_t start_t = clock(), end_t;
+ while(!get_thread_finished()) {
+
+ end_t = clock();
+
+ int wait = (options.ping_period - ((end_t - start_t) / (double)CLOCKS_PER_SEC)) * 1000;
+ if(wait > 0)
+ WaitForSingleObjectEx(hWakeEvent, wait, TRUE);
+
+ if(get_thread_finished()) break;
+
+ start_t = clock();
+
+ bool timeout = false;
+ bool reply = false;
+ int count = 0;
+
+ PINGADDRESS pa;
+ //HANDLE next = 0;
+
+ std::pair<short, DWORD> history_entry;
+
+ Lock(&data_list_cs, "ping thread loop start");
+ set_list_changed(false);
+ int size = data_list.size();
+ Unlock(&data_list_cs);
+
+ int ind;
+ for(ind = 0; ind < size; ind++) {
+ Lock(&data_list_cs, "ping thread loop start");
+ int c = 0;
+ for(PINGLIST::iterator i = data_list.begin(); i != data_list.end() && c <= ind; i++, c++) {
+ if(c == ind) {
+ // copy just what we need - i.e. not history, not command
+ pa.get_status = i->get_status;
+ pa.hContact = i->hContact;
+ pa.miss_count = i->miss_count;
+ pa.port = i->port;
+ strcpy(pa.pszLabel, i->pszLabel);
+ strcpy(pa.pszName, i->pszName);
+ strcpy(pa.pszProto, i->pszProto);
+ pa.set_status = i->set_status;
+ pa.status = i->status;
+ break;
+ }
+
+ }
+ Unlock(&data_list_cs);
+
+ if(get_thread_finished()) break;
+ if(get_list_changed()) break;
+
+ if(pa.status != options.off_status) {
+ if(CallService(MS_DB_CONTACT_IS, (WPARAM)pa.hContact, 0)) {
+ if(!options.no_test_status)
+ DBWriteContactSettingWord(pa.hContact, PROTO, "Status", options.tstatus);
+
+ CallService(PROTO "/Ping", 0, (LPARAM)&pa);
+ } else
+ break;
+
+ if(get_thread_finished()) break;
+ if(get_list_changed()) break;
+
+ Lock(&data_list_cs, "ping thread loop start");
+ for(PINGLIST::iterator i = data_list.begin(); i != data_list.end(); i++) {
+ if(i->hContact == pa.hContact) {
+ i->responding = pa.responding;
+ i->round_trip_time = pa.round_trip_time;
+
+ history_entry.first = i->round_trip_time;
+ history_entry.second = time(0);
+ i->history.push_back(history_entry);
+ // maintain history (-1 represents no response)
+ while(i->history.size() >= MAX_HISTORY) {
+ i->history.erase(i->history.begin());
+ //i->history.pop_front();
+ }
+
+ if(pa.responding) {
+ if(pa.miss_count > 0)
+ pa.miss_count = -1;
+ else
+ pa.miss_count--;
+ pa.status = options.rstatus;
+ }
+ else {
+ if(pa.miss_count < 0)
+ pa.miss_count = 1;
+ else
+ pa.miss_count++;
+ pa.status = options.nrstatus;
+ }
+ i->miss_count = pa.miss_count;
+ i->status = pa.status;
+
+ break;
+ }
+ }
+ Unlock(&data_list_cs);
+
+ if(pa.responding) {
+ count++;
+
+ if(pa.miss_count == -1 - options.retries ||
+ (((-pa.miss_count) % (options.retries + 1)) == 0 && !options.block_reps))
+ {
+ reply = true;
+ if(options.show_popup2 && ServiceExists(MS_POPUP_SHOWMESSAGE)) {
+ ShowPopup("Ping Reply", pa.pszLabel, 1);
+ }
+ if(DBGetContactSettingWord(pa.hContact, PROTO, "Status", ID_STATUS_OFFLINE) != pa.status)
+ DBWriteContactSettingWord(pa.hContact, PROTO, "Status", pa.status);
+ }
+ if(pa.miss_count == -1 - options.retries && options.logging) {
+ std::ostringstream oss2;
+ oss2 << pa.pszLabel << " - reply";
+ CallService(PROTO "/Log", (WPARAM)oss2.str().c_str(), 0);
+ }
+ SetProtoStatus(pa.pszLabel, pa.pszProto, pa.get_status, pa.set_status);
+ if(options.use_status_msg) {
+ std::ostringstream msg;
+ char *mode_desc = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, options.rstatus, 0);
+ msg << (mode_desc ? mode_desc : Translate("Uknnown")) << " (" << pa.round_trip_time << ")";
+ DBWriteContactSettingString(pa.hContact, "CList", "StatusMsg", msg.str().c_str());
+ } else {
+ std::ostringstream handle;
+ handle << pa.pszLabel << " (" << pa.round_trip_time << ")";
+ set_changing_clist_handle(TRUE);
+ DBWriteContactSettingString(pa.hContact, "CList", "MyHandle", handle.str().c_str());
+ set_changing_clist_handle(FALSE);
+ }
+ } else {
+
+ if(pa.miss_count == 1 + options.retries ||
+ ((pa.miss_count % (options.retries + 1)) == 0 && !options.block_reps))
+ {
+ timeout = true;
+ if(options.show_popup && ServiceExists(MS_POPUP_SHOWMESSAGE)) {
+ ShowPopup("Ping Timeout", pa.pszLabel, 0);
+ }
+ if(!timeout) timeout = true;
+ if(DBGetContactSettingWord(pa.hContact, PROTO, "Status", ID_STATUS_OFFLINE) != pa.status)
+ DBWriteContactSettingWord(pa.hContact, PROTO, "Status", pa.status);
+ }
+ if(pa.miss_count == 1 + options.retries && options.logging) {
+ std::ostringstream oss2;
+ oss2 << pa.pszLabel << " - timeout";
+ CallService(PROTO "/Log", (WPARAM)oss2.str().c_str(), 0);
+ }
+ if(options.use_status_msg) {
+ std::ostringstream msg;
+ char *mode_desc = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, options.nrstatus, 0);
+ msg << (mode_desc ? mode_desc : Translate("Uknnown")) << " [" << pa.miss_count << "]";
+ DBWriteContactSettingString(pa.hContact, "CList", "StatusMsg", msg.str().c_str());
+ } else {
+ std::ostringstream handle;
+ handle << pa.pszLabel << " [" << pa.miss_count << "]";
+ set_changing_clist_handle(TRUE);
+ DBWriteContactSettingString(pa.hContact, "CList", "MyHandle", handle.str().c_str());
+ set_changing_clist_handle(FALSE);
+ }
+ }
+ if(!options.no_test_status && DBGetContactSettingWord(pa.hContact, PROTO, "Status", ID_STATUS_OFFLINE) != pa.status)
+ DBWriteContactSettingWord(pa.hContact, PROTO, "Status", pa.status);
+ }
+ }
+
+ if(timeout) SkinPlaySound("PingProtoTimeout");
+ if(reply) SkinPlaySound("PingProtoReply");
+
+ if(!get_list_changed()) {
+ upCount = count;
+ total = ind;
+
+ if(DBGetContactSettingByte(0, PROTO, "SetProtoStatus", 0)) {
+ if(upCount == total)
+ CallService(PROTO PS_SETSTATUS, options.rstatus, 0);
+ else if(upCount == 0)
+ CallService(PROTO PS_SETSTATUS, options.nrstatus, 0);
+ }
+ } else {
+ total = 0;
+ }
+ }
+
+ return 0;
+}
+
+void start_ping_thread() {
+ DWORD tid;
+
+ if(status_update_thread) CloseHandle(status_update_thread);
+ status_update_thread = CreateThread(0, 0, sttCheckStatusThreadProc, 0, 0, &tid);
+}
+
+void stop_ping_thread() {
+ set_thread_finished(true);
+ SetEvent(hWakeEvent);
+ //ICMP::get_instance()->stop();
+ WaitForSingleObject(status_update_thread, 2000);
+ TerminateThread(status_update_thread, 0);
+ CloseHandle(status_update_thread);
+ status_update_thread = 0;
+}
+
+int FillList(WPARAM wParam, LPARAM lParam) {
+
+ if(options.logging)
+ CallService(PROTO "/Log", (WPARAM)"ping address list reload", 0);
+
+ PINGLIST pl;
+ CallService(PROTO "/GetPingList", 0, (LPARAM)&pl);
+
+ Lock(&data_list_cs, "fill_list");
+
+ // copy history
+ for(PINGLIST::iterator i = data_list.begin(); i != data_list.end(); i++) {
+ for(PINGLIST::iterator j = pl.begin(); j != pl.end(); j++) {
+ if(i->hContact == j->hContact) {
+ if(i->history.size())
+ j->history = i->history;
+ else
+ j->history.clear();
+ }
+ }
+ }
+
+ if(pl.size())
+ data_list = pl;
+
+ set_list_changed(true);
+ Unlock(&data_list_cs);
+
+ SetEvent(hWakeEvent);
+ return 0;
+}
+
diff --git a/ping_protocol/pingthread.h b/ping_protocol/pingthread.h
new file mode 100644
index 0000000..c23b2dc
--- /dev/null
+++ b/ping_protocol/pingthread.h
@@ -0,0 +1,21 @@
+#ifndef _PINGTHREAD_H
+#define _PINGTHREAD_H
+
+#include <string>
+#include <sstream>
+#include "pinglist.h"
+#include "utils.h"
+#include "options.h"
+
+extern HANDLE mainThread;
+extern HANDLE hWakeEvent;
+extern CRITICAL_SECTION thread_finished_cs, list_changed_cs, data_list_cs;
+
+extern PINGLIST data_list;
+
+void start_ping_thread();
+void stop_ping_thread();
+
+int FillList(WPARAM wParam, LPARAM lParam);
+
+#endif \ No newline at end of file
diff --git a/ping_protocol/rawping.cpp b/ping_protocol/rawping.cpp
new file mode 100644
index 0000000..008a2a8
--- /dev/null
+++ b/ping_protocol/rawping.cpp
@@ -0,0 +1,206 @@
+#include "stdafx.h"
+#include "rawping.h"
+
+#include <ws2tcpip.h>
+#include <iostream>
+
+#include "rawping.h"
+
+USHORT ip_checksum(USHORT* buffer, int size)
+{
+ unsigned long cksum = 0;
+
+ // Sum all the words together, adding the final byte if size is odd
+ while (size > 1) {
+ cksum += *buffer++;
+ size -= sizeof(USHORT);
+ }
+ if (size) {
+ cksum += *(UCHAR*)buffer;
+ }
+
+ // Do a little shuffling
+ cksum = (cksum >> 16) + (cksum & 0xffff);
+ cksum += (cksum >> 16);
+
+ // Return the bitwise complement of the resulting mishmash
+ return (USHORT)(~cksum);
+}
+
+SOCKET sd = -1;
+char packet[1024];
+char recv_buff[1024];
+USHORT seq_no = 0;
+bool inited = false;
+
+extern int init_raw_ping() {
+ WSAData wsaData;
+ if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
+ WSACleanup();
+ return 1;
+ }
+
+ if(sd != -1)
+ closesocket(sd);
+
+ // Create the socket
+ //sd = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, 0, 0, 0);
+ sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+ if (sd == INVALID_SOCKET) {
+ return 2;
+ }
+
+ int ttl = 255;
+ if (setsockopt(sd, IPPROTO_IP, IP_TTL, (const char*)&ttl, sizeof(ttl)) == SOCKET_ERROR) {
+ return 3;
+ }
+
+ int our_recv_timeout = 100; // so we ca do multiple recv calls
+ if(setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&our_recv_timeout, sizeof(int)) == SOCKET_ERROR) {
+ return 4;
+ }
+
+ ICMPHeader *header = (ICMPHeader *)packet;
+ header->type = ICMP_ECHO_REQUEST;
+ header->code = 0;
+ header->id = (USHORT)GetCurrentProcessId();
+
+ inited = true;
+ if(raw_ping("127.0.0.1", 500) >= 0) {
+ return 0;
+ }
+
+ inited = false;
+ return 5;
+}
+
+extern int raw_ping(char *host, int timeout) {
+ if(!inited) return -1;
+
+ // Initialize the destination host info block
+ sockaddr_in dest;
+ memset(&dest, 0, sizeof(dest));
+
+ // Turn first passed parameter into an IP address to ping
+ unsigned int addr = inet_addr(host);
+ if (addr != INADDR_NONE) {
+ // It was a dotted quad number, so save result
+ dest.sin_addr.s_addr = addr;
+ dest.sin_family = AF_INET;
+ }
+ else {
+ // Not in dotted quad form, so try and look it up
+ hostent* hp = gethostbyname(host);
+ if (hp != 0) {
+ // Found an address for that host, so save it
+ memcpy(&(dest.sin_addr), hp->h_addr, hp->h_length);
+ //dest.sin_family = hp->h_addrtype;
+ dest.sin_family = AF_INET;
+ }
+ else {
+ // Not a recognized hostname either!
+ return -1;
+ }
+ }
+
+ ICMPHeader *header = (ICMPHeader *)packet;
+ header->seq = ++seq_no;
+ header->checksum = 0;
+ header->checksum = ip_checksum((USHORT*)header, sizeof(ICMPHeader));
+
+ bool use_hi_res = false;
+ LARGE_INTEGER hr_freq, hr_send_time;
+ DWORD send_time;
+ if(QueryPerformanceFrequency(&hr_freq)) {
+ use_hi_res = true;
+ QueryPerformanceCounter(&hr_send_time);
+ } else
+ send_time = GetTickCount();
+
+ // send packet
+ int bwrote = sendto(sd, (char*)packet, sizeof(ICMPHeader), 0, (sockaddr*)&dest, sizeof(dest));
+ if (bwrote == SOCKET_ERROR) {
+ return -1;
+ }
+
+ // Wait for the ping reply
+ sockaddr_in source;
+ int fromlen = sizeof(source);
+ IPHeader *reply_header = (IPHeader *)recv_buff;
+ ICMPHeader *reply;
+ DWORD start, current_time;
+ LARGE_INTEGER hr_start, hr_current_time, hr_timeout;
+ if(use_hi_res) {
+ hr_timeout.QuadPart = (timeout * hr_freq.QuadPart / 1000);
+ QueryPerformanceCounter(&hr_start);
+ hr_current_time = hr_start;
+ } else {
+ start = GetTickCount();
+ current_time = start;
+ }
+
+ while(((use_hi_res && (hr_current_time.QuadPart < hr_start.QuadPart + hr_timeout.QuadPart))
+ || (!use_hi_res && current_time < start + timeout)))
+ {
+ int bread = recvfrom(sd, recv_buff, 1024, 0, (sockaddr*)&source, &fromlen);
+
+ if(use_hi_res)
+ QueryPerformanceCounter(&hr_current_time);
+ else
+ current_time = GetTickCount();
+
+ if (bread == SOCKET_ERROR) {
+ if(WSAGetLastError() != WSAETIMEDOUT) {
+ if(options.logging) CallService(PROTO "/Log", (WPARAM)"rawping error: socket error", 0);
+ continue;
+ }
+ }
+
+ if(reply_header->proto != ICMP_PROTO)
+ continue;
+
+ if(reply_header->tos != 0)
+ continue;
+
+ reply = (ICMPHeader *)(recv_buff + reply_header->h_len * 4);
+ if((unsigned)bread < reply_header->h_len * 4 + sizeof(ICMPHeader)) {
+ if(options.logging) CallService(PROTO "/Log", (WPARAM)"rawping error: short header", 0);
+ continue;
+ }
+
+ if(reply->id != (USHORT)GetCurrentProcessId())
+ continue;
+
+ if(reply->type != ICMP_ECHO_REPLY && reply->type != ICMP_SOURCE_QUENCH) {
+ continue;
+ }
+
+ //if(reply->seq < seq_no) continue;
+ //if(reply->seq > seq_no) return -1;
+ if(reply->seq != seq_no) continue;
+
+ if(reply->type == ICMP_SOURCE_QUENCH) {
+ char buff[1024];
+ sprintf(buff, Translate("Host %s requests that you reduce the amount of traffic you are sending."), host);
+ MessageBox(0, buff, Translate(PROTO " Warning"), MB_OK | MB_ICONWARNING);
+ }
+
+ if(use_hi_res) {
+ LARGE_INTEGER ticks;
+ ticks.QuadPart = hr_current_time.QuadPart - hr_send_time.QuadPart;
+ return (int)(ticks.QuadPart * 1000 / hr_freq.QuadPart);
+ } else
+ return current_time - send_time;
+ }
+
+ return -1;
+}
+
+extern int cleanup_raw_ping() {
+ if(inited) {
+ closesocket(sd);
+ sd = -1;
+ WSACleanup();
+ }
+ return 0;
+}
diff --git a/ping_protocol/rawping.h b/ping_protocol/rawping.h
new file mode 100644
index 0000000..2201d19
--- /dev/null
+++ b/ping_protocol/rawping.h
@@ -0,0 +1,61 @@
+#ifndef _RAWPING_H
+#define _RAWPING_H
+
+#include "common.h" // to translate 'SOURCE_QUENCH' warning
+#include "options.h"
+#include "log.h"
+
+
+// ICMP protocol identifier
+#define ICMP_PROTO 1
+
+// ICMP packet types
+#define ICMP_ECHO_REPLY 0
+#define ICMP_DEST_UNREACH 3
+#define ICMP_TTL_EXPIRE 11
+#define ICMP_ECHO_REQUEST 8
+#define ICMP_SOURCE_QUENCH 4
+
+// Minimum ICMP packet size, in bytes
+#define ICMP_MIN 8
+
+#ifdef _MSC_VER
+// The following two structures need to be packed tightly, but unlike
+// Borland C++, Microsoft C++ does not do this by default.
+#pragma pack(1)
+#endif
+
+// The IP header
+struct IPHeader {
+ BYTE h_len:4; // Length of the header in dwords
+ BYTE version:4; // Version of IP
+ BYTE tos; // Type of service
+ USHORT total_len; // Length of the packet in dwords
+ USHORT ident; // unique identifier
+ USHORT flags; // Flags
+ BYTE ttl; // Time to live
+ BYTE proto; // Protocol number (TCP, UDP etc)
+ USHORT checksum; // IP checksum
+ ULONG source_ip;
+ ULONG dest_ip;
+};
+
+// ICMP header
+struct ICMPHeader {
+ BYTE type; // ICMP packet type
+ BYTE code; // Type sub code
+ USHORT checksum;
+ USHORT id;
+ USHORT seq;
+};
+
+#ifdef _MSC_VER
+#pragma pack()
+#endif
+
+extern USHORT ip_checksum(USHORT* buffer, int size);
+
+extern int init_raw_ping();
+extern int raw_ping(char *host, int timeout);
+extern int cleanup_raw_ping();
+#endif \ No newline at end of file
diff --git a/ping_protocol/resource.h b/ping_protocol/resource.h
new file mode 100644
index 0000000..27544cc
--- /dev/null
+++ b/ping_protocol/resource.h
@@ -0,0 +1,65 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by pingproto.rc
+//
+#define IDD_DIALOG1 101
+#define IDD_DIALOG2 102
+#define IDD_DIALOG3 103
+#define IDR_MENU1 106
+#define IDI_ICON_PROTO 108
+#define IDC_PPM 1001
+#define IDC_PT 1002
+#define IDC_RPT 1003
+#define IDC_CHECK1 1005
+#define IDC_CHECKPOPUP 1005
+#define IDC_CHK_DESTTCP 1005
+#define IDC_BUTTONEDIT 1006
+#define IDC_BUTTONRELOAD 1007
+#define IDC_CHK_LOG 1008
+#define IDC_ED_FILENAME 1009
+#define IDC_CHECKPOPUP2 1010
+#define IDC_CHK_MINMAX 1011
+#define IDC_CHK_BLOCK 1012
+#define IDC_BTN_VIEWLOG 1013
+#define IDC_ED_DATAFILENAME 1014
+#define IDC_BTN_LOGBROWSE 1015
+#define IDC_BTN_DATABROWSE 1016
+#define IDC_ED_DESTADDR 1016
+#define IDC_ED_DESTLAB 1017
+#define IDC_BTN_DESTADD 1018
+#define IDC_LST_DEST 1019
+#define IDC_BTN_DESTREM 1020
+#define IDC_ED_DESTPORT 1021
+#define IDC_BTN_DESTEDIT 1021
+#define IDC_ED_DESTPROTO 1022
+#define IDC_BTN_DESTUP 1022
+#define IDC_BTN_DESTDOWN 1023
+#define IDC_COMBO_DESTPROTO 1024
+#define IDC_COMBO_DESTSTAT 1025
+#define IDC_COMBO_DESTSTAT2 1026
+#define IDC_ED_COMMAND 1032
+#define IDC_RSTATUS 1033
+#define IDC_ED_PARAMS 1033
+#define IDC_NRSTATUS 1034
+#define IDC_TSTATUS 1035
+#define IDC_DSTATUS 1036
+#define IDC_CHK_NOTESTSTATUS 1037
+#define IDC_COMBO_GROUP 1038
+#define IDC_CHK_HIDEPROTO 1038
+#define IDC_CHK_USESTATUSMSG 1039
+#define ID_MENU_ENABLEALLPINGS 40002
+#define ID_MENU_OPTIONS 40003
+#define ID_MENU_DISABLEALLPINGS 40004
+#define ID_MENU_DESTINATIONS 40005
+
+#define IDC_STATIC -1
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 109
+#define _APS_NEXT_COMMAND_VALUE 40006
+#define _APS_NEXT_CONTROL_VALUE 1039
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/ping_protocol/utils.cpp b/ping_protocol/utils.cpp
new file mode 100644
index 0000000..1f9c839
--- /dev/null
+++ b/ping_protocol/utils.cpp
@@ -0,0 +1,324 @@
+#include "stdafx.h"
+#include "utils.h"
+
+bool use_raw_ping = true;
+/*
+std::string trim_string(const std::string &in) {
+ std::string out;
+
+ int i = 0;
+ while(i < in.size() && in[i] == ' ')
+ i++;
+ for(; i < in.size(); i++) {
+ out += in[i];
+ }
+
+ while(out.size() && out[out.size() - 1] == ' ') {
+ out = out.substr(0, out.size() - 1);
+ }
+
+
+ return out;
+}
+
+void capitalize(std::string &in) {
+ for(int i = 0; i < in.length(); i++) {
+ if(in[i] >= 'a' && in[i] <= 'z')
+ in[i] = 'A' + (in[i] - 'a');
+ }
+}
+*/
+LRESULT CALLBACK NullWindowProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
+{
+ switch( message ) {
+ case WM_COMMAND: {
+ PUDeletePopUp( hWnd );
+ break;
+ }
+
+ case WM_CONTEXTMENU:
+ PUDeletePopUp( hWnd );
+ break;
+ }
+
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+
+void CALLBACK sttMainThreadCallback( ULONG dwParam )
+{
+ POPUPDATAEX* ppd = ( POPUPDATAEX* )dwParam;
+
+ if ( ServiceExists(MS_POPUP_ADDPOPUPEX) )
+ CallService( MS_POPUP_ADDPOPUPEX, ( WPARAM )ppd, 0 );
+ else
+ if ( ServiceExists(MS_POPUP_ADDPOPUP) )
+ CallService( MS_POPUP_ADDPOPUP, ( WPARAM )ppd, 0 );
+
+ free( ppd );
+}
+
+void __stdcall ShowPopup( const char* line1, const char* line2, int flags )
+{
+ if(CallService(MS_SYSTEM_TERMINATED, 0, 0)) return;
+
+ if ( !ServiceExists( MS_POPUP_ADDPOPUP )) {
+ MessageBox( NULL, line2, PROTO " Message", MB_OK | MB_ICONINFORMATION );
+ return;
+ }
+
+ POPUPDATAEX* ppd = ( POPUPDATAEX* )calloc( sizeof( POPUPDATAEX ), 1 );
+
+ ppd->lchContact = NULL;
+ ppd->lchIcon = (flags ? LoadSkinnedProtoIcon(PROTO, options.rstatus) : LoadSkinnedProtoIcon(PROTO, options.nrstatus));
+ strcpy( ppd->lpzContactName, line1 );
+ strcpy( ppd->lpzText, line2 );
+
+ ppd->colorBack = GetSysColor( COLOR_BTNFACE );
+ ppd->colorText = GetSysColor( COLOR_WINDOWTEXT );
+ ppd->iSeconds = 10;
+
+ ppd->PluginWindowProc = ( WNDPROC )NullWindowProc;
+ ppd->PluginData = NULL;
+
+ QueueUserAPC( sttMainThreadCallback , mainThread, ( ULONG )ppd );
+}
+
+// service functions
+
+// wParam is zero
+// lParam is address of PINGADDRESS structure where ping result is placed (i.e. modifies 'responding'
+// and 'round_trip_time')
+int PluginPing(WPARAM wParam,LPARAM lParam)
+{
+ PINGADDRESS *pa = (PINGADDRESS *)lParam;
+
+ if(pa->port == -1) {
+ if(use_raw_ping) {
+ pa->round_trip_time = raw_ping(pa->pszName, options.ping_timeout * 1000);
+ pa->responding = (pa->round_trip_time != -1);
+ } else {
+ // ICMP echo
+ IP_ECHO_REPLY result;
+ pa->responding = ICMP::get_instance()->ping(pa->pszName, result);
+ if(pa->responding)
+ pa->round_trip_time = result.RoundTripTime;
+ else
+ pa->round_trip_time = -1;
+ }
+ } else if(hNetlibUser) {
+ // TCP connect
+
+ clock_t start_tcp = clock();
+
+ //GetLocalTime(&systime);
+ NETLIBOPENCONNECTION conn = {0};
+ conn.cbSize = sizeof(NETLIBOPENCONNECTION);
+ conn.szHost = pa->pszName;
+ conn.wPort = pa->port;
+ conn.flags = NLOCF_V2;
+ conn.timeout = options.ping_timeout;
+
+ HANDLE s = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)hNetlibUser, (LPARAM)&conn);
+
+ clock_t end_tcp = clock();
+
+ if(s) {
+ LINGER l;
+ char buf[1024];
+ SOCKET socket = (SOCKET)CallService(MS_NETLIB_GETSOCKET, (WPARAM)s, (LPARAM)NLOCF_HTTP);
+ if(socket != INVALID_SOCKET) {
+ l.l_onoff = 1;
+ l.l_linger = 0;
+ setsockopt(socket, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l));
+
+ Netlib_Send(s, "OUT\r\n\r\n", 7, 0); //MSG_RAW);
+
+ //Sleep(ICMP::get_instance()->get_timeout());
+ Sleep(options.ping_timeout * 1000);
+ unsigned long bytes_remaining;
+ ioctlsocket(socket, FIONBIO, &bytes_remaining);
+
+ if(bytes_remaining > 0) {
+ int retval, rx = 0;
+ while((retval = Netlib_Recv(s, buf, 1024, 0)) != SOCKET_ERROR && (retval > 0) && rx < 2048) {
+ rx += retval; // recv at most 2kb before closing connection
+ }
+ }
+ //closesocket(socket);
+
+ }
+
+ Netlib_CloseHandle(s);
+
+ pa->responding = true;
+ pa->round_trip_time = (int)(((end_tcp - start_tcp) / (double)CLOCKS_PER_SEC) * 1000);
+ } else {
+ pa->responding = false;
+ pa->round_trip_time = -1;
+ }
+
+ }
+ return 0;
+}
+
+void Lock(CRITICAL_SECTION *cs, char *lab) {
+// if(logging) {
+// std::ostringstream oss1;
+// oss1 << "Locking cs: " << cs << ", " << lab;
+// CallService(PROTO "/Log", (WPARAM)oss1.str().c_str(), 0);
+// }
+ EnterCriticalSection(cs);
+// if(logging) {
+// std::ostringstream oss2;
+// oss2 << "Locked cs: " << cs;
+// CallService(PROTO "/Log", (WPARAM)oss2.str().c_str(), 0);
+// }
+}
+
+void Unlock(CRITICAL_SECTION *cs) {
+// if(logging) {
+// std::ostringstream oss1;
+// oss1 << "Unlocking cs: " << cs;
+// CallService(PROTO "/Log", (WPARAM)oss1.str().c_str(), 0);
+// }
+ LeaveCriticalSection(cs);
+}
+
+int PingDisableAll(WPARAM wParam, LPARAM lParam) {
+ PINGLIST pl;
+ CallService(PROTO "/GetPingList", 0, (LPARAM)&pl);
+ for(PINGLIST::iterator i = pl.begin(); i != pl.end(); i++) {
+ i->status = options.off_status;
+ DBWriteContactSettingWord(i->hContact, PROTO, "Status", i->status);
+ set_changing_clist_handle(TRUE);
+ DBWriteContactSettingString(i->hContact, "CList", "MyHandle", i->pszLabel);
+ set_changing_clist_handle(FALSE);
+ }
+ CallService(PROTO "/SetPingList", (WPARAM)&pl, 0);
+ return 0;
+}
+
+int PingEnableAll(WPARAM wParam, LPARAM lParam) {
+ PINGLIST pl;
+ CallService(PROTO "/GetPingList", 0, (LPARAM)&pl);
+ for(PINGLIST::iterator i = pl.begin(); i != pl.end(); i++) {
+ if(i->status == options.off_status) {
+ i->status = options.nrstatus;
+ DBWriteContactSettingWord(i->hContact, PROTO, "Status", i->status);
+ }
+ }
+ CallService(PROTO "/SetPingList", (WPARAM)&pl, 0);
+ return 0;
+}
+
+
+int ToggleEnabled(WPARAM wParam, LPARAM lParam) {
+ PINGLIST pl;
+ CallService(PROTO "/GetPingList", 0, (LPARAM)&pl);
+ for(PINGLIST::iterator i = pl.begin(); i != pl.end(); i++) {
+ if(i->hContact == (HANDLE)wParam) {
+
+ if(i->status == options.off_status)
+ i->status = options.nrstatus;
+ else {
+ i->status = options.off_status;
+ set_changing_clist_handle(TRUE);
+ DBWriteContactSettingString(i->hContact, "CList", "MyHandle", i->pszLabel);
+ set_changing_clist_handle(FALSE);
+ }
+ DBWriteContactSettingWord(i->hContact, PROTO, "Status", i->status);
+ }
+ }
+ CallService(PROTO "/SetPingList", (WPARAM)&pl, 0);
+ return 0;
+}
+
+int EditContact(WPARAM wParam, LPARAM lParam) {
+ PINGLIST pl;
+ HWND hwndList = (HWND)CallService(MS_CLUI_GETHWND, 0, 0);
+
+ CallService(PROTO "/GetPingList", 0, (LPARAM)&pl);
+ for(PINGLIST::iterator i = pl.begin(); i != pl.end(); i++) {
+ if(i->hContact == (HANDLE)wParam) {
+
+ add_edit_addr = *i;
+
+ if(DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG3), hwndList, DlgProcDestEdit) == IDOK) {
+
+ *i = add_edit_addr;
+ CallService(PROTO "/SetAndSavePingList", (WPARAM)&pl, 0);
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+int ContactDblClick(WPARAM wParam, LPARAM lParam) {
+ PINGLIST pl;
+ CallService(PROTO "/GetPingList", 0, (LPARAM)&pl);
+ for(PINGLIST::iterator i = pl.begin(); i != pl.end(); i++) {
+ if(i->hContact == (HANDLE)wParam) {
+ if(strlen(i->pszCommand)) {
+ ShellExecute(0, "open", i->pszCommand, i->pszParams, 0, SW_SHOW);
+ } else {
+ CallService(PROTO "/ToggleEnabled", wParam, 0);
+ }
+ }
+ }
+ return 0;
+}
+
+
+void import_ping_address(int index, PINGADDRESS &pa) {
+ std::ostringstream os1, os2, os3, os4, os5, os6, os7;
+ os1 << "Address" << index;
+ os2 << "Label" << index;
+ os3 << "Enabled" << index;
+ os4 << "Port" << index;
+ os5 << "Proto" << index;
+ os6 << "Status" << index;
+ os7 << "Status2" << index;
+
+ DBVARIANT dbv;
+ DBGetContactSetting(0, "PingPlug", os1.str().c_str(), &dbv);
+ strncpy(pa.pszName, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ DBGetContactSetting(0, "PingPlug", os2.str().c_str(), &dbv);
+ strncpy(pa.pszLabel, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+
+ pa.port = (int)DBGetContactSettingDword(0, "PingPlug", os4.str().c_str(), -1);
+
+ DBGetContactSetting(0, "PingPlug", os5.str().c_str(), &dbv);
+ strncpy(pa.pszProto, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+
+ pa.set_status = DBGetContactSettingWord(0, "PingPlug", os6.str().c_str(), ID_STATUS_ONLINE);
+ pa.get_status = DBGetContactSettingWord(0, "PingPlug", os7.str().c_str(), ID_STATUS_OFFLINE);
+
+ pa.responding = false;
+ pa.round_trip_time = 0;
+ pa.miss_count = 0;
+ pa.index = index;
+ pa.pszCommand[0] = '\0';
+
+ pa.hContact = 0;
+ pa.status = options.nrstatus;
+}
+
+// read in addresses from old pingplug
+void import_ping_addresses() {
+ int count = DBGetContactSettingDword(0, "PingPlug", "NumEntries", 0);
+ PINGADDRESS pa;
+
+ EnterCriticalSection(&list_cs);
+ list_items.clear();
+ for(int index = 0; index < count; index++) {
+ import_ping_address(index, pa);
+ list_items.push_back(pa);
+ }
+ std::sort(list_items.begin(), list_items.end(), SAscendingSort());
+ write_ping_addresses();
+ LeaveCriticalSection(&list_cs);
+}
diff --git a/ping_protocol/utils.h b/ping_protocol/utils.h
new file mode 100644
index 0000000..cddcb82
--- /dev/null
+++ b/ping_protocol/utils.h
@@ -0,0 +1,38 @@
+#ifndef _PING_UTILS
+#define _PING_UTILS
+
+//#include <string>
+#include <time.h>
+
+#include "common.h"
+#include "pingthread.h" // for mainthread, for popup
+//#include "icmp.h"
+#include "rawping.h"
+#include "options.h"
+#include "icmp.h"
+
+/*
+std::string trim_string(const std::string &in);
+void capitalize(std::string &in);
+*/
+void __stdcall ShowPopup( const char* line1, const char* line2, int flags );
+
+int PluginPing(WPARAM wParam,LPARAM lParam);
+
+void Lock(CRITICAL_SECTION *cs, char *lab);
+void Unlock(CRITICAL_SECTION *cs);
+
+int PingDisableAll(WPARAM wParam, LPARAM lParam);
+int PingEnableAll(WPARAM wParam, LPARAM lParam);
+
+int ToggleEnabled(WPARAM wParam, LPARAM lParam);
+
+int ContactDblClick(WPARAM wParam, LPARAM lParam);
+
+int EditContact(WPARAM wParam, LPARAM lParam);
+// read in addresses from old pingplug
+void import_ping_addresses();
+
+extern bool use_raw_ping;
+
+#endif