diff options
-rw-r--r-- | ping/IcoLib.h | 37 | ||||
-rw-r--r-- | ping/StdAfx.cpp | 8 | ||||
-rw-r--r-- | ping/StdAfx.h | 33 | ||||
-rw-r--r-- | ping/collection.h | 545 | ||||
-rw-r--r-- | ping/common.h | 124 | ||||
-rw-r--r-- | ping/green.ico | bin | 0 -> 2550 bytes | |||
-rw-r--r-- | ping/grey.ico | bin | 0 -> 3438 bytes | |||
-rw-r--r-- | ping/icmp.cpp | 89 | ||||
-rw-r--r-- | ping/icmp.h | 66 | ||||
-rw-r--r-- | ping/log.cpp | 59 | ||||
-rw-r--r-- | ping/log.h | 12 | ||||
-rw-r--r-- | ping/menu.cpp | 100 | ||||
-rw-r--r-- | ping/menu.h | 10 | ||||
-rw-r--r-- | ping/options.cpp | 631 | ||||
-rw-r--r-- | ping/options.h | 26 | ||||
-rw-r--r-- | ping/ping.cpp | 173 | ||||
-rw-r--r-- | ping/ping.dsp | 249 | ||||
-rw-r--r-- | ping/ping.dsw | 29 | ||||
-rw-r--r-- | ping/ping.h | 42 | ||||
-rw-r--r-- | ping/ping.mdsp | 119 | ||||
-rw-r--r-- | ping/ping.plg | 80 | ||||
-rw-r--r-- | ping/ping.rc | 227 | ||||
-rw-r--r-- | ping/ping.sln | 20 | ||||
-rw-r--r-- | ping/ping.vcproj | 563 | ||||
-rw-r--r-- | ping/pinggraph.cpp | 325 | ||||
-rw-r--r-- | ping/pinggraph.h | 22 | ||||
-rw-r--r-- | ping/pinglist.cpp | 230 | ||||
-rw-r--r-- | ping/pinglist.h | 26 | ||||
-rw-r--r-- | ping/pingthread.cpp | 1052 | ||||
-rw-r--r-- | ping/pingthread.h | 27 | ||||
-rw-r--r-- | ping/rawping.cpp | 217 | ||||
-rw-r--r-- | ping/rawping.h | 61 | ||||
-rw-r--r-- | ping/red.ico | bin | 0 -> 2550 bytes | |||
-rw-r--r-- | ping/resource.h | 80 | ||||
-rw-r--r-- | ping/utils.cpp | 362 | ||||
-rw-r--r-- | ping/utils.h | 35 | ||||
-rw-r--r-- | ping/yellow.ico | bin | 0 -> 2550 bytes |
37 files changed, 5679 insertions, 0 deletions
diff --git a/ping/IcoLib.h b/ping/IcoLib.h new file mode 100644 index 0000000..1817df6 --- /dev/null +++ b/ping/IcoLib.h @@ -0,0 +1,37 @@ +typedef struct {
+ int cbSize;
+ char *pszSection; //section name used to group icons
+ char *pszDescription; //description for options dialog
+ char *pszName; //name to refer to icon when playing and in db
+ //this name is miranda-wide. so use prefixes of your plugin
+ //e.g: "isee_connect", "clist_delete", etc
+ char *pszDefaultFile; //default icon file to use
+ int iDefaultIndex;
+} SKINICONDESC;
+
+typedef struct {
+ int cbSize;
+ char *pszSection;
+ char *pszDescription;
+ char *pszName;
+ char *pszDefaultFile;
+ int iDefaultIndex;
+ HICON hDefaultIcon;
+} SKINICONDESC2;
+
+//
+// Add a icon into options UI
+//
+// wParam = (WPARAM)0
+// lParam = (LPARAM)(SKINICONDESC*)sid;
+//
+#define MS_SKIN2_ADDICON "Skin2/Icons/AddIcon"
+//
+// Retrieve HICON with name specified in lParam
+// Returned HICON SHOULDN'T be destroyed, it managed by IcoLib
+//
+#define MS_SKIN2_GETICON "Skin2/Icons/GetIcon"
+//
+// Icons change notification
+//
+#define ME_SKIN2_ICONSCHANGED "Skin2/IconsChanged"
diff --git a/ping/StdAfx.cpp b/ping/StdAfx.cpp new file mode 100644 index 0000000..b9237ff --- /dev/null +++ b/ping/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/StdAfx.h b/ping/StdAfx.h new file mode 100644 index 0000000..8eba041 --- /dev/null +++ b/ping/StdAfx.h @@ -0,0 +1,33 @@ +// 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 0x0500
+
+#define WINVER 0x0500
+#define _WIN32_WINNT 0x0400
+#define _WIN32_IE 0x0300
+
+#include <windows.h>
+#include <prsht.h>
+#include <winsock2.h>
+#include <winsock.h>
+#include <shellapi.h>
+#include <commdlg.h>
+#include <commctrl.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/collection.h b/ping/collection.h new file mode 100644 index 0000000..8073c21 --- /dev/null +++ b/ping/collection.h @@ -0,0 +1,545 @@ +template<class T> class Collection {
+protected:
+ unsigned long count;
+public:
+ Collection(): count(0) {}
+
+ virtual void clear() = 0;
+ virtual void add(T &val) = 0;
+ virtual const bool remove(T &val) = 0;
+
+ const unsigned long size() const {return count;}
+};
+
+template<class T> class Node {
+public:
+ T val;
+
+ Node(T &v): val(v) {}
+ virtual ~Node() {}
+};
+
+template<class T> class ListNode: public Node<T> {
+public:
+ ListNode<T> *next, *prev;
+
+ ListNode(T &v): Node<T>(v), next(0), prev(0) {}
+ virtual ~ListNode() {
+ if(next) next->prev = prev;
+ if(prev) prev->next = next;
+ }
+};
+
+template<class T> class LinkedList: public Collection<T> {
+protected:
+ ListNode<T> *head, *tail;
+
+public:
+ class Iterator {
+ friend class LinkedList<T>;
+ protected:
+ ListNode<T> *n;
+ Iterator(ListNode<T> *start): n(start) {}
+ public:
+ Iterator(const Iterator &other): n(other.n) {}
+
+ virtual T &val() {return n->val;}
+ virtual void next() {if(n) n = n->next;}
+ virtual void prev() {if(n) n = n->prev;}
+ virtual const bool has_val() {return (n ? true : false); }
+ };
+
+ LinkedList(): Collection<T>(), head(0), tail(0) {};
+ LinkedList(const LinkedList<T> &other): Collection<T>(), head(0), tail(0) {
+ for(Iterator i = other.start(); i.has_val(); i.next())
+ add(i.val());
+ }
+ virtual ~LinkedList() {clear();}
+
+ LinkedList<T> &operator=(const LinkedList<T> &other) {
+ clear();
+ for(Iterator i = other.start(); i.has_val(); i.next())
+ add(i.val());
+ return *this;
+ }
+
+ virtual void clear() {
+ ListNode<T> *n;
+ while(head) {
+ n = head;
+ head = head->next;
+ delete n;
+ }
+ tail = 0;
+ Collection<T>::count = 0;
+ }
+
+ virtual Iterator start() const {return Iterator(head);}
+
+ virtual void add_front(T &val) {
+ ListNode<T> *n = new ListNode<T>(val);
+ n->next = head;
+ if(head) head->prev = n;
+ head = n;
+ if(!tail) tail = n;
+ Collection<T>::count++;
+ }
+
+ virtual void add(T &val) {
+ ListNode<T> *n = new ListNode<T>(val);
+ n->prev = tail;
+ if(tail) tail->next = n;
+ tail = n;
+ if(!head) head = n;
+ Collection<T>::count++;
+ }
+
+ virtual const bool remove(T &val) {
+ ListNode<T> *n = head;
+ while(n) {
+ if(n->val == val) {
+ if(n == head) head = head->next;
+ if(n == tail) tail = tail->prev;
+
+ delete n;
+ Collection<T>::count--;
+ return true;
+ } else
+ n = n->next;
+ }
+
+ return false;
+ }
+
+ // queue/stack functions
+ // stack - use push/pop
+ // queue - use push_back/pop
+ virtual void push(T &val) {
+ add_front(val);
+ }
+
+ virtual void push(T val) {
+ add_front(val);
+ }
+
+ virtual void push_back(T &val) {
+ add(val);
+ }
+
+ virtual const bool pop(T &val) {
+ if(!head) return false;
+
+ ListNode<T> *n = head;
+ if(head) {
+ head = head->next;
+ if(n == tail) tail = 0;
+ val = n->val;
+ delete n;
+ Collection<T>::count--;
+ return true;
+ } else
+ return false;
+ }
+};
+
+template<class T> class DynamicArray: public Collection<T> {
+protected:
+ T *ar;
+
+ unsigned long initial, increment, limit;
+
+public:
+ class Iterator {
+ friend class DynamicArray<T>;
+ protected:
+ T *ar;
+ unsigned long pos;
+ unsigned long count;
+ Iterator(T *a, const int c, unsigned long p): ar(a), count(c), pos(p) {}
+ public:
+ Iterator(const Iterator &other): ar(other.ar), count(other.count), pos(other.pos) {}
+
+ virtual T &val() {return ar[pos];}
+ virtual void next() {pos++;}
+ virtual void prev() {pos--;}
+ virtual const bool has_val() {return pos < count; }
+ };
+
+ DynamicArray(unsigned long init = 0, unsigned long inc = 1): Collection<T>(), ar(0), initial(init), limit(init), increment(inc) {
+ if(limit) ar = (T *)malloc(limit * sizeof(T));
+ }
+ virtual ~DynamicArray() {free(ar);}
+
+ virtual void clear() {
+ Collection<T>::count = 0;
+ limit = initial;
+ if(limit) ar = (T *)realloc(ar, limit * sizeof(T));
+ else free(ar);
+ }
+
+ virtual Iterator start() {return Iterator(ar, Collection<T>::count, 0);}
+
+ virtual void add(T &val) {
+ if(Collection<T>::count == limit) {
+ limit += increment;
+ ar = (T *)realloc(ar, limit * sizeof(T));
+ ar[Collection<T>::count++] = val;
+ } else
+ ar[Collection<T>::count++] = val;
+ }
+
+ virtual const bool remove(T &val) {
+ for(unsigned long i = 0; i < Collection<T>::count; i++) {
+ if(ar[i] == val) {
+ memmove(ar + i, ar + i + 1, (Collection<T>::count - i) * sizeof(T));
+ Collection<T>::count--;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ virtual const bool remove(const unsigned long index) {
+ if(index >= Collection<T>::count) return false;
+
+ memmove(ar + index, ar + index + 1, (Collection<T>::count - index) * sizeof(T));
+ Collection<T>::count--;
+ return true;
+ }
+
+ virtual const bool insert(T &val, const unsigned long index) {
+ if(index > Collection<T>::count) return false;
+
+ if(Collection<T>::count == limit) {
+ limit += increment;
+ ar = (T *)realloc(ar, limit * sizeof(T));
+ }
+
+ if(index < Collection<T>::count)
+ memmove(ar + index + 1, ar + index, (Collection<T>::count - index) * sizeof(T));
+
+ ar[index] = val;
+ Collection<T>::count++;
+ return true;
+ }
+
+ virtual T &operator[](const int index) {
+ return ar[index];
+ }
+
+ const bool index_of(const T &val, unsigned long &index) {
+ for(int i = 0; i < Collection<T>::count; i++) {
+ if(ar[index] == val) {
+ index = i;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // stack functions
+ virtual const bool pop(T &val) {
+ if(Collection<T>::count) {
+ val = ar[Collection<T>::count -1];
+ remove(Collection<T>::count -1);
+ return true;
+ }
+ return false;
+ }
+
+ virtual void push(T &val) {
+ add(val);
+ }
+};
+
+template<class T> class SortedDynamicArray: public DynamicArray<T> {
+public:
+ SortedDynamicArray(unsigned long init = 0, unsigned long inc = 1): DynamicArray<T>(init, inc) {}
+ virtual ~SortedDynamicArray() {}
+
+ const bool get_index(T &val, unsigned long &index) {
+ unsigned long low = 0;
+ unsigned long high = Collection<T>::count-1;
+
+ while( high < Collection<T>::count && low <= high )
+ {
+ unsigned long i = ( low+high )/2;
+ if ( DynamicArray<T>::ar[i] == val )
+ { index = i;
+ return true;
+ } else if (DynamicArray<T>::ar[i] < val)
+ low = i+1;
+ else
+ high = i-1;
+ }
+
+ index = low;
+ return false;
+ }
+
+ virtual void add(T &val) {
+ unsigned long index;
+ get_index(val, index);
+ insert(val, index);
+ }
+};
+
+template<class T> class TreeNode: public Node<T> {
+public:
+ TreeNode<T> *parent, *left, *right;
+
+ TreeNode(T &v, TreeNode<T> *par): Node<T>(v), parent(par), left(0), right(0) {}
+ virtual ~TreeNode() {
+ if(parent) {
+ if(parent->left == this) parent->left = 0;
+ else parent->right = 0;
+ }
+ }
+};
+
+template<class T> class BinaryTree: public Collection<T> {
+protected:
+
+ TreeNode<T> *root;
+
+ TreeNode<T> *delete_node(TreeNode<T> *n) {
+ if(n->left && n->right) {
+ //if(rand() & 1) { // ?
+ TreeNode<T> *minmax = n->left;
+ while(minmax->right) minmax = minmax->right;
+ //} else {
+ // Node *minmax = current->right;
+ // while(minmax->left) minmax = minmax->left;
+ //}
+ n->val = minmax->val;
+ delete_node(minmax);
+ Collection<T>::count--;
+ return n;
+ } else if(n->right) {
+ if(n->parent) {
+ if(n->parent->left = n) n->parent->left = n->right;
+ else n->parent->right = n->right;
+ } else
+ root = n->right;
+ n->right->parent = n->parent;
+ } else if(n->left) {
+ if(n->parent) {
+ if(n->parent->left = n) n->parent->left = n->left;
+ else n->parent->right = n->left;
+ } else
+ root = n->left;
+ n->left->parent = n->parent;
+ } else {
+ if(n == root) root = 0;
+ }
+ delete n;
+ Collection<T>::count--;
+ return 0;
+ }
+
+ void insert_node(TreeNode<T> *n) {
+ TreeNode<T> *current = root, *parent = 0;
+ while(current) {
+ parent = current;
+ if(n->val < current->val)
+ current = current->left;
+ else
+ current = current->right;
+ }
+
+ if(parent) {
+ if(n->val < parent->val) {
+ parent->left = n;
+ n->parent = parent;
+ } else {
+ parent->right = n;
+ n->parent = parent;
+ }
+ } else
+ root = n;
+
+ }
+
+public:
+ class Iterator {
+ friend class BinaryTree<T>;
+ protected:
+
+ class EvalNode {
+ public:
+ bool evaluate;
+ TreeNode<T> *node;
+
+ EvalNode(): evaluate(false), node(0) {}
+ EvalNode(const bool eval, TreeNode<T> *n): evaluate(eval), node(n) {}
+ const bool operator==(const EvalNode &other) const {return node == other.node;}
+ EvalNode &operator=(const EvalNode &other) {evaluate = other.evaluate; node = other.node; return *this;}
+
+ };
+
+ TreeNode<T> *n;
+ LinkedList<EvalNode> stack;
+
+
+ Iterator(TreeNode<T> *start): n(0) {
+ if(start) {
+ stack.push(EvalNode(true, start));
+ next();
+ }
+ }
+
+ public:
+ Iterator(const Iterator &other):n(other.n), stack(other.stack) {}
+ virtual ~Iterator() {}
+
+ virtual T &val() {return n->val;}
+ virtual void next() {
+ EvalNode en;
+ bool popped = false;
+ while((popped = stack.pop(en)) && en.evaluate) {
+ if(en.node->right) stack.push(EvalNode(true, en.node->right));
+ stack.push(EvalNode(false, en.node));
+ if(en.node->left) stack.push(EvalNode(true, en.node->left));
+ }
+
+ n = (popped ? en.node : 0);
+ }
+ virtual const bool has_val() {return (n ? true : false);}
+ };
+
+ BinaryTree(): Collection<T>(), root(0) {};
+ BinaryTree(BinaryTree<T> &other): Collection<T>(), root(0) {
+ for(Iterator i = other.start(); i.has_val(); i.next())
+ add(i.val());
+ }
+ virtual ~BinaryTree() {clear();}
+
+ BinaryTree &operator=(BinaryTree<T> &other) {
+ clear();
+ for(Iterator i = other.start(); i.has_val(); i.next())
+ add(i.val());
+ return *this;
+ }
+
+ virtual void clear() {
+ TreeNode<T> *current = root, *parent = 0;
+ while(current) {
+ if(current->left) current = current->left;
+ else if(current->right) current = current->right;
+ else {
+ parent = current->parent;
+ delete current;
+ current = parent;
+ }
+ }
+
+ root = 0;
+ Collection<T>::count = 0;
+ }
+
+ void add(T &val) {
+ TreeNode<T> *n = new TreeNode<T>(val, 0);
+ insert_node(n);
+ Collection<T>::count++;
+ }
+
+ const bool remove(T &val) {
+ TreeNode<T> *current = root;
+ while(current) {
+ if(current->val == val)
+ break;
+ else if(val < current->val)
+ current = current->left;
+ else
+ current = current->right;
+ }
+
+ if(current) {
+ delete_node(current);
+ return true;
+ }
+
+ return false;
+ }
+
+ Iterator start() {return Iterator(root);}
+};
+
+template<class A, class B> class Pair {
+public:
+ A first;
+ B second;
+
+ Pair(const A &f): first(f) {}
+ Pair(const A &f, const B &s): first(f), second(s) {}
+ Pair(Pair<A,B> &other): first(other.first), second(other.second) {}
+ virtual ~Pair() {}
+
+ const bool operator<(const Pair<A,B> &other) const {return first < other.first;}
+ const bool operator==(const Pair<A,B> &other) const {return first == other.first;}
+ Pair<A,B> &operator=(const Pair<A,B> &other) {first = other.first; second = other.second; return *this;}
+};
+
+template<class A, class B> class Map: public BinaryTree< Pair< A, B > > {
+protected:
+
+ TreeNode<Pair< A, B > > *find(A &val) {
+ TreeNode<Pair< A, B > > *n = BinaryTree< Pair< A, B > >::root;
+ while(n) {
+ if(n->val.first == val)
+ return n;
+ else if(val < n->val.first)
+ n = n->left;
+ else
+ n = n->right;
+
+ }
+ return 0;
+ }
+public:
+ Map(): BinaryTree< Pair<A,B> >() {}
+ virtual ~Map() {}
+
+ void put(A &key, B &value) {
+ add(Pair<A,B>(key, value));
+ }
+
+ const bool get(A &key, B &val) const {
+ const TreeNode<Pair< A, B > > *n = find(key);
+ if(n) {
+ val = n->val.second;
+ return true;
+ } else
+ return false;
+ }
+
+ B &operator[](A &key) {
+ TreeNode<Pair< A, B > > *n = find(key);
+ if(n)
+ return n->val.second;
+ else {
+ Pair< A, B > p(key);
+ TreeNode<Pair< A, B > > *n = new TreeNode<Pair< A, B > >(p, 0);
+ insert_node(n);
+ Collection< Pair< A, B > >::count++;
+ return n->val.second;
+ }
+ }
+
+ const bool exists(A &key) const {
+ const TreeNode<Pair< A, B > > *n = find(key);
+ if(n) {
+ return true;
+ } else
+ return false;
+ }
+
+ const bool remove(A &key) {
+ TreeNode<Pair< A, B > > *n = find(key);
+ if(n) {
+ delete_node(n);
+ return true;
+ } else
+ return false;
+ }
+};
diff --git a/ping/common.h b/ping/common.h new file mode 100644 index 0000000..b43eca2 --- /dev/null +++ b/ping/common.h @@ -0,0 +1,124 @@ +#ifndef _COMMON_H
+#define _COMMON_H
+
+#define MAX_HISTORY (1440) // 12 hrs at 30 sec intervals
+
+#define PLUG "PING"
+
+#define DEFAULT_PING_PERIOD 30
+#define DEFAULT_PING_TIMEOUT 2
+#define DEFAULT_SHOW_POPUP true
+#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_ICON true
+#define DEFAULT_ATTACH_TO_CLIST false
+
+#define MAX_PINGADDRESS_STRING_LENGTH 256
+
+//#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+//#define VC_EXTRALEAN
+//#define _WIN32_WINNT 0x0500
+
+#define WINVER 0x0500
+#define _WIN32_WINNT 0x0400
+#define _WIN32_IE 0x0300
+
+#include <windows.h>
+#include <prsht.h>
+//#include <winsock2.h>
+#include <shellapi.h>
+#include <commdlg.h>
+#include <commctrl.h>
+#include <time.h>
+
+#include <stdio.h>
+
+#include <newpluginapi.h>
+#include <statusmodes.h>
+#include <m_options.h>
+#include <m_langpack.h>
+#include <m_popup.h>
+#include <m_system.h>
+#include <m_skin.h>
+#include <m_netlib.h>
+#include <m_database.h>
+#include <m_protocols.h>
+#include <m_protomod.h>
+#include <m_protosvc.h>
+#include <m_ignore.h>
+#include <m_clist.h>
+#include <m_clui.h>
+#include <m_genmenu.h>
+#include <m_cluiframes.h>
+#include <m_utils.h>
+
+#include <m_fontservice.h>
+
+#include <m_updater.h>
+
+#include "IcoLib.h"
+
+#include "collection.h"
+
+typedef struct {
+ int ping_period, ping_timeout;
+ bool show_popup, show_popup2, block_reps, logging;
+ char log_filename[MAX_PATH];
+ bool no_test_icon;
+ int row_height;
+ int indent;
+ COLORREF bg_colour;
+ int retries;
+ bool attach_to_clist;
+ bool log_csv;
+} PingOptions;
+
+#pragma warning( disable : 4786 )
+
+// a deque of pairs - ping time and timestamp
+struct HistPair {
+ short first;
+ time_t second;
+
+ const bool operator==(const HistPair &other) const {return first == other.first && second == other.second;}
+};
+typedef LinkedList< HistPair > HistoryList;
+
+
+#define PS_RESPONDING 1
+#define PS_NOTRESPONDING 2
+#define PS_TESTING 3
+#define PS_DISABLED 4
+
+struct PINGADDRESS {
+ int cbSize; //size in bytes of this structure
+ DWORD item_id;
+ 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
+ int index;
+
+ const bool operator==(const PINGADDRESS &b) const;
+ const bool operator<(const PINGADDRESS &b) const;
+};
+
+typedef Map<DWORD, HistoryList> HistoryMap;
+
+
+extern HANDLE hNetlibUser;
+extern HINSTANCE hInst;
+
+extern bool use_raw_ping;
+
+#endif
diff --git a/ping/green.ico b/ping/green.ico Binary files differnew file mode 100644 index 0000000..82ce348 --- /dev/null +++ b/ping/green.ico diff --git a/ping/grey.ico b/ping/grey.ico Binary files differnew file mode 100644 index 0000000..7b91f7a --- /dev/null +++ b/ping/grey.ico diff --git a/ping/icmp.cpp b/ping/icmp.cpp new file mode 100644 index 0000000..356cc34 --- /dev/null +++ b/ping/icmp.cpp @@ -0,0 +1,89 @@ +#include "common.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;
+ }
+
+ hIP = pIcmpCreateFile();
+ if (hIP == INVALID_HANDLE_VALUE) {
+ pIcmpCloseHandle(hIP);
+ 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/icmp.h b/ping/icmp.h new file mode 100644 index 0000000..902942e --- /dev/null +++ b/ping/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
diff --git a/ping/log.cpp b/ping/log.cpp new file mode 100644 index 0000000..6c6ba84 --- /dev/null +++ b/ping/log.cpp @@ -0,0 +1,59 @@ +#include "common.h"
+#include "log.h"
+
+int Log(WPARAM wParam, LPARAM lParam) {
+
+ char buf[1024], tbuf[512], dbuf[512];
+ CallService(PLUG "/GetLogFilename", (WPARAM)1024, (LPARAM)buf);
+
+ //char TBcapt[255];
+ SYSTEMTIME systime;
+
+ GetLocalTime(&systime);
+
+ GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systime, 0, tbuf, 512);
+ GetDateFormat(LOCALE_USER_DEFAULT, 0, &systime, 0, dbuf, 512);
+
+ char *line = (char *)wParam;
+
+ FILE *f = fopen(buf, "w+");
+ if(f) {
+ if(options.log_csv) {
+ fprintf(f, "%s, %s, %s\n", dbuf, tbuf, line);
+ } else {
+ fprintf(f, "%s, %s: %s\n", dbuf, tbuf, line);
+ }
+ fclose(f);
+ }
+
+ return 0;
+}
+
+int GetLogFilename(WPARAM wParam, LPARAM lParam) {
+ DBVARIANT dbv;
+ char *filename = (char *)lParam;
+ if(DBGetContactSetting(0, PLUG, "LogFilename", &dbv)) {
+ CallService(MS_DB_GETPROFILEPATH, (WPARAM)wParam, (LPARAM)filename);
+ strcat(filename, "\\");
+ strcat(filename, "ping_log.txt");
+ } else {
+ strncpy(filename, dbv.pszVal, wParam);
+ DBFreeVariant(&dbv);
+ }
+
+ ((char *)lParam)[wParam - 1] = 0;
+
+ return 0;
+}
+
+int SetLogFilename(WPARAM wParam, LPARAM lParam) {
+ DBWriteContactSettingString(0, PLUG, "LogFilename", (char *)lParam);
+ return 0;
+}
+
+int ViewLogData(WPARAM wParam, LPARAM lParam) {
+ char buf[1024];
+ CallService(PLUG "/GetLogFilename", (WPARAM)MAX_PATH, (LPARAM)buf);
+ return (int)ShellExecute((HWND)wParam, "edit", buf, "", "", SW_SHOW);
+}
+
diff --git a/ping/log.h b/ping/log.h new file mode 100644 index 0000000..6a18ea0 --- /dev/null +++ b/ping/log.h @@ -0,0 +1,12 @@ +#ifndef _PING_LOG
+#define _PING_LOG
+
+#pragma warning( disable : 4786 )
+#include "options.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
diff --git a/ping/menu.cpp b/ping/menu.cpp new file mode 100644 index 0000000..7d87b13 --- /dev/null +++ b/ping/menu.cpp @@ -0,0 +1,100 @@ +#include "common.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, PLUG, "Status", ID_STATUS_OFFLINE) != options.off_status;
+ if(disable) {
+ menu.hIcon = hIconDisabled;
+ menu.pszName = Translate("Disable");
+ } else {
+ menu.hIcon = hIconEnabled;
+ 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, PLUG, "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 = hIconResponding;
+ menu.pszName = Translate( "Enable All Pings" );
+ menu.pszService = PLUG "/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 = hIconDisabled;
+ menu.pszName = Translate( "Disable All Pings" );
+ menu.pszService = PLUG "/DisableAll";
+ CallService( MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&menu );
+
+ /*
+ // list items
+ menu.flags = 0;
+ menu.popupPosition = 0;
+ menu.pszPopupName = 0;
+ menu.cbSize = sizeof( menu );
+ menu.position =-300100;
+ //menu.popupPosition = 0;
+ menu.hIcon = hIconDisabled;
+ menu.pszName = Translate( "Disable" );
+ menu.pszService = PLUG "/ToggleEnabled";
+ menu.pszContactOwner = PLUG;
+ 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 = hIconResponding
+ menu.pszName = Translate( "Graph" );
+ menu.pszService = PLUG "/ShowGraph";
+ menu.pszContactOwner = PLUG;
+ 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 = hIconResponding;
+ menu.pszName = Translate( "Edit..." );
+ menu.pszService = PLUG "/Edit";
+ menu.pszContactOwner = PLUG;
+ hMenuGraph = (HANDLE)CallService( MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&menu );
+
+ hEventMenuBuild = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, MenuBuild);
+ */
+}
diff --git a/ping/menu.h b/ping/menu.h new file mode 100644 index 0000000..e6e1334 --- /dev/null +++ b/ping/menu.h @@ -0,0 +1,10 @@ +#ifndef _MENU_H
+#define _MENU_H
+
+#include "pinglist.h"
+#include "pinggraph.h"
+#include "utils.h"
+
+void InitMenus();
+
+#endif
diff --git a/ping/options.cpp b/ping/options.cpp new file mode 100644 index 0000000..621825b --- /dev/null +++ b/ping/options.cpp @@ -0,0 +1,631 @@ +#include "common.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};
+
+ switch ( msg ) {
+ case WM_INITDIALOG: {
+ TranslateDialogDefault( hwndDlg );
+
+ if(!ServiceExists(MS_FONT_REGISTER)) {
+ SetDlgItemText(hwndDlg, IDC_STATFS, Translate("Install the FontService plugin to change the font and font colour."));
+ }
+
+ if(ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) {
+ hw = GetDlgItem(hwndDlg, IDC_CHK_ATTACH);
+ EnableWindow(hw, FALSE);
+ }
+ CheckDlgButton(hwndDlg, IDC_CHK_ATTACH, options.attach_to_clist);
+
+ 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_LOGCSV, options.log_csv);
+ CheckDlgButton(hwndDlg, IDC_CHK_NOTESTICON, options.no_test_icon);
+
+ SendMessage(GetDlgItem(hwndDlg, IDC_SP_INDENT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(500, 0));
+ SendMessage(GetDlgItem(hwndDlg, IDC_SP_INDENT), UDM_SETPOS, 0, options.indent);
+ SendMessage(GetDlgItem(hwndDlg, IDC_SP_ROWHEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(500, 6));
+ SendMessage(GetDlgItem(hwndDlg, IDC_SP_ROWHEIGHT), UDM_SETPOS, 0, options.row_height);
+
+ SetDlgItemInt(hwndDlg, IDC_RPT, options.retries, FALSE);
+
+ SendDlgItemMessage(hwndDlg, IDC_BGCOL, CPM_SETCOLOUR, 0, options.bg_colour);
+
+ 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);
+ hw = GetDlgItem(hwndDlg, IDC_CHK_LOGCSV);
+ 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(LOWORD(wParam) == IDC_BGCOL) {
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ break;
+ }
+ 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);
+ }
+ break;
+ }
+
+ if (HIWORD( wParam ) == CBN_SELCHANGE) {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ break;
+ }
+
+ 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));
+ hw = GetDlgItem(hwndDlg, IDC_CHK_LOGCSV);
+ EnableWindow(hw, IsDlgButtonChecked(hwndDlg, IDC_CHK_LOG));
+ // drop through
+ case IDC_CHK_LOGCSV:
+ case IDC_CHECKPOPUP:
+ case IDC_CHECKPOPUP2:
+ case IDC_CHK_BLOCK:
+ case IDC_CHK_MINMAX:
+ case IDC_CHK_NOTESTICON:
+ case IDC_CHK_ATTACH:
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ break;
+ case IDC_BTN_VIEWLOG:
+ CallService(PLUG "/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;
+ }
+ break;
+ }
+ break;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->code == UDN_DELTAPOS ) {
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ }
+ if (((LPNMHDR)lParam)->code == PSN_APPLY ) {
+
+ 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;
+ options.log_csv = IsDlgButtonChecked(hwndDlg, IDC_CHK_LOGCSV) == BST_CHECKED;
+ GetDlgItemText(hwndDlg, IDC_ED_FILENAME, options.log_filename, MAX_PATH);
+
+ options.no_test_icon = IsDlgButtonChecked(hwndDlg, IDC_CHK_NOTESTICON) == BST_CHECKED;
+
+ options.indent = SendMessage(GetDlgItem(hwndDlg, IDC_SP_INDENT), UDM_GETPOS, 0, 0);
+ options.row_height = SendMessage(GetDlgItem(hwndDlg, IDC_SP_ROWHEIGHT), UDM_GETPOS, 0, 0);
+ options.bg_colour = SendDlgItemMessage(hwndDlg, IDC_BGCOL, CPM_GETCOLOUR, 0, 0);
+
+ DWORD new_retries = GetDlgItemInt( hwndDlg, IDC_RPT, &trans_success, FALSE);
+ if(trans_success) {
+ options.retries = new_retries;
+ }
+
+ bool new_attach = (IsDlgButtonChecked(hwndDlg, IDC_CHK_ATTACH) == BST_CHECKED);
+ if(!ServiceExists(MS_CLIST_FRAMES_ADDFRAME) && options.attach_to_clist != new_attach)
+ AttachToClist(new_attach);
+
+ options.attach_to_clist = new_attach;
+
+ SaveOptions();
+
+ RefreshWindow(0, 0);
+
+ if(options.logging) CallService(PLUG "/Log", (WPARAM)"options changed", 0);
+ if(hWakeEvent) SetEvent(hWakeEvent);
+ return TRUE;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+PINGLIST temp_list;
+PINGADDRESS add_edit_addr;
+
+// host edit
+BOOL CALLBACK DlgProcDestEdit(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
+ HWND hw;
+ int sel;
+ char *strptr;
+
+ switch ( msg ) {
+ case WM_INITDIALOG:
+ {
+ 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);
+
+ 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_DESTLAB);
+ SetFocus(hw);
+ }
+ return FALSE;
+ 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';
+
+ 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;
+}
+
+BOOL Edit(HWND hwnd, PINGADDRESS &addr) {
+ add_edit_addr = addr;
+ if(DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG3), hwnd, DlgProcDestEdit) == IDOK) {
+ addr = add_edit_addr;
+ return TRUE;
+ }
+ return FALSE;
+}
+// ping hosts 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.start(); i.has_val(); i.next()) {
+ int index = SendMessage(hw, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)i.val().pszLabel);
+ SendMessage(hw, LB_SETITEMDATA, index, (LPARAM)&i.val());
+ }
+
+ }
+ 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) {
+ PINGADDRESS *item = (PINGADDRESS *)SendMessage(hw, LB_GETITEMDATA, sel, 0);
+ PINGADDRESS temp = *item;
+ if(Edit(hwndDlg, temp)) {
+ *item = temp;
+ SendMessage(hw, LB_DELETESTRING, (WPARAM)sel, (LPARAM)0);
+ SendMessage(hw, LB_INSERTSTRING, (WPARAM)sel, (LPARAM)item->pszLabel);
+ SendMessage(hw, LB_SETITEMDATA, (WPARAM)sel, (LPARAM)item);
+ 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, sel > 0);
+ hw = GetDlgItem(hwndDlg, IDC_BTN_DESTDOWN);
+ int count = SendMessage(hw, LB_GETCOUNT, 0, 0);
+ EnableWindow(hw, (sel < count - 1));
+
+ 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 = PS_NOTRESPONDING;
+ add_edit_addr.item_id = 0;
+
+ if(DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG3), hwndDlg, DlgProcDestEdit) == IDOK) {
+
+ temp_list.add(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) {
+ PINGADDRESS *item = (PINGADDRESS *)SendMessage(hw, LB_GETITEMDATA, sel, 0);
+ SendMessage(hw, LB_DELETESTRING, (WPARAM)sel, 0);
+ temp_list.remove(*item);
+ }
+
+ 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) {
+ PINGADDRESS *item = (PINGADDRESS *)SendMessage(hw, LB_GETITEMDATA, sel2, 0),
+ *item2 = (PINGADDRESS *)SendMessage(hw, LB_GETITEMDATA, sel2 + 1, 0);
+ add_edit_addr = *item;
+ *item = *item2;
+ *item2 = add_edit_addr;
+
+ // keep indexes the same, as they're used for sorting the binary tree
+ int index = item->index, index2 = item2->index;
+ item->index = index2;
+ item2->index = index;
+
+ SendMessage(hw, LB_DELETESTRING, (WPARAM)sel2, (LPARAM)0);
+ SendMessage(hw, LB_INSERTSTRING, (WPARAM)sel2, (LPARAM)item->pszLabel);
+ SendMessage(hw, LB_SETITEMDATA, (WPARAM)sel2, (LPARAM)item);
+ SendMessage(hw, LB_DELETESTRING, (WPARAM)(sel2 + 1), (LPARAM)0);
+ SendMessage(hw, LB_INSERTSTRING, (WPARAM)(sel2 + 1), (LPARAM)item2->pszLabel);
+ SendMessage(hw, LB_SETITEMDATA, (WPARAM)(sel2 + 1), (LPARAM)item2);
+ 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) {
+ PINGADDRESS *item = (PINGADDRESS *)SendMessage(hw, LB_GETITEMDATA, sel2, 0),
+ *item2 = (PINGADDRESS *)SendMessage(hw, LB_GETITEMDATA, sel2 - 1, 0);
+ add_edit_addr = *item;
+ *item = *item2;
+ *item2 = add_edit_addr;
+
+ // keep indexes the same, as they're used for sorting the binary tree
+ int index = item->index, index2 = item2->index;
+ item->index = index2;
+ item2->index = index;
+
+ SendMessage(hw, LB_DELETESTRING, (WPARAM)sel2, (LPARAM)0);
+ SendMessage(hw, LB_INSERTSTRING, (WPARAM)sel2, (LPARAM)item->pszLabel);
+ SendMessage(hw, LB_SETITEMDATA, (WPARAM)sel2, (LPARAM)item);
+
+ SendMessage(hw, LB_DELETESTRING, (WPARAM)(sel2 - 1), (LPARAM)0);
+ SendMessage(hw, LB_INSERTSTRING, (WPARAM)(sel2 - 1), (LPARAM)item2->pszLabel);
+ SendMessage(hw, LB_SETITEMDATA, (WPARAM)(sel2 - 1), (LPARAM)item2);
+
+ 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;
+ }
+ }
+ if(LOWORD(wParam) == IDC_BGCOL
+ || LOWORD(wParam) == IDC_SP_INDENT || LOWORD(wParam) == IDC_SP_ROWHEIGHT)
+ {
+ SendMessage( GetParent( hwndDlg ), PSM_CHANGED, 0, 0 );
+ }
+ break;
+
+ case WM_NOTIFY:
+ if (((LPNMHDR)lParam)->code == PSN_APPLY ) {
+ CallService(PLUG "/SetAndSavePingList", (WPARAM)&temp_list, 0);
+ CallService(PLUG "/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)
+{
+#define OPTIONPAGE_OLD_SIZE2 60
+ DWORD mirVir = (DWORD)CallService(MS_SYSTEM_GETVERSION, 0, 0);
+
+ OPTIONSDIALOGPAGE odp = { 0 };
+ //odp.cbSize = sizeof(odp);
+ odp.cbSize = (mirVir >= 0x00060000 ? sizeof(odp) : OPTIONPAGE_OLD_SIZE2);
+ 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 = 0;
+ odp.pfnDlgProc = DlgProcOpts;
+ odp.pszTab = Translate("Settings");
+ CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp );
+
+ OPTIONSDIALOGPAGE odp2 = { 0 };
+ //odp.cbSize = sizeof(odp);
+ odp2.cbSize = (mirVir >= 0x00060000 ? sizeof(odp) : OPTIONPAGE_OLD_SIZE2);
+ odp2.position = -790000100;
+ odp2.hInstance = hInst;
+ odp2.pszTemplate = MAKEINTRESOURCE(IDD_DIALOG2);
+ odp2.pszTitle = (mirVir >= 0x00060000 ? Translate("PING") : Translate("PING Hosts"));
+ odp2.pszGroup = Translate("Network");
+ odp2.flags = ODPF_BOLDGROUPS;
+ odp2.nIDBottomSimpleControl = 0;
+ odp2.pfnDlgProc = DlgProcOpts2;
+ odp2.pszTab = Translate("Hosts");
+ CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp2 );
+ return 0;
+}
+
+void LoadOptions() {
+ options.ping_period = DBGetContactSettingDword(NULL, PLUG, "PingPeriod", DEFAULT_PING_PERIOD);
+
+ options.ping_timeout = DBGetContactSettingDword(NULL, PLUG, "PingTimeout", DEFAULT_PING_TIMEOUT);
+ CallService(PLUG "/SetPingTimeout", (WPARAM)options.ping_timeout, 0);
+ options.show_popup = (DBGetContactSettingByte(NULL, PLUG, "ShowPopup", DEFAULT_SHOW_POPUP ? 1 : 0) == 1);
+ options.show_popup2 = (DBGetContactSettingByte(NULL, PLUG, "ShowPopup2", DEFAULT_SHOW_POPUP2 ? 1 : 0) == 1);
+ options.block_reps = (DBGetContactSettingByte(NULL, PLUG, "BlockReps", DEFAULT_BLOCK_REPS ? 1 : 0) == 1);
+ options.logging = (DBGetContactSettingByte(NULL, PLUG, "LoggingEnabled", DEFAULT_LOGGING_ENABLED ? 1 : 0) == 1);
+
+ options.no_test_icon = (DBGetContactSettingByte(NULL, PLUG, "NoTestStatus", DEFAULT_NO_TEST_ICON ? 1 : 0) == 1);
+
+ options.indent = DBGetContactSettingWord(NULL, PLUG, "Indent", 0);
+ options.row_height = DBGetContactSettingWord(NULL, PLUG, "RowHeight", GetSystemMetrics(SM_CYSMICON));
+ options.bg_colour = (COLORREF)DBGetContactSettingDword(NULL, PLUG, "BgColor", GetSysColor(COLOR_3DFACE));
+
+ options.retries = DBGetContactSettingDword(NULL, PLUG, "Retries", 0);
+
+ CallService(PLUG "/GetLogFilename", (WPARAM)MAX_PATH, (LPARAM)options.log_filename);
+
+ ICMP::get_instance()->set_timeout(options.ping_timeout * 1000);
+
+ options.attach_to_clist = (DBGetContactSettingByte(NULL, PLUG, "AttachToClist", DEFAULT_ATTACH_TO_CLIST ? 1 : 0) == 1);
+ options.log_csv = (DBGetContactSettingByte(NULL, PLUG, "LogCSV", 0) == 1);
+}
+
+void SaveOptions() {
+ DBWriteContactSettingDword(NULL, PLUG, "PingPeriod", options.ping_period);
+ DBWriteContactSettingDword(NULL, PLUG, "PingTimeout", options.ping_timeout);
+ CallService(PLUG "/SetPingTimeout", (WPARAM)options.ping_timeout, 0);
+ DBWriteContactSettingByte(NULL, PLUG, "ShowPopup", options.show_popup ? 1 : 0);
+ DBWriteContactSettingByte(NULL, PLUG, "ShowPopup2", options.show_popup2 ? 1 : 0);
+ DBWriteContactSettingByte(NULL, PLUG, "BlockReps", options.block_reps ? 1 : 0);
+ DBWriteContactSettingByte(NULL, PLUG, "LoggingEnabled", options.logging ? 1 : 0);
+
+ DBWriteContactSettingByte(NULL, PLUG, "NoTestStatus", options.no_test_icon ? 1 : 0);
+
+ DBWriteContactSettingWord(NULL, PLUG, "Indent", options.indent);
+ DBWriteContactSettingWord(NULL, PLUG, "RowHeight", options.row_height);
+ DBWriteContactSettingDword(NULL, PLUG, "BgColor", (DWORD)options.bg_colour);
+
+ DBWriteContactSettingDword(NULL, PLUG, "Retries", (DWORD)options.retries);
+
+ CallService(PLUG "/SetLogFilename", (WPARAM)MAX_PATH, (LPARAM)options.log_filename);
+
+ ICMP::get_instance()->set_timeout(options.ping_timeout * 1000);
+
+ DBWriteContactSettingByte(NULL, PLUG, "AttachToClist", options.attach_to_clist ? 1 : 0);
+ DBWriteContactSettingByte(NULL, PLUG, "LogCSV", options.log_csv ? 1 : 0);
+}
diff --git a/ping/options.h b/ping/options.h new file mode 100644 index 0000000..8fe17ab --- /dev/null +++ b/ping/options.h @@ -0,0 +1,26 @@ +#ifndef _PING_OPTIONS
+#define _PING_OPTIONS
+
+#include "pinglist.h"
+#include "utils.h"
+#include "icmp.h"
+#include "pingthread.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);
+
+BOOL Edit(HWND hwnd, PINGADDRESS &addr);
+
+void LoadOptions();
+void SaveOptions();
+
+#endif
diff --git a/ping/ping.cpp b/ping/ping.cpp new file mode 100644 index 0000000..c1cbfb5 --- /dev/null +++ b/ping/ping.cpp @@ -0,0 +1,173 @@ +#include "common.h"
+#include "ping.h"
+#include <list>
+HINSTANCE hInst;
+PLUGINLINK *pluginLink;
+
+HANDLE hNetlibUser = 0;
+HANDLE hFillListEvent = 0;
+
+bool use_raw_ping = true;
+
+// plugin stuff
+PLUGININFO pluginInfo={
+ sizeof(PLUGININFO),
+ "Ping Plugin",
+ PLUGIN_MAKE_VERSION(0, 7, 0, 1),
+ "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" PING_API PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ return &pluginInfo;
+}
+
+void CreatePluginServices() {
+ // general
+ CreateServiceFunction(PLUG "/Ping", PluginPing);
+ CreateServiceFunction(PLUG "/DblClick", DblClick);
+
+ // list
+ CreateServiceFunction(PLUG "/ClearPingList", ClearPingList);
+ CreateServiceFunction(PLUG "/GetPingList", GetPingList);
+ CreateServiceFunction(PLUG "/SetPingList", SetPingList);
+ CreateServiceFunction(PLUG "/SetAndSavePingList", SetAndSavePingList);
+ CreateServiceFunction(PLUG "/LoadPingList", LoadPingList);
+ CreateServiceFunction(PLUG "/SavePingList", SavePingList);
+
+ reload_event_handle = CreateHookableEvent(PLUG "/ListReload");
+
+ //log
+ CreateServiceFunction(PLUG "/Log", Log);
+ CreateServiceFunction(PLUG "/ViewLogData", ViewLogData);
+ CreateServiceFunction(PLUG "/GetLogFilename", GetLogFilename);
+ CreateServiceFunction(PLUG "/SetLogFilename", SetLogFilename);
+
+ // menu
+ CreateServiceFunction(PLUG "/DisableAll", PingDisableAll);
+ CreateServiceFunction(PLUG "/EnableAll", PingEnableAll);
+ CreateServiceFunction(PLUG "/ToggleEnabled", ToggleEnabled);
+ CreateServiceFunction(PLUG "/ShowGraph", ShowGraph);
+ CreateServiceFunction(PLUG "/Edit", EditContact);
+
+}
+
+int OnShutdown(WPARAM wParam, LPARAM lParam) {
+ graphs_cleanup();
+
+ UnhookEvent(hFillListEvent);
+
+ if(use_raw_ping)
+ cleanup_raw_ping();
+ else
+ ICMP::get_instance()->stop();
+
+ DeinitList();
+
+ return 0;
+}
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam) {
+
+ NETLIBUSER nl_user = {0};
+ nl_user.cbSize = sizeof(nl_user);
+ nl_user.szSettingsModule = PLUG;
+ //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 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);
+
+ InitIcons();
+
+ InitMenus();
+
+ hFillListEvent = HookEvent(PLUG "/ListReload", FillList);
+
+ if(!DBGetContactSettingByte(0, PLUG, "PingPlugImport", 0)) {
+ if(DBGetContactSettingDword(0, "PingPlug", "NumEntries", 0)) {
+ import_ping_addresses();
+ DBWriteContactSettingByte(0, PLUG, "PingPlugImport", 1);
+ }
+ }
+
+ InitList();
+
+ CallService(PLUG "/LoadPingList", 0, 0);
+
+ graphs_init();
+
+ if(options.logging) CallService(PLUG "/Log", (WPARAM)"start", 0);
+
+ return 0;
+}
+
+extern "C" PING_API int Load(PLUGINLINK *link)
+{
+ pluginLink=link;
+
+ if(init_raw_ping()) {
+ //MessageBox(0, Translate("Failed to initialize. Plugin disabled."), Translate("Ping Plugin"), MB_OK | MB_ICONERROR);
+ //return 1;
+ use_raw_ping = false;
+ }
+ DBWriteContactSettingByte(0, PLUG, "UsingRawSockets", (BYTE)use_raw_ping);
+
+ DuplicateHandle( GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &mainThread, THREAD_SET_CONTEXT, FALSE, 0 );
+ hWakeEvent = CreateEvent(NULL, FALSE, FALSE, "Local\\ThreadWaitEvent");
+
+ InitializeCriticalSection(&list_cs);
+ InitializeCriticalSection(&thread_finished_cs);
+ InitializeCriticalSection(&list_changed_cs);
+ InitializeCriticalSection(&data_list_cs);
+
+ // create services before loading options - so we can have the 'getlogfilename' service!
+ CreatePluginServices();
+
+ LoadOptions();
+
+ SkinAddNewSound("PingTimeout", "Ping Timout", 0);
+ SkinAddNewSound("PingReply", "Ping Reply", 0);
+
+ HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
+
+ HookEvent(ME_OPT_INITIALISE, PingOptInit );
+
+ HookEvent(ME_SYSTEM_PRESHUTDOWN, OnShutdown);
+
+ return 0;
+}
+
+extern "C" PING_API int Unload(void)
+{
+ SavePingList(0, 0);
+
+ DeleteCriticalSection(&list_cs);
+ DeleteCriticalSection(&thread_finished_cs);
+ DeleteCriticalSection(&list_changed_cs);
+ DeleteCriticalSection(&data_list_cs);
+
+ CloseHandle( mainThread );
+
+ if(options.logging) CallService(PLUG "/Log", (WPARAM)"stop", 0);
+
+ return 0;
+}
diff --git a/ping/ping.dsp b/ping/ping.dsp new file mode 100644 index 0000000..3e5ada7 --- /dev/null +++ b/ping/ping.dsp @@ -0,0 +1,249 @@ +# Microsoft Developer Studio Project File - Name="ping" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=ping - 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 "ping.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 "ping.mak" CFG="ping - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "ping - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "ping - 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)" == "ping - 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 "PING_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 "PING_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 /dll /machine:I386 /out:"../../bin/release/plugins/pingplug.dll"
+# SUBTRACT LINK32 /nodefaultlib
+
+!ELSEIF "$(CFG)" == "ping - 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 "PING_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 "PING_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 /base:"0x22040000" /dll /debug /machine:I386 /out:"../../bin/debug/plugins/pingplug.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "ping - Win32 Release"
+# Name "ping - 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=.\ping.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=.\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=.\IcoLib.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=.\ping.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=.\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=.\green.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\grey.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\ico00001.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\icon1.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\icon2.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\icon3.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\ping.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\red.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\yellow.ico
+# 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/ping.dsw b/ping/ping.dsw new file mode 100644 index 0000000..732d816 --- /dev/null +++ b/ping/ping.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "ping"=".\ping.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/ping/ping.h b/ping/ping.h new file mode 100644 index 0000000..f38ecca --- /dev/null +++ b/ping/ping.h @@ -0,0 +1,42 @@ +/*
+Based on the
+Miranda plugin template, originally by Richard Hughes
+http://miranda-icq.sourceforge.net/
+
+© 2004 Scott Ellis
+
+*/
+
+#ifndef _PING
+#define _PING
+
+
+// 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 PING_EXPORTS
+#define PING_API __declspec(dllexport)
+#else
+#define PING_API __declspec(dllimport)
+#endif
+
+#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" PING_API PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion);
+extern "C" PING_API int Load(PLUGINLINK *link);
+extern "C" PING_API int Unload(void);
+
+#endif
diff --git a/ping/ping.mdsp b/ping/ping.mdsp new file mode 100644 index 0000000..7d12ab0 --- /dev/null +++ b/ping/ping.mdsp @@ -0,0 +1,119 @@ +[Project]
+name=ping
+type=2
+defaultConfig=0
+
+[Debug]
+// compiler
+workingDirectory=
+arguments=
+intermediateFilesDirectory=Debug
+outputFilesDirectory=Debug
+compilerPreprocessor=PING_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\pingplug.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=PING_EXPORTS
+extraCompilerOptions=
+compilerIncludeDirectory=
+noWarning=0
+defaultWarning=0
+allWarning=1
+extraWarning=0
+isoWarning=0
+warningsAsErrors=0
+debugType=1
+debugLevel=1
+exceptionEnabled=0
+runtimeTypeEnabled=0
+optimizeLevel=2
+
+// linker
+libraryPath=
+outputFilename=Release\pingplug.dll
+libraries=ws2_32,gdi32,comdlg32
+extraLinkerOptions=
+ignoreStartupFile=0
+ignoreDefaultLibs=0
+stripExecutableFile=1
+
+// archive
+extraArchiveOptions=
+
+//resource
+resourcePreprocessor=
+resourceIncludeDirectory=
+extraResourceOptions=
+
+[Source]
+1=icmp.cpp
+2=log.cpp
+3=menu.cpp
+4=options.cpp
+5=ping.cpp
+6=pinggraph.cpp
+7=pinglist.cpp
+8=pingthread.cpp
+9=rawping.cpp
+10=utils.cpp
+[Header]
+1=IcoLib.h
+2=common.h
+3=icmp.h
+4=log.h
+5=menu.h
+6=options.h
+7=ping.h
+8=pinggraph.h
+9=pinglist.h
+10=pingthread.h
+11=rawping.h
+12=resource.h
+13=utils.h
+14=collection.h
+[Resource]
+1=ping.rc
+[Other]
+[History]
+utils.cpp,7005
+pinglist.cpp,3419
+pinggraph.cpp,7484
+collection.h,6339
+options.cpp,21263
+..\..\..\..\..\..\..\msys\include\stlport\stl\_list.h,1137
+rawping.cpp,3607
+pingthread.cpp,13438
diff --git a/ping/ping.plg b/ping/ping.plg new file mode 100644 index 0000000..64fe6ba --- /dev/null +++ b/ping/ping.plg @@ -0,0 +1,80 @@ +<html>
+<body>
+<pre>
+<h1>Build Log</h1>
+<h3>
+--------------------Configuration: ping - Win32 Release--------------------
+</h3>
+<h3>Command Lines</h3>
+Creating temporary file "C:\DOCUME~1\sje\LOCALS~1\Temp\RSPE7.tmp" with contents
+[
+/nologo /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PING_EXPORTS" /D "_WINDLL" /D "_AFXDLL" /Fp"Release/ping.pch" /Yu"stdafx.h" /Fo"Release/" /Fd"Release/" /FD /c
+"C:\Documents and Settings\sje\My Documents\MyProjects\miranda\plugins\ping\ping.cpp"
+]
+Creating command line "cl.exe @C:\DOCUME~1\sje\LOCALS~1\Temp\RSPE7.tmp"
+Creating temporary file "C:\DOCUME~1\sje\LOCALS~1\Temp\RSPE8.tmp" with contents
+[
+ws2_32.lib wsock32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib /nologo /dll /incremental:no /pdb:"Release/pingplug.pdb" /machine:I386 /out:"../../bin/release/plugins/pingplug.dll" /implib:"Release/pingplug.lib"
+".\Release\icmp.obj"
+".\Release\log.obj"
+".\Release\menu.obj"
+".\Release\options.obj"
+".\Release\ping.obj"
+".\Release\pinggraph.obj"
+".\Release\pinglist.obj"
+".\Release\pingthread.obj"
+".\Release\rawping.obj"
+".\Release\StdAfx.obj"
+".\Release\utils.obj"
+".\Release\ping.res"
+]
+Creating command line "link.exe @C:\DOCUME~1\sje\LOCALS~1\Temp\RSPE8.tmp"
+<h3>Output Window</h3>
+Compiling...
+ping.cpp
+Linking...
+ Creating library Release/pingplug.lib and object Release/pingplug.exp
+
+
+
+<h3>Results</h3>
+pingplug.dll - 0 error(s), 0 warning(s)
+<h3>
+--------------------Configuration: ping - Win32 Debug--------------------
+</h3>
+<h3>Command Lines</h3>
+Creating temporary file "C:\DOCUME~1\sje\LOCALS~1\Temp\RSPEC.tmp" with contents
+[
+/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PING_EXPORTS" /D "_WINDLL" /D "_AFXDLL" /Fp"Debug/ping.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
+"C:\Documents and Settings\sje\My Documents\MyProjects\miranda\plugins\ping\ping.cpp"
+]
+Creating command line "cl.exe @C:\DOCUME~1\sje\LOCALS~1\Temp\RSPEC.tmp"
+Creating temporary file "C:\DOCUME~1\sje\LOCALS~1\Temp\RSPED.tmp" with contents
+[
+user32.lib gdi32.lib ws2_32.lib shell32.lib comdlg32.lib /nologo /base:"0x22040000" /dll /incremental:yes /pdb:"Debug/pingplug.pdb" /debug /machine:I386 /out:"../../bin/debug/plugins/pingplug.dll" /implib:"Debug/pingplug.lib" /pdbtype:sept
+".\Debug\icmp.obj"
+".\Debug\log.obj"
+".\Debug\menu.obj"
+".\Debug\options.obj"
+".\Debug\ping.obj"
+".\Debug\pinggraph.obj"
+".\Debug\pinglist.obj"
+".\Debug\pingthread.obj"
+".\Debug\rawping.obj"
+".\Debug\StdAfx.obj"
+".\Debug\utils.obj"
+".\Debug\ping.res"
+]
+Creating command line "link.exe @C:\DOCUME~1\sje\LOCALS~1\Temp\RSPED.tmp"
+<h3>Output Window</h3>
+Compiling...
+ping.cpp
+Linking...
+
+
+
+<h3>Results</h3>
+pingplug.dll - 0 error(s), 0 warning(s)
+</pre>
+</body>
+</html>
diff --git a/ping/ping.rc b/ping/ping.rc new file mode 100644 index 0000000..f26caec --- /dev/null +++ b/ping/ping.rc @@ -0,0 +1,227 @@ +// 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
+
+/////////////////////////////////////////////////////////////////////////////
+// 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
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON_DISABLED ICON "grey.ico"
+IDI_ICON_NOTRESPONDING ICON "red.ico"
+IDI_ICON_RESPONDING ICON "green.ico"
+IDI_ICON_TESTING ICON "yellow.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG1 DIALOGEX 0, 0, 303, 227
+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,9,21,121,8
+ EDITTEXT IDC_PPM,135,18,40,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "Timeout",IDC_CHECKPOPUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,20,72,10
+ RTEXT "Ping timeout (secs):",IDC_STATIC,9,41,121,8
+ EDITTEXT IDC_PT,135,39,40,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ GROUPBOX "Logging",IDC_STATIC,4,165,293,55
+ CONTROL "Log to File",IDC_CHK_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,39,178,69,10
+ LTEXT "Log Filename:",IDC_STATIC,14,198,56,8
+ EDITTEXT IDC_ED_FILENAME,74,195,158,14,ES_AUTOHSCROLL
+ GROUPBOX "Network",IDC_STATIC,4,5,205,72
+ GROUPBOX "PopUps",IDC_STATIC,218,5,79,72
+ CONTROL "Reply",IDC_CHECKPOPUP2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,36,72,10
+ CONTROL "Block Repetitions",IDC_CHK_BLOCK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,223,60,72,10
+ PUSHBUTTON "View Log",IDC_BTN_VIEWLOG,238,176,54,14
+ PUSHBUTTON "Browse...",IDC_BTN_LOGBROWSE,238,194,54,16
+ GROUPBOX "Interface",IDC_STATIC,4,84,293,76
+ CONTROL "Do not change icon when testing",IDC_CHK_NOTESTICON,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,145,181,10
+ CONTROL "Custom1",IDC_BGCOL,"ColourPicker",WS_TABSTOP,220,108,40,9
+ CTEXT "Background",IDC_STATIC,217,96,45,9
+ LTEXT "Use the Customize/Fonts options to change text size and colour.",IDC_STATFS,20,101,174,18
+ RTEXT "Indent:",IDC_STATIC,44,127,33,8
+ EDITTEXT IDC_EDIT1,89,124,33,15,ES_AUTOHSCROLL
+ CONTROL "Spin2",IDC_SP_INDENT,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,121,124,12,15
+ RTEXT "Row height:",IDC_STATIC,154,127,52,8
+ EDITTEXT IDC_EDIT2,217,124,33,15,ES_AUTOHSCROLL
+ CONTROL "Spin3",IDC_SP_ROWHEIGHT,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,250,124,12,15
+ RTEXT "Repeats for success/failure:",IDC_STATIC,9,60,121,8
+ EDITTEXT IDC_RPT,135,59,40,12,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT
+ CONTROL "Attach to contact list",IDC_CHK_ATTACH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,145,94,10
+ CONTROL "Use CSV format",IDC_CHK_LOGCSV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,136,178,96,10
+END
+
+IDD_DIALOG2 DIALOGEX 0, 0, 285, 212
+STYLE DS_SETFONT | WS_POPUP
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+ PUSHBUTTON "Add",IDC_BTN_DESTADD,30,172,38,15
+ LISTBOX IDC_LST_DEST,29,32,228,128,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ PUSHBUTTON "Remove",IDC_BTN_DESTREM,124,172,38,15,WS_DISABLED
+ PUSHBUTTON "Edit",IDC_BTN_DESTEDIT,77,172,38,15,WS_DISABLED
+ PUSHBUTTON "Up",IDC_BTN_DESTUP,171,172,38,15,WS_DISABLED
+ PUSHBUTTON "Down",IDC_BTN_DESTDOWN,218,172,38,15,WS_DISABLED
+END
+
+IDD_DIALOG3 DIALOG 0, 0, 263, 291
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Edit Host"
+FONT 8, "MS Sans Serif"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,78,270,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,134,270,50,14
+ LTEXT "Address:",IDC_STATIC,24,34,37,8
+ LTEXT "Label:",IDC_STATIC,31,49,30,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,72,69,71,10
+ LTEXT "Port:",IDC_STATIC,151,69,25,8
+ EDITTEXT IDC_ED_DESTPORT,181,66,40,12,ES_RIGHT | ES_AUTOHSCROLL | ES_WANTRETURN | ES_NUMBER | WS_DISABLED
+ CTEXT "Control Protocol:",IDC_STATIC,84,106,92,8
+ COMBOBOX IDC_COMBO_DESTPROTO,83,119,97,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX IDC_COMBO_DESTSTAT,156,158,76,30,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Set my status to:",IDC_STATIC,151,143,87,8
+ LTEXT "On success, if my status is:",IDC_STATIC,25,143,115,8
+ COMBOBOX IDC_COMBO_DESTSTAT2,33,158,90,30,CBS_DROPDOWNLIST | WS_DISABLED | WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_ED_COMMAND,34,197,195,14,ES_AUTOHSCROLL
+ CTEXT "Execute the following command on double-click:",IDC_STATIC,28,182,207,8
+ GROUPBOX "Contact",IDC_STATIC,7,7,249,86
+ GROUPBOX "Protocols",IDC_STATIC,7,97,249,166
+ EDITTEXT IDC_ED_PARAMS,33,236,195,14,ES_AUTOHSCROLL
+ CTEXT "(Optional) Command Parameters:",IDC_STATIC,27,219,207,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DIALOG1, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 297
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 220
+ END
+
+ IDD_DIALOG2, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 278
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 205
+ END
+
+ IDD_DIALOG3, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 256
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 284
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MENU1 MENU
+BEGIN
+ POPUP "Menu"
+ BEGIN
+ MENUITEM "Graph", ID_MENU_GRAPH
+ MENUITEM "Enable", ID_MENU_TOGGLE
+ MENUITEM "Edit", ID_MENU_EDIT
+ MENUITEM SEPARATOR
+ MENUITEM "Disable all pings", ID_MENU_DISABLEALLPINGS
+ MENUITEM "Enable all pings", ID_MENU_ENABLEALLPINGS
+ MENUITEM SEPARATOR
+ MENUITEM "Options...", ID_MENU_OPTIONS
+ MENUITEM "Hosts...", 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/ping.sln b/ping/ping.sln new file mode 100644 index 0000000..3e77848 --- /dev/null +++ b/ping/ping.sln @@ -0,0 +1,20 @@ +
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ping", "ping.vcproj", "{F31BD1B6-EE9D-4F76-A047-F8AEADC26086}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F31BD1B6-EE9D-4F76-A047-F8AEADC26086}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F31BD1B6-EE9D-4F76-A047-F8AEADC26086}.Debug|Win32.Build.0 = Debug|Win32
+ {F31BD1B6-EE9D-4F76-A047-F8AEADC26086}.Release|Win32.ActiveCfg = Release|Win32
+ {F31BD1B6-EE9D-4F76-A047-F8AEADC26086}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/ping/ping.vcproj b/ping/ping.vcproj new file mode 100644 index 0000000..5209216 --- /dev/null +++ b/ping/ping.vcproj @@ -0,0 +1,563 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="ping"
+ ProjectGUID="{F31BD1B6-EE9D-4F76-A047-F8AEADC26086}"
+ RootNamespace="ping"
+ 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/ping.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;PING_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="common.h"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ />
+ <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/pingplug.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug/pingplug.pdb"
+ BaseAddress="0x22040000"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Debug/ping.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"
+ WholeProgramOptimization="1"
+ >
+ <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/ping.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="1"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;PING_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ StringPooling="true"
+ ExceptionHandling="1"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="common.h"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <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/pingplug.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Release/pingplug.pdb"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ BaseAddress="0x22040000"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ EmbedManifest="false"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release/ping.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="ping.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="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="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="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=".\collection.h"
+ >
+ </File>
+ <File
+ RelativePath="common.h"
+ >
+ </File>
+ <File
+ RelativePath="icmp.h"
+ >
+ </File>
+ <File
+ RelativePath="IcoLib.h"
+ >
+ </File>
+ <File
+ RelativePath="log.h"
+ >
+ </File>
+ <File
+ RelativePath="menu.h"
+ >
+ </File>
+ <File
+ RelativePath="options.h"
+ >
+ </File>
+ <File
+ RelativePath="ping.h"
+ >
+ </File>
+ <File
+ RelativePath="pinggraph.h"
+ >
+ </File>
+ <File
+ RelativePath="pinglist.h"
+ >
+ </File>
+ <File
+ RelativePath="pingthread.h"
+ >
+ </File>
+ <File
+ RelativePath="rawping.h"
+ >
+ </File>
+ <File
+ RelativePath="resource.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="green.ico"
+ >
+ </File>
+ <File
+ RelativePath="grey.ico"
+ >
+ </File>
+ <File
+ RelativePath="ico00001.ico"
+ >
+ </File>
+ <File
+ RelativePath="icon1.ico"
+ >
+ </File>
+ <File
+ RelativePath="icon2.ico"
+ >
+ </File>
+ <File
+ RelativePath="icon3.ico"
+ >
+ </File>
+ <File
+ RelativePath="ping.rc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="red.ico"
+ >
+ </File>
+ <File
+ RelativePath="yellow.ico"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="cut_code.txt"
+ >
+ </File>
+ <File
+ RelativePath="ReadMe.txt"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/ping/pinggraph.cpp b/ping/pinggraph.cpp new file mode 100644 index 0000000..0ce5184 --- /dev/null +++ b/ping/pinggraph.cpp @@ -0,0 +1,325 @@ +#include "common.h"
+#include "pinggraph.h"
+
+HistoryMap history_map;
+
+#define ID_REPAINT_TIMER 10101
+
+struct WindowData {
+ DWORD item_id;
+ HistoryList list;
+ HWND hwnd_chk_grid;
+ HWND hwnd_chk_stat;
+ bool show_grid;
+ bool show_stat;
+};
+
+#define WM_REBUILDLIST (WM_USER + 5)
+
+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.start(); i.has_val(); i.next()) {
+ if(i.val().item_id == wd->item_id) {
+ wd->list = history_map[wd->item_id];
+ 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);
+
+ if(wd->hwnd_chk_grid == 0) {
+ wd->hwnd_chk_grid = CreateWindow("BUTTON", Translate("Show grid lines"), WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 0, 0, 0, 0, hwnd, 0, hInst, 0);
+ SendMessage(wd->hwnd_chk_grid, BM_SETCHECK, wd->show_grid ? BST_CHECKED : BST_UNCHECKED, 0);
+ }
+ if(wd->hwnd_chk_stat == 0) {
+ wd->hwnd_chk_stat = CreateWindow("BUTTON", Translate("Show stats"), WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 0, 0, 0, 0, hwnd, 0, hInst, 0);
+ SendMessage(wd->hwnd_chk_stat, BM_SETCHECK, wd->show_stat ? BST_CHECKED : BST_UNCHECKED, 0);
+ }
+ 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_COMMAND:
+ if(HIWORD(wParam) == BN_CLICKED) {
+ WindowData *wd = (WindowData *)GetWindowLong(hwnd, GWL_USERDATA);
+ if((HWND)lParam == wd->hwnd_chk_grid) {
+ wd->show_grid = (SendMessage(wd->hwnd_chk_grid, BM_GETCHECK, 0, 0) == BST_CHECKED);
+ } else if((HWND)lParam == wd->hwnd_chk_stat) {
+ wd->show_stat = (SendMessage(wd->hwnd_chk_stat, BM_GETCHECK, 0, 0) == BST_CHECKED);
+ }
+ InvalidateRect(hwnd, 0, TRUE);
+ }
+ return TRUE;
+ 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(wd && (hdc = BeginPaint(hwnd, &ps)) != 0) {
+ GetClientRect(hwnd, &r);
+ FillRect(hdc, &r, GetSysColorBrush(COLOR_WINDOW));
+
+ short max_value = -1, min_value = (short)0x7FFF,
+ graph_height = 0; // this is minimum graph height, in ms
+ double avg = 0;
+ for(HistoryList::Iterator hli = wd->list.start(); hli.has_val(); hli.next()) {
+ if(hli.val().first > max_value) max_value = hli.val().first;
+ if(hli.val().first >= 0 && hli.val().first < min_value) min_value = hli.val().first;
+ avg += hli.val().first;
+ }
+ if(wd->list.size())
+ avg /= wd->list.size();
+
+ graph_height = (int)(max_value * 1.2f);
+ if(graph_height < MIN_GRAPH_HEIGHT) graph_height = 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)graph_height;
+
+ time_t last_time = 0, time, start_time = 0;
+ if(wd->list.size())
+ start_time = wd->list.start().val().second;
+
+ 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);
+
+ // set up pen for horiz (ping time) and vert (time covered by graph) lines
+ HPEN hPenOld, hPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DDKSHADOW));
+ hPenOld = (HPEN)SelectObject(hdc, hPen);
+
+ for(HistoryList::Iterator hi = wd->list.start(); hi.has_val(); hi.next()) {
+ if(hi.val().first != -1) {
+ bar.top = bar.bottom - (int)(hi.val().first * unit_height + 0.5f);
+ FillRect(hdc, &bar, GetSysColorBrush(COLOR_HOTLIGHT));
+ }
+
+ time = hi.val().second - start_time;
+
+ if(time / MARK_PERIOD != last_time / MARK_PERIOD) { // new minute
+ 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);
+ }
+
+ if(wd->show_grid) {
+ // draw horizontal lines to mark every 100ms
+ for(int li = 0; li < graph_height; 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));
+ }
+ }
+
+ HPEN hPen2 = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
+ if(wd->show_stat) {
+ SelectObject(hdc, hPen2);
+ MoveToEx(hdc, r.left, r.bottom - (int)(avg * unit_height + 0.5f), 0);
+ LineTo(hdc, r.right, r.bottom - (int)(avg * unit_height + 0.5f));
+ if(max_value != avg) {
+ MoveToEx(hdc, r.left, r.bottom - (int)(max_value * unit_height + 0.5f), 0);
+ LineTo(hdc, r.right, r.bottom - (int)(max_value * unit_height + 0.5f));
+ MoveToEx(hdc, r.left, r.bottom - (int)(min_value * unit_height + 0.5f), 0);
+ LineTo(hdc, r.right, r.bottom - (int)(min_value * unit_height + 0.5f));
+ }
+ }
+
+ // restore pen
+ SelectObject(hdc, hPenOld);
+ DeleteObject(hPen);
+ DeleteObject(hPen2);
+
+ SetBkMode(hdc, TRANSPARENT);
+ SetTextColor(hdc, GetSysColor(COLOR_3DDKSHADOW));
+ char buff[64];
+ if(wd->show_grid) {
+ sprintf(buff, Translate("%d ms"), MARK_TIME);
+ TextOut(hdc, r.right - 100, r.bottom - (int)(unit_height * MARK_TIME + 0.5f), buff, strlen(buff));
+ }
+
+ if(wd->show_stat) {
+ SetTextColor(hdc, RGB(255, 0, 0));
+ sprintf(buff, Translate("AVG %.1lf ms"), avg);
+ TextOut(hdc, r.left + 10, r.bottom - (int)(avg * unit_height + 0.5f), buff, strlen(buff));
+ if(max_value != avg) {
+ sprintf(buff, Translate("MAX %hd ms"), max_value);
+ TextOut(hdc, r.left + 10, r.bottom - (int)(max_value * unit_height + 0.5f), buff, strlen(buff));
+ sprintf(buff, Translate("MIN %hd ms"), min_value);
+ TextOut(hdc, r.left + 10, r.bottom - (int)(min_value * unit_height + 0.5f), buff, strlen(buff));
+ }
+ }
+
+ EndPaint(hwnd, &ps);
+ }
+ }
+ return TRUE;
+
+ case WM_ERASEBKGND:
+ return TRUE;
+
+ case WM_SIZE:
+ {
+ WindowData *wd = (WindowData *)GetWindowLong(hwnd, GWL_USERDATA);
+ RECT r;
+ GetClientRect(hwnd, &r);
+ if(wd->hwnd_chk_grid != 0) SetWindowPos(wd->hwnd_chk_grid, 0, r.right - 150, r.top + 10, 120, 20, SWP_NOZORDER | SWP_NOACTIVATE);
+ if(wd->hwnd_chk_stat != 0) SetWindowPos(wd->hwnd_chk_stat, 0, r.right - 150, r.top + 30, 120, 20, SWP_NOZORDER | SWP_NOACTIVATE);
+ }
+ InvalidateRect(hwnd, 0, FALSE);
+ break;
+ case WM_CLOSE:
+ {
+ KillTimer(hwnd, ID_REPAINT_TIMER);
+ WindowData *wd = (WindowData *)GetWindowLong(hwnd, GWL_USERDATA);
+ {
+ char buff[30];
+ sprintf(buff, "pinggraphwnd%d", wd->item_id);
+ Utils_SaveWindowPosition(hwnd, 0, PLUG, buff);
+ }
+ }
+ break;
+ case WM_DESTROY:
+ {
+ WindowData *wd = (WindowData *)GetWindowLong(hwnd, GWL_USERDATA);
+ {
+ char buff[30];
+ sprintf(buff, "WindowHandle%d", wd->item_id);
+ DBWriteContactSettingDword(0, PLUG, buff, 0);
+ }
+ delete wd;
+ }
+ // drop through
+ };
+
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+int ShowGraph(WPARAM wParam, LPARAM lParam) {
+ char buff[30];
+ sprintf(buff, "WindowHandle%d", (DWORD)wParam);
+ HWND hGraphWnd = (HWND)DBGetContactSettingDword(0, PLUG, buff, 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 = hIconResponding;
+ wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
+ wndclass.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = PLUG "GraphWindow";
+ RegisterClass(&wndclass);
+
+ char title[256];
+ strcpy(title, "Ping Graph");
+ if(lParam) {
+ strcat(title, " - ");
+ strncat(title, (char *)lParam, 256 - 13);
+ }
+
+ HWND parent = 0;
+ hGraphWnd = CreateWindowEx(0, PLUG "GraphWindow", title,
+ (WS_THICKFRAME | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN) & ~CS_VREDRAW & ~CS_HREDRAW,
+ 0,0,800,600,parent,NULL,hInst,NULL);
+
+ WindowData *wd = new WindowData;
+ wd->item_id = (DWORD)wParam; // wParam is destination id
+ wd->hwnd_chk_grid = 0;
+ wd->hwnd_chk_stat = 0;
+ wd->show_grid = DBGetContactSettingByte(0, PLUG, "ShowGridLines", 0) ? true : false;
+ wd->show_stat = DBGetContactSettingByte(0, PLUG, "ShowStats", 1) ? true : false;
+
+ DBWriteContactSettingDword(0, PLUG, buff, (DWORD)hGraphWnd);
+
+ SetWindowLong(hGraphWnd, GWL_USERDATA, (LONG)wd);
+
+ sprintf(buff, "pinggraphwnd%d", wd->item_id);
+ Utils_RestoreWindowPosition(hGraphWnd, 0, PLUG, buff);
+
+ if(!IsWindowVisible(hGraphWnd))
+ ShowWindow(hGraphWnd, SW_SHOW);
+
+ return 0;
+}
+
+// save window positions, close windows
+void graphs_cleanup() {
+ int list_size = GetListSize(0, 0);
+ char buff[64];
+ HWND hwnd;
+
+ for(int i = 0; i < list_size; i++) {
+ sprintf(buff, "WindowHandle%d", i);
+ if(hwnd = (HWND)DBGetContactSettingDword(0, PLUG, buff, 0)) {
+ DestroyWindow(hwnd);
+ DBWriteContactSettingDword(0, PLUG, buff, 0);
+ sprintf(buff, "WindowWasOpen%d", i);
+ DBWriteContactSettingByte(0, PLUG, buff, 1);
+ }
+ }
+}
+
+// remove old data, possibly left from a crash
+void graphs_init() {
+ PINGLIST pl;
+ char buff[64];
+ CallService(PLUG "/GetPingList", 0, (LPARAM)&pl);
+ for(PINGLIST::Iterator i = pl.start(); i.has_val(); i.next()) {
+ sprintf(buff, "WindowHandle%d", i.val().item_id); // clean up from possible crash
+ DBWriteContactSettingDword(0, PLUG, buff, 0);
+ sprintf(buff, "WindowWasOpen%d", i.val().item_id); // restore windows that were open on shutdown
+ if(DBGetContactSettingByte(0, PLUG, buff, 0)) {
+ DBWriteContactSettingByte(0, PLUG, buff, 0);
+ ShowGraph((WPARAM)i.val().item_id, (LPARAM)i.val().pszLabel);
+ }
+ }
+}
diff --git a/ping/pinggraph.h b/ping/pinggraph.h new file mode 100644 index 0000000..4777d82 --- /dev/null +++ b/ping/pinggraph.h @@ -0,0 +1,22 @@ +#ifndef _PINGGRAPH_H
+#define _PINGGRAPH_H
+
+#include "pinglist.h"
+#include "pingthread.h"
+
+#define MIN_GRAPH_HEIGHT 10 // 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();
+
+extern HistoryMap history_map;
+
+#endif
diff --git a/ping/pinglist.cpp b/ping/pinglist.cpp new file mode 100644 index 0000000..fcb0611 --- /dev/null +++ b/ping/pinglist.cpp @@ -0,0 +1,230 @@ +#include "common.h"
+#include "pinglist.h"
+
+#include "options.h"
+
+PINGLIST list_items;
+CRITICAL_SECTION list_cs;
+HANDLE reload_event_handle;
+
+DWORD NextID = 1;
+
+BOOL clist_handle_changing = FALSE;
+
+BOOL changing_clist_handle() {
+ return clist_handle_changing;
+}
+
+void set_changing_clist_handle(BOOL flag) {
+ clist_handle_changing = flag;
+}
+
+const bool PINGADDRESS::operator==(const PINGADDRESS &b) const {
+ return index == b.index;
+}
+
+const bool PINGADDRESS::operator<(const PINGADDRESS &b) const {
+ return index < b.index;
+}
+
+// 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;
+}
+
+int GetListSize(WPARAM wParam, LPARAM lParam) {
+ int ret = 0;
+ EnterCriticalSection(&list_cs);
+ ret = list_items.size();
+ LeaveCriticalSection(&list_cs);
+ return ret;
+}
+
+void write_ping_address(PINGADDRESS *i) {
+ char buff[16];
+ sprintf(buff, "PING_DEST_%d", i->index);
+
+ if(i->item_id == 0) {
+ i->item_id = NextID++;
+ DBWriteContactSettingDword(0, PLUG, "NextID", NextID);
+ }
+
+ DBWriteContactSettingDword(0, buff, "Id", i->item_id);
+ DBWriteContactSettingString(0, buff, "Address", i->pszName);
+ DBWriteContactSettingString(0, buff, "Label", i->pszLabel);
+ DBWriteContactSettingWord(0, buff, "Status", i->status);
+ DBWriteContactSettingDword(0, buff, "Port", i->port);
+ DBWriteContactSettingString(0, buff, "Proto", i->pszProto);
+ if(strlen(i->pszCommand))
+ DBWriteContactSettingString(0, buff, "Command", i->pszCommand);
+ else
+ DBDeleteContactSetting(0, buff, "Command");
+ if(strlen(i->pszParams))
+ DBWriteContactSettingString(0, buff, "CommandParams", i->pszParams);
+ else
+ DBDeleteContactSetting(0, buff, "CommandParams");
+ DBWriteContactSettingWord(0, buff, "SetStatus", i->set_status);
+ DBWriteContactSettingWord(0, buff, "GetStatus", i->get_status);
+ DBWriteContactSettingWord(0, buff, "Index", i->index);
+}
+
+// call with list_cs locked
+void write_ping_addresses() {
+ int index = 0;
+ for(PINGLIST::Iterator i = list_items.start(); i.has_val(); i.next(), index++) {
+ i.val().index = index;
+ write_ping_address(&i.val());
+ }
+
+ // mark further destinations in the DB as invalid
+ char buff[16];
+ bool found;
+
+ do {
+ found = false;
+ sprintf(buff, "PING_DEST_%d", index++);
+ if(DBGetContactSettingDword(0, buff, "Id", 0) != 0) {
+ found = true;
+ DBWriteContactSettingDword(0, buff, "Id", 0);
+ }
+ } while(found);
+}
+
+bool read_ping_address(PINGADDRESS &pa) {
+ int index = pa.index;
+
+ char buff[16];
+ sprintf(buff, "PING_DEST_%d", index);
+
+ // return if not more contacts, or only deleted contacts remaining
+ if((pa.item_id = DBGetContactSettingDword(0, buff, "Id", 0)) == 0) return false;
+
+ DBVARIANT dbv;
+ if(!DBGetContactSetting(0, buff, "Address", &dbv)) {
+ strncpy(pa.pszName, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ } else return false;
+
+ if(!DBGetContactSetting(0, buff, "Label", &dbv)) {
+ strncpy(pa.pszLabel, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ } else return false;
+
+ pa.status = DBGetContactSettingWord(0, buff, "Status", PS_NOTRESPONDING);
+ if(pa.status != PS_DISABLED) pa.status = PS_NOTRESPONDING;
+
+ pa.port = (int)DBGetContactSettingDword(0, buff, "Port", -1);
+
+ if(!DBGetContactSetting(0, buff, "Proto", &dbv)) {
+ strncpy(pa.pszProto, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ } else pa.pszProto[0] = '\0';
+
+ if(!DBGetContactSetting(0, buff, "Command", &dbv)) {
+ strncpy(pa.pszCommand, dbv.pszVal, MAX_PATH);
+ DBFreeVariant(&dbv);
+ } else
+ pa.pszCommand[0] = '\0';
+ if(!DBGetContactSetting(0, buff, "CommandParams", &dbv)) {
+ strncpy(pa.pszParams, dbv.pszVal, MAX_PATH);
+ DBFreeVariant(&dbv);
+ } else
+ pa.pszParams[0] = '\0';
+
+ pa.set_status = DBGetContactSettingWord(0, buff, "SetStatus", ID_STATUS_ONLINE);
+ pa.get_status = DBGetContactSettingWord(0, buff, "GetStatus", ID_STATUS_OFFLINE);
+
+ pa.responding = false;
+ pa.round_trip_time = 0;
+ pa.miss_count = 0;
+ pa.index = DBGetContactSettingWord(0, buff, "Index", 0);
+
+ pa.index = index;
+ if(pa.item_id >= NextID) {
+ NextID = pa.item_id + 1;
+ DBWriteContactSettingDword(0, PLUG, "NextID", NextID);
+ }
+
+ return true;
+}
+
+// call with list_cs locked
+void read_ping_addresses() {
+ PINGADDRESS pa;
+
+ pa.index = 0;
+
+
+ list_items.clear();
+ while(read_ping_address(pa)) {
+ list_items.add(pa);
+ pa.index++;
+ }
+}
+
+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);
+
+ // set new list
+ list_items = *pli;
+ 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/pinglist.h b/ping/pinglist.h new file mode 100644 index 0000000..db946a7 --- /dev/null +++ b/ping/pinglist.h @@ -0,0 +1,26 @@ +#ifndef _PINGLIST_H
+#define _PINGLIST_H
+
+typedef BinaryTree<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);
+int GetListSize(WPARAM wParam, LPARAM lParam);
+
+// only call with list_cs locked!
+void write_ping_addresses();
+
+
+BOOL changing_clist_handle();
+void set_changing_clist_handle(BOOL flag);
+#endif
diff --git a/ping/pingthread.cpp b/ping/pingthread.cpp new file mode 100644 index 0000000..afbaea2 --- /dev/null +++ b/ping/pingthread.cpp @@ -0,0 +1,1052 @@ +#include "common.h"
+#include "pingthread.h"
+
+int upCount, total = 0;
+
+int list_size = 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;
+
+HWND hpwnd = 0, list_hwnd, hwnd_clist = 0;
+int frame_id = -1;
+
+HBRUSH tbrush = 0;
+
+FontID font_id;
+HFONT hFont = 0;
+
+////////////////
+#define WinVerMajor() LOBYTE(LOWORD(GetVersion()))
+#define WinVerMinor() HIBYTE(LOWORD(GetVersion()))
+#define IsWinVer2000Plus() (WinVerMajor()>=5)
+
+static HMODULE hUserDll;
+BOOL (WINAPI *MySetLayeredWindowAttributes)(HWND,COLORREF,BYTE,DWORD);
+BOOL (WINAPI *MyAnimateWindow)(HWND hWnd,DWORD dwTime,DWORD dwFlags);
+#define TM_AUTOALPHA 1
+static int transparentFocus=1;
+/////////////////
+
+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 {
+ char get_status[512], set_status[512];
+ mir_snprintf(get_status, 512, "%s%s", pszProto, PS_GETSTATUS);
+ if(ServiceExists(get_status)) {
+ mir_snprintf(set_status, 512, "%s%s", pszProto, PS_SETSTATUS);
+ if(CallService(get_status, 0, 0) == if_status) {
+ if(options.logging) {
+ char buf[1024];
+ mir_snprintf(buf, 1024, Translate("%s - setting status of protocol '%s' (%d)"), pszLabel, pszProto, new_status);
+ CallService(PLUG "/Log", (WPARAM)buf, 0);
+ }
+ CallService(set_status, new_status, 0);
+ }
+ }
+ }
+}
+
+DWORD WINAPI sttCheckStatusThreadProc( void *vp)
+{
+ clock_t start_t = clock(), end_t;
+ while(!get_thread_finished()) {
+
+ end_t = clock();
+
+ int wait = (int)((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;
+ HistPair history_entry;
+
+ Lock(&data_list_cs, "ping thread loop start");
+ set_list_changed(false);
+ int size = data_list.size();
+ Unlock(&data_list_cs);
+
+ int index = 0;
+ for(; index < size; index++) {
+ Lock(&data_list_cs, "ping thread loop start");
+ int c = 0;
+ for(PINGLIST::Iterator i = data_list.start(); i.has_val() && c <= index; i.next(), c++) {
+ if(c == index) {
+ // copy just what we need - i.e. not history, not command
+ pa.get_status = i.val().get_status;
+ pa.item_id = i.val().item_id;
+ pa.miss_count = i.val().miss_count;
+ pa.port = i.val().port;
+ strcpy(pa.pszLabel, i.val().pszLabel);
+ strcpy(pa.pszName, i.val().pszName);
+ strcpy(pa.pszProto, i.val().pszProto);
+ pa.set_status = i.val().set_status;
+ pa.status = i.val().status;
+ break;
+ }
+
+ }
+ Unlock(&data_list_cs);
+
+ if(get_thread_finished()) break;
+ if(get_list_changed()) break;
+
+ if(pa.status != PS_DISABLED) {
+ if(!options.no_test_icon) {
+ Lock(&data_list_cs, "ping thread loop start");
+ for(PINGLIST::Iterator i = data_list.start(); i.has_val(); i.next()) {
+ if(i.val().item_id == pa.item_id) {
+ i.val().status = PS_TESTING;
+ }
+ }
+ Unlock(&data_list_cs);
+ InvalidateRect(list_hwnd, 0, FALSE);
+ }
+
+ CallService(PLUG "/Ping", 0, (LPARAM)&pa);
+
+ if(get_thread_finished()) break;
+ if(get_list_changed()) break;
+
+ Lock(&data_list_cs, "ping thread loop start");
+ for(PINGLIST::Iterator i = data_list.start(); i.has_val(); i.next()) {
+ if(i.val().item_id == pa.item_id) {
+ i.val().responding = pa.responding;
+ i.val().round_trip_time = pa.round_trip_time;
+ history_entry.first = i.val().round_trip_time;
+ history_entry.second = time(0);
+ history_map[i.val().item_id].push_back(history_entry);
+ // maintain history (-1 represents no response)
+ while(history_map[i.val().item_id].size() >= MAX_HISTORY)
+ //history_map[i.val().item_id].pop_front();
+ history_map[i.val().item_id].remove(history_map[i.val().item_id].start().val());
+
+ if(pa.responding) {
+ if(pa.miss_count > 0)
+ pa.miss_count = -1;
+ else
+ pa.miss_count--;
+ pa.status = PS_RESPONDING;
+ }
+ else {
+ if(pa.miss_count < 0)
+ pa.miss_count = 1;
+ else
+ pa.miss_count++;
+ pa.status = PS_NOTRESPONDING;
+ }
+ i.val().miss_count = pa.miss_count;
+ i.val().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(pa.miss_count == -1 - options.retries && options.logging) {
+ char buf[512];
+ mir_snprintf(buf, 512, Translate("%s - reply, %d"), pa.pszLabel, pa.round_trip_time);
+ CallService(PLUG "/Log", (WPARAM)buf, 0);
+ }
+ SetProtoStatus(pa.pszLabel, pa.pszProto, pa.get_status, pa.set_status);
+ } 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(pa.miss_count == 1 + options.retries && options.logging) {
+ char buf[512];
+ mir_snprintf(buf, 512, Translate("%s - timeout"), pa.pszLabel);
+ CallService(PLUG "/Log", (WPARAM)buf, 0);
+ }
+ }
+
+ InvalidateRect(list_hwnd, 0, FALSE);
+ }
+ }
+
+ if(timeout) SkinPlaySound("PingTimeout");
+ if(reply) SkinPlaySound("PingReply");
+
+ if(!get_list_changed()) {
+ upCount = count;
+ total = index;
+ } 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;
+}
+
+bool FrameIsFloating() {
+ if(frame_id == -1)
+ return true; // no frames, always floating
+
+ return (CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS, MAKEWPARAM(FO_FLOATING, frame_id), 0) != 0);
+}
+
+int FillList(WPARAM wParam, LPARAM lParam) {
+
+ if(options.logging)
+ CallService(PLUG "/Log", (WPARAM)"ping address list reload", 0);
+
+ PINGLIST pl;
+ CallService(PLUG "/GetPingList", 0, (LPARAM)&pl);
+
+ SendMessage(list_hwnd, WM_SETREDRAW, (WPARAM)FALSE, 0);
+ Lock(&data_list_cs, "fill_list");
+
+ data_list = pl;
+ SendMessage(list_hwnd, LB_RESETCONTENT, 0, 0);
+
+ int index = 0;
+ for(PINGLIST::Iterator j = data_list.start(); j.has_val(); j.next(), index++) {
+ SendMessage(list_hwnd, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)&j.val());
+ }
+ set_list_changed(true);
+
+ list_size = data_list.size();
+
+ Unlock(&data_list_cs);
+ SendMessage(list_hwnd, WM_SETREDRAW, (WPARAM)TRUE, 0);
+
+ InvalidateRect(list_hwnd, 0, FALSE);
+
+ SetEvent(hWakeEvent);
+
+ if(!ServiceExists(MS_CLIST_FRAMES_ADDFRAME) && options.attach_to_clist)
+ UpdateFrame();
+
+ return 0;
+}
+
+int PingPlugShowWindow(WPARAM wParam, LPARAM lParam) {
+ if(hpwnd) {
+ if(frame_id != -1 && ServiceExists(MS_CLIST_FRAMES_SHFRAME)) CallService(MS_CLIST_FRAMES_SHFRAME, (WPARAM)frame_id, 0);
+ else {
+ ShowWindow(hpwnd, IsWindowVisible(hpwnd) ? SW_HIDE : SW_SHOW);
+ }
+ }
+ return 0;
+}
+
+#define TIMER_ID 11042
+void CALLBACK TimerProc(
+ HWND hwnd, // handle to window
+ UINT uMsg, // WM_TIMER message
+ UINT idEvent, // timer identifier
+ DWORD dwTime // current system time
+)
+{
+ if(frame_id != -1 && ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) {
+ char TBcapt[255];
+ if(total > 0)
+ wsprintf(TBcapt,"Ping (%d/%d)", upCount, total);
+ else
+ wsprintf(TBcapt,"Ping");
+
+ CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,MAKEWPARAM(FO_TBNAME,frame_id),(LPARAM)TBcapt);
+ CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,MAKEWPARAM(FO_TBTIPNAME,frame_id),(LPARAM)TBcapt);
+ CallService(MS_CLIST_FRAMES_UPDATEFRAME,frame_id,FU_TBREDRAW);
+ } else {
+// if(options.attach_to_clist) {
+// AttachToClist(true);
+// }
+ }
+}
+
+DWORD context_point;
+bool context_point_valid = false;
+LRESULT CALLBACK FrameWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ RECT rect;
+ MEASUREITEMSTRUCT *mis;
+ LPDRAWITEMSTRUCT dis;
+ SIZE textSize;
+ PINGADDRESS itemData;
+ RECT r;
+ LPARAM lp;
+ int sel;
+
+ switch(msg)
+ {
+
+ case WM_MEASUREITEM:
+ mis = (MEASUREITEMSTRUCT *)lParam;
+ mis->itemWidth = 100;
+ mis->itemHeight = options.row_height;
+ return TRUE;
+
+ case WM_DRAWITEM:
+ dis = (LPDRAWITEMSTRUCT)lParam;
+ if(dis->hwndItem == list_hwnd) {
+ HBRUSH ttbrush = 0;
+ COLORREF tcol;
+ if(dis->itemID != -1) {
+ Lock(&data_list_cs, "draw item");
+ itemData = *(PINGADDRESS *)dis->itemData;
+ Unlock(&data_list_cs);
+
+ SendMessage(list_hwnd, LB_SETITEMHEIGHT, 0, (LPARAM)options.row_height);
+ //dis->rcItem.bottom = dis->rcItem.top + options.row_height;
+
+ LONG x, y;
+ if(context_point_valid) {
+ RECT r;
+ GetWindowRect(list_hwnd, &r);
+ x = LOWORD(context_point) - r.left,
+ y = HIWORD(context_point) - r.top;
+ }
+
+ GetClientRect(hwnd, &r);
+
+ if((dis->itemState & ODS_SELECTED && dis->itemState & ODS_FOCUS)
+ || (context_point_valid && (x >= dis->rcItem.left && x <= dis->rcItem.right) && (y >= dis->rcItem.top && y <= dis->rcItem.bottom)))
+ {
+ tcol = DBGetContactSettingDword(NULL,"CLC","SelBkColour", GetSysColor(COLOR_HIGHLIGHT));
+ SetBkColor(dis->hDC, tcol);
+ FillRect(dis->hDC, &dis->rcItem, (ttbrush = CreateSolidBrush(tcol)));
+
+ tcol = DBGetContactSettingDword(NULL,"CLC","SelTextColour", GetSysColor(COLOR_HIGHLIGHTTEXT));
+ SetTextColor(dis->hDC, tcol);
+ } else {
+ tcol = options.bg_colour;
+ SetBkColor(dis->hDC, tcol);
+ FillRect(dis->hDC, &dis->rcItem, (ttbrush = CreateSolidBrush(tcol)));
+
+ tcol = DBGetContactSettingDword(NULL, PLUG, "FontCol", GetSysColor(COLOR_WINDOWTEXT));
+ SetTextColor(dis->hDC, tcol);
+ }
+
+ SetBkMode(dis->hDC, TRANSPARENT);
+ HICON hIcon = (itemData.status != PS_DISABLED ? (itemData.status == PS_TESTING ? hIconTesting : (itemData.status == PS_RESPONDING ? hIconResponding : hIconNotResponding)) : hIconDisabled);
+ dis->rcItem.left += options.indent;
+ //DrawIconEx(dis->hDC,dis->rcItem.left,(dis->rcItem.top + dis->rcItem.bottom - GetSystemMetrics(SM_CYSMICON))>>1,hIcon,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL);
+ //DrawIconEx(dis->hDC,dis->rcItem.left,(dis->rcItem.top + dis->rcItem.bottom - GetSystemMetrics(SM_CYSMICON))>>1,hIcon,0, 0, 0, NULL, DI_NORMAL);
+ DrawIconEx(dis->hDC,dis->rcItem.left,dis->rcItem.top + ((options.row_height - 16)>>1),hIcon,0, 0, 0, NULL, DI_NORMAL);
+
+ GetTextExtentPoint32(dis->hDC,itemData.pszLabel,lstrlen(itemData.pszLabel),&textSize);
+ TextOut(dis->hDC,dis->rcItem.left + 16 + 4,(dis->rcItem.top + dis->rcItem.bottom - textSize.cy)>>1,itemData.pszLabel,lstrlen(itemData.pszLabel));
+
+ if(itemData.status != PS_DISABLED) {
+ char buf[256];
+ if(itemData.responding) {
+ mir_snprintf(buf, 256, Translate("%d ms"), itemData.round_trip_time);
+ GetTextExtentPoint32(dis->hDC,buf,lstrlen(buf),&textSize);
+ TextOut(dis->hDC,dis->rcItem.right - textSize.cx - 2,(dis->rcItem.top + dis->rcItem.bottom -textSize.cy)>>1,buf,lstrlen(buf));
+ } else if(itemData.miss_count > 0) {
+ mir_snprintf(buf, 256, "[%d]", itemData.miss_count);
+ GetTextExtentPoint32(dis->hDC,buf,lstrlen(buf),&textSize);
+ TextOut(dis->hDC,dis->rcItem.right - textSize.cx - 2,(dis->rcItem.top + dis->rcItem.bottom -textSize.cy)>>1,buf,lstrlen(buf));
+ }
+ }
+ SetBkMode(dis->hDC, OPAQUE);
+ }
+ if(ttbrush) DeleteObject(ttbrush);
+ return TRUE;
+ }
+ //return DefWindowProc(hwnd, msg, wParam, lParam);
+ return TRUE;
+
+ case WM_CTLCOLORLISTBOX:
+ {
+ if(tbrush) DeleteObject(tbrush);
+
+ return (BOOL)(tbrush = CreateSolidBrush(options.bg_colour));
+ }
+
+ case WM_ERASEBKGND:
+ {
+ RECT r;
+ GetClientRect(hwnd, &r);
+ if(!tbrush) tbrush = CreateSolidBrush(options.bg_colour);
+ FillRect((HDC)wParam, &r, tbrush);
+ }
+ return TRUE;
+
+ case WM_CONTEXTMENU:
+ {
+ context_point = lParam;
+ context_point_valid = true;
+ InvalidateRect(list_hwnd, 0, FALSE);
+ HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1)),
+ submenu = GetSubMenu(menu, 0);
+
+ POINT pt = {LOWORD(context_point),HIWORD(context_point)};
+
+ RECT r;
+ GetClientRect(list_hwnd, &r);
+ ScreenToClient(list_hwnd, &pt);
+
+ DWORD item = SendMessage(list_hwnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(pt.x, pt.y));
+ bool found = false;
+ if(HIWORD(item) == 0) {
+ int count = LOWORD(item);
+ Lock(&data_list_cs, "show graph");
+ if(count >= 0 && count < (int)data_list.size()) {
+ itemData = *(PINGADDRESS *)SendMessage(list_hwnd, LB_GETITEMDATA, count, 0);
+ found = true;
+ }
+ Unlock(&data_list_cs);
+
+ }
+
+ if(found) {
+ EnableMenuItem(submenu, ID_MENU_GRAPH, MF_BYCOMMAND | MF_ENABLED);
+ EnableMenuItem(submenu, ID_MENU_EDIT, MF_BYCOMMAND | MF_ENABLED);
+ EnableMenuItem(submenu, ID_MENU_TOGGLE, MF_BYCOMMAND | MF_ENABLED);
+ if(itemData.status == PS_DISABLED) {
+ ModifyMenu(submenu, ID_MENU_TOGGLE, MF_BYCOMMAND | MF_STRING, ID_MENU_TOGGLE, Translate("Enable"));
+ } else {
+ ModifyMenu(submenu, ID_MENU_TOGGLE, MF_BYCOMMAND | MF_STRING, ID_MENU_TOGGLE, Translate("Disable"));
+ }
+ } else {
+ EnableMenuItem(submenu, ID_MENU_GRAPH, MF_BYCOMMAND | MF_GRAYED);
+ EnableMenuItem(submenu, ID_MENU_EDIT, MF_BYCOMMAND | MF_GRAYED);
+ EnableMenuItem(submenu, ID_MENU_TOGGLE, MF_BYCOMMAND | MF_GRAYED);
+ }
+
+ CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)submenu,0);
+
+ //ClientToScreen(list_hwnd, &pt);
+ GetCursorPos(&pt);
+ BOOL ret = TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL);
+ DestroyMenu(menu);
+ if(ret) {
+ SendMessage(hwnd, WM_COMMAND, ret, 0);
+ }
+ context_point_valid = false;
+ InvalidateRect(list_hwnd, 0, FALSE);
+ }
+
+ return TRUE;
+
+ case WM_SYSCOLORCHANGE:
+ SendMessage(list_hwnd,msg,wParam,lParam);
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+
+ case WM_CREATE:
+ list_hwnd = CreateWindow("LISTBOX", "",
+ //(WS_VISIBLE | WS_CHILD | LBS_NOINTEGRALHEIGHT| LBS_STANDARD | WS_CLIPCHILDREN | LBS_OWNERDRAWVARIABLE | LBS_NOTIFY)
+ (WS_VISIBLE | WS_CHILD | LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_NOTIFY)
+ & ~WS_BORDER, 0, 0, 0, 0, hwnd, NULL, hInst,0);
+
+ if (DBGetContactSettingByte(NULL,"CList","Transparent",0))
+ {
+ if(ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) {
+
+ } else {
+#ifdef WS_EX_LAYERED
+ SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
+#endif
+#ifdef LWA_ALPHA
+ if (MySetLayeredWindowAttributes) MySetLayeredWindowAttributes(hwnd, RGB(0,0,0), (BYTE)DBGetContactSettingByte(NULL,"CList","Alpha",SETTING_ALPHA_DEFAULT), LWA_ALPHA);
+#endif
+ }
+ }
+
+ // timer to update titlebar
+ if(ServiceExists(MS_CLIST_FRAMES_ADDFRAME))
+ SetTimer(hwnd, TIMER_ID, 1000, TimerProc);
+
+ PostMessage(hwnd, WM_SIZE, 0, 0);
+ return TRUE;;
+
+ case WM_ACTIVATE:
+ if(wParam==WA_INACTIVE) {
+ if((HWND)wParam!=hwnd)
+ if(DBGetContactSettingByte(NULL,"CList","Transparent",SETTING_TRANSPARENT_DEFAULT))
+ if(transparentFocus)
+ SetTimer(hwnd, TM_AUTOALPHA,250,NULL);
+ }
+ else {
+ if(DBGetContactSettingByte(NULL,"CList","Transparent",SETTING_TRANSPARENT_DEFAULT)) {
+ KillTimer(hwnd,TM_AUTOALPHA);
+#ifdef LWA_ALPHA
+ if (MySetLayeredWindowAttributes) MySetLayeredWindowAttributes(hwnd, RGB(0,0,0), (BYTE)DBGetContactSettingByte(NULL,"CList","Alpha",SETTING_ALPHA_DEFAULT), LWA_ALPHA);
+#endif
+ transparentFocus=1;
+ }
+ }
+ return DefWindowProc(hwnd,msg,wParam,lParam);
+
+ case WM_SETCURSOR:
+ if(DBGetContactSettingByte(NULL,"CList","Transparent",SETTING_TRANSPARENT_DEFAULT)) {
+ if (!transparentFocus && GetForegroundWindow()!=hwnd && MySetLayeredWindowAttributes) {
+#ifdef LWA_ALPHA
+ MySetLayeredWindowAttributes(hwnd, RGB(0,0,0), (BYTE)DBGetContactSettingByte(NULL,"CList","Alpha",SETTING_ALPHA_DEFAULT), LWA_ALPHA);
+#endif
+ transparentFocus=1;
+ SetTimer(hwnd, TM_AUTOALPHA,250,NULL);
+ }
+ }
+ return DefWindowProc(hwnd,msg,wParam,lParam);
+
+ case WM_TIMER:
+ if ((int)wParam==TM_AUTOALPHA)
+ { int inwnd;
+
+ if (GetForegroundWindow()==hwnd) {
+ KillTimer(hwnd,TM_AUTOALPHA);
+ inwnd=1;
+ }
+ else {
+ POINT pt;
+ HWND hwndPt;
+ pt.x=(short)LOWORD(GetMessagePos());
+ pt.y=(short)HIWORD(GetMessagePos());
+ hwndPt=WindowFromPoint(pt);
+ inwnd=(hwndPt==hwnd || GetParent(hwndPt)==hwnd);
+ }
+ if (inwnd!=transparentFocus && MySetLayeredWindowAttributes)
+ { //change
+ transparentFocus=inwnd;
+#ifdef LWA_ALPHA
+ if(transparentFocus) MySetLayeredWindowAttributes(hwnd, RGB(0,0,0), (BYTE)DBGetContactSettingByte(NULL,"CList","Alpha",SETTING_ALPHA_DEFAULT), LWA_ALPHA);
+ else MySetLayeredWindowAttributes(hwnd, RGB(0,0,0), (BYTE)DBGetContactSettingByte(NULL,"CList","AutoAlpha",SETTING_AUTOALPHA_DEFAULT), LWA_ALPHA);
+#endif
+ }
+ if(!transparentFocus) KillTimer(hwnd,TM_AUTOALPHA);
+ return TRUE;
+ }
+ return FALSE;
+
+ case WM_SHOWWINDOW:
+ { static int noRecurse=0;
+ if(lParam) break;
+ if(noRecurse) break;
+ if(!DBGetContactSettingByte(NULL,"CLUI","FadeInOut",0) || !IsWinVer2000Plus()) break;
+#ifdef WS_EX_LAYERED
+ if(GetWindowLong(hwnd,GWL_EXSTYLE)&WS_EX_LAYERED) {
+ DWORD thisTick,startTick;
+ int sourceAlpha,destAlpha;
+ if(wParam) {
+ sourceAlpha=0;
+ destAlpha=(BYTE)DBGetContactSettingByte(NULL,"CList","Alpha",SETTING_AUTOALPHA_DEFAULT);
+#ifdef LWA_ALPHA
+ MySetLayeredWindowAttributes(hwnd, RGB(0,0,0), 0, LWA_ALPHA);
+#endif
+ noRecurse=1;
+ ShowWindow(hwnd,SW_SHOW);
+ noRecurse=0;
+ }
+ else {
+ sourceAlpha=(BYTE)DBGetContactSettingByte(NULL,"CList","Alpha",SETTING_AUTOALPHA_DEFAULT);
+ destAlpha=0;
+ }
+ for(startTick=GetTickCount();;) {
+ thisTick=GetTickCount();
+ if(thisTick>=startTick+200) break;
+#ifdef LWA_ALPHA
+ MySetLayeredWindowAttributes(hwnd, RGB(0,0,0), (BYTE)(sourceAlpha+(destAlpha-sourceAlpha)*(int)(thisTick-startTick)/200), LWA_ALPHA);
+#endif
+ }
+#ifdef LWA_ALPHA
+ MySetLayeredWindowAttributes(hwnd, RGB(0,0,0), (BYTE)destAlpha, LWA_ALPHA);
+#endif
+ }
+ else {
+// if(wParam) SetForegroundWindow(hwnd);
+ MyAnimateWindow(hwnd,200,AW_BLEND|(wParam?0:AW_HIDE));
+ //SetWindowPos(label,0,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED);
+ }
+#endif
+ //int res = DefWindowProc(hwnd, msg, wParam, lParam);
+ //return res;
+ //break;
+ //return FALSE; //break;
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ }
+
+ /*
+ case WM_PAINT:
+ {
+ paintDC = BeginPaint(hwnd, &paintStruct); //
+ //SelectObject(paintDC,TitleBarFont);
+ //SetBkMode(paintDC,TRANSPARENT);
+
+ //paintStruct.fErase=TRUE;
+ //color=RGB(1,1,1);
+ //brush=CreateSolidBrush(RGB(200,20,20));
+
+ //GetClientRect(hwnd,&rect);
+ //FillRect(paintDC,&rect,brush);
+ //TextOut(paintDC,4,4,"cl1 Bottom window",sizeof("cl1 Bottom window")-1);
+ //DeleteObject(brush);
+ EndPaint(hwnd, &paintStruct); //
+
+
+ };
+ return TRUE;
+
+ */
+ case WM_COMMAND:
+ //CreateServiceFunction("PingPlug/DisableAll", PingPlugDisableAll);
+ //CreateServiceFunction("PingPlug/EnableAll", PingPlugEnableAll);
+ switch(LOWORD(wParam)) {
+ case ID_MENU_GRAPH:
+ if(context_point_valid) {
+ WORD x = LOWORD(context_point),
+ y = HIWORD(context_point);
+ RECT r;
+ GetWindowRect(list_hwnd, &r);
+ DWORD item = SendMessage(list_hwnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(x - r.left, y - r.top));
+ if(HIWORD(item) == 0) {
+ int count = LOWORD(item);
+ bool found = false;
+ Lock(&data_list_cs, "menu show graph");
+ if(count >= 0 && count < (int)data_list.size()) {
+ itemData = *(PINGADDRESS *)SendMessage(list_hwnd, LB_GETITEMDATA, count, 0);
+ found = true;
+ }
+ Unlock(&data_list_cs);
+ if(found)
+ CallService(PLUG "/ShowGraph", (WPARAM)itemData.item_id, (LPARAM)itemData.pszLabel);
+ }
+ }
+ return TRUE;
+ case ID_MENU_TOGGLE:
+ if(context_point_valid) {
+ WORD x = LOWORD(context_point),
+ y = HIWORD(context_point);
+ RECT r;
+ GetWindowRect(list_hwnd, &r);
+ DWORD item = SendMessage(list_hwnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(x - r.left, y - r.top));
+ if(HIWORD(item) == 0) {
+ int count = LOWORD(item);
+ bool found = false;
+ Lock(&data_list_cs, "menu toggle");
+ if(count >= 0 && count < (int)data_list.size()) {
+ itemData = *(PINGADDRESS *)SendMessage(list_hwnd, LB_GETITEMDATA, count, 0);
+ found = true;
+ }
+ Unlock(&data_list_cs);
+ if(found)
+ CallService(PLUG "/ToggleEnabled", (WPARAM)itemData.item_id, 0);
+ }
+ }
+ return TRUE;
+ case ID_MENU_EDIT:
+ if(context_point_valid) {
+ WORD x = LOWORD(context_point),
+ y = HIWORD(context_point);
+ RECT r;
+ GetWindowRect(list_hwnd, &r);
+ DWORD item = SendMessage(list_hwnd, LB_ITEMFROMPOINT, 0, MAKELPARAM(x - r.left, y - r.top));
+ PINGADDRESS *temp = 0;
+ if(HIWORD(item) == 0) {
+ int count = LOWORD(item);
+ Lock(&data_list_cs, "menu edit");
+ if(count >= 0 && count < (int)data_list.size()) {
+ temp = (PINGADDRESS *)SendMessage(list_hwnd, LB_GETITEMDATA, count, 0);
+ }
+ Unlock(&data_list_cs);
+ if(temp) {
+ itemData = *temp;
+ if(Edit(hwnd, itemData)) {
+ Lock(&data_list_cs, "menu edited");
+ *temp = itemData;
+ CallService(PLUG "/SetAndSavePingList", (WPARAM)&data_list, 0);
+ Unlock(&data_list_cs);
+ }
+ }
+ }
+ }
+ return TRUE;
+ case ID_MENU_DISABLEALLPINGS:
+ CallService(PLUG "/DisableAll", 0, 0);
+ return TRUE;
+ case ID_MENU_ENABLEALLPINGS:
+ CallService(PLUG "/EnableAll", 0, 0);
+ return TRUE;
+ case ID_MENU_OPTIONS:
+ {
+ OPENOPTIONSDIALOG oop;
+ oop.cbSize = sizeof(oop);
+ oop.pszGroup = Translate("Network");
+ oop.pszPage = Translate("PING");
+ CallService(MS_OPT_OPENOPTIONS, 0, (WPARAM)&oop);
+ }
+ return TRUE;
+ case ID_MENU_DESTINATIONS:
+ {
+ OPENOPTIONSDIALOG oop;
+ oop.cbSize = sizeof(oop);
+ oop.pszGroup = Translate("Network");
+ oop.pszPage = Translate("PING Hosts");
+ CallService(MS_OPT_OPENOPTIONS, 0, (WPARAM)&oop);
+ }
+ return TRUE;
+ }
+ if (HIWORD( wParam ) == LBN_DBLCLK) {
+ sel = SendMessage(list_hwnd, LB_GETCURSEL, 0, 0);
+ if(sel != LB_ERR) {
+ lp = SendMessage(list_hwnd, LB_GETITEMDATA, sel, 0);
+ if(lp != LB_ERR) {
+ PINGADDRESS *pItemData = (PINGADDRESS *)lp;
+
+ Lock(&data_list_cs, "command");
+
+ if(pItemData) {
+ DWORD item_id = pItemData->item_id;
+ Unlock(&data_list_cs);
+
+ int wake = CallService(PLUG "/DblClick", (WPARAM)item_id, 0);
+ InvalidateRect(list_hwnd, 0, FALSE);
+ if(wake) SetEvent(hWakeEvent);
+
+ if(options.logging) {
+ char buf[1024];
+ mir_snprintf(buf, 1024, "%s - %s", pItemData->pszLabel, (wake ? Translate("enabled") : Translate("double clicked")));
+ CallService(PLUG "/Log", (WPARAM)buf, 0);
+ }
+
+ } else {
+ Unlock(&data_list_cs);
+ }
+ }
+ }
+ return TRUE;
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+
+ case WM_MOVE: // needed for docked frames in clist_mw (not needed in clist_modern)
+ if(FrameIsFloating())
+ break;
+ case WM_SIZE:
+ {
+ //PostMessage(label, WM_SIZE, wParam, lParam);
+
+ GetClientRect(hwnd,&rect);
+ //SetWindowPos(list_hwnd, 0, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, SWP_NOZORDER);
+ //InvalidateRect(list_hwnd, &rect, FALSE);
+ int winheight = rect.bottom - rect.top,
+ itemheight = SendMessage(list_hwnd, LB_GETITEMHEIGHT, 0, 0),
+ count = SendMessage(list_hwnd, LB_GETCOUNT, 0, 0),
+#ifdef min
+ height = min(winheight - winheight % itemheight, itemheight * count);
+#else
+ height = std::min(winheight - winheight % itemheight, itemheight * count);
+#endif
+ SetWindowPos(list_hwnd, 0, rect.left, rect.top, rect.right-rect.left, height, SWP_NOZORDER);
+ InvalidateRect(list_hwnd, 0, FALSE);
+ }
+ InvalidateRect(hwnd, 0, TRUE);
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+
+ case WM_DESTROY:
+ if(!ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) {
+ Utils_SaveWindowPosition(hwnd, 0, PLUG, "main_window");
+ }
+
+ KillTimer(hwnd, TIMER_ID);
+ if(tbrush) DeleteObject(tbrush);
+
+ DestroyWindow(list_hwnd);
+
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+
+ case WM_CLOSE:
+ if(!ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) {
+ Utils_SaveWindowPosition(hwnd, 0, PLUG, "main_window");
+ ShowWindow(hwnd, SW_HIDE);
+ return 0;
+ }
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+/*
+ case WM_POWERBROADCAST:
+
+ if(options.logging) {
+ std::ostringstream oss;
+ switch(wParam) {
+ case PBT_APMSUSPEND:
+ CallService("PingPlug/Log", (WPARAM)"system suspend", 0);
+ break;
+ case PBT_APMRESUMESUSPEND:
+ oss << "system resume";
+ if(lParam == PBTF_APMRESUMEFROMFAILURE)
+ oss << " [suspend failure!]";
+ CallService("PingPlug/Log", (WPARAM)oss.str().c_str(), 0);
+ break;
+ case PBT_APMRESUMEAUTOMATIC:
+ oss << "system resume (automatic)";
+ if(lParam == PBTF_APMRESUMEFROMFAILURE)
+ oss << " [suspend failure!]";
+ CallService("PingPlug/Log", (WPARAM)oss.str().c_str(), 0);
+ break;
+ case PBT_APMRESUMECRITICAL:
+ oss << "system resume (critical)";
+ if(lParam == PBTF_APMRESUMEFROMFAILURE)
+ oss << " [suspend failure!]";
+ CallService("PingPlug/Log", (WPARAM)oss.str().c_str(), 0);
+ break;
+ }
+ }
+ break;
+*/
+ default:
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+
+ };
+
+ return(TRUE);
+};
+
+
+int ReloadFont(WPARAM wParam, LPARAM lParam) {
+ DeleteObject(hFont);
+
+ LOGFONT log_font;
+ CallService(MS_FONT_GET, (WPARAM)&font_id, (LPARAM)&log_font);
+ hFont = CreateFontIndirect(&log_font);
+ SendMessage(list_hwnd, WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
+
+ return 0;
+}
+
+int RefreshWindow(WPARAM wParam, LPARAM lParam) {
+ InvalidateRect(list_hwnd, 0, TRUE);
+ InvalidateRect(hpwnd, 0, TRUE);
+ return 0;
+}
+
+void UpdateFrame() {
+ if(IsWindowVisible(hwnd_clist) != IsWindowVisible(hpwnd))
+ ShowWindow(hpwnd, IsWindowVisible(hwnd_clist) ? SW_SHOW : SW_HIDE);
+
+ if(!IsWindowVisible(hpwnd)) return;
+
+ RECT r_clist;
+ GetWindowRect(hwnd_clist, &r_clist);
+ RECT r_frame;
+ GetWindowRect(hpwnd, &r_frame);
+ int height = list_size * options.row_height;
+ if(GetWindowLong(hpwnd, GWL_STYLE) & WS_BORDER) {
+ RECT r_frame_client;
+ GetClientRect(hpwnd, &r_frame_client);
+ height += (r_frame.bottom - r_frame.top) - (r_frame_client.bottom - r_frame_client.top);
+ }
+
+ SetWindowPos(hpwnd, 0, r_clist.left, r_clist.top - height, (r_clist.right - r_clist.left), height, SWP_NOZORDER | SWP_NOACTIVATE);
+}
+
+WNDPROC wpOrigClistProc;
+
+// Subclass procedure
+LRESULT APIENTRY ClistSubclassProc(
+ HWND hwnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ if(uMsg == WM_SIZE || uMsg == WM_MOVE)
+ UpdateFrame();
+
+ if(uMsg == WM_NCCALCSIZE) { // possible window style change
+ if(GetWindowLong(hwnd_clist, GWL_STYLE) != GetWindowLong(hpwnd, GWL_STYLE)
+ || GetWindowLong(hwnd_clist, GWL_STYLE) != GetWindowLong(hpwnd, GWL_STYLE))
+ {
+ SetWindowLong(hpwnd, GWL_STYLE, GetWindowLong(hwnd_clist, GWL_STYLE));
+ SetWindowLong(hpwnd, GWL_EXSTYLE, GetWindowLong(hwnd_clist, GWL_EXSTYLE));
+ SetWindowPos(hpwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
+ }
+ }
+
+ if(uMsg == WM_SHOWWINDOW) {
+ ShowWindow(hpwnd, wParam);
+ }
+
+ return CallWindowProc(wpOrigClistProc, hwnd, uMsg, wParam, lParam);
+}
+
+void AttachToClist(bool attach) {
+ if(!hpwnd) return;
+
+ if(attach) {
+ SetWindowLong(hpwnd, GWL_STYLE, GetWindowLong(hwnd_clist, GWL_STYLE));
+ SetWindowLong(hpwnd, GWL_EXSTYLE, GetWindowLong(hwnd_clist, GWL_EXSTYLE));
+ SetWindowPos(hpwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
+
+ // subclass clist to trap move/size
+ wpOrigClistProc = (WNDPROC) SetWindowLong(hwnd_clist, GWL_WNDPROC, (LONG) ClistSubclassProc);
+
+ UpdateFrame();
+ } else {
+ SetWindowLong(hpwnd, GWL_STYLE, (WS_POPUPWINDOW | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_VISIBLE | WS_CLIPCHILDREN));
+ SetWindowLong(hpwnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
+ SetWindowPos(hpwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
+
+ SetWindowLong(hwnd_clist, GWL_WNDPROC, (LONG) wpOrigClistProc);
+ }
+}
+
+void InitList() {
+
+ hUserDll = LoadLibrary("user32.dll");
+ if (hUserDll) {
+ MySetLayeredWindowAttributes = (BOOL (WINAPI *)(HWND,COLORREF,BYTE,DWORD))GetProcAddress(hUserDll, "SetLayeredWindowAttributes");
+ MyAnimateWindow=(BOOL (WINAPI*)(HWND,DWORD,DWORD))GetProcAddress(hUserDll,"AnimateWindow");
+ }
+
+ hwnd_clist = (HWND)CallService(MS_CLUI_GETHWND, 0, 0);
+
+ WNDCLASS wndclass;
+
+ wndclass.style = 0;
+ wndclass.lpfnWndProc = FrameWindowProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = hInst;
+ wndclass.hIcon = hIconResponding;
+ wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
+ wndclass.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = PLUG "WindowClass";
+ RegisterClass(&wndclass);
+
+ if(ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) {
+ hpwnd=CreateWindow(PLUG "WindowClass", "Ping", (WS_BORDER | WS_CHILD | WS_CLIPCHILDREN), 0, 0, 0, 0, hwnd_clist, NULL, hInst, NULL);
+
+ CLISTFrame frame = {0};
+ frame.name=PLUG;
+ frame.cbSize=sizeof(CLISTFrame);
+ frame.hWnd=hpwnd;
+ frame.align=alBottom;
+ frame.Flags=F_VISIBLE|F_SHOWTB|F_SHOWTBTIP;
+ frame.height=30;
+ frame.TBname=Translate("Ping");
+
+ frame_id=CallService(MS_CLIST_FRAMES_ADDFRAME,(WPARAM)&frame,0);
+ } else {
+ hpwnd=CreateWindowEx(WS_EX_TOOLWINDOW, PLUG "WindowClass","Ping",
+ (WS_POPUPWINDOW | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_CLIPCHILDREN),
+ 0,0,400,300,hwnd_clist,NULL,hInst,NULL);
+
+ Utils_RestoreWindowPosition(hpwnd, 0, PLUG, "main_window");
+
+ CreateServiceFunction(PLUG "/ShowWindow", PingPlugShowWindow);
+
+ CLISTMENUITEM mi = {0};
+
+ mi.flags = 0;
+ mi.popupPosition = 1000200001;
+ mi.pszPopupName = Translate( "Ping" );
+ mi.cbSize = sizeof( mi );
+ mi.position = 3000320001;
+ mi.hIcon = 0;//LoadIcon( hInst, 0);
+ mi.pszName = Translate( "Show/Hide &Ping Window" );
+ mi.pszService = PLUG "/ShowWindow";
+ CallService( MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi );
+
+ if(options.attach_to_clist) AttachToClist(true);
+ else ShowWindow(hpwnd, SW_SHOW);
+ }
+
+ if(ServiceExists(MS_FONT_REGISTER)) {
+ font_id.cbSize = sizeof(FontID);
+ strncpy(font_id.group, "Frames", sizeof(font_id.group));
+ strncpy(font_id.name, "Ping", sizeof(font_id.name));
+ strncpy(font_id.dbSettingsGroup, "PING", sizeof(font_id.dbSettingsGroup));
+ strncpy(font_id.prefix, "Font", sizeof(font_id.prefix));
+ font_id.order = 0;
+
+ CallService(MS_FONT_REGISTER, (WPARAM)&font_id, 0);
+ LOGFONT log_font;
+ CallService(MS_FONT_GET, (WPARAM)&font_id, (LPARAM)&log_font);
+ hFont = CreateFontIndirect(&log_font);
+ SendMessage(list_hwnd, WM_SETFONT, (WPARAM)hFont, (LPARAM)TRUE);
+
+ HookEvent(ME_FONT_RELOAD, ReloadFont);
+ }
+
+ start_ping_thread();
+}
+
+void DeinitList() {
+ DestroyWindow(hpwnd);
+ stop_ping_thread();
+ if(hFont) DeleteObject(hFont);
+}
\ No newline at end of file diff --git a/ping/pingthread.h b/ping/pingthread.h new file mode 100644 index 0000000..eda6dae --- /dev/null +++ b/ping/pingthread.h @@ -0,0 +1,27 @@ +#ifndef _PINGTHREAD_H
+#define _PINGTHREAD_H
+
+#include "pinglist.h"
+#include "pinggraph.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;
+
+int FillList(WPARAM wParam, LPARAM lParam);
+
+int RefreshWindow(WPARAM wParam, LPARAM lParam);
+
+void UpdateFrame();
+void AttachToClist(bool attach);
+
+void InitList();
+void DeinitList();
+
+#endif
+
+
diff --git a/ping/rawping.cpp b/ping/rawping.cpp new file mode 100644 index 0000000..65478e2 --- /dev/null +++ b/ping/rawping.cpp @@ -0,0 +1,217 @@ +#include "common.h"
+#include "rawping.h"
+
+//#define _WSPIAPI_COUNTOF
+#ifndef _MSC_VER
+#include <ws2tcpip.h>
+#endif
+
+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!
+ if(options.logging) CallService(PLUG "/Log", (WPARAM)"rawping error: unrecognised host", 0);
+ 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) {
+ if(options.logging) CallService(PLUG "/Log", (WPARAM)"rawping error: unable to send", 0);
+ 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(PLUG "/Log", (WPARAM)"rawping error: socket error...cycling", 0);
+ }
+ continue;
+ }
+
+ if(reply_header->proto != ICMP_PROTO)
+ if(options.logging) CallService(PLUG "/Log", (WPARAM)"rawping error: packet not ICMP...cycling", 0);
+ continue;
+
+ if(reply_header->tos != 0)
+ if(options.logging) CallService(PLUG "/Log", (WPARAM)"rawping error: TOS not 0...cycling", 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(PLUG "/Log", (WPARAM)"rawping error: short header", 0);
+ continue;
+ }
+
+ if(reply->id != (USHORT)GetCurrentProcessId())
+ if(options.logging) CallService(PLUG "/Log", (WPARAM)"rawping error: wrong ID...cycling", 0);
+ continue;
+
+ if(reply->type != ICMP_ECHO_REPLY && reply->type != ICMP_SOURCE_QUENCH) {
+ if(options.logging) CallService(PLUG "/Log", (WPARAM)"rawping error: wrong type...cycling", 0);
+ continue;
+ }
+
+ //if(reply->seq < seq_no) continue;
+ //if(reply->seq > seq_no) return -1;
+ if(reply->seq != seq_no) {
+ if(options.logging) CallService(PLUG "/Log", (WPARAM)"rawping error: wrong sequence number...cycling", 0);
+ 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(PLUG " 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;
+ }
+ if(options.logging) CallService(PLUG "/Log", (WPARAM)"rawping error: timeout", 0);
+
+ return -1;
+}
+
+extern int cleanup_raw_ping() {
+ if(inited) {
+ closesocket(sd);
+ sd = -1;
+ WSACleanup();
+ }
+ return 0;
+}
diff --git a/ping/rawping.h b/ping/rawping.h new file mode 100644 index 0000000..1149180 --- /dev/null +++ b/ping/rawping.h @@ -0,0 +1,61 @@ +#ifndef _RAWPING_H
+#define _RAWPING_H
+
+#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
diff --git a/ping/red.ico b/ping/red.ico Binary files differnew file mode 100644 index 0000000..9c0c7c5 --- /dev/null +++ b/ping/red.ico diff --git a/ping/resource.h b/ping/resource.h new file mode 100644 index 0000000..214edad --- /dev/null +++ b/ping/resource.h @@ -0,0 +1,80 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by ping.rc
+//
+#define IDD_DIALOG1 101
+#define IDD_DIALOG2 102
+#define IDD_DIALOG3 103
+#define IDR_MENU1 106
+#define IDI_ICON_PROTO 108
+#define IDI_ICON_DISABLED 112
+#define IDI_ICON_NOTRESPONDING 113
+#define IDI_ICON_RESPONDING 114
+#define IDI_ICON_TESTING 115
+#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_LOGCSV 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_BGCOL 1031
+#define IDC_ED_COMMAND 1032
+#define IDC_STATFS 1032
+#define IDC_RSTATUS 1033
+#define IDC_ED_PARAMS 1033
+#define IDC_NRSTATUS 1034
+#define IDC_TSTATUS 1035
+#define IDC_EDIT1 1035
+#define IDC_DSTATUS 1036
+#define IDC_CHK_NOTESTSTATUS 1037
+#define IDC_CHK_NOTESTICON 1037
+#define IDC_COMBO_GROUP 1038
+#define IDC_CHK_HIDEPROTO 1038
+#define IDC_SP_INDENT 1038
+#define IDC_EDIT2 1039
+#define IDC_SP_ROWHEIGHT 1040
+#define IDC_CHK_ATTACH 1041
+#define IDC_CHK_MINMAX 1042
+#define IDC_ST_VER 1043
+#define ID_MENU_ENABLEALLPINGS 40002
+#define ID_MENU_OPTIONS 40003
+#define ID_MENU_DISABLEALLPINGS 40004
+#define ID_MENU_DESTINATIONS 40005
+#define ID_MENU_GRAPH 40006
+#define ID_MENU_TOGGLE 40007
+#define ID_MENU_EDIT 40008
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 116
+#define _APS_NEXT_COMMAND_VALUE 40009
+#define _APS_NEXT_CONTROL_VALUE 1044
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/ping/utils.cpp b/ping/utils.cpp new file mode 100644 index 0000000..06a89a0 --- /dev/null +++ b/ping/utils.cpp @@ -0,0 +1,362 @@ +#include "common.h"
+#include "utils.h"
+
+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, PLUG " Message", MB_OK | MB_ICONINFORMATION );
+ return;
+ }
+
+ POPUPDATAEX* ppd = ( POPUPDATAEX* )calloc( sizeof( POPUPDATAEX ), 1 );
+
+ ppd->lchContact = NULL;
+ ppd->lchIcon = (flags ? hIconResponding : hIconNotResponding);
+ 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) {
+ // ICMP echo
+ if(use_raw_ping) {
+ pa->round_trip_time = raw_ping(pa->pszName, options.ping_timeout * 1000);
+ pa->responding = (pa->round_trip_time != -1);
+ } else {
+
+ IP_ECHO_REPLY result;
+ pa->responding = ICMP::get_instance()->ping(pa->pszName, result);
+ if(pa->responding)
+ pa->round_trip_time = (short)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.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);
+ 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);
+ pa->responding = true;
+ pa->round_trip_time = (int)(((end_tcp - start_tcp) / (double)CLOCKS_PER_SEC) * 1000);
+
+ Netlib_CloseHandle(s);
+ } 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(PLUG "/GetPingList", 0, (LPARAM)&pl);
+ for(PINGLIST::Iterator i = pl.start(); i.has_val(); i.next()) {
+ i.val().status = PS_DISABLED;
+ i.val().miss_count = 0;
+ }
+ CallService(PLUG "/SetPingList", (WPARAM)&pl, 0);
+ return 0;
+}
+
+int PingEnableAll(WPARAM wParam, LPARAM lParam) {
+ PINGLIST pl;
+ CallService(PLUG "/GetPingList", 0, (LPARAM)&pl);
+ for(PINGLIST::Iterator i = pl.start(); i.has_val(); i.next()) {
+ if(i.val().status == PS_DISABLED) {
+ i.val().status = PS_NOTRESPONDING;
+ }
+ }
+ CallService(PLUG "/SetPingList", (WPARAM)&pl, 0);
+ return 0;
+}
+
+
+int ToggleEnabled(WPARAM wParam, LPARAM lParam) {
+ int retval = 0;
+ PINGLIST pl;
+ CallService(PLUG "/GetPingList", 0, (LPARAM)&pl);
+ for(PINGLIST::Iterator i = pl.start(); i.has_val(); i.next()) {
+ if(i.val().item_id == (DWORD)wParam) {
+
+ if(i.val().status == PS_DISABLED)
+ i.val().status = PS_NOTRESPONDING;
+ else {
+ i.val().status = PS_DISABLED;
+ i.val().miss_count = 0;
+ retval = 1;
+ }
+ }
+ }
+ CallService(PLUG "/SetPingList", (WPARAM)&pl, 0);
+ return 0;
+}
+
+int EditContact(WPARAM wParam, LPARAM lParam) {
+ PINGLIST pl;
+ HWND hwndList = (HWND)CallService(MS_CLUI_GETHWND, 0, 0);
+
+ CallService(PLUG "/GetPingList", 0, (LPARAM)&pl);
+ for(PINGLIST::Iterator i = pl.start(); i.has_val(); i.next()) {
+ if(i.val().item_id == (DWORD)wParam) {
+
+ add_edit_addr = i.val();
+
+ if(DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG3), hwndList, DlgProcDestEdit) == IDOK) {
+
+ i.val() = add_edit_addr;
+ CallService(PLUG "/SetAndSavePingList", (WPARAM)&pl, 0);
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+int DblClick(WPARAM wParam, LPARAM lParam) {
+ PINGLIST pl;
+ CallService(PLUG "/GetPingList", 0, (LPARAM)&pl);
+ for(PINGLIST::Iterator i = pl.start(); i.has_val(); i.next()) {
+ if(i.val().item_id == (DWORD)wParam) {
+ if(strlen(i.val().pszCommand)) {
+ ShellExecute(0, "open", i.val().pszCommand, i.val().pszParams, 0, SW_SHOW);
+ } else {
+ return CallService(PLUG "/ToggleEnabled", wParam, 0);
+ }
+ }
+ }
+ return 0;
+}
+
+
+void import_ping_address(int index, PINGADDRESS &pa) {
+ DBVARIANT dbv;
+ char buf[256];
+ mir_snprintf(buf, 256, "Address%d", index);
+ if(!DBGetContactSetting(0, "PingPlug", buf, &dbv)) {
+ strncpy(pa.pszName, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ } else
+ strcpy(pa.pszName, Translate("Unknown Address"));
+
+ mir_snprintf(buf, 256, "Label%d", index);
+ if(!DBGetContactSetting(0, "PingPlug", buf, &dbv)) {
+ strncpy(pa.pszLabel, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ } else
+ strcpy(pa.pszLabel, Translate("Unknown"));
+
+ mir_snprintf(buf, 256, "Port%d", index);
+ pa.port = (int)DBGetContactSettingDword(0, "PingPlug", buf, -1);
+
+ mir_snprintf(buf, 256, "Proto%d", index);
+ if(!DBGetContactSetting(0, "PingPlug", buf, &dbv)) {
+ strncpy(pa.pszProto, dbv.pszVal, MAX_PINGADDRESS_STRING_LENGTH);
+ DBFreeVariant(&dbv);
+ mir_snprintf(buf, 256, "Status%d", index);
+ pa.set_status = DBGetContactSettingWord(0, "PingPlug", buf, ID_STATUS_ONLINE);
+ mir_snprintf(buf, 256, "Status2%d", index);
+ pa.get_status = DBGetContactSettingWord(0, "PingPlug", buf, ID_STATUS_OFFLINE);
+ } else
+ pa.pszProto[0] = '\0';
+
+
+ pa.responding = false;
+ pa.round_trip_time = 0;
+ pa.miss_count = 0;
+ pa.index = index;
+ pa.pszCommand[0] = '\0';
+ pa.pszParams[0] = '\0';
+
+ pa.item_id = 0;
+ mir_snprintf(buf, 256, "Enabled%d", index);
+ if(DBGetContactSettingByte(0, "PingPlug", buf, 1) == 1)
+ pa.status = PS_NOTRESPONDING;
+ else
+ pa.status = PS_DISABLED;
+}
+
+// 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.add(pa);
+ }
+ write_ping_addresses();
+ LeaveCriticalSection(&list_cs);
+}
+
+HANDLE hIcoLibIconsChanged;
+
+HICON hIconResponding, hIconNotResponding, hIconTesting, hIconDisabled;
+
+int ReloadIcons(WPARAM wParam, LPARAM lParam) {
+ hIconResponding = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"ping_responding");
+ hIconNotResponding = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"ping_not_responding");
+ hIconTesting = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"ping_testing");
+ hIconDisabled = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"ping_disabled");
+
+ RefreshWindow(0, 0);
+ return 0;
+}
+
+void InitIcons() {
+ if(ServiceExists(MS_SKIN2_ADDICON)) {
+ SKINICONDESC2 sid;
+
+ sid.cbSize = sizeof(SKINICONDESC2);
+ sid.pszSection = "Ping";
+
+ sid.pszDescription = Translate("Responding");
+ sid.pszName = "ping_responding";
+ sid.pszDefaultFile = "ping.dll";
+ sid.iDefaultIndex = 0;
+ sid.hDefaultIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_RESPONDING), IMAGE_ICON, 16, 16, 0);
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+
+ sid.pszDescription = Translate("Not Responding");
+ sid.pszName = "ping_not_responding";
+ sid.pszDefaultFile = "ping.dll";
+ sid.iDefaultIndex = 1;
+ sid.hDefaultIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_NOTRESPONDING), IMAGE_ICON, 16, 16, 0);//LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS );
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+
+ sid.pszDescription = Translate("Testing");
+ sid.pszName = "ping_testing";
+ sid.pszDefaultFile = "ping.dll";
+ sid.iDefaultIndex = 2;
+ sid.hDefaultIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_TESTING), IMAGE_ICON, 16, 16, 0);//LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS );
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+
+ sid.pszDescription = Translate("Disabled");
+ sid.pszName = "ping_disabled";
+ sid.pszDefaultFile = "ping.dll";
+ sid.iDefaultIndex = 3;
+ sid.hDefaultIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_DISABLED), IMAGE_ICON, 16, 16, 0);//LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS );
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+
+ hIconResponding = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"ping_responding");
+ hIconNotResponding = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"ping_not_responding");
+ hIconTesting = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"ping_testing");
+ hIconDisabled = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)"ping_disabled");
+
+ hIcoLibIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, ReloadIcons);
+ } else {
+ hIconResponding = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_RESPONDING), IMAGE_ICON, 16, 16, 0);//LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS );
+ hIconNotResponding = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_NOTRESPONDING), IMAGE_ICON, 16, 16, 0);//LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS );
+ hIconTesting = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_TESTING), IMAGE_ICON, 16, 16, 0);//LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS );
+ hIconDisabled = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON_DISABLED), IMAGE_ICON, 16, 16, 0);//LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS );
+ }
+}
+
+
diff --git a/ping/utils.h b/ping/utils.h new file mode 100644 index 0000000..a7ec017 --- /dev/null +++ b/ping/utils.h @@ -0,0 +1,35 @@ +#ifndef _PING_UTILS
+#define _PING_UTILS
+
+#pragma warning( disable : 4786 )
+
+#include "pingthread.h" // for mainthread, for popup
+//#include "icmp.h"
+#include "rawping.h"
+#include "icmp.h"
+#include "options.h"
+
+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 DblClick(WPARAM wParam, LPARAM lParam);
+
+int EditContact(WPARAM wParam, LPARAM lParam);
+// read in addresses from old pingplug
+void import_ping_addresses();
+
+// use icolib if possible
+void InitIcons();
+extern HICON hIconResponding, hIconNotResponding, hIconTesting, hIconDisabled;
+
+
+#endif
diff --git a/ping/yellow.ico b/ping/yellow.ico Binary files differnew file mode 100644 index 0000000..94f62a2 --- /dev/null +++ b/ping/yellow.ico |