diff options
author | watcherhd <watcherhd@e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb> | 2011-11-17 12:37:21 +0000 |
---|---|---|
committer | watcherhd <watcherhd@e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb> | 2011-11-17 12:37:21 +0000 |
commit | 3c0233134bc5a8e42e3a621f0a5eef2aaf487474 (patch) | |
tree | 30e49d3065aa387392028a54ef3c1ee7294b9e1e | |
parent | 9139772a56e38f15e08f1a4a3215cfd402f85dde (diff) |
adding from berlios: dbx_tree, lastseen-mod, nudge, yamn
git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@173 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb
231 files changed, 63780 insertions, 0 deletions
diff --git a/dbx_tree/BTree.h b/dbx_tree/BTree.h new file mode 100644 index 0000000..20c2abf --- /dev/null +++ b/dbx_tree/BTree.h @@ -0,0 +1,1358 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include <stack>
+#include "lockfree_hashmultimap.h"
+#include "sigslot.h"
+#ifdef _MSC_VER
+#include "stdint.h"
+#else
+#include <stdint.h>
+#endif
+
+#include "Logger.h"
+
+#ifndef _MSC_VER
+#ifdef offsetof
+#undef offsetof
+#endif
+#define offsetof(TYPE, MEMBER) \
+ ( (reinterpret_cast <size_t> \
+ (&reinterpret_cast <const volatile char &> \
+ (static_cast<TYPE *> (0)->MEMBER))))
+#endif
+
+template <typename TKey, uint16_t SizeParam = 4>
+class CBTree
+{
+public:
+ typedef uint32_t TNodeRef; /// 32bit indices (not storing pointers)
+ typedef sigslot::signal2< void *, TNodeRef > TOnRootChanged;
+
+ #pragma pack(push, 1) // push current alignment to stack, set alignment to 1 byte boundary
+
+ typedef struct TNode {
+ uint16_t Info; /// Node information (IsLeaf and stored KeyCount)
+ uint16_t Signature; /// signature
+ TNodeRef Parent; /// Handle to the parent node
+ TKey Key[SizeParam * 2 - 1]; /// array with Keys
+ TNodeRef Child[SizeParam * 2]; /// array with child node handles
+ } TNode;
+
+ #pragma pack(pop)
+
+ class iterator
+ {
+ public:
+ iterator();
+ iterator(CBTree* Tree, TNodeRef Node, uint16_t Index);
+ iterator(const iterator& Other);
+ ~iterator();
+
+ CBTree * Tree();
+
+ /**
+ \brief Keeps track of changes in the tree and refresh the iterator
+ **/
+ void setManaged();
+ bool wasDeleted();
+
+ operator bool() const;
+ bool operator !() const;
+
+ const TKey & operator *();
+ const TKey * operator->();
+
+
+ bool operator == (iterator & Other);
+ bool operator < (iterator & Other);
+ bool operator > (iterator & Other);
+
+ iterator& operator =(const iterator& Other);
+
+ iterator& operator ++(); //pre ++i
+ iterator& operator --(); //pre --i
+ iterator operator ++(int); //post i++
+ iterator operator --(int); //post i--
+
+
+ protected:
+ friend class CBTree;
+
+ TNodeRef m_Node;
+ uint16_t m_Index;
+ CBTree* m_Tree;
+
+ bool m_Managed;
+ bool m_LoadedKey;
+ TKey m_ManagedKey;
+ bool m_ManagedDeleted;
+
+ void Backup();
+ void Dec();
+ void Inc();
+ void RemoveManaged(TNodeRef FromNode);
+ void InsertManaged();
+ };
+
+
+ CBTree(TNodeRef RootNode = 0);
+ virtual ~CBTree();
+
+ iterator Insert(const TKey & Key);
+ iterator Find(const TKey & Key);
+ iterator LowerBound(const TKey & Key);
+ iterator UpperBound(const TKey & Key);
+ bool Delete(const TKey & Key);
+
+ typedef sigslot::signal3<void *, const TKey &, uint32_t> TDeleteCallback;
+ void DeleteTree(TDeleteCallback * CallBack, uint32_t Param);
+
+ TNodeRef getRoot();
+ void setRoot(TNodeRef NewRoot);
+
+ TOnRootChanged & sigRootChanged() {return m_sigRootChanged;};
+
+
+protected:
+ static const uint16_t cIsLeafMask = 0x8000;
+ static const uint16_t cKeyCountMask = 0x7FFF;
+ static const uint16_t cFullNode = SizeParam * 2 - 1;
+ static const uint16_t cEmptyNode = SizeParam - 1;
+
+ typedef lockfree::hash_multimap<TNodeRef, iterator*> TManagedMap;
+
+ TNodeRef m_Root;
+ TOnRootChanged m_sigRootChanged;
+ TManagedMap m_ManagedIterators;
+
+ bool m_DestroyTree;
+
+ uint32_t m_AllocCount;
+ uint32_t m_Count;
+ uint32_t m_FreeIndex;
+ TNode * m_Alloc;
+
+ virtual void PrepareInsertOperation();
+ virtual TNode * CreateNewNode(TNodeRef & NodeRef);
+ virtual void DeleteNode(TNodeRef Node);
+ virtual TNode * Read(TNodeRef Node);
+ virtual void Write(TNodeRef Node);
+
+ void DestroyTree();
+
+
+private:
+ friend class iterator;
+
+ bool InNodeFind(const TNode * Node, const TKey & Key, uint16_t & GreaterEqual);
+ void SplitNode(TNodeRef Node, TNode * NodeData, TNodeRef & Left, TNodeRef & Right, TKey & UpKey, TNodeRef ParentNode, uint16_t ParentIndex);
+ TNodeRef MergeNodes(TNodeRef Left, TNode * LeftData, TNodeRef Right, TNode * RightData, const TKey & DownKey, TNodeRef ParentNode, uint16_t ParentIndex);
+ void KeyInsert(TNodeRef Node, TNode * NodeData, uint16_t Where);
+ void KeyDelete(TNodeRef Node, TNode * NodeData, uint16_t Where);
+ void KeyMove(TNodeRef Source, uint16_t SourceIndex, const TNode * SourceData, TNodeRef Dest, uint16_t DestIndex, TNode * DestData);
+};
+
+
+
+
+
+
+template <typename TKey, uint16_t SizeParam>
+CBTree<TKey, SizeParam>::CBTree(TNodeRef RootNode = NULL)
+: m_sigRootChanged(),
+ m_ManagedIterators()
+{
+ m_Root = RootNode;
+ m_DestroyTree = true;
+
+ m_AllocCount = 0;
+ m_Count = 0;
+ m_FreeIndex = 0;
+ m_Alloc = NULL;
+}
+
+template <typename TKey, uint16_t SizeParam>
+CBTree<TKey, SizeParam>::~CBTree()
+{
+ typename TManagedMap::iterator i = m_ManagedIterators.begin();
+ while (i != m_ManagedIterators.end())
+ {
+ i->second->m_Tree = NULL;
+ i++;
+ }
+
+ if (m_DestroyTree)
+ DestroyTree();
+}
+
+template <typename TKey, uint16_t SizeParam>
+inline bool CBTree<TKey, SizeParam>::InNodeFind(const TNode * Node, const TKey & Key, uint16_t & GreaterEqual)
+{
+ uint16_t l = 0;
+ uint16_t r = (Node->Info & cKeyCountMask);
+ bool res = false;
+ GreaterEqual = 0;
+ while ((l < r) && !res)
+ {
+ GreaterEqual = (l + r) >> 1;
+ if (Node->Key[GreaterEqual] < Key)
+ {
+ GreaterEqual++;
+ l = GreaterEqual;
+ } else if (Node->Key[GreaterEqual] == Key)
+ {
+ //r = -1;
+ res = true;
+ } else {
+ r = GreaterEqual;
+ }
+ }
+
+ return res;
+}
+
+
+template <typename TKey, uint16_t SizeParam>
+inline void CBTree<TKey, SizeParam>::SplitNode(TNodeRef Node, TNode * NodeData, TNodeRef & Left, TNodeRef & Right, TKey & UpKey, TNodeRef ParentNode, uint16_t ParentIndex)
+{
+ const uint16_t upindex = SizeParam - 1;
+ TNode *ldata, *rdata;
+ Left = Node;
+ ldata = NodeData;
+ rdata = CreateNewNode(Right);
+
+ typename TManagedMap::iterator it = m_ManagedIterators.find(Node);
+ while ((it != m_ManagedIterators.end()) && (it->first == Node))
+ {
+ if (it->second->m_Index == upindex)
+ {
+ it->second->m_Index = ParentIndex;
+ it->second->m_Node = ParentNode;
+ m_ManagedIterators.insert(std::make_pair(ParentNode, it->second));
+ it = m_ManagedIterators.erase(it);
+ } else if (it->second->m_Index > upindex)
+ {
+ it->second->m_Index = it->second->m_Index - upindex - 1;
+ it->second->m_Node = Right;
+ m_ManagedIterators.insert(std::make_pair(Right, it->second));
+ it = m_ManagedIterators.erase(it);
+ } else {
+ ++it;
+ }
+ }
+
+ UpKey = NodeData->Key[upindex];
+
+ memcpy(&(rdata->Key[0]), &(NodeData->Key[upindex+1]), sizeof(TKey) * (cFullNode - upindex));
+ if ((NodeData->Info & cIsLeafMask) == 0)
+ {
+ memcpy(&(rdata->Child[0]), &(NodeData->Child[upindex+1]), sizeof(TNodeRef) * (cFullNode - upindex + 1));
+
+ for (int i = 0; i <= upindex; i++)
+ {
+ TNode * tmp = Read(rdata->Child[i]);
+ tmp->Parent = Right;
+ Write(rdata->Child[i]);
+ }
+ }
+
+ rdata->Info = (NodeData->Info & cIsLeafMask) | upindex;
+ NodeData->Info = rdata->Info;
+ rdata->Parent = NodeData->Parent;
+
+ Write(Left);
+ Write(Right);
+}
+
+template <typename TKey, uint16_t SizeParam>
+inline typename CBTree<TKey, SizeParam>::TNodeRef CBTree<TKey, SizeParam>::MergeNodes(TNodeRef Left, TNode * LeftData, TNodeRef Right, TNode * RightData, const TKey & DownKey, TNodeRef ParentNode, uint16_t ParentIndex)
+{
+ uint16_t downindex = LeftData->Info & cKeyCountMask;
+ LeftData->Key[downindex] = DownKey;
+
+ typename TManagedMap::iterator it = m_ManagedIterators.find(Right);
+ while ((it != m_ManagedIterators.end()) && (it->first == Right))
+ {
+ it->second->m_Index = it->second->m_Index + downindex + 1;
+ it->second->m_Node = Left;
+ m_ManagedIterators.insert(std::make_pair(Left, it->second));
+ it = m_ManagedIterators.erase(it);
+ }
+
+ it = m_ManagedIterators.find(ParentNode);
+ while ((it != m_ManagedIterators.end()) && (it->first == ParentNode))
+ {
+ if (it->second->m_Index == ParentIndex)
+ {
+ it->second->m_Index = downindex;
+ it->second->m_Node = Left;
+ m_ManagedIterators.insert(std::make_pair(Left, it->second));
+ it = m_ManagedIterators.erase(it);
+ } else {
+ ++it;
+ }
+ }
+
+ memcpy(&(LeftData->Key[downindex+1]), &(RightData->Key[0]), sizeof(TKey) * (RightData->Info & cKeyCountMask));
+ if ((LeftData->Info & cIsLeafMask) == 0)
+ {
+ memcpy(&(LeftData->Child[downindex+1]), &(RightData->Child[0]), sizeof(TNodeRef) * ((RightData->Info & cKeyCountMask) + 1));
+
+ for (int i = 0; i <= (RightData->Info & cKeyCountMask); i++)
+ {
+ TNode * tmp = Read(RightData->Child[i]);
+ tmp->Parent = Left;
+ Write(RightData->Child[i]);
+ }
+ }
+
+ LeftData->Info = ((LeftData->Info & cIsLeafMask) | (downindex + 1 + (RightData->Info & cKeyCountMask)));
+
+ Write(Left);
+ DeleteNode(Right);
+
+ return Left;
+}
+
+
+template <typename TKey, uint16_t SizeParam>
+inline void CBTree<TKey, SizeParam>::KeyInsert(TNodeRef Node, TNode * NodeData, uint16_t Where)
+{
+ memcpy(&(NodeData->Key[Where+1]), &(NodeData->Key[Where]), sizeof(TKey) * ((NodeData->Info & cKeyCountMask) - Where));
+
+ if ((NodeData->Info & cIsLeafMask) == 0)
+ memcpy(&(NodeData->Child[Where+1]), &(NodeData->Child[Where]), sizeof(TNodeRef) * ((NodeData->Info & cKeyCountMask) - Where + 1));
+
+ NodeData->Info++;
+
+ typename TManagedMap::iterator it = m_ManagedIterators.find(Node);
+ while ((it != m_ManagedIterators.end()) && (it->first == Node))
+ {
+ if (it->second->m_Index >= Where)
+ it->second->m_Index++;
+
+ ++it;
+ }
+}
+
+template <typename TKey, uint16_t SizeParam>
+inline void CBTree<TKey, SizeParam>::KeyDelete(TNodeRef Node, TNode * NodeData, uint16_t Where)
+{
+ NodeData->Info--;
+
+ typename TManagedMap::iterator it = m_ManagedIterators.find(Node);
+ while ((it != m_ManagedIterators.end()) && (it->first == Node))
+ {
+ if (it->second->m_Index == Where)
+ {
+ it->second->Backup();
+ } else if (it->second->m_Index > Where)
+ {
+ it->second->m_Index--;
+ }
+
+ ++it;
+ }
+
+ memcpy(&(NodeData->Key[Where]), &(NodeData->Key[Where+1]), sizeof(TKey) * ((NodeData->Info & cKeyCountMask) - Where));
+
+ if ((NodeData->Info & cIsLeafMask) == 0)
+ memcpy(&(NodeData->Child[Where]), &(NodeData->Child[Where+1]), sizeof(TNodeRef) * ((NodeData->Info & cKeyCountMask) - Where + 1));
+}
+
+
+template <typename TKey, uint16_t SizeParam>
+inline void CBTree<TKey, SizeParam>::KeyMove(TNodeRef Source, uint16_t SourceIndex, const TNode * SourceData, TNodeRef Dest, uint16_t DestIndex, TNode * DestData)
+{
+ DestData->Key[DestIndex] = SourceData->Key[SourceIndex];
+
+ typename TManagedMap::iterator it = m_ManagedIterators.find(Source);
+ while ((it != m_ManagedIterators.end()) && (it->first == Source))
+ {
+ if (it->second->m_Index == SourceIndex)
+ {
+ it->second->m_Index = DestIndex;
+ it->second->m_Node = Dest;
+ m_ManagedIterators.insert(std::make_pair(Dest, it->second));
+ it = m_ManagedIterators.erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::iterator
+CBTree<TKey, SizeParam>::Insert(const TKey & Key)
+{
+ TNode *node, *node2;
+ TNodeRef actnode;
+ TNodeRef nextnode;
+ bool exists;
+ uint16_t ge;
+
+ PrepareInsertOperation();
+
+ if (!m_Root)
+ {
+ node = CreateNewNode(m_Root);
+ node->Info = cIsLeafMask;
+ Write(m_Root);
+ m_sigRootChanged.emit(this, m_Root);
+ }
+
+ actnode = m_Root;
+ node = Read(actnode);
+ if ((node->Info & cKeyCountMask) == cFullNode) // root split
+ {
+ // be a little tricky and let the main code handle the actual splitting.
+ // just assign a new root with keycount to zero and one child = old root
+ // the InNode test will fail with GreaterEqual = 0
+ node2 = CreateNewNode(nextnode);
+ node2->Info = 0;
+ node2->Child[0] = actnode;
+ Write(nextnode);
+
+ node->Parent = nextnode;
+ Write(actnode);
+
+ node = node2;
+ actnode = nextnode;
+
+ m_Root = nextnode;
+ m_sigRootChanged.emit(this, m_Root);
+ }
+
+ while (actnode)
+ {
+ exists = InNodeFind(node, Key, ge);
+ if (exists) // already exists
+ {
+ return iterator(this, actnode, ge);
+ } else {
+ if (node->Info & cIsLeafMask) // direct insert to leaf node
+ {
+ KeyInsert(actnode, node, ge);
+
+ node->Key[ge] = Key;
+
+ Write(actnode);
+
+ return iterator(this, actnode, ge);
+
+ } else { // middle node
+ nextnode = node->Child[ge];
+ node2 = Read(nextnode);
+
+ if ((node2->Info & cKeyCountMask) == cFullNode) // split the childnode
+ {
+ KeyInsert(actnode, node, ge);
+ SplitNode(nextnode, node2, node->Child[ge], node->Child[ge+1], node->Key[ge], actnode, ge);
+
+ Write(actnode);
+ if (node->Key[ge] == Key)
+ {
+ return iterator(this, actnode, ge);
+ } else {
+ if (node->Key[ge] < Key)
+ {
+ nextnode = node->Child[ge+1];
+ } else {
+ nextnode = node->Child[ge];
+ }
+ }
+
+ }
+ actnode = nextnode;
+ node = Read(actnode);
+
+ } // if (node.Info & cIsLeafMask)
+ } // if (exists)
+ } // while (actnode)
+
+ // something went wrong
+ return iterator(this, 0, 0xFFFF);
+}
+
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::iterator
+CBTree<TKey, SizeParam>::Find(const TKey & Key)
+{
+ TNode * node;
+ TNodeRef actnode = m_Root;
+ uint16_t ge;
+
+ if (!m_Root) return iterator(this, 0, 0xFFFF);
+
+ node = Read(actnode);
+
+ while (actnode)
+ {
+ if (InNodeFind(node, Key, ge))
+ {
+ return iterator(this, actnode, ge);
+ }
+
+ if (!(node->Info & cIsLeafMask))
+ {
+ actnode = node->Child[ge];
+ node = Read(actnode);
+ } else {
+ actnode = 0;
+ }
+ }
+
+ return iterator(this, 0, 0xFFFF);
+}
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::iterator
+CBTree<TKey, SizeParam>::LowerBound(const TKey & Key)
+{
+ TNode * node;
+ TNodeRef actnode = m_Root;
+ uint16_t ge;
+
+ if (!m_Root) return iterator(this, 0, 0xFFFF);
+
+ node = Read(actnode);
+
+ while (actnode)
+ {
+ if (InNodeFind(node, Key, ge))
+ {
+ return iterator(this, actnode, ge);
+ }
+
+ if (node->Info & cIsLeafMask)
+ {
+ if (ge >= (node->Info & cKeyCountMask))
+ {
+ iterator i(this, actnode, ge - 1);
+ ++i;
+ return i;
+ } else {
+ return iterator(this, actnode, ge);
+ }
+ } else {
+ actnode = node->Child[ge];
+ node = Read(actnode);
+ }
+ }
+
+ return iterator(this, 0, 0xFFFF);
+}
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::iterator
+CBTree<TKey, SizeParam>::UpperBound(const TKey & Key)
+{
+ TNode * node;
+ TNodeRef actnode = m_Root;
+ uint16_t ge;
+ if (!m_Root) return iterator(this, 0, 0xFFFF);
+
+ node = Read(actnode);
+
+ while (actnode)
+ {
+ if (InNodeFind(node, Key, ge))
+ {
+ return iterator(this, actnode, ge);
+ }
+
+ if (node->Info & cIsLeafMask)
+ {
+ if (ge == 0)
+ {
+ iterator i(this, actnode, 0);
+ --i;
+ return i;
+ } else {
+ return iterator(this, actnode, ge - 1);
+ }
+ } else {
+ actnode = node->Child[ge];
+ node = Read(actnode);
+ }
+ }
+
+ return iterator(this, 0, 0xFFFF);
+}
+
+template <typename TKey, uint16_t SizeParam>
+bool CBTree<TKey, SizeParam>::Delete(const TKey& Key)
+{
+ if (!m_Root) return false;
+
+ TNode *node, *node2, *lnode, *rnode;
+
+ TNodeRef actnode = m_Root;
+ TNodeRef nextnode, l, r;
+ bool exists, skipread;
+ uint16_t ge;
+
+ bool foundininnernode = false;
+ bool wantleftmost = false;
+ TNodeRef innernode = 0;
+ TNode * innernodedata = NULL;
+ uint16_t innerindex = 0xFFFF;
+
+ node = Read(actnode);
+
+ while (actnode)
+ {
+ skipread = false;
+
+ if (foundininnernode)
+ {
+ exists = false;
+ if (wantleftmost)
+ ge = 0;
+ else
+ ge = node->Info & cKeyCountMask;
+
+ } else {
+ exists = InNodeFind(node, Key, ge);
+ }
+
+ if (exists)
+ {
+ if (node->Info & cIsLeafMask) // delete in leaf
+ {
+ KeyDelete(actnode, node, ge);
+ Write(actnode);
+
+ return true;
+
+ } else { // delete in inner node
+ l = node->Child[ge];
+ r = node->Child[ge+1];
+ lnode = Read(l);
+ rnode = Read(r);
+
+
+ if (((rnode->Info & cKeyCountMask) == cEmptyNode) && ((lnode->Info & cKeyCountMask) == cEmptyNode))
+ { // merge childnodes and keep going
+ nextnode = MergeNodes(l, lnode, r, rnode, node->Key[ge], actnode, ge);
+
+ KeyDelete(actnode, node, ge);
+ node->Child[ge] = nextnode;
+
+ if ((actnode == m_Root) && ((node->Info & cKeyCountMask) == 0))
+ { // root node is empty. delete it
+ DeleteNode(actnode);
+ m_Root = nextnode;
+ m_sigRootChanged.emit(this, m_Root);
+ } else {
+ Write(actnode);
+ }
+
+ } else { // need a key-data-pair from a leaf to replace deleted pair -> save position
+ foundininnernode = true;
+ innernode = actnode;
+ innerindex = ge;
+ innernodedata = node;
+
+ if ((lnode->Info & cKeyCountMask) == cEmptyNode)
+ {
+ wantleftmost = true;
+ nextnode = r;
+ } else {
+ wantleftmost = false;
+ nextnode = l;
+ }
+ }
+ }
+
+ } else if (node->Info & cIsLeafMask) { // we are at the bottom. finish it
+ if (foundininnernode)
+ {
+ if (wantleftmost)
+ {
+ KeyMove(actnode, 0, node, innernode, innerindex, innernodedata);
+ Write(innernode);
+
+ KeyDelete(actnode, node, 0);
+ Write(actnode);
+
+ } else {
+ KeyMove(actnode, (node->Info & cKeyCountMask) - 1, node, innernode, innerindex, innernodedata);
+ Write(innernode);
+
+ //KeyDelete(actnode, node, node.Info & cKeyCountMask);
+ node->Info--;
+ Write(actnode);
+ }
+ }
+ return foundininnernode;
+
+ } else { // inner node. go on and check if moving or merging is neccessary
+ nextnode = node->Child[ge];
+ node2 = Read(nextnode);
+
+ if ((node2->Info & cKeyCountMask) == cEmptyNode) // move or merge
+ {
+ // set l and r for easier access
+ if (ge > 0)
+ {
+ l = node->Child[ge - 1];
+ lnode = Read(l);
+ } else
+ l = 0;
+
+ if (ge < (node->Info & cKeyCountMask))
+ {
+ r = node->Child[ge + 1];
+ rnode = Read(r);
+ } else
+ r = 0;
+
+ if ((r != 0) && ((rnode->Info & cKeyCountMask) > cEmptyNode)) // move a Key-Data-pair from the right
+ {
+ // move key-data-pair down from current to the next node
+ KeyMove(actnode, ge, node, nextnode, node2->Info & cKeyCountMask, node2);
+
+ // move the child from right to next node
+ node2->Child[(node2->Info & cKeyCountMask) + 1] = rnode->Child[0];
+
+ // move key-data-pair up from right to current node
+ KeyMove(r, 0, rnode, actnode, ge, node);
+ Write(actnode);
+
+ // decrement right node key count and remove the first key-data-pair
+ KeyDelete(r, rnode, 0);
+
+ // increment KeyCount of the next node
+ node2->Info++;
+
+ if ((node2->Info & cIsLeafMask) == 0) // update the parent property of moved child
+ {
+ TNode * tmp = Read(node2->Child[node2->Info & cKeyCountMask]);
+ tmp->Parent = nextnode;
+ Write(node2->Child[node2->Info & cKeyCountMask]);
+ }
+
+
+ Write(r);
+ Write(nextnode);
+ node = node2;
+ skipread = true;
+
+ } else if ((l != 0) && ((lnode->Info & cKeyCountMask) > cEmptyNode)) // move a Key-Data-pair from the left
+ {
+ // increment next node key count and make new first key-data-pair
+ KeyInsert(nextnode, node2, 0);
+
+ // move key-data-pair down from current to the next node
+ KeyMove(actnode, ge - 1, node, nextnode, 0, node2);
+
+ // move the child from left to next node
+ node2->Child[0] = lnode->Child[lnode->Info & cKeyCountMask];
+
+ // move key-data-pair up from left to current node
+ KeyMove(l, (lnode->Info & cKeyCountMask) - 1, lnode, actnode, ge - 1, node);
+ Write(actnode);
+
+ // decrement left node key count
+ lnode->Info--;
+ Write(l);
+
+ if ((node2->Info & cIsLeafMask) == 0) // update the parent property of moved child
+ {
+ TNode * tmp = Read(node2->Child[0]);
+ tmp->Parent = nextnode;
+ Write(node2->Child[0]);
+ }
+
+ Write(nextnode);
+ node = node2;
+ skipread = true;
+
+ } else {
+ if (l != 0) // merge with the left node
+ {
+ nextnode = MergeNodes(l, lnode, nextnode, node2, node->Key[ge - 1], actnode, ge - 1);
+ KeyDelete(actnode, node, ge - 1);
+ node->Child[ge - 1] = nextnode;
+
+ } else { // merge with the right node
+ nextnode = MergeNodes(nextnode, node2, r, rnode, node->Key[ge], actnode, ge);
+ KeyDelete(actnode, node, ge);
+ node->Child[ge] = nextnode;
+ }
+
+ if ((actnode == m_Root) && ((node->Info & cKeyCountMask) == 0))
+ {
+ DeleteNode(actnode);
+ m_Root = nextnode;
+ m_sigRootChanged(this, nextnode);
+ } else {
+ Write(actnode);
+ }
+ }
+ }
+ } // if (exists) else if (node.Info & cIsLeafMask)
+
+ actnode = nextnode;
+ if (!skipread)
+ node = Read(actnode);
+
+ } // while(actnode)
+
+ return false;
+}
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::TNodeRef CBTree<TKey, SizeParam>::getRoot()
+{
+ return m_Root;
+}
+
+template <typename TKey, uint16_t SizeParam>
+void CBTree<TKey, SizeParam>::setRoot(TNodeRef NewRoot)
+{
+ m_Root = NewRoot;
+ return;
+}
+
+template <typename TKey, uint16_t SizeParam>
+void CBTree<TKey, SizeParam>::PrepareInsertOperation()
+{
+ if (m_Count + 64 > m_AllocCount)
+ {
+ m_AllocCount += 64;
+ m_Alloc = (TNode *)realloc(m_Alloc, sizeof(TNode) * m_AllocCount);
+
+ for (TNodeRef i = m_AllocCount - 64; i < m_AllocCount; ++i)
+ m_Alloc[i].Parent = i + 1;
+
+ m_Alloc[m_AllocCount - 1].Parent = 0;
+
+ if (m_FreeIndex)
+ {
+ TNodeRef i = m_FreeIndex;
+ while (m_Alloc[i].Parent)
+ i = m_Alloc[i].Parent;
+
+ m_Alloc[i].Parent = m_AllocCount - 64;
+
+ } else {
+ m_FreeIndex = m_AllocCount - 63;
+ }
+
+ }
+}
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::TNode * CBTree<TKey, SizeParam>::CreateNewNode(TNodeRef & NodeRef)
+{
+ NodeRef = m_FreeIndex;
+ m_FreeIndex = m_Alloc[m_FreeIndex].Parent;
+ m_Count++;
+ memset(m_Alloc + NodeRef, 0, sizeof(TNode));
+ return m_Alloc + NodeRef;
+}
+
+template <typename TKey, uint16_t SizeParam>
+void CBTree<TKey, SizeParam>::DeleteNode(TNodeRef Node)
+{
+ CHECK((Node > 0) && (Node < m_AllocCount), logERROR, _T("Invalid Node"));
+ m_Alloc[Node].Parent = m_FreeIndex;
+ m_FreeIndex = Node;
+ m_Count--;
+}
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::TNode * CBTree<TKey, SizeParam>::Read(TNodeRef Node)
+{
+ CHECK((Node > 0) && (Node < m_AllocCount), logERROR, _T("Invalid Node"));
+ return m_Alloc + Node;
+}
+
+template <typename TKey, uint16_t SizeParam>
+void CBTree<TKey, SizeParam>::Write(TNodeRef Node)
+{
+ return;
+}
+
+template <typename TKey, uint16_t SizeParam>
+void CBTree<TKey, SizeParam>::DestroyTree()
+{
+ std::stack<TNodeRef> s;
+ TNodeRef node;
+ TNode* nodedata;
+ uint16_t i;
+
+ if (m_Root)
+ s.push(m_Root);
+ while (!s.empty())
+ {
+ node = s.top();
+ nodedata = Read(node);
+ s.pop();
+
+ if ((nodedata->Info & cIsLeafMask) == 0)
+ {
+ for (i = 0; i <= (nodedata->Info & cKeyCountMask); i++)
+ s.push(nodedata->Child[i]);
+ }
+
+ DeleteNode(node);
+ }
+
+ if (m_Alloc)
+ free(m_Alloc);
+ m_Alloc = NULL;
+ m_AllocCount = 0;
+ m_Count = 0;
+ m_FreeIndex = 0;
+}
+
+
+template <typename TKey, uint16_t SizeParam>
+void CBTree<TKey, SizeParam>::DeleteTree(TDeleteCallback * CallBack, uint32_t Param)
+{
+ std::stack<TNodeRef> s;
+ TNodeRef actnode;
+ TNode * node;
+ uint16_t i;
+
+ typename TManagedMap::iterator it = m_ManagedIterators.begin();
+ while (it != m_ManagedIterators.end())
+ {
+ it->second->m_Node = 0;
+ it->second->m_Index = 0xffff;
+ ++it;
+ }
+
+ if (m_Root)
+ s.push(m_Root);
+
+ m_Root = 0;
+ m_sigRootChanged.emit(this, m_Root);
+
+ while (!s.empty())
+ {
+ actnode = s.top();
+ s.pop();
+
+ node = Read(actnode);
+
+ if ((node->Info & cIsLeafMask) == 0)
+ {
+ for (i = 0; i <= (node->Info & cKeyCountMask); i++)
+ s.push(node->Child[i]);
+
+ }
+ if (CallBack)
+ {
+ for (i = 0; i < (node->Info & cKeyCountMask); i++)
+ CallBack->emit(this, node->Key[i], Param);
+ }
+
+ DeleteNode(actnode);
+ }
+}
+
+
+
+
+
+
+
+template <typename TKey, uint16_t SizeParam>
+CBTree<TKey, SizeParam>::iterator::iterator()
+{
+ m_Tree = NULL;
+ m_Node = 0;
+ m_Index = 0xFFFF;
+ m_Managed = false;
+ m_ManagedDeleted = false;
+ m_LoadedKey = false;
+}
+template <typename TKey, uint16_t SizeParam>
+CBTree<TKey, SizeParam>::iterator::iterator(CBTree* Tree, TNodeRef Node, uint16_t Index)
+{
+ m_Tree = Tree;
+ m_Node = Node;
+ m_Index = Index;
+ m_Managed = false;
+ m_ManagedDeleted = false;
+ m_LoadedKey = false;
+}
+template <typename TKey, uint16_t SizeParam>
+CBTree<TKey, SizeParam>::iterator::iterator(const iterator& Other)
+{
+ m_Tree = Other.m_Tree;
+ m_Node = Other.m_Node;
+ m_Index = Other.m_Index;
+ m_ManagedDeleted = Other.m_ManagedDeleted;
+ m_Managed = Other.m_Managed;
+ m_LoadedKey = Other.m_LoadedKey;
+ m_ManagedKey = Other.m_ManagedKey;
+
+ if (m_Managed)
+ InsertManaged();
+}
+
+template <typename TKey, uint16_t SizeParam>
+CBTree<TKey, SizeParam>::iterator::~iterator()
+{
+ RemoveManaged(m_Node);
+}
+
+
+template <typename TKey, uint16_t SizeParam>
+void CBTree<TKey, SizeParam>::iterator::setManaged()
+{
+ if (!m_Managed)
+ InsertManaged();
+
+ m_Managed = true;
+}
+
+template <typename TKey, uint16_t SizeParam>
+inline void CBTree<TKey, SizeParam>::iterator::RemoveManaged(TNodeRef FromNode)
+{
+ if (m_Managed && m_Tree)
+ {
+ typename TManagedMap::iterator i = m_Tree->m_ManagedIterators.find(FromNode);
+
+ while ((i != m_Tree->m_ManagedIterators.end()) && (i->second != this) && (i->first == FromNode))
+ ++i;
+
+ if ((i != m_Tree->m_ManagedIterators.end()) && (i->second == this))
+ m_Tree->m_ManagedIterators.erase(i);
+ }
+}
+template <typename TKey, uint16_t SizeParam>
+inline void CBTree<TKey, SizeParam>::iterator::InsertManaged()
+{
+ if (m_Tree)
+ m_Tree->m_ManagedIterators.insert(std::make_pair(m_Node, this));
+}
+
+template <typename TKey, uint16_t SizeParam>
+bool CBTree<TKey, SizeParam>::iterator::wasDeleted()
+{
+ return m_ManagedDeleted;
+}
+
+template <typename TKey, uint16_t SizeParam>
+void CBTree<TKey, SizeParam>::iterator::Backup()
+{
+ if ((!m_ManagedDeleted) && (*this))
+ {
+ TNode * tmp;
+ if (!m_LoadedKey)
+ {
+ tmp = m_Tree->Read(m_Node);
+ m_ManagedKey = tmp->Key[m_Index];
+ }
+ m_LoadedKey = true;
+ }
+
+ m_ManagedDeleted = true;
+}
+
+template <typename TKey, uint16_t SizeParam>
+CBTree<TKey, SizeParam> * CBTree<TKey, SizeParam>::iterator::Tree()
+{
+ return m_Tree;
+}
+
+template <typename TKey, uint16_t SizeParam>
+const TKey& CBTree<TKey, SizeParam>::iterator::operator *()
+{
+ if (!m_LoadedKey)
+ {
+ TNode * node;
+ node = m_Tree->Read(m_Node);
+ m_ManagedKey = node->Key[m_Index];
+ m_LoadedKey = true;
+ }
+ return m_ManagedKey;
+}
+
+template <typename TKey, uint16_t SizeParam>
+const TKey* CBTree<TKey, SizeParam>::iterator::operator ->()
+{
+ if (!m_LoadedKey)
+ {
+ TNode * node;
+ node = m_Tree->Read(m_Node);
+ m_ManagedKey = node->Key[m_Index];
+ m_LoadedKey = true;
+ }
+ return &m_ManagedKey;
+}
+
+template <typename TKey, uint16_t SizeParam>
+inline CBTree<TKey, SizeParam>::iterator::operator bool() const
+{
+ if (m_Tree && m_Node)
+ {
+ TNode * node;
+ node = m_Tree->Read(m_Node);
+ return (m_Index < (node->Info & cKeyCountMask));
+ } else
+ return false;
+}
+
+template <typename TKey, uint16_t SizeParam>
+inline bool CBTree<TKey, SizeParam>::iterator::operator !() const
+{
+ if (m_Tree && m_Node)
+ {
+ TNode * node;
+ node = m_Tree->Read(m_Node);
+ return (m_Index > (node->Info & cKeyCountMask));
+ } else
+ return true;
+}
+
+template <typename TKey, uint16_t SizeParam>
+inline bool CBTree<TKey, SizeParam>::iterator::operator ==(iterator & Other)
+{
+ //return (m_Tree == Other.m_Tree) && (m_Node == Other.m_Node) && (m_Index == Other.m_Index) && (!m_ManagedDeleted) && (!Other.m_ManagedDeleted);
+ return Key() == Other.Key();
+}
+
+template <typename TKey, uint16_t SizeParam>
+inline bool CBTree<TKey, SizeParam>::iterator::operator < (iterator & Other)
+{
+ return Key() < Other.Key();
+}
+template <typename TKey, uint16_t SizeParam>
+inline bool CBTree<TKey, SizeParam>::iterator::operator > (iterator & Other)
+{
+ return Key() > Other.Key();
+}
+
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::iterator&
+CBTree<TKey, SizeParam>::iterator::operator =(const iterator& Other)
+{
+ RemoveManaged(m_Node);
+
+ m_Tree = Other.m_Tree;
+ m_Node = Other.m_Node;
+ m_Index = Other.m_Index;
+ m_ManagedDeleted = Other.m_ManagedDeleted;
+ m_Managed = Other.m_Managed;
+ m_LoadedKey = Other.m_LoadedKey;
+ m_ManagedKey = Other.m_ManagedKey;
+
+ if (m_Managed)
+ InsertManaged();
+
+ return *this;
+}
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::iterator&
+CBTree<TKey, SizeParam>::iterator::operator ++() //pre ++i
+{
+ TNodeRef oldnode = m_Node;
+ if (m_Managed && m_ManagedDeleted)
+ {
+ TKey oldkey = m_ManagedKey;
+ m_LoadedKey = false;
+ m_ManagedDeleted = false;
+ iterator other = m_Tree->LowerBound(m_ManagedKey);
+ m_Node = other.m_Node;
+ m_Index = other.m_Index;
+ while (((**this) == oldkey) && (*this))
+ Inc();
+
+ } else
+ Inc();
+
+ if (m_Managed && (oldnode != m_Node))
+ {
+ RemoveManaged(oldnode);
+ InsertManaged();
+ }
+ return *this;
+}
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::iterator&
+CBTree<TKey, SizeParam>::iterator::operator --() //pre --i
+{
+ TNodeRef oldnode = m_Node;
+ if (m_Managed && m_ManagedDeleted)
+ {
+ TKey oldkey = m_ManagedKey;
+ m_LoadedKey = false;
+
+ m_ManagedDeleted = false;
+ iterator other = m_Tree->UpperBound(m_ManagedKey);
+ m_Node = other.m_Node;
+ m_Index = other.m_Index;
+ while (((**this) == oldkey) && (*this))
+ Dec();
+ } else
+ Dec();
+
+ if (m_Managed && (oldnode != m_Node))
+ {
+ RemoveManaged(oldnode);
+ InsertManaged();
+ }
+ return *this;
+}
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::iterator
+CBTree<TKey, SizeParam>::iterator::operator ++(int) //post i++
+{
+ iterator tmp(*this);
+ ++(*this);
+ return tmp;
+}
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::iterator
+CBTree<TKey, SizeParam>::iterator::operator --(int) //post i--
+{
+ iterator tmp(*this);
+ --(*this);
+ return tmp;
+}
+
+template <typename TKey, uint16_t SizeParam>
+void CBTree<TKey, SizeParam>::iterator::Inc()
+{
+ TNode * node;
+ TNodeRef nextnode;
+ node = m_Tree->Read(m_Node);
+
+ m_LoadedKey = false;
+
+ if ((node->Info & cIsLeafMask) && ((node->Info & cKeyCountMask) > m_Index + 1)) // leaf
+ {
+ m_Index++;
+ return;
+ }
+
+ if ((node->Info & cIsLeafMask) == 0) // inner node. go down
+ {
+ m_Node = node->Child[m_Index + 1];
+ node = m_Tree->Read(m_Node);
+
+ m_Index = 0;
+
+ while ((node->Info & cIsLeafMask) == 0) // go down to a leaf
+ {
+ m_Node = node->Child[0];
+ node = m_Tree->Read(m_Node);
+ }
+
+ return;
+ }
+
+ while (m_Index >= (node->Info & cKeyCountMask) - 1) // go up
+ {
+ if (m_Node == m_Tree->m_Root) // the root is the top, we cannot go further
+ {
+ m_Index = 0xFFFF;
+ m_Node = 0;
+ return;
+ }
+
+ nextnode = node->Parent;
+ node = m_Tree->Read(nextnode);
+ m_Index = 0;
+
+ while ((m_Index <= (node->Info & cKeyCountMask)) && (node->Child[m_Index] != m_Node))
+ m_Index++;
+
+ m_Node = nextnode;
+
+ if (m_Index < (node->Info & cKeyCountMask))
+ return;
+ }
+
+}
+
+template <typename TKey, uint16_t SizeParam>
+void CBTree<TKey, SizeParam>::iterator::Dec()
+{
+ TNode * node;
+ TNodeRef nextnode;
+ node = m_Tree->Read(m_Node);
+
+ m_LoadedKey = false;
+
+ if ((node->Info & cIsLeafMask) && (m_Index > 0)) // leaf
+ {
+ m_Index--;
+ return;
+ }
+
+ if ((node->Info & cIsLeafMask) == 0) // inner node. go down
+ {
+ m_Node = node->Child[m_Index];
+ node = m_Tree->Read(m_Node);
+ m_Index = (node->Info & cKeyCountMask) - 1;
+
+ while ((node->Info & cIsLeafMask) == 0) // go down to a leaf
+ {
+ m_Node = node->Child[node->Info & cKeyCountMask];
+ node = m_Tree->Read(m_Node);
+ m_Index = (node->Info & cKeyCountMask) - 1;
+ }
+
+ return;
+ }
+
+ while (m_Index == 0) // go up
+ {
+ if (m_Node == m_Tree->m_Root) // the root is the top, we cannot go further
+ {
+ m_Index = 0xFFFF;
+ m_Node = 0;
+ return;
+ }
+
+ nextnode = node->Parent;
+ node = m_Tree->Read(nextnode);
+ m_Index = 0;
+
+ while ((m_Index <= (node->Info & cKeyCountMask)) && (node->Child[m_Index] != m_Node))
+ m_Index++;
+
+ m_Node = nextnode;
+
+ if (m_Index > 0)
+ {
+ m_Index--;
+ return;
+ }
+ }
+}
diff --git a/dbx_tree/BlockManager.cpp b/dbx_tree/BlockManager.cpp new file mode 100644 index 0000000..3be5d80 --- /dev/null +++ b/dbx_tree/BlockManager.cpp @@ -0,0 +1,965 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "BlockManager.h"
+#include "Logger.h"
+
+CBlockManager::CBlockManager(
+ CFileAccess & FileAccess,
+ CEncryptionManager & EncryptionManager
+ )
+: m_BlockSync(),
+ m_FileAccess(FileAccess),
+ m_EncryptionManager(EncryptionManager),
+ m_BlockTable(1024),
+ m_FreeBlocks()
+{
+ m_Optimize.Thread = NULL;
+ m_Optimize.Source = 0;
+ m_Optimize.Dest = 0;
+
+ m_CacheInfo.Growth = 0;
+ m_CacheInfo.Size = 0;
+ m_CacheInfo.LastPurge = time(NULL);
+
+ m_PendingHead = NULL;
+ m_PendingTail = NULL;
+ m_PendingLast = NULL;
+ m_LastFlush = time(NULL);
+ m_BytesPending = 20;
+ m_FirstFreeIndex = 0;
+
+ m_SaveMode = true;
+ m_ReadOnly = m_FileAccess.ReadOnly();
+
+ memset(m_Cache, 0, sizeof(m_Cache));
+}
+
+CBlockManager::~CBlockManager()
+{
+ m_BlockSync.BeginWrite();
+ if (m_Optimize.Thread)
+ {
+ m_Optimize.Thread->FreeOnTerminate(false);
+ m_Optimize.Thread->Terminate();
+
+ m_BlockSync.EndWrite();
+ m_Optimize.Thread->WaitFor();
+
+ delete m_Optimize.Thread;
+ } else {
+ m_BlockSync.EndWrite();
+ }
+
+ _PendingFlush(true);
+
+ for (uint32_t buddy = 0; buddy < cCacheBuddyCount; buddy++)
+ {
+ TCacheEntry * i = m_Cache[buddy];
+ while (i)
+ {
+ free(i->Cache);
+
+ TCacheEntry * tmp = i;
+ i = i->Next;
+ free(tmp);
+ }
+ }
+}
+
+// Optimize File Size
+void CBlockManager::ExecuteOptimize()
+{ /*
+ TBlockHeadFree h = {0,0};
+ uint8_t * buf = (uint8_t*)malloc(1 << 18); // 256kb
+ uint32_t bufuse = 0;
+ uint32_t bufsize = 1 << 18;
+ uint32_t lastflush = 0;
+
+ {
+ int i = 0;
+ while (!m_Optimize.Thread->Terminated() && (i < 600))
+ {
+ ++i;
+ Sleep(100); // wait for Miranda to start
+ }
+ }
+
+ TransactionBeginWrite();
+
+ while (!m_Optimize.Thread->Terminated() && (m_Optimize.Source < m_FileAccess.Size()) && !m_ReadOnly)
+ {
+ m_FileAccess.Read(&h, m_Optimize.Source, sizeof(h));
+ if (h.ID == cFreeBlockID)
+ {
+ _RemoveFreeBlock(m_Optimize.Source, h.Size);
+
+ m_Optimize.Source += h.Size;
+ } else {
+
+ if (bufsize < bufuse + h.Size)
+ {
+ buf = (uint8_t*)realloc(buf, bufuse + h.Size);
+ bufsize = bufuse + h.Size;
+ }
+ m_FileAccess.Read(buf + bufuse, m_Optimize.Source, h.Size);
+
+ m_BlockTable[h.ID >> 2].Addr = (m_Optimize.Dest + bufuse) >> 2;
+
+ m_Optimize.Source += h.Size;
+ bufuse += h.Size;
+ }
+
+ if ((m_BlockSync.Waiting() > 0)
+ || (bufuse + 1024 >= bufsize)
+ || (m_Optimize.Source >= m_FileAccess.Size())) // buffer is nearly full or EOF
+ {
+ if (m_Optimize.Dest != m_Optimize.Source) // move blocks
+ {
+ TBlockHeadFree h = {cFreeBlockID, m_Optimize.Source - m_Optimize.Dest};
+ TBlockTailFree t = {m_Optimize.Source - m_Optimize.Dest, cFreeBlockID};
+
+ m_FileAccess.Write(buf, m_Optimize.Dest, bufuse);
+
+ m_FileAccess.Write(&h, m_Optimize.Dest + bufuse, sizeof(h));
+ m_FileAccess.Invalidate(m_Optimize.Dest + bufuse + sizeof(h), m_Optimize.Source - m_Optimize.Dest - bufuse - sizeof(h) - sizeof(t));
+ m_FileAccess.Write(&t, m_Optimize.Dest + bufuse - sizeof(t), sizeof(t));
+
+ if (m_SaveMode)
+ {
+ m_FileAccess.CloseTransaction();
+ m_FileAccess.Flush();
+ m_FileAccess.UseJournal(false);
+
+ m_FileAccess.Write(buf, m_Optimize.Dest, bufuse);
+
+ m_FileAccess.Write(&h, m_Optimize.Dest + bufuse, sizeof(h));
+ m_FileAccess.Invalidate(m_Optimize.Dest + bufuse + sizeof(h), m_Optimize.Source - m_Optimize.Dest - bufuse - sizeof(h) - sizeof(t));
+ m_FileAccess.Write(&t, m_Optimize.Dest + bufuse - sizeof(t), sizeof(t));
+
+ m_FileAccess.Flush();
+ m_FileAccess.CleanJournal();
+ m_FileAccess.UseJournal(true);
+ }
+
+ m_Optimize.Dest += bufuse;
+ bufuse = 0;
+ }
+
+ if (m_BlockSync.Waiting() > 0)
+ {
+ unsigned int w = m_BlockSync.Waiting();
+ m_BlockSync.EndWrite();
+ Sleep(w * 64 + 1);
+ m_BlockSync.BeginWrite();
+ m_FileAccess.UseJournal(m_SaveMode);
+ }
+ }
+ }
+
+ if (m_Optimize.Source >= m_FileAccess.Size())
+ m_FileAccess.Size(m_Optimize.Dest);
+
+ m_Optimize.Thread = NULL;
+ m_Optimize.Source = 0;
+ m_Optimize.Dest = 0;
+ if (m_SaveMode)
+ TransactionEndWrite();
+ else
+ m_BlockSync.EndWrite();
+
+ free(buf); */
+
+ m_Optimize.Thread = NULL;
+}
+
+inline void CBlockManager::_PendingAdd(uint32_t BlockID, uint32_t Addr, uint32_t Size, TCacheEntry * Cache)
+{
+ TPendingOperation * p = NULL;
+ if (BlockID == cFreeBlockID)
+ {
+ p = (TPendingOperation*)malloc(sizeof(TPendingOperation));
+
+ p->BlockID = cFreeBlockID;
+ p->Addr = Addr;
+ p->Size = Size;
+ p->CacheEntry = NULL;
+ p->EncryptionBuffer = NULL;
+
+ m_BytesPending += 24 + sizeof(TBlockHeadFree) + sizeof(TBlockTailFree);
+ if (Addr & cPendingInvalidate)
+ m_BytesPending += 12;
+
+ } else {
+ if (Cache->Pending)
+ {
+ p = Cache->Pending;
+ _PendingRemove(Cache->Pending, false);
+ } else {
+ p = (TPendingOperation*)malloc(sizeof(TPendingOperation));
+ }
+
+ p->BlockID = BlockID;
+ p->Addr = Addr;
+ p->Size = Size;
+ p->CacheEntry = Cache;
+ p->EncryptionBuffer = NULL;
+
+ m_BytesPending += 12 + Size;
+
+ Cache->Pending = p;
+ }
+
+ p->Next = NULL;
+ p->Prev = m_PendingTail;
+ if (m_PendingTail)
+ m_PendingTail->Next = p;
+
+ m_PendingTail = p;
+ if (!m_PendingHead)
+ m_PendingHead = p;
+}
+
+inline void CBlockManager::_PendingRemove(TPendingOperation * Pending, bool Free)
+{
+ if (Pending->Prev)
+ Pending->Prev->Next = Pending->Next;
+ else
+ m_PendingHead = Pending->Next;
+
+ if (Pending->Next)
+ Pending->Next->Prev = Pending->Prev;
+ else
+ m_PendingTail = Pending->Prev;
+
+ if (Pending->EncryptionBuffer)
+ free(Pending->EncryptionBuffer);
+
+ if (m_PendingLast == Pending)
+ m_PendingLast = Pending->Prev;
+
+ Pending->CacheEntry->Pending = NULL;
+ if (Free)
+ free(Pending);
+}
+
+inline void CBlockManager::_PendingFlush(bool FullFlush)
+{
+ TPendingOperation * i = NULL;
+
+ if (m_ReadOnly)
+ return;
+
+ if (FullFlush)
+ {
+ if (m_SaveMode)
+ {
+ _PendingFlush(false); // write to journal
+ m_FileAccess.Flush();
+ m_FileAccess.UseJournal(false);
+ m_FileAccess.Size(m_FileAccess.Size()); // resize real file
+ } else {
+ m_FileAccess.UseJournal(false);
+ }
+
+ i = m_PendingHead;
+ } else if (m_PendingLast)
+ {
+ i = m_PendingLast->Next;
+ m_FileAccess.UseJournal(m_SaveMode);
+ } else {
+ i = m_PendingHead;
+ m_FileAccess.UseJournal(m_SaveMode);
+ }
+
+ while (i)
+ {
+ if (i->BlockID == cFreeBlockID)
+ {
+ uint32_t addr = i->Addr & ~cPendingInvalidate;
+ if (addr + i->Size <= m_FileAccess.Size())
+ {
+ TBlockHeadFree h = {cFreeBlockID, i->Size};
+ TBlockTailFree t = {i->Size, cFreeBlockID};
+
+ m_FileAccess.Write(&h, addr, sizeof(h));
+ if (i->Addr & cPendingInvalidate)
+ m_FileAccess.Invalidate(addr + sizeof(h), i->Size - sizeof(h) - sizeof(t));
+ m_FileAccess.Write(&t, addr + i->Size - sizeof(t), sizeof(t));
+ }
+
+ } else {
+
+ if (i->BlockID && !i->EncryptionBuffer && m_EncryptionManager.IsEncrypted(i->BlockID))
+ {
+ i->EncryptionBuffer = (TBlockHeadOcc*) malloc(i->Size);
+ memcpy(i->EncryptionBuffer, i->CacheEntry->Cache, i->Size);
+ m_EncryptionManager.Encrypt(i->EncryptionBuffer + 1, i->Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc), i->BlockID, 0);
+ }
+
+ if (i->EncryptionBuffer)
+ {
+ m_FileAccess.Write(i->EncryptionBuffer, i->Addr, i->Size);
+ } else {
+ m_FileAccess.Write(i->CacheEntry->Cache, i->Addr, i->Size);
+ }
+ }
+
+ i = i->Next;
+ } // while
+
+ if (FullFlush)
+ {
+ m_FileAccess.Flush();
+ if (m_SaveMode)
+ m_FileAccess.CleanJournal();
+
+ m_BytesPending = 20;
+ m_LastFlush = time(NULL);
+
+ i = m_PendingHead;
+ while (i)
+ {
+ if (i->EncryptionBuffer)
+ free(i->EncryptionBuffer);
+
+ if (i->CacheEntry)
+ i->CacheEntry->Pending = NULL;
+
+ TPendingOperation * tmp = i;
+ i = i->Next;
+ free(tmp);
+ }
+ m_PendingHead = NULL;
+ m_PendingTail = NULL;
+ m_PendingLast = NULL;
+ } else {
+ m_PendingLast = m_PendingTail;
+ m_FileAccess.CloseTransaction();
+ }
+}
+
+inline CBlockManager::TCacheEntry * CBlockManager::_CacheInsert(uint32_t Idx, TBlockHeadOcc * Cache, bool Virtual)
+{
+ TCacheEntry * res;
+ uint32_t myidx = ROR_32(Idx, cCacheBuddyBits);
+
+ res = (TCacheEntry *)malloc(sizeof(TCacheEntry));
+ res->Cache = Cache;
+ res->Pending = NULL;
+ res->Idx = myidx;
+ res->Forced = Virtual;
+
+ TCacheEntry * volatile * last = &m_Cache[Idx % cCacheBuddyCount];
+ TCacheEntry * i;
+ do {
+ i = *last;
+
+ while (i && (i->Idx < myidx))
+ {
+ last = &i->Next;
+ i = i->Next;
+ }
+
+ if (i && (i->Idx == myidx))
+ {
+ free(res);
+ free(Cache);
+
+ i->LastUse = time(NULL) >> 2;
+ return i;
+ }
+
+ res->Next = i;
+
+ } while (i != CMPXCHG_Ptr(*last, res, i) );
+
+ res->LastUse = time(NULL) >> 2;
+
+ m_BlockTable[Idx].InCache = true;
+ if (!Virtual)
+ XADD_32(m_CacheInfo.Growth, res->Cache->Size);
+
+ return res;
+}
+
+inline CBlockManager::TCacheEntry * CBlockManager::_CacheFind(uint32_t Idx)
+{
+ TCacheEntry * i = m_Cache[Idx % cCacheBuddyCount];
+ uint32_t myidx = ROR_32(Idx, cCacheBuddyBits);
+ while (i && (i->Idx < myidx))
+ i = i->Next;
+
+ if (i && (i->Idx == myidx))
+ return i;
+ else
+ return NULL;
+}
+
+inline void CBlockManager::_CacheErase(uint32_t Idx)
+{
+ TCacheEntry * i = m_Cache[Idx % cCacheBuddyCount];
+ TCacheEntry * volatile * l = &m_Cache[Idx % cCacheBuddyCount];
+
+ uint32_t myidx = ROR_32(Idx, cCacheBuddyBits);
+
+ while (i->Idx < myidx)
+ {
+ l = &i->Next;
+ i = i->Next;
+ }
+ *l = i->Next;
+
+ if (i->Cache)
+ free(i->Cache);
+ free(i);
+}
+
+inline void CBlockManager::_CachePurge()
+{
+ _PendingFlush(true);
+
+ uint32_t ts = time(NULL);
+ if (m_CacheInfo.Size + m_CacheInfo.Growth > cCachePurgeSize) {
+ ts = ts - (ts - m_CacheInfo.LastPurge) * cCachePurgeSize / (m_CacheInfo.Size + 2 * m_CacheInfo.Growth);
+ } else if (m_CacheInfo.Growth > m_CacheInfo.Size)
+ {
+ ts = ts - (ts - m_CacheInfo.LastPurge) * m_CacheInfo.Size / m_CacheInfo.Growth;
+ } else if (m_CacheInfo.Size > m_CacheInfo.Growth)
+ {
+ ts = ts - (ts - m_CacheInfo.LastPurge) * m_CacheInfo.Growth / m_CacheInfo.Size;
+ } else {
+ ts = m_CacheInfo.LastPurge;
+ }
+
+ m_CacheInfo.Size += m_CacheInfo.Growth;
+ m_CacheInfo.Growth = 0;
+ m_CacheInfo.LastPurge = time(NULL);
+
+ for (uint32_t buddy = 0; buddy < cCacheBuddyCount; buddy++)
+ {
+ TCacheEntry * i = m_Cache[buddy];
+ TCacheEntry * volatile * l = &m_Cache[buddy];
+
+ while (i)
+ {
+ if (!i->Forced && !i->KeepInCache && i->Idx && ((i->LastUse << 2) < ts))
+ {
+ uint32_t idx = ROL_32(i->Idx, cCacheBuddyBits);
+ m_CacheInfo.Size -= i->Cache->Size;
+ m_BlockTable[idx].InCache = false;
+ free(i->Cache);
+
+ *l = i->Next;
+ TCacheEntry * tmp = i;
+ i = i->Next;
+ free(tmp);
+
+ } else {
+ l = &i->Next;
+ i = i->Next;
+ }
+ }
+ }
+}
+
+inline uint32_t CBlockManager::_GetAvailableIndex()
+{
+ uint32_t id;
+ if (m_FirstFreeIndex)
+ {
+ id = m_FirstFreeIndex;
+ m_FirstFreeIndex = m_BlockTable[id].Addr;
+ TBlockTableEntry b = {false, false, 0};
+ m_BlockTable[id] = b;
+ } else {
+ id = static_cast<uint32_t>(m_BlockTable.size());
+ if (id > (1 << 12))
+ m_BlockTable.resize(id + (1 << 12));
+ else
+ m_BlockTable.resize(id * 2);
+
+ for (uint32_t i = static_cast<uint32_t>(m_BlockTable.size() - 1); i > id; --i)
+ {
+ TBlockTableEntry b = {true, true, m_FirstFreeIndex};
+ m_BlockTable[i] = b;
+ m_FirstFreeIndex = i;
+ }
+ }
+ return id;
+}
+
+inline void CBlockManager::_InsertFreeBlock(uint32_t Addr, uint32_t Size, bool InvalidateData, bool Reuse)
+{
+ if (Addr + Size == m_FileAccess.Size())
+ {
+ if (Reuse) // in FindFreePosition we would want to use that block
+ m_FileAccess.Size(Addr);
+ } else {
+
+ if (Reuse)
+ m_FreeBlocks.insert(std::make_pair(Size, Addr));
+
+ if (!m_ReadOnly)
+ _PendingAdd(cFreeBlockID, InvalidateData ? Addr | cPendingInvalidate : Addr, Size, NULL);
+
+ }
+}
+
+inline void CBlockManager::_RemoveFreeBlock(uint32_t Addr, uint32_t Size)
+{
+ TFreeBlockMap::iterator i = m_FreeBlocks.find(Size);
+ while ((i != m_FreeBlocks.end()) && (i->first == Size))
+ {
+ if (i->second == Addr)
+ {
+ m_FreeBlocks.erase(i);
+ i = m_FreeBlocks.end();
+ } else {
+ ++i;
+ }
+ }
+}
+
+inline uint32_t CBlockManager::_FindFreePosition(uint32_t Size)
+{
+ // try to find free block
+ TFreeBlockMap::iterator f;
+ TFreeBlockMap::iterator e = m_FreeBlocks.end();
+
+ if (m_FreeBlocks.size())
+ {
+ f = m_FreeBlocks.find(Size);
+ if (f == e)
+ {
+ if (m_FreeBlocks.rbegin()->first > Size * 2)
+ {
+ f = m_FreeBlocks.end();
+ --f;
+ }
+ }
+ } else {
+ f = e;
+ }
+
+ uint32_t addr = 0;
+
+ if (f == e) // no block found - expand file
+ {
+ addr = m_FileAccess.Size();
+ m_FileAccess.Size(addr + Size);
+
+ } else {
+ addr = f->second;
+
+ if (f->first != Size)
+ {
+ _InsertFreeBlock(addr + Size, f->first - Size, false, true);
+ }
+ _InsertFreeBlock(addr, Size, false, false);
+
+ m_FreeBlocks.erase(f);
+ }
+
+ return addr;
+}
+
+inline bool CBlockManager::_InitOperation(uint32_t BlockID, uint32_t & Addr, TCacheEntry * & Cache)
+{
+ if (!BlockID || (BlockID & 3) || ((BlockID >> 2) >= m_BlockTable.size()))
+ return false;
+
+ uint32_t idx = BlockID >> 2;
+ TBlockTableEntry dat = m_BlockTable[idx];
+
+ if (dat.Deleted) // deleted or FreeIDList item
+ return false;
+
+ Addr = dat.Addr << 2;
+ if (dat.InCache)
+ {
+ Cache = _CacheFind(idx);
+ } else if (Addr)
+ {
+ TBlockHeadOcc h;
+
+ m_FileAccess.Read(&h, Addr, sizeof(h));
+
+ TBlockHeadOcc * block = (TBlockHeadOcc *) malloc(h.Size);
+ m_FileAccess.Read(block, Addr, h.Size);
+
+ m_EncryptionManager.Decrypt(block + 1, h.Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc), BlockID, 0);
+
+ Cache = _CacheInsert(idx, block, false);
+ } else {
+ return false;
+ }
+
+ return Cache != NULL;
+}
+
+inline void CBlockManager::_UpdateBlock(uint32_t BlockID, TCacheEntry * CacheEntry, uint32_t Addr)
+{
+ CacheEntry->KeepInCache = m_ReadOnly;
+
+ if (!CacheEntry->Forced)
+ {
+ if (!m_ReadOnly)
+ _PendingAdd(BlockID, Addr, CacheEntry->Cache->Size, CacheEntry);
+ }
+}
+
+
+uint32_t CBlockManager::ScanFile(uint32_t FirstBlockStart, uint32_t HeaderSignature, uint32_t FileSize)
+{
+ TBlockHeadOcc h, lasth = {0, 0, 0};
+ uint32_t p;
+ uint32_t res = 0;
+ bool invalidateblock = false;
+
+ p = FirstBlockStart;
+ m_FirstBlockStart = FirstBlockStart;
+ m_Optimize.Source = 0;
+ m_Optimize.Dest = 0;
+
+ { // insert header cache element
+ void * header = malloc(FirstBlockStart);
+ m_FileAccess.Read(header, 0, FirstBlockStart);
+ _CacheInsert(0, (TBlockHeadOcc*)header, false);
+ }
+
+ TransactionBeginWrite();
+
+ while (p < FileSize)
+ {
+ m_FileAccess.Read(&h, p, sizeof(h));
+ if (CLogger::Instance().Level() >= CLogger::logERROR || !h.Size)
+ {
+ LOG(logCRITICAL, _T("Block-structure of file is corrupt!"));
+ return 0;
+ }
+
+ if (h.ID == cFreeBlockID)
+ {
+ if (m_Optimize.Dest == 0)
+ m_Optimize.Dest = p;
+
+ if (lasth.ID == cFreeBlockID)
+ {
+ lasth.Size += h.Size;
+ invalidateblock = true;
+ } else {
+ lasth = h;
+ }
+
+ } else {
+
+ if (lasth.ID == cFreeBlockID)
+ {
+ if (m_Optimize.Source == 0)
+ m_Optimize.Source = p;
+
+ _InsertFreeBlock(p - lasth.Size, lasth.Size, invalidateblock, true);
+ }
+ lasth = h;
+ invalidateblock = false;
+
+ while ((h.ID >> 2) >= m_BlockTable.size())
+ m_BlockTable.resize(m_BlockTable.size() << 1);
+
+ m_BlockTable[h.ID >> 2].Addr = p >> 2;
+
+ if (h.Signature == HeaderSignature)
+ res = h.ID;
+ }
+
+ p = p + h.Size;
+ }
+
+ m_FirstFreeIndex = 0;
+ for (uint32_t i = static_cast<uint32_t>(m_BlockTable.size() - 1); i > 0; --i)
+ {
+ if (m_BlockTable[i].Addr == 0)
+ {
+ TBlockTableEntry b = {true, true, m_FirstFreeIndex};
+ m_BlockTable[i] = b;
+ m_FirstFreeIndex = i;
+ }
+ }
+
+ TransactionEndWrite();
+
+ if (m_Optimize.Source && !m_FileAccess.ReadOnly())
+ {
+ m_Optimize.Thread = new COptimizeThread(*this);
+ m_Optimize.Thread->Priority(CThread::tpLowest);
+ m_Optimize.Thread->FreeOnTerminate(true);
+ m_Optimize.Thread->Resume();
+ }
+
+ return res;
+}
+
+void * CBlockManager::_CreateBlock(uint32_t & BlockID, const uint32_t Signature, uint32_t Size)
+{
+ uint32_t idx = _GetAvailableIndex();
+ BlockID = idx << 2;
+
+ Size = m_EncryptionManager.AlignSize(BlockID, (Size + 3) & 0xfffffffc); // align on cipher after we aligned on 4 bytes
+
+ TBlockHeadOcc h = {BlockID, Size + sizeof(TBlockHeadOcc) + sizeof(TBlockTailOcc), Signature};
+ TBlockTailOcc t = {BlockID};
+
+ TBlockHeadOcc * block = (TBlockHeadOcc*) malloc(Size + sizeof(h) + sizeof(t));
+ *block = h;
+ memset(block + 1, 0, Size);
+ *(TBlockTailOcc*)(((uint8_t*)(block + 1)) + Size) = t;
+
+ TCacheEntry * ce = _CacheInsert(idx, block, false);
+
+ if (m_ReadOnly)
+ {
+ TBlockTableEntry b = {false, true, 0};
+ m_BlockTable[idx] = b;
+ } else {
+ uint32_t addr = _FindFreePosition(Size + sizeof(h) + sizeof(t));
+ TBlockTableEntry b = {false, true, addr >> 2 };
+ m_BlockTable[idx] = b;
+
+ _UpdateBlock(BlockID, ce, addr);
+ }
+
+ return ce->Cache + 1;
+}
+
+void * CBlockManager::_CreateBlockVirtual(uint32_t & BlockID, const uint32_t Signature, uint32_t Size)
+{
+ uint32_t idx = _GetAvailableIndex();
+ BlockID = idx << 2;
+
+ Size = m_EncryptionManager.AlignSize(BlockID, (Size + 3) & 0xfffffffc); // align on cipher after we aligned on 4 bytes
+
+ TBlockHeadOcc h = {BlockID, Size + sizeof(TBlockHeadOcc) + sizeof(TBlockTailOcc), Signature};
+ TBlockTailOcc t = {BlockID};
+
+ TBlockHeadOcc * block = (TBlockHeadOcc*) malloc(Size + sizeof(h) + sizeof(t));
+ *block = h;
+ memset(block + 1, 0, Size);
+ *(TBlockTailOcc*)(((uint8_t*)(block + 1)) + Size) = t;
+
+ return _CacheInsert(idx, block, true)->Cache + 1;
+}
+
+bool CBlockManager::DeleteBlock(uint32_t BlockID)
+{
+ uint32_t idx = BlockID >> 2;
+ uint32_t addr;
+ uint32_t size;
+ TCacheEntry * ce;
+ if (!_InitOperation(BlockID, addr, ce))
+ return false;
+
+ if (!ce->Forced)
+ XADD_32(m_CacheInfo.Size, 0 - ce->Cache->Size);
+
+ if (ce->Pending)
+ _PendingRemove(ce->Pending, true);
+
+ size = ce->Cache->Size;
+ _CacheErase(idx);
+
+ if (addr == 0) // Block in memory only
+ {
+ TBlockTableEntry b = {false, false, 0};
+ m_BlockTable[idx] = b;
+
+ } else if (m_ReadOnly)
+ {
+ m_BlockTable[idx].Deleted = true;
+ m_BlockTable[idx].InCache = false;
+ } else {
+ _InsertFreeBlock(addr, size, true, true);
+
+ TBlockTableEntry b = {false, false, 0};
+ m_BlockTable[idx] = b;
+ }
+
+ return true;
+}
+
+uint32_t CBlockManager::_ResizeBlock(uint32_t BlockID, void * & Buffer, uint32_t Size)
+{
+ uint32_t idx = BlockID >> 2;
+ uint32_t addr;
+ TCacheEntry * ce;
+
+ if (Size == 0)
+ return 0;
+
+ if (!_InitOperation(BlockID, addr, ce))
+ return 0;
+
+ Size = m_EncryptionManager.AlignSize(BlockID, (Size + 3) & 0xfffffffc); // align on cipher after we aligned on 4 bytes
+
+ uint32_t os = ce->Cache->Size;
+ uint32_t ns = Size + sizeof(TBlockHeadOcc) + sizeof(TBlockTailOcc);
+ if (ns == ce->Cache->Size)
+ {
+ Buffer = ce->Cache + 1;
+ return Size;
+ }
+
+ ce->Cache = (TBlockHeadOcc*) realloc(ce->Cache, ns);
+ ce->Cache->Size = ns;
+ TBlockTailOcc t = {BlockID};
+ *(TBlockTailOcc*)(((uint8_t*)(ce->Cache + 1)) + Size) = t;
+ XADD_32(m_CacheInfo.Size, ns - os);
+
+ Buffer = ce->Cache + 1;
+ ce->KeepInCache = m_ReadOnly;
+
+ if (!m_ReadOnly && addr)
+ {
+ _InsertFreeBlock(addr, os, true, true);
+ addr = _FindFreePosition(ns);
+ m_BlockTable[idx].Addr = addr >> 2;
+
+ _UpdateBlock(BlockID, ce, addr); // write down
+ }
+
+ return Size;
+}
+
+bool CBlockManager::IsForcedVirtual(uint32_t BlockID)
+{
+ TCacheEntry * ce = _CacheFind(BlockID >> 2);
+ return ce && ce->Forced;
+}
+
+bool CBlockManager::WriteBlockToDisk(uint32_t BlockID)
+{
+ uint32_t addr;
+ TCacheEntry * ce;
+
+ if (!_InitOperation(BlockID, addr, ce))
+ return false;
+
+ if (!ce->Forced)
+ return true;
+
+ ce->Forced = false;
+ XADD_32(m_CacheInfo.Size, ce->Cache->Size);
+
+ if (!m_ReadOnly)
+ {
+ addr = _FindFreePosition(ce->Cache->Size);
+ m_BlockTable[BlockID >> 2].Addr = addr >> 2;
+ _UpdateBlock(BlockID, ce, addr);
+ }
+ return true;
+}
+
+bool CBlockManager::MakeBlockVirtual(uint32_t BlockID)
+{
+ uint32_t addr;
+ TCacheEntry * ce;
+
+ if (!_InitOperation(BlockID, addr, ce))
+ return false;
+
+ if (ce->Forced)
+ return true;
+
+ if (ce->Pending) // don't write down, we kill it anyway
+ _PendingRemove(ce->Pending, true);
+
+ ce->Forced = true;
+ XADD_32(m_CacheInfo.Size, 0 - ce->Cache->Size);
+
+ if (!m_ReadOnly)
+ {
+ _InsertFreeBlock(addr, ce->Cache->Size, true, true);
+ m_BlockTable[BlockID >> 2].Addr = 0;
+ }
+ return true;
+}
+
+void * CBlockManager::_ReadBlock(uint32_t BlockID, uint32_t & Size, uint32_t & Signature)
+{
+ uint32_t addr;
+ TCacheEntry * ce;
+
+ if ((BlockID == 0) && (Signature == -1))
+ {
+ Size = m_FirstBlockStart;
+ return m_Cache[0]->Cache;
+ }
+
+ if (!_InitOperation(BlockID, addr, ce))
+ return NULL;
+
+ if ((Signature != 0) && (Signature != ce->Cache->Signature))
+ {
+ Signature = ce->Cache->Signature;
+ return NULL;
+ }
+ Signature = ce->Cache->Signature;
+
+ if ((Size != 0) && (Size != ce->Cache->Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc)))
+ {
+ Size = ce->Cache->Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc);
+ return NULL;
+ }
+ Size = ce->Cache->Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc);
+
+ return ce->Cache + 1;
+}
+
+bool CBlockManager::UpdateBlock(uint32_t BlockID, uint32_t Signature)
+{
+ uint32_t addr;
+ TCacheEntry * ce;
+
+ if ((BlockID == 0) && (Signature == -1))
+ {
+ if (!m_ReadOnly)
+ _PendingAdd(0, 0, m_FirstBlockStart, m_Cache[0]);
+
+ return true;
+ }
+
+ if (!_InitOperation(BlockID, addr, ce))
+ return false;
+
+ if (Signature)
+ ce->Cache->Signature = Signature;
+
+ _UpdateBlock(BlockID, ce, addr);
+
+ return true;
+}
+
+// make file writeable:
+// write all cached blocks to file and check for the old addresses
+// remove virtual only from file
+// update m_FreeBlocks along the way
+
diff --git a/dbx_tree/BlockManager.h b/dbx_tree/BlockManager.h new file mode 100644 index 0000000..dcccd4f --- /dev/null +++ b/dbx_tree/BlockManager.h @@ -0,0 +1,401 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include <windows.h>
+#include <map>
+#include <vector>
+
+#include "stdint.h"
+#include "FileAccess.h"
+#include "EncryptionManager.h"
+#include "MREWSync.h"
+#include "Thread.h"
+#include "intrinsics.h"
+
+class CBlockManager
+{
+protected:
+ static const uint32_t cFreeBlockID = 0xFFFFFFFF;
+
+ static const uint32_t cJournalFlushBytes = (1 << 20) - 2048; // flush before reserved journal-space is exhausted
+ static const uint32_t cJournalFlushTimeout = 300; // journal flush every 5 minutes
+
+ static const uint32_t cCacheBuddyBits = 10;
+ static const uint32_t cCacheBuddyCount = 1 << cCacheBuddyBits; // count of static allocated buddy nodes
+ static const uint32_t cCacheBuddyCheck = 0xffffffff << cCacheBuddyBits;
+
+ static const uint32_t cCacheMinimumTimeout = 2; // purge less than every n seconds (high priority)
+ static const uint32_t cCacheMaximumTimeout = 600; // purge every 10 minutes (high priority)
+ static const uint32_t cCachePurgeSize = 1 << 21; // cache up to 2MB
+ static const uint32_t cCacheMinimumGrowthForPurge = 1 << 19; // cache only when 512kb were added
+
+ #pragma pack(push, 1) // push current alignment to stack, set alignment to 1 byte boundary
+
+ typedef struct TBlockHeadFree {
+ uint32_t ID;
+ uint32_t Size;
+ } TBlockHeadFree;
+ typedef struct TBlockHeadOcc {
+ uint32_t ID;
+ uint32_t Size;
+ uint32_t Signature; /// if occupied block
+ } TBlockHeadOcc;
+
+ typedef struct TBlockTailOcc {
+ uint32_t ID;
+ } TBlockTailOcc;
+
+ typedef struct TBlockTailFree {
+ uint32_t Size; /// if free block
+ uint32_t ID;
+ } TBlockTailFree;
+
+ #pragma pack(pop)
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ /// <summary> Block table entry. </summary>
+ ///
+ /// Addr Deleted InCache Meaning
+ /// 0 0 0 successfully deleted block
+ /// 0 0 1 virtual only block (either forced virtual or created on a read-only file)
+ /// 0 1 0 invalid
+ /// 0 1 1 FreeID list (last entry)
+ /// set 0 0 Normal in-file block
+ /// set 0 1 in file and cache (normal cache which could differ on a read-only file or forced virtual out of a read-only file - check TCacheEntry)
+ /// set 1 0 deleted block or a read-only file
+ /// set 1 1 FreeID list entry
+ ///
+ /// <remarks> Michael "Protogenes" Kunz, 07.09.2010. </remarks>
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ typedef struct TBlockTableEntry {
+ uint32_t Deleted : 1; ///< Flag is set if the block was deleted but can't be removed, because the file is read-only
+ uint32_t InCache : 1; ///< Flag is set if block is in the cache (either forced virtual or from the file)
+ uint32_t Addr : 30; ///< The Offset in the file div 4, so we can address files up to 4GB
+ } TBlockTableEntry;
+ std::vector<TBlockTableEntry> m_BlockTable;
+
+ struct TPendingOperation;
+ typedef struct TCacheEntry {
+ TCacheEntry * volatile Next;
+ TBlockHeadOcc * volatile Cache;
+ TPendingOperation * Pending;
+
+ uint32_t Idx;
+ uint32_t Forced : 1;
+ uint32_t KeepInCache : 1;
+ uint32_t LastUse : 30;
+ } TCacheEntry;
+
+ TCacheEntry * m_Cache[cCacheBuddyCount];
+
+ struct {
+ uint32_t volatile Size;
+ uint32_t volatile Growth;
+ uint32_t volatile LastPurge;
+ } m_CacheInfo;
+
+ CFileAccess & m_FileAccess;
+ CEncryptionManager & m_EncryptionManager;
+ CMultiReadExclusiveWriteSynchronizer m_BlockSync;
+
+ uint32_t m_FirstBlockStart;
+ bool m_SaveMode;
+ bool m_ReadOnly;
+
+ typedef std::multimap<uint32_t, uint32_t> TFreeBlockMap;
+ TFreeBlockMap m_FreeBlocks;
+ uint32_t m_FirstFreeIndex;
+
+ static const uint32_t cPendingInvalidate = 0x00000001;
+ typedef struct TPendingOperation {
+ TPendingOperation * Next; ///< The next
+ TPendingOperation * Prev; ///< The previous
+ uint32_t BlockID; ///< Identifier for the block
+ uint32_t Addr; ///< The address in the file
+ uint32_t Size; ///< The size of the block
+ TCacheEntry * CacheEntry; ///< The cache entry
+ TBlockHeadOcc * EncryptionBuffer; ///< Buffer for encrypted block
+ } TPendingOperation;
+
+ TPendingOperation * m_PendingHead; ///< The double linked list head
+ TPendingOperation * m_PendingTail; ///< The double linked list tail
+ TPendingOperation * m_PendingLast; ///< The last processed item
+
+ uint32_t m_LastFlush; ///< The last flush timestamp
+ uint32_t m_BytesPending; ///< The bytes pending for write
+
+ class COptimizeThread : public CThread
+ {
+ protected:
+ CBlockManager & m_Owner;
+ void Execute() { m_Owner.ExecuteOptimize(); };
+ public:
+ COptimizeThread(CBlockManager & Owner) : CThread(true), m_Owner(Owner) {};
+ ~COptimizeThread() {};
+ };
+
+ struct {
+ uint32_t Source;
+ uint32_t Dest;
+ COptimizeThread * Thread;
+ } m_Optimize;
+ void ExecuteOptimize();
+
+ uint32_t _GetAvailableIndex();
+ void _InsertFreeBlock(uint32_t Addr, uint32_t Size, bool InvalidateData, bool Reuse);
+ void _RemoveFreeBlock(uint32_t Addr, uint32_t Size);
+ uint32_t _FindFreePosition(uint32_t Size);
+
+ bool _InitOperation(uint32_t BlockID, uint32_t & Addr, TCacheEntry * & Cache);
+ void _UpdateBlock(uint32_t BlockID, TCacheEntry * CacheEntry, uint32_t Addr);
+
+ void * _ReadBlock(uint32_t BlockID, uint32_t & Size, uint32_t & Signature);
+ void * _CreateBlock(uint32_t & BlockID, const uint32_t Signature, uint32_t Size);
+ void * _CreateBlockVirtual(uint32_t & BlockID, const uint32_t Signature, uint32_t Size);
+ uint32_t _ResizeBlock(uint32_t BlockID, void * & Buffer, uint32_t Size);
+
+ TCacheEntry * _CacheInsert(uint32_t Idx, TBlockHeadOcc * Cache, bool Virtual);
+ TCacheEntry * _CacheFind(uint32_t Idx);
+ void _CacheErase(uint32_t Idx);
+
+ void _CachePurge();
+ void _PendingAdd(uint32_t BlockID, uint32_t Addr, uint32_t Size, TCacheEntry * Cache);
+ void _PendingRemove(TPendingOperation * Pending, bool Free);
+ void _PendingFlush(bool FullFlush);
+
+
+
+ void TransactionBeginRead()
+ {
+ m_BlockSync.BeginRead();
+ };
+
+ void TransactionEndRead()
+ {
+ m_BlockSync.EndRead();
+ };
+
+ void TransactionBeginWrite()
+ {
+ m_BlockSync.BeginWrite();
+ m_FileAccess.UseJournal(m_SaveMode);
+ };
+
+ void TransactionEndWrite()
+ {
+ if (m_BlockSync.WriteRecursionCount() == 1)
+ {
+ m_FileAccess.CompleteTransaction();
+ m_BytesPending += 12;
+
+ if ((m_CacheInfo.LastPurge + cCacheMaximumTimeout < time(NULL))
+ || ((m_CacheInfo.Size + m_CacheInfo.Growth > cCachePurgeSize)
+ && (m_CacheInfo.Growth > cCacheMinimumGrowthForPurge)
+ && (m_CacheInfo.LastPurge + cCacheMinimumTimeout < time(NULL))))
+ {
+ _CachePurge();
+ } else if ((m_BytesPending >= cJournalFlushBytes) || (time(NULL) > m_LastFlush + cJournalFlushTimeout))
+ {
+ _PendingFlush(true);
+ } else {
+ _PendingFlush(false);
+ }
+ }
+
+ m_BlockSync.EndWrite();
+ };
+public:
+ CBlockManager(CFileAccess & FileAccess, CEncryptionManager & EncryptionManager);
+ ~CBlockManager();
+
+
+ class ReadTransaction
+ {
+ private:
+ CBlockManager * m_Owner;
+ uint32_t volatile * m_RefCount;
+ bool m_Closed;
+ public:
+ ReadTransaction()
+ : m_Owner(NULL),
+ m_RefCount(NULL),
+ m_Closed(true)
+ {
+
+ };
+ ReadTransaction(CBlockManager & BlockManager)
+ : m_Owner(&BlockManager),
+ m_RefCount(new uint32_t(1)),
+ m_Closed(false)
+ {
+ m_Owner->TransactionBeginRead();
+ };
+ ReadTransaction(const ReadTransaction & Other)
+ : m_Owner(Other.m_Owner),
+ m_RefCount(Other.m_RefCount),
+ m_Closed(Other.m_Closed)
+ {
+ if (!m_Closed)
+ INC_32(*m_RefCount);
+ };
+ ~ReadTransaction()
+ {
+ if (!m_Closed && (DEC_32(*m_RefCount) == 0))
+ {
+ delete m_RefCount;
+ m_Owner->TransactionEndRead();
+ }
+ };
+
+ ReadTransaction & operator =(const ReadTransaction & Other)
+ {
+ if (!m_Closed && (DEC_32(*m_RefCount) == 0))
+ {
+ delete m_RefCount;
+ m_Owner->TransactionEndRead();
+ }
+
+ m_Owner = Other.m_Owner;
+ m_RefCount = Other.m_RefCount;
+ m_Closed = Other.m_Closed;
+ if (!m_Closed)
+ INC_32(*m_RefCount);
+
+ return *this;
+ }
+
+ void Close()
+ {
+ if (!m_Closed && (DEC_32(*m_RefCount) == 0))
+ {
+ delete m_RefCount;
+ m_Owner->TransactionEndRead();
+ }
+ m_Closed = true;
+ }
+
+ };
+ class WriteTransaction
+ {
+ private:
+ CBlockManager * m_Owner;
+ uint32_t volatile * m_RefCount;
+ bool m_Closed;
+ public:
+ WriteTransaction()
+ : m_Owner(NULL),
+ m_RefCount(NULL),
+ m_Closed(true)
+ {
+
+ };
+ WriteTransaction(CBlockManager & BlockManager)
+ : m_Owner(&BlockManager),
+ m_RefCount(new uint32_t(1)),
+ m_Closed(false)
+ {
+ m_Owner->TransactionBeginWrite();
+ };
+ WriteTransaction(const WriteTransaction & Other)
+ : m_Owner(Other.m_Owner),
+ m_RefCount(Other.m_RefCount),
+ m_Closed(Other.m_Closed)
+ {
+ if (!m_Closed)
+ INC_32(*m_RefCount);
+ };
+ ~WriteTransaction()
+ {
+ if (!m_Closed && (DEC_32(*m_RefCount) == 0))
+ {
+ delete m_RefCount;
+ m_Owner->TransactionEndWrite();
+ }
+ };
+
+ WriteTransaction & operator =(const WriteTransaction & Other)
+ {
+ if (!m_Closed && (DEC_32(*m_RefCount) == 0))
+ {
+ delete m_RefCount;
+ m_Owner->TransactionEndWrite();
+ }
+
+ m_Owner = Other.m_Owner;
+ m_RefCount = Other.m_RefCount;
+ m_Closed = Other.m_Closed;
+ if (!m_Closed)
+ INC_32(*m_RefCount);
+
+ return *this;
+ }
+
+ void Close()
+ {
+ if (!m_Closed && (DEC_32(*m_RefCount) == 0))
+ {
+ delete m_RefCount;
+ m_Owner->TransactionEndWrite();
+ }
+ m_Closed = true;
+ }
+
+ };
+
+ uint32_t ScanFile(uint32_t FirstBlockStart, uint32_t HeaderSignature, uint32_t FileSize);
+
+ template <typename BlockType>
+ BlockType * ReadBlock(uint32_t BlockID, uint32_t & Size, uint32_t & Signature)
+ {
+ return reinterpret_cast<BlockType*>(_ReadBlock(BlockID, Size, Signature));
+ };
+
+ template <typename BlockType>
+ BlockType * CreateBlock(uint32_t & BlockID, const uint32_t Signature, uint32_t Size = sizeof(BlockType))
+ {
+ return reinterpret_cast<BlockType*>(_CreateBlock(BlockID, Signature, Size));
+ };
+
+ template <typename BlockType>
+ BlockType * CreateBlockVirtual(uint32_t & BlockID, const uint32_t Signature, uint32_t Size = sizeof(BlockType))
+ {
+ return reinterpret_cast<BlockType*>(_CreateBlockVirtual(BlockID, Signature, Size));
+ };
+
+ template <typename BlockType>
+ uint32_t ResizeBlock(uint32_t BlockID, BlockType * & Buffer, uint32_t Size)
+ {
+ void * tmp = Buffer;
+ uint32_t res = _ResizeBlock(BlockID, tmp, Size);
+ Buffer = reinterpret_cast<BlockType*>(tmp);
+ return res;
+ };
+
+ bool UpdateBlock(uint32_t BlockID, uint32_t Signature = 0);
+ bool DeleteBlock(uint32_t BlockID);
+
+ bool IsForcedVirtual(uint32_t BlockID);
+ bool WriteBlockToDisk(uint32_t BlockID);
+ bool MakeBlockVirtual(uint32_t BlockID);
+};
diff --git a/dbx_tree/Compatibility.cpp b/dbx_tree/Compatibility.cpp new file mode 100644 index 0000000..38b8f92 --- /dev/null +++ b/dbx_tree/Compatibility.cpp @@ -0,0 +1,866 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "Compatibility.h"
+#include "Logger.h"
+#define DB_NOHELPERFUNCTIONS
+ #include "m_database.h"
+#undef DB_NOHELPERFUNCTIONS
+#ifndef _MSC_VER
+#include "savestrings_gcc.h"
+#endif
+
+HANDLE gCompServices[31] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+HANDLE gEvents[6] = {0,0,0,0,0,0};
+
+HANDLE hEventDeletedEvent,
+ hEventAddedEvent,
+ hEventFilterAddedEvent,
+ hSettingChangeEvent,
+ hContactDeletedEvent,
+ hContactAddedEvent;
+
+INT_PTR CompAddContact(WPARAM wParam, LPARAM lParam)
+{
+ TDBTEntity entity = {0,0,0,0};
+ entity.hParentEntity = DBEntityGetRoot(0, 0);
+ entity.hAccountEntity = entity.hParentEntity;
+
+ TDBTEntityHandle res = gDataBase->getEntities().CreateEntity(entity);
+ if (res == DBT_INVALIDPARAM)
+ return 1;
+
+ NotifyEventHooks(hContactAddedEvent, res, 0);
+ return res;
+}
+INT_PTR CompDeleteContact(WPARAM hContact, LPARAM lParam)
+{
+ NotifyEventHooks(hContactDeletedEvent, hContact, 0);
+
+ int res = DBEntityDelete(hContact, 0);
+ if (res == DBT_INVALIDPARAM)
+ return 1;
+
+ return res;
+}
+INT_PTR CompIsDbContact(WPARAM hContact, LPARAM lParam)
+{
+ int flags = DBEntityGetFlags(hContact, 0);
+ return (flags != DBT_INVALIDPARAM) &&
+ ((flags & DBT_NFM_SpecialEntity) == 0);
+}
+INT_PTR CompGetContactCount(WPARAM wParam, LPARAM lParam)
+{
+ TDBTEntityIterFilter f = {0,0,0,0};
+ f.cbSize = sizeof(f);
+ f.fDontHasFlags = DBT_NF_IsGroup | DBT_NF_IsVirtual | DBT_NF_IsAccount | DBT_NF_IsRoot;
+ f.Options = DBT_NIFO_OSC_AC | DBT_NIFO_OC_AC;
+
+ TDBTEntityIterationHandle hiter = DBEntityIterInit((WPARAM)&f, gDataBase->getEntities().getRootEntity());
+ int c = 0;
+ if ((hiter != 0) && (hiter != DBT_INVALIDPARAM))
+ {
+ TDBTEntityHandle con = DBEntityIterNext(hiter, 0);
+
+ while ((con != DBT_INVALIDPARAM) && (con != 0))
+ {
+ if ((con != 0) && (con != DBT_INVALIDPARAM))
+ c++;
+
+ con = DBEntityIterNext(hiter, 0);
+ }
+ DBEntityIterClose(hiter, 0);
+ }
+ return c;
+}
+INT_PTR CompFindFirstContact(WPARAM wParam, LPARAM lParam)
+{
+ return gDataBase->getEntities().compFirstContact();
+}
+INT_PTR CompFindNextContact(WPARAM hContact, LPARAM lParam)
+{
+ return gDataBase->getEntities().compNextContact(hContact);
+}
+
+INT_PTR CompGetContactSetting(WPARAM hContact, LPARAM pSetting)
+{
+ DBCONTACTGETSETTING * dbcgs = reinterpret_cast<DBCONTACTGETSETTING *>(pSetting);
+ dbcgs->pValue->type = 0;
+
+ char namebuf[512];
+ namebuf[0] = 0;
+
+ if (!(dbcgs->szModule || dbcgs->szSetting))
+ return -1;
+
+ if (dbcgs->szModule)
+ strcpy_s(namebuf, dbcgs->szModule);
+ strcat_s(namebuf, "/");
+ if (dbcgs->szSetting)
+ strcat_s(namebuf, dbcgs->szSetting);
+
+ TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0};
+ TDBTSetting set = {0,0,0,0};
+ desc.cbSize = sizeof(desc);
+ desc.Entity = hContact;
+ desc.pszSettingName = namebuf;
+
+ set.cbSize = sizeof(set);
+ set.Descriptor = &desc;
+
+ if (DBSettingRead(reinterpret_cast<WPARAM>(&set), 0) == DBT_INVALIDPARAM)
+ return -1;
+
+ switch (set.Type)
+ {
+ case DBT_ST_ANSI:
+ {
+ dbcgs->pValue->type = DBVT_ASCIIZ;
+ dbcgs->pValue->pszVal = set.Value.pAnsi;
+ dbcgs->pValue->cchVal = set.Value.Length - 1;
+ } break;
+ case DBT_ST_UTF8:
+ {
+ dbcgs->pValue->type = DBVT_WCHAR;
+ dbcgs->pValue->pwszVal = mir_utf8decodeW(set.Value.pUTF8);
+ if (dbcgs->pValue->pwszVal)
+ dbcgs->pValue->cchVal = static_cast<uint32_t>(wcslen(dbcgs->pValue->pwszVal));
+ else
+ dbcgs->pValue->cchVal = 0;
+ mir_free(set.Value.pUTF8);
+ } break;
+ case DBT_ST_WCHAR:
+ {
+ dbcgs->pValue->type = DBVT_WCHAR;
+ dbcgs->pValue->pwszVal = set.Value.pWide;
+ dbcgs->pValue->cchVal = set.Value.Length - 1;
+ } break;
+ case DBT_ST_BLOB:
+ {
+ dbcgs->pValue->type = DBVT_BLOB;
+ dbcgs->pValue->pbVal = set.Value.pBlob;
+ dbcgs->pValue->cpbVal = set.Value.Length;
+ } break;
+ case DBT_ST_BOOL:
+ {
+ dbcgs->pValue->type = DBVT_BYTE;
+ dbcgs->pValue->bVal = (uint8_t)set.Value.Bool;
+ } break;
+ case DBT_ST_BYTE: case DBT_ST_CHAR:
+ {
+ dbcgs->pValue->type = DBVT_BYTE;
+ dbcgs->pValue->bVal = set.Value.Byte;
+ } break;
+ case DBT_ST_SHORT: case DBT_ST_WORD:
+ {
+ dbcgs->pValue->type = DBVT_WORD;
+ dbcgs->pValue->wVal = set.Value.Word;
+ } break;
+ case DBT_ST_INT: case DBT_ST_DWORD:
+ {
+ dbcgs->pValue->type = DBVT_DWORD;
+ dbcgs->pValue->dVal = set.Value.DWord;
+ } break;
+ case DBT_ST_INT64: case DBT_ST_QWORD:
+ case DBT_ST_DOUBLE: case DBT_ST_FLOAT:
+ {
+ dbcgs->pValue->type = DBVT_BLOB;
+ dbcgs->pValue->cpbVal = sizeof(set.Value);
+ dbcgs->pValue->pbVal = reinterpret_cast<BYTE*>(mir_alloc(sizeof(set.Value)));
+ memcpy(dbcgs->pValue->pbVal, &set.Value, sizeof(set.Value));
+ } break;
+ default:
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+INT_PTR CompGetContactSettingStr(WPARAM hContact, LPARAM pSetting)
+{
+ DBCONTACTGETSETTING * dbcgs = reinterpret_cast<DBCONTACTGETSETTING *>(pSetting);
+
+ if ((dbcgs->pValue->type & DBVTF_VARIABLELENGTH) == 0)
+ {
+ CompFreeVariant(0, reinterpret_cast<LPARAM>(dbcgs->pValue));
+ dbcgs->pValue->type = 0;
+ }
+
+ char namebuf[512];
+ namebuf[0] = 0;
+ if (dbcgs->szModule)
+ strcpy_s(namebuf, dbcgs->szModule);
+ strcat_s(namebuf, "/");
+ if (dbcgs->szSetting)
+ strcat_s(namebuf, dbcgs->szSetting);
+
+ TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0};
+ TDBTSetting set = {0,0,0,0};
+ desc.cbSize = sizeof(desc);
+ desc.Entity = hContact;
+ desc.pszSettingName = namebuf;
+
+ set.cbSize = sizeof(set);
+ set.Descriptor = &desc;
+
+
+ switch (dbcgs->pValue->type)
+ {
+ case DBVT_ASCIIZ: set.Type = DBT_ST_ANSI; break;
+ case DBVT_BLOB: set.Type = DBT_ST_BLOB; break;
+ case DBVT_UTF8: set.Type = DBT_ST_UTF8; break;
+ case DBVT_WCHAR: set.Type = DBT_ST_WCHAR; break;
+ }
+
+ if (DBSettingRead(reinterpret_cast<WPARAM>(&set), 0) == DBT_INVALIDPARAM)
+ return -1;
+
+ switch (set.Type)
+ {
+ case DBT_ST_ANSI:
+ {
+ dbcgs->pValue->type = DBVT_ASCIIZ;
+ dbcgs->pValue->pszVal = set.Value.pAnsi;
+ dbcgs->pValue->cchVal = set.Value.Length - 1;
+ } break;
+ case DBT_ST_UTF8:
+ {
+ dbcgs->pValue->type = DBVT_UTF8;
+ dbcgs->pValue->pszVal = set.Value.pUTF8;
+ dbcgs->pValue->cchVal = set.Value.Length - 1;
+ } break;
+ case DBT_ST_WCHAR:
+ {
+ if (dbcgs->pValue->type == DBVT_WCHAR)
+ {
+ dbcgs->pValue->pwszVal = set.Value.pWide;
+ dbcgs->pValue->cchVal = set.Value.Length - 1;
+ } else {
+ dbcgs->pValue->type = DBVT_UTF8;
+ dbcgs->pValue->pszVal = mir_utf8encodeW(set.Value.pWide);
+ dbcgs->pValue->cchVal = static_cast<uint32_t>(strlen(dbcgs->pValue->pszVal));
+ mir_free(set.Value.pWide);
+ }
+ } break;
+ case DBT_ST_BLOB:
+ {
+ dbcgs->pValue->type = DBVT_BLOB;
+ dbcgs->pValue->pbVal = set.Value.pBlob;
+ dbcgs->pValue->cpbVal = set.Value.Length;
+ } break;
+ case DBT_ST_BOOL:
+ {
+ dbcgs->pValue->type = DBVT_BYTE;
+ dbcgs->pValue->bVal = (uint8_t)set.Value.Bool;
+ } break;
+ case DBT_ST_BYTE: case DBT_ST_CHAR:
+ {
+ dbcgs->pValue->type = DBVT_BYTE;
+ dbcgs->pValue->bVal = set.Value.Byte;
+ } break;
+ case DBT_ST_SHORT: case DBT_ST_WORD:
+ {
+ dbcgs->pValue->type = DBVT_WORD;
+ dbcgs->pValue->wVal = set.Value.Word;
+ } break;
+ case DBT_ST_INT: case DBT_ST_DWORD:
+ {
+ dbcgs->pValue->type = DBVT_DWORD;
+ dbcgs->pValue->dVal = set.Value.DWord;
+ } break;
+ case DBT_ST_INT64: case DBT_ST_QWORD:
+ case DBT_ST_DOUBLE: case DBT_ST_FLOAT:
+ {
+ dbcgs->pValue->type = DBVT_BLOB;
+ dbcgs->pValue->cpbVal = sizeof(set.Value);
+ dbcgs->pValue->pbVal = reinterpret_cast<BYTE*>(mir_alloc(sizeof(set.Value)));
+ memcpy(dbcgs->pValue->pbVal, &set.Value, sizeof(set.Value));
+ } break;
+ default:
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+INT_PTR CompGetContactSettingStatic(WPARAM hContact, LPARAM pSetting)
+{
+ DBCONTACTGETSETTING * dbcgs = reinterpret_cast<DBCONTACTGETSETTING *>(pSetting);
+
+ char namebuf[512];
+ namebuf[0] = 0;
+ if (dbcgs->szModule)
+ strcpy_s(namebuf, dbcgs->szModule);
+ strcat_s(namebuf, "/");
+ if (dbcgs->szSetting)
+ strcat_s(namebuf, dbcgs->szSetting);
+
+ TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0};
+ TDBTSetting set = {0,0,0,0};
+ desc.cbSize = sizeof(desc);
+ desc.Entity = hContact;
+ desc.pszSettingName = namebuf;
+
+ set.cbSize = sizeof(set);
+ set.Descriptor = &desc;
+
+ if (DBSettingRead(reinterpret_cast<WPARAM>(&set), 0) == DBT_INVALIDPARAM)
+ return -1;
+
+ if ((set.Type & DBT_STF_VariableLength) ^ (dbcgs->pValue->type & DBVTF_VARIABLELENGTH))
+ {
+ if (set.Type & DBT_STF_VariableLength)
+ mir_free(set.Value.pBlob);
+ return -1;
+ }
+
+ switch (set.Type)
+ {
+ case DBT_ST_ANSI:
+ {
+ if (dbcgs->pValue->cchVal < set.Value.Length)
+ {
+ memcpy(dbcgs->pValue->pszVal, set.Value.pAnsi, dbcgs->pValue->cchVal);
+ dbcgs->pValue->pszVal[dbcgs->pValue->cchVal - 1] = 0;
+ } else {
+ memcpy(dbcgs->pValue->pszVal, set.Value.pAnsi, set.Value.Length);
+ }
+ dbcgs->pValue->type = DBVT_ASCIIZ;
+ dbcgs->pValue->cchVal = set.Value.Length - 1;
+
+ mir_free(set.Value.pAnsi);
+ } break;
+ case DBT_ST_UTF8:
+ {
+ set.Value.pUTF8 = mir_utf8decode(set.Value.pUTF8, NULL);
+ set.Value.Length = static_cast<uint32_t>(strlen(set.Value.pUTF8));
+
+ if (dbcgs->pValue->cchVal < set.Value.Length)
+ {
+ memcpy(dbcgs->pValue->pszVal, set.Value.pUTF8, dbcgs->pValue->cchVal);
+ dbcgs->pValue->pszVal[dbcgs->pValue->cchVal - 1] = 0;
+ } else {
+ memcpy(dbcgs->pValue->pszVal, set.Value.pUTF8, set.Value.Length);
+ }
+ dbcgs->pValue->type = DBVT_ASCIIZ;
+ dbcgs->pValue->cchVal = set.Value.Length - 1;
+
+ mir_free(set.Value.pUTF8);
+ } break;
+ case DBT_ST_WCHAR:
+ {
+ char * tmp = mir_u2a(set.Value.pWide);
+ WORD l = static_cast<WORD>(strlen(tmp));
+ mir_free(set.Value.pWide);
+
+ if (dbcgs->pValue->cchVal < l + 1)
+ {
+ memcpy(dbcgs->pValue->pszVal, tmp, dbcgs->pValue->cchVal);
+ dbcgs->pValue->pszVal[l] = 0;
+ } else {
+ memcpy(dbcgs->pValue->pszVal, tmp, l + 1);
+ }
+ dbcgs->pValue->type = DBVT_ASCIIZ;
+ dbcgs->pValue->cchVal = l;
+
+ mir_free(tmp);
+ } break;
+ case DBT_ST_BLOB:
+ {
+ if (dbcgs->pValue->cchVal < set.Value.Length)
+ {
+ memcpy(dbcgs->pValue->pbVal, set.Value.pBlob, dbcgs->pValue->cchVal);
+ } else {
+ memcpy(dbcgs->pValue->pbVal, set.Value.pBlob, set.Value.Length);
+ }
+ dbcgs->pValue->type = DBVT_BLOB;
+ dbcgs->pValue->cchVal = set.Value.Length;
+
+ mir_free(set.Value.pBlob);
+ } break;
+ case DBT_ST_BOOL:
+ {
+ dbcgs->pValue->type = DBVT_BYTE;
+ dbcgs->pValue->bVal = set.Value.Bool ? TRUE : FALSE;
+ } break;
+ case DBT_ST_BYTE: case DBT_ST_CHAR:
+ {
+ dbcgs->pValue->type = DBVT_BYTE;
+ dbcgs->pValue->bVal = set.Value.Byte;
+ } break;
+ case DBT_ST_SHORT: case DBT_ST_WORD:
+ {
+ dbcgs->pValue->type = DBVT_WORD;
+ dbcgs->pValue->wVal = set.Value.Word;
+ } break;
+ case DBT_ST_INT: case DBT_ST_DWORD:
+ {
+ dbcgs->pValue->type = DBVT_DWORD;
+ dbcgs->pValue->dVal = set.Value.DWord;
+ } break;
+ default:
+ {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+INT_PTR CompFreeVariant(WPARAM wParam, LPARAM pSetting)
+{
+ DBVARIANT * dbv = reinterpret_cast<DBVARIANT *>(pSetting);
+
+ if ((dbv->type == DBVT_BLOB) && (dbv->pbVal))
+ {
+ mir_free(dbv->pbVal);
+ dbv->pbVal = 0;
+ } else if ((dbv->type & DBVTF_VARIABLELENGTH) && (dbv->pszVal))
+ {
+ mir_free(dbv->pszVal);
+ dbv->pszVal = NULL;
+ }
+ dbv->type = 0;
+ return 0;
+}
+INT_PTR CompWriteContactSetting(WPARAM hContact, LPARAM pSetting)
+{
+ DBCONTACTWRITESETTING * dbcws = reinterpret_cast<DBCONTACTWRITESETTING *>(pSetting);
+
+ char namebuf[512];
+ namebuf[0] = 0;
+ if (dbcws->szModule)
+ strcpy_s(namebuf, dbcws->szModule);
+ strcat_s(namebuf, "/");
+ if (dbcws->szSetting)
+ strcat_s(namebuf, dbcws->szSetting);
+
+ TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0};
+ TDBTSetting set = {0,0,0,0};
+ desc.cbSize = sizeof(desc);
+ desc.Entity = hContact;
+ desc.pszSettingName = namebuf;
+
+ set.cbSize = sizeof(set);
+ set.Descriptor = &desc;
+
+ switch (dbcws->value.type)
+ {
+ case DBVT_ASCIIZ:
+ {
+ set.Type = DBT_ST_ANSI;
+ set.Value.pAnsi = dbcws->value.pszVal;
+ } break;
+ case DBVT_UTF8:
+ {
+ wchar_t * tmp = mir_utf8decodeW(dbcws->value.pszVal);
+ if (tmp == 0)
+ {
+ if (IsDebuggerPresent())
+ {
+ DebugBreak();
+#ifdef _DEBUG
+ } else {
+ LOG(logWARNING, _T("Trying to write malformed UTF8 setting \"%hs\" in module \"%hs\""), dbcws->szSetting, dbcws->szModule);
+ CLogger::Instance().ShowMessage();
+#endif
+ }
+ return -1;
+ } else {
+ mir_free(tmp);
+ }
+
+ set.Type = DBT_ST_UTF8;
+ set.Value.pUTF8 = dbcws->value.pszVal;
+ } break;
+ case DBVT_WCHAR:
+ {
+ set.Type = DBT_ST_WCHAR;
+ set.Value.pWide = dbcws->value.pwszVal;
+ } break;
+ case DBVT_BLOB:
+ {
+ set.Type = DBT_ST_BLOB;
+ set.Value.pBlob = dbcws->value.pbVal;
+ set.Value.Length = dbcws->value.cpbVal;
+ } break;
+ case DBVT_BYTE:
+ {
+ set.Type = DBT_ST_BYTE;
+ set.Value.Byte = dbcws->value.bVal;
+ } break;
+ case DBVT_WORD:
+ {
+ set.Type = DBT_ST_WORD;
+ set.Value.Word = dbcws->value.wVal;
+ } break;
+ case DBVT_DWORD:
+ {
+ set.Type = DBT_ST_DWORD;
+ set.Value.DWord = dbcws->value.dVal;
+ } break;
+ default:
+ {
+ return -1;
+ }
+ }
+
+ if (DBSettingWrite(reinterpret_cast<WPARAM>(&set), 0) == DBT_INVALIDPARAM)
+ return -1;
+
+ if (dbcws->value.type == DBVT_WCHAR)
+ {
+ dbcws->value.type = DBVT_UTF8;
+ wchar_t * tmp = dbcws->value.pwszVal;
+ dbcws->value.pszVal = mir_utf8encodeW(dbcws->value.pwszVal);
+ NotifyEventHooks(hSettingChangeEvent, hContact, pSetting);
+ mir_free(dbcws->value.pszVal);
+ dbcws->value.type = DBVT_WCHAR;
+ dbcws->value.pwszVal = tmp;
+ } else {
+ NotifyEventHooks(hSettingChangeEvent, hContact, pSetting);
+ }
+
+ return 0;
+}
+
+INT_PTR CompDeleteContactSetting(WPARAM hContact, LPARAM pSetting)
+{
+ DBCONTACTGETSETTING * dbcgs = reinterpret_cast<DBCONTACTGETSETTING *>(pSetting);
+
+ char namebuf[512];
+ namebuf[0] = 0;
+ if (dbcgs->szModule)
+ strcpy_s(namebuf, dbcgs->szModule);
+ strcat_s(namebuf, "/");
+ if (dbcgs->szSetting)
+ strcat_s(namebuf, dbcgs->szSetting);
+
+ TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0};
+ desc.cbSize = sizeof(desc);
+ desc.Entity = hContact;
+ desc.pszSettingName = namebuf;
+
+ if (DBSettingDelete(reinterpret_cast<WPARAM>(&desc), 0) == DBT_INVALIDPARAM)
+ return -1;
+
+ {
+ DBCONTACTWRITESETTING tmp = {0,0,0,0};
+ tmp.szModule = dbcgs->szModule;
+ tmp.szSetting = dbcgs->szSetting;
+ tmp.value.type = 0;
+ NotifyEventHooks(hSettingChangeEvent, hContact, reinterpret_cast<LPARAM>(&tmp));
+ }
+
+ return 0;
+}
+INT_PTR CompEnumContactSettings(WPARAM hContact, LPARAM pEnum)
+{
+ DBCONTACTENUMSETTINGS * pces = reinterpret_cast<DBCONTACTENUMSETTINGS *>(pEnum);
+
+ TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0};
+ desc.cbSize = sizeof(desc);
+ desc.Entity = hContact;
+
+ char namebuf[512];
+ namebuf[0] = 0;
+ if (pces->szModule)
+ strcpy_s(namebuf, pces->szModule);
+ strcat_s(namebuf, "/");
+
+ TDBTSettingIterFilter filter = {0,0,0,0,0,0,0,0};
+ filter.cbSize = sizeof(filter);
+ filter.Descriptor = &desc;
+ filter.hEntity = hContact;
+ filter.NameStart = namebuf;
+
+ TDBTSettingIterationHandle hiter = DBSettingIterInit(reinterpret_cast<WPARAM>(&filter), 0);
+ if ((hiter == 0) || (hiter == DBT_INVALIDPARAM))
+ return -1;
+
+ int res = 0;
+ TDBTSettingHandle hset = DBSettingIterNext(hiter, 0);
+ while (hset != 0)
+ {
+ char * p = strchr(desc.pszSettingName, '/');
+ if (p) {
+ ++p;
+ } else {
+ p = desc.pszSettingName;
+ }
+
+ res = pces->pfnEnumProc(p, pces->lParam);
+ if (res == 0)
+ {
+ hset = DBSettingIterNext(hiter, 0);
+ } else {
+ hset = 0;
+ }
+ }
+
+ DBSettingIterClose(hiter, 0);
+
+ if (desc.pszSettingName)
+ mir_free(desc.pszSettingName);
+
+ return res;
+}
+
+
+INT_PTR CompGetEventCount(WPARAM hContact, LPARAM lParam)
+{
+ if (hContact == 0)
+ hContact = gDataBase->getEntities().getRootEntity();
+
+ return DBEventGetCount(hContact, 0);
+}
+INT_PTR CompAddEvent(WPARAM hContact, LPARAM pEventInfo)
+{
+ DBEVENTINFO * dbei = reinterpret_cast<DBEVENTINFO*>(pEventInfo);
+ if (dbei->cbSize < sizeof(DBEVENTINFO))
+ return -1;
+
+ int tmp = NotifyEventHooks(hEventFilterAddedEvent, hContact, pEventInfo);
+ if (tmp != 0)
+ return tmp;
+
+ if (hContact == 0)
+ hContact = gDataBase->getEntities().getRootEntity();
+
+
+ TDBTEvent ev = {0,0,0,0,0,0,0};
+ ev.cbSize = sizeof(ev);
+ ev.ModuleName = dbei->szModule;
+ ev.Timestamp = dbei->timestamp;
+ ev.Flags = dbei->flags;
+ if (ev.Flags & DBEF_SENT)
+ ev.Flags = ev.Flags | DBEF_READ;
+ ev.EventType = dbei->eventType;
+ ev.cbBlob = dbei->cbBlob;
+ ev.pBlob = dbei->pBlob;
+
+ int res = DBEventAdd(hContact, reinterpret_cast<LPARAM>(&ev));
+ if (res != DBT_INVALIDPARAM)
+ {
+ NotifyEventHooks(hEventAddedEvent, hContact, res);
+ return res;
+ }
+ return 0;
+}
+INT_PTR CompDeleteEvent(WPARAM hContact, LPARAM hEvent)
+{
+ int res = NotifyEventHooks(hEventDeletedEvent, hContact, hEvent);
+
+ if (hContact == 0)
+ hContact = gDataBase->getEntities().getRootEntity();
+
+ if (res == 0)
+ return DBEventDelete(hEvent, 0);
+
+ return res;
+}
+INT_PTR CompGetBlobSize(WPARAM hEvent, LPARAM lParam)
+{
+ int res = DBEventGetBlobSize(hEvent, 0);
+ if (res == DBT_INVALIDPARAM)
+ return -1;
+
+ return res;
+}
+INT_PTR CompGetEvent(WPARAM hEvent, LPARAM pEventInfo)
+{
+ DBEVENTINFO * dbei = reinterpret_cast<DBEVENTINFO*>(pEventInfo);
+ if (dbei->cbSize < sizeof(DBEVENTINFO))
+ return -1;
+
+ TDBTEvent ev = {0,0,0,0,0,0,0};
+ ev.cbSize = sizeof(ev);
+ ev.cbBlob = 0;
+ ev.pBlob = NULL;
+
+ int res = DBEventGet(hEvent, reinterpret_cast<LPARAM>(&ev));
+
+ dbei->szModule = ev.ModuleName;
+ dbei->timestamp = ev.Timestamp;
+ dbei->flags = ev.Flags;
+ if (dbei->flags & DBEF_SENT)
+ dbei->flags = dbei->flags & ~DBEF_READ;
+ dbei->eventType = ev.EventType;
+
+ if (dbei->cbBlob && dbei->pBlob)
+ {
+ if (dbei->cbBlob >= ev.cbBlob)
+ memcpy(dbei->pBlob, ev.pBlob, ev.cbBlob);
+ else
+ memcpy(dbei->pBlob, ev.pBlob, dbei->cbBlob);
+ }
+ mir_free(ev.pBlob);
+ dbei->cbBlob = ev.cbBlob;
+
+ if (res == DBT_INVALIDPARAM)
+ return 1;
+
+ return res;
+}
+INT_PTR CompMarkEventRead(WPARAM hContact, LPARAM hEvent)
+{
+ int res = DBEventMarkRead(hEvent, 0);
+ if ((res != DBT_INVALIDPARAM) && (res & DBEF_SENT))
+ res = res & ~DBEF_READ;
+ return res;
+}
+INT_PTR CompGetEventContact(WPARAM hEvent, LPARAM lParam)
+{
+ TDBTEntityHandle res = DBEventGetEntity(hEvent, 0);
+ if (res == gDataBase->getEntities().getRootEntity())
+ res = 0;
+
+ return res;
+}
+INT_PTR CompFindFirstEvent(WPARAM hContact, LPARAM lParam)
+{
+ if (hContact == 0)
+ hContact = gDataBase->getEntities().getRootEntity();
+
+ return gDataBase->getEvents().compFirstEvent(hContact);
+}
+INT_PTR CompFindFirstUnreadEvent(WPARAM hContact, LPARAM lParam)
+{
+ if (hContact == 0)
+ hContact = gDataBase->getEntities().getRootEntity();
+ return gDataBase->getEvents().compFirstUnreadEvent(hContact);
+}
+INT_PTR CompFindLastEvent(WPARAM hContact, LPARAM lParam)
+{
+ if (hContact == 0)
+ hContact = gDataBase->getEntities().getRootEntity();
+ return gDataBase->getEvents().compLastEvent(hContact);
+}
+INT_PTR CompFindNextEvent(WPARAM hEvent, LPARAM lParam)
+{
+ return gDataBase->getEvents().compNextEvent(hEvent);
+}
+INT_PTR CompFindPrevEvent(WPARAM hEvent, LPARAM lParam)
+{
+ return gDataBase->getEvents().compPrevEvent(hEvent);
+}
+
+INT_PTR CompEnumModules(WPARAM wParam, LPARAM pCallback)
+{
+ if (!pCallback)
+ return -1;
+
+ return gDataBase->getSettings().CompEnumModules(reinterpret_cast<DBMODULEENUMPROC>(pCallback), wParam);
+}
+
+void Encrypt(char* msg, BOOL up)
+{
+ int i;
+ const int jump = up ? 5 : -5;
+
+ for (i=0; msg[i]; i++)
+ {
+ msg[i] = msg[i] + jump;
+ }
+
+}
+
+INT_PTR CompEncodeString(WPARAM wParam, LPARAM lParam)
+{
+ Encrypt(reinterpret_cast<char*>(lParam),TRUE);
+ return 0;
+}
+
+INT_PTR CompDecodeString(WPARAM wParam, LPARAM lParam)
+{
+ Encrypt(reinterpret_cast<char*>(lParam),FALSE);
+ return 0;
+}
+
+INT_PTR CompGetProfileName(WPARAM cbBytes, LPARAM pszName)
+{
+ return gDataBase->getProfileName(cbBytes, reinterpret_cast<char*>(pszName));
+}
+
+INT_PTR CompGetProfilePath(WPARAM cbBytes, LPARAM pszName)
+{
+ return gDataBase->getProfilePath(cbBytes, reinterpret_cast<char*>(pszName));
+}
+
+bool CompatibilityRegister()
+{
+ gCompServices[ 0] = CreateServiceFunction(MS_DB_CONTACT_GETCOUNT, CompGetContactCount);
+ gCompServices[ 1] = CreateServiceFunction(MS_DB_CONTACT_FINDFIRST, CompFindFirstContact);
+ gCompServices[ 2] = CreateServiceFunction(MS_DB_CONTACT_FINDNEXT, CompFindNextContact);
+ gCompServices[ 3] = CreateServiceFunction(MS_DB_CONTACT_DELETE, CompDeleteContact);
+ gCompServices[ 4] = CreateServiceFunction(MS_DB_CONTACT_ADD, CompAddContact);
+ gCompServices[ 5] = CreateServiceFunction(MS_DB_CONTACT_IS, CompIsDbContact);
+
+ gCompServices[ 6] = CreateServiceFunction(MS_DB_CONTACT_GETSETTING, CompGetContactSetting);
+ gCompServices[ 7] = CreateServiceFunction(MS_DB_CONTACT_GETSETTING_STR, CompGetContactSettingStr);
+ gCompServices[ 8] = CreateServiceFunction(MS_DB_CONTACT_GETSETTINGSTATIC, CompGetContactSettingStatic);
+ gCompServices[ 9] = CreateServiceFunction(MS_DB_CONTACT_FREEVARIANT, CompFreeVariant);
+ gCompServices[10] = CreateServiceFunction(MS_DB_CONTACT_WRITESETTING, CompWriteContactSetting);
+ gCompServices[11] = CreateServiceFunction(MS_DB_CONTACT_DELETESETTING, CompDeleteContactSetting);
+ gCompServices[12] = CreateServiceFunction(MS_DB_CONTACT_ENUMSETTINGS, CompEnumContactSettings);
+ //gCompServices[13] = CreateServiceFunction(MS_DB_SETSETTINGRESIDENT, CompSetSettingResident);
+
+ gCompServices[14] = CreateServiceFunction(MS_DB_EVENT_GETCOUNT, CompGetEventCount);
+ gCompServices[15] = CreateServiceFunction(MS_DB_EVENT_ADD, CompAddEvent);
+ gCompServices[16] = CreateServiceFunction(MS_DB_EVENT_DELETE, CompDeleteEvent);
+ gCompServices[17] = CreateServiceFunction(MS_DB_EVENT_GETBLOBSIZE, CompGetBlobSize);
+ gCompServices[18] = CreateServiceFunction(MS_DB_EVENT_GET, CompGetEvent);
+ gCompServices[19] = CreateServiceFunction(MS_DB_EVENT_MARKREAD, CompMarkEventRead);
+ gCompServices[20] = CreateServiceFunction(MS_DB_EVENT_GETCONTACT, CompGetEventContact);
+ gCompServices[21] = CreateServiceFunction(MS_DB_EVENT_FINDFIRST, CompFindFirstEvent);
+ gCompServices[22] = CreateServiceFunction(MS_DB_EVENT_FINDFIRSTUNREAD, CompFindFirstUnreadEvent);
+ gCompServices[23] = CreateServiceFunction(MS_DB_EVENT_FINDLAST, CompFindLastEvent);
+ gCompServices[24] = CreateServiceFunction(MS_DB_EVENT_FINDNEXT, CompFindNextEvent);
+ gCompServices[25] = CreateServiceFunction(MS_DB_EVENT_FINDPREV, CompFindPrevEvent);
+
+ gCompServices[26] = CreateServiceFunction(MS_DB_MODULES_ENUM, CompEnumModules);
+
+ gCompServices[27] = CreateServiceFunction(MS_DB_CRYPT_ENCODESTRING, CompEncodeString);
+ gCompServices[28] = CreateServiceFunction(MS_DB_CRYPT_DECODESTRING, CompDecodeString);
+
+ gCompServices[29] = CreateServiceFunction(MS_DB_GETPROFILENAME, CompGetProfileName);
+ gCompServices[30] = CreateServiceFunction(MS_DB_GETPROFILEPATH, CompGetProfilePath);
+
+
+ hEventDeletedEvent = CreateHookableEvent(ME_DB_EVENT_DELETED);
+ hEventAddedEvent = CreateHookableEvent(ME_DB_EVENT_ADDED);
+ hEventFilterAddedEvent = CreateHookableEvent(ME_DB_EVENT_FILTER_ADD);
+ hSettingChangeEvent = CreateHookableEvent(ME_DB_CONTACT_SETTINGCHANGED);
+ hContactDeletedEvent = CreateHookableEvent(ME_DB_CONTACT_DELETED);
+ hContactAddedEvent = CreateHookableEvent(ME_DB_CONTACT_ADDED);
+ return true;
+}
+bool CompatibilityUnRegister()
+{
+ int i;
+ for (i = 0; i < sizeof(gCompServices) / sizeof(gCompServices[0]); ++i)
+ {
+ DestroyServiceFunction(gCompServices[i]);
+ }
+ return true;
+}
diff --git a/dbx_tree/Compatibility.h b/dbx_tree/Compatibility.h new file mode 100644 index 0000000..b6b6c16 --- /dev/null +++ b/dbx_tree/Compatibility.h @@ -0,0 +1,65 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include "Interface.h"
+#include "DataBase.h"
+#include "Services.h"
+
+bool CompatibilityRegister();
+bool CompatibilityUnRegister();
+
+INT_PTR CompGetContactCount(WPARAM wParam,LPARAM lParam);
+INT_PTR CompFindFirstContact(WPARAM wParam,LPARAM lParam);
+INT_PTR CompFindNextContact(WPARAM hContact,LPARAM lParam);
+INT_PTR CompDeleteContact(WPARAM hContact,LPARAM lParam);
+INT_PTR CompAddContact(WPARAM wParam,LPARAM lParam);
+INT_PTR CompIsDbContact(WPARAM hContact,LPARAM lParam);
+
+INT_PTR CompGetContactSetting(WPARAM hContact, LPARAM pSetting);
+INT_PTR CompGetContactSettingStr(WPARAM hContact, LPARAM pSetting);
+INT_PTR CompGetContactSettingStatic(WPARAM hContact, LPARAM pSetting);
+INT_PTR CompFreeVariant(WPARAM wParam, LPARAM pSetting);
+INT_PTR CompWriteContactSetting(WPARAM hContact, LPARAM pSetting);
+INT_PTR CompDeleteContactSetting(WPARAM hContact, LPARAM pSetting);
+INT_PTR CompEnumContactSettings(WPARAM hContact, LPARAM pEnum);
+
+INT_PTR CompGetEventCount(WPARAM wParam, LPARAM lParam);
+INT_PTR CompAddEvent(WPARAM hContact, LPARAM pEventInfo);
+INT_PTR CompDeleteEvent(WPARAM hContact, LPARAM hEvent);
+INT_PTR CompGetBlobSize(WPARAM hEvent, LPARAM lParam);
+INT_PTR CompGetEvent(WPARAM hEvent, LPARAM pEventInfo);
+INT_PTR CompMarkEventRead(WPARAM hContact, LPARAM hEvent);
+INT_PTR CompGetEventContact(WPARAM hEvent, LPARAM lParam);
+INT_PTR CompFindFirstEvent(WPARAM hContact, LPARAM lParam);
+INT_PTR CompFindFirstUnreadEvent(WPARAM hContact, LPARAM lParam);
+INT_PTR CompFindLastEvent(WPARAM hContact, LPARAM lParam);
+INT_PTR CompFindNextEvent(WPARAM hEvent, LPARAM lParam);
+INT_PTR CompFindPrevEvent(WPARAM hEvent, LPARAM lParam);
+
+
+INT_PTR CompEncodeString(WPARAM wParam, LPARAM lParam);
+INT_PTR CompDecodeString(WPARAM wParam, LPARAM lParam);
+
+INT_PTR CompGetProfileName(WPARAM cbBytes, LPARAM pszName);
+INT_PTR CompGetProfilePath(WPARAM cbBytes, LPARAM pszName);
diff --git a/dbx_tree/DataBase.cpp b/dbx_tree/DataBase.cpp new file mode 100644 index 0000000..85a9d67 --- /dev/null +++ b/dbx_tree/DataBase.cpp @@ -0,0 +1,374 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "DataBase.h"
+#include "newpluginapi.h"
+#ifndef _MSC_VER
+#include "savestrings_gcc.h"
+#endif
+#include "Logger.h"
+
+CDataBase *gDataBase = NULL;
+
+CDataBase::CDataBase(const char* FileName)
+{
+ int len;
+#ifdef UNICODE
+ len = MultiByteToWideChar(CP_ACP, 0, FileName, -1, NULL, 0);
+ m_FileName[0] = new TCHAR[len + 1];
+ MultiByteToWideChar(CP_ACP, 0, FileName, -1, m_FileName[0], len + 1);
+ m_FileName[0][len] = 0;
+#else
+ len = strlen(FileName);
+ m_FileName[0] = new TCHAR[len + 1];
+ strcpy_s(m_FileName[0], len + 1, FileName);
+#endif
+
+ TCHAR * tmp = _tcsrchr(m_FileName[0], '.');
+ if (tmp)
+ {
+ m_FileName[1] = new TCHAR[len + 1];
+ _tcsncpy_s(m_FileName[1], len + 1, m_FileName[0], tmp - m_FileName[0]);
+ _tcscat_s(m_FileName[1], len + 1, _T(".pri"));
+ } else {
+ m_FileName[1] = new TCHAR[len + 5];
+ _tcscpy_s(m_FileName[1], len + 5, m_FileName[0]);
+ _tcscat_s(m_FileName[1], len + 5, _T(".pri"));
+ }
+
+ m_Opened = false;
+
+ for (int i = 0; i < DBFileMax; ++i)
+ {
+ m_BlockManager[i] = NULL;
+ m_FileAccess[i] = NULL;
+ m_EncryptionManager[i] = NULL;
+ m_HeaderBlock[i] = 0;
+ }
+
+ m_Entities = NULL;
+ m_Settings = NULL;
+ m_Events = NULL;
+}
+CDataBase::~CDataBase()
+{
+ if (m_Events) delete m_Events;
+ if (m_Settings) delete m_Settings;
+ if (m_Entities) delete m_Entities;
+
+ m_Entities = NULL;
+ m_Settings = NULL;
+ m_Events = NULL;
+
+ for (int i = DBFileMax - 1; i >= 0; --i)
+ {
+ if (m_BlockManager[i]) delete m_BlockManager[i];
+ if (m_FileAccess[i]) delete m_FileAccess[i];
+ if (m_EncryptionManager[i]) delete m_EncryptionManager[i];
+
+ m_BlockManager[i] = NULL;
+ m_FileAccess[i] = NULL;
+ m_EncryptionManager[i] = NULL;
+
+ delete [] (m_FileName[i]);
+ }
+
+}
+int CDataBase::CreateDB()
+{
+ /// TODO: create and show wizard
+ if (!CreateNewFile(DBFileSetting) ||
+ !CreateNewFile(DBFilePrivate))
+ return EMKPRF_CREATEFAILED;
+
+ return 0;
+}
+
+
+int CDataBase::CheckFile(TDBFileType Index)
+{
+ TGenericFileHeader h;
+ memset(&h, 0, sizeof(h));
+ DWORD r = 0;
+ HANDLE htmp = CreateFile(m_FileName[Index], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
+ if (htmp != INVALID_HANDLE_VALUE)
+ {
+ SetFilePointer(htmp, 0, NULL, FILE_BEGIN);
+ if (ReadFile(htmp, &h, sizeof(h), &r, NULL))
+ {
+ if (0 != memcmp(h.Gen.Signature, cFileSignature[Index], sizeof(cFileSignature[Index])))
+ {
+ CloseHandle(htmp);
+ return EGROKPRF_UNKHEADER;
+ }
+
+ if (cDBVersion < h.Gen.Version)
+ {
+ CloseHandle(htmp);
+ return EGROKPRF_VERNEWER;
+ }
+
+ CloseHandle(htmp);
+ return EGROKPRF_NOERROR;
+ }
+ CloseHandle(htmp);
+ }
+
+ return EGROKPRF_CANTREAD;
+}
+
+int CDataBase::CheckDB()
+{
+ int res = CheckFile(DBFileSetting);
+
+ if (res != EGROKPRF_NOERROR)
+ return res;
+
+ if (PrivateFileExists())
+ res = CheckFile(DBFilePrivate);
+
+ return res;
+}
+
+int CDataBase::LoadFile(TDBFileType Index)
+{
+ TGenericFileHeader h;
+ m_EncryptionManager[Index] = new CEncryptionManager;
+
+ if (CMappedMemory::InitMMAP())
+ m_FileAccess[Index] = new CMappedMemory(m_FileName[Index]);
+ else
+ m_FileAccess[Index] = new CDirectAccess(m_FileName[Index]);
+
+ m_FileAccess[Index]->Read(&h, 0, sizeof(h));
+ m_EncryptionManager[Index]->InitEncryption(h.Gen.FileEncryption);
+
+ m_FileAccess[Index]->Size(h.Gen.FileSize);
+ m_FileAccess[Index]->sigFileSizeChanged().connect(this, &CDataBase::onFileSizeChanged);
+
+ m_BlockManager[Index] = new CBlockManager(*m_FileAccess[Index], *m_EncryptionManager[Index]);
+
+ CBlockManager::WriteTransaction trans(*m_BlockManager[Index]); // don't fire size event until header is loaded
+
+ m_HeaderBlock[Index] = m_BlockManager[Index]->ScanFile(sizeof(h), cHeaderBlockSignature, h.Gen.FileSize);
+
+ if (m_HeaderBlock[Index] == 0)
+ {
+ LOG(logCRITICAL, _T("Header Block not found! File damaged: \"%s\""), m_FileName[Index]);
+ return -1;
+ }
+
+ uint32_t size = sizeof(h);
+ uint32_t sig = -1;
+ m_Header[Index] = m_BlockManager[Index]->ReadBlock<TGenericFileHeader>(0, size, sig);
+
+ sig = cHeaderBlockSignature;
+ TGenericFileHeader * buf = m_BlockManager[Index]->ReadBlock<TGenericFileHeader>(m_HeaderBlock[Index], size, sig);
+ if (!buf)
+ {
+ LOG(logCRITICAL, _T("Header Block cannot be read! File damaged: \"%s\""), m_FileName[Index]);
+ return -1;
+ }
+
+ buf->Gen.Obscure = 0;
+
+ if (memcmp(m_Header[Index], buf, size))
+ {
+ LOG(logCRITICAL, _T("Header Block in \"%s\" damaged!"), m_FileName[Index]);
+ return -1;
+ }
+
+ return 0;
+}
+
+int CDataBase::OpenDB()
+{
+ if (!PrivateFileExists())
+ {
+ // TODO WIZARD
+ if (!CreateNewFile(DBFilePrivate))
+ return -1;
+ }
+
+ int res = LoadFile(DBFileSetting);
+ if ((res != 0) && (CLogger::logERROR <= CLogger::Instance().ShowMessage()))
+ {
+ return res;
+ }
+
+ res = LoadFile(DBFilePrivate);
+
+ if ((res != 0) && (CLogger::logERROR <= CLogger::Instance().ShowMessage()))
+ {
+ return res;
+ }
+ if (CLogger::logERROR <= CLogger::Instance().ShowMessage())
+ return -1;
+
+ m_Entities = new CEntities(*m_BlockManager[DBFilePrivate],
+ m_Header[DBFilePrivate]->Pri.RootEntity,
+ m_Header[DBFilePrivate]->Pri.Entities,
+ m_Header[DBFilePrivate]->Pri.Virtuals);
+
+ m_Entities->sigRootChanged().connect(this, &CDataBase::onEntitiesRootChanged);
+ m_Entities->sigVirtualRootChanged().connect(this, &CDataBase::onVirtualsRootChanged);
+
+ if (m_Entities->getRootEntity() != m_Header[DBFilePrivate]->Pri.RootEntity)
+ {
+ m_Header[DBFilePrivate]->Pri.RootEntity = m_Entities->getRootEntity();
+ ReWriteHeader(DBFilePrivate);
+ }
+
+ m_Settings = new CSettings(*m_BlockManager[DBFileSetting],
+ *m_BlockManager[DBFilePrivate],
+ m_Header[DBFileSetting]->Set.Settings,
+ *m_Entities);
+
+ m_Settings->sigRootChanged().connect(this, &CDataBase::onSettingsRootChanged);
+
+ m_Events = new CEvents(*m_BlockManager[DBFilePrivate],
+ *m_EncryptionManager[DBFilePrivate],
+ *m_Entities,
+ *m_Settings);
+
+ return 0;
+}
+
+bool CDataBase::PrivateFileExists()
+{
+ HANDLE htmp = CreateFile(m_FileName[DBFilePrivate], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
+ if (htmp != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(htmp);
+ return true;
+ }
+
+ return false;
+}
+
+
+bool CDataBase::CreateNewFile(TDBFileType File)
+{
+ CEncryptionManager enc;
+ CDirectAccess fa(m_FileName[File]);
+ fa.Size(sizeof(TGenericFileHeader));
+ CBlockManager bm(fa, enc);
+ bm.ScanFile(sizeof(TGenericFileHeader), 0, sizeof(TGenericFileHeader));
+
+ CBlockManager::WriteTransaction trans(bm);
+
+ uint32_t block;
+ TGenericFileHeader * buf = bm.CreateBlock<TGenericFileHeader>(block, cHeaderBlockSignature);
+ uint32_t size = 0;
+ uint32_t sig = -1;
+ TGenericFileHeader * h = bm.ReadBlock<TGenericFileHeader>(0, size, sig);
+
+ memset(h, 0, sizeof(TGenericFileHeader));
+ memcpy(&h->Gen.Signature, &cFileSignature[File], sizeof(h->Gen.Signature));
+ h->Gen.Version = cDBVersion;
+ h->Gen.FileSize = fa.Size();
+
+ memcpy(buf, h, sizeof(TGenericFileHeader));
+ bm.UpdateBlock(block, 0);
+ bm.UpdateBlock(0, -1);
+
+ return true;
+}
+
+inline void CDataBase::ReWriteHeader(TDBFileType Index)
+{
+ m_BlockManager[Index]->UpdateBlock(0, -1);
+ uint32_t size = 0, sig = 0;
+ TGenericFileHeader * h = m_BlockManager[Index]->ReadBlock<TGenericFileHeader>(m_HeaderBlock[Index], size, sig);
+
+ *h = *m_Header[Index];
+ h->Gen.Obscure = GetTickCount();
+ m_BlockManager[Index]->UpdateBlock(m_HeaderBlock[Index], 0);
+}
+
+
+void CDataBase::onSettingsRootChanged(CSettings* Settings, CSettingsTree::TNodeRef NewRoot)
+{
+ m_Header[DBFileSetting]->Set.Settings = NewRoot;
+ ReWriteHeader(DBFileSetting);
+}
+void CDataBase::onVirtualsRootChanged(void* Virtuals, CVirtuals::TNodeRef NewRoot)
+{
+ m_Header[DBFilePrivate]->Pri.Virtuals = NewRoot;
+ ReWriteHeader(DBFilePrivate);
+}
+void CDataBase::onEntitiesRootChanged(void* Entities, CEntities::TNodeRef NewRoot)
+{
+ m_Header[DBFilePrivate]->Pri.Entities = NewRoot;
+ ReWriteHeader(DBFilePrivate);
+}
+void CDataBase::onFileSizeChanged(CFileAccess * File, uint32_t Size)
+{
+ if (File == m_FileAccess[DBFileSetting])
+ {
+ m_Header[DBFileSetting]->Gen.FileSize = Size;
+ ReWriteHeader(DBFileSetting);
+ } else {
+ m_Header[DBFilePrivate]->Gen.FileSize = Size;
+ ReWriteHeader(DBFilePrivate);
+ }
+}
+
+int CDataBase::getProfileName(int BufferSize, char * Buffer)
+{
+ TCHAR * slash = _tcsrchr(m_FileName[DBFileSetting], '\\');
+ if (slash)
+ slash++;
+ else
+ slash = m_FileName[DBFileSetting];
+
+ int l = static_cast<int>(_tcslen(slash));
+ if (BufferSize < l + 1)
+ return -1;
+
+ char * tmp = mir_t2a(slash);
+ strcpy_s(Buffer, BufferSize, tmp);
+ mir_free(tmp);
+
+ return 0;
+}
+int CDataBase::getProfilePath(int BufferSize, char * Buffer)
+{
+ TCHAR * slash = _tcsrchr(m_FileName[DBFileSetting], '\\');
+ if (!slash)
+ return -1;
+
+ int l = slash - m_FileName[DBFileSetting];
+
+ if (BufferSize < l + 1)
+ {
+ return -1;
+ }
+
+ *slash = 0;
+ char * tmp = mir_t2a(m_FileName[DBFileSetting]);
+ strcpy_s(Buffer, BufferSize, tmp);
+ mir_free(tmp);
+ *slash = '\\';
+
+ return 0;
+}
diff --git a/dbx_tree/DataBase.h b/dbx_tree/DataBase.h new file mode 100644 index 0000000..2577249 --- /dev/null +++ b/dbx_tree/DataBase.h @@ -0,0 +1,157 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#ifndef _MSC_VER
+#include <stdint.h>
+#else
+#include "stdint.h"
+#endif
+#include "MREWSync.h"
+
+#include "Events.h"
+#include "Settings.h"
+#include "Entities.h"
+
+#include "FileAccess.h"
+#include "MappedMemory.h"
+#include "DirectAccess.h"
+#include "Blockmanager.h"
+
+#include "sigslot.h"
+
+#include "EncryptionManager.h"
+
+typedef enum TDBFileType {
+ DBFileSetting = 0,
+ DBFilePrivate = 1,
+ DBFileMax = 2
+} TDBFileType;
+
+static const uint8_t cFileSignature[DBFileMax][20] = {"Miranda IM Settings", "Miranda IM DataTree"};
+static const uint32_t cDBVersion = 0x00000001;
+
+static const uint32_t cHeaderBlockSignature = 0x7265491E;
+
+#pragma pack(push, 1) // push current alignment to stack, set alignment to 1 byte boundary
+
+typedef struct TSettingsHeader {
+ uint8_t Signature[20]; /// signature must be cSettingsHeader
+ uint32_t Version; /// internal DB version cDataBaseVersion
+ uint32_t Obscure;
+ TFileEncryption FileEncryption; /// Encryption Method
+ uint32_t FileStructureBlock; /// Offset of CBlockManager master block
+ uint32_t FileSize; /// Offset to the last used byte + 1
+ uint32_t Settings; /// Offset to the SettingsBTree RootNode
+ uint8_t Reserved[256 - sizeof(TFileEncryption) - 20 - 5*sizeof(uint32_t)]; /// reserved storage
+} TSettingsHeader;
+
+typedef struct TPrivateHeader {
+ uint8_t Signature[20]; /// signature must be CDataHeader
+ uint32_t Version; /// internal DB version cDataBaseVersion
+ uint32_t Obscure;
+ TFileEncryption FileEncryption; /// Encryption Method
+ uint32_t FileStructureBlock; /// Offset of CBlockManager master block
+ uint32_t FileSize; /// Offset to the last used byte + 1
+ uint32_t RootEntity; /// Offset to the Root CList Entity
+ uint32_t Entities; /// Offset to the EntityBTree RootNode
+ uint32_t Virtuals; /// Offset to the VirtualsBTree RootNode
+ uint8_t Reserved[256 - sizeof(TFileEncryption) - 20 - 7*sizeof(uint32_t)]; /// reserved storage
+} TPrivateHeader;
+
+
+typedef union TGenericFileHeader {
+ struct {
+ uint8_t Signature[20]; /// signature must be cSettingsHeader
+ uint32_t Version; /// internal DB version cDataBaseVersion
+ uint32_t Obscure;
+ TFileEncryption FileEncryption; /// Encryption Method
+ uint32_t FileStructureBlock; /// Offset of CBlockManager master block
+ uint32_t FileSize; /// Offset to the last used byte + 1
+ uint8_t Reserved[256 - sizeof(TFileEncryption) - 20 - 4*sizeof(uint32_t)]; /// reserved storage
+ } Gen;
+ TSettingsHeader Set;
+ TPrivateHeader Pri;
+} TGenericFileHeader;
+
+#pragma pack(pop)
+
+
+class CDataBase : public sigslot::has_slots<>
+{
+private:
+ TCHAR* m_FileName[DBFileMax];
+ bool m_Opened;
+
+ CBlockManager *m_BlockManager[DBFileMax];
+ CFileAccess *m_FileAccess[DBFileMax];
+ TGenericFileHeader * m_Header[DBFileMax];
+ CEncryptionManager *m_EncryptionManager[DBFileMax];
+
+ uint32_t m_HeaderBlock[DBFileMax];
+
+ void onSettingsRootChanged(CSettings* Settings, CSettingsTree::TNodeRef NewRoot);
+ void onVirtualsRootChanged(void* Virtuals, CVirtuals::TNodeRef NewRoot);
+ void onEntitiesRootChanged(void* Entities, CEntities::TNodeRef NewRoot);
+ void onFileSizeChanged(CFileAccess * File, uint32_t Size);
+
+ bool PrivateFileExists();
+ bool CreateNewFile(TDBFileType File);
+
+ int CheckFile(TDBFileType Index);
+ int LoadFile(TDBFileType Index);
+protected:
+ CEntities *m_Entities;
+ CSettings *m_Settings;
+ CEvents *m_Events;
+
+ void ReWriteHeader(TDBFileType Index);
+
+public:
+ CDataBase(const char* FileName);
+ virtual ~CDataBase();
+
+ int CreateDB();
+ int CheckDB();
+ int OpenDB();
+
+ CEntities & getEntities()
+ {
+ return *m_Entities;
+ }
+ CSettings & getSettings()
+ {
+ return *m_Settings;
+ }
+ CEvents & getEvents()
+ {
+ return *m_Events;
+ }
+
+ int getProfileName(int BufferSize, char * Buffer);
+ int getProfilePath(int BufferSize, char * Buffer);
+
+};
+
+
+extern CDataBase *gDataBase;
diff --git a/dbx_tree/DatabaseLink.cpp b/dbx_tree/DatabaseLink.cpp new file mode 100644 index 0000000..b6cd91e --- /dev/null +++ b/dbx_tree/DatabaseLink.cpp @@ -0,0 +1,178 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "DatabaseLink.h"
+#ifndef _MSC_VER
+#include "savestrings_gcc.h"
+#endif
+
+static int getCapability(int);
+static int getFriendlyName(char*, size_t, int);
+static int makeDatabase(char*, int*);
+static int grokHeader(char*, int*);
+static int Load(char*, void*);
+static int Unload(int);
+
+DATABASELINK gDBLink = {
+ sizeof(DATABASELINK),
+ getCapability,
+ getFriendlyName,
+ makeDatabase,
+ grokHeader,
+ Load,
+ Unload,
+};
+
+PLUGINLINK *pluginLink = NULL;
+MM_INTERFACE mmi = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+UTF8_INTERFACE utfi = {0,0,0,0,0,0,0};
+HANDLE hSystemModulesLoaded = 0;
+
+
+static int SystemModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ Update upd = {0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ upd.cbSize = sizeof(upd);
+ upd.szComponentName = gInternalName;
+ upd.szBetaVersionURL = "http://www-user.tu-chemnitz.de/~kunmi/?dbx_tree";
+#ifdef _M_X64
+ upd.pbBetaVersionPrefix = (BYTE *)"<!-- Updater Beta x64: ";
+ upd.cpbBetaVersionPrefix = 23;
+ upd.szBetaUpdateURL = "http://www-user.tu-chemnitz.de/~kunmi/Downloads/dbx_tree64.zip";
+#else
+ upd.pbBetaVersionPrefix = (BYTE *)"<!-- Updater Beta: ";
+ upd.cpbBetaVersionPrefix = 19;
+ upd.szBetaUpdateURL = "http://www-user.tu-chemnitz.de/~kunmi/Downloads/dbx_tree.zip";
+#endif
+ upd.pbVersion = (BYTE*)gResVersionString;
+ upd.cpbVersion = sizeof(gResVersionString) - 1;
+ upd.szBetaChangelogURL = "http://www-user.tu-chemnitz.de/~kunmi/?dbx_tree=BetaLog&lang=en";
+
+ CallService(MS_UPDATE_REGISTER, 0, (LPARAM)&upd);
+
+ UnhookEvent(hSystemModulesLoaded);
+ hSystemModulesLoaded = 0;
+
+ return 0;
+}
+
+/*
+returns what the driver can do given the flag
+*/
+static int getCapability(int flag)
+{
+ return 0;
+}
+
+/*
+ buf: pointer to a string buffer
+ cch: length of buffer
+ shortName: if true, the driver should return a short but descriptive name, e.g. "3.xx profile"
+ Affect: The database plugin must return a "friendly name" into buf and not exceed cch bytes,
+ e.g. "Database driver for 3.xx profiles"
+ Returns: 0 on success, non zero on failure
+*/
+
+static int getFriendlyName(char* buf, size_t cch, int shortName)
+{
+ if (shortName)
+ strncpy_s(buf, cch, gInternalName, strlen(gInternalName));
+ else
+ strncpy_s(buf, cch, gInternalNameLong, strlen(gInternalNameLong));
+ return 0;
+}
+
+/*
+ profile: pointer to a string which contains full path + name
+ Affect: The database plugin should create the profile, the filepath will not exist at
+ the time of this call, profile will be C:\..\<name>.dat
+ Note: Do not prompt the user in anyway about this operation.
+ Note: Do not initialise internal data structures at this point!
+ Returns: 0 on success, non zero on failure - error contains extended error information, see EMKPRF_*
+*/
+static int makeDatabase(char* profile, int* error)
+{
+ if (gDataBase) delete gDataBase;
+ gDataBase = new CDataBase(profile);
+
+ *error = gDataBase->CreateDB();
+ return *error;
+}
+
+/*
+ profile: [in] a null terminated string to file path of selected profile
+ error: [in/out] pointer to an int to set with error if any
+ Affect: Ask the database plugin if it supports the given profile, if it does it will
+ return 0, if it doesnt return 1, with the error set in error -- EGROKPRF_* can be valid error
+ condition, most common error would be [EGROKPRF_UNKHEADER]
+ Note: Just because 1 is returned, doesnt mean the profile is not supported, the profile might be damaged
+ etc.
+ Returns: 0 on success, non zero on failure
+*/
+static int grokHeader(char* profile, int* error)
+{
+ if (gDataBase) delete gDataBase;
+ gDataBase = new CDataBase(profile);
+
+ *error = gDataBase->CheckDB();
+ return *error;
+}
+
+/*
+Affect: Tell the database to create all services/hooks that a 3.xx legecy database might support into link,
+ which is a PLUGINLINK structure
+Returns: 0 on success, nonzero on failure
+*/
+static int Load(char* profile, void* link)
+{
+ if (gDataBase) delete gDataBase;
+ gDataBase = new CDataBase(profile);
+
+ pluginLink = (PLUGINLINK*)link;
+
+ mir_getMMI(&mmi);
+ mir_getUTFI(&utfi);
+
+ RegisterServices();
+ CompatibilityRegister();
+
+ hSystemModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, SystemModulesLoaded);
+
+ return gDataBase->OpenDB();
+}
+
+/*
+Affect: The database plugin should shutdown, unloading things from the core and freeing internal structures
+Returns: 0 on success, nonzero on failure
+Note: Unload() might be called even if Load() was never called, wasLoaded is set to 1 if Load() was ever called.
+*/
+static int Unload(int wasLoaded)
+{
+ if (gDataBase)
+ delete gDataBase;
+
+ gDataBase = NULL;
+ return 0;
+}
+
+
diff --git a/dbx_tree/DatabaseLink.h b/dbx_tree/DatabaseLink.h new file mode 100644 index 0000000..0ec4cd7 --- /dev/null +++ b/dbx_tree/DatabaseLink.h @@ -0,0 +1,29 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+#include <windows.h>
+#include "Interface.h"
+#include "Database.h"
+#include "Services.h"
+#include "Compatibility.h"
+#include "m_updater.h"
\ No newline at end of file diff --git a/dbx_tree/DirectAccess.cpp b/dbx_tree/DirectAccess.cpp new file mode 100644 index 0000000..33785af --- /dev/null +++ b/dbx_tree/DirectAccess.cpp @@ -0,0 +1,118 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "DirectAccess.h"
+#include "Logger.h"
+
+CDirectAccess::CDirectAccess(const TCHAR* FileName)
+: CFileAccess(FileName)
+{
+ m_File = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 0);
+ CHECKSYS(m_File != INVALID_HANDLE_VALUE,
+ logCRITICAL, _T("CreateFile failed"));
+
+ m_MinAllocGranularity = 0x00001000; // 4kb to avoid heavy fragmentation
+ m_AllocGranularity = 0x00008000; // 32kb
+ m_MaxAllocGranularity = 0x00100000; // 1mb for fast increasing
+
+ uint32_t size = GetFileSize(m_File, NULL);
+ size = (size + m_AllocGranularity - 1) & ~(m_AllocGranularity - 1);
+
+ if (size == 0)
+ size = m_AllocGranularity;
+
+ m_AllocSize = size;
+
+ InitJournal();
+}
+
+CDirectAccess::~CDirectAccess()
+{
+ if (m_File)
+ {
+ if (INVALID_SET_FILE_POINTER != SetFilePointer(m_File, m_Size, NULL, FILE_BEGIN))
+ SetEndOfFile(m_File);
+
+ CloseHandle(m_File);
+ }
+}
+
+uint32_t CDirectAccess::_Read(void* Buf, uint32_t Source, uint32_t Size)
+{
+ DWORD read = 0;
+
+ CHECKSYS(INVALID_SET_FILE_POINTER != SetFilePointer(m_File, Source, NULL, FILE_BEGIN),
+ logERROR, _T("SetFilePointer failed"));
+
+ CHECKSYS(ReadFile(m_File, Buf, Size, &read, NULL),
+ logERROR, _T("ReadFile failed"));
+
+ return read;
+}
+uint32_t CDirectAccess::_Write(void* Buf, uint32_t Dest, uint32_t Size)
+{
+ DWORD written = 0;
+
+ CHECKSYS(INVALID_SET_FILE_POINTER != SetFilePointer(m_File, Dest, NULL, FILE_BEGIN),
+ logERROR, _T("SetFilePointer failed"));
+
+ CHECKSYS(WriteFile(m_File, Buf, Size, &written, NULL),
+ logERROR, _T("WriteFile failed"));
+
+ return written;
+}
+
+uint32_t CDirectAccess::_SetSize(uint32_t Size)
+{
+ CHECKSYS(INVALID_SET_FILE_POINTER != SetFilePointer(m_File, Size, NULL, FILE_BEGIN),
+ logERROR, _T("SetFilePointer failed"));
+
+ CHECKSYS(SetEndOfFile(m_File),
+ logERROR, _T("SetEndOfFile failed"));
+
+ return Size;
+}
+
+void CDirectAccess::_Invalidate(uint32_t Dest, uint32_t Size)
+{
+ DWORD written;
+ uint8_t buf[4096];
+ memset(buf, 0, sizeof(buf));
+
+ CHECKSYS(INVALID_SET_FILE_POINTER != SetFilePointer(m_File, Dest, NULL, FILE_BEGIN),
+ logERROR, _T("SetFilePointer failed"));
+
+ while (Size > sizeof(buf))
+ {
+ Size -= sizeof(buf);
+ CHECKSYS(WriteFile(m_File, buf, sizeof(buf), &written, NULL),
+ logERROR, _T("WriteFile failed"));
+ }
+ CHECKSYS(WriteFile(m_File, buf, Size, &written, NULL),
+ logERROR, _T("WriteFile failed"));
+}
+
+void CDirectAccess::_Flush()
+{
+ CHECKSYS(FlushFileBuffers(m_File),
+ logERROR, _T("FlushFileBuffers failed"));
+}
diff --git a/dbx_tree/DirectAccess.h b/dbx_tree/DirectAccess.h new file mode 100644 index 0000000..cc4241c --- /dev/null +++ b/dbx_tree/DirectAccess.h @@ -0,0 +1,43 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include <windows.h>
+#include "FileAccess.h"
+
+class CDirectAccess : public CFileAccess
+{
+private:
+
+ HANDLE m_File;
+protected:
+ uint32_t _Read(void* Buf, uint32_t Source, uint32_t Size);
+ uint32_t _Write(void* Buf, uint32_t Dest, uint32_t Size);
+ void _Invalidate(uint32_t Dest, uint32_t Size);
+ uint32_t _SetSize(uint32_t Size);
+ void _Flush();
+public:
+ CDirectAccess(const TCHAR* FileName);
+ virtual ~CDirectAccess();
+
+};
diff --git a/dbx_tree/EncryptionManager.cpp b/dbx_tree/EncryptionManager.cpp new file mode 100644 index 0000000..7afdcb2 --- /dev/null +++ b/dbx_tree/EncryptionManager.cpp @@ -0,0 +1,241 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "EncryptionManager.h"
+#include <tchar.h>
+
+uint32_t CEncryptionManager::CipherListRefCount = 0;
+CEncryptionManager::TCipherList* CEncryptionManager::CipherList = NULL;
+
+static const uint32_t cFileBlockMask = 0xfffff000;
+
+void CEncryptionManager::LoadCipherList()
+{
+ if (CipherList)
+ return;
+
+ CipherList = new TCipherList;
+ CipherListRefCount++;
+
+ WIN32_FIND_DATA search;
+ TCHAR path[MAX_PATH * 8];
+ GetModuleFileName(NULL, path, sizeof(path));
+ TCHAR * file = _tcsrchr(path, '\\');
+ if (!file)
+ file = path;
+
+ _tcscpy_s(file, sizeof(path) / sizeof(path[0]) - (file - path), _T("\\plugins\\encryption\\*.dll"));
+ file += 20;
+
+ HANDLE hfinder = FindFirstFile(path, &search);
+ if (hfinder != INVALID_HANDLE_VALUE)
+ {
+ TCipherItem item;
+ TCipherInfo* (__cdecl *CipherInfoProc)(void *);
+ do {
+ _tcscpy_s(file, sizeof(path) / sizeof(path[0]) - (file - path), search.cFileName);
+ HMODULE hmod = LoadLibrary(path);
+ if (hmod)
+ {
+ CipherInfoProc = (TCipherInfo*(__cdecl*)(void*)) GetProcAddress(hmod, "CipherInfo");
+ if (CipherInfoProc)
+ {
+ TCipherInfo* info = CipherInfoProc(NULL);
+ if (info && (info->cbSize == sizeof(TCipherInfo)) && (CipherList->find(info->ID) == CipherList->end()))
+ {
+ item.ID = info->ID;
+ item.Name = _wcsdup(info->Name);
+ item.Description = _wcsdup(info->Description);
+ item.FilePath = _tcsdup(path);
+ item.FileName = item.FilePath + (file - path);
+
+ CipherList->insert(std::make_pair(item.ID, item));
+ }
+ }
+
+ FreeLibrary(hmod);
+
+ }
+ } while (FindNextFile(hfinder, &search));
+
+ FindClose(hfinder);
+ }
+}
+
+CEncryptionManager::CEncryptionManager()
+{
+ m_Ciphers[CURRENT].Cipher = NULL;
+ m_Ciphers[OLD].Cipher = NULL;
+ m_Changing = false;
+ m_ChangingProcess = 0;
+
+ LoadCipherList();
+}
+CEncryptionManager::~CEncryptionManager()
+{
+ if (m_Ciphers[CURRENT].Cipher)
+ delete m_Ciphers[CURRENT].Cipher;
+ m_Ciphers[CURRENT].Cipher = NULL;
+ if (m_Ciphers[OLD].Cipher)
+ delete m_Ciphers[OLD].Cipher;
+ m_Ciphers[OLD].Cipher = NULL;
+
+ CipherListRefCount--;
+ if (!CipherListRefCount)
+ {
+ TCipherList::iterator i = CipherList->begin();
+ while (i != CipherList->end())
+ {
+ free(i->second.Description);
+ free(i->second.Name);
+ free(i->second.FilePath);
+ // do not free Filename... it's a substring of FilePath
+ ++i;
+ }
+
+ delete CipherList;
+ CipherList = NULL;
+ }
+}
+
+bool CEncryptionManager::InitEncryption(TFileEncryption & Enc)
+{
+ if (Enc.ConversionProcess)
+ {
+ m_Changing = true;
+ m_ChangingProcess = Enc.ConversionProcess;
+ }
+
+ for (int c = (int)CURRENT; c < (int)COUNT; c++)
+ {
+ TCipherList::iterator i = CipherList->find(Enc.CipherID);
+ if (i != CipherList->end())
+ {
+ m_Ciphers[c].CipherDLL = LoadLibrary(i->second.FilePath);
+ if (m_Ciphers[c].CipherDLL)
+ {
+ TCipherInfo* (__cdecl *cipherinfoproc)(void *);
+ cipherinfoproc = (TCipherInfo*(__cdecl*)(void*)) GetProcAddress(m_Ciphers[c].CipherDLL, "CipherInfo");
+ if (cipherinfoproc)
+ {
+ TCipherInfo* info = cipherinfoproc(NULL);
+ if (info && (info->cbSize == sizeof(TCipherInfo)))
+ m_Ciphers[c].Cipher = new CCipher(info->Create());
+
+ }
+
+ if (!m_Ciphers[c].Cipher)
+ {
+ FreeLibrary(m_Ciphers[c].CipherDLL);
+ m_Ciphers[c].CipherDLL = NULL;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CEncryptionManager::AlignData(uint32_t ID, uint32_t & Start, uint32_t & End)
+{
+ if (m_Ciphers[CURRENT].Cipher && (!m_Changing || (ID < m_ChangingProcess)))
+ {
+ if (m_Ciphers[CURRENT].Cipher->IsStreamCipher())
+ {
+ Start = 0;
+ End = End - End % m_Ciphers[CURRENT].Cipher->BlockSizeBytes() + m_Ciphers[CURRENT].Cipher->BlockSizeBytes();
+ } else {
+ Start = Start - Start % m_Ciphers[CURRENT].Cipher->BlockSizeBytes();
+ if (End % m_Ciphers[CURRENT].Cipher->BlockSizeBytes())
+ End = End - End % m_Ciphers[CURRENT].Cipher->BlockSizeBytes() + m_Ciphers[CURRENT].Cipher->BlockSizeBytes();
+ }
+
+ return true;
+ } else if (m_Ciphers[OLD].Cipher && m_Changing && (ID >= m_ChangingProcess))
+ {
+ if (m_Ciphers[OLD].Cipher->IsStreamCipher())
+ {
+ Start = 0;
+ End = End - End % m_Ciphers[OLD].Cipher->BlockSizeBytes() + m_Ciphers[OLD].Cipher->BlockSizeBytes();
+ } else {
+ Start = Start - Start % m_Ciphers[OLD].Cipher->BlockSizeBytes();
+ if (End % m_Ciphers[OLD].Cipher->BlockSizeBytes())
+ End = End - End % m_Ciphers[OLD].Cipher->BlockSizeBytes() + m_Ciphers[OLD].Cipher->BlockSizeBytes();
+ }
+
+ return true;
+ }
+
+ return false;
+}
+uint32_t CEncryptionManager::AlignSize(uint32_t ID, uint32_t Size)
+{
+ if (m_Ciphers[CURRENT].Cipher && (!m_Changing || (ID < m_ChangingProcess)))
+ {
+ if (Size % m_Ciphers[CURRENT].Cipher->BlockSizeBytes())
+ return Size - Size % m_Ciphers[CURRENT].Cipher->BlockSizeBytes() + m_Ciphers[CURRENT].Cipher->BlockSizeBytes();
+
+ } else if (m_Ciphers[OLD].Cipher && m_Changing && (ID >= m_ChangingProcess))
+ {
+ if (Size % m_Ciphers[OLD].Cipher->BlockSizeBytes())
+ return Size - Size % m_Ciphers[OLD].Cipher->BlockSizeBytes() + m_Ciphers[OLD].Cipher->BlockSizeBytes();
+
+ }
+
+ return Size;
+}
+
+bool CEncryptionManager::IsEncrypted(uint32_t ID)
+{
+ return (m_Ciphers[CURRENT].Cipher && (!m_Changing || (ID < m_ChangingProcess))) ||
+ (m_Ciphers[OLD].Cipher && m_Changing && (ID >= m_ChangingProcess));
+}
+
+void CEncryptionManager::Encrypt(void* Data, uint32_t DataLength, uint32_t ID, uint32_t StartByte)
+{
+ if (m_Ciphers[CURRENT].Cipher && (!m_Changing || (ID < m_ChangingProcess)))
+ {
+ m_Ciphers[CURRENT].Cipher->Encrypt(Data, DataLength, ID, StartByte);
+ } else if (m_Ciphers[OLD].Cipher && m_Changing && (ID >= m_ChangingProcess))
+ {
+ m_Ciphers[OLD].Cipher->Encrypt(Data, DataLength, ID, StartByte);
+ }
+}
+void CEncryptionManager::Decrypt(void* Data, uint32_t DataLength, uint32_t ID, uint32_t StartByte)
+{
+ if (m_Ciphers[CURRENT].Cipher && (!m_Changing || (ID < m_ChangingProcess)))
+ {
+ m_Ciphers[CURRENT].Cipher->Decrypt(Data, DataLength, ID, StartByte);
+ } else if (m_Ciphers[OLD].Cipher && m_Changing && (ID >= m_ChangingProcess))
+ {
+ m_Ciphers[OLD].Cipher->Decrypt(Data, DataLength, ID, StartByte);
+ }
+}
+
+bool CEncryptionManager::CanChangeCipher()
+{
+ return false;
+}
+bool CEncryptionManager::ChangeCipher(TEncryption & Encryption)
+{
+ return false;
+}
diff --git a/dbx_tree/EncryptionManager.h b/dbx_tree/EncryptionManager.h new file mode 100644 index 0000000..763df26 --- /dev/null +++ b/dbx_tree/EncryptionManager.h @@ -0,0 +1,107 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#ifndef _MSC_VER
+#include <stdint.h>
+#else
+#include "stdint.h"
+#endif
+#include "sigslot.h"
+
+#define __INTERFACE_ONLY__
+#include "encryption/Cipher.h"
+#undef __INTERFACE_ONLY__
+
+#include "SHA256.h"
+#include "Interface.h"
+//#include "Thread.h"
+#include <map>
+#include <windows.h>
+
+static const uint32_t cEncryptionChangingFlag = 0x80000000;
+
+#pragma pack(push, 1)
+
+typedef struct TFileEncryption {
+ uint32_t CipherID;
+ uint32_t CipherOldID;
+ uint32_t ConversionProcess;
+ uint8_t SHA[32];
+ uint8_t SHAOld[32];
+ uint32_t Reserved[2];
+} TFileEncryption, *PFileEncryption;
+
+#pragma pack(pop)
+
+typedef struct TEncryption {
+ uint32_t CipherID;
+ wchar_t * Password;
+} TEncryption, *PEncryption;
+
+class CEncryptionManager
+{
+public:
+ CEncryptionManager();
+ ~CEncryptionManager();
+
+ typedef struct {
+ TCHAR * FilePath;
+ TCHAR * FileName;
+ uint32_t ID;
+ wchar_t * Name;
+ wchar_t * Description;
+ } TCipherItem;
+ typedef std::map<uint32_t, TCipherItem> TCipherList;
+
+ static TCipherList* CipherList; // = NULL; see cpp
+ static uint32_t CipherListRefCount; // = 0; see cpp
+ static void LoadCipherList();
+
+ bool InitEncryption(TFileEncryption & Enc);
+
+ bool AlignData(uint32_t ID, uint32_t & Start, uint32_t & End);
+ uint32_t AlignSize(uint32_t ID, uint32_t Size);
+ bool IsEncrypted(uint32_t ID);
+ void Encrypt(void* Data, uint32_t DataLength, uint32_t ID, uint32_t StartByte);
+ void Decrypt(void* Data, uint32_t DataLength, uint32_t ID, uint32_t StartByte);
+
+ bool CanChangeCipher();
+ bool ChangeCipher(TEncryption & Encryption);
+private:
+ bool m_Changing;
+ uint32_t m_ChangingProcess;
+
+ typedef enum TUsedCiphers {
+ CURRENT = 0,
+ OLD = 1,
+ COUNT = 2
+ } TUsedCiphers;
+
+ struct
+ {
+ CCipher * Cipher;
+ HMODULE CipherDLL;
+ } m_Ciphers[COUNT];
+
+};
diff --git a/dbx_tree/Entities.cpp b/dbx_tree/Entities.cpp new file mode 100644 index 0000000..73e9487 --- /dev/null +++ b/dbx_tree/Entities.cpp @@ -0,0 +1,1032 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "Entities.h"
+
+CVirtuals::CVirtuals(CBlockManager & BlockManager, TNodeRef RootNode)
+: CFileBTree<TVirtualKey, 4>::CFileBTree(BlockManager, RootNode, cVirtualNodeSignature)
+{
+
+}
+
+CVirtuals::~CVirtuals()
+{
+
+}
+
+TDBTEntityHandle CVirtuals::_DeleteRealEntity(TDBTEntityHandle hRealEntity)
+{
+ TDBTEntityHandle result;
+ TVirtualKey key;
+ TEntity * entity;
+ bool copies = false;
+ uint32_t size = sizeof(TEntity);
+ uint32_t sig = cEntitySignature;
+
+ key.RealEntity = hRealEntity;
+ key.Virtual = 0;
+
+ iterator i = LowerBound(key);
+ result = i->Virtual;
+ i.setManaged();
+ Delete(*i);
+
+ while ((i) && (i->RealEntity == hRealEntity))
+ {
+ key = *i;
+ Delete(key);
+
+ key.RealEntity = result;
+ Insert(key);
+
+ entity = m_BlockManager.ReadBlock<TEntity>(key.Virtual, size, sig);
+ if (entity)
+ {
+ entity->VParent = result;
+ m_BlockManager.UpdateBlock(key.Virtual);
+
+ copies = true;
+ } // TODO log
+ }
+
+ entity = m_BlockManager.ReadBlock<TEntity>(result, size, sig);
+ if (entity)
+ {
+ entity->Flags = entity->Flags & ~(DBT_NF_HasVirtuals | DBT_NF_IsVirtual);
+ if (copies)
+ entity->Flags |= DBT_NF_HasVirtuals;
+
+ m_BlockManager.UpdateBlock(result);
+ } // TODO log
+ return result;
+}
+
+bool CVirtuals::_InsertVirtual(TDBTEntityHandle hRealEntity, TDBTEntityHandle hVirtual)
+{
+ TVirtualKey key;
+ key.RealEntity = hRealEntity;
+ key.Virtual = hVirtual;
+
+ Insert(key);
+
+ return true;
+}
+void CVirtuals::_DeleteVirtual(TDBTEntityHandle hRealEntity, TDBTEntityHandle hVirtual)
+{
+ TVirtualKey key;
+ key.RealEntity = hRealEntity;
+ key.Virtual = hVirtual;
+
+ Delete(key);
+}
+TDBTEntityHandle CVirtuals::getParent(TDBTEntityHandle hVirtual)
+{
+ TEntity * entity;
+ uint32_t size = sizeof(TEntity);
+ uint32_t sig = cEntitySignature;
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ entity = m_BlockManager.ReadBlock<TEntity>(hVirtual, size, sig);
+ if (!entity || ((entity->Flags & DBT_NF_IsVirtual) == 0))
+ return DBT_INVALIDPARAM;
+
+ return entity->VParent;
+}
+TDBTEntityHandle CVirtuals::getFirst(TDBTEntityHandle hRealEntity)
+{
+ TEntity * entity;
+ uint32_t size = sizeof(TEntity);
+ uint32_t sig = cEntitySignature;
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ entity = m_BlockManager.ReadBlock<TEntity>(hRealEntity, size, sig);
+ if (!entity || ((entity->Flags & DBT_NF_HasVirtuals) == 0))
+ return DBT_INVALIDPARAM;
+
+ TVirtualKey key;
+ key.RealEntity = hRealEntity;
+ key.Virtual = 0;
+
+ iterator i = LowerBound(key);
+
+ if (i && (i->RealEntity == hRealEntity))
+ key.Virtual = i->Virtual;
+ else
+ key.Virtual = 0;
+
+ return key.Virtual;
+}
+TDBTEntityHandle CVirtuals::getNext(TDBTEntityHandle hVirtual)
+{
+ TEntity * entity;
+ uint32_t size = sizeof(TEntity);
+ uint32_t sig = cEntitySignature;
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ entity = m_BlockManager.ReadBlock<TEntity>(hVirtual, size, sig);
+ if (!entity || ((entity->Flags & DBT_NF_IsVirtual) == 0))
+ return DBT_INVALIDPARAM;
+
+ TVirtualKey key;
+ key.RealEntity = entity->VParent;
+ key.Virtual = hVirtual + 1;
+
+ iterator i = LowerBound(key);
+
+ if ((i) && (i->RealEntity == entity->VParent))
+ key.Virtual = i->Virtual;
+ else
+ key.Virtual = 0;
+
+ return key.Virtual;
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+CEntities::CEntities(CBlockManager & BlockManager, TDBTEntityHandle RootEntity, TNodeRef EntityRoot, CVirtuals::TNodeRef VirtualRoot)
+: CFileBTree<TEntityKey, 6>::CFileBTree(BlockManager, EntityRoot, cEntityNodeSignature),
+ m_Virtuals(BlockManager, VirtualRoot),
+
+ m_sigEntityDelete(),
+ m_sigInternalDeleteEvents(),
+ m_sigInternalDeleteSettings(),
+ m_sigInternalMergeSettings(),
+ m_sigInternalTransferEvents()
+{
+ if (RootEntity == 0)
+ m_RootEntity = _CreateRootEntity();
+ else
+ m_RootEntity = RootEntity;
+
+}
+
+CEntities::~CEntities()
+{
+
+}
+
+TDBTEntityHandle CEntities::_CreateRootEntity()
+{
+ TEntity * entity;
+ TEntityKey key = {0,0,0};
+
+ CBlockManager::WriteTransaction trans(m_BlockManager);
+
+ entity = m_BlockManager.CreateBlock<TEntity>(key.Entity, cEntitySignature);
+ entity->Flags = DBT_NF_IsGroup | DBT_NF_IsRoot;
+ m_BlockManager.UpdateBlock(key.Entity);
+ Insert(key);
+ return key.Entity;
+}
+
+void CEntities::_InternalTransferContacts(TDBTEntityHandle OldAccount, TDBTEntityHandle NewAccount)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+
+ TEntityKey key = {0,0,0};
+ iterator i = LowerBound(key);
+
+ while (i)
+ {
+ sig = cEntitySignature;
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(i->Entity, size, sig);
+ if (entity && (entity->Account == OldAccount))
+ {
+ entity->Account = NewAccount;
+ m_BlockManager.UpdateBlock(i->Entity);
+ }
+
+ ++i;
+ }
+}
+
+uint32_t CEntities::_getSettingsRoot(TDBTEntityHandle hEntity)
+{
+ /*CSettingsTree::TNodeRef*/
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+
+ if (!entity)
+ return DBT_INVALIDPARAM;
+
+ return entity->Settings;
+}
+bool CEntities::_setSettingsRoot(TDBTEntityHandle hEntity, /*CSettingsTree::TNodeRef*/ uint32_t NewRoot)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+
+ if (!entity)
+ return false;
+
+ entity->Settings = NewRoot;
+ m_BlockManager.UpdateBlock(hEntity);
+
+ return true;
+}
+
+uint32_t CEntities::_getEventsRoot(TDBTEntityHandle hEntity)
+{
+ /*CEventsTree::TNodeRef*/
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+
+ if (!entity)
+ return DBT_INVALIDPARAM;
+
+ return entity->Events;
+}
+bool CEntities::_setEventsRoot(TDBTEntityHandle hEntity, /*CEventsTree::TNodeRef*/ uint32_t NewRoot)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+
+ if (!entity)
+ return false;
+ entity->Events = NewRoot;
+ m_BlockManager.UpdateBlock(hEntity);
+
+ return true;
+}
+
+uint32_t CEntities::_getEventCount(TDBTEntityHandle hEntity)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+
+ if (!entity)
+ return DBT_INVALIDPARAM;
+
+ return entity->EventCount;
+}
+
+uint32_t CEntities::_adjustEventCount(TDBTEntityHandle hEntity, int32_t Adjust)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+
+ if (!entity)
+ return DBT_INVALIDPARAM;
+
+ if (((Adjust < 0) && ((uint32_t)(-Adjust) <= entity->EventCount)) ||
+ ((Adjust > 0) && ((0xffffffff - entity->EventCount) > (uint32_t)Adjust)))
+ {
+ entity->EventCount += Adjust;
+ m_BlockManager.UpdateBlock(hEntity);
+ }
+
+ return entity->EventCount;
+}
+
+bool CEntities::_getFirstUnreadEvent(TDBTEntityHandle hEntity, uint32_t & hEvent, uint32_t & Timestamp)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+
+ if (!entity)
+ return false;
+
+ Timestamp = entity->FirstUnreadEventTimestamp;
+ hEvent = entity->FirstUnreadEventHandle;
+ return true;
+}
+bool CEntities::_setFirstUnreadEvent(TDBTEntityHandle hEntity, uint32_t hEvent, uint32_t Timestamp)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+
+ if (!entity)
+ return false;
+ entity->FirstUnreadEventTimestamp = Timestamp;
+ entity->FirstUnreadEventHandle = hEvent;
+ m_BlockManager.UpdateBlock(hEntity);
+
+ return true;
+}
+
+TDBTEntityHandle CEntities::getParent(TDBTEntityHandle hEntity)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+ if (!entity)
+ return DBT_INVALIDPARAM;
+
+ return entity->ParentEntity;
+}
+TDBTEntityHandle CEntities::setParent(TDBTEntityHandle hEntity, TDBTEntityHandle hParent)
+{
+ TEntity *entity, *newparent, *oldparent;
+ uint32_t size = sizeof(TEntity);
+ uint32_t sig = cEntitySignature;
+
+ CBlockManager::WriteTransaction trans(m_BlockManager);
+
+ entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+ newparent = m_BlockManager.ReadBlock<TEntity>(hParent, size, sig);
+ if (!entity || !newparent)
+ return DBT_INVALIDPARAM;
+
+ oldparent = m_BlockManager.ReadBlock<TEntity>(entity->ParentEntity, size, sig);
+ if (!oldparent)
+ return DBT_INVALIDPARAM;
+
+ // update parents
+ if (--oldparent->ChildCount == 0)
+ oldparent->Flags &= ~DBT_NF_HasChildren;
+
+ if (++newparent->ChildCount == 1)
+ newparent->Flags |= DBT_NF_HasChildren;
+
+
+ m_BlockManager.UpdateBlock(entity->ParentEntity);
+ m_BlockManager.UpdateBlock(hParent);
+
+ // update rest
+
+ TEntityKey key;
+ int dif = newparent->Level - entity->Level + 1;
+
+ if (dif == 0) // no level difference, update only moved Entity
+ {
+ key.Entity = hEntity;
+ key.Level = entity->Level;
+ key.Parent = entity->ParentEntity;
+ Delete(key);
+ key.Parent = hParent;
+ Insert(key);
+
+ entity->ParentEntity = hParent;
+ m_BlockManager.UpdateBlock(hEntity);
+
+ } else {
+ TDBTEntityIterFilter filter = {0,0,0,0};
+ filter.cbSize = sizeof(filter);
+ filter.Options = DBT_NIFO_OSC_AC | DBT_NIFO_OC_AC;
+
+ TDBTEntityIterationHandle iter = IterationInit(filter, hEntity);
+
+ key.Entity = IterationNext(iter);
+
+ while ((key.Entity != 0) && (key.Entity != DBT_INVALIDPARAM))
+ {
+ size = sizeof(TEntity);
+ sig = cEntitySignature;
+ TEntity * child = m_BlockManager.ReadBlock<TEntity>(key.Entity, size, sig);
+
+ if (child)
+ {
+ key.Level = child->Level;
+ key.Parent = child->ParentEntity;
+ Delete(key);
+
+ if (key.Entity == hEntity)
+ {
+ key.Parent = hParent;
+ entity->ParentEntity = hParent;
+ }
+
+ child->Level += dif;
+ key.Level += dif;
+ m_BlockManager.UpdateBlock(key.Entity);
+
+ Insert(key);
+ } // TODO log
+ key.Entity = IterationNext(iter);
+ }
+
+ IterationClose(iter);
+ }
+
+ /// TODO raise event
+
+ return entity->ParentEntity;
+}
+
+uint32_t CEntities::getChildCount(TDBTEntityHandle hEntity)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+ if (!entity)
+ return DBT_INVALIDPARAM;
+
+ return entity->ChildCount;
+}
+
+uint32_t CEntities::getFlags(TDBTEntityHandle hEntity)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+ if (!entity)
+ return DBT_INVALIDPARAM;
+
+ return entity->Flags;
+}
+
+uint32_t CEntities::getAccount(TDBTEntityHandle hEntity)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+ if (!entity)
+ return DBT_INVALIDPARAM;
+
+ if (entity->Flags & DBT_NF_IsVirtual)
+ return getAccount(entity->VParent);
+ else if (entity->Flags & (DBT_NF_IsAccount | DBT_NF_IsGroup | DBT_NF_IsRoot))
+ return 0;
+
+ return entity->Flags;
+}
+
+TDBTEntityHandle CEntities::CreateEntity(const TDBTEntity & Entity)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+ TDBTEntityHandle haccount = 0;
+
+ CBlockManager::WriteTransaction trans(m_BlockManager);
+
+ TEntity * parent = m_BlockManager.ReadBlock<TEntity>(Entity.hParentEntity, size, sig);
+
+ if (!parent)
+ return DBT_INVALIDPARAM;
+
+ // check account specification
+ if ((Entity.fFlags == 0) && (Entity.hAccountEntity != m_RootEntity)) // TODO disable root account thing, after conversion
+ {
+ TEntity * account = m_BlockManager.ReadBlock<TEntity>(Entity.hAccountEntity, size, sig);
+ if (!account || !(account->Flags & DBT_NF_IsAccount))
+ return DBT_INVALIDPARAM;
+
+ if (account->Flags & DBT_NF_IsVirtual)
+ {
+ haccount = VirtualGetParent(Entity.hAccountEntity);
+ } else {
+ haccount = Entity.hAccountEntity;
+ }
+ }
+
+ TDBTEntityHandle hentity;
+ TEntity * entityblock = m_BlockManager.CreateBlock<TEntity>(hentity, cEntitySignature);
+ if (!entityblock)
+ return DBT_INVALIDPARAM;
+
+ TEntityKey key;
+
+ entityblock->Level = parent->Level + 1;
+ entityblock->ParentEntity = Entity.hParentEntity;
+ entityblock->Flags = Entity.fFlags;
+ entityblock->Account = haccount;
+
+ m_BlockManager.UpdateBlock(hentity);
+
+ key.Level = entityblock->Level;
+ key.Parent = entityblock->ParentEntity;
+ key.Entity = hentity;
+
+ Insert(key);
+
+ if (parent->ChildCount == 0)
+ parent->Flags = parent->Flags | DBT_NF_HasChildren;
+
+ ++parent->ChildCount;
+ m_BlockManager.UpdateBlock(Entity.hParentEntity);
+
+ return hentity;
+}
+
+unsigned int CEntities::DeleteEntity(TDBTEntityHandle hEntity)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+ TDBTEntityHandle haccount = 0;
+
+ CBlockManager::WriteTransaction trans(m_BlockManager);
+
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+
+ if (!entity)
+ return DBT_INVALIDPARAM;
+
+ TEntity * parent = m_BlockManager.ReadBlock<TEntity>(entity->ParentEntity, size, sig);
+ if (!parent)
+ return DBT_INVALIDPARAM;
+
+ m_sigEntityDelete.emit(this, hEntity);
+
+ if (entity->Flags & DBT_NF_HasVirtuals)
+ {
+ // move virtuals and make one of them real
+ TDBTEntityHandle newreal = m_Virtuals._DeleteRealEntity(hEntity);
+
+ TEntity * realblock = m_BlockManager.ReadBlock<TEntity>(newreal, size, sig);
+ if (realblock)
+ {
+ realblock->EventCount = entity->EventCount;
+ realblock->Events = entity->Events;
+
+ m_BlockManager.UpdateBlock(newreal);
+
+ m_sigInternalTransferEvents.emit(this, hEntity, newreal);
+ m_sigInternalMergeSettings.emit(this, hEntity, newreal);
+
+ if (entity->Flags & DBT_NF_IsAccount)
+ _InternalTransferContacts(hEntity, newreal);
+ } // TODO log
+ } else {
+ m_sigInternalDeleteEvents.emit(this, hEntity);
+ m_sigInternalDeleteSettings.emit(this, hEntity);
+
+ if ((entity->Flags & DBT_NF_IsAccount) && !(entity->Flags & DBT_NF_IsVirtual))
+ _InternalTransferContacts(hEntity, m_RootEntity);
+
+ }
+
+ TEntityKey key;
+ key.Level = entity->Level;
+ key.Parent = entity->ParentEntity;
+ key.Entity = hEntity;
+ Delete(key);
+
+ if (entity->Flags & DBT_NF_HasChildren) // keep the children
+ {
+ parent->Flags |= DBT_NF_HasChildren;
+ parent->ChildCount += entity->ChildCount;
+
+ TDBTEntityIterFilter filter = {0,0,0,0};
+ filter.cbSize = sizeof(filter);
+ filter.Options = DBT_NIFO_OSC_AC | DBT_NIFO_OC_AC;
+
+ TDBTEntityIterationHandle iter = IterationInit(filter, hEntity);
+ if (iter != DBT_INVALIDPARAM)
+ {
+ IterationNext(iter);
+ key.Entity = IterationNext(iter);
+
+ while ((key.Entity != 0) && (key.Entity != DBT_INVALIDPARAM))
+ {
+ size = sizeof(TEntity);
+ sig = cEntitySignature;
+ TEntity * child = m_BlockManager.ReadBlock<TEntity>(key.Entity, size, sig);
+ if (child)
+ {
+ key.Parent = child->ParentEntity;
+ key.Level = child->Level;
+ Delete(key);
+
+ if (key.Parent == hEntity)
+ {
+ key.Parent = entity->ParentEntity;
+ child->ParentEntity = entity->ParentEntity;
+ }
+
+ key.Level--;
+ m_BlockManager.UpdateBlock(key.Entity);
+
+ Insert(key);
+
+ }
+ key.Entity = IterationNext(iter);
+ }
+
+ IterationClose(iter);
+ }
+ }
+
+ if (--parent->ChildCount == 0)
+ parent->Flags = parent->Flags & (~DBT_NF_HasChildren);
+
+ m_BlockManager.UpdateBlock(entity->ParentEntity);
+
+ m_BlockManager.DeleteBlock(hEntity); // we needed this block, delete it now
+
+ return 0;
+}
+
+
+
+TDBTEntityIterationHandle CEntities::IterationInit(const TDBTEntityIterFilter & Filter, TDBTEntityHandle hParent)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+ TDBTEntityHandle haccount = 0;
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TEntity * parent = m_BlockManager.ReadBlock<TEntity>(hParent, size, sig);
+
+ if (!parent)
+ return DBT_INVALIDPARAM;
+
+ PEntityIteration iter = new TEntityIteration;
+ iter->filter = Filter;
+ iter->q = new std::deque<TEntityIterationItem>;
+ iter->parents = new std::deque<TEntityIterationItem>;
+ iter->accounts = new std::deque<TEntityIterationItem>;
+ #ifdef _MSC_VER
+ iter->returned = new stdext::hash_set<TDBTEntityHandle>;
+ #else
+ iter->returned = new __gnu_cxx::hash_set<TDBTEntityHandle>;
+ #endif
+ iter->returned->insert(hParent);
+
+ TEntityIterationItem it;
+ it.Flags = parent->Flags;
+ it.Handle = hParent;
+ it.Level = parent->Level;
+ it.Options = Filter.Options & 0x000000ff;
+ it.LookupDepth = 0;
+
+ iter->q->push_back(it);
+
+ return (TDBTEntityIterationHandle)iter;
+}
+TDBTEntityHandle CEntities::IterationNext(TDBTEntityIterationHandle Iteration)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ PEntityIteration iter = reinterpret_cast<PEntityIteration>(Iteration);
+ TEntityIterationItem item;
+ TDBTEntityHandle result = 0;
+
+ if (iter->q->empty())
+ {
+ std::deque <TEntityIterationItem> * tmp = iter->q;
+ iter->q = iter->parents;
+ iter->parents = tmp;
+ }
+
+ if (iter->q->empty())
+ {
+ std::deque <TEntityIterationItem> * tmp = iter->q;
+ iter->q = iter->accounts;
+ iter->accounts = tmp;
+ }
+
+ if (iter->q->empty() &&
+ (iter->filter.Options & DBT_NIFO_GF_USEROOT) &&
+ (iter->returned->find(m_RootEntity) == iter->returned->end()))
+ {
+ item.Handle = m_RootEntity;
+ item.Level = 0;
+ item.Options = 0;
+ item.Flags = 0;
+ item.LookupDepth = 255;
+
+ iter->filter.Options = iter->filter.Options & ~DBT_NIFO_GF_USEROOT;
+
+ iter->q->push_back(item);
+ }
+
+ if (iter->q->empty())
+ return 0;
+
+ do {
+ item = iter->q->front();
+ iter->q->pop_front();
+
+ std::deque<TEntityIterationItem> tmp;
+ TEntityIterationItem newitem;
+
+ // children
+ if ((item.Flags & DBT_NF_HasChildren) &&
+ (item.Options & DBT_NIFO_OSC_AC))
+ {
+ TEntityKey key;
+ key.Parent = item.Handle;
+ key.Level = item.Level + 1;
+
+ newitem.Level = item.Level + 1;
+ newitem.LookupDepth = item.LookupDepth;
+ newitem.Options = (iter->filter.Options / DBT_NIFO_OC_AC * DBT_NIFO_OSC_AC) & (DBT_NIFO_OSC_AC | DBT_NIFO_OSC_AO | DBT_NIFO_OSC_AOC | DBT_NIFO_OSC_AOP);
+
+ if (iter->filter.Options & DBT_NIFO_GF_DEPTHFIRST)
+ {
+ key.Entity = 0xffffffff;
+
+ CEntities::iterator c = UpperBound(key);
+ while ((c) && (c->Parent == item.Handle))
+ {
+ newitem.Handle = c->Entity;
+
+ if (iter->returned->find(newitem.Handle) == iter->returned->end())
+ {
+ TEntity * tmp = m_BlockManager.ReadBlock<TEntity>(newitem.Handle, size, sig);
+ if (tmp)
+ {
+ newitem.Flags = tmp->Flags;
+ if (((newitem.Flags & DBT_NF_IsGroup) == 0) || ((DBT_NF_IsGroup & iter->filter.fHasFlags) == 0)) // if we want only groups, we don't need to trace down Entities...
+ {
+ iter->q->push_front(newitem);
+ iter->returned->insert(newitem.Handle);
+ }
+ }
+ }
+
+ --c;
+ }
+ } else {
+ key.Entity = 0;
+
+ CEntities::iterator c = LowerBound(key);
+ while ((c) && (c->Parent == item.Handle))
+ {
+ newitem.Handle = c->Entity;
+
+ if (iter->returned->find(newitem.Handle) == iter->returned->end())
+ {
+ TEntity * tmp = m_BlockManager.ReadBlock<TEntity>(newitem.Handle, size, sig);
+ if (tmp)
+ {
+ newitem.Flags = tmp->Flags;
+ if (((newitem.Flags & DBT_NF_IsGroup) == 0) || ((DBT_NF_IsGroup & iter->filter.fHasFlags) == 0)) // if we want only groups, we don't need to trace down Entities...
+ {
+ iter->q->push_back(newitem);
+ iter->returned->insert(newitem.Handle);
+ }
+ }
+ }
+
+ ++c;
+ }
+
+ }
+ }
+
+ // parent...
+ if ((item.Options & DBT_NIFO_OSC_AP) && (item.Handle != m_RootEntity))
+ {
+ newitem.Handle = getParent(item.Handle);
+ if ((iter->returned->find(newitem.Handle) == iter->returned->end()) &&
+ (newitem.Handle != DBT_INVALIDPARAM))
+ {
+ TEntity * tmp = m_BlockManager.ReadBlock<TEntity>(newitem.Handle, size, sig);
+ if (tmp)
+ {
+ newitem.Level = item.Level - 1;
+ newitem.LookupDepth = item.LookupDepth;
+ newitem.Options = (iter->filter.Options / DBT_NIFO_OP_AC * DBT_NIFO_OSC_AC) & (DBT_NIFO_OSC_AC | DBT_NIFO_OSC_AP | DBT_NIFO_OSC_AO | DBT_NIFO_OSC_AOC | DBT_NIFO_OSC_AOP);
+ newitem.Flags = tmp->Flags;
+
+ if ((newitem.Flags & iter->filter.fDontHasFlags & DBT_NF_IsGroup) == 0) // if we don't want groups, stop it
+ {
+ iter->parents->push_back(newitem);
+ iter->returned->insert(newitem.Handle);
+ }
+ }
+ }
+ }
+
+ // virtual lookup, original Entity is the next one
+ if ((item.Flags & DBT_NF_IsVirtual) &&
+ (item.Options & DBT_NIFO_OSC_AO) &&
+ (((iter->filter.Options >> 28) >= item.LookupDepth) || ((iter->filter.Options >> 28) == 0)))
+ {
+ newitem.Handle = VirtualGetParent(item.Handle);
+
+ if ((iter->returned->find(newitem.Handle) == iter->returned->end()) &&
+ (newitem.Handle != DBT_INVALIDPARAM))
+ {
+ TEntity * tmp = m_BlockManager.ReadBlock<TEntity>(newitem.Handle, size, sig);
+ if (tmp)
+ {
+ newitem.Level = tmp->Level;
+ newitem.Options = 0;
+ newitem.Flags = tmp->Flags;
+
+ if ((item.Options & DBT_NIFO_OSC_AOC) == DBT_NIFO_OSC_AOC)
+ newitem.Options |= DBT_NIFO_OSC_AC;
+ if ((item.Options & DBT_NIFO_OSC_AOP) == DBT_NIFO_OSC_AOP)
+ newitem.Options |= DBT_NIFO_OSC_AP;
+
+ newitem.LookupDepth = item.LookupDepth + 1;
+
+ iter->q->push_front(newitem);
+ iter->returned->insert(newitem.Handle);
+ }
+ }
+ }
+
+ if (((iter->filter.fHasFlags & item.Flags) == iter->filter.fHasFlags) &&
+ ((iter->filter.fDontHasFlags & item.Flags) == 0))
+ {
+ result = item.Handle;
+
+ // account lookup
+ if (((item.Flags & (DBT_NF_IsAccount | DBT_NF_IsGroup | DBT_NF_IsRoot)) == 0) &&
+ ((item.Options & DBT_NIFO_OC_USEACCOUNT) == DBT_NIFO_OC_USEACCOUNT))
+ {
+ TDBTEntityHandle acc = item.Handle;
+ if (item.Flags & DBT_NF_IsVirtual)
+ acc = VirtualGetParent(item.Handle);
+
+ acc = getAccount(acc);
+
+ std::deque<TEntityIterationItem>::iterator acci = iter->accounts->begin();
+
+ while ((acci != iter->accounts->end()) && (acc != 0))
+ {
+ if (acci->Handle == acc)
+ acc = 0;
+ acci++;
+ }
+ if (acc != 0)
+ {
+ TEntity * tmp = m_BlockManager.ReadBlock<TEntity>(acc, size, sig);
+ if (tmp)
+ {
+ newitem.Options = 0;
+ newitem.LookupDepth = 0;
+ newitem.Handle = acc;
+ newitem.Flags = tmp->Flags;
+ newitem.Level = tmp->Level;
+ iter->accounts->push_back(newitem);
+ }
+ }
+ }
+ }
+
+ } while ((result == 0) && !iter->q->empty());
+
+ if (result == 0)
+ result = IterationNext(Iteration);
+
+ return result;
+}
+unsigned int CEntities::IterationClose(TDBTEntityIterationHandle Iteration)
+{
+ PEntityIteration iter = reinterpret_cast<PEntityIteration>(Iteration);
+
+ delete iter->q;
+ delete iter->parents;
+ delete iter->accounts;
+ delete iter->returned;
+ delete iter;
+
+ return 0;
+}
+
+
+TDBTEntityHandle CEntities::VirtualCreate(TDBTEntityHandle hRealEntity, TDBTEntityHandle hParent)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+ TDBTEntityHandle haccount = 0;
+
+ CBlockManager::WriteTransaction trans(m_BlockManager);
+
+ TEntity * realentity = m_BlockManager.ReadBlock<TEntity>(hRealEntity, size, sig);
+
+ if (!realentity || (realentity->Flags & (DBT_NF_IsGroup | DBT_NF_IsRoot)))
+ return DBT_INVALIDPARAM;
+
+ TDBTEntity entity = {0,0,0,0};
+ entity.hParentEntity = hParent;
+ entity.fFlags = DBT_NF_IsVirtual | (realentity->Flags & DBT_NF_IsAccount);
+ entity.hAccountEntity = 0;
+
+ TDBTEntityHandle result = CreateEntity(entity);
+ if (result == DBT_INVALIDPARAM)
+ return DBT_INVALIDPARAM;
+
+ TEntity * entityblock = m_BlockManager.ReadBlock<TEntity>(result, size, sig);
+ if (!entityblock)
+ return DBT_INVALIDPARAM;
+
+ if (realentity->Flags & DBT_NF_IsVirtual)
+ {
+ hRealEntity = realentity->VParent;
+ realentity = m_BlockManager.ReadBlock<TEntity>(hRealEntity, size, sig);
+
+ if (!realentity)
+ return DBT_INVALIDPARAM;
+ }
+
+ entityblock->VParent = hRealEntity;
+ m_BlockManager.UpdateBlock(result);
+
+ if ((realentity->Flags & DBT_NF_HasVirtuals) == 0)
+ {
+ realentity->Flags |= DBT_NF_HasVirtuals;
+ m_BlockManager.UpdateBlock(hRealEntity);
+ }
+
+ m_Virtuals._InsertVirtual(hRealEntity, result);
+ return result;
+}
+
+
+TDBTEntityHandle CEntities::compFirstContact()
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TEntityKey key = {0,0,0};
+ iterator i = LowerBound(key);
+ TDBTEntityHandle res = 0;
+
+ while (i && (res == 0))
+ {
+ TEntity * tmp = m_BlockManager.ReadBlock<TEntity>(i->Entity, size, sig);
+ if (tmp)
+ {
+ if ((tmp->Flags & DBT_NFM_SpecialEntity) == 0)
+ res = i->Entity;
+ }
+ if (res == 0)
+ ++i;
+ }
+
+ return res;
+}
+TDBTEntityHandle CEntities::compNextContact(TDBTEntityHandle hEntity)
+{
+ uint32_t sig = cEntitySignature;
+ uint32_t size = sizeof(TEntity);
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TEntityKey key;
+ key.Entity = hEntity;
+ TDBTEntityHandle res = 0;
+
+ TEntity * entity = m_BlockManager.ReadBlock<TEntity>(hEntity, size, sig);
+
+ if (entity)
+ {
+ key.Level = entity->Level;
+ key.Parent = entity->ParentEntity;
+ key.Entity++;
+ iterator i = LowerBound(key);
+
+ while (i && (res == 0))
+ {
+ entity = m_BlockManager.ReadBlock<TEntity>(i->Entity, size, sig);
+ if (entity)
+ {
+ if ((entity->Flags & DBT_NFM_SpecialEntity) == 0)
+ res = i->Entity;
+ }
+ if (res == 0)
+ ++i;
+ }
+ }
+
+ return res;
+}
diff --git a/dbx_tree/Entities.h b/dbx_tree/Entities.h new file mode 100644 index 0000000..579383d --- /dev/null +++ b/dbx_tree/Entities.h @@ -0,0 +1,299 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include "Interface.h"
+#include "FileBTree.h"
+#include "MREWSync.h"
+#include <deque>
+#ifdef _MSC_VER
+#include <hash_set>
+#else
+#include <ext/hash_set>
+#endif
+
+#pragma pack(push, 1) // push current alignment to stack, set alignment to 1 byte boundary
+
+
+/**
+ \brief Key Type of the VirtualsBTree
+
+ This BTree don't hold data itself, it's just for organisation
+ The virtual Entities are sorted first based on their real Entity.
+ That is for enumeration of one Entity's virtual copies, which are all stored in one block in the BTree
+**/
+typedef struct TVirtualKey {
+ TDBTEntityHandle RealEntity; /// hEntity of the duplicated RealEntity
+ TDBTEntityHandle Virtual; /// hEntity of the virtual duplicate
+
+ bool operator < (const TVirtualKey & Other) const
+ {
+ if (RealEntity != Other.RealEntity) return RealEntity < Other.RealEntity;
+ if (Virtual != Other.Virtual) return Virtual < Other.Virtual;
+ return false;
+ }
+ //bool operator <= (const TVirtualKey & Other);
+ bool operator == (const TVirtualKey & Other) const
+ {
+ return (RealEntity == Other.RealEntity) && (Virtual == Other.Virtual);
+ }
+ //bool operator >= (const TVirtualKey & Other);
+ bool operator > (const TVirtualKey & Other) const
+ {
+ if (RealEntity != Other.RealEntity) return RealEntity > Other.RealEntity;
+ if (Virtual != Other.Virtual) return Virtual > Other.Virtual;
+ return false;
+ }
+} TVirtualKey;
+
+/**
+ \brief Key Type of the EntityBTree
+
+ The Entities are sorted first based on their level. (root is first node, followed by its children)
+ That is for enumeration of one Entity's children, which are all stored in one block in the BTree
+**/
+typedef struct TEntityKey {
+ uint16_t Level; /// Level where Entity is located or parent-steps to root. Root.Level == 0, root children have level 1 etc.
+ TDBTEntityHandle Parent; /// hEntity of the Parent. Root.Parent == 0
+ TDBTEntityHandle Entity; /// hEntity of the stored Entity itself
+
+ bool operator < (const TEntityKey & Other) const
+ {
+ if (Level != Other.Level) return Level < Other.Level;
+ if (Parent != Other.Parent) return Parent < Other.Parent;
+ if (Entity != Other.Entity) return Entity < Other.Entity;
+ return false;
+ }
+ //bool operator <= (const TEntityKey & Other);
+ bool operator == (const TEntityKey & Other) const
+ {
+ return (Level == Other.Level) && (Parent == Other.Parent) && (Entity == Other.Entity);
+ }
+ //bool operator >= (const TEntityKey & Other);
+ bool operator > (const TEntityKey & Other) const
+ {
+ if (Level != Other.Level) return Level > Other.Level;
+ if (Parent != Other.Parent) return Parent > Other.Parent;
+ if (Entity != Other.Entity) return Entity > Other.Entity;
+ return false;
+ }
+} TEntityKey;
+
+/**
+ \brief The data of an Entity
+**/
+typedef struct TEntity {
+ uint16_t Level; /// Level where Entity is located or parent-steps to root. Root.Level == 0, root children have level 1 etc. !used in the BTreeKey!
+ uint16_t ChildCount; /// Count of the children !invalid for Virtual Entity!
+ TDBTEntityHandle ParentEntity; /// hEntity of the Parent. Root.Parent == 0 !used in the BTreeKey!
+ union {
+ TDBTEntityHandle VParent; /// if the Entity is Virtual this is the hEntity of the related Realnode
+ TDBTEntityHandle Account; /// if the Entity's account, only for real real normal Entities
+ };
+ uint32_t Flags; /// flags, see cEF_*
+ /*CSettingsTree::TNodeRef*/
+ uint32_t Settings; /// Offset to the SettingsBTree RootNode of this Entity, NULL if no settings are present
+ /*CEventsTree::TNodeRef*/
+ uint32_t Events; /// Offset to the EventsBTree RootNode of this Entity, NULL if no events are present !invalid for Virtal Entity!
+ uint32_t EventCount; /// Count of the stored events !invalid for Virtual Entity!
+ uint32_t FirstUnreadEventTimestamp; /// timestamp of the first unread event
+ uint32_t FirstUnreadEventHandle;/// ID of the first unread event
+ uint8_t Reserved[4]; /// reserved storage
+} TEntity;
+
+#pragma pack(pop) // pop the alignment from stack
+
+
+
+
+/**
+ \brief Manages the Virtual Entities in the Database
+
+ A virtual Entity is stored as normal Entity in the database-structure, but doesn't hold own settings/events.
+ Such an Entity has the virtual flag set and refers its original duplicate.
+ All copies are stored in this BTree sorted to the RealEntity.
+ If the RealEntity should be deleted take the first virtual duplicate and make it real. Also change the relation of other copies.
+**/
+class CVirtuals : public CFileBTree<TVirtualKey, 4>
+{
+private:
+
+protected:
+
+public:
+ CVirtuals(CBlockManager & BlockManager, TNodeRef Root);
+ virtual ~CVirtuals();
+
+ /**
+ \brief Changes reference for all copies to the first Virtual in list
+
+ \return New Original (previously first Virtual) to associate data with
+ **/
+ TDBTEntityHandle _DeleteRealEntity(TDBTEntityHandle hRealEntity);
+
+ bool _InsertVirtual(TDBTEntityHandle hRealEntity, TDBTEntityHandle hVirtual);
+ void _DeleteVirtual(TDBTEntityHandle hRealEntity, TDBTEntityHandle hVirtual);
+
+ // services:
+ TDBTEntityHandle getParent(TDBTEntityHandle hVirtual);
+ TDBTEntityHandle getFirst(TDBTEntityHandle hRealEntity);
+ TDBTEntityHandle getNext(TDBTEntityHandle hVirtual);
+};
+
+
+static const uint32_t cEntitySignature = 0x9A6B3C0D;
+static const uint16_t cEntityNodeSignature = 0x65A9;
+static const uint16_t cVirtualNodeSignature = 0x874E;
+/**
+ \brief Manages the Entities in the Database
+
+ A hEntity is equivalent to the fileoffset of its related TEntity structure
+**/
+class CEntities : public CFileBTree<TEntityKey, 6>
+{
+
+public:
+ CEntities(CBlockManager & BlockManager, TDBTEntityHandle RootEntity, TNodeRef EntityRoot, CVirtuals::TNodeRef VirtualRoot);
+ virtual ~CEntities();
+
+ typedef sigslot::signal2<CEntities *, TDBTEntityHandle> TOnEntityDelete;
+ typedef sigslot::signal2<CEntities *, TDBTEntityHandle> TOnInternalDeleteSettings;
+ typedef sigslot::signal2<CEntities *, TDBTEntityHandle> TOnInternalDeleteEvents;
+
+ typedef sigslot::signal3<CEntities *, TDBTEntityHandle, TDBTEntityHandle> TOnInternalMergeSettings;
+ typedef sigslot::signal3<CEntities *, TDBTEntityHandle, TDBTEntityHandle> TOnInternalTransferEvents;
+
+ CVirtuals::TOnRootChanged & sigVirtualRootChanged()
+ {
+ return m_Virtuals.sigRootChanged();
+ };
+
+ TOnEntityDelete & sigEntityDelete()
+ {
+ return m_sigEntityDelete;
+ };
+ TOnInternalDeleteEvents & _sigDeleteEvents()
+ {
+ return m_sigInternalDeleteEvents;
+ };
+ TOnInternalDeleteSettings & _sigDeleteSettings()
+ {
+ return m_sigInternalDeleteSettings;
+ };
+ TOnInternalMergeSettings & _sigMergeSettings()
+ {
+ return m_sigInternalMergeSettings;
+ };
+ TOnInternalTransferEvents & _sigTransferEvents()
+ {
+ return m_sigInternalTransferEvents;
+ };
+
+ //internal helpers:
+ /*CSettingsTree::TNodeRef*/
+ uint32_t _getSettingsRoot(TDBTEntityHandle hEntity);
+ bool _setSettingsRoot(TDBTEntityHandle hEntity, /*CSettingsTree::TNodeRef*/ uint32_t NewRoot);
+ uint32_t _getEventsRoot(TDBTEntityHandle hEntity);
+ bool _setEventsRoot(TDBTEntityHandle hEntity, /*CSettingsTree::TNodeRef*/ uint32_t NewRoot);
+ uint32_t _getEventCount(TDBTEntityHandle hEntity);
+ uint32_t _adjustEventCount(TDBTEntityHandle hEntity, int32_t Adjust);
+ bool _getFirstUnreadEvent(TDBTEntityHandle hEntity, uint32_t & hEvent, uint32_t & Timestamp);
+ bool _setFirstUnreadEvent(TDBTEntityHandle hEntity, uint32_t hEvent, uint32_t Timestamp);
+
+ CVirtuals & _getVirtuals()
+ {
+ return m_Virtuals;
+ };
+
+ //compatibility:
+ TDBTEntityHandle compFirstContact();
+ TDBTEntityHandle compNextContact(TDBTEntityHandle hEntity);
+ //Services:
+ TDBTEntityHandle CEntities::getRootEntity()
+ {
+ return m_RootEntity;
+ };
+
+ TDBTEntityHandle getParent(TDBTEntityHandle hEntity);
+ TDBTEntityHandle setParent(TDBTEntityHandle hEntity, TDBTEntityHandle hParent);
+ uint32_t getChildCount(TDBTEntityHandle hEntity);
+ uint32_t getFlags(TDBTEntityHandle hEntity);
+ uint32_t getAccount(TDBTEntityHandle hEntity);
+
+ TDBTEntityHandle CreateEntity(const TDBTEntity & Entity);
+ unsigned int DeleteEntity(TDBTEntityHandle hEntity);
+
+ TDBTEntityIterationHandle IterationInit(const TDBTEntityIterFilter & Filter, TDBTEntityHandle hParent);
+ TDBTEntityHandle IterationNext(TDBTEntityIterationHandle Iteration);
+ unsigned int IterationClose(TDBTEntityIterationHandle Iteration);
+
+ TDBTEntityHandle VirtualCreate(TDBTEntityHandle hRealEntity, TDBTEntityHandle hParent);
+ TDBTEntityHandle VirtualGetParent(TDBTEntityHandle hVirtual)
+ {
+ return m_Virtuals.getParent(hVirtual);
+ };
+ TDBTEntityHandle VirtualGetFirst(TDBTEntityHandle hRealEntity)
+ {
+ return m_Virtuals.getFirst(hRealEntity);
+ };
+ TDBTEntityHandle VirtualGetNext(TDBTEntityHandle hVirtual)
+ {
+ return m_Virtuals.getNext(hVirtual);
+ };
+private:
+
+protected:
+
+ typedef struct TEntityIterationItem {
+ uint8_t Options;
+ uint8_t LookupDepth;
+ uint16_t Level;
+ TDBTEntityHandle Handle;
+ uint32_t Flags;
+ } TEntityIterationItem;
+
+ typedef struct TEntityIteration {
+ TDBTEntityIterFilter filter;
+ std::deque<TEntityIterationItem> * q;
+ std::deque<TEntityIterationItem> * parents;
+ std::deque<TEntityIterationItem> * accounts;
+ #ifdef _MSC_VER
+ stdext::hash_set<TDBTEntityHandle> * returned;
+ #else
+ __gnu_cxx::hash_set<TDBTEntityHandle> * returned;
+ #endif
+ } TEntityIteration, *PEntityIteration;
+
+ TDBTEntityHandle m_RootEntity;
+ CVirtuals m_Virtuals;
+
+ TDBTEntityHandle _CreateRootEntity();
+ void _InternalTransferContacts(TDBTEntityHandle OldAccount, TDBTEntityHandle NewAccount);
+
+ TOnEntityDelete m_sigEntityDelete;
+ TOnInternalDeleteEvents m_sigInternalDeleteEvents;
+ TOnInternalDeleteSettings m_sigInternalDeleteSettings;
+ TOnInternalMergeSettings m_sigInternalMergeSettings;
+ TOnInternalTransferEvents m_sigInternalTransferEvents;
+
+};
diff --git a/dbx_tree/Events.cpp b/dbx_tree/Events.cpp new file mode 100644 index 0000000..732f624 --- /dev/null +++ b/dbx_tree/Events.cpp @@ -0,0 +1,986 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "Events.h"
+#ifndef _MSC_VER
+#include "savestrings_gcc.h"
+#endif
+
+
+CEventsTypeManager::CEventsTypeManager(CEntities & Entities, CSettings & Settings)
+: m_Entities(Entities),
+ m_Settings(Settings),
+ m_Map()
+{
+ m_Settings._EnsureModuleExists("$EventTypes");
+}
+CEventsTypeManager::~CEventsTypeManager()
+{
+ TTypeMap::iterator it = m_Map.begin();
+
+ while (it != m_Map.end())
+ {
+ delete [] it->second->ModuleName;
+ delete it->second;
+ ++it;
+ }
+}
+
+uint32_t CEventsTypeManager::MakeGlobalID(char* Module, uint32_t EventType)
+{
+ uint32_t l = static_cast<uint32_t>(strlen(Module));
+ void * buf = malloc(l + sizeof(uint32_t));
+ memcpy(buf, Module, l);
+ memcpy(((char*)buf) + l, &EventType, sizeof(uint32_t));
+
+ uint32_t h = Hash(buf, l + sizeof(uint32_t));
+ free(buf);
+
+ char * m;
+ uint32_t t;
+ while (GetType(h, m, t) && ((t != EventType) || (strcmp(m, Module) != 0)))
+ {
+ ++h;
+ }
+
+ return h;
+}
+bool CEventsTypeManager::GetType(uint32_t GlobalID, char * & Module, uint32_t & EventType)
+{
+ TTypeMap::iterator it = m_Map.find(GlobalID);
+
+ if (it == m_Map.end())
+ {
+ char n[256];
+
+ TDBTSettingDescriptor d = {0,0,0,0,0,0,0,0};
+ d.cbSize = sizeof(d);
+ d.Entity = m_Entities.getRootEntity();
+ d.pszSettingName = n;
+
+ TDBTSetting sid = {0,0,0,0};
+ TDBTSetting sname = {0,0,0,0};
+
+ sid.cbSize = sizeof(sid);
+ sid.Descriptor = &d;
+ sid.Type = DBT_ST_INT;
+
+ sname.cbSize = sizeof(sname);
+ sname.Descriptor = &d;
+ sname.Type = DBT_ST_ANSI;
+
+ sprintf_s(n, "$EventTypes/%08x/ModuleID", GlobalID);
+ TDBTSettingHandle h = m_Settings.ReadSetting(sid);
+
+ if ((h != DBT_INVALIDPARAM) && (h != 0))
+ {
+ sprintf_s(n, "$EventTypes/%08x/ModuleName", GlobalID);
+ d.Flags = 0;
+ h = m_Settings.ReadSetting(sname);
+
+ if ((h != DBT_INVALIDPARAM) && (h != 0))
+ {
+ PEventType t = new TEventType;
+
+ t->EventType = sid.Value.Int;
+
+ t->ModuleName = new char[sname.Value.Length];
+ strcpy_s(t->ModuleName, sname.Value.Length, sname.Value.pAnsi);
+
+ m_Map.insert(std::make_pair(GlobalID, t));
+
+ mir_free(sname.Value.pAnsi);
+
+ Module = t->ModuleName;
+ EventType = t->EventType;
+
+ return true;
+ }
+ }
+ } else {
+ Module = it->second->ModuleName;
+ EventType = it->second->EventType;
+
+ return true;
+ }
+
+ return false;
+}
+
+uint32_t CEventsTypeManager::EnsureIDExists(char* Module, uint32_t EventType)
+{
+ uint32_t res = MakeGlobalID(Module, EventType);
+ char * m;
+ uint32_t t;
+ if (!GetType(res, m, t))
+ {
+ char n[256];
+
+ TDBTSettingDescriptor d = {0,0,0,0,0,0,0,0};
+ d.cbSize = sizeof(d);
+ d.pszSettingName = n;
+ d.Entity = m_Entities.getRootEntity();
+
+ TDBTSetting s = {0,0,0,0};
+ s.cbSize = sizeof(s);
+ s.Descriptor = &d;
+
+ sprintf_s(n, "$EventTypes/%08x/ModuleID", res);
+ s.Type = DBT_ST_INT;
+ s.Value.Int = EventType;
+ m_Settings.WriteSetting(s);
+
+ sprintf_s(n, "$EventTypes/%08x/ModuleName", res);
+ d.Flags = 0;
+ s.Type = DBT_ST_ANSI;
+ s.Value.Length = static_cast<uint32_t>(strlen(Module) + 1);
+ s.Value.pAnsi = Module;
+ m_Settings.WriteSetting(s);
+
+ m_Settings._EnsureModuleExists(Module);
+ }
+
+ return res;
+}
+
+
+CEvents::CEvents(
+ CBlockManager & BlockManager,
+ CEncryptionManager & EncryptionManager,
+ CEntities & Entities,
+ CSettings & Settings
+)
+: m_BlockManager(BlockManager),
+ m_EncryptionManager(EncryptionManager),
+ m_Entities(Entities),
+ m_Types(Entities, Settings),
+ m_EntityEventsMap()
+{
+ m_Entities._sigDeleteEvents().connect(this, &CEvents::onDeleteEvents);
+ m_Entities._sigTransferEvents().connect(this, &CEvents::onTransferEvents);
+}
+
+CEvents::~CEvents()
+{
+ TEntityEventsMap::iterator i = m_EntityEventsMap.begin();
+ while (i != m_EntityEventsMap.end())
+ {
+ delete i->second->RealTree;
+ delete i->second->VirtualTree;
+ delete i->second;
+ ++i;
+ }
+}
+
+void CEvents::onRootChanged(void* EventsTree, CEventsTree::TNodeRef NewRoot)
+{
+ m_Entities._setEventsRoot(reinterpret_cast<CEventsTree*>(EventsTree)->Entity(), NewRoot);
+}
+
+void CEvents::onDeleteEventCallback(void * Tree, const TEventKey & Key, uint32_t Param)
+{
+ m_BlockManager.DeleteBlock(Key.Event);
+}
+
+void CEvents::onDeleteVirtualEventCallback(void * Tree, const TEventKey & Key, uint32_t Param)
+{
+ m_BlockManager.DeleteBlock(Key.Event);
+}
+void CEvents::onDeleteEvents(CEntities * Entities, TDBTEntityHandle hEntity)
+{
+ PEntityEventsRecord record = getEntityRecord(hEntity);
+
+ if (record == NULL)
+ return;
+
+ m_Entities._setEventsRoot(hEntity, 0);
+
+ if (record->VirtualCount)
+ {
+ CVirtualEventsTree::TDeleteCallback callback;
+ callback.connect(this, &CEvents::onDeleteVirtualEventCallback);
+
+ record->VirtualTree->DeleteTree(&callback, hEntity);
+ }
+ delete record->VirtualTree;
+
+ CEventsTree::TDeleteCallback callback;
+ callback.connect(this, &CEvents::onDeleteEventCallback);
+ record->RealTree->DeleteTree(&callback, hEntity);
+ delete record->RealTree;
+ m_EntityEventsMap.erase(hEntity);
+}
+void CEvents::onTransferEvents(CEntities * Entities, TDBTEntityHandle Source, TDBTEntityHandle Dest)
+{
+ PEntityEventsRecord record = getEntityRecord(Source);
+
+ if (record == NULL)
+ return;
+
+ if (record->VirtualCount)
+ {
+ TEventKey key = {0,0};
+
+ CVirtualEventsTree::iterator i = record->VirtualTree->LowerBound(key);
+
+ while (i)
+ {
+ uint32_t sig = cEventSignature;
+ uint32_t size = 0;
+ TEvent * tmp = m_BlockManager.ReadBlock<TEvent>(i->Event, size, sig);
+ if (tmp)
+ {
+ tmp->Entity = Dest;
+ m_BlockManager.UpdateBlock(i->Event);
+ }
+ ++i;
+ }
+ }
+
+ {
+ TEventKey key = {0,0};
+
+ CEventsTree::iterator i = record->RealTree->LowerBound(key);
+ while (i)
+ {
+ uint32_t sig = cEventSignature;
+ uint32_t size = 0;
+ TEvent * tmp = m_BlockManager.ReadBlock<TEvent>(i->Event, size, sig);
+ if (tmp)
+ {
+ tmp->Entity = Dest;
+ m_BlockManager.UpdateBlock(i->Event);
+ }
+ ++i;
+ }
+
+ m_Entities._setEventsRoot(Source, 0);
+ m_Entities._setEventsRoot(Dest, record->RealTree->getRoot());
+ m_Entities._adjustEventCount(Dest, m_Entities._getEventCount(Source));
+ m_Entities._getFirstUnreadEvent(Source, key.Event, key.TimeStamp);
+ m_Entities._setFirstUnreadEvent(Dest, key.Event, key.TimeStamp);
+ }
+
+ record->VirtualTree->Entity(Dest);
+ record->RealTree->Entity(Dest);
+ m_EntityEventsMap.erase(Source);
+ m_EntityEventsMap.insert(std::make_pair(Dest, record));
+}
+
+CEvents::PEntityEventsRecord CEvents::getEntityRecord(TDBTEntityHandle hEntity)
+{
+ TEntityEventsMap::iterator i = m_EntityEventsMap.find(hEntity);
+ if (i != m_EntityEventsMap.end())
+ return i->second;
+
+ uint32_t root = m_Entities._getEventsRoot(hEntity);
+ if (root == DBT_INVALIDPARAM)
+ return NULL;
+
+ PEntityEventsRecord res = new TEntityEventsRecord;
+ res->RealTree = new CEventsTree(m_BlockManager, root, hEntity);
+ res->RealTree->sigRootChanged().connect(this, &CEvents::onRootChanged);
+ res->VirtualTree = new CVirtualEventsTree(hEntity);
+ res->VirtualCount = 0;
+ res->FirstVirtualUnread.TimeStamp = 0;
+ res->FirstVirtualUnread.Event = 0;
+ m_EntityEventsMap.insert(std::make_pair(hEntity, res));
+
+ return res;
+}
+
+inline uint32_t CEvents::adjustVirtualEventCount(PEntityEventsRecord Record, int32_t Adjust)
+{
+ if (((Adjust < 0) && ((uint32_t)(-Adjust) <= Record->VirtualCount)) ||
+ ((Adjust > 0) && ((0xffffffff - Record->VirtualCount) > (uint32_t)Adjust)))
+ {
+ Record->VirtualCount += Adjust;
+ }
+
+ return Record->VirtualCount;
+}
+
+inline bool CEvents::MarkEventsTree(TEventBase::iterator Iterator, TDBTEventHandle FirstUnread)
+{
+ uint32_t sig, size;
+ bool b = true;
+ bool res = false;
+ while (Iterator && b)
+ {
+ sig = cEventSignature;
+ size = 0;
+ TEvent * event = m_BlockManager.ReadBlock<TEvent>(Iterator->Event, size, sig);
+ if (event)
+ {
+ if (Iterator->Event == FirstUnread)
+ res = true;
+
+ if ((event->Flags & DBT_EF_READ) == 0)
+ {
+ event->Flags |= DBT_EF_READ;
+ m_BlockManager.UpdateBlock(Iterator->Event);
+ --Iterator;
+ } else {
+ b = false;
+ }
+ } else {
+ --Iterator;
+ }
+ }
+ return res;
+}
+inline void CEvents::FindNextUnreadEvent(TEventBase::iterator & Iterator)
+{
+ uint32_t sig, size;
+ while (Iterator)
+ {
+ sig = cEventSignature;
+ size = 0;
+ TEvent * event = m_BlockManager.ReadBlock<TEvent>(Iterator->Event, size, sig);
+ if (event)
+ {
+ if (event->Flags & DBT_EF_READ)
+ ++Iterator;
+ else
+ return;
+ } else {
+ ++Iterator;
+ }
+ }
+}
+
+unsigned int CEvents::GetBlobSize(TDBTEventHandle hEvent)
+{
+ uint32_t sig = cEventSignature;
+ uint32_t size = 0;
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+ TEvent * event = m_BlockManager.ReadBlock<TEvent>(hEvent, size, sig);
+ if (!event)
+ return DBT_INVALIDPARAM;
+
+ return event->DataLength;
+}
+
+unsigned int CEvents::Get(TDBTEventHandle hEvent, TDBTEvent & Event)
+{
+ uint32_t sig = cEventSignature;
+ uint32_t size = 0;
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TEvent * event = m_BlockManager.ReadBlock<TEvent>(hEvent, size, sig);
+ if (!event)
+ return DBT_INVALIDPARAM;
+
+ uint8_t * blob = reinterpret_cast<uint8_t *>(event + 1);
+
+ if (!m_Types.GetType(event->Type, Event.ModuleName, Event.EventType))
+ {
+ Event.EventType = event->Type;
+ Event.ModuleName = "???";
+ }
+
+ Event.Flags = event->Flags;
+ if (m_BlockManager.IsForcedVirtual(hEvent))
+ Event.Flags |= DBT_EF_VIRTUAL;
+
+ Event.Timestamp = event->TimeStamp;
+
+ if (Event.cbBlob < event->DataLength)
+ Event.pBlob = (uint8_t*) mir_realloc(Event.pBlob, event->DataLength);
+
+ memcpy(Event.pBlob, blob, event->DataLength);
+ Event.cbBlob = event->DataLength;
+
+ return 0;
+}
+
+unsigned int CEvents::GetCount(TDBTEntityHandle hEntity)
+{
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ uint32_t res = m_Entities._getEventCount(hEntity);
+ PEntityEventsRecord record = getEntityRecord(hEntity);
+
+ if ((res == DBT_INVALIDPARAM) || !record)
+ return DBT_INVALIDPARAM;
+
+ res = res + record->VirtualCount; // access to Virtual Count need sync, too
+
+ return res;
+}
+
+unsigned int CEvents::Delete(TDBTEventHandle hEvent)
+{
+ uint32_t sig = cEventSignature;
+ uint32_t size = 0;
+ TEventKey key = {0, hEvent};
+
+ CBlockManager::WriteTransaction trans(m_BlockManager);
+
+ TEvent * event = m_BlockManager.ReadBlock<TEvent>(hEvent, size, sig);
+ if (!event)
+ return DBT_INVALIDPARAM;
+
+ key.TimeStamp = event->TimeStamp;
+
+ PEntityEventsRecord record = getEntityRecord(event->Entity);
+ if (!record)
+ return DBT_INVALIDPARAM;
+
+ if (m_BlockManager.IsForcedVirtual(hEvent))
+ {
+ if (record->VirtualTree->Delete(key))
+ {
+ adjustVirtualEventCount(record, -1);
+
+ if (record->FirstVirtualUnread.Event == hEvent)
+ {
+ CVirtualEventsTree::iterator vi = record->VirtualTree->LowerBound(key);
+ FindNextUnreadEvent(vi);
+ if (vi)
+ {
+ record->FirstVirtualUnread = *vi;
+ } else {
+ record->FirstVirtualUnread.TimeStamp = 0;
+ record->FirstVirtualUnread.Event = 0;
+ }
+ }
+ }
+ } else { // real event
+ if (record->RealTree->Delete(key))
+ {
+ m_Entities._adjustEventCount(event->Entity, -1);
+ TEventKey unreadkey;
+ m_Entities._getFirstUnreadEvent(event->Entity, unreadkey.Event, unreadkey.TimeStamp);
+ if (unreadkey.Event == hEvent)
+ {
+ CEventsTree::iterator it = record->VirtualTree->LowerBound(key);
+ FindNextUnreadEvent(it);
+ if (it)
+ {
+ m_Entities._setFirstUnreadEvent(event->Entity, it->Event, it->TimeStamp);
+ } else {
+ m_Entities._setFirstUnreadEvent(event->Entity, 0, 0);
+ }
+ }
+ }
+ }
+ m_BlockManager.DeleteBlock(hEvent);
+
+ return 0;
+}
+
+TDBTEventHandle CEvents::Add(TDBTEntityHandle hEntity, TDBTEvent & Event)
+{
+ TDBTEventHandle res = 0;
+ TEvent * event;
+
+ CBlockManager::WriteTransaction trans(m_BlockManager);
+
+ uint32_t eflags = m_Entities.getFlags(hEntity);
+ PEntityEventsRecord record = getEntityRecord(hEntity);
+
+ if ((eflags == DBT_INVALIDPARAM) ||
+ ((eflags & (DBT_NF_IsGroup | DBT_NF_IsRoot)) == DBT_NF_IsGroup) || // forbid events in groups. but allow root to have system history
+ !record)
+ {
+ return DBT_INVALIDPARAM;
+ }
+
+ if (eflags & DBT_NF_IsVirtual)
+ hEntity = m_Entities.VirtualGetParent(hEntity);
+
+ uint8_t *blobdata = Event.pBlob;
+ bool bloballocated = false;
+
+ if (Event.Flags & DBT_EF_VIRTUAL)
+ {
+ event = m_BlockManager.CreateBlockVirtual<TEvent>(res, cEventSignature, sizeof(TEvent) + Event.cbBlob);
+ } else {
+ event = m_BlockManager.CreateBlock<TEvent>(res, cEventSignature, sizeof(TEvent) + Event.cbBlob);
+ }
+
+ if (!event)
+ return DBT_INVALIDPARAM;
+
+ TEventKey key = {0,0};
+
+ event->TimeStamp = Event.Timestamp;
+ event->Flags = Event.Flags & ~DBT_EF_VIRTUAL;
+ event->Type = m_Types.EnsureIDExists(Event.ModuleName, Event.EventType);
+ event->DataLength = Event.cbBlob;
+ event->Entity = hEntity;
+
+ key.TimeStamp = event->TimeStamp;
+ key.Event = res;
+ memcpy(event + 1, Event.pBlob, Event.cbBlob);
+
+ m_BlockManager.UpdateBlock(res);
+
+ if (Event.Flags & DBT_EF_VIRTUAL)
+ {
+ record->VirtualTree->Insert(key);
+ adjustVirtualEventCount(record, +1);
+ if (!(Event.Flags & DBT_EF_READ) && ((record->FirstVirtualUnread.Event == 0) || (key < record->FirstVirtualUnread)))
+ {
+ record->FirstVirtualUnread = key;
+ }
+ } else {
+ record->RealTree->Insert(key);
+ m_Entities._adjustEventCount(hEntity, +1);
+
+ if (!(Event.Flags & DBT_EF_READ))
+ {
+ TEventKey unreadkey;
+ if (m_Entities._getFirstUnreadEvent(hEntity, unreadkey.Event, unreadkey.TimeStamp) &&
+ ((unreadkey.Event == 0) || (key < unreadkey)))
+ {
+ m_Entities._setFirstUnreadEvent(hEntity, key.Event, key.TimeStamp);
+ }
+ }
+ }
+
+ return res;
+}
+unsigned int CEvents::MarkRead(TDBTEventHandle hEvent)
+{
+ uint32_t sig = cEventSignature;
+ uint32_t size = 0;
+ TEventKey key = {0, hEvent};
+
+ CBlockManager::WriteTransaction trans(m_BlockManager);
+
+ TEvent * event = m_BlockManager.ReadBlock<TEvent>(hEvent, size, sig);
+
+ if (!event)
+ return DBT_INVALIDPARAM;
+
+ key.TimeStamp = event->TimeStamp;
+
+ if (event->Flags & DBT_EF_READ)
+ return event->Flags;
+
+ PEntityEventsRecord record = getEntityRecord(event->Entity);
+ if (!record)
+ return DBT_INVALIDPARAM;
+
+ CEventsTree::iterator it = record->RealTree->UpperBound(key);
+ CVirtualEventsTree::iterator vi = record->VirtualTree->UpperBound(key);
+
+ m_Entities._getFirstUnreadEvent(event->Entity, key.Event, key.TimeStamp);
+ if (MarkEventsTree(it, key.Event))
+ {
+ FindNextUnreadEvent(++it);
+ if (it)
+ {
+ m_Entities._setFirstUnreadEvent(event->Entity, it->Event, it->TimeStamp);
+ } else {
+ m_Entities._setFirstUnreadEvent(event->Entity, 0, 0);
+ }
+ }
+ if (MarkEventsTree(vi, record->FirstVirtualUnread.Event))
+ {
+ FindNextUnreadEvent(++vi);
+ if (vi)
+ {
+ record->FirstVirtualUnread = *it;
+ } else {
+ record->FirstVirtualUnread.TimeStamp = 0;
+ record->FirstVirtualUnread.Event = 0;
+ }
+ }
+
+ return event->Flags | DBT_EF_READ;
+}
+unsigned int CEvents::WriteToDisk(TDBTEventHandle hEvent)
+{
+ uint32_t sig = cEventSignature;
+ uint32_t size = 0;
+ TEventKey key;
+ key.Event = hEvent;
+
+ CBlockManager::WriteTransaction trans(m_BlockManager);
+
+ if (!m_BlockManager.IsForcedVirtual(hEvent))
+ return DBT_INVALIDPARAM;
+
+ TEvent * event = m_BlockManager.ReadBlock<TEvent>(hEvent, size, sig);
+ if (!event || (size < sizeof(TEvent)))
+ return DBT_INVALIDPARAM;
+
+ PEntityEventsRecord record = getEntityRecord(event->Entity);
+ if (!record)
+ return DBT_INVALIDPARAM;
+
+ key.TimeStamp = event->TimeStamp;
+ key.Event = hEvent;
+
+ if (record->VirtualTree->Delete(key))
+ adjustVirtualEventCount(record, -1);
+
+ if (record->RealTree->Insert(key))
+ m_Entities._adjustEventCount(event->Entity, +1);
+ m_BlockManager.WriteBlockToDisk(hEvent);
+
+ return 0;
+}
+
+TDBTEntityHandle CEvents::getEntity(TDBTEventHandle hEvent)
+{
+ uint32_t sig = cEventSignature;
+ uint32_t size = 0;
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+ TEvent * event = m_BlockManager.ReadBlock<TEvent>(hEvent, size, sig);
+ if (!event)
+ return DBT_INVALIDPARAM;
+
+ return event->Entity;
+}
+
+TDBTEventIterationHandle CEvents::IterationInit(TDBTEventIterFilter & Filter)
+{
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ PEntityEventsRecord record = getEntityRecord(Filter.hEntity);
+
+ if (!record)
+ return DBT_INVALIDPARAM;
+
+ std::queue<TEventBase * > q;
+ q.push(record->RealTree);
+ q.push(record->VirtualTree);
+
+ TDBTEntityIterFilter f = {0,0,0,0};
+ f.cbSize = sizeof(f);
+ f.Options = Filter.Options;
+
+ TDBTEntityIterationHandle citer = m_Entities.IterationInit(f, Filter.hEntity);
+ if (citer != DBT_INVALIDPARAM)
+ {
+ m_Entities.IterationNext(citer);
+ TDBTEntityHandle c = m_Entities.IterationNext(citer);
+ while (c != 0)
+ {
+ record = getEntityRecord(c);
+ if (record)
+ {
+ q.push(record->RealTree);
+ q.push(record->VirtualTree);
+ }
+
+ c = m_Entities.IterationNext(citer);
+ }
+
+ m_Entities.IterationClose(citer);
+ }
+
+ for (unsigned j = 0; j < Filter.ExtraCount; ++j)
+ {
+ record = getEntityRecord(Filter.ExtraEntities[j]);
+ if (record)
+ {
+ q.push(record->RealTree);
+ q.push(record->VirtualTree);
+ }
+ }
+
+ PEventIteration iter = new TEventIteration;
+ iter->Filter = Filter;
+ iter->LastEvent = 0;
+ iter->Heap = NULL;
+
+ TEventKey key;
+ key.TimeStamp = Filter.tSince;
+ key.Event = 0;
+
+ while (!q.empty())
+ {
+ TEventBase * b = q.front();
+ q.pop();
+
+ TEventBase::iterator it = b->LowerBound(key);
+ if (it)
+ {
+ TEventBase::iterator * it2 = new TEventBase::iterator(it);
+ it2->setManaged();
+ if (iter->Heap)
+ {
+ iter->Heap->Insert(*it2);
+ } else {
+ iter->Heap = new TEventsHeap(*it2, TEventsHeap::ITForward, true);
+ }
+ }
+ }
+
+ if (iter->Heap == NULL)
+ {
+ delete iter;
+ iter = (PEventIteration)DBT_INVALIDPARAM;
+ }
+
+ return reinterpret_cast<TDBTEventIterationHandle>(iter);
+}
+
+TDBTEventHandle CEvents::IterationNext(TDBTEventIterationHandle Iteration)
+{
+ PEventIteration iter = reinterpret_cast<PEventIteration>(Iteration);
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TDBTEventHandle res = 0;
+ TEventBase::iterator it = iter->Heap->Top();
+
+ while ((it) && (it.wasDeleted() || ((it->TimeStamp <= iter->Filter.tTill) && (it->Event == iter->LastEvent))))
+ {
+ iter->Heap->Pop();
+ it = iter->Heap->Top();
+ }
+
+ if ((it) && !it.wasDeleted() && (it->TimeStamp <= iter->Filter.tTill))
+ {
+ res = it->Event;
+ iter->Heap->Pop();
+ }
+
+ if (res)
+ {
+ iter->LastEvent = res;
+ if (iter->Filter.Event)
+ {
+ iter->Filter.Event->EventType = 0;
+ Get(res, *iter->Filter.Event);
+ }
+ }
+
+ return res;
+}
+
+unsigned int CEvents::IterationClose(TDBTEventIterationHandle Iteration)
+{
+ PEventIteration iter = reinterpret_cast<PEventIteration>(Iteration);
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+ delete iter->Heap;
+ delete iter;
+ return 0;
+}
+
+
+TDBTEventHandle CEvents::compFirstEvent(TDBTEntityHandle hEntity)
+{
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TDBTEventHandle res = 0;
+
+ PEntityEventsRecord record = getEntityRecord(hEntity);
+ if (!record)
+ return 0;
+
+ TEventKey key = {0,0};
+ CEventsTree::iterator i = record->RealTree->LowerBound(key);
+ CVirtualEventsTree::iterator vi = record->VirtualTree->LowerBound(key);
+
+ if (i && vi)
+ {
+ if (*i < *vi)
+ {
+ res = i->Event;
+ } else {
+ res = vi->Event;
+ }
+ } else if (i)
+ {
+ res = i->Event;
+ } else if (vi)
+ {
+ res = vi->Event;
+ }
+
+ return res;
+}
+TDBTEventHandle CEvents::compFirstUnreadEvent(TDBTEntityHandle hEntity)
+{
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TDBTEventHandle res = 0;
+
+ PEntityEventsRecord record = getEntityRecord(hEntity);
+ if (!record)
+ return 0;
+
+ TEventKey key;
+ m_Entities._getFirstUnreadEvent(hEntity, key.Event, key.TimeStamp);
+ if (key.Event)
+ {
+ if (record->FirstVirtualUnread.Event && (record->FirstVirtualUnread < key))
+ {
+ res = record->FirstVirtualUnread.Event;
+ } else {
+ res = key.Event;
+ }
+ } else if (record->FirstVirtualUnread.Event)
+ {
+ res = record->FirstVirtualUnread.Event;
+ }
+
+ return res;
+}
+TDBTEventHandle CEvents::compLastEvent(TDBTEntityHandle hEntity)
+{
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+ TDBTEventHandle res = 0;
+
+ PEntityEventsRecord record = getEntityRecord(hEntity);
+ if (!record)
+ return 0;
+
+ TEventKey key = {0xffffffff, 0xffffffff};
+
+ CEventsTree::iterator i = record->RealTree->UpperBound(key);
+ CVirtualEventsTree::iterator vi = record->VirtualTree->UpperBound(key);
+
+ if (i && vi)
+ {
+ if (*i > *vi)
+ {
+ res = i->Event;
+ } else {
+ res = vi->Event;
+ }
+ } else if (i)
+ {
+ res = i->Event;
+ } else if (vi)
+ {
+ res = vi->Event;
+ }
+
+ return res;
+}
+TDBTEventHandle CEvents::compNextEvent(TDBTEventHandle hEvent)
+{
+ uint32_t sig = cEventSignature;
+ uint32_t size = 0;
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TEvent * event = m_BlockManager.ReadBlock<TEvent>(hEvent, size, sig);
+
+ if (!event)
+ return 0;
+
+ TEventKey key = {event->TimeStamp, hEvent};
+
+ PEntityEventsRecord record = getEntityRecord(event->Entity);
+
+ if (!record)
+ return 0;
+
+ if (key.Event == 0xffffffff)
+ {
+ if (key.TimeStamp == 0xffffffff)
+ {
+ return 0;
+ } else {
+ ++key.TimeStamp;
+ }
+ } else {
+ ++key.Event;
+ }
+
+ CEventsTree::iterator i = record->RealTree->LowerBound(key);
+ CVirtualEventsTree::iterator vi = record->VirtualTree->LowerBound(key);
+
+ TDBTEventHandle res = 0;
+ if (i && vi)
+ {
+ if (*i < *vi)
+ {
+ res = i->Event;
+ } else {
+ res = vi->Event;
+ }
+ } else if (i)
+ {
+ res = i->Event;
+ } else if (vi)
+ {
+ res = vi->Event;
+ }
+
+ return res;
+}
+TDBTEventHandle CEvents::compPrevEvent(TDBTEventHandle hEvent)
+{
+ uint32_t sig = cEventSignature;
+ uint32_t size = 0;
+
+ CBlockManager::ReadTransaction trans(m_BlockManager);
+
+ TEvent * event = m_BlockManager.ReadBlock<TEvent>(hEvent, size, sig);
+
+ if (!event)
+ return 0;
+
+ TEventKey key = {event->TimeStamp, hEvent};
+
+ PEntityEventsRecord record = getEntityRecord(event->Entity);
+ if (!record)
+ return 0;
+
+ if (key.Event == 0)
+ {
+ if (key.TimeStamp == 0)
+ {
+ return 0;
+ } else {
+ --key.TimeStamp;
+ }
+ } else {
+ --key.Event;
+ }
+
+ CEventsTree::iterator i = record->RealTree->UpperBound(key);
+ CVirtualEventsTree::iterator vi = record->VirtualTree->UpperBound(key);
+
+ TDBTEventHandle res = 0;
+ if (i && vi)
+ {
+ if (*i > *vi)
+ {
+ res = i->Event;
+ } else {
+ res = vi->Event;
+ }
+ } else if (i)
+ {
+ res = i->Event;
+ } else if (vi)
+ {
+ res = vi->Event;
+ }
+
+ return res;
+}
diff --git a/dbx_tree/Events.h b/dbx_tree/Events.h new file mode 100644 index 0000000..7a3d50f --- /dev/null +++ b/dbx_tree/Events.h @@ -0,0 +1,263 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include "Interface.h"
+#include "BTree.h"
+#include "FileBTree.h"
+#include "BlockManager.h"
+#include "IterationHeap.h"
+#include "Entities.h"
+#include "Settings.h"
+#include "Hash.h"
+#include "EncryptionManager.h"
+#include "sigslot.h"
+
+#ifdef _MSC_VER
+#include <hash_map>
+#include <hash_set>
+#else
+#include <ext/hash_map>
+#include <ext/hash_set>
+#endif
+#include <queue>
+#include <time.h>
+#include <windows.h>
+
+#pragma pack(push, 1) // push current alignment to stack, set alignment to 1 byte boundary
+
+/**
+ \brief Key Type of the EventsBTree
+
+ The Key consists of a timestamp, seconds elapsed since 1.1.1970
+ and an Index, which makes it possible to store multiple events with the same timestamp
+**/
+typedef struct TEventKey {
+ uint32_t TimeStamp; /// timestamp at which the event occoured
+ TDBTEventHandle Event;
+
+ bool operator < (const TEventKey & Other) const
+ {
+ if (TimeStamp != Other.TimeStamp) return TimeStamp < Other.TimeStamp;
+ if (Event != Other.Event) return Event < Other.Event;
+ return false;
+ }
+ //bool operator <= (const TEventKey & Other);
+ bool operator == (const TEventKey & Other) const
+ {
+ return (TimeStamp == Other.TimeStamp) && (Event == Other.Event);
+ }
+
+ //bool operator >= (const TEventKey & Other);
+ bool operator > (const TEventKey & Other) const
+ {
+ if (TimeStamp != Other.TimeStamp) return TimeStamp > Other.TimeStamp;
+ if (Event != Other.Event) return Event > Other.Event;
+ return false;
+ }
+
+} TEventKey;
+
+/**
+ \brief The data of an Event
+
+ A event's data is variable length. The data is a TDBTEvent-structure followed by varaible length data.
+ - fixed data
+ - blob data (mostly UTF8 message body)
+**/
+typedef struct TEvent {
+ uint32_t Flags; /// Flags
+ uint32_t TimeStamp; /// Timestamp of the event (seconds elapsed since 1.1.1970) used as key element
+ uint32_t Type; /// Eventtype
+ TDBTEntityHandle Entity; /// hEntity which owns this event
+ uint32_t DataLength; /// Length of the stored data in bytes
+
+ uint8_t Reserved[8]; /// reserved storage
+} TEvent;
+
+#pragma pack(pop)
+
+
+static const uint32_t cEventSignature = 0x365A7E92;
+static const uint16_t cEventNodeSignature = 0x195C;
+
+/**
+ \brief Manages the Events Index in the Database
+**/
+class CEventsTree : public CFileBTree<TEventKey, 16>
+{
+private:
+ TDBTEntityHandle m_Entity;
+
+public:
+ CEventsTree(CBlockManager & BlockManager, TNodeRef RootNode, TDBTEntityHandle Entity)
+ : CFileBTree<TEventKey, 16>::CFileBTree(BlockManager, RootNode, cEventNodeSignature),
+ m_Entity(Entity)
+ { };
+ ~CEventsTree()
+ { };
+
+ TDBTEntityHandle Entity()
+ {
+ return m_Entity;
+ };
+ void Entity(TDBTEntityHandle NewEntity)
+ {
+ m_Entity = NewEntity;
+ };
+};
+
+/**
+ \brief Manages the Virtual Events Index
+ Sorry for duplicating code...
+**/
+class CVirtualEventsTree : public CBTree<TEventKey, 16>
+{
+private:
+ TDBTEntityHandle m_Entity;
+
+public:
+ CVirtualEventsTree(TDBTEntityHandle Entity)
+ : CBTree<TEventKey, 16>::CBTree(0),
+ m_Entity(Entity)
+ { };
+
+ ~CVirtualEventsTree()
+ { };
+
+ TDBTEntityHandle Entity()
+ {
+ return m_Entity;
+ };
+ void Entity(TDBTEntityHandle NewEntity)
+ {
+ m_Entity = NewEntity;
+ };
+};
+
+
+class CEventsTypeManager
+{
+public:
+ CEventsTypeManager(CEntities & Entities, CSettings & Settings);
+ ~CEventsTypeManager();
+
+ uint32_t MakeGlobalID(char* Module, uint32_t EventType);
+ bool GetType(uint32_t GlobalID, char * & Module, uint32_t & EventType);
+ uint32_t EnsureIDExists(char* Module, uint32_t EventType);
+
+private:
+ typedef struct TEventType {
+ char * ModuleName;
+ uint32_t EventType;
+ } TEventType, *PEventType;
+ #ifdef _MSC_VER
+ typedef stdext::hash_map<uint32_t, PEventType> TTypeMap;
+ #else
+ typedef __gnu_cxx::hash_map<uint32_t, PEventType> TTypeMap;
+ #endif
+
+ CEntities & m_Entities;
+ CSettings & m_Settings;
+ TTypeMap m_Map;
+
+};
+
+
+class CEvents : public sigslot::has_slots<>
+{
+public:
+
+ CEvents(
+ CBlockManager & BlockManager,
+ CEncryptionManager & EncryptionManager,
+ CEntities & Entities,
+ CSettings & Settings
+ );
+ ~CEvents();
+
+ //compatibility
+ TDBTEventHandle compFirstEvent(TDBTEntityHandle hEntity);
+ TDBTEventHandle compFirstUnreadEvent(TDBTEntityHandle hEntity);
+ TDBTEventHandle compLastEvent(TDBTEntityHandle hEntity);
+ TDBTEventHandle compNextEvent(TDBTEventHandle hEvent);
+ TDBTEventHandle compPrevEvent(TDBTEventHandle hEvent);
+
+ //services
+ unsigned int GetBlobSize(TDBTEventHandle hEvent);
+ unsigned int Get(TDBTEventHandle hEvent, TDBTEvent & Event);
+ unsigned int GetCount(TDBTEntityHandle hEntity);
+ unsigned int Delete(TDBTEventHandle hEvent);
+ TDBTEventHandle Add(TDBTEntityHandle hEntity, TDBTEvent & Event);
+ unsigned int MarkRead(TDBTEventHandle hEvent);
+ unsigned int WriteToDisk(TDBTEventHandle hEvent);
+
+ TDBTEntityHandle getEntity(TDBTEventHandle hEvent);
+
+ TDBTEventIterationHandle IterationInit(TDBTEventIterFilter & Filter);
+ TDBTEventHandle IterationNext(TDBTEventIterationHandle Iteration);
+ unsigned int IterationClose(TDBTEventIterationHandle Iteration);
+
+
+private:
+ typedef CBTree<TEventKey, 16> TEventBase;
+ typedef struct
+ {
+ CEventsTree * RealTree;
+ CVirtualEventsTree * VirtualTree;
+ uint32_t VirtualCount;
+ TEventKey FirstVirtualUnread;
+ } TEntityEventsRecord, *PEntityEventsRecord;
+ #ifdef _MSC_VER
+ typedef stdext::hash_map<TDBTEntityHandle, TEntityEventsRecord*> TEntityEventsMap;
+ #else
+ typedef __gnu_cxx::hash_map<TDBTEntityHandle, TEntityEventsRecord*> TEntityEventsMap;
+ #endif
+ typedef CIterationHeap<TEventBase::iterator> TEventsHeap;
+
+ CBlockManager & m_BlockManager;
+ CEncryptionManager & m_EncryptionManager;
+
+ CEntities & m_Entities;
+ CEventsTypeManager m_Types;
+
+ TEntityEventsMap m_EntityEventsMap;
+
+ typedef struct TEventIteration {
+ TDBTEventIterFilter Filter;
+ TEventsHeap * Heap;
+ TDBTEventHandle LastEvent;
+ } TEventIteration, *PEventIteration;
+
+ void onRootChanged(void* EventsTree, CEventsTree::TNodeRef NewRoot);
+
+ void onDeleteEventCallback(void * Tree, const TEventKey & Key, uint32_t Param);
+ void onDeleteVirtualEventCallback(void * Tree, const TEventKey & Key, uint32_t Param);
+ void onDeleteEvents(CEntities * Entities, TDBTEntityHandle hEntity);
+ void onTransferEvents(CEntities * Entities, TDBTEntityHandle Source, TDBTEntityHandle Dest);
+
+ PEntityEventsRecord getEntityRecord(TDBTEntityHandle hEntity);
+ uint32_t adjustVirtualEventCount(PEntityEventsRecord Record, int32_t Adjust);
+ bool MarkEventsTree(TEventBase::iterator Iterator, TDBTEventHandle FirstUnread);
+ void FindNextUnreadEvent(TEventBase::iterator & Iterator);
+};
diff --git a/dbx_tree/FileAccess.cpp b/dbx_tree/FileAccess.cpp new file mode 100644 index 0000000..a0aa85a --- /dev/null +++ b/dbx_tree/FileAccess.cpp @@ -0,0 +1,299 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "FileAccess.h"
+#include <vector>
+#ifndef _MSC_VER
+#include "savestrings_gcc.h"
+#define _time32 time
+#endif
+#include "Logger.h"
+
+const uint8_t CFileAccess::cJournalSignature[20] = "Miranda IM Journal!";
+
+CFileAccess::CFileAccess(const TCHAR* FileName)
+{
+ m_FileName = new TCHAR[_tcslen(FileName) + 1];
+ m_Journal.FileName = new TCHAR[_tcslen(FileName) + 5];
+ _tcscpy_s(m_FileName, _tcslen(FileName) + 1, FileName);
+ _tcscpy_s(m_Journal.FileName, _tcslen(FileName) + 5, FileName);
+ _tcscat_s(m_Journal.FileName, _tcslen(FileName) + 5, _T(".jrn"));
+
+ m_ReadOnly = false;
+ m_LastSize = 0;
+ m_Size = 0;
+ m_Journal.Use = false;
+ m_Journal.hFile = 0;
+ m_Journal.BufUse = 0;
+
+ m_LastAllocTime = _time32(NULL);
+}
+
+CFileAccess::~CFileAccess()
+{
+ CloseHandle(m_Journal.hFile);
+ DeleteFile(m_Journal.FileName);
+
+ delete [] m_FileName;
+ delete [] m_Journal.FileName;
+}
+
+uint32_t CFileAccess::Size(uint32_t NewSize)
+{
+ m_Size = NewSize;
+ if (!m_Journal.Use)
+ {
+ NewSize = (NewSize + m_AllocGranularity - 1) & ~(m_AllocGranularity - 1);
+
+ if (NewSize == 0)
+ NewSize = m_AllocGranularity;
+
+ if (NewSize != m_AllocSize)
+ {
+ m_AllocSize = _SetSize(NewSize);
+
+ // adapt Alloc Granularity
+ uint32_t t = _time32(NULL);
+ uint32_t d = t - m_LastAllocTime;
+ m_LastAllocTime = t;
+
+ if (d < 30) // increase alloc stepping
+ {
+ if (m_AllocGranularity < m_MaxAllocGranularity)
+ m_AllocGranularity = m_AllocGranularity << 1;
+ } else if (d > 120) // decrease alloc stepping
+ {
+ if (m_AllocGranularity > m_MinAllocGranularity)
+ m_AllocGranularity = m_AllocGranularity >> 1;
+ }
+ }
+ }
+ return NewSize;
+}
+
+
+void CFileAccess::CleanJournal()
+{
+ SetFilePointer(m_Journal.hFile, 0, NULL, FILE_BEGIN);
+ SetEndOfFile(m_Journal.hFile);
+
+ DWORD written;
+ WriteFile(m_Journal.hFile, cJournalSignature, sizeof(cJournalSignature), &written, NULL);
+}
+
+void CFileAccess::ProcessJournal()
+{
+ uint32_t filesize = GetFileSize(m_Journal.hFile, NULL) - sizeof(cJournalSignature);
+ SetFilePointer(m_Journal.hFile, sizeof(cJournalSignature), NULL, FILE_BEGIN);
+
+ uint8_t* buf = (uint8_t*)malloc(filesize);
+ TJournalEntry* e = (TJournalEntry*)buf;
+ DWORD read = 0;
+ if (!ReadFile(m_Journal.hFile, buf, filesize, &read, NULL) || (read != filesize))
+ {
+ free(buf);
+ LOGSYS(logCRITICAL, _T("Couldn't flush the journal because ReadFile failed!"));
+ return;
+ }
+
+ m_Journal.Use = false;
+ std::vector<TJournalEntry*> currentops;
+
+ while (filesize >= sizeof(TJournalEntry))
+ {
+ switch (e->Signature)
+ {
+ case 'fini':
+ {
+ Size(e->Size);
+
+ std::vector<TJournalEntry*>::iterator i = currentops.begin();
+ while (i != currentops.end())
+ {
+ switch ((*i)->Signature)
+ {
+ case 'writ':
+ {
+ if ((*i)->Address + (*i)->Size <= m_AllocSize)
+ {
+ _Write(*i + 1, (*i)->Address, (*i)->Size);
+ } else if ((*i)->Address < m_AllocSize)
+ {
+ _Write(*i + 1, (*i)->Address, m_AllocSize - (*i)->Address);
+ }
+ } break;
+ case 'inva':
+ {
+ if ((*i)->Address + (*i)->Size <= m_AllocSize)
+ {
+ _Invalidate((*i)->Address, (*i)->Size);
+ } else if ((*i)->Address < m_AllocSize)
+ {
+ _Invalidate((*i)->Address, m_AllocSize - (*i)->Address);
+ }
+ } break;
+ }
+ ++i;
+ }
+ currentops.clear();
+
+ e++;
+ filesize = filesize - sizeof(TJournalEntry);
+ } break;
+ case 'writ':
+ {
+ if (filesize < sizeof(e) + e->Size)
+ {
+ filesize = 0;
+ } else {
+ currentops.push_back(e);
+ filesize = filesize - sizeof(TJournalEntry) - e->Size;
+ e = (TJournalEntry*)((uint8_t*)e + sizeof(TJournalEntry) + e->Size);
+ }
+ } break;
+ case 'inva':
+ {
+ if (filesize < sizeof(e))
+ {
+ filesize = 0;
+ } else {
+ currentops.push_back(e);
+ e++;
+ filesize = filesize - sizeof(TJournalEntry);
+ }
+ } break;
+ default:
+ {
+ filesize = 0;
+ if (currentops.size())
+ LOG(logWARNING, _T("Your database journal wasn't completely written to disk."));
+ } break;
+ }
+ }
+
+ _Flush();
+
+ CleanJournal();
+
+ free(buf);
+ m_Journal.Use = true;
+}
+
+void CFileAccess::InitJournal()
+{
+ m_Journal.hFile = CreateFile(m_Journal.FileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0);
+ if (m_Journal.hFile == INVALID_HANDLE_VALUE)
+ {
+ LOGSYS(logCRITICAL, _T("CreateFile failed on Journal %s"), m_Journal.FileName);
+ return;
+ }
+
+ uint8_t h[sizeof(cJournalSignature)];
+ DWORD read;
+ if (ReadFile(m_Journal.hFile, &h, sizeof(h), &read, NULL) && (read == sizeof(h)) && (0 == memcmp(h, cJournalSignature, sizeof(h))))
+ {
+ TCHAR * bckname = new TCHAR[_tcslen(m_FileName) + 12];
+ _tcscpy_s(bckname, _tcslen(m_FileName) + 12, m_FileName);
+ _tcscat_s(bckname, _tcslen(m_FileName) + 12, _T(".autobackup"));
+
+ TCHAR * bckjrnname = new TCHAR[_tcslen(m_Journal.FileName) + 12];
+ _tcscpy_s(bckjrnname, _tcslen(m_Journal.FileName) + 12, m_Journal.FileName);
+ _tcscat_s(bckjrnname, _tcslen(m_Journal.FileName) + 12, _T(".autobackup"));
+
+ char buf[4096];
+ HANDLE hfilebackup = CreateFile(bckname, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0);
+ if (hfilebackup)
+ {
+ uint32_t i = 0;
+ while (i + sizeof(buf) <= m_AllocSize)
+ {
+ DWORD w;
+ _Read(buf, i, sizeof(buf));
+ i += sizeof(buf);
+ WriteFile(hfilebackup, buf, sizeof(buf), &w, NULL);
+ }
+ if (i < m_AllocSize)
+ {
+ DWORD w;
+ _Read(buf, i, m_AllocSize - i);
+ WriteFile(hfilebackup, buf, m_AllocSize - i, &w, NULL);
+ }
+
+ CloseHandle(hfilebackup);
+ }
+
+ HANDLE hjrnfilebackup = CreateFile(bckjrnname, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0);
+ if (hjrnfilebackup)
+ {
+ uint32_t i = 0;
+
+ uint32_t filesize = GetFileSize(m_Journal.hFile, NULL);
+ SetFilePointer(m_Journal.hFile, 0, NULL, FILE_BEGIN);
+
+ while (i + sizeof(buf) <= filesize)
+ {
+ DWORD w, r;
+ ReadFile(m_Journal.hFile, buf, sizeof(buf), &r, NULL);
+ i += sizeof(buf);
+ WriteFile(hjrnfilebackup, buf, sizeof(buf), &w, NULL);
+ }
+ if (i < filesize)
+ {
+ DWORD w, r;
+ ReadFile(m_Journal.hFile, buf, filesize - i, &r, NULL);
+ WriteFile(hjrnfilebackup, buf, filesize - i, &w, NULL);
+ }
+ CloseHandle(hjrnfilebackup);
+ }
+
+ TCHAR* path = bckname;
+ TCHAR* fn = _tcsrchr(m_Journal.FileName, _T('\\'));
+ TCHAR* bfn = _tcsrchr(bckname, _T('\\'));
+ TCHAR* jrn = _tcsrchr(bckjrnname, _T('\\'));
+ if (bfn) // truncate path var
+ *bfn = 0;
+
+ if (hfilebackup || hjrnfilebackup)
+ {
+ LOG(logWARNING,
+ _T("Journal \"%s\" was found on start.\nBackup \"%s\"%s created and backup \"%s\"%s created.\nYou may delete these file(s) after successful start from \"%s\"."),
+ fn?fn+1:m_Journal.FileName,
+ bfn?bfn+1:bckname, (hfilebackup!=INVALID_HANDLE_VALUE)?_T(" was successfully"):_T(" could not be"),
+ jrn?jrn+1:bckjrnname, (hjrnfilebackup!=INVALID_HANDLE_VALUE)?_T(" was successfully"):_T(" could not be"),
+ path);
+ } else {
+ LOG(logWARNING,
+ _T("Journal \"%s\" was found on start.\nBackups \"%s\"and \"%s\" could not be created in \"%s\"."),
+ fn?fn+1:m_Journal.FileName,
+ bfn?bfn+1:bckname,
+ jrn?jrn+1:bckjrnname,
+ path);
+ }
+
+ delete [] bckname;
+ delete [] bckjrnname;
+
+ ProcessJournal();
+ }
+
+ CleanJournal();
+}
diff --git a/dbx_tree/FileAccess.h b/dbx_tree/FileAccess.h new file mode 100644 index 0000000..f49643e --- /dev/null +++ b/dbx_tree/FileAccess.h @@ -0,0 +1,191 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include <windows.h>
+#include <time.h>
+#include "stdint.h"
+#include "sigslot.h"
+
+class CFileAccess
+{
+public:
+ static const uint8_t cJournalSignature[20];
+
+ CFileAccess(const TCHAR* FileName);
+ virtual ~CFileAccess();
+
+
+ uint32_t Read(void* Buf, uint32_t Source, uint32_t Size)
+ {
+ return _Read(Buf, Source, Size);
+ };
+
+ bool Write(void* Buf, uint32_t Dest, uint32_t Size)
+ {
+ if (m_Journal.Use)
+ {
+ DWORD written;
+
+ TJournalEntry * data = reinterpret_cast<TJournalEntry*>(m_Journal.Buffer + m_Journal.BufUse);
+ data->Signature = 'writ';
+ data->Address = Dest;
+ data->Size = Size;
+ m_Journal.BufUse += 12;
+ if (Size + m_Journal.BufUse < sizeof(m_Journal.Buffer) - 12) // one journal header has always to fit in
+ {
+ memcpy(m_Journal.Buffer + m_Journal.BufUse, Buf, Size);
+ m_Journal.BufUse += Size;
+ } else {
+ WriteFile(m_Journal.hFile, m_Journal.Buffer, m_Journal.BufUse, &written, NULL);
+ WriteFile(m_Journal.hFile, Buf, Size, &written, NULL);
+
+ m_Journal.BufUse = 0;
+ }
+ } else {
+ _Write(Buf, Dest, Size);
+ }
+
+ return true;
+ };
+
+ void Invalidate(uint32_t Dest, uint32_t Size)
+ {
+ if (m_Journal.Use)
+ {
+ DWORD written;
+
+ TJournalEntry * data = reinterpret_cast<TJournalEntry*>(m_Journal.Buffer + m_Journal.BufUse);
+ data->Signature = 'inva';
+ data->Address = Dest;
+ data->Size = Size;
+ m_Journal.BufUse += 12;
+ if (m_Journal.BufUse > sizeof(m_Journal.Buffer) - 12)
+ {
+ WriteFile(m_Journal.hFile, m_Journal.Buffer, m_Journal.BufUse, &written, NULL);
+ m_Journal.BufUse = 0;
+ }
+ } else {
+ _Invalidate(Dest, Size);
+ }
+ };
+
+ void Flush()
+ {
+ if (m_Journal.Use)
+ {
+ if (m_Journal.BufUse)
+ {
+ DWORD written;
+ WriteFile(m_Journal.hFile, m_Journal.Buffer, m_Journal.BufUse, &written, NULL);
+ m_Journal.BufUse = 0;
+ }
+ FlushFileBuffers(m_Journal.hFile);
+ } else {
+ _Flush();
+ }
+ };
+
+ void UseJournal(bool UseIt)
+ {
+ m_Journal.Use = UseIt;
+ };
+
+ void CompleteTransaction()
+ {
+ if (m_Size != m_LastSize)
+ {
+ m_sigFileSizeChanged.emit(this, m_Size);
+ m_LastSize = m_Size;
+ }
+ };
+ void CloseTransaction()
+ {
+ if (m_Journal.Use)
+ {
+ DWORD written;
+
+ TJournalEntry * data = reinterpret_cast<TJournalEntry*>(m_Journal.Buffer + m_Journal.BufUse);
+ data->Signature = 'fini';
+ data->Address = 0;
+ data->Size = m_Size;
+
+ WriteFile(m_Journal.hFile, m_Journal.Buffer, m_Journal.BufUse + 12, &written, NULL);
+ m_Journal.BufUse = 0;
+ }
+ };
+
+ void CleanJournal();
+
+ uint32_t Size(uint32_t NewSize);
+ uint32_t Size()
+ { return m_Size; };
+ void ReadOnly(bool ReadOnly)
+ { m_ReadOnly = ReadOnly; };
+ bool ReadOnly()
+ { return m_ReadOnly; };
+
+ typedef sigslot::signal2<CFileAccess *, uint32_t> TOnFileSizeChanged;
+
+ TOnFileSizeChanged & sigFileSizeChanged()
+ { return m_sigFileSizeChanged; };
+
+protected:
+ TCHAR* m_FileName;
+ struct {
+ bool Use;
+ TCHAR* FileName;
+ HANDLE hFile;
+
+ uint8_t Buffer[4096];
+ uint32_t BufUse;
+ } m_Journal;
+
+ uint32_t m_Size;
+ uint32_t m_AllocSize;
+ uint32_t m_AllocGranularity;
+ uint32_t m_MinAllocGranularity;
+ uint32_t m_MaxAllocGranularity;
+ uint32_t m_LastAllocTime;
+ bool m_ReadOnly;
+ uint32_t m_LastSize;
+
+ TOnFileSizeChanged m_sigFileSizeChanged;
+ virtual uint32_t _Read(void* Buf, uint32_t Source, uint32_t Size) = 0;
+ virtual uint32_t _Write(void* Buf, uint32_t Dest, uint32_t Size) = 0;
+ virtual void _Invalidate(uint32_t Dest, uint32_t Size) = 0;
+ virtual uint32_t _SetSize(uint32_t Size) = 0;
+ virtual void _Flush() = 0;
+
+#pragma pack (push, 1)
+ typedef struct TJournalEntry
+ {
+ uint32_t Signature;
+ uint32_t Address;
+ uint32_t Size;
+ } TJournalEntry;
+#pragma pack (pop)
+
+ void InitJournal();
+ void ProcessJournal();
+};
diff --git a/dbx_tree/FileBTree.h b/dbx_tree/FileBTree.h new file mode 100644 index 0000000..3a9e58a --- /dev/null +++ b/dbx_tree/FileBTree.h @@ -0,0 +1,102 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+#include "BTree.h"
+#include "BlockManager.h"
+#include "Logger.h"
+
+template <typename TKey, uint16_t SizeParam = 4>
+class CFileBTree : public CBTree<TKey, SizeParam>
+{
+private:
+
+protected:
+ CBlockManager & m_BlockManager;
+ uint16_t cSignature;
+
+ virtual void PrepareInsertOperation();
+ virtual TNode * CreateNewNode(TNodeRef & NodeRef);
+ virtual void DeleteNode(TNodeRef Node);
+ virtual TNode * Read(TNodeRef Node);
+ virtual void Write(TNodeRef Node);
+public:
+ CFileBTree(CBlockManager & BlockManager, typename CBTree<TKey, SizeParam>::TNodeRef RootNode, uint16_t Signature);
+ virtual ~CFileBTree();
+};
+
+
+
+
+template <typename TKey, uint16_t SizeParam>
+CFileBTree<TKey, SizeParam>::CFileBTree(CBlockManager & BlockManager, typename CBTree<TKey, SizeParam>::TNodeRef RootNode, uint16_t Signature)
+: CBTree<TKey, SizeParam>::CBTree(RootNode),
+ m_BlockManager(BlockManager)
+{
+ cSignature = Signature;
+ CBTree<TKey, SizeParam>::m_DestroyTree = false;
+}
+
+template <typename TKey, uint16_t SizeParam>
+CFileBTree<TKey, SizeParam>::~CFileBTree()
+{
+ CBTree<TKey, SizeParam>::m_DestroyTree = false;
+}
+
+
+template <typename TKey, uint16_t SizeParam>
+void CFileBTree<TKey, SizeParam>::PrepareInsertOperation()
+{
+
+}
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::TNode * CFileBTree<TKey, SizeParam>::CreateNewNode(typename CBTree<TKey, SizeParam>::TNodeRef & NodeRef)
+{
+ return reinterpret_cast<TNode*>( m_BlockManager.CreateBlock<uint32_t>(NodeRef, cSignature << 16, sizeof(typename CBTree<TKey, SizeParam>::TNode) - 4) - 1);
+}
+
+template <typename TKey, uint16_t SizeParam>
+void CFileBTree<TKey, SizeParam>::DeleteNode(typename CBTree<TKey, SizeParam>::TNodeRef Node)
+{
+ m_BlockManager.DeleteBlock(Node);
+}
+
+template <typename TKey, uint16_t SizeParam>
+typename CBTree<TKey, SizeParam>::TNode * CFileBTree<TKey, SizeParam>::Read(typename CBTree<TKey, SizeParam>::TNodeRef Node)
+{
+ uint32_t sig = 0;
+ uint32_t size = 0;
+ TNode * res = reinterpret_cast<TNode*>( m_BlockManager.ReadBlock<uint32_t>(Node, size, sig) - 1); /// HACK using knowledge about the blockmanager here
+
+ CHECK(res->Signature == cSignature,
+ logCRITICAL, _T("Signature check failed"));
+
+ return res;
+}
+
+template <typename TKey, uint16_t SizeParam>
+void CFileBTree<TKey, SizeParam>::Write(typename CBTree<TKey, SizeParam>::TNodeRef Node)
+{
+ m_BlockManager.UpdateBlock(Node, 0);
+}
+
diff --git a/dbx_tree/Filestructure.txt b/dbx_tree/Filestructure.txt Binary files differnew file mode 100644 index 0000000..6128b5f --- /dev/null +++ b/dbx_tree/Filestructure.txt diff --git a/dbx_tree/Hash.cpp b/dbx_tree/Hash.cpp new file mode 100644 index 0000000..f0541c2 --- /dev/null +++ b/dbx_tree/Hash.cpp @@ -0,0 +1,183 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "Hash.h"
+
+
+/// lookup3, by Bob Jenkins, May 2006, Public Domain.
+#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+#define HASHmix(a,b,c) \
+{ \
+ a -= c; a ^= rot(c, 4); c += b; \
+ b -= a; b ^= rot(a, 6); a += c; \
+ c -= b; c ^= rot(b, 8); b += a; \
+ a -= c; a ^= rot(c,16); c += b; \
+ b -= a; b ^= rot(a,19); a += c; \
+ c -= b; c ^= rot(b, 4); b += a; \
+}
+#define HASHfinal(a,b,c) \
+{ \
+ c ^= b; c -= rot(b,14); \
+ a ^= c; a -= rot(c,11); \
+ b ^= a; b -= rot(a,25); \
+ c ^= b; c -= rot(b,16); \
+ a ^= c; a -= rot(c, 4); \
+ b ^= a; b -= rot(a,14); \
+ c ^= b; c -= rot(b,24); \
+}
+
+
+uint32_t Hash(const void * Data, uint32_t Length)
+{
+ register uint32_t a,b,c; // internal state
+ union { const void *ptr; uint32_t i; } u; // needed for Mac Powerbook G4
+
+ // Set up the internal state
+ a = b = c = 0xdeadbeef + Length; // + initval = 0
+
+ u.ptr = Data;
+ if ((u.i & 0x3) == 0)
+ {
+ const uint32_t *k = (const uint32_t *)Data; // read 32-bit chunks
+
+ // all but last block: aligned reads and affect 32 bits of (a,b,c)
+ while (Length > 12)
+ {
+ a += k[0];
+ b += k[1];
+ c += k[2];
+ HASHmix(a,b,c);
+ Length -= 12;
+ k += 3;
+ }
+
+ switch(Length)
+ {
+ case 12: c += k[2]; b += k[1]; a += k[0]; break;
+ case 11: c += k[2] & 0xffffff; b += k[1]; a += k[0]; break;
+ case 10: c += k[2] & 0xffff; b += k[1]; a += k[0]; break;
+ case 9 : c += k[2] & 0xff; b += k[1]; a += k[0]; break;
+ case 8 : b += k[1]; a += k[0]; break;
+ case 7 : b += k[1] & 0xffffff; a += k[0]; break;
+ case 6 : b += k[1] & 0xffff; a += k[0]; break;
+ case 5 : b += k[1] & 0xff; a += k[0]; break;
+ case 4 : a += k[0]; break;
+ case 3 : a += k[0] & 0xffffff; break;
+ case 2 : a += k[0] & 0xffff; break;
+ case 1 : a += k[0] & 0xff; break;
+ case 0 : return c; // zero length strings require no mixing
+ }
+
+ } else if ((u.i & 0x1) == 0) {
+ const uint16_t *k = (const uint16_t *)Data; /* read 16-bit chunks */
+ const uint8_t *k8;
+
+ // all but last block: aligned reads and different mixing
+ while (Length > 12)
+ {
+ a += k[0] + (((uint32_t)k[1]) << 16);
+ b += k[2] + (((uint32_t)k[3]) << 16);
+ c += k[4] + (((uint32_t)k[5]) << 16);
+ HASHmix(a,b,c);
+ Length -= 12;
+ k += 6;
+ }
+
+ // handle the last (probably partial) block
+ k8 = (const uint8_t *)k;
+ switch(Length)
+ {
+ case 12: c += k[4] + (((uint32_t)k[5]) << 16);
+ b += k[2] + (((uint32_t)k[3]) << 16);
+ a += k[0] + (((uint32_t)k[1]) << 16);
+ break;
+ case 11: c += ((uint32_t)k8[10]) << 16; // fall through
+ case 10: c += k[4];
+ b += k[2] + (((uint32_t)k[3]) << 16);
+ a += k[0] + (((uint32_t)k[1]) << 16);
+ break;
+ case 9 : c += k8[8]; // fall through
+ case 8 : b += k[2] + (((uint32_t)k[3]) << 16);
+ a += k[0] + (((uint32_t)k[1]) << 16);
+ break;
+ case 7 : b += ((uint32_t)k8[6]) << 16; // fall through
+ case 6 : b += k[2];
+ a += k[0] + (((uint32_t)k[1]) << 16);
+ break;
+ case 5 : b += k8[4]; // fall through
+ case 4 : a += k[0] + (((uint32_t)k[1]) << 16);
+ break;
+ case 3 : a += ((uint32_t)k8[2]) << 16; // fall through
+ case 2 : a += k[0];
+ break;
+ case 1 : a += k8[0];
+ break;
+ case 0 : return c; // zero length requires no mixing
+ }
+
+ } else { // need to read the key one byte at a time
+ const uint8_t *k = (const uint8_t *)Data;
+
+ // all but the last block: affect some 32 bits of (a,b,c)
+ while (Length > 12)
+ {
+ a += k[0];
+ a += ((uint32_t)k[1] ) << 8;
+ a += ((uint32_t)k[2] ) << 16;
+ a += ((uint32_t)k[3] ) << 24;
+ b += k[4];
+ b += ((uint32_t)k[5] ) << 8;
+ b += ((uint32_t)k[6] ) << 16;
+ b += ((uint32_t)k[7] ) << 24;
+ c += k[8];
+ c += ((uint32_t)k[9] ) << 8;
+ c += ((uint32_t)k[10]) << 16;
+ c += ((uint32_t)k[11]) << 24;
+ HASHmix(a,b,c);
+ Length -= 12;
+ k += 12;
+ }
+
+ // last block: affect all 32 bits of (c)
+ switch(Length) // all the case statements fall through
+ {
+ case 12: c += ((uint32_t)k[11]) << 24;
+ case 11: c += ((uint32_t)k[10]) << 16;
+ case 10: c += ((uint32_t)k[9] ) << 8;
+ case 9 : c += k[8];
+ case 8 : b += ((uint32_t)k[7] ) << 24;
+ case 7 : b += ((uint32_t)k[6] ) << 16;
+ case 6 : b += ((uint32_t)k[5] ) << 8;
+ case 5 : b += k[4];
+ case 4 : a += ((uint32_t)k[3] ) << 24;
+ case 3 : a += ((uint32_t)k[2] ) << 16;
+ case 2 : a += ((uint32_t)k[1] ) << 8;
+ case 1 : a += k[0];
+ break;
+ case 0 : return c;
+ }
+ }
+
+ HASHfinal(a,b,c);
+ return c;
+}
diff --git a/dbx_tree/Hash.h b/dbx_tree/Hash.h new file mode 100644 index 0000000..886e8b1 --- /dev/null +++ b/dbx_tree/Hash.h @@ -0,0 +1,29 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef _MSC_VER
+#include <stdint.h>
+#else
+#include "stdint.h"
+#endif
+
+uint32_t Hash(const void * Data, uint32_t Length);
diff --git a/dbx_tree/Interface.h b/dbx_tree/Interface.h new file mode 100644 index 0000000..54df3e8 --- /dev/null +++ b/dbx_tree/Interface.h @@ -0,0 +1,58 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#ifndef INTERFACE_VERSION_ONLY
+
+#define MIRANDA_VER 0x0800
+#include <windows.h>
+#include "newpluginapi.h"
+#include "m_plugins.h"
+#include "m_system.h"
+#include "m_utils.h"
+
+#include "m_langpack.h"
+
+#include "m_dbx_tree.h"
+
+extern HINSTANCE hInstance;
+extern PLUGINLINK *pluginLink;
+extern MM_INTERFACE mmi;
+extern UTF8_INTERFACE utfi;
+
+extern DATABASELINK gDBLink;
+#endif
+
+
+#define gVersion 0x00000012
+#define gResVersion 0,0,0,18
+#define gResVersionString "0.0.0.18"
+#define gInternalName "dbx_tree"
+#define gInternalNameLong "Miranda dbx_tree database driver"
+#define gDescription "Provides extended Miranda database support"
+#define gAutor "Michael 'Protogenes' Kunz"
+#define gAutorEmail "Michael.Kunz@s2005.TU-Chemnitz.de"
+#define gCopyright "2007 - 2010 Michael 'Protogenes' Kunz"
+
+
+
diff --git a/dbx_tree/IterationHeap.h b/dbx_tree/IterationHeap.h new file mode 100644 index 0000000..db06f7e --- /dev/null +++ b/dbx_tree/IterationHeap.h @@ -0,0 +1,196 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include <vector>
+
+template <class TType>
+class CIterationHeap
+{
+public:
+ enum TIterationType {ITForward, ITBackward};
+
+ CIterationHeap(TType & InitialItem, TIterationType ForBack, bool DeleteItems = true);
+ ~CIterationHeap();
+
+ bool Insert(TType & Item);
+ TType & Top();
+ void Pop();
+
+protected:
+ typedef struct THeapElement {
+ TType * Elem;
+ size_t Index;
+ } THeapElement, * PHeapElement;
+
+ std::vector <PHeapElement> m_Heap;
+ TIterationType m_Type;
+ bool m_DeleteItems;
+
+ bool A_b4_B(PHeapElement a, PHeapElement b);
+private:
+
+};
+
+
+template <class TType>
+inline bool CIterationHeap<TType>::A_b4_B(PHeapElement a, PHeapElement b)
+{
+ if (m_Type == ITForward)
+ {
+ if ((**a->Elem) == (**b->Elem)) return a->Index < b->Index;
+ return (**a->Elem) < (**b->Elem);
+ } else {
+ if ((**a->Elem) == (**b->Elem)) return a->Index > b->Index;
+ return (**a->Elem) > (**b->Elem);
+ }
+}
+
+template <class TType>
+CIterationHeap<TType>::CIterationHeap(TType & InitialItem, TIterationType MinMax, bool DeleteItems)
+: m_Heap()
+{
+ m_Heap.resize(1);
+ m_Heap.reserve(1 << 1);
+ m_Type = MinMax;
+
+ m_Heap[0] = new THeapElement;
+ m_Heap[0]->Elem = &InitialItem;
+ m_Heap[0]->Index = m_Heap.size();
+ m_DeleteItems = DeleteItems;
+}
+
+template <class TType>
+CIterationHeap<TType>::~CIterationHeap()
+{
+ unsigned int i = 0;
+ while ((i < m_Heap.size()) && (m_Heap[i]))
+ {
+ if (m_DeleteItems && m_Heap[i]->Elem)
+ delete m_Heap[i]->Elem;
+
+ delete m_Heap[i];
+ ++i;
+ }
+}
+
+template <class TType>
+bool CIterationHeap<TType>::Insert(TType & Item)
+{
+ if (!Item)
+ return false;
+
+ if (m_Heap.capacity() == m_Heap.size() + 1)
+ m_Heap.reserve(m_Heap.capacity() << 1);
+
+ m_Heap.push_back(NULL);
+
+ size_t way = m_Heap.capacity() >> 2;
+ size_t index = 0;
+ PHeapElement ins = new THeapElement;
+ ins->Elem = &Item;
+ ins->Index = m_Heap.size();
+
+ PHeapElement next;
+
+ while ((way > 0) && (index + 1 < m_Heap.size()))
+ {
+ next = m_Heap[index];
+ if ((!(*next->Elem)) || A_b4_B(ins, next))
+ {
+ m_Heap[index] = ins;
+ ins = next;
+ }
+
+ if (way & m_Heap.size()) //right
+ {
+ index = (index << 1) + 2;
+ } else { // left
+ index = (index << 1) + 1;
+ }
+ way = way >> 1;
+ }
+
+ m_Heap[index] = ins;
+
+ return true;
+}
+
+template <class TType>
+TType & CIterationHeap<TType>::Top()
+{
+ return *m_Heap[0]->Elem;
+}
+
+template <class TType>
+void CIterationHeap<TType>::Pop()
+{
+ if (m_Type == ITForward)
+ ++(*m_Heap[0]->Elem);
+ else
+ --(*m_Heap[0]->Elem);
+
+ size_t index = 0;
+ PHeapElement ins = m_Heap[0];
+ size_t big = 1;
+
+ while ((big > 0) && (index < (m_Heap.size() >> 1)))
+ {
+ big = 0;
+
+ if ((((index << 1) + 2) < m_Heap.size()) && (*m_Heap[(index << 1) + 2]->Elem))
+ {
+ if (*ins->Elem)
+ {
+ if (A_b4_B(m_Heap[(index << 1) + 2], m_Heap[(index << 1) + 1]))
+ big = (index << 1) + 2;
+ else
+ big = (index << 1) + 1;
+
+ } else {
+ m_Heap[index] = m_Heap[(index << 1) + 2];
+ index = (index << 1) + 2;
+ m_Heap[index] = ins;
+ }
+ } else if ((((index << 1) + 1) < m_Heap.size()) && (*m_Heap[(index << 1) + 1]->Elem))
+ {
+ if (*ins->Elem)
+ {
+ big = (index << 1) + 1;
+ } else {
+ m_Heap[index] = m_Heap[(index << 1) + 1];
+ index = (index << 1) + 1;
+ m_Heap[index] = ins;
+ }
+ }
+
+ if ((big > 0) && A_b4_B(m_Heap[big], ins))
+ {
+ m_Heap[index] = m_Heap[big];
+ index = big;
+ m_Heap[big] = ins;
+ } else {
+ big = 0;
+ }
+ }
+}
diff --git a/dbx_tree/Logger.cpp b/dbx_tree/Logger.cpp new file mode 100644 index 0000000..551824d --- /dev/null +++ b/dbx_tree/Logger.cpp @@ -0,0 +1,124 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "Logger.h"
+#include <process.h>
+
+CLogger CLogger::_Instance;
+
+CLogger::CLogger()
+ : m_Length(0),
+ m_Level(logNOTICE)
+{
+
+}
+
+CLogger::~CLogger()
+{
+ for (std::vector<TCHAR *>::iterator it = m_Messages.begin(); it != m_Messages.end(); ++it)
+ delete [] *it;
+}
+
+void CLogger::Append(const TCHAR * File, const TCHAR * Function, const int Line, DWORD SysState, TLevel Level, const TCHAR * Message, ...)
+{
+ if (m_Level < Level)
+ m_Level = Level;
+
+ time_t rawtime = time(NULL);
+ tm timeinfo;
+ TCHAR timebuf[80];
+ localtime_s(&timeinfo, &rawtime);
+ size_t len = _tcsftime(timebuf, sizeof(timebuf) / sizeof(*timebuf), _T("%c"), &timeinfo);
+
+ TCHAR msgbuf[4096];
+ va_list va;
+ va_start(va, Message);
+ len += _vstprintf_s(msgbuf, Message, va);
+ va_end(va);
+
+ TCHAR * message;
+ if (SysState)
+ {
+ TCHAR syserror[2048];
+ len += FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, SysState, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), syserror, 2048, NULL);
+
+ len += /*_tcslen(File) + 10 +*/ _tcslen(Function) + 32 + 12 + 1;
+
+ message = new TCHAR[len];
+ m_Length += _stprintf_s(message, len, _T("[%s - %s]\n%s\n\nSystem Error Code: %d\n%s\n\n"), timebuf, /*File, Line, */ Function, msgbuf, SysState, syserror) + 1;
+ } else {
+ len += /*_tcslen(File) + 10 +*/ _tcslen(Function) + 12 + 1;
+
+ message = new TCHAR[len];
+ m_Length += _stprintf_s(message, len, _T("[%s - %s]\n%s\n\n"), timebuf, /*File, Line, */Function, msgbuf) + 1;
+ }
+ m_Messages.push_back(message);
+}
+
+CLogger::TLevel CLogger::ShowMessage(TLevel CanAsyncTill)
+{
+ if (m_Messages.size() == 0)
+ return logNOTICE;
+
+ TCHAR * msg = new TCHAR[m_Length];
+ *msg = 0;
+
+ for (std::vector<TCHAR *>::iterator it = m_Messages.begin(); it != m_Messages.end(); ++it)
+ {
+ _tcscat_s(msg, m_Length, *it);
+ delete [] *it;
+ }
+ m_Messages.clear();
+
+ if (m_Level <= CanAsyncTill)
+ {
+ MSGBOXPARAMS * p = new MSGBOXPARAMS;
+ p->cbSize = sizeof(*p);
+ p->hwndOwner = 0;
+ p->hInstance = NULL;
+ p->lpszText = msg;
+ p->lpszCaption = _T(gInternalNameLong);
+ p->dwStyle = MB_OK | (m_Level >= logERROR)?MB_ICONHAND:((m_Level == logWARNING)?MB_ICONWARNING:MB_ICONINFORMATION);
+ p->lpszIcon = NULL;
+ p->dwContextHelpId = 0;
+ p->lpfnMsgBoxCallback = NULL;
+ p->dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
+
+ _beginthread(&CLogger::MessageBoxAsync, 0, p);
+ } else {
+ MessageBox(0, msg, _T(gInternalNameLong), MB_OK | (m_Level >= logERROR)?MB_ICONHAND:((m_Level == logWARNING)?MB_ICONWARNING:MB_ICONINFORMATION));
+ delete [] msg;
+ }
+
+ TLevel tmp = m_Level;
+ m_Level = logNOTICE;
+ return tmp;
+}
+
+void CLogger::MessageBoxAsync(void * MsgBoxParams)
+{
+ MSGBOXPARAMS* p = reinterpret_cast<MSGBOXPARAMS*>(MsgBoxParams);
+ MessageBoxIndirect(p);
+ if (p->lpszText)
+ delete [] p->lpszText;
+ delete p;
+}
\ No newline at end of file diff --git a/dbx_tree/Logger.h b/dbx_tree/Logger.h new file mode 100644 index 0000000..5c88cc7 --- /dev/null +++ b/dbx_tree/Logger.h @@ -0,0 +1,76 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include <vector>
+#include <time.h>
+#include "Interface.h"
+
+#define WIDEN2(x) L ## x
+#define WIDEN(x) WIDEN2(x)
+#define __WFILE__ WIDEN(__FILE__)
+#define __WFUNCTION__ WIDEN(__FUNCTION__)
+
+#ifdef UNICODE
+ #define LOG(Level, Message, ...) CLogger::Instance().Append(__WFILE__, __WFUNCTION__, __LINE__, 0, CLogger:: ## Level, Message, __VA_ARGS__)
+ #define LOGSYS(Level, Message, ...) CLogger::Instance().Append(__WFILE__, __WFUNCTION__, __LINE__, GetLastError(), CLogger:: ## Level, Message, __VA_ARGS__)
+#else
+ #define LOG(Level, Message, ...) CLogger::Instance().Append(__FILE__, __FUNCTION__, __LINE__, 0, CLogger:: ## Level, Message, __VA_ARGS__)
+ #define LOGSYS(Level, Message, ...) CLogger::Instance().Append(__FILE__, __FUNCTION__, __LINE__, GetLastError(), CLogger:: ## Level, Message, __VA_ARGS__)
+#endif
+
+#define CHECK(Assertion, Level, Message, ...) if (!(Assertion)) LOG(Level, Message, __VA_ARGS__)
+#define CHECKSYS(Assertion, Level, Message, ...) if (!(Assertion)) LOGSYS(Level, Message, __VA_ARGS__)
+
+class CLogger
+{
+ public:
+ enum TLevel
+ {
+ logNOTICE,
+ logWARNING,
+ logERROR,
+ logCRITICAL
+ };
+
+ CLogger();
+ ~CLogger();
+
+ void Append(const TCHAR * File, const TCHAR * Function, const int Line, DWORD SysState, TLevel Level, const TCHAR * Message, ...);
+ TLevel ShowMessage(TLevel CanAsyncTill = logERROR);
+
+ static CLogger & Instance()
+ { return _Instance; };
+
+ TLevel Level()
+ { return m_Level; };
+ protected:
+ std::vector<TCHAR *> m_Messages;
+ size_t m_Length;
+ TLevel m_Level;
+
+ static void MessageBoxAsync(void * MsgBoxParams);
+ private:
+ static CLogger _Instance;
+
+};
diff --git a/dbx_tree/MREWSync.cpp b/dbx_tree/MREWSync.cpp new file mode 100644 index 0000000..6e08be6 --- /dev/null +++ b/dbx_tree/MREWSync.cpp @@ -0,0 +1,330 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "MREWSync.h"
+#include <assert.h>
+#include "intrinsics.h"
+
+#if defined(MREW_DO_DEBUG_LOGGING) && (defined(DEBUG) || defined(_DEBUG))
+ #include <stdio.h>
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// +------------+---------------+---------------+------------+---------------+
+// | ReaderBusy | ReaderWaiting | WriterWaiting | WriterBusy | UseOddReader? |
+// +------------+---------------+---------------+------------+---------------+
+// 63..44 43..24 23..4 3 0
+///////////////////////////////////////////////////////////////////////////////////////////////////
+#define isWriterBusy(Sentinel) ((Sentinel) & 0x0000000000000008ui64)
+#define isWriterWaiting(Sentinel) ((Sentinel) & 0x0000000000fffff0ui64)
+#define isReaderWaiting(Sentinel) ((Sentinel) & 0x00000fffff000000ui64)
+#define isReaderBusy(Sentinel) ((Sentinel) & 0xfffff00000000000ui64)
+
+#define countWriterWaiting(Sentinel) (((Sentinel) & 0x0000000000fffff0ui64) >> 4)
+#define countReaderWaiting(Sentinel) (((Sentinel) & 0x00000fffff000000ui64) >> 24)
+#define countReaderBusy(Sentinel) (((Sentinel) & 0xfffff00000000000ui64) >> 44)
+
+#define WriterBusy (1ui64 << 3)
+#define WriterWaiting (1ui64 << 4)
+#define ReaderWaiting (1ui64 << 24)
+#define ReaderBusy (1ui64 << 44)
+
+#define isUseOddReader(Sentinel) ((Sentinel) & 1)
+#define useOddReader (1ui64)
+
+CMultiReadExclusiveWriteSynchronizer::CMultiReadExclusiveWriteSynchronizer(void)
+: tls(),
+ m_Sentinel(0)
+{
+ m_ReadSignal[0] = CreateEvent(NULL, TRUE, FALSE, NULL);
+ m_ReadSignal[1] = CreateEvent(NULL, TRUE, FALSE, NULL);
+ m_WriteSignal = CreateEvent(NULL, FALSE, FALSE, NULL);
+ m_WriterID = 0;
+ m_WriteRecursion = 0;
+ m_Revision = 0;
+}
+
+CMultiReadExclusiveWriteSynchronizer::~CMultiReadExclusiveWriteSynchronizer(void)
+{
+ BeginWrite();
+ CloseHandle(m_WriteSignal);
+ CloseHandle(m_ReadSignal[0]);
+ CloseHandle(m_ReadSignal[1]);
+}
+
+void CMultiReadExclusiveWriteSynchronizer::BeginRead()
+{
+ unsigned long id = GetCurrentThreadId();
+ unsigned & reccount(tls.Open(this, 0));
+
+ reccount++;
+ if ((m_WriterID != id) && (reccount == 1))
+ {
+ int64_t old;
+ int64_t newvalue;
+
+ do {
+ old = m_Sentinel;
+ if (isWriterBusy(old))
+ newvalue = old + ReaderBusy; // writer has lock -> we are going to enter after he leaves -> we are busy but have to wait
+ else if (isWriterWaiting(old))
+ newvalue = old + ReaderWaiting; // writer is waiting for lock -> don't set myself busy as he waits for all readers to leave lock
+ else
+ newvalue = old + ReaderBusy; // no writer in sight, just take lock
+
+ } while (CMPXCHG_64(m_Sentinel, newvalue, old) != old);
+
+
+ if (isWriterBusy(old) || isWriterWaiting(old))
+ {
+ if (isUseOddReader(old))
+ WaitForSingleObject(m_ReadSignal[1], INFINITE);
+ else
+ WaitForSingleObject(m_ReadSignal[0], INFINITE);
+ }
+ }
+}
+void CMultiReadExclusiveWriteSynchronizer::EndRead()
+{
+ unsigned long id = GetCurrentThreadId();
+ unsigned & reccount(tls.Open(this, 1));
+ reccount--;
+
+ if ((reccount == 0) && (m_WriterID != id))
+ {
+ int64_t old;
+ int64_t newvalue;
+
+ do {
+ old = m_Sentinel;
+ if ((countReaderBusy(old) == 1) && isWriterWaiting(old))
+ { // give control to the writer... move waiting readers to busy (but blocked)
+ newvalue = old - WriterWaiting + WriterBusy - ReaderBusy + countReaderWaiting(old) * (ReaderBusy - ReaderWaiting);
+ } else {
+ newvalue = old - ReaderBusy;
+ }
+ } while (CMPXCHG_64(m_Sentinel, newvalue, old) != old);
+
+ if ((countReaderBusy(old) == 1) && isWriterWaiting(old))
+ {
+ SetEvent(m_WriteSignal);
+ }
+ }
+
+ if (reccount == 0)
+ tls.Remove(this);
+}
+bool CMultiReadExclusiveWriteSynchronizer::BeginWrite()
+{
+ unsigned long id = GetCurrentThreadId();
+ unsigned * reccount = tls.Find(this);
+ bool res = true;
+
+ if (m_WriterID != id)
+ {
+ int64_t old;
+ int64_t newvalue;
+ unsigned int oldrevision = m_Revision;
+
+ if (reccount) // upgrade our readlock
+ {
+ do {
+ old = m_Sentinel;
+ // isWriterBusy cannot happen because we have a readlock, so we ignore it
+ if (countReaderBusy(old) > 1) // there is another reader.. we have to wait for him. set arriving readers to waiting state
+ {
+ newvalue = old + WriterWaiting - ReaderBusy;
+ } else if (isWriterWaiting(old)) // there is another writer waiting, who arrived earlier. we will sign him in and wait. we are the last reader, so we have to update the sentinel
+ {
+ newvalue = old + WriterBusy - ReaderBusy + countReaderWaiting(old) * (ReaderBusy - ReaderWaiting);
+ } else { // nobody is busy, we want the lock
+ newvalue = old + WriterBusy - ReaderBusy;
+ }
+ } while (CMPXCHG_64(m_Sentinel, newvalue, old) != old);
+
+ if (countReaderBusy(old) > 1)
+ {
+ WaitForSingleObject(m_WriteSignal, INFINITE); // someone woke me up... he had to take care of all state changes of the sentinel
+ } else if (isWriterWaiting(old)) // we will wait for the other writer, as we are the last reader, we have to wake him up
+ {
+ SetEvent(m_WriteSignal);
+ Sleep(0); // yield thread trying to keep FIFO order
+ WaitForSingleObject(m_WriteSignal, INFINITE); // someone woke me up... he had to take care of all state changes of the sentinel
+ }
+ } else { // gain write lock
+ do {
+ old = m_Sentinel;
+ if (isWriterBusy(old)) // there is a writer.. we have to wait for him
+ {
+ newvalue = old + WriterWaiting;
+ } else if (isReaderBusy(old)) // there is a reader.. we have to wait for him. set arriving readers to waiting state
+ {
+ newvalue = old + WriterWaiting;
+ } else if (isWriterWaiting(old)) // there is another writer waiting, who arrived earlier. we will wait
+ {
+ newvalue = old + WriterWaiting;
+ } else { // nobody is busy, we want the lock
+ newvalue = old + WriterBusy;
+ }
+ } while (CMPXCHG_64(m_Sentinel, newvalue, old) != old);
+
+ if (isWriterBusy(old) || isReaderBusy(old) || isWriterWaiting(old))
+ {
+ WaitForSingleObject(m_WriteSignal, INFINITE); // someone woke me up... he had to take care of all state changes of the sentinel
+ }
+ }
+ res = (oldrevision == (INC_32(m_Revision) - 1));
+
+ m_WriterID = id;
+ }
+ m_WriteRecursion++;
+
+ return res;
+}
+
+bool CMultiReadExclusiveWriteSynchronizer::EndWrite()
+{
+ unsigned long id = GetCurrentThreadId();
+ unsigned * reccount = tls.Find(this);
+
+ m_WriteRecursion--;
+
+ if (m_WriteRecursion == 0)
+ {
+ int64_t old;
+ int64_t newvalue;
+
+ m_WriterID = 0;
+
+ if (isUseOddReader(m_Sentinel)) // reset upcoming signal
+ ResetEvent(m_ReadSignal[0]);
+ else
+ ResetEvent(m_ReadSignal[1]);
+
+ if (reccount) // downgrade to reader lock
+ {
+ do {
+ old = m_Sentinel;
+ newvalue = (old ^ useOddReader) - WriterBusy + ReaderBusy; // single case... we are a waiting reader and we will keep control of the lock
+ } while (CMPXCHG_64(m_Sentinel, newvalue, old) != old);
+
+ if (isUseOddReader(old)) // allow additional readers to pass
+ SetEvent(m_ReadSignal[1]);
+ else
+ SetEvent(m_ReadSignal[0]);
+
+ } else {
+
+ do {
+ old = m_Sentinel;
+ if (isReaderBusy(old)) // give control to waiting readers
+ {
+ newvalue = (old ^ useOddReader) - WriterBusy;
+ } else if (isWriterWaiting(old)) // no reader arrived while i was working... give control to next writer
+ {
+ newvalue = (old ^ useOddReader) - WriterWaiting;
+ } else { // nobody else is there... just close lock
+ newvalue = (old ^ useOddReader) - WriterBusy;
+ }
+ } while (CMPXCHG_64(m_Sentinel, newvalue, old) != old);
+
+ if (isReaderBusy(old)) // release waiting readers
+ {
+ if (isUseOddReader(old))
+ SetEvent(m_ReadSignal[1]);
+ else
+ SetEvent(m_ReadSignal[0]);
+ } else if (isWriterWaiting(old))
+ {
+ SetEvent(m_WriteSignal);
+ }
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool CMultiReadExclusiveWriteSynchronizer::TryBeginWrite()
+{
+ unsigned long id = GetCurrentThreadId();
+ unsigned * reccount = tls.Find(this);
+
+ if (m_WriterID != id)
+ {
+ int64_t old;
+ int64_t newvalue;
+ unsigned int oldrevision = m_Revision;
+
+ if (reccount) // upgrade our readlock
+ {
+ do {
+ old = m_Sentinel;
+ // isWriterBusy cannot happen because we have a readlock, so we ignore it
+ if (countReaderBusy(old) > 1) // there is another reader.. we have to wait for him. set arriving readers to waiting state
+ {
+ return false;
+ } else if (isWriterWaiting(old)) // there is another writer waiting, who arrived earlier. we will sign him in and wait. we are the last reader, so we have to update the sentinel
+ {
+ return false;
+ } else { // nobody is busy, we want the lock
+ newvalue = old + WriterBusy - ReaderBusy;
+ }
+ } while (CMPXCHG_64(m_Sentinel, newvalue, old) != old);
+
+ } else { // gain write lock
+ do {
+ old = m_Sentinel;
+ if (isWriterBusy(old)) // there is a writer.. we have to wait for him
+ {
+ return false;
+ } else if (isReaderBusy(old)) // there is a reader.. we have to wait for him. set arriving readers to waiting state
+ {
+ return false;
+ } else if (isWriterWaiting(old)) // there is another writer waiting, who arrived earlier. we will wait
+ {
+ return false;
+ } else { // nobody is busy, we want the lock
+ newvalue = old + WriterBusy;
+ }
+ } while (CMPXCHG_64(m_Sentinel, newvalue, old) != old);
+ }
+ INC_32(m_Revision);
+
+ m_WriterID = id;
+ }
+ m_WriteRecursion++;
+
+ return true;
+}
+
+unsigned int CMultiReadExclusiveWriteSynchronizer::Waiting()
+{
+ int64_t old = m_Sentinel;
+ if (isWriterBusy(old))
+ { // cast is safe, we don't loose data because these fields are max 20 bits
+ return static_cast<unsigned int>(countReaderBusy(old) + countReaderWaiting(old) + countWriterWaiting(old));
+ } else {
+ return static_cast<unsigned int>(countReaderWaiting(old) + countWriterWaiting(old));
+ }
+};
diff --git a/dbx_tree/MREWSync.h b/dbx_tree/MREWSync.h new file mode 100644 index 0000000..2ffcbc0 --- /dev/null +++ b/dbx_tree/MREWSync.h @@ -0,0 +1,55 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include <windows.h>
+#include "TLS.h"
+#include "stdint.h"
+
+class CMultiReadExclusiveWriteSynchronizer
+{
+private:
+ uint64_t volatile m_Sentinel;
+ HANDLE m_ReadSignal[2];
+ HANDLE m_WriteSignal;
+
+ volatile uint32_t m_Revision;
+ unsigned int m_WriterID;
+ unsigned int m_WriteRecursion;
+
+ CThreadLocalStorage<CMultiReadExclusiveWriteSynchronizer, unsigned> tls;
+
+public:
+ CMultiReadExclusiveWriteSynchronizer();
+ virtual ~CMultiReadExclusiveWriteSynchronizer();
+
+ void BeginRead();
+ void EndRead();
+ bool BeginWrite();
+ bool TryBeginWrite();
+ bool EndWrite();
+
+ unsigned int Waiting();
+ unsigned int WriteRecursionCount() {return m_WriteRecursion;};
+
+};
diff --git a/dbx_tree/MappedMemory.cpp b/dbx_tree/MappedMemory.cpp new file mode 100644 index 0000000..09a1471 --- /dev/null +++ b/dbx_tree/MappedMemory.cpp @@ -0,0 +1,167 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "MappedMemory.h"
+#include "Logger.h"
+
+typedef BOOL (WINAPI *TUnmapViewOfFile)(LPCVOID);
+typedef BOOL (WINAPI *TFlushViewOfFile)(LPCVOID, SIZE_T);
+typedef HANDLE (WINAPI *TCreateFileMappingA)(HANDLE, LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD, LPCSTR);
+typedef LPVOID (WINAPI *TMapViewOfFile)(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
+
+HMODULE myKernelLib = NULL;
+TUnmapViewOfFile myUnmapViewOfFile = NULL;
+TFlushViewOfFile myFlushViewOfFile = NULL;
+TCreateFileMappingA myCreateFileMappingA = NULL;
+TMapViewOfFile myMapViewOfFile = NULL;
+
+bool CMappedMemory::InitMMAP()
+{
+ if (!myKernelLib)
+ myKernelLib = GetModuleHandleA("kernel32.dll"); // is always loaded
+
+ if (myKernelLib)
+ {
+ myUnmapViewOfFile = (TUnmapViewOfFile) GetProcAddress(myKernelLib, "UnmapViewOfFile");
+ myFlushViewOfFile = (TFlushViewOfFile) GetProcAddress(myKernelLib, "FlushViewOfFile");
+ myCreateFileMappingA = (TCreateFileMappingA) GetProcAddress(myKernelLib, "CreateFileMappingA");
+ myMapViewOfFile = (TMapViewOfFile) GetProcAddress(myKernelLib, "MapViewOfFile");
+ }
+
+ return myUnmapViewOfFile && myFlushViewOfFile && myCreateFileMappingA && myMapViewOfFile;
+}
+CMappedMemory::CMappedMemory(const TCHAR* FileName)
+: CFileAccess(FileName)
+{
+ SYSTEM_INFO sysinfo;
+
+ m_AllocSize = 0;
+ m_DirectFile = 0;
+ m_FileMapping = 0;
+ m_Base = NULL;
+
+ GetSystemInfo(&sysinfo);
+ m_AllocGranularity = sysinfo.dwAllocationGranularity; // usually 64kb
+ m_MinAllocGranularity = m_AllocGranularity; // must be at least one segment
+ m_MaxAllocGranularity = m_AllocGranularity << 4; // usually 1mb for fast increasing
+
+ m_DirectFile = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 0);
+ if (m_DirectFile == INVALID_HANDLE_VALUE)
+ LOGSYS(logCRITICAL, _T("CreateFile failed"));
+
+ uint32_t size = GetFileSize(m_DirectFile, NULL);
+ size = (size + m_AllocGranularity - 1) & ~(m_AllocGranularity - 1);
+
+ if (size == 0)
+ size = m_AllocGranularity;
+
+ _SetSize(size);
+ m_AllocSize = size;
+
+ InitJournal();
+}
+
+CMappedMemory::~CMappedMemory()
+{
+ if (m_Base)
+ {
+ myFlushViewOfFile(m_Base, NULL);
+ myUnmapViewOfFile(m_Base);
+ }
+ if (m_FileMapping)
+ CloseHandle(m_FileMapping);
+
+ if (m_DirectFile)
+ {
+ if (INVALID_SET_FILE_POINTER != SetFilePointer(m_DirectFile, m_Size, NULL, FILE_BEGIN))
+ SetEndOfFile(m_DirectFile);
+
+ FlushFileBuffers(m_DirectFile);
+ CloseHandle(m_DirectFile);
+ }
+}
+
+
+uint32_t CMappedMemory::_Read(void* Buf, uint32_t Source, uint32_t Size)
+{
+ memcpy(Buf, m_Base + Source, Size);
+ return Size;
+}
+uint32_t CMappedMemory::_Write(void* Buf, uint32_t Dest, uint32_t Size)
+{
+ memcpy(m_Base + Dest, Buf, Size);
+ return Size;
+}
+
+uint32_t CMappedMemory::_SetSize(uint32_t Size)
+{
+ if (m_Base)
+ {
+ myFlushViewOfFile(m_Base, 0);
+ myUnmapViewOfFile(m_Base);
+ }
+ if (m_FileMapping)
+ CloseHandle(m_FileMapping);
+
+ m_Base = NULL;
+ m_FileMapping = NULL;
+
+ if (INVALID_SET_FILE_POINTER == SetFilePointer(m_DirectFile, Size, NULL, FILE_BEGIN))
+ {
+ LOGSYS(logERROR, _T("SetFilePointer failed"));
+ return 0;
+ }
+
+ if (!SetEndOfFile(m_DirectFile))
+ {
+ LOGSYS(logERROR, _T("Cannot set end of file"));
+ return 0;
+ }
+
+ m_FileMapping = myCreateFileMappingA(m_DirectFile, NULL, PAGE_READWRITE, 0, Size, NULL);
+
+ if (!m_FileMapping)
+ {
+ LOGSYS(logERROR, _T("CreateFileMapping failed"));
+ return 0;
+ }
+
+ m_Base = (uint8_t*) myMapViewOfFile(m_FileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
+ if (!m_Base)
+ {
+ LOGSYS(logERROR, _T("MapViewOfFile failed"));
+ return 0;
+ }
+
+ return Size;
+}
+
+void CMappedMemory::_Invalidate(uint32_t Dest, uint32_t Size)
+{
+ memset(m_Base + Dest, 0, Size);
+}
+
+void CMappedMemory::_Flush()
+{
+ myFlushViewOfFile(m_Base, NULL);
+ FlushFileBuffers(m_DirectFile);
+}
diff --git a/dbx_tree/MappedMemory.h b/dbx_tree/MappedMemory.h new file mode 100644 index 0000000..e668628 --- /dev/null +++ b/dbx_tree/MappedMemory.h @@ -0,0 +1,47 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include <windows.h>
+#include "FileAccess.h"
+
+class CMappedMemory : public CFileAccess
+{
+private:
+ uint8_t* m_Base;
+
+ HANDLE m_DirectFile;
+ HANDLE m_FileMapping;
+protected:
+
+ uint32_t _Read(void* Buf, uint32_t Source, uint32_t Size);
+ uint32_t _Write(void* Buf, uint32_t Dest, uint32_t Size);
+ void _Invalidate(uint32_t Dest, uint32_t Size);
+ uint32_t _SetSize(uint32_t Size);
+ void _Flush();
+public:
+ CMappedMemory(const TCHAR* FileName);
+ virtual ~CMappedMemory();
+
+ static bool InitMMAP();
+};
diff --git a/dbx_tree/SHA256.cpp b/dbx_tree/SHA256.cpp new file mode 100644 index 0000000..9ca7df3 --- /dev/null +++ b/dbx_tree/SHA256.cpp @@ -0,0 +1,301 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "SHA256.h"
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(_MSC_VER) || !defined(_M_IX86)
+#define NO_ASM
+#endif
+#define SHA_LOOPUNROLL
+
+#ifndef _MSC_VER
+ #define rotr(x,n) (((x)>>(n))|((x)<<(32-(n))))
+#else
+ #define rotr(x,n) _lrotr(x,n)
+#endif
+
+
+// table of round constants
+// (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
+static const uint32_t cKey[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+
+// initialisation vector
+// (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
+static const SHA256::THash cHashInit = {
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+};
+
+
+
+SHA256::SHA256()
+{
+ SHAInit();
+}
+SHA256::~SHA256()
+{
+
+}
+void SHA256::SHAInit()
+{
+ memcpy(m_Hash, cHashInit, sizeof(m_Hash));
+ m_Length = 0;
+}
+void SHA256::SHAUpdate(void * Data, uint32_t Length)
+{
+ uint8_t * dat = (uint8_t *)Data;
+ uint32_t len = Length;
+
+ if (m_Length & 63)
+ {
+ uint32_t p = (m_Length & 63);
+ uint32_t pl = 64 - p;
+ if (pl > len)
+ pl = len;
+
+ memcpy(&(m_Block[p]), dat, pl);
+ len -= pl;
+ dat += pl;
+
+ if (p + pl == 64)
+ SHABlock();
+ }
+
+ while (len >= 64)
+ {
+ memcpy(m_Block, dat, sizeof(m_Block));
+ SHABlock();
+ len -= 64;
+ dat += 64;
+ }
+
+ if (len > 0)
+ {
+ memcpy(m_Block, dat, len);
+ }
+
+ m_Length += Length;
+}
+
+void SHA256::SHAFinal(SHA256::THash & Hash)
+{
+ uint8_t pad[128] = {
+ 0x80, 0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0
+ };
+
+ uint32_t padlen = 0;
+ if ((m_Length & 63) < 55) // 64 - 9 -> short padding
+ {
+ padlen = 64 - (m_Length & 63);
+ } else {
+ padlen = 128 - (m_Length & 63);
+ }
+
+ uint64_t l = m_Length << 3;
+ {
+ uint8_t * p = (uint8_t *) &l;
+#ifdef NO_ASM
+ pad[padlen - 1] = (uint8_t)(p[0]);
+ pad[padlen - 2] = (uint8_t)(p[1]);
+ pad[padlen - 3] = (uint8_t)(p[2]);
+ pad[padlen - 4] = (uint8_t)(p[3]);
+ pad[padlen - 5] = (uint8_t)(p[4]);
+ pad[padlen - 6] = (uint8_t)(p[5]);
+ pad[padlen - 7] = (uint8_t)(p[6]);
+ pad[padlen - 8] = (uint8_t)(p[7]);
+#else
+ uint8_t * p2 = (uint8_t *) &(pad[padlen - 8]);
+ __asm {
+ MOV ebx, p
+ MOV eax, [ebx]
+ BSWAP eax
+ MOV edx, [ebx + 4]
+ MOV ebx, p2
+ BSWAP edx
+ MOV [ebx + 4], eax
+ MOV [ebx], edx
+ }
+#endif
+ }
+
+ SHAUpdate((uint32_t *)pad, padlen);
+
+ {
+ uint8_t * h = (uint8_t *)Hash;
+ uint8_t * m = (uint8_t *)m_Hash;
+#ifdef NO_ASM
+ for (int i = 0; i < 32; i += 4)
+ {
+ h[i] = m[i + 3];
+ h[i + 1] = m[i + 2];
+ h[i + 2] = m[i + 1];
+ h[i + 3] = m[i];
+ }
+#else
+ __asm {
+ MOV esi, m
+ MOV edi, h
+ MOV ecx, 8
+ loop_label:
+ LODSD
+ BSWAP eax
+ STOSD
+ dec ecx
+ jnz loop_label
+ }
+#endif
+ }
+
+ SHAInit();
+}
+
+#define SHA256_ROUND(a,b,c,d,e,f,g,h, i) { \
+t1 = (h) + (rotr((e), 6) ^ rotr((e), 11) ^ rotr((e), 25)) + \
+ (((e) & (f)) ^ ((~(e)) & (g))) + cKey[i] + w[i]; \
+t2 = (rotr((a), 2) ^ rotr((a), 13) ^ rotr((a), 22)) + \
+ (((a) & (b)) ^ ((a) & (c)) ^ ((b) & (c))); \
+d += t1; \
+h = t1 + t2; \
+}
+
+void SHA256::SHABlock()
+{
+ uint32_t w[64];
+
+ // make Big Endian
+ {
+ uint8_t * d = (uint8_t *)w;
+ uint8_t * s = (uint8_t *)m_Block;
+#ifdef NO_ASM
+ for (int i = 0; i < 64; i += 4)
+ {
+ d[i] = s[i + 3];
+ d[i + 1] = s[i + 2];
+ d[i + 2] = s[i + 1];
+ d[i + 3] = s[i];
+ }
+#else
+ __asm {
+ MOV esi, s
+ MOV edi, d
+ MOV ecx, 16
+ loop_label:
+ LODSD
+ BSWAP eax
+ STOSD
+ dec ecx
+ jnz loop_label
+ }
+#endif
+ }
+
+ uint32_t t1, t2, a,b,c,d,e,f,g,h;
+ for (uint32_t i = 16; i < 64; ++i)
+ {
+ t1 = w[i-15];
+ t2 = w[i-2];
+ w[i] = w[i-16] + (rotr(t1, 7) ^ rotr(t1, 18) ^ (t1 >> 3)) + w[i-7] + (rotr(t2, 17) ^ rotr(t2, 19) ^ (t2 >> 10));
+ }
+
+ a = m_Hash[0];
+ b = m_Hash[1];
+ c = m_Hash[2];
+ d = m_Hash[3];
+ e = m_Hash[4];
+ f = m_Hash[5];
+ g = m_Hash[6];
+ h = m_Hash[7];
+
+#ifdef SHA_LOOPUNROLL
+ for (uint32_t i = 0; i < 64; ++i)
+ {
+ SHA256_ROUND(a,b,c,d,e,f,g,h,i); ++i;
+ SHA256_ROUND(h,a,b,c,d,e,f,g,i); ++i;
+ SHA256_ROUND(g,h,a,b,c,d,e,f,i); ++i;
+ SHA256_ROUND(f,g,h,a,b,c,d,e,i); ++i;
+ SHA256_ROUND(e,f,g,h,a,b,c,d,i); ++i;
+ SHA256_ROUND(d,e,f,g,h,a,b,c,i); ++i;
+ SHA256_ROUND(c,d,e,f,g,h,a,b,i); ++i;
+ SHA256_ROUND(b,c,d,e,f,g,h,a,i);
+ }
+#else
+ for (uint32_t i = 0; i < 64; ++i)
+ {
+ t1 = h + (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) + //s1
+ ((e & f) ^ ((~e) & g)) + cKey[i] + w[i]; //ch
+
+ t2 = (rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + //s0
+ ((a & b) ^ (a & c) ^ (b & c)); //maj
+
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2;
+ }
+#endif
+
+ m_Hash[0] += a;
+ m_Hash[1] += b;
+ m_Hash[2] += c;
+ m_Hash[3] += d;
+ m_Hash[4] += e;
+ m_Hash[5] += f;
+ m_Hash[6] += g;
+ m_Hash[7] += h;
+}
diff --git a/dbx_tree/SHA256.h b/dbx_tree/SHA256.h new file mode 100644 index 0000000..a9629e6 --- /dev/null +++ b/dbx_tree/SHA256.h @@ -0,0 +1,49 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef _MSC_VER
+#include <stdint.h>
+#else
+#include "stdint.h"
+#endif
+
+
+class SHA256
+{
+public:
+ typedef uint32_t THash[8];
+
+ SHA256();
+ ~SHA256();
+
+ void SHAInit();
+ void SHAUpdate(void * Data, uint32_t Length);
+ void SHAFinal(THash & Hash);
+private:
+ THash m_Hash;
+ uint64_t m_Length; /// Datalength in byte
+
+ uint8_t m_Block[64];
+
+ void SHABlock();
+ void Swap64(void * Addr);
+};
diff --git a/dbx_tree/Services.cpp b/dbx_tree/Services.cpp new file mode 100644 index 0000000..d8b7347 --- /dev/null +++ b/dbx_tree/Services.cpp @@ -0,0 +1,402 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "Services.h"
+
+HANDLE gServices[40] = {0};
+
+INT_PTR DBEntityGetRoot(WPARAM wParam, LPARAM lParam)
+{
+ return gDataBase->getEntities().getRootEntity();
+}
+INT_PTR DBEntityChildCount(WPARAM hEntity, LPARAM lParam)
+{
+ if (hEntity == 0)
+ hEntity = gDataBase->getEntities().getRootEntity();
+
+ return gDataBase->getEntities().getChildCount(hEntity);
+}
+INT_PTR DBEntityGetParent(WPARAM hEntity, LPARAM lParam)
+{
+ if (hEntity == 0)
+ hEntity = gDataBase->getEntities().getRootEntity();
+
+ return gDataBase->getEntities().getParent(hEntity);
+}
+INT_PTR DBEntityMove(WPARAM hEntity, LPARAM hParent)
+{
+ if ((hEntity == 0) || (hEntity == gDataBase->getEntities().getRootEntity()))
+ return DBT_INVALIDPARAM;
+
+ if (hParent == 0)
+ hParent = gDataBase->getEntities().getRootEntity();
+
+ return gDataBase->getEntities().setParent(hEntity, hParent);
+}
+INT_PTR DBEntityGetFlags(WPARAM hEntity, LPARAM lParam)
+{
+ if (hEntity == 0)
+ hEntity = gDataBase->getEntities().getRootEntity();
+
+ return gDataBase->getEntities().getFlags(hEntity);
+}
+INT_PTR DBEntityIterInit(WPARAM pFilter, LPARAM hParent)
+{
+ TDBTEntityIterFilter fil = {0,0,0,0};
+ if (pFilter == NULL)
+ {
+ pFilter = reinterpret_cast<WPARAM>(&fil);
+ fil.cbSize = sizeof(fil);
+ }
+
+ if (reinterpret_cast<PDBTEntityIterFilter>(pFilter)->cbSize != sizeof(TDBTEntityIterFilter))
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTEntityIterFilter>(pFilter)->fDontHasFlags & ((PDBTEntityIterFilter)pFilter)->fHasFlags)
+ return DBT_INVALIDPARAM;
+
+ if (hParent == 0)
+ hParent = gDataBase->getEntities().getRootEntity();
+
+ return gDataBase->getEntities().IterationInit(*reinterpret_cast<PDBTEntityIterFilter>(pFilter), hParent);
+}
+INT_PTR DBEntityIterNext(WPARAM hIteration, LPARAM lParam)
+{
+ if ((hIteration == 0) || (hIteration == DBT_INVALIDPARAM))
+ return hIteration;
+
+ return gDataBase->getEntities().IterationNext(hIteration);
+}
+INT_PTR DBEntityIterClose(WPARAM hIteration, LPARAM lParam)
+{
+ if ((hIteration == 0) || (hIteration == DBT_INVALIDPARAM))
+ return hIteration;
+
+ return gDataBase->getEntities().IterationClose(hIteration);
+}
+INT_PTR DBEntityDelete(WPARAM hEntity, LPARAM lParam)
+{
+ if ((hEntity == 0) || (hEntity == gDataBase->getEntities().getRootEntity()))
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getEntities().DeleteEntity(hEntity);
+}
+INT_PTR DBEntityCreate(WPARAM pEntity, LPARAM lParam)
+{
+ if (reinterpret_cast<PDBTEntity>(pEntity)->bcSize != sizeof(TDBTEntity))
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTEntity>(pEntity)->hParentEntity == 0)
+ reinterpret_cast<PDBTEntity>(pEntity)->hParentEntity = gDataBase->getEntities().getRootEntity();
+
+ reinterpret_cast<PDBTEntity>(pEntity)->fFlags = reinterpret_cast<PDBTEntity>(pEntity)->fFlags & ~(DBT_NF_IsRoot | DBT_NF_HasChildren | DBT_NF_IsVirtual | DBT_NF_HasVirtuals); // forbidden flags...
+ return gDataBase->getEntities().CreateEntity(*reinterpret_cast<PDBTEntity>(pEntity));
+}
+
+INT_PTR DBEntityGetAccount(WPARAM hEntity, LPARAM lParam)
+{
+ return gDataBase->getEntities().getAccount(hEntity);
+}
+
+INT_PTR DBVirtualEntityCreate(WPARAM hEntity, LPARAM hParent)
+{
+ if ((hEntity == 0) || (hEntity == gDataBase->getEntities().getRootEntity()))
+ return DBT_INVALIDPARAM;
+
+ if (hParent == 0)
+ hParent = gDataBase->getEntities().getRootEntity();
+
+ return gDataBase->getEntities().VirtualCreate(hEntity, hParent);
+}
+INT_PTR DBVirtualEntityGetParent(WPARAM hVirtualEntity, LPARAM lParam)
+{
+ if ((hVirtualEntity == 0) || (hVirtualEntity == gDataBase->getEntities().getRootEntity()))
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getEntities().VirtualGetParent(hVirtualEntity);
+}
+INT_PTR DBVirtualEntityGetFirst(WPARAM hEntity, LPARAM lParam)
+{
+ if ((hEntity == 0) || (hEntity == gDataBase->getEntities().getRootEntity()))
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getEntities().VirtualGetFirst(hEntity);
+}
+INT_PTR DBVirtualEntityGetNext(WPARAM hVirtualEntity, LPARAM lParam)
+{
+ if ((hVirtualEntity == 0) || (hVirtualEntity == gDataBase->getEntities().getRootEntity()))
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getEntities().VirtualGetNext(hVirtualEntity);
+}
+
+
+INT_PTR DBSettingFind(WPARAM pSettingDescriptor, LPARAM lParam)
+{
+ if (pSettingDescriptor == NULL)
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSettingDescriptor>(pSettingDescriptor)->cbSize != sizeof(TDBTSettingDescriptor))
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSettingDescriptor>(pSettingDescriptor)->pszSettingName == NULL)
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getSettings().FindSetting(*reinterpret_cast<PDBTSettingDescriptor>(pSettingDescriptor));
+}
+INT_PTR DBSettingDelete(WPARAM pSettingDescriptor, LPARAM lParam)
+{
+ if (pSettingDescriptor == NULL)
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSettingDescriptor>(pSettingDescriptor)->cbSize != sizeof(TDBTSettingDescriptor))
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSettingDescriptor>(pSettingDescriptor)->pszSettingName == NULL)
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getSettings().DeleteSetting(*reinterpret_cast<PDBTSettingDescriptor>(pSettingDescriptor));
+}
+INT_PTR DBSettingDeleteHandle(WPARAM hSetting, LPARAM lParam)
+{
+ if (hSetting == 0)
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getSettings().DeleteSetting(hSetting);
+}
+INT_PTR DBSettingWrite(WPARAM pSetting, LPARAM lParam)
+{
+ if (pSetting == NULL)
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSetting>(pSetting)->cbSize != sizeof(TDBTSetting))
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSetting>(pSetting)->Descriptor == NULL)
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSetting>(pSetting)->Descriptor->cbSize != sizeof(TDBTSettingDescriptor))
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSetting>(pSetting)->Descriptor->pszSettingName == NULL)
+ return DBT_INVALIDPARAM;
+
+ if ((reinterpret_cast<PDBTSetting>(pSetting)->Type & DBT_STF_VariableLength) && (reinterpret_cast<PDBTSetting>(pSetting)->Value.pBlob == NULL))
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getSettings().WriteSetting(*reinterpret_cast<PDBTSetting>(pSetting));
+}
+INT_PTR DBSettingWriteHandle(WPARAM pSetting, LPARAM hSetting)
+{
+ if (pSetting == NULL)
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSetting>(pSetting)->cbSize != sizeof(TDBTSetting))
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getSettings().WriteSetting(*reinterpret_cast<PDBTSetting>(pSetting), hSetting);
+}
+INT_PTR DBSettingRead(WPARAM pSetting, LPARAM lParam)
+{
+ if (pSetting == NULL)
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSetting>(pSetting)->cbSize != sizeof(TDBTSetting))
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSetting>(pSetting)->Descriptor == NULL)
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSetting>(pSetting)->Descriptor->cbSize != sizeof(TDBTSettingDescriptor))
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSetting>(pSetting)->Descriptor->pszSettingName == NULL)
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getSettings().ReadSetting(*reinterpret_cast<PDBTSetting>(pSetting));
+}
+INT_PTR DBSettingReadHandle(WPARAM pSetting, LPARAM hSetting)
+{
+ if ((pSetting == NULL) || (hSetting == 0))
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSetting>(pSetting)->cbSize != sizeof(TDBTSetting))
+ return DBT_INVALIDPARAM;
+
+ if ((reinterpret_cast<PDBTSetting>(pSetting)->Descriptor != NULL) && (reinterpret_cast<PDBTSetting>(pSetting)->Descriptor->cbSize != sizeof(TDBTSettingDescriptor)))
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getSettings().ReadSetting(*((PDBTSetting)pSetting), hSetting);
+}
+INT_PTR DBSettingIterInit(WPARAM pFilter, LPARAM lParam)
+{
+ if (pFilter == NULL)
+ return DBT_INVALIDPARAM;
+
+ if (reinterpret_cast<PDBTSettingIterFilter>(pFilter)->cbSize != sizeof(TDBTSettingIterFilter))
+ return DBT_INVALIDPARAM;
+
+ if ((reinterpret_cast<PDBTSettingIterFilter>(pFilter)->Descriptor != NULL) && (reinterpret_cast<PDBTSettingIterFilter>(pFilter)->Descriptor->cbSize != sizeof(TDBTSettingDescriptor)))
+ return DBT_INVALIDPARAM;
+
+ if ((reinterpret_cast<PDBTSettingIterFilter>(pFilter)->Setting != NULL) && (reinterpret_cast<PDBTSettingIterFilter>(pFilter)->Setting->cbSize != sizeof(TDBTSetting)))
+ return DBT_INVALIDPARAM;
+
+ if ((reinterpret_cast<PDBTSettingIterFilter>(pFilter)->Setting != NULL) && (reinterpret_cast<PDBTSettingIterFilter>(pFilter)->Setting->Descriptor != NULL) && (reinterpret_cast<PDBTSettingIterFilter>(pFilter)->Setting->Descriptor->cbSize != sizeof(TDBTSettingIterFilter)))
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getSettings().IterationInit(*reinterpret_cast<PDBTSettingIterFilter>(pFilter));
+}
+INT_PTR DBSettingIterNext(WPARAM hIteration, LPARAM lParam)
+{
+ if ((hIteration == 0) || (hIteration == DBT_INVALIDPARAM))
+ return hIteration;
+
+ return gDataBase->getSettings().IterationNext(hIteration);
+}
+INT_PTR DBSettingIterClose(WPARAM hIteration, LPARAM lParam)
+{
+ if ((hIteration == 0) || (hIteration == DBT_INVALIDPARAM))
+ return hIteration;
+
+ return gDataBase->getSettings().IterationClose(hIteration);
+}
+
+INT_PTR DBEventGetBlobSize(WPARAM hEvent, LPARAM lParam)
+{
+ return gDataBase->getEvents().GetBlobSize(hEvent);
+}
+
+INT_PTR DBEventGet(WPARAM hEvent, LPARAM pEvent)
+{
+ if ((pEvent == NULL) || (reinterpret_cast<PDBTEvent>(pEvent)->cbSize != sizeof(TDBTEvent)))
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getEvents().Get(hEvent, *reinterpret_cast<PDBTEvent>(pEvent));
+}
+
+INT_PTR DBEventGetCount(WPARAM hEntity, LPARAM lParam)
+{
+ return gDataBase->getEvents().GetCount(hEntity);
+}
+
+INT_PTR DBEventDelete(WPARAM hEvent, LPARAM lParam)
+{
+ return gDataBase->getEvents().Delete(hEvent);
+}
+
+INT_PTR DBEventAdd(WPARAM hEntity, LPARAM pEvent)
+{
+ if ((pEvent == NULL) || (reinterpret_cast<PDBTEvent>(pEvent)->cbSize != sizeof(TDBTEvent)) || (reinterpret_cast<PDBTEvent>(pEvent)->pBlob == NULL) || (reinterpret_cast<PDBTEvent>(pEvent)->cbBlob == 0))
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getEvents().Add(hEntity, *((PDBTEvent)pEvent));
+}
+
+INT_PTR DBEventMarkRead(WPARAM hEvent, LPARAM lParam)
+{
+ return gDataBase->getEvents().MarkRead(hEvent);
+}
+
+INT_PTR DBEventWriteToDisk(WPARAM hEvent, LPARAM lParam)
+{
+ return gDataBase->getEvents().WriteToDisk(hEvent);
+}
+
+INT_PTR DBEventGetEntity(WPARAM hEvent, LPARAM lParam)
+{
+ return gDataBase->getEvents().getEntity(hEvent);
+}
+
+INT_PTR DBEventIterInit(WPARAM pFilter, LPARAM lParam)
+{
+ if ((pFilter == NULL) || (reinterpret_cast<PDBTEventIterFilter>(pFilter)->cbSize != sizeof(TDBTEventIterFilter)))
+ return DBT_INVALIDPARAM;
+
+ if ((reinterpret_cast<PDBTEventIterFilter>(pFilter)->Event != NULL) && (reinterpret_cast<PDBTEventIterFilter>(pFilter)->Event->cbSize != sizeof(TDBTEvent)))
+ return DBT_INVALIDPARAM;
+
+ return gDataBase->getEvents().IterationInit(*reinterpret_cast<PDBTEventIterFilter>(pFilter));
+}
+
+INT_PTR DBEventIterNext(WPARAM hIteration, LPARAM lParam)
+{
+ if ((hIteration == 0) || (hIteration == DBT_INVALIDPARAM))
+ return hIteration;
+
+ return gDataBase->getEvents().IterationNext(hIteration);
+}
+
+INT_PTR DBEventIterClose(WPARAM hIteration, LPARAM lParam)
+{
+ if ((hIteration == 0) || (hIteration == DBT_INVALIDPARAM))
+ return hIteration;
+
+ return gDataBase->getEvents().IterationClose(hIteration);
+}
+
+
+bool RegisterServices()
+{
+ gServices[ 0] = CreateServiceFunction(MS_DBT_ENTITY_GETROOT, DBEntityGetRoot);
+ gServices[ 1] = CreateServiceFunction(MS_DBT_ENTITY_CHILDCOUNT, DBEntityChildCount);
+ gServices[ 2] = CreateServiceFunction(MS_DBT_ENTITY_GETPARENT, DBEntityGetParent);
+ gServices[ 3] = CreateServiceFunction(MS_DBT_ENTITY_MOVE, DBEntityMove);
+ gServices[ 8] = CreateServiceFunction(MS_DBT_ENTITY_GETFLAGS, DBEntityGetFlags);
+ gServices[ 9] = CreateServiceFunction(MS_DBT_ENTITY_ITER_INIT, DBEntityIterInit);
+ gServices[10] = CreateServiceFunction(MS_DBT_ENTITY_ITER_NEXT, DBEntityIterNext);
+ gServices[11] = CreateServiceFunction(MS_DBT_ENTITY_ITER_CLOSE, DBEntityIterClose);
+ gServices[12] = CreateServiceFunction(MS_DBT_ENTITY_DELETE, DBEntityDelete);
+ gServices[13] = CreateServiceFunction(MS_DBT_ENTITY_CREATE, DBEntityCreate);
+ gServices[13] = CreateServiceFunction(MS_DBT_ENTITY_GETACCOUNT, DBEntityGetAccount);
+
+ gServices[14] = CreateServiceFunction(MS_DBT_VIRTUALENTITY_CREATE, DBVirtualEntityCreate);
+ gServices[15] = CreateServiceFunction(MS_DBT_VIRTUALENTITY_GETPARENT, DBVirtualEntityGetParent);
+ gServices[16] = CreateServiceFunction(MS_DBT_VIRTUALENTITY_GETFIRST, DBVirtualEntityGetFirst);
+ gServices[17] = CreateServiceFunction(MS_DBT_VIRTUALENTITY_GETNEXT, DBVirtualEntityGetNext);
+
+ gServices[18] = CreateServiceFunction(MS_DBT_SETTING_FIND, DBSettingFind);
+ gServices[19] = CreateServiceFunction(MS_DBT_SETTING_DELETE, DBSettingDelete);
+ gServices[20] = CreateServiceFunction(MS_DBT_SETTING_DELETEHANDLE, DBSettingDeleteHandle);
+ gServices[21] = CreateServiceFunction(MS_DBT_SETTING_WRITE, DBSettingWrite);
+ gServices[22] = CreateServiceFunction(MS_DBT_SETTING_WRITEHANDLE, DBSettingWriteHandle);
+ gServices[23] = CreateServiceFunction(MS_DBT_SETTING_READ, DBSettingRead);
+ gServices[24] = CreateServiceFunction(MS_DBT_SETTING_READHANDLE, DBSettingReadHandle);
+ gServices[25] = CreateServiceFunction(MS_DBT_SETTING_ITER_INIT, DBSettingIterInit);
+ gServices[26] = CreateServiceFunction(MS_DBT_SETTING_ITER_NEXT, DBSettingIterNext);
+ gServices[27] = CreateServiceFunction(MS_DBT_SETTING_ITER_CLOSE, DBSettingIterClose);
+
+ gServices[28] = CreateServiceFunction(MS_DBT_EVENT_GETBLOBSIZE, DBEventGetBlobSize);
+ gServices[29] = CreateServiceFunction(MS_DBT_EVENT_GET, DBEventGet);
+ gServices[30] = CreateServiceFunction(MS_DBT_EVENT_GETCOUNT, DBEventGetCount);
+ gServices[31] = CreateServiceFunction(MS_DBT_EVENT_DELETE, DBEventDelete);
+ gServices[32] = CreateServiceFunction(MS_DBT_EVENT_ADD, DBEventAdd);
+ gServices[33] = CreateServiceFunction(MS_DBT_EVENT_MARKREAD, DBEventMarkRead);
+ gServices[34] = CreateServiceFunction(MS_DBT_EVENT_WRITETODISK, DBEventWriteToDisk);
+ gServices[35] = CreateServiceFunction(MS_DBT_EVENT_GETENTITY, DBEventGetEntity);
+ gServices[36] = CreateServiceFunction(MS_DBT_EVENT_ITER_INIT, DBEventIterInit);
+ gServices[37] = CreateServiceFunction(MS_DBT_EVENT_ITER_NEXT, DBEventIterNext);
+ gServices[38] = CreateServiceFunction(MS_DBT_EVENT_ITER_CLOSE, DBEventIterClose);
+
+
+ return true;
+}
diff --git a/dbx_tree/Services.h b/dbx_tree/Services.h new file mode 100644 index 0000000..0d75552 --- /dev/null +++ b/dbx_tree/Services.h @@ -0,0 +1,69 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include "Interface.h"
+#include "DataBase.h"
+
+bool RegisterServices();
+
+
+INT_PTR DBEntityGetRoot(WPARAM wParam, LPARAM lParam);
+INT_PTR DBEntityChildCount(WPARAM hEntity, LPARAM lParam);
+INT_PTR DBEntityGetParent(WPARAM hEntity, LPARAM lParam);
+INT_PTR DBEntityMove(WPARAM hEntity, LPARAM hParent);
+INT_PTR DBEntityGetFlags(WPARAM hEntity, LPARAM lParam);
+INT_PTR DBEntityIterInit(WPARAM pFilter, LPARAM hParent);
+INT_PTR DBEntityIterNext(WPARAM hIteration, LPARAM lParam);
+INT_PTR DBEntityIterClose(WPARAM hIteration, LPARAM lParam);
+INT_PTR DBEntityDelete(WPARAM hEntity, LPARAM lParam);
+INT_PTR DBEntityCreate(WPARAM pEntity, LPARAM lParam);
+INT_PTR DBEntityGetAccount(WPARAM hEntity, LPARAM lParam);
+
+INT_PTR DBVirtualEntityCreate(WPARAM hEntity, LPARAM hParent);
+INT_PTR DBVirtualEntityGetParent(WPARAM hVirtualEntity, LPARAM lParam);
+INT_PTR DBVirtualEntityGetFirst(WPARAM hEntity, LPARAM lParam);
+INT_PTR DBVirtualEntityGetNext(WPARAM hVirtualEntity, LPARAM lParam);
+
+INT_PTR DBSettingFind(WPARAM pSettingDescriptor, LPARAM lParam);
+INT_PTR DBSettingDelete(WPARAM pSettingDescriptor, LPARAM lParam);
+INT_PTR DBSettingDeleteHandle(WPARAM hSetting, LPARAM lParam);
+INT_PTR DBSettingWrite(WPARAM pSetting, LPARAM lParam);
+INT_PTR DBSettingWriteHandle(WPARAM pSetting, LPARAM hSetting);
+INT_PTR DBSettingRead(WPARAM pSetting, LPARAM lParam);
+INT_PTR DBSettingReadHandle(WPARAM pSetting, LPARAM hSetting);
+INT_PTR DBSettingIterInit(WPARAM pFilter, LPARAM lParam);
+INT_PTR DBSettingIterNext(WPARAM hIteration, LPARAM lParam);
+INT_PTR DBSettingIterClose(WPARAM hIteration, LPARAM lParam);
+
+INT_PTR DBEventGetBlobSize(WPARAM hEvent, LPARAM lParam);
+INT_PTR DBEventGet(WPARAM hEvent, LPARAM pEvent);
+INT_PTR DBEventGetCount(WPARAM hEntity, LPARAM lParam);
+INT_PTR DBEventDelete(WPARAM hEvent, LPARAM lParam);
+INT_PTR DBEventAdd(WPARAM hEntity, LPARAM pEvent);
+INT_PTR DBEventMarkRead(WPARAM hEvent, LPARAM lParam);
+INT_PTR DBEventWriteToDisk(WPARAM hEvent, LPARAM lParam);
+INT_PTR DBEventGetEntity(WPARAM hEvent, LPARAM lParam);
+INT_PTR DBEventIterInit(WPARAM pFilter, LPARAM lParam);
+INT_PTR DBEventIterNext(WPARAM hIteration, LPARAM lParam);
+INT_PTR DBEventIterClose(WPARAM hIteration, LPARAM lParam);
diff --git a/dbx_tree/Settings.cpp b/dbx_tree/Settings.cpp new file mode 100644 index 0000000..c4e555e --- /dev/null +++ b/dbx_tree/Settings.cpp @@ -0,0 +1,1479 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "Settings.h"
+#include <math.h> // floor function
+#include "Hash.h"
+#ifndef _MSC_VER
+#include "savestrings_gcc.h"
+#endif
+
+TDBTSettingHandle CSettingsTree::_FindSetting(const uint32_t Hash, const char * Name, const uint32_t Length)
+{
+ TSettingKey key = {0,0};
+ key.Hash = Hash;
+ iterator i = LowerBound(key);
+ uint16_t l;
+
+ TDBTSettingHandle res = 0;
+
+ char * str = NULL;
+
+ while ((res == 0) && (i) && (i->Hash == Hash))
+ {
+ l = Length;
+ if (m_Owner._ReadSettingName(m_BlockManager, i->Setting, l, str) &&
+ (strncmp(str, Name, Length) == 0))
+ {
+ res = i->Setting;
+ } else {
+ ++i;
+ }
+ }
+
+ if (str)
+ free(str);
+
+ return res;
+}
+
+bool CSettingsTree::_DeleteSetting(const uint32_t Hash, const TDBTSettingHandle hSetting)
+{
+ TSettingKey key = {0,0};
+ key.Hash = Hash;
+ iterator i = LowerBound(key);
+
+ while ((i) && (i->Hash == Hash) && (i->Setting != hSetting))
+ ++i;
+
+ if ((i) && (i->Hash == Hash))
+ {
+ Delete(*i);
+ return true;
+ }
+
+ return false;
+}
+
+bool CSettingsTree::_AddSetting(const uint32_t Hash, const TDBTSettingHandle hSetting)
+{
+ TSettingKey key;
+ key.Hash = Hash;
+ key.Setting = hSetting;
+ Insert(key);
+ return true;
+}
+
+CSettings::CSettings(
+ CBlockManager & BlockManagerSet,
+ CBlockManager & BlockManagerPri,
+ CSettingsTree::TNodeRef SettingsRoot,
+ CEntities & Entities
+)
+: m_BlockManagerSet(BlockManagerSet),
+ m_BlockManagerPri(BlockManagerPri),
+ m_Entities(Entities),
+ m_SettingsMap(),
+ m_sigRootChanged(),
+ m_Modules()
+{
+ CSettingsTree * settree = new CSettingsTree(*this, m_BlockManagerSet, SettingsRoot, 0);
+
+ settree->sigRootChanged().connect(this, &CSettings::onRootChanged);
+ m_SettingsMap.insert(std::make_pair(0, settree));
+
+ m_Entities._sigDeleteSettings().connect(this, &CSettings::onDeleteSettings);
+ m_Entities._sigMergeSettings().connect (this, &CSettings::onMergeSettings);
+
+ _LoadModules();
+ _EnsureModuleExists("$Modules");
+}
+
+CSettings::~CSettings()
+{
+ TSettingsTreeMap::iterator it = m_SettingsMap.begin();
+
+ while (it != m_SettingsMap.end())
+ {
+ delete it->second;
+ ++it;
+ }
+
+ TModulesMap::iterator it2 = m_Modules.begin();
+ while (it2 != m_Modules.end())
+ {
+ if (it2->second)
+ delete [] it2->second;
+ ++it2;
+ }
+}
+
+
+CSettingsTree * CSettings::getSettingsTree(TDBTEntityHandle hEntity)
+{
+ TSettingsTreeMap::iterator i = m_SettingsMap.find(hEntity);
+ if (i != m_SettingsMap.end())
+ return i->second;
+
+ uint32_t root = m_Entities._getSettingsRoot(hEntity);
+ if (root == DBT_INVALIDPARAM)
+ return NULL;
+
+ CSettingsTree * tree = new CSettingsTree(*this, m_BlockManagerPri, root, hEntity);
+ tree->sigRootChanged().connect(this, &CSettings::onRootChanged);
+ m_SettingsMap.insert(std::make_pair(hEntity, tree));
+
+ return tree;
+}
+
+// TODO check if we need to copy the name or if we can just use the cache
+inline bool CSettings::_ReadSettingName(CBlockManager & BlockManager, TDBTSettingHandle Setting, uint16_t & NameLength, char *& NameBuf)
+{
+ uint32_t sig = cSettingSignature;
+ uint32_t size = 0;
+
+ TSetting * setting = BlockManager.ReadBlock<TSetting>(Setting, size, sig);
+ if (!setting)
+ return false;
+
+ if ((NameLength != 0) && (NameLength != setting->NameLength))
+ return false;
+
+ NameLength = setting->NameLength;
+ NameBuf = (char*) realloc(NameBuf, NameLength + 1);
+
+ memcpy(NameBuf, setting + 1, NameLength + 1);
+ NameBuf[NameLength] = 0;
+
+ return true;
+}
+
+void CSettings::_EnsureModuleExists(char * Module)
+{
+ if ((Module == NULL) || (*Module == 0))
+ return;
+
+ char * e = strchr(Module, '/');
+ if (e)
+ *e = 0;
+
+ TModulesMap::iterator i = m_Modules.find(*((uint16_t*)Module));
+ while ((i != m_Modules.end()) && (i->first == *((uint16_t*)Module)) && (strcmp(i->second, Module) != 0))
+ {
+ ++i;
+ }
+
+ if ((i == m_Modules.end()) || (i->first != *reinterpret_cast<uint16_t*>(Module)))
+ {
+ size_t l = strlen(Module);
+ char * tmp = new char [l + 1];
+ memcpy(tmp, Module, l + 1);
+ m_Modules.insert(std::make_pair(*reinterpret_cast<uint16_t*>(tmp), tmp));
+
+ char namebuf[512];
+ strcpy_s(namebuf, "$Modules/");
+ strcat_s(namebuf, Module);
+
+ TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0};
+ desc.cbSize = sizeof(desc);
+ desc.pszSettingName = namebuf;
+
+ TDBTSetting set = {0,0,0,0};
+ set.cbSize = sizeof(set);
+ set.Descriptor = &desc;
+ set.Type = DBT_ST_DWORD;
+
+ WriteSetting(set, cSettingsFileFlag);
+ }
+
+ if (e)
+ *e = '/';
+}
+
+void CSettings::_LoadModules()
+{
+ TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0};
+ desc.cbSize = sizeof(desc);
+
+ TDBTSettingIterFilter f = {0,0,0,0,0,0,0,0};
+ f.cbSize = sizeof(f);
+ f.Descriptor = &desc;
+ f.NameStart = "$Modules/";
+
+ TDBTSettingIterationHandle hiter = IterationInit(f);
+
+ if ((hiter != 0) && (hiter != DBT_INVALIDPARAM))
+ {
+ TDBTSettingHandle res = IterationNext(hiter);
+ while ((res != 0) && (res != DBT_INVALIDPARAM))
+ {
+ size_t l = strlen(desc.pszSettingName);
+ char * tmp = new char [l - 9 + 1];
+ memcpy(tmp, desc.pszSettingName + 9, l - 9 + 1);
+ m_Modules.insert(std::make_pair(*reinterpret_cast<uint16_t*>(tmp), tmp));
+ res = IterationNext(hiter);
+ }
+
+ IterationClose(hiter);
+ }
+}
+
+void CSettings::onRootChanged(void* SettingsTree, CSettingsTree::TNodeRef NewRoot)
+{
+ if (((CSettingsTree*)SettingsTree)->Entity() == 0)
+ m_sigRootChanged.emit(this, NewRoot);
+ else
+ m_Entities._setSettingsRoot(((CSettingsTree*)SettingsTree)->Entity(), NewRoot);
+}
+
+void CSettings::onDeleteSettingCallback(void * Tree, const TSettingKey & Key, uint32_t Param)
+{
+ if (Param == 0)
+ {
+ m_BlockManagerSet.DeleteBlock(Key.Setting);
+ } else {
+ m_BlockManagerPri.DeleteBlock(Key.Setting);
+ }
+}
+void CSettings::onDeleteSettings(CEntities * Entities, TDBTEntityHandle hEntity)
+{
+ CSettingsTree * tree = getSettingsTree(hEntity);
+
+ m_Entities._setSettingsRoot(hEntity, 0);
+
+ if (tree)
+ {
+ CSettingsTree::TDeleteCallback callback;
+ callback.connect(this, &CSettings::onDeleteSettingCallback);
+
+ tree->DeleteTree(&callback, hEntity);
+
+ TSettingsTreeMap::iterator i = m_SettingsMap.find(hEntity);
+ delete i->second; // tree
+ m_SettingsMap.erase(i);
+ }
+}
+
+
+typedef struct TSettingMergeHelper
+{
+ TDBTEntityHandle Source;
+ TDBTEntityHandle Dest;
+ CSettingsTree * SourceTree;
+
+} TSettingMergeHelper, *PSettingMergeHelper;
+
+
+void CSettings::onMergeSettingCallback(void * Tree, const TSettingKey & Key,uint32_t Param)
+{
+ PSettingMergeHelper hlp = (PSettingMergeHelper)Param;
+
+ uint16_t dnl = 0;
+ char * dnb = NULL;
+
+ _ReadSettingName(m_BlockManagerPri, Key.Setting, dnl, dnb);
+
+ TSettingKey k = {0,0};
+ k.Hash = Key.Hash;
+
+ CSettingsTree::iterator i = hlp->SourceTree->LowerBound(k);
+ TDBTSettingHandle res = 0;
+ while ((res == 0) && i && (i->Hash == Key.Hash))
+ {
+ uint16_t snl = dnl;
+ char * snb = NULL;
+
+ if (_ReadSettingName(m_BlockManagerPri, i->Setting, snl, snb)
+ && (strcmp(dnb, snb) == 0)) // found it
+ {
+ res = i->Setting;
+ }
+ }
+
+ if (res == 0)
+ {
+ hlp->SourceTree->Insert(Key);
+ } else {
+ hlp->SourceTree->Delete(*i);
+ hlp->SourceTree->Insert(Key);
+ m_BlockManagerPri.DeleteBlock(res);
+ }
+}
+
+void CSettings::onMergeSettings(CEntities * Entities, TDBTEntityHandle Source, TDBTEntityHandle Dest)
+{
+
+ if ((Source != 0) && (Dest != 0))
+ {
+ LOG(logERROR, _T("Cannot Merge with global settings!\nSource %d Dest %d"), Source, Dest);
+ return;
+ }
+
+ CSettingsTree * stree = getSettingsTree(Source);
+ CSettingsTree * dtree = getSettingsTree(Dest);
+
+ if (stree && dtree)
+ {
+ m_Entities._setSettingsRoot(Source, 0);
+
+ stree->Entity(Dest);
+ m_Entities._setSettingsRoot(Dest, stree->getRoot());
+
+ TSettingKey key = {0,0};
+ CSettingsTree::iterator it = stree->LowerBound(key);
+
+ while (it) // transfer all source settings to new Entity
+ {
+ uint32_t sig = cSettingSignature;
+ uint32_t size = 0;
+ TSetting * tmp = m_BlockManagerPri.ReadBlock<TSetting>(it->Setting, size, sig);
+ if (tmp)
+ {
+ tmp->Entity = Dest;
+ m_BlockManagerPri.UpdateBlock(it->Setting);
+ }
+ ++it;
+ }
+
+ // merge the dest tree into the source tree. override existing items
+ // do it this way, because source tree should be much larger
+ TSettingMergeHelper hlp;
+ hlp.Source = Source;
+ hlp.Dest = Dest;
+ hlp.SourceTree = stree;
+
+ CSettingsTree::TDeleteCallback callback;
+ callback.connect(this, &CSettings::onMergeSettingCallback);
+ dtree->DeleteTree(&callback, (uint32_t)&hlp);
+
+ TSettingsTreeMap::iterator i = m_SettingsMap.find(Dest);
+ delete i->second; // dtree
+ i->second = stree;
+ m_SettingsMap.erase(Source);
+
+ }
+}
+
+
+
+
+TDBTSettingHandle CSettings::FindSetting(TDBTSettingDescriptor & Descriptor)
+{
+ if (Descriptor.Flags & DBT_SDF_FoundValid)
+ return Descriptor.FoundHandle;
+
+ uint32_t namelength = static_cast<uint32_t>( strlen(Descriptor.pszSettingName) );
+ uint32_t namehash;
+
+ if (Descriptor.Flags & DBT_SDF_HashValid)
+ {
+ namehash = Descriptor.Hash;
+ } else {
+ namehash = Hash(Descriptor.pszSettingName, namelength);
+ Descriptor.Hash = namehash;
+ Descriptor.Flags = Descriptor.Flags | DBT_SDF_HashValid;
+ }
+
+ Descriptor.Flags = Descriptor.Flags & ~DBT_SDF_FoundValid;
+
+ CSettingsTree * tree;
+ TDBTSettingHandle res = 0;
+ CBlockManager * file = &m_BlockManagerPri;
+ if (Descriptor.Entity == 0)
+ file = &m_BlockManagerSet;
+
+ CBlockManager::ReadTransaction trans(*file);
+
+ if ((Descriptor.Entity == 0) || (Descriptor.Options == 0))
+ {
+ tree = getSettingsTree(Descriptor.Entity);
+ if (tree == NULL)
+ return DBT_INVALIDPARAM;
+
+ res = tree->_FindSetting(namehash, Descriptor.pszSettingName, namelength);
+
+ if (res)
+ {
+ Descriptor.FoundInEntity = Descriptor.Entity;
+ Descriptor.FoundHandle = res;
+ Descriptor.Flags = Descriptor.Flags | DBT_SDF_FoundValid;
+ }
+
+ if (Descriptor.Entity == 0)
+ res = res | cSettingsFileFlag;
+
+ return res;
+ }
+
+ uint32_t cf = m_Entities.getFlags(Descriptor.Entity);
+ if (cf == DBT_INVALIDPARAM)
+ return DBT_INVALIDPARAM;
+
+ // search the setting
+ res = 0;
+
+ TDBTEntityIterFilter f;
+ f.cbSize = sizeof(f);
+ if (cf & DBT_NF_IsGroup)
+ {
+ f.fDontHasFlags = 0;
+ f.fHasFlags = DBT_NF_IsGroup;
+ } else {
+ f.fDontHasFlags = DBT_NF_IsGroup;
+ f.fHasFlags = 0;
+ }
+ f.Options = Descriptor.Options;
+
+ TDBTEntityIterationHandle i = m_Entities.IterationInit(f, Descriptor.Entity);
+ if ((i == DBT_INVALIDPARAM) || (i == 0))
+ return DBT_INVALIDPARAM;
+
+ TDBTEntityHandle e = m_Entities.IterationNext(i);
+ TDBTEntityHandle found = 0;
+ while ((res == 0) && (e != 0))
+ {
+ tree = getSettingsTree(e);
+ if (tree)
+ {
+ res = tree->_FindSetting(namehash, Descriptor.pszSettingName, namelength);
+ found = e;
+ }
+
+ e = m_Entities.IterationNext(i);
+ }
+
+ m_Entities.IterationClose(i);
+
+ if (res)
+ {
+ Descriptor.FoundInEntity = found;
+ Descriptor.FoundHandle = res;
+ Descriptor.Flags = Descriptor.Flags | DBT_SDF_FoundValid;
+ }
+
+ return res;
+}
+
+unsigned int CSettings::DeleteSetting(TDBTSettingDescriptor & Descriptor)
+{
+ TDBTSettingHandle hset = FindSetting(Descriptor);
+ if ((hset == 0) || (hset == DBT_INVALIDPARAM))
+ {
+ return DBT_INVALIDPARAM;
+ }
+
+ unsigned int res = 0;
+ if ((Descriptor.Flags & DBT_SDF_FoundValid) && (Descriptor.Flags & DBT_SDF_HashValid))
+ {
+ CBlockManager * file = &m_BlockManagerPri;
+
+ if (Descriptor.FoundInEntity == 0)
+ {
+ file = &m_BlockManagerSet;
+ hset = hset & ~cSettingsFileFlag;
+ }
+
+ CBlockManager::WriteTransaction trans(*file);
+
+ uint32_t sig = cSettingSignature;
+ uint32_t size = 0;
+ TSetting * setting = file->ReadBlock<TSetting>(hset, size, sig);
+ if (setting && (setting->Entity == Descriptor.FoundInEntity))
+ {
+ CSettingsTree * tree = getSettingsTree(setting->Entity);
+ if (tree)
+ {
+ tree->_DeleteSetting(Descriptor.Hash, hset);
+ file->DeleteBlock(hset);
+ }
+ }
+
+ } else {
+ res = DeleteSetting(hset);
+ }
+
+ return res;
+}
+unsigned int CSettings::DeleteSetting(TDBTSettingHandle hSetting)
+{
+ CBlockManager * file = &m_BlockManagerPri;
+
+ if (hSetting & cSettingsFileFlag)
+ {
+ file = &m_BlockManagerSet;
+ hSetting = hSetting & ~cSettingsFileFlag;
+ }
+
+ CBlockManager::WriteTransaction trans(*file);
+
+ uint32_t sig = cSettingSignature;
+ uint32_t size = 0;
+ TSetting * setting = file->ReadBlock<TSetting>(hSetting, size, sig);
+
+ if (!setting)
+ return DBT_INVALIDPARAM;
+
+ CSettingsTree * tree = getSettingsTree(setting->Entity);
+ if (tree == NULL)
+ return DBT_INVALIDPARAM;
+
+ char * str = reinterpret_cast<char*>(setting + 1);
+ tree->_DeleteSetting(Hash(str, setting->NameLength), hSetting);
+
+ file->DeleteBlock(hSetting);
+
+ return 0;
+}
+TDBTSettingHandle CSettings::WriteSetting(TDBTSetting & Setting)
+{
+ CBlockManager * file = &m_BlockManagerPri;
+ if (Setting.Descriptor->Entity == 0)
+ file = &m_BlockManagerSet;
+
+ CBlockManager::WriteTransaction trans(*file);
+
+ TDBTSettingHandle hset = FindSetting(*Setting.Descriptor);
+ if (hset == DBT_INVALIDPARAM)
+ return hset;
+
+ hset = WriteSetting(Setting, hset);
+
+ return hset;
+}
+
+TDBTSettingHandle CSettings::WriteSetting(TDBTSetting & Setting, TDBTSettingHandle hSetting)
+{
+ uint32_t sig = cSettingSignature;
+ uint32_t size = 0;
+ TSetting * setting = NULL;
+
+ if (!hSetting && !(Setting.Descriptor && Setting.Descriptor->Entity))
+ return DBT_INVALIDPARAM;
+
+ CBlockManager * file = &m_BlockManagerPri;
+ bool fileflag = false;
+
+ if (hSetting & cSettingsFileFlag)
+ {
+ file = &m_BlockManagerSet;
+ hSetting = hSetting & ~cSettingsFileFlag;
+ fileflag = true;
+ }
+
+ CSettingsTree * tree = NULL;
+
+ if (hSetting == 0)
+ {
+ if (Setting.Descriptor->Entity == 0)
+ {
+ file = &m_BlockManagerSet;
+ fileflag = true;
+ }
+
+ CBlockManager::WriteTransaction trans(*file);
+
+ if ((Setting.Descriptor) && (Setting.Descriptor->pszSettingName)) // setting needs a name
+ {
+ tree = getSettingsTree(Setting.Descriptor->Entity);
+ _EnsureModuleExists(Setting.Descriptor->pszSettingName);
+ }
+
+ } else {
+ CBlockManager::WriteTransaction trans(*file);
+
+ setting = file->ReadBlock<TSetting>(hSetting, size, sig);
+
+ if (setting) // check if hSetting is valid
+ tree = getSettingsTree(setting->Entity);
+ }
+
+ if (tree == NULL)
+ return DBT_INVALIDPARAM;
+
+ uint32_t blobsize = 0;
+
+ if (Setting.Type & DBT_STF_VariableLength)
+ {
+ switch (Setting.Type)
+ {
+ case DBT_ST_ANSI: case DBT_ST_UTF8:
+ {
+ if (Setting.Value.Length == 0)
+ blobsize = static_cast<uint32_t>(strlen(Setting.Value.pAnsi) + 1);
+ else
+ blobsize = Setting.Value.Length;
+ } break;
+ case DBT_ST_WCHAR:
+ {
+ if (Setting.Value.Length == 0)
+ blobsize = sizeof(wchar_t) * static_cast<uint32_t>(wcslen(Setting.Value.pWide) + 1);
+ else
+ blobsize = sizeof(wchar_t) * (Setting.Value.Length);
+ } break;
+ default:
+ blobsize = Setting.Value.Length;
+ break;
+ }
+ }
+
+ size = sizeof(TSetting) + static_cast<uint32_t>(strlen(Setting.Descriptor->pszSettingName)) + 1 + blobsize;
+
+ if (hSetting == 0) // create new setting
+ {
+ setting = file->CreateBlock<TSetting>(hSetting, cSettingSignature, size);
+
+ setting->Entity = Setting.Descriptor->Entity;
+ setting->Flags = 0;
+ setting->AllocSize = blobsize;
+
+ if (Setting.Descriptor && (Setting.Descriptor->Flags & DBT_SDF_HashValid))
+ {
+ tree->_AddSetting(Setting.Descriptor->Hash, hSetting);
+ } else {
+ tree->_AddSetting(Hash(Setting.Descriptor->pszSettingName, static_cast<uint32_t>(strlen(Setting.Descriptor->pszSettingName))), hSetting);
+ }
+
+ } else {
+ uint32_t tmp = 0;
+ setting = file->ReadBlock<TSetting>(hSetting, tmp, sig);
+
+ if (((Setting.Type & DBT_STF_VariableLength) == 0) && (setting->Type & DBT_STF_VariableLength))
+ { // shrink setting (variable size->fixed size)
+ file->ResizeBlock(hSetting, setting, size);
+ }
+
+ if ((Setting.Type & DBT_STF_VariableLength) && ((setting->Type & DBT_STF_VariableLength) == 0))
+ { // trick it
+ setting->AllocSize = 0;
+ }
+ }
+
+ setting->Type = Setting.Type;
+ setting->NameLength = static_cast<uint32_t>(strlen(Setting.Descriptor->pszSettingName));
+ memcpy(setting + 1, Setting.Descriptor->pszSettingName, setting->NameLength + 1);
+
+ if (Setting.Type & DBT_STF_VariableLength)
+ {
+ setting->AllocSize = file->ResizeBlock(hSetting, setting, size) -
+ (sizeof(TSetting) + setting->NameLength + 1);
+
+ setting->BlobLength = blobsize;
+
+ memcpy(reinterpret_cast<uint8_t*>(setting + 1) + setting->NameLength + 1, Setting.Value.pBlob, blobsize);
+ } else {
+ memset(&(setting->Value), 0, sizeof(setting->Value));
+ switch (Setting.Type)
+ {
+ case DBT_ST_BOOL:
+ setting->Value.Bool = Setting.Value.Bool; break;
+ case DBT_ST_BYTE: case DBT_ST_CHAR:
+ setting->Value.Byte = Setting.Value.Byte; break;
+ case DBT_ST_SHORT: case DBT_ST_WORD:
+ setting->Value.Short = Setting.Value.Short; break;
+ case DBT_ST_INT: case DBT_ST_DWORD:
+ setting->Value.Int = Setting.Value.Int; break;
+ default:
+ setting->Value.QWord = Setting.Value.QWord; break;
+ }
+ }
+
+ file->UpdateBlock(hSetting);
+
+ if (fileflag)
+ hSetting = hSetting | cSettingsFileFlag;
+
+ return hSetting;
+}
+
+unsigned int CSettings::ReadSetting(TDBTSetting & Setting)
+{
+ CBlockManager * file = &m_BlockManagerPri;
+ if (Setting.Descriptor->Entity == 0)
+ file = &m_BlockManagerSet;
+
+ CBlockManager::ReadTransaction trans(*file);
+
+ TDBTSettingHandle hset = FindSetting(*Setting.Descriptor);
+ if ((hset == 0) || (hset == DBT_INVALIDPARAM))
+ return DBT_INVALIDPARAM;
+
+ PDBTSettingDescriptor back = Setting.Descriptor;
+ Setting.Descriptor = NULL;
+
+ if (ReadSetting(Setting, hset) == DBT_INVALIDPARAM)
+ hset = DBT_INVALIDPARAM;
+
+ Setting.Descriptor = back;
+
+ return hset;
+}
+
+unsigned int CSettings::ReadSetting(TDBTSetting & Setting, TDBTSettingHandle hSetting)
+{
+ CBlockManager * file = &m_BlockManagerPri;
+
+ if (hSetting & cSettingsFileFlag)
+ {
+ file = &m_BlockManagerSet;
+ hSetting = hSetting & ~cSettingsFileFlag;
+ }
+
+ uint32_t sig = cSettingSignature;
+ uint32_t size = 0;
+
+ if (hSetting == 0)
+ return DBT_INVALIDPARAM;
+
+ CBlockManager::ReadTransaction trans(*file);
+
+ TSetting * setting = file->ReadBlock<TSetting>(hSetting, size, sig);
+
+ if (!setting)
+ return DBT_INVALIDPARAM;
+
+ uint8_t* str = reinterpret_cast<uint8_t*>(setting + 1) + setting->NameLength + 1;
+
+ if (Setting.Type == 0)
+ {
+ Setting.Type = setting->Type;
+ if (setting->Type & DBT_STF_VariableLength)
+ {
+ Setting.Value.Length = setting->BlobLength;
+ switch (setting->Type)
+ {
+ case DBT_ST_WCHAR:
+ {
+ Setting.Value.Length = setting->BlobLength / sizeof(wchar_t);
+ Setting.Value.pWide = (wchar_t*) mir_realloc(Setting.Value.pWide, sizeof(wchar_t) * Setting.Value.Length);
+ memcpy(Setting.Value.pWide, str, setting->BlobLength);
+ Setting.Value.pWide[Setting.Value.Length - 1] = 0;
+
+ } break;
+ case DBT_ST_ANSI: case DBT_ST_UTF8:
+ {
+ Setting.Value.Length = setting->BlobLength;
+ Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, setting->BlobLength);
+ memcpy(Setting.Value.pAnsi, str, setting->BlobLength);
+ Setting.Value.pAnsi[Setting.Value.Length - 1] = 0;
+
+ } break;
+ default:
+ {
+ Setting.Value.Length = setting->BlobLength;
+ Setting.Value.pBlob = (uint8_t *) mir_realloc(Setting.Value.pBlob, setting->BlobLength);
+ memcpy(Setting.Value.pBlob, str, setting->BlobLength);
+ } break;
+ }
+ } else {
+ Setting.Value.QWord = setting->Value.QWord;
+ }
+ } else {
+ switch (setting->Type)
+ {
+ case DBT_ST_BYTE: case DBT_ST_WORD: case DBT_ST_DWORD: case DBT_ST_QWORD:
+ {
+ switch (Setting.Type)
+ {
+ case DBT_ST_BYTE: Setting.Value.Byte = (uint8_t) setting->Value.QWord; break;
+ case DBT_ST_WORD: Setting.Value.Word = (uint16_t) setting->Value.QWord; break;
+ case DBT_ST_DWORD: Setting.Value.DWord = (uint32_t) setting->Value.QWord; break;
+ case DBT_ST_QWORD: Setting.Value.QWord = (uint64_t) setting->Value.QWord; break;
+ case DBT_ST_CHAR: Setting.Value.Char = ( int8_t) setting->Value.QWord; break;
+ case DBT_ST_SHORT: Setting.Value.Short = ( int16_t) setting->Value.QWord; break;
+ case DBT_ST_INT: Setting.Value.Int = ( int32_t) setting->Value.QWord; break;
+ case DBT_ST_INT64: Setting.Value.Int64 = ( int64_t) setting->Value.QWord; break;
+ case DBT_ST_BOOL: Setting.Value.Bool = setting->Value.QWord != 0; break;
+
+ case DBT_ST_ANSI: case DBT_ST_UTF8:
+ {
+ char buffer[24];
+ buffer[0] = 0;
+ Setting.Value.Length = 1 + sprintf_s(buffer, "%llu", setting->Value.QWord);
+ Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, Setting.Value.Length);
+ memcpy(Setting.Value.pAnsi, buffer, Setting.Value.Length);
+
+ } break;
+ case DBT_ST_WCHAR:
+ {
+ wchar_t buffer[24];
+ buffer[0] = 0;
+ Setting.Value.Length = 1 + swprintf_s(buffer, L"%llu", setting->Value.QWord);
+ Setting.Value.pWide = (wchar_t *) mir_realloc(Setting.Value.pWide, Setting.Value.Length * sizeof(wchar_t));
+ memcpy(Setting.Value.pWide, buffer, Setting.Value.Length * sizeof(wchar_t));
+
+ } break;
+ case DBT_ST_BLOB:
+ {
+ Setting.Value.Length = 0;
+ switch (setting->Type)
+ {
+ case DBT_ST_BYTE: Setting.Value.Length = 1; break;
+ case DBT_ST_WORD: Setting.Value.Length = 2; break;
+ case DBT_ST_DWORD: Setting.Value.Length = 4; break;
+ case DBT_ST_QWORD: Setting.Value.Length = 8; break;
+ }
+
+ Setting.Value.pBlob = (uint8_t *) mir_realloc(Setting.Value.pBlob, Setting.Value.Length);
+ memcpy(Setting.Value.pBlob, &setting->Value, Setting.Value.Length);
+
+
+ } break;
+ }
+
+ } break;
+ case DBT_ST_CHAR: case DBT_ST_SHORT: case DBT_ST_INT: case DBT_ST_INT64:
+ {
+ int64_t val = 0;
+ switch (setting->Type)
+ {
+ case DBT_ST_CHAR: val = setting->Value.Char; break;
+ case DBT_ST_SHORT: val = setting->Value.Short; break;
+ case DBT_ST_INT: val = setting->Value.Int; break;
+ case DBT_ST_INT64: val = setting->Value.Int64; break;
+ }
+ switch (Setting.Type)
+ {
+ case DBT_ST_BYTE: Setting.Value.Byte = (uint8_t) val; break;
+ case DBT_ST_WORD: Setting.Value.Word = (uint16_t) val; break;
+ case DBT_ST_DWORD: Setting.Value.DWord = (uint32_t) val; break;
+ case DBT_ST_QWORD: Setting.Value.QWord = (uint64_t) val; break;
+ case DBT_ST_CHAR: Setting.Value.Char = ( int8_t) val; break;
+ case DBT_ST_SHORT: Setting.Value.Short = ( int16_t) val; break;
+ case DBT_ST_INT: Setting.Value.Int = ( int32_t) val; break;
+ case DBT_ST_INT64: Setting.Value.Int64 = ( int64_t) val; break;
+ case DBT_ST_BOOL: Setting.Value.Bool = val != 0; break;
+
+ case DBT_ST_ANSI: case DBT_ST_UTF8:
+ {
+ char buffer[24];
+ buffer[0] = 0;
+ Setting.Value.Length = 1 + sprintf_s(buffer, "%lli", val);
+ Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, Setting.Value.Length);
+ memcpy(Setting.Value.pAnsi, buffer, Setting.Value.Length);
+
+ } break;
+ case DBT_ST_WCHAR:
+ {
+ wchar_t buffer[24];
+ buffer[0] = 0;
+ Setting.Value.Length = 1 + swprintf_s(buffer, L"%lli", val);
+ Setting.Value.pWide = (wchar_t *) mir_realloc(Setting.Value.pWide, Setting.Value.Length * sizeof(wchar_t));
+ memcpy(Setting.Value.pWide, buffer, Setting.Value.Length * sizeof(wchar_t));
+
+ } break;
+ case DBT_ST_BLOB:
+ {
+ Setting.Value.Length = 0;
+ switch (setting->Type)
+ {
+ case DBT_ST_CHAR: Setting.Value.Length = 1; break;
+ case DBT_ST_SHORT: Setting.Value.Length = 2; break;
+ case DBT_ST_INT: Setting.Value.Length = 4; break;
+ case DBT_ST_INT64: Setting.Value.Length = 8; break;
+ }
+
+ Setting.Value.pBlob = (unsigned char *) mir_realloc(Setting.Value.pBlob, Setting.Value.Length);
+ memcpy(Setting.Value.pBlob, &setting->Value, Setting.Value.Length);
+
+ } break;
+ }
+
+ } break;
+ case DBT_ST_FLOAT: case DBT_ST_DOUBLE:
+ {
+ double val = 0;
+ if (setting->Type == DBT_ST_DOUBLE)
+ val = setting->Value.Double;
+ else
+ val = setting->Value.Float;
+
+ switch (Setting.Type)
+ {
+ case DBT_ST_BYTE: Setting.Value.Byte = (uint8_t) floor(val); break;
+ case DBT_ST_WORD: Setting.Value.Word = (uint16_t) floor(val); break;
+ case DBT_ST_DWORD: Setting.Value.DWord = (uint32_t) floor(val); break;
+ case DBT_ST_QWORD: Setting.Value.QWord = (uint64_t) floor(val); break;
+ case DBT_ST_CHAR: Setting.Value.Char = ( int8_t) floor(val); break;
+ case DBT_ST_SHORT: Setting.Value.Short = ( int16_t) floor(val); break;
+ case DBT_ST_INT: Setting.Value.Int = ( int32_t) floor(val); break;
+ case DBT_ST_INT64: Setting.Value.Int64 = ( int64_t) floor(val); break;
+ case DBT_ST_BOOL: Setting.Value.Bool = val != 0; break;
+
+ case DBT_ST_ANSI: case DBT_ST_UTF8:
+ {
+ char buffer[128];
+ buffer[0] = 0;
+ Setting.Value.Length = 1 + sprintf_s(buffer, "%lf", setting->Value.QWord);
+ Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, Setting.Value.Length);
+ memcpy(Setting.Value.pAnsi, buffer, Setting.Value.Length);
+ } break;
+ case DBT_ST_WCHAR:
+ {
+ wchar_t buffer[128];
+ buffer[0] = 0;
+ Setting.Value.Length = 1 + swprintf_s(buffer, L"%lf", setting->Value.QWord);
+ Setting.Value.pWide = (wchar_t *) mir_realloc(Setting.Value.pWide, Setting.Value.Length * sizeof(wchar_t));
+ memcpy(Setting.Value.pWide, buffer, Setting.Value.Length * sizeof(wchar_t));
+ } break;
+ case DBT_ST_BLOB:
+ {
+ Setting.Value.Length = 4;
+ if (setting->Type == DBT_ST_DOUBLE)
+ Setting.Value.Length = 8;
+
+ Setting.Value.pBlob = (uint8_t*) mir_realloc(Setting.Value.pBlob, Setting.Value.Length);
+ memcpy(Setting.Value.pBlob, &setting->Value, Setting.Value.Length);
+
+ } break;
+ }
+
+ } break;
+ case DBT_ST_BOOL:
+ {
+ switch (Setting.Type)
+ {
+ case DBT_ST_BYTE: case DBT_ST_WORD: case DBT_ST_DWORD: case DBT_ST_QWORD:
+ case DBT_ST_CHAR: case DBT_ST_SHORT: case DBT_ST_INT: case DBT_ST_INT64:
+ {
+ if (setting->Value.Bool)
+ Setting.Value.QWord = 1;
+ else
+ Setting.Value.QWord = 0;
+ } break;
+ case DBT_ST_FLOAT:
+ {
+ if (setting->Value.Bool)
+ Setting.Value.Float = 1;
+ else
+ Setting.Value.Float = 0;
+ } break;
+ case DBT_ST_DOUBLE:
+ {
+ if (setting->Value.Bool)
+ Setting.Value.Double = 1;
+ else
+ Setting.Value.Double = 0;
+ } break;
+ case DBT_ST_ANSI: case DBT_ST_UTF8:
+ {
+ char * buffer = "false";
+ Setting.Value.Length = 5;
+ if (setting->Value.Bool)
+ {
+ buffer = "true";
+ Setting.Value.Length = 4;
+ }
+
+ Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, Setting.Value.Length);
+ memcpy(Setting.Value.pAnsi, buffer, Setting.Value.Length);
+ } break;
+ case DBT_ST_WCHAR:
+ {
+ wchar_t * buffer = L"false";
+ Setting.Value.Length = 5;
+ if (setting->Value.Bool)
+ {
+ buffer = L"true";
+ Setting.Value.Length = 4;
+ }
+
+ Setting.Value.pWide = (wchar_t *) mir_realloc(Setting.Value.pWide, Setting.Value.Length * sizeof(wchar_t));
+ memcpy(Setting.Value.pWide, buffer, Setting.Value.Length * sizeof(wchar_t));
+ } break;
+ case DBT_ST_BLOB:
+ {
+ Setting.Value.pBlob = (uint8_t*) mir_realloc(Setting.Value.pBlob, sizeof(bool));
+ (*((bool*)Setting.Value.pBlob)) = setting->Value.Bool;
+ Setting.Value.Length = sizeof(bool);
+ } break;
+ }
+ } break;
+ case DBT_ST_ANSI:
+ {
+ str[setting->BlobLength - 1] = 0;
+
+ switch (Setting.Type)
+ {
+ case DBT_ST_BYTE: case DBT_ST_WORD: case DBT_ST_DWORD: case DBT_ST_QWORD: case DBT_ST_BOOL:
+ case DBT_ST_CHAR: case DBT_ST_SHORT: case DBT_ST_INT: case DBT_ST_INT64:
+ {
+ Setting.Value.QWord = 0;
+ } break;
+ case DBT_ST_ANSI:
+ {
+ Setting.Value.Length = setting->BlobLength;
+ Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, setting->BlobLength);
+ memcpy(Setting.Value.pAnsi, str, setting->BlobLength);
+ } break;
+ case DBT_ST_UTF8:
+ {
+ Setting.Value.pUTF8 = mir_utf8encode((char*)str);
+ Setting.Value.Length = static_cast<uint32_t>(strlen(Setting.Value.pUTF8) + 1);
+ } break;
+ case DBT_ST_WCHAR:
+ {
+ Setting.Value.pWide = mir_a2u((char*)str);
+ Setting.Value.Length = static_cast<uint32_t>(wcslen(Setting.Value.pWide) + 1);
+ } break;
+ case DBT_ST_BLOB:
+ {
+ Setting.Value.Length = setting->BlobLength;
+ Setting.Value.pBlob = (uint8_t *) mir_realloc(Setting.Value.pBlob, setting->BlobLength);
+ memcpy(Setting.Value.pBlob, str, setting->BlobLength);
+ } break;
+ }
+ } break;
+ case DBT_ST_UTF8:
+ {
+ str[setting->BlobLength - 1] = 0;
+
+ switch (Setting.Type)
+ {
+ case DBT_ST_BYTE: case DBT_ST_WORD: case DBT_ST_DWORD: case DBT_ST_QWORD: case DBT_ST_BOOL:
+ case DBT_ST_CHAR: case DBT_ST_SHORT: case DBT_ST_INT: case DBT_ST_INT64:
+ {
+ Setting.Value.QWord = 0;
+ } break;
+ case DBT_ST_ANSI:
+ {
+ mir_utf8decode((char*)str, NULL);
+ Setting.Value.Length = static_cast<uint32_t>(strlen((char*)str) + 1);
+ Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, Setting.Value.Length);
+ memcpy(Setting.Value.pAnsi, str, Setting.Value.Length);
+ } break;
+ case DBT_ST_UTF8:
+ {
+ Setting.Value.Length = setting->BlobLength;
+ Setting.Value.pUTF8 = (char *) mir_realloc(Setting.Value.pUTF8, setting->BlobLength);
+ memcpy(Setting.Value.pUTF8, str, setting->BlobLength);
+ } break;
+ case DBT_ST_WCHAR:
+ {
+ Setting.Value.pWide = mir_utf8decodeW((char*)str);
+ if (Setting.Value.pWide)
+ {
+ Setting.Value.Length = static_cast<uint32_t>(wcslen(Setting.Value.pWide) + 1);
+ } else {
+ Setting.Value.Length = 0;
+ Setting.Type = 0;
+ }
+ } break;
+ case DBT_ST_BLOB:
+ {
+ Setting.Value.pBlob = (uint8_t *) mir_realloc(Setting.Value.pBlob, setting->BlobLength);
+ memcpy(Setting.Value.pBlob, str, setting->BlobLength);
+ Setting.Value.Length = setting->BlobLength;
+ } break;
+ }
+ } break;
+ case DBT_ST_WCHAR:
+ {
+ ((wchar_t*)str)[setting->BlobLength / sizeof(wchar_t) - 1] = 0;
+
+ switch (Setting.Type)
+ {
+ case DBT_ST_BYTE: case DBT_ST_WORD: case DBT_ST_DWORD: case DBT_ST_QWORD: case DBT_ST_BOOL:
+ case DBT_ST_CHAR: case DBT_ST_SHORT: case DBT_ST_INT: case DBT_ST_INT64:
+ {
+ Setting.Value.QWord = 0;
+ } break;
+ case DBT_ST_ANSI:
+ {
+ Setting.Value.pAnsi = mir_u2a((wchar_t*)str);
+ Setting.Value.Length = static_cast<uint32_t>(strlen(Setting.Value.pAnsi) + 1);
+ } break;
+ case DBT_ST_UTF8:
+ {
+ Setting.Value.pUTF8 = mir_utf8encodeW((wchar_t*)str);
+ Setting.Value.Length = static_cast<uint32_t>(strlen(Setting.Value.pUTF8) + 1);
+ } break;
+ case DBT_ST_WCHAR:
+ {
+ Setting.Value.Length = setting->BlobLength / sizeof(wchar_t);
+ Setting.Value.pWide = (wchar_t*) mir_realloc(Setting.Value.pWide, Setting.Value.Length * sizeof(wchar_t));
+ memcpy(Setting.Value.pWide, str, Setting.Value.Length * sizeof(wchar_t));
+ } break;
+ case DBT_ST_BLOB:
+ {
+ Setting.Value.pBlob = (uint8_t *) mir_realloc(Setting.Value.pBlob, setting->BlobLength);
+ memcpy(Setting.Value.pBlob, str, setting->BlobLength);
+ Setting.Value.Length = setting->BlobLength;
+ } break;
+ }
+ } break;
+ case DBT_ST_BLOB:
+ {
+ switch (Setting.Type)
+ {
+ case DBT_ST_BYTE: case DBT_ST_WORD: case DBT_ST_DWORD: case DBT_ST_QWORD: case DBT_ST_BOOL:
+ case DBT_ST_CHAR: case DBT_ST_SHORT: case DBT_ST_INT: case DBT_ST_INT64:
+ {
+ Setting.Value.QWord = 0;
+ } break;
+ case DBT_ST_ANSI: case DBT_ST_WCHAR: case DBT_ST_UTF8:
+ {
+ Setting.Value.Length = 0;
+ if (Setting.Value.pBlob)
+ mir_free(Setting.Value.pBlob);
+
+ Setting.Value.pBlob = NULL;
+ } break;
+ case DBT_ST_BLOB:
+ {
+ Setting.Value.pBlob = (uint8_t *) mir_realloc(Setting.Value.pBlob, setting->BlobLength);
+ memcpy(Setting.Value.pBlob, str, setting->BlobLength);
+ Setting.Value.Length = setting->BlobLength;
+ } break;
+ }
+ } break;
+
+ }
+ }
+
+
+ if (Setting.Descriptor)
+ {
+ Setting.Descriptor->Entity = setting->Entity;
+ Setting.Descriptor->FoundInEntity = setting->Entity;
+
+ Setting.Descriptor->pszSettingName = (char *) mir_realloc(Setting.Descriptor->pszSettingName, setting->NameLength + 1);
+ memcpy(Setting.Descriptor->pszSettingName, setting + 1, setting->NameLength + 1);
+ Setting.Descriptor->pszSettingName[setting->NameLength] = 0;
+ }
+
+ return setting->Type;
+}
+
+
+
+
+TDBTSettingIterationHandle CSettings::IterationInit(TDBTSettingIterFilter & Filter)
+{
+ CBlockManager::ReadTransaction transset(m_BlockManagerSet);
+ CBlockManager::ReadTransaction transpri(m_BlockManagerPri);
+
+ std::queue<TDBTEntityHandle> Entities;
+ Entities.push(Filter.hEntity);
+
+ CSettingsTree * tree = getSettingsTree(Filter.hEntity);
+
+ if (tree == NULL)
+ return DBT_INVALIDPARAM;
+
+ if (Filter.hEntity != 0)
+ {
+ uint32_t cf = m_Entities.getFlags(Filter.hEntity);
+
+ if (cf == DBT_INVALIDPARAM)
+ return DBT_INVALIDPARAM;
+
+ TDBTEntityIterFilter f = {0,0,0,0};
+ f.cbSize = sizeof(f);
+ if (cf & DBT_NF_IsGroup)
+ {
+ f.fHasFlags = DBT_NF_IsGroup;
+ } else {
+ f.fDontHasFlags = DBT_NF_IsGroup;
+ }
+ f.Options = Filter.Options;
+
+ TDBTEntityIterationHandle citer = m_Entities.IterationInit(f, Filter.hEntity);
+ if (citer != DBT_INVALIDPARAM)
+ {
+ m_Entities.IterationNext(citer); // the initial Entity was already added
+ TDBTEntityHandle e = m_Entities.IterationNext(citer);
+ while (e != 0)
+ {
+ Entities.push(e);
+ e = m_Entities.IterationNext(citer);
+ }
+
+ m_Entities.IterationClose(citer);
+ }
+ }
+
+ for (unsigned int j = 0; j < Filter.ExtraCount; ++j)
+ Entities.push(Filter.ExtraEntities[j]);
+
+
+ PSettingIteration iter = new TSettingIteration;
+ iter->Filter = Filter;
+ iter->FilterNameStartLength = 0;
+ iter->LockSetting = (Filter.hEntity == 0);
+ iter->LockPrivate = (Filter.hEntity != 0);
+ if (Filter.NameStart)
+ {
+ uint16_t l = static_cast<uint32_t>(strlen(Filter.NameStart));
+ iter->Filter.NameStart = new char[l + 1];
+ memcpy(iter->Filter.NameStart, Filter.NameStart, l + 1);
+ iter->FilterNameStartLength = l;
+ }
+
+ TSettingKey key = {0, 0};
+
+ // pop first Entity. we have always one and always its tree
+ Entities.pop();
+
+ CSettingsTree::iterator * tmp = new CSettingsTree::iterator(tree->LowerBound(key));
+ tmp->setManaged();
+ iter->Heap = new TSettingsHeap(*tmp, TSettingsHeap::ITForward, true);
+
+ while (!Entities.empty())
+ {
+ TDBTEntityHandle e = Entities.front();
+ Entities.pop();
+
+ tree = getSettingsTree(e);
+ if (tree != NULL)
+ {
+ tmp = new CSettingsTree::iterator(tree->LowerBound(key));
+ tmp->setManaged();
+ iter->Heap->Insert(*tmp);
+
+ iter->LockSetting = iter->LockSetting || (e == 0);
+ iter->LockPrivate = iter->LockPrivate || (e != 0);
+ }
+ }
+
+ iter->Frame = new std::queue<TSettingIterationResult>;
+
+ return reinterpret_cast<TDBTSettingIterationHandle>(iter);
+}
+
+
+typedef struct TSettingIterationHelper {
+ TDBTSettingHandle Handle;
+ CSettingsTree * Tree;
+ uint16_t NameLen;
+ char * Name;
+ } TSettingIterationHelper;
+
+TDBTSettingHandle CSettings::IterationNext(TDBTSettingIterationHandle Iteration)
+{
+ PSettingIteration iter = reinterpret_cast<PSettingIteration>(Iteration);
+ CBlockManager::ReadTransaction transset;
+ CBlockManager::ReadTransaction transpri;
+
+ if (iter->LockSetting)
+ transset = CBlockManager::ReadTransaction(m_BlockManagerSet);
+ if (iter->LockPrivate)
+ transpri = CBlockManager::ReadTransaction(m_BlockManagerPri);
+
+ while (iter->Frame->empty() && iter->Heap->Top())
+ {
+ while (iter->Heap->Top() && iter->Heap->Top().wasDeleted())
+ iter->Heap->Pop();
+
+ if (iter->Heap->Top())
+ {
+ uint32_t h = iter->Heap->Top()->Hash;
+ std::queue<TSettingIterationHelper> q;
+ TSettingIterationHelper help;
+ help.NameLen = 0;
+ help.Name = NULL;
+
+ help.Handle = iter->Heap->Top()->Setting;
+ help.Tree = (CSettingsTree *) iter->Heap->Top().Tree();
+ if (help.Tree)
+ q.push(help);
+
+ iter->Heap->Pop();
+
+ // add all candidates
+ while (iter->Heap->Top() && (iter->Heap->Top()->Hash == h))
+ {
+ if (!iter->Heap->Top().wasDeleted())
+ {
+ help.Handle = iter->Heap->Top()->Setting;
+ help.Tree = (CSettingsTree *) iter->Heap->Top().Tree();
+ q.push(help);
+ }
+ iter->Heap->Pop();
+ }
+
+ while (!q.empty())
+ {
+ help = q.front();
+ q.pop();
+
+ if (help.Name == NULL)
+ {
+ if (help.Tree->Entity() == 0)
+ _ReadSettingName(m_BlockManagerSet, help.Handle, help.NameLen, help.Name);
+ else
+ _ReadSettingName(m_BlockManagerPri, help.Handle, help.NameLen, help.Name);
+ }
+
+
+ q.push(help);
+ while (q.front().Handle != help.Handle) // remove all queued settings with same name
+ {
+ bool namereadres = false;
+
+ TSettingIterationHelper tmp;
+ tmp = q.front();
+ q.pop();
+
+ if (tmp.Name == NULL)
+ {
+ if (tmp.Tree->Entity() == 0)
+ namereadres = _ReadSettingName(m_BlockManagerSet, tmp.Handle, tmp.NameLen, tmp.Name);
+ else
+ namereadres = _ReadSettingName(m_BlockManagerPri, tmp.Handle, tmp.NameLen, tmp.Name);
+ }
+
+ if (!namereadres)
+ {
+ q.push(tmp);
+ } else {
+ if (strcmp(tmp.Name, help.Name) != 0)
+ {
+ q.push(tmp);
+ } else {
+ free(tmp.Name);
+ }
+ }
+ }
+
+ // namefilter
+ if ((iter->Filter.NameStart == NULL) || ((iter->FilterNameStartLength <= help.NameLen) && (memcmp(iter->Filter.NameStart, help.Name, iter->FilterNameStartLength) == 0)))
+ {
+ TSettingIterationResult tmp;
+ if (help.Tree->Entity() == 0)
+ help.Handle |= cSettingsFileFlag;
+
+ tmp.Handle = help.Handle;
+ tmp.Entity = help.Tree->Entity();
+ tmp.Name = help.Name;
+ tmp.NameLen = help.NameLen;
+ iter->Frame->push(tmp);
+ } else {
+ free(help.Name);
+ }
+
+ q.pop();
+ }
+ }
+ }
+
+
+ TSettingIterationResult res = {0,0,0,0};
+ if (!iter->Frame->empty())
+ {
+ res = iter->Frame->front();
+ iter->Frame->pop();
+
+ if ((iter->Filter.Descriptor) && ((iter->Filter.Setting == NULL) || (iter->Filter.Setting->Descriptor != iter->Filter.Descriptor)))
+ {
+ iter->Filter.Descriptor->Entity = res.Entity;
+ iter->Filter.Descriptor->pszSettingName = (char *) mir_realloc(iter->Filter.Descriptor->pszSettingName, res.NameLen + 1);
+ memcpy(iter->Filter.Descriptor->pszSettingName, res.Name, res.NameLen + 1);
+ iter->Filter.Descriptor->FoundInEntity = res.Entity;
+ }
+ if (iter->Filter.Setting)
+ {
+ if ((iter->Filter.Setting->Type & DBT_STF_VariableLength) && (iter->Filter.Setting->Value.pBlob))
+ {
+ mir_free(iter->Filter.Setting->Value.pBlob);
+ iter->Filter.Setting->Value.pBlob = NULL;
+ }
+ iter->Filter.Setting->Type = 0;
+
+ ReadSetting(*iter->Filter.Setting, res.Handle);
+ }
+
+ free(res.Name);
+ }
+
+ return res.Handle;
+}
+unsigned int CSettings::IterationClose(TDBTSettingIterationHandle Iteration)
+{
+ PSettingIteration iter = reinterpret_cast<PSettingIteration>(Iteration);
+ {
+ CBlockManager::ReadTransaction transset;
+ CBlockManager::ReadTransaction transpri;
+
+ if (iter->LockSetting)
+ transset = CBlockManager::ReadTransaction(m_BlockManagerSet);
+ if (iter->LockPrivate)
+ transpri = CBlockManager::ReadTransaction(m_BlockManagerPri);
+
+ delete iter->Heap; // only this needs synchronization
+ }
+
+ if (iter->Filter.NameStart)
+ delete [] iter->Filter.NameStart;
+
+ if (iter->Filter.Descriptor && iter->Filter.Descriptor->pszSettingName)
+ {
+ mir_free(iter->Filter.Descriptor->pszSettingName);
+ iter->Filter.Descriptor->pszSettingName = NULL;
+ }
+ if (iter->Filter.Setting)
+ {
+ if (iter->Filter.Setting->Descriptor)
+ {
+ mir_free(iter->Filter.Setting->Descriptor->pszSettingName);
+ iter->Filter.Setting->Descriptor->pszSettingName = NULL;
+ }
+
+ if (iter->Filter.Setting->Type & DBT_STF_VariableLength)
+ {
+ mir_free(iter->Filter.Setting->Value.pBlob);
+ iter->Filter.Setting->Value.pBlob = NULL;
+ }
+ }
+
+ while (!iter->Frame->empty())
+ {
+ if (iter->Frame->front().Name)
+ free(iter->Frame->front().Name);
+
+ iter->Frame->pop();
+ }
+ delete iter->Frame;
+ delete iter;
+
+ return 0;
+}
+
+
+int CSettings::CompEnumModules(DBMODULEENUMPROC CallBack, LPARAM lParam)
+{
+ CBlockManager::ReadTransaction trans(m_BlockManagerSet);
+
+ TModulesMap::iterator i = m_Modules.begin();
+ int res = 0;
+ while ((i != m_Modules.end()) && (res == 0))
+ {
+ char * tmp = i->second;
+ trans.Close();
+
+ res = CallBack(tmp, 0, lParam);
+
+ trans = CBlockManager::ReadTransaction(m_BlockManagerSet);
+ ++i;
+ }
+
+ return res;
+}
diff --git a/dbx_tree/Settings.h b/dbx_tree/Settings.h new file mode 100644 index 0000000..28be106 --- /dev/null +++ b/dbx_tree/Settings.h @@ -0,0 +1,235 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include "Interface.h"
+#include "FileBTree.h"
+#include "MREWSync.h"
+#include "sigslot.h"
+#include "IterationHeap.h"
+#include <queue>
+#include "lockfree_hashmap.h"
+
+class CSettings;
+class CSettingsTree;
+
+#include "Entities.h"
+
+#pragma pack(push, 1) // push current alignment to stack, set alignment to 1 byte boundary
+
+/**
+ \brief Key Type of the SettingsBTree
+
+ The setting names (ASCII) are hashed, so that they can easily be accessed.
+**/
+
+typedef struct TSettingKey {
+ uint32_t Hash; /// 32 bit hash of the Setting name
+ TDBTSettingHandle Setting;
+
+ bool operator < (const TSettingKey & Other) const
+ {
+ if (Hash != Other.Hash) return Hash < Other.Hash;
+ if (Setting != Other.Setting) return Setting < Other.Setting;
+ return false;
+ }
+ //bool operator <= (const TSettingKey & Other);
+ bool operator == (const TSettingKey & Other) const
+ {
+ return (Hash == Other.Hash) && (Setting == Other.Setting);
+ }
+ //bool operator >= (const TSettingKey & Other);
+ bool operator > (const TSettingKey & Other) const
+ {
+ if (Hash != Other.Hash) return Hash > Other.Hash;
+ if (Setting != Other.Setting) return Setting > Other.Setting;
+ return false;
+ }
+} TSettingKey;
+
+static const uint32_t cSettingSignature = 0xF5B87A3D;
+static const uint16_t cSettingNodeSignature = 0xBA12;
+
+/**
+ \brief The data of a setting
+
+ A setting's data is variable length. The data is a TSetting-structure followed by variable length data.
+ - fixed data
+ - SettingName (ASCII)
+ - maybe blob data
+**/
+typedef struct TSetting {
+ TDBTEntityHandle Entity; /// Settings' Entity
+ uint32_t Flags; /// flags
+ uint16_t Type; /// setting type
+ uint16_t NameLength; /// settingname length
+ union {
+ union {
+ bool Bool;
+ int8_t Char; uint8_t Byte;
+ int16_t Short; uint16_t Word;
+ uint32_t Int; uint32_t DWord;
+ int64_t Int64; uint64_t QWord;
+ float Float;
+ double Double;
+ } Value; /// if type is fixed length, the data is stored right here
+
+ struct {
+ uint32_t BlobLength; /// if type is variable length this describes the length of the data in bytes
+ uint32_t AllocSize; /// this is the allocated space for the blob ALWAYS in byte! this prevents us to realloc it too often
+ };
+ };
+ uint8_t Reserved[8];
+ // settingname with terminating NULL
+ // blob
+} TSetting;
+
+#pragma pack(pop)
+
+/**
+ \brief Manages the Settings in the Database
+**/
+class CSettingsTree : public CFileBTree<TSettingKey, 8>
+{
+protected:
+ TDBTEntityHandle m_Entity;
+ CSettings & m_Owner;
+public:
+ CSettingsTree(CSettings & Owner, CBlockManager & BlockManager, TNodeRef RootNode, TDBTEntityHandle Entity)
+ : CFileBTree<TSettingKey, 8>(BlockManager, RootNode, cSettingNodeSignature),
+ m_Owner(Owner),
+ m_Entity(Entity)
+ {
+
+ };
+ ~CSettingsTree()
+ {
+
+ };
+
+ TDBTEntityHandle Entity()
+ {
+ return m_Entity;
+ };
+ void Entity(TDBTEntityHandle NewEntity)
+ {
+ m_Entity = NewEntity;
+ };
+
+ TDBTSettingHandle _FindSetting(const uint32_t Hash, const char * Name, const uint32_t Length);
+ bool _DeleteSetting(const uint32_t Hash, const TDBTSettingHandle hSetting);
+ bool _AddSetting(const uint32_t Hash, const TDBTSettingHandle hSetting);
+};
+
+
+/**
+ \brief Manages all Settings and provides access to them
+**/
+class CSettings : public sigslot::has_slots<>
+{
+public:
+ typedef sigslot::signal2<CSettings*, CSettingsTree::TNodeRef> TOnRootChanged;
+
+ static const uint32_t cSettingsFileFlag = 0x00000001;
+
+ CSettings(
+ CBlockManager & BlockManagerSet,
+ CBlockManager & BlockManagerPri,
+ CSettingsTree::TNodeRef SettingsRoot,
+ CEntities & Entities
+ );
+ virtual ~CSettings();
+
+
+ TOnRootChanged & sigRootChanged()
+ {
+ return m_sigRootChanged;
+ };
+
+ bool _ReadSettingName(CBlockManager & BlockManager, TDBTSettingHandle Setting, uint16_t & NameLength, char *& NameBuf);
+ void _EnsureModuleExists(char * Module);
+
+ // compatibility:
+ typedef int (*DBMODULEENUMPROC)(const char *szModuleName,DWORD ofsModuleName,LPARAM lParam);
+
+ int CompEnumModules(DBMODULEENUMPROC CallBack, LPARAM lParam);
+ // services:
+ TDBTSettingHandle FindSetting(TDBTSettingDescriptor & Descriptor);
+ unsigned int DeleteSetting(TDBTSettingDescriptor & Descriptor);
+ unsigned int DeleteSetting(TDBTSettingHandle hSetting);
+ TDBTSettingHandle WriteSetting(TDBTSetting & Setting);
+ TDBTSettingHandle WriteSetting(TDBTSetting & Setting, TDBTSettingHandle hSetting);
+ unsigned int ReadSetting(TDBTSetting & Setting);
+ unsigned int ReadSetting(TDBTSetting & Setting, TDBTSettingHandle hSetting);
+
+
+ TDBTSettingIterationHandle IterationInit(TDBTSettingIterFilter & Filter);
+ TDBTSettingHandle IterationNext(TDBTSettingIterationHandle Iteration);
+ unsigned int IterationClose(TDBTSettingIterationHandle Iteration);
+
+
+private:
+
+ typedef lockfree::hash_map<TDBTEntityHandle, CSettingsTree*> TSettingsTreeMap;
+
+ typedef CIterationHeap<CSettingsTree::iterator> TSettingsHeap;
+
+ CBlockManager & m_BlockManagerSet;
+ CBlockManager & m_BlockManagerPri;
+
+ CEntities & m_Entities;
+
+ TSettingsTreeMap m_SettingsMap;
+
+ typedef struct TSettingIterationResult {
+ TDBTSettingHandle Handle;
+ TDBTEntityHandle Entity;
+ char * Name;
+ uint16_t NameLen;
+ } TSettingIterationResult;
+
+ typedef struct TSettingIteration {
+ TDBTSettingIterFilter Filter;
+ uint16_t FilterNameStartLength;
+ TSettingsHeap * Heap;
+ std::queue<TSettingIterationResult> * Frame;
+ bool LockSetting;
+ bool LockPrivate;
+ } TSettingIteration, *PSettingIteration;
+
+ TOnRootChanged m_sigRootChanged;
+ void onRootChanged(void* SettingsTree, CSettingsTree::TNodeRef NewRoot);
+
+ void onDeleteSettingCallback(void * Tree, const TSettingKey & Key, uint32_t Param);
+ void onDeleteSettings(CEntities * Entities, TDBTEntityHandle hEntity);
+ void onMergeSettingCallback(void * Tree, const TSettingKey & Key, uint32_t Param);
+ void onMergeSettings(CEntities * Entities, TDBTEntityHandle Source, TDBTEntityHandle Dest);
+
+ CSettingsTree * getSettingsTree(TDBTEntityHandle hEntity);
+ typedef lockfree::hash_multimap<uint16_t, char *> TModulesMap;
+
+ TModulesMap m_Modules;
+
+ void _LoadModules();
+
+};
diff --git a/dbx_tree/TLS.h b/dbx_tree/TLS.h new file mode 100644 index 0000000..d309090 --- /dev/null +++ b/dbx_tree/TLS.h @@ -0,0 +1,161 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include "lockfree_hashmap.h"
+
+template <typename TAdministrator, typename TData>
+class CThreadLocalStorage
+{
+ private:
+ typedef struct TListElem
+ {
+ TListElem * Next;
+ TAdministrator * Admin;
+ TData Data;
+ TListElem(TListElem * ANext, TAdministrator * AAdmin, const TData & AData)
+ : Next(ANext), Admin(AAdmin), Data(AData)
+ { };
+
+ } TListElem, *PListElem;
+ static __declspec(thread) PListElem m_Head;
+
+ static inline uint32_t DummyHash(const void * Data, uint32_t Length)
+ {
+ return *reinterpret_cast<const uint32_t *>(Data);
+ }
+
+ lockfree::hash_map<DWORD, TData, DummyHash> * m_LockfreeList;
+ typedef typename lockfree::hash_map<DWORD, TData, DummyHash>::iterator TThreadStorage;
+
+ public:
+ CThreadLocalStorage();
+ ~CThreadLocalStorage();
+
+ TData & Open(TAdministrator * Admin, const TData & Default);
+ TData * Find(TAdministrator * Admin);
+ void Remove(TAdministrator * Admin);
+};
+
+const bool _CanUseTLS = ((LOBYTE(LOWORD(GetVersion()))) >= 6);
+
+template <typename TAdministrator, typename TData>
+typename CThreadLocalStorage<TAdministrator, TData>::PListElem CThreadLocalStorage<TAdministrator, TData>::m_Head = NULL;
+
+
+template <typename TAdministrator, typename TData>
+CThreadLocalStorage<TAdministrator, TData>::CThreadLocalStorage()
+{
+ m_LockfreeList = NULL;
+ if (!_CanUseTLS)
+ m_LockfreeList = new lockfree::hash_map<DWORD, TData, DummyHash>();
+}
+template <typename TAdministrator, typename TData>
+CThreadLocalStorage<TAdministrator, TData>::~CThreadLocalStorage()
+{
+ if (m_LockfreeList)
+ delete m_LockfreeList;
+}
+
+
+template <typename TAdministrator, typename TData>
+typename TData & CThreadLocalStorage<TAdministrator, TData>::Open(typename TAdministrator * Admin, const TData & Default)
+{
+ if (_CanUseTLS)
+ {
+ PListElem * last = &m_Head;
+ PListElem i = m_Head;
+ while (i && (i->Admin != Admin))
+ {
+ last = &i->Next;
+ i = i->Next;
+ }
+
+ if (i)
+ {
+ *last = i->Next;
+ i->Next = m_Head;
+ m_Head = i;
+ } else {
+ m_Head = new TListElem(m_Head, Admin, Default);
+ }
+ return m_Head->Data;
+ } else {
+ TThreadStorage & res = m_LockfreeList->insert(std::make_pair(GetCurrentThreadId(), Default)).first;
+ return res->second;
+ }
+}
+
+template <typename TAdministrator, typename TData>
+typename TData * CThreadLocalStorage<TAdministrator, TData>::Find(typename TAdministrator * Admin)
+{
+ if (_CanUseTLS)
+ {
+ PListElem * last = &m_Head;
+ PListElem i = m_Head;
+ while (i && (i->Admin != Admin))
+ {
+ last = &i->Next;
+ i = i->Next;
+ }
+
+ if (i)
+ {
+ *last = i->Next;
+ i->Next = m_Head;
+ m_Head = i;
+ } else {
+ return NULL;
+ }
+ return &m_Head->Data;
+ } else {
+ TThreadStorage & res = m_LockfreeList->find(GetCurrentThreadId());
+ if (res != m_LockfreeList->end())
+ return &res->second;
+ else
+ return NULL;
+ }
+}
+
+template <typename TAdministrator, typename TData>
+void CThreadLocalStorage<TAdministrator, TData>::Remove(typename TAdministrator * Admin)
+{
+ if (_CanUseTLS)
+ {
+ PListElem * last = &m_Head;
+ PListElem i = m_Head;
+ while (i && (i->Admin != Admin))
+ {
+ last = &i->Next;
+ i = i->Next;
+ }
+
+ if (i)
+ {
+ *last = i->Next;
+ delete i;
+ }
+ } else {
+ m_LockfreeList->erase(GetCurrentThreadId());
+ }
+}
diff --git a/dbx_tree/Thread.cpp b/dbx_tree/Thread.cpp new file mode 100644 index 0000000..bdb01f1 --- /dev/null +++ b/dbx_tree/Thread.cpp @@ -0,0 +1,114 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "Thread.h"
+#include "intrinsics.h"
+
+unsigned int __stdcall ThreadDistributor(void* Param)
+{
+ CThread * thread = static_cast<CThread *>(Param);
+ DWORD result = thread->Wrapper();
+ _endthreadex(result);
+ return result; // to make the compiler happy
+}
+
+CThread::CThread(bool CreateSuspended)
+{
+ m_Handle = NULL;
+ m_Terminated = 0;
+ m_FreeOnTerminate = false;
+ m_Finished = false;
+ m_Suspended = CreateSuspended;
+ m_ReturnValue = 0;
+ unsigned int flags = 0;
+ if (CreateSuspended)
+ flags = CREATE_SUSPENDED;
+
+ m_Handle = reinterpret_cast<HANDLE> (_beginthreadex(NULL, 0, &ThreadDistributor, this, flags, &m_ThreadID));
+}
+CThread::~CThread()
+{
+ if (!m_Finished && !m_Suspended)
+ {
+ Terminate();
+ WaitFor();
+ }
+ if (m_Handle)
+ CloseHandle(m_Handle);
+}
+DWORD CThread::Wrapper()
+{
+ Execute();
+
+ bool dofree = FreeOnTerminate();
+ DWORD result = ReturnValue();
+ m_Finished = true;
+
+ m_sigTerminate(this);
+ if (dofree)
+ delete this;
+
+ return result;
+}
+
+void CThread::Resume()
+{
+ if (ResumeThread(m_Handle) == 1)
+ XCHG_32(m_Suspended, 0);
+}
+void CThread::Suspend()
+{
+ SuspendThread(m_Handle);
+ XCHG_32(m_Suspended, 1);
+}
+void CThread::Terminate()
+{
+ XCHG_32(m_Terminated, 1);
+}
+DWORD CThread::WaitFor()
+{
+ HANDLE tmp = m_Handle;
+ DWORD result = WAIT_FAILED;
+
+ if (WaitForSingleObject(m_Handle, INFINITE) != WAIT_FAILED)
+ GetExitCodeThread(tmp, &result);
+
+ return result;
+}
+
+void CThread::FreeOnTerminate(bool Terminate)
+{
+ XCHG_32(m_FreeOnTerminate, Terminate);
+}
+void CThread::ReturnValue(DWORD Value)
+{
+ XCHG_32(m_ReturnValue, Value);
+}
+
+void CThread::Priority(TPriority NewPriority)
+{
+ SetThreadPriority(m_Handle, NewPriority);
+}
+CThread::TPriority CThread::Priority()
+{
+ return static_cast<TPriority> (GetThreadPriority(m_Handle) & 0xffff);
+}
diff --git a/dbx_tree/Thread.h b/dbx_tree/Thread.h new file mode 100644 index 0000000..09b0b6c --- /dev/null +++ b/dbx_tree/Thread.h @@ -0,0 +1,77 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include <process.h>
+#include <windows.h>
+#include "sigslot.h"
+#include "stdint.h"
+
+class CThread
+{
+private:
+ uint32_t volatile m_Terminated;
+ uint32_t volatile m_FreeOnTerminate;
+ uint32_t volatile m_Finished;
+ uint32_t volatile m_Suspended;
+ uint32_t volatile m_ReturnValue;
+protected:
+ HANDLE m_Handle;
+ unsigned int m_ThreadID;
+
+ void ReturnValue(DWORD Value);
+ virtual void Execute() = 0;
+public:
+ CThread(bool CreateSuspended);
+ virtual ~CThread();
+
+ DWORD Wrapper();
+
+ void Resume();
+ void Suspend();
+ void Terminate();
+ DWORD WaitFor();
+
+ bool Suspended() {return m_Suspended != 0;};
+ bool Terminated() {return m_Terminated != 0;};
+ bool FreeOnTerminate() {return m_FreeOnTerminate != 0;};
+ void FreeOnTerminate(bool Terminate);
+ DWORD ReturnValue() {return m_ReturnValue;};
+
+ typedef enum TPriority {
+ tpIdle = THREAD_PRIORITY_IDLE,
+ tpLowest = THREAD_PRIORITY_LOWEST,
+ tpLower = THREAD_PRIORITY_BELOW_NORMAL,
+ tpNormal = THREAD_PRIORITY_NORMAL,
+ tpHigher = THREAD_PRIORITY_ABOVE_NORMAL,
+ tpHighest = THREAD_PRIORITY_HIGHEST,
+ tpRealTime = THREAD_PRIORITY_TIME_CRITICAL
+ } TPriority;
+
+ void Priority(TPriority NewPriority);
+ TPriority Priority();
+
+ typedef sigslot::signal1<CThread *> TOnTerminate;
+ TOnTerminate m_sigTerminate;
+ TOnTerminate & sigTerminate() {return m_sigTerminate;};
+};
diff --git a/dbx_tree/dbConfig.rc b/dbx_tree/dbConfig.rc new file mode 100644 index 0000000..1dff63b --- /dev/null +++ b/dbx_tree/dbConfig.rc @@ -0,0 +1,113 @@ +// Microsoft Visual C++ generated resource script.
+//
+#include "dbConfig_rc.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOGBAR DIALOGEX 0, 0, 429, 290
+STYLE DS_LOCALEDIT | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "dbxTree Profile Wizard"
+FONT 8, "MS Shell Dlg", 400, 0, 0x0
+BEGIN
+ PUSHBUTTON "Cancel",IDC_BUTTON1,316,267,54,16
+ PUSHBUTTON "Next >",IDC_BUTTON2,254,267,54,16
+ PUSHBUTTON "< Prev",IDC_BUTTON3,192,267,54,16
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,6,258,416,1
+ LISTBOX IDC_LIST1,6,6,116,252,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DIALOGBAR, DIALOG
+ BEGIN
+ LEFTMARGIN, 6
+ RIGHTMARGIN, 422
+ TOPMARGIN, 6
+ BOTTOMMARGIN, 284
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// German (Germany) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "dbConfig_rc.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // German (Germany) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/dbx_tree/dbConfig_rc.h b/dbx_tree/dbConfig_rc.h new file mode 100644 index 0000000..099067d --- /dev/null +++ b/dbx_tree/dbConfig_rc.h @@ -0,0 +1,20 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by dbConfig.rc
+//
+#define IDD_DIALOGBAR 103
+#define IDC_BUTTON1 1001
+#define IDC_BUTTON2 1002
+#define IDC_BUTTON3 1003
+#define IDC_LIST1 1004
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1005
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/dbx_tree/dbVersion.rc b/dbx_tree/dbVersion.rc new file mode 100644 index 0000000..170da6f --- /dev/null +++ b/dbx_tree/dbVersion.rc @@ -0,0 +1,105 @@ +// Microsoft Visual C++ generated resource script.
+//
+#include "dbVersion_rc.h"
+#define INTERFACE_VERSION_ONLY
+#include "Interface.h"
+#undef INTERFACE_VERSION_ONLY
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// German (Germany) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "dbVersion_rc.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION gResVersion
+ PRODUCTVERSION gResVersion
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x3L
+#else
+ FILEFLAGS 0x2L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName", gAutor
+ VALUE "FileDescription", gDescription
+ VALUE "FileVersion", gResVersionString
+ VALUE "InternalName", gInternalName
+ VALUE "LegalCopyright", gCopyright
+ VALUE "OriginalFilename", "dbx_tree.dll"
+ VALUE "ProductName", gInternalNameLong
+ VALUE "ProductVersion", gResVersionString
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
+
+#endif // German (Germany) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/dbx_tree/dbVersion_rc.h b/dbx_tree/dbVersion_rc.h new file mode 100644 index 0000000..24a3ae4 --- /dev/null +++ b/dbx_tree/dbVersion_rc.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by dbVersion.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/dbx_tree/dbx_tree.vcproj b/dbx_tree/dbx_tree.vcproj new file mode 100644 index 0000000..332ef2c --- /dev/null +++ b/dbx_tree/dbx_tree.vcproj @@ -0,0 +1,1169 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="dbx_tree"
+ ProjectGUID="{2D0BB338-FF3A-4FB5-A7A5-32B63967678C}"
+ RootNamespace="dbx_tree"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ BrowseInformation="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1033"
+ AdditionalIncludeDirectories="../../include"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ OptimizeForWindows98="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="false"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="../../include"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="2"
+ FloatingPointModel="2"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ ShowIncludes="false"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1033"
+ AdditionalIncludeDirectories="../../include"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="2"
+ LinkTimeCodeGeneration="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ AllowIsolation="true"
+ CLRImageType="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ EmbedManifest="true"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="UNICODE;_UNICODE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ BrowseInformation="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1033"
+ AdditionalIncludeDirectories="../../include"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="false"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="UNICODE;_UNICODE"
+ StringPooling="true"
+ ExceptionHandling="1"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="true"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ DefaultCharIsUnsigned="false"
+ RuntimeTypeInfo="false"
+ AssemblerOutput="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ ShowIncludes="false"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1033"
+ AdditionalIncludeDirectories="../../include"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="0"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
+ GenerateMapFile="false"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ AllowIsolation="true"
+ CLRImageType="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ EmbedManifest="true"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="myDebugExecute|Win32"
+ OutputDirectory="..\..\..\..\Miranda IM Test\Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="UNICODE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BrowseInformation="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="D:\Programme\Miranda IM Test\Plugins\dbx_tree.dll"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ LinkTimeCodeGeneration="0"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)64/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ BrowseInformation="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1033"
+ AdditionalIncludeDirectories="../../include"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ OptimizeForWindows98="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)64/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="false"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="../../include"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="2"
+ FloatingPointModel="2"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ ShowIncludes="false"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1033"
+ AdditionalIncludeDirectories="../../include"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="2"
+ LinkTimeCodeGeneration="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="17"
+ AllowIsolation="true"
+ CLRImageType="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ EmbedManifest="true"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)64/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="UNICODE;_UNICODE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ BrowseInformation="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1033"
+ AdditionalIncludeDirectories="../../include"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)64/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="false"
+ WholeProgramOptimization="true"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="UNICODE;_UNICODE"
+ StringPooling="true"
+ ExceptionHandling="1"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="true"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ DefaultCharIsUnsigned="false"
+ RuntimeTypeInfo="false"
+ AssemblerOutput="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ ShowIncludes="false"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ Culture="1033"
+ AdditionalIncludeDirectories="../../include"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="0"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"
+ GenerateMapFile="false"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="17"
+ AllowIsolation="true"
+ CLRImageType="0"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ EmbedManifest="true"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="myDebugExecute|x64"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)64/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="UNICODE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BrowseInformation="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="D:\Programme\Miranda IM Test\Plugins\dbx_tree.dll"
+ GenerateManifest="false"
+ GenerateDebugInformation="true"
+ LinkTimeCodeGeneration="0"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Resource"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\dbConfig.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\dbConfig_rc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\dbVersion.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\dbVersion_rc.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Database"
+ >
+ <File
+ RelativePath=".\DataBase.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Entities.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Events.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Settings.cpp"
+ >
+ </File>
+ <Filter
+ Name="HeaderFiles"
+ >
+ <File
+ RelativePath=".\BTree.h"
+ >
+ </File>
+ <File
+ RelativePath=".\DataBase.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Entities.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Events.h"
+ >
+ </File>
+ <File
+ RelativePath=".\FileBTree.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Settings.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="FileAccess"
+ >
+ <File
+ RelativePath=".\BlockManager.cpp"
+ >
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ GeneratePreprocessedFile="0"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ GeneratePreprocessedFile="0"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\DirectAccess.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\FileAccess.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\MappedMemory.cpp"
+ >
+ </File>
+ <Filter
+ Name="Encryption"
+ >
+ <File
+ RelativePath=".\encryption\Cipher.h"
+ >
+ </File>
+ <File
+ RelativePath=".\EncryptionManager.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\EncryptionManager.h"
+ >
+ </File>
+ <Filter
+ Name="SHA256"
+ >
+ <File
+ RelativePath=".\SHA256.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\SHA256.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="HeaderFiles"
+ >
+ <File
+ RelativePath=".\BlockManager.h"
+ >
+ </File>
+ <File
+ RelativePath=".\DirectAccess.h"
+ >
+ </File>
+ <File
+ RelativePath=".\FileAccess.h"
+ >
+ </File>
+ <File
+ RelativePath=".\MappedMemory.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Interface"
+ >
+ <File
+ RelativePath=".\Compatibility.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\DatabaseLink.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\init.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Services.cpp"
+ >
+ </File>
+ <Filter
+ Name="HeaderFiles"
+ >
+ <File
+ RelativePath=".\Compatibility.h"
+ >
+ </File>
+ <File
+ RelativePath=".\DatabaseLink.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Interface.h"
+ >
+ </File>
+ <File
+ RelativePath=".\m_dbx_tree.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Services.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Utils"
+ >
+ <File
+ RelativePath=".\Hash.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Logger.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\MREWSync.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Thread.cpp"
+ >
+ </File>
+ <Filter
+ Name="HeaderFiles"
+ >
+ <File
+ RelativePath=".\Hash.h"
+ >
+ </File>
+ <File
+ RelativePath=".\interlocked.h"
+ >
+ </File>
+ <File
+ RelativePath=".\inttypes.h"
+ >
+ </File>
+ <File
+ RelativePath=".\IterationHeap.h"
+ >
+ </File>
+ <File
+ RelativePath=".\lockfree_hashmap.h"
+ >
+ </File>
+ <File
+ RelativePath=".\lockfree_hashmultimap.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Logger.h"
+ >
+ </File>
+ <File
+ RelativePath=".\MREWSync.h"
+ >
+ </File>
+ <File
+ RelativePath=".\savestrings_gcc.h"
+ >
+ </File>
+ <File
+ RelativePath=".\sigslot.h"
+ >
+ </File>
+ <File
+ RelativePath=".\stdint.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Thread.h"
+ >
+ </File>
+ <File
+ RelativePath=".\TLS.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ <Global
+ Name="RESOURCE_FILE"
+ Value="dbx_tree.rc"
+ />
+ </Globals>
+</VisualStudioProject>
diff --git a/dbx_tree/dbx_tree_10.vcxproj b/dbx_tree/dbx_tree_10.vcxproj new file mode 100644 index 0000000..993a419 --- /dev/null +++ b/dbx_tree/dbx_tree_10.vcxproj @@ -0,0 +1,710 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug Unicode|Win32">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Unicode|x64">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|x64">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>dbx_tree</ProjectName>
+ <ProjectGuid>{2D0BB338-FF3A-4FB5-A7A5-32B63967678C}</ProjectGuid>
+ <RootNamespace>dbx_tree</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v100</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v100</PlatformToolset>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v100</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <PlatformToolset>v100</PlatformToolset>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateManifest>
+ <EmbedManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</EmbedManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</GenerateManifest>
+ <EmbedManifest Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</EmbedManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
+ <EmbedManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</EmbedManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</GenerateManifest>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">false</LinkIncremental>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</GenerateManifest>
+ <EmbedManifest Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</EmbedManifest>
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+ <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" />
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" />
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</LinkIncremental>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" />
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(ProjectName)</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(ProjectName)</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(ProjectName)</TargetName>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(ProjectName)</TargetName>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</LinkIncremental>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">.dll</TargetExt>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">.dll</TargetExt>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <RunCodeAnalysis Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">false</RunCodeAnalysis>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ <LinkStatus>false</LinkStatus>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ShowIncludes>false</ShowIncludes>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <AllowIsolation>true</AllowIsolation>
+ <CLRImageType>Default</CLRImageType>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <SubSystem>Windows</SubSystem>
+ <LinkStatus>false</LinkStatus>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>UNICODE;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <BrowseInformation>false</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <CreateHotpatchableImage>false</CreateHotpatchableImage>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <EnablePREfast>false</EnablePREfast>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ <LinkStatus>false</LinkStatus>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>UNICODE;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <AssemblerOutput>
+ </AssemblerOutput>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ShowIncludes>false</ShowIncludes>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <CreateHotpatchableImage>false</CreateHotpatchableImage>
+ <BrowseInformation>false</BrowseInformation>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <AllowIsolation>true</AllowIsolation>
+ <CLRImageType>Default</CLRImageType>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <MapExports>false</MapExports>
+ <SubSystem>Windows</SubSystem>
+ <LinkStatus>false</LinkStatus>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <BrowseInformation>
+ </BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ <LinkStatus>false</LinkStatus>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ShowIncludes>false</ShowIncludes>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ <AllowIsolation>true</AllowIsolation>
+ <CLRImageType>Default</CLRImageType>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <SubSystem>Windows</SubSystem>
+ <LinkStatus>false</LinkStatus>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>UNICODE;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <BrowseInformation>false</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <CreateHotpatchableImage>false</CreateHotpatchableImage>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <OpenMPSupport>false</OpenMPSupport>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <LinkStatus>false</LinkStatus>
+ <CreateHotPatchableImage>
+ </CreateHotPatchableImage>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <Midl>
+ <TargetEnvironment>X64</TargetEnvironment>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>UNICODE;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <AdditionalOptions>
+ </AdditionalOptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ <AssemblerOutput>
+ </AssemblerOutput>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <ShowIncludes>false</ShowIncludes>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <UseUnicodeForAssemblerListing>false</UseUnicodeForAssemblerListing>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <CreateHotpatchableImage>false</CreateHotpatchableImage>
+ <OpenMPSupport>false</OpenMPSupport>
+ <BrowseInformation>false</BrowseInformation>
+ </ClCompile>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <AdditionalIncludeDirectories>../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX64</TargetMachine>
+ <AllowIsolation>true</AllowIsolation>
+ <CLRImageType>Default</CLRImageType>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <LinkStatus>false</LinkStatus>
+ <CreateHotPatchableImage>
+ </CreateHotPatchableImage>
+ <MapExports>false</MapExports>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ResourceCompile Include="dbConfig.rc" />
+ <ResourceCompile Include="dbVersion.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="dbConfig_rc.h" />
+ <ClInclude Include="dbVersion_rc.h" />
+ <ClInclude Include="BTree.h" />
+ <ClInclude Include="DataBase.h" />
+ <ClInclude Include="Entities.h" />
+ <ClInclude Include="Events.h" />
+ <ClInclude Include="FileBTree.h" />
+ <ClInclude Include="intrinsics.h" />
+ <ClInclude Include="Settings.h" />
+ <ClInclude Include="encryption\Cipher.h" />
+ <ClInclude Include="EncryptionManager.h" />
+ <ClInclude Include="SHA256.h" />
+ <ClInclude Include="BlockManager.h" />
+ <ClInclude Include="DirectAccess.h" />
+ <ClInclude Include="FileAccess.h" />
+ <ClInclude Include="MappedMemory.h" />
+ <ClInclude Include="Compatibility.h" />
+ <ClInclude Include="DatabaseLink.h" />
+ <ClInclude Include="Interface.h" />
+ <ClInclude Include="m_dbx_tree.h" />
+ <ClInclude Include="Services.h" />
+ <ClInclude Include="Hash.h" />
+ <ClInclude Include="inttypes.h" />
+ <ClInclude Include="IterationHeap.h" />
+ <ClInclude Include="lockfree_hashmap.h" />
+ <ClInclude Include="lockfree_hashmultimap.h" />
+ <ClInclude Include="Logger.h" />
+ <ClInclude Include="MREWSync.h" />
+ <ClInclude Include="savestrings_gcc.h" />
+ <ClInclude Include="sigslot.h" />
+ <ClInclude Include="stdint.h" />
+ <ClInclude Include="Thread.h" />
+ <ClInclude Include="TLS.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="DataBase.cpp" />
+ <ClCompile Include="Entities.cpp" />
+ <ClCompile Include="Events.cpp" />
+ <ClCompile Include="Settings.cpp" />
+ <ClCompile Include="BlockManager.cpp">
+ <PreprocessToFile Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">false</PreprocessToFile>
+ <PreprocessSuppressLineNumbers Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">false</PreprocessSuppressLineNumbers>
+ <PreprocessToFile Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">false</PreprocessToFile>
+ <PreprocessSuppressLineNumbers Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">false</PreprocessSuppressLineNumbers>
+ </ClCompile>
+ <ClCompile Include="DirectAccess.cpp" />
+ <ClCompile Include="FileAccess.cpp" />
+ <ClCompile Include="MappedMemory.cpp" />
+ <ClCompile Include="EncryptionManager.cpp" />
+ <ClCompile Include="SHA256.cpp" />
+ <ClCompile Include="Compatibility.cpp" />
+ <ClCompile Include="DatabaseLink.cpp" />
+ <ClCompile Include="init.cpp" />
+ <ClCompile Include="Services.cpp" />
+ <ClCompile Include="Hash.cpp" />
+ <ClCompile Include="Logger.cpp" />
+ <ClCompile Include="MREWSync.cpp" />
+ <ClCompile Include="Thread.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+ <ProjectExtensions>
+ <VisualStudio>
+ <UserProperties RESOURCE_FILE="dbx_tree.rc" />
+ </VisualStudio>
+ </ProjectExtensions>
+</Project>
\ No newline at end of file diff --git a/dbx_tree/dbx_tree_10.vcxproj.filters b/dbx_tree/dbx_tree_10.vcxproj.filters new file mode 100644 index 0000000..feeb922 --- /dev/null +++ b/dbx_tree/dbx_tree_10.vcxproj.filters @@ -0,0 +1,204 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Resource">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+ </Filter>
+ <Filter Include="Database">
+ <UniqueIdentifier>{9e004988-9f2b-4ba4-8f56-d0fadd675d27}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Database\HeaderFiles">
+ <UniqueIdentifier>{456c2bea-e723-4178-815d-93f04e79c678}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Database\FileAccess">
+ <UniqueIdentifier>{015b2001-dc24-47da-97f4-1b85117384cb}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Database\FileAccess\Encryption">
+ <UniqueIdentifier>{e1687ef4-a061-4986-8fba-5b5a66d40623}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Database\FileAccess\Encryption\SHA256">
+ <UniqueIdentifier>{f612e60c-0040-4985-9d76-8a61c2f3df3c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Database\FileAccess\HeaderFiles">
+ <UniqueIdentifier>{3a265a80-f78a-44c0-87ca-759560867d83}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Interface">
+ <UniqueIdentifier>{b93e9ed7-b0c7-4a03-91e3-ccaaf6cacc9c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Interface\HeaderFiles">
+ <UniqueIdentifier>{063a42d4-5023-435c-9040-f87607c13d58}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Utils">
+ <UniqueIdentifier>{de45f9d3-861f-4d67-908c-3a77d4fec7a0}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Utils\HeaderFiles">
+ <UniqueIdentifier>{b44370e5-0bf1-4d18-bbd7-7690a7bcad4b}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="dbConfig.rc">
+ <Filter>Resource</Filter>
+ </ResourceCompile>
+ <ResourceCompile Include="dbVersion.rc">
+ <Filter>Resource</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="dbConfig_rc.h">
+ <Filter>Resource</Filter>
+ </ClInclude>
+ <ClInclude Include="dbVersion_rc.h">
+ <Filter>Resource</Filter>
+ </ClInclude>
+ <ClInclude Include="BTree.h">
+ <Filter>Database\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="DataBase.h">
+ <Filter>Database\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="Entities.h">
+ <Filter>Database\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="Events.h">
+ <Filter>Database\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="FileBTree.h">
+ <Filter>Database\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="Settings.h">
+ <Filter>Database\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="encryption\Cipher.h">
+ <Filter>Database\FileAccess\Encryption</Filter>
+ </ClInclude>
+ <ClInclude Include="EncryptionManager.h">
+ <Filter>Database\FileAccess\Encryption</Filter>
+ </ClInclude>
+ <ClInclude Include="SHA256.h">
+ <Filter>Database\FileAccess\Encryption\SHA256</Filter>
+ </ClInclude>
+ <ClInclude Include="BlockManager.h">
+ <Filter>Database\FileAccess\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="DirectAccess.h">
+ <Filter>Database\FileAccess\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="FileAccess.h">
+ <Filter>Database\FileAccess\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="MappedMemory.h">
+ <Filter>Database\FileAccess\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="Compatibility.h">
+ <Filter>Interface\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="DatabaseLink.h">
+ <Filter>Interface\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="Interface.h">
+ <Filter>Interface\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="m_dbx_tree.h">
+ <Filter>Interface\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="Services.h">
+ <Filter>Interface\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="Hash.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="inttypes.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="IterationHeap.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="lockfree_hashmap.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="lockfree_hashmultimap.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="Logger.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="MREWSync.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="savestrings_gcc.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="sigslot.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="stdint.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="Thread.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="TLS.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ <ClInclude Include="intrinsics.h">
+ <Filter>Utils\HeaderFiles</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="DataBase.cpp">
+ <Filter>Database</Filter>
+ </ClCompile>
+ <ClCompile Include="Entities.cpp">
+ <Filter>Database</Filter>
+ </ClCompile>
+ <ClCompile Include="Events.cpp">
+ <Filter>Database</Filter>
+ </ClCompile>
+ <ClCompile Include="Settings.cpp">
+ <Filter>Database</Filter>
+ </ClCompile>
+ <ClCompile Include="BlockManager.cpp">
+ <Filter>Database\FileAccess</Filter>
+ </ClCompile>
+ <ClCompile Include="DirectAccess.cpp">
+ <Filter>Database\FileAccess</Filter>
+ </ClCompile>
+ <ClCompile Include="FileAccess.cpp">
+ <Filter>Database\FileAccess</Filter>
+ </ClCompile>
+ <ClCompile Include="MappedMemory.cpp">
+ <Filter>Database\FileAccess</Filter>
+ </ClCompile>
+ <ClCompile Include="EncryptionManager.cpp">
+ <Filter>Database\FileAccess\Encryption</Filter>
+ </ClCompile>
+ <ClCompile Include="SHA256.cpp">
+ <Filter>Database\FileAccess\Encryption\SHA256</Filter>
+ </ClCompile>
+ <ClCompile Include="Compatibility.cpp">
+ <Filter>Interface</Filter>
+ </ClCompile>
+ <ClCompile Include="DatabaseLink.cpp">
+ <Filter>Interface</Filter>
+ </ClCompile>
+ <ClCompile Include="init.cpp">
+ <Filter>Interface</Filter>
+ </ClCompile>
+ <ClCompile Include="Services.cpp">
+ <Filter>Interface</Filter>
+ </ClCompile>
+ <ClCompile Include="Hash.cpp">
+ <Filter>Utils</Filter>
+ </ClCompile>
+ <ClCompile Include="Logger.cpp">
+ <Filter>Utils</Filter>
+ </ClCompile>
+ <ClCompile Include="MREWSync.cpp">
+ <Filter>Utils</Filter>
+ </ClCompile>
+ <ClCompile Include="Thread.cpp">
+ <Filter>Utils</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
\ No newline at end of file diff --git a/dbx_tree/encryption/ARC4.cpp b/dbx_tree/encryption/ARC4.cpp new file mode 100644 index 0000000..7f3780e --- /dev/null +++ b/dbx_tree/encryption/ARC4.cpp @@ -0,0 +1,129 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2008 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "ARC4.h"
+#include <string.h>
+
+const wchar_t * ARC4::Name()
+{
+ return cName;
+}
+const wchar_t * ARC4::Description()
+{
+ return cDescription;
+}
+const uint32_t ARC4::BlockSizeBytes()
+{
+ return cBlockSizeBytes;
+}
+const bool ARC4::IsStreamCipher()
+{
+ return cIsStreamCipher;
+}
+
+ARC4::ARC4()
+{
+
+}
+ARC4::~ARC4()
+{
+
+}
+
+CCipher::TCipherInterface* ARC4::Create()
+{
+ return (new ARC4())->m_Interface;
+}
+
+void ARC4::SetKey(void* Key, uint32_t KeyLength)
+{
+ uint8_t swapbyte;
+ uint8_t index1;
+ uint8_t index2;
+ unsigned int i;
+
+ uint8_t * k = (uint8_t *) Key;
+
+ for (i = 0; i < 256; ++i)
+ State[i] = i;
+
+ x = 0;
+ y = 0;
+ index1 = 0;
+ index2 = 0;
+ for (i = 0; i < 256; ++i)
+ {
+ index2 = (k[index1] + State[i] + index2) & 0xff;
+ swapbyte = State[i];
+ State[i] = State[index2];
+ State[index2] = swapbyte;
+ index1 = (index1 + 1) % KeyLength;
+ }
+
+ for (i = 0; i < 3742; ++i)
+ Stream();
+
+ Backx = x;
+ Backy = y;
+ memcpy(BackState, State, sizeof(State));
+}
+
+inline uint8_t ARC4::Stream()
+{
+ uint8_t swapbyte;
+
+ x = (x + 1) & 0xff;
+ y = (State[x] + y) & 0xff;
+
+ swapbyte = State[x];
+ State[x] = State[y];
+ State[y] = swapbyte;
+
+ return State[ (State[x] + State[y]) & 0xff ];
+}
+
+void ARC4::Encrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte)
+{
+ uint8_t * dat = (uint8_t *) Data;
+ x = Backx;
+ y = Backy;
+ memcpy(State, BackState, sizeof(State));
+
+ for (unsigned int i = (Nonce + (Nonce >> 8) + (Nonce >> 16) + (Nonce >> 24)) & 0x1ff; i > 0; --i)
+ Stream();
+
+ while (Size > 0)
+ {
+ (*dat) = (*dat) ^ Stream();
+ --Size;
+ ++dat;
+ }
+}
+void ARC4::Decrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte)
+{
+ Encrypt(Data, Size, Nonce, StartByte);
+}
+
+extern "C" __declspec(dllexport) const TCipherInfo* CipherInfo(void * Reserved)
+{
+ return &ARC4::cCipherInfo;
+}
diff --git a/dbx_tree/encryption/ARC4.h b/dbx_tree/encryption/ARC4.h new file mode 100644 index 0000000..48fdc35 --- /dev/null +++ b/dbx_tree/encryption/ARC4.h @@ -0,0 +1,65 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2008 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include "Cipher.h"
+
+class ARC4 : public CCipher
+{
+private:
+ uint8_t x;
+ uint8_t y;
+ uint8_t State[256];
+
+ uint8_t Backx;
+ uint8_t Backy;
+ uint8_t BackState[256];
+
+ uint8_t Stream();
+
+ static const wchar_t* cName;
+ static const wchar_t* cDescription;
+ static const uint32_t cBlockSizeBytes = 1;
+ static const bool cIsStreamCipher = true;
+
+public:
+ const wchar_t * __cdecl Name();
+ const wchar_t * __cdecl Description();
+ const uint32_t __cdecl BlockSizeBytes();
+ const bool __cdecl IsStreamCipher();
+
+ static const TCipherInfo cCipherInfo;
+
+ ARC4();
+ ~ARC4();
+ static CCipher::TCipherInterface* __cdecl Create();
+
+ void __cdecl SetKey(void* Key, uint32_t KeyLength);
+ void __cdecl Encrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte);
+ void __cdecl Decrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte);
+
+};
+
+const wchar_t* ARC4::cName = L"ARC4";
+const wchar_t* ARC4::cDescription = L"Streamcipher - 8bit step, fast, Ron Rivest 1987";
+const TCipherInfo ARC4::cCipherInfo = {sizeof(TCipherInfo), 'ARC4', cName, cDescription, &ARC4::Create};
diff --git a/dbx_tree/encryption/ARC4.vcproj b/dbx_tree/encryption/ARC4.vcproj new file mode 100644 index 0000000..fc4918a --- /dev/null +++ b/dbx_tree/encryption/ARC4.vcproj @@ -0,0 +1,376 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="dbx_tree_ARC4"
+ ProjectGUID="{F60935E3-8F27-46E2-8598-013E7D4C90E7}"
+ RootNamespace="dbx_tree_encryption"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins/encryption"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;DBX_TREE_ENCRYPTION_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins/encryption"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="false"
+ WholeProgramOptimization="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;DBX_TREE_ENCRYPTION_EXPORTS"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="2"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins/encryption"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;DBX_TREE_ENCRYPTION_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins/encryption"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="false"
+ WholeProgramOptimization="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;DBX_TREE_ENCRYPTION_EXPORTS"
+ StringPooling="true"
+ ExceptionHandling="1"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="2"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="0"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ EmbedManifest="true"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\ARC4.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\ARC4.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Cipher.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/dbx_tree/encryption/ARC4.vcxproj b/dbx_tree/encryption/ARC4.vcxproj new file mode 100644 index 0000000..6387807 --- /dev/null +++ b/dbx_tree/encryption/ARC4.vcxproj @@ -0,0 +1,476 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug Unicode|Win32">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Unicode|x64">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|x64">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>dbx_tree_ARC4</ProjectName>
+ <ProjectGUID>{F60935E3-8F27-46E2-8598-013E7D4C90E7}</ProjectGUID>
+ <RootNamespace>dbx_tree_encryption</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(LocalAppData)\Microsoft\VisualStudio\10.0\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(LocalAppData)\Microsoft\VisualStudio\10.0\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">false</LinkIncremental>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DBX_TREE_ENCRYPTION_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DBX_TREE_ENCRYPTION_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DBX_TREE_ENCRYPTION_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DBX_TREE_ENCRYPTION_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DBX_TREE_ENCRYPTION_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;DBX_TREE_ENCRYPTION_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DBX_TREE_ENCRYPTION_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DBX_TREE_ENCRYPTION_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="ARC4.h" />
+ <ClInclude Include="Cipher.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="ARC4.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file diff --git a/dbx_tree/encryption/ARC4.vcxproj.filters b/dbx_tree/encryption/ARC4.vcxproj.filters new file mode 100644 index 0000000..513c512 --- /dev/null +++ b/dbx_tree/encryption/ARC4.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="ARC4.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Cipher.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="ARC4.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
\ No newline at end of file diff --git a/dbx_tree/encryption/CAST128.cpp b/dbx_tree/encryption/CAST128.cpp new file mode 100644 index 0000000..2814a41 --- /dev/null +++ b/dbx_tree/encryption/CAST128.cpp @@ -0,0 +1,260 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2008 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "CAST128.h"
+#include "CAST128.inc"
+
+const wchar_t * CAST128::Name()
+{
+ return cName;
+}
+const wchar_t * CAST128::Description()
+{
+ return cDescription;
+}
+const uint32_t CAST128::BlockSizeBytes()
+{
+ return cBlockSizeBytes;
+}
+const bool CAST128::IsStreamCipher()
+{
+ return cIsStreamCipher;
+}
+
+CAST128::CAST128()
+{
+
+}
+CAST128::~CAST128()
+{
+
+}
+CCipher::TCipherInterface* CAST128::Create()
+{
+ return (new CAST128())->m_Interface;
+}
+
+void CAST128::SetKey(void* Key, uint32_t KeyLength)
+{
+ uint8_t k128[16] = "Mirandadbx_tree";
+ int i = 0;
+ uint8_t* k = (uint8_t*) Key;
+ while (KeyLength > 0)
+ {
+ k128[i] = k128[i] ^ (*k);
+ i = (i + 1) % 16;
+ ++k;
+ --KeyLength;
+ }
+ CreateSubKeys(k128);
+}
+void CAST128::Encrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte)
+{
+ for (uint32_t i = 0; i <= Size - BlockSizeBytes(); i += BlockSizeBytes())
+ {
+ EncryptBlock((uint8_t*)Data + i);
+ StartByte += BlockSizeBytes();
+ }
+}
+void CAST128::Decrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte)
+{
+ for (uint32_t i = 0; i <= Size - BlockSizeBytes(); i += BlockSizeBytes())
+ {
+ DecryptBlock((uint8_t*)Data + i);
+ StartByte += BlockSizeBytes();
+ }
+}
+
+void CAST128::CreateSubKeys(uint8_t* Key)
+{
+ union {
+ uint8_t z[16];
+ uint32_t i[4];
+ } t;
+
+ uint32_t* k;
+ k = (uint32_t*) Key;
+
+ t.i[0] = k[0] ^ S5[Key[0xD]] ^ S6[Key[0xF]] ^ S7[Key[0xC]] ^ S8[Key[0xE]] ^ S7[Key[0x8]];
+ t.i[1] = k[2] ^ S5[t.z[0x0]] ^ S6[t.z[0x2]] ^ S7[t.z[0x1]] ^ S8[t.z[0x3]] ^ S8[Key[0xA]];
+ t.i[2] = k[3] ^ S5[t.z[0x7]] ^ S6[t.z[0x6]] ^ S7[t.z[0x5]] ^ S8[t.z[0x4]] ^ S5[Key[0x9]];
+ t.i[3] = k[1] ^ S5[t.z[0xA]] ^ S6[t.z[0x9]] ^ S7[t.z[0xB]] ^ S8[t.z[0x8]] ^ S6[Key[0xB]];
+
+ Km[0x0] = S5[t.z[0x8]] ^ S6[t.z[0x9]] ^ S7[t.z[0x7]] ^ S8[t.z[0x6]] ^ S5[t.z[0x2]];
+ Km[0x1] = S5[t.z[0xA]] ^ S6[t.z[0xB]] ^ S7[t.z[0x5]] ^ S8[t.z[0x4]] ^ S6[t.z[0x6]];
+ Km[0x2] = S5[t.z[0xC]] ^ S6[t.z[0xD]] ^ S7[t.z[0x3]] ^ S8[t.z[0x2]] ^ S7[t.z[0x9]];
+ Km[0x3] = S5[t.z[0xE]] ^ S6[t.z[0xF]] ^ S7[t.z[0x1]] ^ S8[t.z[0x0]] ^ S8[t.z[0xC]];
+
+ k[0] = t.i[2] ^ S5[t.z[0x5]] ^ S6[t.z[0x7]] ^ S7[t.z[0x4]] ^ S8[t.z[0x6]] ^ S7[t.z[0x0]];
+ k[1] = t.i[0] ^ S5[Key[0x0]] ^ S6[Key[0x2]] ^ S7[Key[0x1]] ^ S8[Key[0x3]] ^ S8[t.z[0x2]];
+ k[2] = t.i[1] ^ S5[Key[0x7]] ^ S6[Key[0x6]] ^ S7[Key[0x5]] ^ S8[Key[0x4]] ^ S5[t.z[0x1]];
+ k[3] = t.i[3] ^ S5[Key[0xA]] ^ S6[Key[0x9]] ^ S7[Key[0xB]] ^ S8[Key[0x8]] ^ S6[t.z[0x3]];
+
+ Km[0x4] = S5[Key[0x3]] ^ S6[Key[0x2]] ^ S7[Key[0xC]] ^ S8[Key[0xD]] ^ S5[Key[0x8]];
+ Km[0x5] = S5[Key[0x1]] ^ S6[Key[0x0]] ^ S7[Key[0xE]] ^ S8[Key[0xF]] ^ S6[Key[0xD]];
+ Km[0x6] = S5[Key[0x7]] ^ S6[Key[0x6]] ^ S7[Key[0x8]] ^ S8[Key[0x9]] ^ S7[Key[0x3]];
+ Km[0x7] = S5[Key[0x5]] ^ S6[Key[0x4]] ^ S7[Key[0xA]] ^ S8[Key[0xB]] ^ S8[Key[0x7]];
+
+ t.i[0] = k[0] ^ S5[Key[0xD]] ^ S6[Key[0xF]] ^ S7[Key[0xC]] ^ S8[Key[0xE]] ^ S7[Key[0x8]];
+ t.i[1] = k[2] ^ S5[t.z[0x0]] ^ S6[t.z[0x2]] ^ S7[t.z[0x1]] ^ S8[t.z[0x3]] ^ S8[Key[0xA]];
+ t.i[2] = k[3] ^ S5[t.z[0x7]] ^ S6[t.z[0x6]] ^ S7[t.z[0x5]] ^ S8[t.z[0x4]] ^ S5[Key[0x9]];
+ t.i[3] = k[1] ^ S5[t.z[0xA]] ^ S6[t.z[0x9]] ^ S7[t.z[0xB]] ^ S8[t.z[0x8]] ^ S6[Key[0xB]];
+
+ Km[0x8] = S5[t.z[0x3]] ^ S6[t.z[0x2]] ^ S7[t.z[0xC]] ^ S8[t.z[0xD]] ^ S5[t.z[0x9]];
+ Km[0x9] = S5[t.z[0x1]] ^ S6[t.z[0x0]] ^ S7[t.z[0xE]] ^ S8[t.z[0xF]] ^ S6[t.z[0xC]];
+ Km[0xa] = S5[t.z[0x7]] ^ S6[t.z[0x6]] ^ S7[t.z[0x8]] ^ S8[t.z[0x9]] ^ S7[t.z[0x2]];
+ Km[0xb] = S5[t.z[0x5]] ^ S6[t.z[0x4]] ^ S7[t.z[0xA]] ^ S8[t.z[0xB]] ^ S8[t.z[0x6]];
+
+ k[0] = t.i[2] ^ S5[t.z[0x5]] ^ S6[t.z[0x7]] ^ S7[t.z[0x4]] ^ S8[t.z[0x6]] ^ S7[t.z[0x0]];
+ k[1] = t.i[0] ^ S5[Key[0x0]] ^ S6[Key[0x2]] ^ S7[Key[0x1]] ^ S8[Key[0x3]] ^ S8[t.z[0x2]];
+ k[2] = t.i[1] ^ S5[Key[0x7]] ^ S6[Key[0x6]] ^ S7[Key[0x5]] ^ S8[Key[0x4]] ^ S5[t.z[0x1]];
+ k[3] = t.i[3] ^ S5[Key[0xA]] ^ S6[Key[0x9]] ^ S7[Key[0xB]] ^ S8[Key[0x8]] ^ S6[t.z[0x3]];
+
+ Km[0xc] = S5[Key[0x8]] ^ S6[Key[0x9]] ^ S7[Key[0x7]] ^ S8[Key[0x6]] ^ S5[Key[0x3]];
+ Km[0xd] = S5[Key[0xA]] ^ S6[Key[0xB]] ^ S7[Key[0x5]] ^ S8[Key[0x4]] ^ S6[Key[0x7]];
+ Km[0xe] = S5[Key[0xC]] ^ S6[Key[0xD]] ^ S7[Key[0x3]] ^ S8[Key[0x2]] ^ S7[Key[0x8]];
+ Km[0xf] = S5[Key[0xE]] ^ S6[Key[0xF]] ^ S7[Key[0x1]] ^ S8[Key[0x0]] ^ S8[Key[0xD]];
+
+
+
+ t.i[0] = k[0] ^ S5[Key[0xD]] ^ S6[Key[0xF]] ^ S7[Key[0xC]] ^ S8[Key[0xE]] ^ S7[Key[0x8]];
+ t.i[1] = k[2] ^ S5[t.z[0x0]] ^ S6[t.z[0x2]] ^ S7[t.z[0x1]] ^ S8[t.z[0x3]] ^ S8[Key[0xA]];
+ t.i[2] = k[3] ^ S5[t.z[0x7]] ^ S6[t.z[0x6]] ^ S7[t.z[0x5]] ^ S8[t.z[0x4]] ^ S5[Key[0x9]];
+ t.i[3] = k[1] ^ S5[t.z[0xA]] ^ S6[t.z[0x9]] ^ S7[t.z[0xB]] ^ S8[t.z[0x8]] ^ S6[Key[0xB]];
+
+ Kr[0x0] = S5[t.z[0x8]] ^ S6[t.z[0x9]] ^ S7[t.z[0x7]] ^ S8[t.z[0x6]] ^ S5[t.z[0x2]];
+ Kr[0x1] = S5[t.z[0xA]] ^ S6[t.z[0xB]] ^ S7[t.z[0x5]] ^ S8[t.z[0x4]] ^ S6[t.z[0x6]];
+ Kr[0x2] = S5[t.z[0xC]] ^ S6[t.z[0xD]] ^ S7[t.z[0x3]] ^ S8[t.z[0x2]] ^ S7[t.z[0x9]];
+ Kr[0x3] = S5[t.z[0xE]] ^ S6[t.z[0xF]] ^ S7[t.z[0x1]] ^ S8[t.z[0x0]] ^ S8[t.z[0xC]];
+
+ k[0] = t.i[2] ^ S5[t.z[0x5]] ^ S6[t.z[0x7]] ^ S7[t.z[0x4]] ^ S8[t.z[0x6]] ^ S7[t.z[0x0]];
+ k[1] = t.i[0] ^ S5[Key[0x0]] ^ S6[Key[0x2]] ^ S7[Key[0x1]] ^ S8[Key[0x3]] ^ S8[t.z[0x2]];
+ k[2] = t.i[1] ^ S5[Key[0x7]] ^ S6[Key[0x6]] ^ S7[Key[0x5]] ^ S8[Key[0x4]] ^ S5[t.z[0x1]];
+ k[3] = t.i[3] ^ S5[Key[0xA]] ^ S6[Key[0x9]] ^ S7[Key[0xB]] ^ S8[Key[0x8]] ^ S6[t.z[0x3]];
+
+ Kr[0x4] = S5[Key[0x3]] ^ S6[Key[0x2]] ^ S7[Key[0xC]] ^ S8[Key[0xD]] ^ S5[Key[0x8]];
+ Kr[0x5] = S5[Key[0x1]] ^ S6[Key[0x0]] ^ S7[Key[0xE]] ^ S8[Key[0xF]] ^ S6[Key[0xD]];
+ Kr[0x6] = S5[Key[0x7]] ^ S6[Key[0x6]] ^ S7[Key[0x8]] ^ S8[Key[0x9]] ^ S7[Key[0x3]];
+ Kr[0x7] = S5[Key[0x5]] ^ S6[Key[0x4]] ^ S7[Key[0xA]] ^ S8[Key[0xB]] ^ S8[Key[0x7]];
+
+ t.i[0] = k[0] ^ S5[Key[0xD]] ^ S6[Key[0xF]] ^ S7[Key[0xC]] ^ S8[Key[0xE]] ^ S7[Key[0x8]];
+ t.i[1] = k[2] ^ S5[t.z[0x0]] ^ S6[t.z[0x2]] ^ S7[t.z[0x1]] ^ S8[t.z[0x3]] ^ S8[Key[0xA]];
+ t.i[2] = k[3] ^ S5[t.z[0x7]] ^ S6[t.z[0x6]] ^ S7[t.z[0x5]] ^ S8[t.z[0x4]] ^ S5[Key[0x9]];
+ t.i[3] = k[1] ^ S5[t.z[0xA]] ^ S6[t.z[0x9]] ^ S7[t.z[0xB]] ^ S8[t.z[0x8]] ^ S6[Key[0xB]];
+
+ Kr[0x8] = S5[t.z[0x3]] ^ S6[t.z[0x2]] ^ S7[t.z[0xC]] ^ S8[t.z[0xD]] ^ S5[t.z[0x9]];
+ Kr[0x9] = S5[t.z[0x1]] ^ S6[t.z[0x0]] ^ S7[t.z[0xE]] ^ S8[t.z[0xF]] ^ S6[t.z[0xC]];
+ Kr[0xa] = S5[t.z[0x7]] ^ S6[t.z[0x6]] ^ S7[t.z[0x8]] ^ S8[t.z[0x9]] ^ S7[t.z[0x2]];
+ Kr[0xb] = S5[t.z[0x5]] ^ S6[t.z[0x4]] ^ S7[t.z[0xA]] ^ S8[t.z[0xB]] ^ S8[t.z[0x6]];
+
+ k[0] = t.i[2] ^ S5[t.z[0x5]] ^ S6[t.z[0x7]] ^ S7[t.z[0x4]] ^ S8[t.z[0x6]] ^ S7[t.z[0x0]];
+ k[1] = t.i[0] ^ S5[Key[0x0]] ^ S6[Key[0x2]] ^ S7[Key[0x1]] ^ S8[Key[0x3]] ^ S8[t.z[0x2]];
+ k[2] = t.i[1] ^ S5[Key[0x7]] ^ S6[Key[0x6]] ^ S7[Key[0x5]] ^ S8[Key[0x4]] ^ S5[t.z[0x1]];
+ k[3] = t.i[3] ^ S5[Key[0xA]] ^ S6[Key[0x9]] ^ S7[Key[0xB]] ^ S8[Key[0x8]] ^ S6[t.z[0x3]];
+
+ Kr[0xc] = S5[Key[0x8]] ^ S6[Key[0x9]] ^ S7[Key[0x7]] ^ S8[Key[0x6]] ^ S5[Key[0x3]];
+ Kr[0xd] = S5[Key[0xA]] ^ S6[Key[0xB]] ^ S7[Key[0x5]] ^ S8[Key[0x4]] ^ S6[Key[0x7]];
+ Kr[0xe] = S5[Key[0xC]] ^ S6[Key[0xD]] ^ S7[Key[0x3]] ^ S8[Key[0x2]] ^ S7[Key[0x8]];
+ Kr[0xf] = S5[Key[0xE]] ^ S6[Key[0xF]] ^ S7[Key[0x1]] ^ S8[Key[0x0]] ^ S8[Key[0xD]];
+
+
+ for (int i = 0; i < 16; i++)
+ Kr[i] = Kr[i] & 0x0000001F;
+}
+
+
+inline void CAST128::EncryptBlock(uint8_t *Block)
+{
+ uint32_t l, r, tmp;
+ union {
+ uint8_t byte[4];
+ uint32_t block;
+ } t;
+
+ l = ((uint32_t*)Block)[0];
+ r = ((uint32_t*)Block)[1];
+
+ for (int i = 0; i < 16; i++)
+ {
+ if ((i % 3) == 0)
+ {
+ t.block = (t.block << Kr[i]) | (t.block >> (32 - Kr[i]));
+ t.block = ((S1[t.byte[0]] ^ S2[t.byte[1]]) - S3[t.byte[2]]) + S4[t.byte[3]];
+ } else if ((i % 3) == 1)
+ {
+ t.block = (t.block << Kr[i]) | (t.block >> (32 - Kr[i]));
+ t.block = ((S1[t.byte[0]] - S2[t.byte[1]]) + S3[t.byte[2]]) ^ S4[t.byte[3]];
+ } else {
+ t.block = (t.block << Kr[i]) | (t.block >> (32 - Kr[i]));
+ t.block = ((S1[t.byte[0]] + S2[t.byte[1]]) ^ S3[t.byte[2]]) - S4[t.byte[3]];
+ }
+
+ tmp = r;
+ r = l ^ t.block;
+ l = tmp;
+ }
+
+ ((uint32_t*)Block)[0] = l;
+ ((uint32_t*)Block)[1] = r;
+}
+
+
+
+inline void CAST128::DecryptBlock(uint8_t *Block)
+{
+ uint32_t l, r, tmp;
+ union {
+ uint8_t byte[4];
+ uint32_t block;
+ } t;
+
+ r = ((uint32_t*)Block)[0];
+ l = ((uint32_t*)Block)[1];
+
+ for (int i = 15; i >= 0; i--)
+ {
+ if ((i % 3) == 0)
+ {
+ t.block = (t.block << Kr[i]) | (t.block >> (32 - Kr[i]));
+ t.block = ((S1[t.byte[0]] ^ S2[t.byte[1]]) - S3[t.byte[2]]) + S4[t.byte[3]];
+ } else if ((i % 3) == 1)
+ {
+ t.block = (t.block << Kr[i]) | (t.block >> (32 - Kr[i]));
+ t.block = ((S1[t.byte[0]] - S2[t.byte[1]]) + S3[t.byte[2]]) ^ S4[t.byte[3]];
+ } else {
+ t.block = (t.block << Kr[i]) | (t.block >> (32 - Kr[i]));
+ t.block = ((S1[t.byte[0]] + S2[t.byte[1]]) ^ S3[t.byte[2]]) - S4[t.byte[3]];
+ }
+
+ tmp = r;
+ r = l ^ t.block;
+ l = tmp;
+ }
+
+ ((uint32_t*)Block)[0] = r;
+ ((uint32_t*)Block)[1] = l;
+}
+
+extern "C" __declspec(dllexport) const TCipherInfo* CipherInfo(void * Reserved)
+{
+ return &CAST128::cCipherInfo;
+}
diff --git a/dbx_tree/encryption/CAST128.h b/dbx_tree/encryption/CAST128.h new file mode 100644 index 0000000..9477254 --- /dev/null +++ b/dbx_tree/encryption/CAST128.h @@ -0,0 +1,61 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2008 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include "Cipher.h"
+
+class CAST128 : public CCipher
+{
+private:
+ uint32_t Km[16], Kr[16];
+
+ void EncryptBlock(uint8_t *Block);
+ void DecryptBlock(uint8_t *Block);
+ void CreateSubKeys(uint8_t* Key);
+
+ static const wchar_t* cName;
+ static const wchar_t* cDescription;
+ static const uint32_t cBlockSizeBytes = 8;
+ static const bool cIsStreamCipher = false;
+
+public:
+ const wchar_t * __cdecl Name();
+ const wchar_t * __cdecl Description();
+ const uint32_t __cdecl BlockSizeBytes();
+ const bool __cdecl IsStreamCipher();
+
+ static const TCipherInfo cCipherInfo;
+
+ CAST128();
+ ~CAST128();
+ static CCipher::TCipherInterface* __cdecl Create();
+
+ void __cdecl SetKey(void* Key, uint32_t KeyLength);
+ void __cdecl Encrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte);
+ void __cdecl Decrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte);
+
+};
+
+const wchar_t* CAST128::cName = L"Cast128";
+const wchar_t* CAST128::cDescription = L"Blockcipher - 64bit block, fast and secure, Carlisle Adams and Stafford Tavares 1996";
+const TCipherInfo CAST128::cCipherInfo = {sizeof(TCipherInfo), 'Cast', cName, cDescription, &CAST128::Create};
diff --git a/dbx_tree/encryption/CAST128.inc b/dbx_tree/encryption/CAST128.inc new file mode 100644 index 0000000..8389acc --- /dev/null +++ b/dbx_tree/encryption/CAST128.inc @@ -0,0 +1,302 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2008 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+
+static const uint32_t S1[256] = {
+0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
+0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
+0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
+0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
+0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
+0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
+0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
+0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
+0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
+0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
+0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
+0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
+0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
+0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
+0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
+0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
+0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
+0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
+0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
+0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
+0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
+0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
+0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
+0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
+0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
+0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
+0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
+0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
+0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
+0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
+0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
+0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf,
+};
+
+static const uint32_t S2[256] = {
+0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
+0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
+0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
+0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
+0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
+0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
+0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
+0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
+0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
+0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
+0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
+0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
+0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
+0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
+0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
+0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
+0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
+0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
+0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
+0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
+0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
+0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
+0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
+0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
+0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
+0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
+0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
+0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
+0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
+0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
+0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
+0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1,
+};
+
+static const uint32_t S3[256] = {
+0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
+0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
+0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
+0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
+0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
+0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
+0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
+0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
+0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
+0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
+0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
+0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
+0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
+0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
+0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
+0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
+0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
+0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
+0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
+0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
+0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
+0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
+0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
+0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
+0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
+0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
+0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
+0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
+0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
+0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
+0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
+0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783,
+};
+
+static const uint32_t S4[256] = {
+0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
+0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
+0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
+0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
+0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
+0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
+0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
+0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
+0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
+0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
+0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
+0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
+0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
+0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
+0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
+0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
+0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
+0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
+0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
+0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
+0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
+0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
+0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
+0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
+0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
+0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
+0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
+0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
+0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
+0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
+0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
+0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2,
+};
+
+static const uint32_t S5[256] = {
+0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
+0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
+0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
+0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
+0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
+0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
+0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
+0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
+0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
+0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
+0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
+0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
+0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
+0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
+0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
+0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
+0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
+0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
+0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
+0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
+0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
+0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
+0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
+0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
+0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
+0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
+0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
+0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
+0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
+0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
+0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
+0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4,
+};
+
+static const uint32_t S6[256] = {
+0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
+0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
+0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
+0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
+0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
+0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
+0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
+0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
+0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
+0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
+0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
+0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
+0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
+0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
+0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
+0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
+0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
+0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
+0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
+0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
+0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
+0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
+0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
+0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
+0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
+0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
+0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
+0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
+0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
+0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
+0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
+0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f,
+};
+
+static const uint32_t S7[256] = {
+0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
+0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
+0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
+0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
+0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
+0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
+0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
+0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
+0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
+0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
+0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
+0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
+0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
+0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
+0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
+0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
+0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
+0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
+0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
+0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
+0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
+0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
+0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
+0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
+0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
+0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
+0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
+0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
+0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
+0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
+0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
+0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3,
+};
+
+static const uint32_t S8[256] = {
+0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
+0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
+0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
+0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
+0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
+0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
+0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
+0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
+0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
+0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
+0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
+0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
+0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
+0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
+0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
+0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
+0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
+0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
+0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
+0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
+0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
+0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
+0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
+0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
+0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
+0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
+0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
+0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
+0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
+0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
+0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
+0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e,
+};
diff --git a/dbx_tree/encryption/Cast128.vcproj b/dbx_tree/encryption/Cast128.vcproj new file mode 100644 index 0000000..8b1fd92 --- /dev/null +++ b/dbx_tree/encryption/Cast128.vcproj @@ -0,0 +1,380 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="dbx_tree_Cast128"
+ ProjectGUID="{7E88D7F5-8B0A-4B79-84CD-D7982D4E0D4D}"
+ RootNamespace="Cast128"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins/encryption"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;CAST128_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins/encryption"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="false"
+ WholeProgramOptimization="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;CAST128_EXPORTS"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="2"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins/encryption"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;CAST128_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins/encryption"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="false"
+ WholeProgramOptimization="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;CAST128_EXPORTS"
+ StringPooling="true"
+ ExceptionHandling="1"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="2"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="0"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ EmbedManifest="true"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\CAST128.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\CAST128.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CAST128.inc"
+ >
+ </File>
+ <File
+ RelativePath=".\Cipher.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/dbx_tree/encryption/Cast128.vcxproj b/dbx_tree/encryption/Cast128.vcxproj new file mode 100644 index 0000000..432bd9a --- /dev/null +++ b/dbx_tree/encryption/Cast128.vcxproj @@ -0,0 +1,479 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug Unicode|Win32">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Unicode|x64">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|x64">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>dbx_tree_Cast128</ProjectName>
+ <ProjectGUID>{7E88D7F5-8B0A-4B79-84CD-D7982D4E0D4D}</ProjectGUID>
+ <RootNamespace>Cast128</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(LocalAppData)\Microsoft\VisualStudio\10.0\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(LocalAppData)\Microsoft\VisualStudio\10.0\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">false</LinkIncremental>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CAST128_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CAST128_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CAST128_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CAST128_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CAST128_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CAST128_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CAST128_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CAST128_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="CAST128.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="CAST128.h" />
+ <ClInclude Include="Cipher.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="CAST128.inc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file diff --git a/dbx_tree/encryption/Cast128.vcxproj.filters b/dbx_tree/encryption/Cast128.vcxproj.filters new file mode 100644 index 0000000..5c3548e --- /dev/null +++ b/dbx_tree/encryption/Cast128.vcxproj.filters @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="CAST128.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="CAST128.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="Cipher.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="CAST128.inc">
+ <Filter>Header Files</Filter>
+ </None>
+ </ItemGroup>
+</Project>
\ No newline at end of file diff --git a/dbx_tree/encryption/Cipher.h b/dbx_tree/encryption/Cipher.h new file mode 100644 index 0000000..76d07e6 --- /dev/null +++ b/dbx_tree/encryption/Cipher.h @@ -0,0 +1,180 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#ifdef _MSC_VER
+#include "../stdint.h"
+#else
+#include <stdint.h>
+#endif
+
+#include <wchar.h>
+
+#pragma pack(push, 1)
+
+#ifdef __INTERFACE_ONLY__
+#define __INTERFACE_VIRTUAL__
+#else
+#define __INTERFACE_VIRTUAL__ virtual
+#endif
+
+class CCipher
+{
+public:
+ typedef struct TCipherInterface
+ {
+ CCipher * self;
+ uint32_t Size;
+ void (__cdecl CCipher::*Destroy)();
+
+ const wchar_t* (__cdecl CCipher::*Name)();
+ const wchar_t* (__cdecl CCipher::*Description)();
+ const uint32_t (__cdecl CCipher::*BlockSizeBytes)();
+ const bool (__cdecl CCipher::*IsStreamCipher)();
+
+ void (__cdecl CCipher::*SetKey)(void* Key, uint32_t KeyLength);
+ void (__cdecl CCipher::*Encrypt)(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte);
+ void (__cdecl CCipher::*Decrypt)(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte);
+
+ } TCipherInterface;
+ TCipherInterface * m_Interface;
+
+#ifndef __INTERFACE_ONLY__
+ virtual void __cdecl Destroy()
+ {
+ delete this;
+ }
+
+ CCipher()
+ {
+ m_Interface = new TCipherInterface;
+ m_Interface->Size = sizeof(TCipherInterface);
+ m_Interface->self = this;
+ m_Interface->Destroy = &CCipher::Destroy;
+ m_Interface->Name = &CCipher::Name;
+ m_Interface->Description = &CCipher::Description;
+ m_Interface->BlockSizeBytes = &CCipher::BlockSizeBytes;
+ m_Interface->IsStreamCipher = &CCipher::IsStreamCipher;
+ m_Interface->SetKey = &CCipher::SetKey;
+ m_Interface->Encrypt = &CCipher::Encrypt;
+ m_Interface->Decrypt = &CCipher::Decrypt;
+ };
+#endif
+
+#ifdef __INTERFACE_ONLY__
+ CCipher(TCipherInterface * Interface)
+ {
+ m_Interface = Interface;
+ };
+#endif
+
+ __INTERFACE_VIRTUAL__ ~CCipher()
+#ifdef __INTERFACE_ONLY__
+ {
+ (m_Interface->self->*(m_Interface->Destroy))();
+ }
+#else
+ { }
+#endif
+ ;
+
+ __INTERFACE_VIRTUAL__ const wchar_t* __cdecl Name()
+#ifdef __INTERFACE_ONLY__
+ {
+ return (m_Interface->self->*(m_Interface->Name))();
+ }
+#else
+ = 0
+#endif
+ ;
+
+ __INTERFACE_VIRTUAL__ const wchar_t* __cdecl Description()
+#ifdef __INTERFACE_ONLY__
+ {
+ return (m_Interface->self->*(m_Interface->Description))();
+ }
+#else
+ = 0
+#endif
+ ;
+
+ __INTERFACE_VIRTUAL__ const uint32_t __cdecl BlockSizeBytes()
+#ifdef __INTERFACE_ONLY__
+ {
+ return (m_Interface->self->*(m_Interface->BlockSizeBytes))();
+ }
+#else
+ = 0
+#endif
+ ;
+
+ __INTERFACE_VIRTUAL__ const bool __cdecl IsStreamCipher()
+#ifdef __INTERFACE_ONLY__
+ {
+ return (m_Interface->self->*(m_Interface->IsStreamCipher))();
+ }
+#else
+ = 0
+#endif
+ ;
+
+ __INTERFACE_VIRTUAL__ void __cdecl SetKey(void* Key, uint32_t KeyLength)
+#ifdef __INTERFACE_ONLY__
+ {
+ return (m_Interface->self->*(m_Interface->SetKey))(Key, KeyLength);
+ }
+#else
+ = 0
+#endif
+ ;
+ __INTERFACE_VIRTUAL__ void __cdecl Encrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte)
+#ifdef __INTERFACE_ONLY__
+ {
+ return (m_Interface->self->*(m_Interface->Encrypt))(Data, Size, Nonce, StartByte);
+ }
+#else
+ = 0
+#endif
+ ;
+ __INTERFACE_VIRTUAL__ void __cdecl Decrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte)
+#ifdef __INTERFACE_ONLY__
+ {
+ return (m_Interface->self->*(m_Interface->Decrypt))(Data, Size, Nonce, StartByte);
+ }
+#else
+ = 0
+#endif
+ ;
+
+};
+
+typedef struct TCipherInfo
+{
+ uint32_t cbSize;
+ const uint32_t ID;
+ const wchar_t* Name;
+ const wchar_t* Description;
+ CCipher::TCipherInterface * (__cdecl *Create)();
+} TCipherInfo;
+
+#pragma pack(pop)
diff --git a/dbx_tree/encryption/HC256.cpp b/dbx_tree/encryption/HC256.cpp new file mode 100644 index 0000000..19b1ca7 --- /dev/null +++ b/dbx_tree/encryption/HC256.cpp @@ -0,0 +1,243 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2008 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "HC256.h"
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _MSC_VER
+ #define rotr(x,n) (((x)>>(n))|((x)<<(32-(n))))
+#else
+ #define rotr(x,n) _lrotr(x,n)
+#endif
+
+#define h1(x,y) { \
+ uint8_t a,b,c,d; \
+ a = (uint8_t) (x); \
+ b = (uint8_t) ((x) >> 8); \
+ c = (uint8_t) ((x) >> 16); \
+ d = (uint8_t) ((x) >> 24); \
+ (y) = Q[a]+Q[256+b]+Q[512+c]+Q[768+d]; \
+}
+#define h2(x,y) { \
+ uint8_t a,b,c,d; \
+ a = (uint8_t) (x); \
+ b = (uint8_t) ((x) >> 8); \
+ c = (uint8_t) ((x) >> 16); \
+ d = (uint8_t) ((x) >> 24); \
+ (y) = P[a]+P[256+b]+P[512+c]+P[768+d]; \
+}
+#define step_A(u,v,a,b,c,d,m){ \
+ uint32_t tem0,tem1,tem2,tem3; \
+ tem0 = rotr((v),23); \
+ tem1 = rotr((c),10); \
+ tem2 = ((v) ^ (c)) & 0x3ff; \
+ (u) += (b)+(tem0^tem1)+Q[tem2]; \
+ (a) = (u); \
+ h1((d),tem3); \
+ (m) ^= tem3 ^ (u) ; \
+}
+#define step_B(u,v,a,b,c,d,m){ \
+ uint32_t tem0,tem1,tem2,tem3; \
+ tem0 = rotr((v),23); \
+ tem1 = rotr((c),10); \
+ tem2 = ((v) ^ (c)) & 0x3ff; \
+ (u) += (b)+(tem0^tem1)+P[tem2]; \
+ (a) = (u); \
+ h2((d),tem3); \
+ (m) ^= tem3 ^ (u) ; \
+}
+
+
+#define f1(x) (rotr((x),7) ^ rotr((x),18) ^ ((x) >> 3))
+#define f2(x) (rotr((x),17) ^ rotr((x),19) ^ ((x) >> 10))
+#define f(a,b,c,d) (f2((a)) + (b) + f1((c)) + (d))
+#define feedback_1(u,v,b,c) { \
+ uint32_t tem0,tem1,tem2; \
+ tem0 = rotr((v),23); \
+ tem1 = rotr((c),10); \
+ tem2 = ((v) ^ (c)) & 0x3ff; \
+ (u) += (b)+(tem0^tem1)+Q[tem2]; \
+}
+#define feedback_2(u,v,b,c) { \
+ uint32_t tem0,tem1,tem2; \
+ tem0 = rotr((v),23); \
+ tem1 = rotr((c),10); \
+ tem2 = ((v) ^ (c)) & 0x3ff; \
+ (u) += (b)+(tem0^tem1)+P[tem2]; \
+}
+
+const wchar_t * HC256::Name()
+{
+ return cName;
+}
+const wchar_t * HC256::Description()
+{
+ return cDescription;
+}
+const uint32_t HC256::BlockSizeBytes()
+{
+ return cBlockSizeBytes;
+}
+const bool HC256::IsStreamCipher()
+{
+ return cIsStreamCipher;
+}
+
+HC256::HC256()
+{
+
+}
+HC256::~HC256()
+{
+
+}
+CCipher::TCipherInterface* HC256::Create()
+{
+ return (new HC256())->m_Interface;
+}
+
+void HC256::SetKey(void* Key, uint32_t KeyLength)
+{
+ uint8_t k[32] = {0};
+
+ for (uint32_t i = 0; i < KeyLength; ++i)
+ {
+ k[i & 0x1f] ^= ((uint8_t *)Key)[i];
+ }
+ CreateTables(k);
+}
+void HC256::Encrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte)
+{
+ memcpy(X, BackX, sizeof(X));
+ memcpy(Y, BackY, sizeof(Y));
+ memcpy(P, BackP, sizeof(P));
+ memcpy(Q, BackQ, sizeof(Q));
+
+ counter2048 = (Nonce + (Nonce >> 11) + (Nonce >> 22)) & 0x7ff;
+
+ for (uint32_t i = 0; i <= Size - BlockSizeBytes(); i += BlockSizeBytes())
+ {
+ EncryptBlock((uint32_t*)((uint8_t*)Data + i));
+ StartByte += BlockSizeBytes();
+ }
+}
+void HC256::Decrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte)
+{
+ Encrypt(Data, Size, Nonce, StartByte);
+}
+
+inline void HC256::EncryptBlock(uint32_t *Data)
+{
+ uint32_t cc,dd;
+ cc = counter2048 & 0x3ff;
+ dd = (cc + 16) & 0x3ff;
+ if (counter2048 < 1024)
+ {
+ counter2048 = (counter2048 + 16) & 0x7ff;
+ step_A(P[cc+0], P[cc+1], X[0], X[6], X[13],X[4], Data[0]);
+ step_A(P[cc+1], P[cc+2], X[1], X[7], X[14],X[5], Data[1]);
+ step_A(P[cc+2], P[cc+3], X[2], X[8], X[15],X[6], Data[2]);
+ step_A(P[cc+3], P[cc+4], X[3], X[9], X[0], X[7], Data[3]);
+ step_A(P[cc+4], P[cc+5], X[4], X[10],X[1], X[8], Data[4]);
+ step_A(P[cc+5], P[cc+6], X[5], X[11],X[2], X[9], Data[5]);
+ step_A(P[cc+6], P[cc+7], X[6], X[12],X[3], X[10],Data[6]);
+ step_A(P[cc+7], P[cc+8], X[7], X[13],X[4], X[11],Data[7]);
+ step_A(P[cc+8], P[cc+9], X[8], X[14],X[5], X[12],Data[8]);
+ step_A(P[cc+9], P[cc+10],X[9], X[15],X[6], X[13],Data[9]);
+ step_A(P[cc+10],P[cc+11],X[10],X[0], X[7], X[14],Data[10]);
+ step_A(P[cc+11],P[cc+12],X[11],X[1], X[8], X[15],Data[11]);
+ step_A(P[cc+12],P[cc+13],X[12],X[2], X[9], X[0], Data[12]);
+ step_A(P[cc+13],P[cc+14],X[13],X[3], X[10],X[1], Data[13]);
+ step_A(P[cc+14],P[cc+15],X[14],X[4], X[11],X[2], Data[14]);
+ step_A(P[cc+15],P[dd+0], X[15],X[5], X[12],X[3], Data[15]);
+
+ } else {
+
+ counter2048 = (counter2048 + 16) & 0x7ff;
+ step_B(Q[cc+0], Q[cc+1], Y[0], Y[6], Y[13],Y[4], Data[0]);
+ step_B(Q[cc+1], Q[cc+2], Y[1], Y[7], Y[14],Y[5], Data[1]);
+ step_B(Q[cc+2], Q[cc+3], Y[2], Y[8], Y[15],Y[6], Data[2]);
+ step_B(Q[cc+3], Q[cc+4], Y[3], Y[9], Y[0], Y[7], Data[3]);
+ step_B(Q[cc+4], Q[cc+5], Y[4], Y[10],Y[1], Y[8], Data[4]);
+ step_B(Q[cc+5], Q[cc+6], Y[5], Y[11],Y[2], Y[9], Data[5]);
+ step_B(Q[cc+6], Q[cc+7], Y[6], Y[12],Y[3], Y[10],Data[6]);
+ step_B(Q[cc+7], Q[cc+8], Y[7], Y[13],Y[4], Y[11],Data[7]);
+ step_B(Q[cc+8], Q[cc+9], Y[8], Y[14],Y[5], Y[12],Data[8]);
+ step_B(Q[cc+9], Q[cc+10],Y[9], Y[15],Y[6], Y[13],Data[9]);
+ step_B(Q[cc+10],Q[cc+11],Y[10],Y[0], Y[7], Y[14],Data[10]);
+ step_B(Q[cc+11],Q[cc+12],Y[11],Y[1], Y[8], Y[15],Data[11]);
+ step_B(Q[cc+12],Q[cc+13],Y[12],Y[2], Y[9], Y[0], Data[12]);
+ step_B(Q[cc+13],Q[cc+14],Y[13],Y[3], Y[10],Y[1], Data[13]);
+ step_B(Q[cc+14],Q[cc+15],Y[14],Y[4], Y[11],Y[2], Data[14]);
+ step_B(Q[cc+15],Q[dd+0], Y[15],Y[5], Y[12],Y[3], Data[15]);
+ }
+}
+inline void HC256::CreateTables(uint8_t* Key)
+{
+ uint32_t i, j;
+ uint8_t iv[32] = "Miranda IM dbx_tree Protogenes!";
+ //expand the key and iv into P and Q
+ for (i = 0; i < 8; i++)
+ P[i] = Key[i];
+ for (i = 8; i < 16; i++)
+ P[i] = iv[i - 8];
+ for (i = 16; i < 528; i++)
+ P[i] = f(P[i - 2], P[i - 7], P[i - 15], P[i - 16]) + i;
+ for (i = 0; i < 16; i++)
+ P[i] = P[i + 512];
+ for (i = 16; i < 1024; i++)
+ P[i] = f(P[i - 2], P[i - 7], P[i - 15], P[i - 16]) + 512 + i;
+ for (i = 0; i < 16; i++)
+ Q[i] = P[1024 - 16 + i];
+ for (i = 16; i < 32; i++)
+ Q[i] = f(Q[i - 2], Q[i - 7], Q[i - 15], Q[i - 16]) + 1520 + i;
+ for (i = 0; i < 16; i++)
+ Q[i] = Q[i + 16];
+ for (i = 16; i < 1024;i++)
+ Q[i] = f(Q[i - 2], Q[i - 7], Q[i - 15], Q[i - 16]) + 1536 + i;
+ //run the cipher 4096 steps without generating output
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < 10; j++)
+ feedback_1(P[j], P[j + 1], P[(j - 10) & 0x3ff], P[(j - 3) & 0x3ff]);
+ for (j = 10; j < 1023; j++)
+ feedback_1(P[j], P[j + 1], P[j - 10], P[j - 3]);
+ feedback_1(P[1023], P[0], P[1013], P[1020]);
+ for (j = 0; j < 10; j++)
+ feedback_2(Q[j], Q[j+1], Q[(j-10) & 0x3ff], Q[(j - 3) & 0x3ff]);
+ for (j = 10; j < 1023; j++)
+ feedback_2(Q[j], Q[j + 1], Q[j - 10], Q[j - 3]);
+ feedback_2(Q[1023], Q[0], Q[1013], Q[1020]);
+ }
+ //initialize counter2048, and tables X and Y
+ counter2048 = 0;
+ for (i = 0; i < 16; i++)
+ X[i] = P[1008 + i];
+ for (i = 0; i < 16; i++)
+ Y[i] = Q[1008 + i];
+}
+
+extern "C" __declspec(dllexport) const TCipherInfo* CipherInfo(void * Reserved)
+{
+ return &HC256::cCipherInfo;
+}
diff --git a/dbx_tree/encryption/HC256.h b/dbx_tree/encryption/HC256.h new file mode 100644 index 0000000..d4acb31 --- /dev/null +++ b/dbx_tree/encryption/HC256.h @@ -0,0 +1,66 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2008 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include "Cipher.h"
+
+class HC256 : public CCipher
+{
+private:
+ uint32_t counter2048;
+ uint32_t P[1024], Q[1024];
+ uint32_t X[16], Y[16];
+
+ uint32_t BackP[1024], BackQ[1024];
+ uint32_t BackX[16], BackY[16];
+
+ void EncryptBlock(uint32_t *Data);
+ void CreateTables(uint8_t* Key);
+
+ static const wchar_t* cName;
+ static const wchar_t* cDescription;
+ static const uint32_t cBlockSizeBytes = 64;
+ static const bool cIsStreamCipher = true;
+
+public:
+
+ const wchar_t * __cdecl Name();
+ const wchar_t * __cdecl Description();
+ const uint32_t __cdecl BlockSizeBytes();
+ const bool __cdecl IsStreamCipher();
+
+ static const TCipherInfo cCipherInfo;
+
+ HC256();
+ ~HC256();
+ static CCipher::TCipherInterface* __cdecl Create();
+
+ void __cdecl SetKey(void* Key, uint32_t KeyLength);
+ void __cdecl Encrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte);
+ void __cdecl Decrypt(void* Data, uint32_t Size, uint32_t Nonce, uint32_t StartByte);
+
+};
+
+const wchar_t* HC256::cName = L"HC-256";
+const wchar_t* HC256::cDescription = L"Streamcipher - 512bit step, very fast, Hongjun Wu 2005";
+const TCipherInfo HC256::cCipherInfo = {sizeof(TCipherInfo), 'HC25', cName, cDescription, &HC256::Create};
diff --git a/dbx_tree/encryption/HC256.vcproj b/dbx_tree/encryption/HC256.vcproj new file mode 100644 index 0000000..3d072f8 --- /dev/null +++ b/dbx_tree/encryption/HC256.vcproj @@ -0,0 +1,376 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="dbx_tree_HC256"
+ ProjectGUID="{541BE2B3-4320-47B8-AB64-C7F7ED0EFABA}"
+ RootNamespace="HC256"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins/encryption"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;HC256_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins/encryption"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="false"
+ WholeProgramOptimization="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;HC256_EXPORTS"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="2"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins/encryption"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;HC256_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins/encryption"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ OmitFramePointers="false"
+ WholeProgramOptimization="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;HC256_EXPORTS"
+ StringPooling="true"
+ ExceptionHandling="1"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableFunctionLevelLinking="false"
+ EnableEnhancedInstructionSet="2"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="0"
+ GenerateManifest="true"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ LinkTimeCodeGeneration="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ EmbedManifest="true"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\HC256.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\Cipher.h"
+ >
+ </File>
+ <File
+ RelativePath=".\HC256.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/dbx_tree/encryption/HC256.vcxproj b/dbx_tree/encryption/HC256.vcxproj new file mode 100644 index 0000000..b46e2b8 --- /dev/null +++ b/dbx_tree/encryption/HC256.vcxproj @@ -0,0 +1,476 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug Unicode|Win32">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Unicode|x64">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|x64">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>dbx_tree_HC256</ProjectName>
+ <ProjectGUID>{541BE2B3-4320-47B8-AB64-C7F7ED0EFABA}</ProjectGUID>
+ <RootNamespace>HC256</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(LocalAppData)\Microsoft\VisualStudio\10.0\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(LocalAppData)\Microsoft\VisualStudio\10.0\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</LinkIncremental>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Plugins/encryption/</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(SolutionDir)$(Configuration)/$(PlatformArchitecture)/Obj/$(ProjectName)/</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">false</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">false</LinkIncremental>
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectName)</TargetName>
+ <TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.dll</TargetExt>
+ <ExtensionsToDeleteOnClean Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</GenerateManifest>
+ <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateManifest>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;HC256_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;HC256_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HC256_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HC256_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;HC256_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;HC256_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <IntrinsicFunctions>false</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>false</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HC256_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;HC256_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAsManaged>false</CompileAsManaged>
+ <MultiProcessorCompilation>false</MultiProcessorCompilation>
+ <OmitFramePointers>false</OmitFramePointers>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <StringPooling>true</StringPooling>
+ <MinimalRebuild>true</MinimalRebuild>
+ <ExceptionHandling>Sync</ExceptionHandling>
+ <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <FloatingPointModel>Fast</FloatingPointModel>
+ <FloatingPointExceptions>false</FloatingPointExceptions>
+ <RuntimeTypeInfo>false</RuntimeTypeInfo>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <GenerateMapFile>false</GenerateMapFile>
+ <MapExports>false</MapExports>
+ <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClInclude Include="Cipher.h" />
+ <ClInclude Include="HC256.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="HC256.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file diff --git a/dbx_tree/encryption/HC256.vcxproj.filters b/dbx_tree/encryption/HC256.vcxproj.filters new file mode 100644 index 0000000..5d1e3ec --- /dev/null +++ b/dbx_tree/encryption/HC256.vcxproj.filters @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="Cipher.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="HC256.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="HC256.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project>
\ No newline at end of file diff --git a/dbx_tree/init.cpp b/dbx_tree/init.cpp new file mode 100644 index 0000000..f901e9d --- /dev/null +++ b/dbx_tree/init.cpp @@ -0,0 +1,83 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "Interface.h"
+
+HINSTANCE hInstance = NULL;
+
+static const DWORD gMinMirVer = 0x00080000;
+static const MUUID gInterfaces[] = {MIID_DATABASE, MIID_LAST};
+// {28F45248-8C9C-4bee-9307-7BCF3E12BF99}
+static const MUUID gGUID =
+{ 0x28f45248, 0x8c9c, 0x4bee, { 0x93, 0x07, 0x7b, 0xcf, 0x3e, 0x12, 0xbf, 0x99 } };
+
+
+static PLUGININFOEX gPluginInfoEx = {
+ sizeof(PLUGININFOEX),
+ gInternalNameLong,
+ gVersion,
+ gDescription " - build " __DATE__ " @ " __TIME__,
+ gAutor,
+ gAutorEmail,
+ gCopyright,
+ "http://www-user.tu-chemnitz.de/~kunmi/?dbx_tree&lang=en",
+ UNICODE_AWARE,
+ DEFMOD_DB,
+ gGUID
+};
+
+extern "C" __declspec(dllexport) DATABASELINK* DatabasePluginInfo(void * Reserved)
+{
+ return &gDBLink;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD MirandaVersion)
+{
+ if (MirandaVersion < gMinMirVer)
+ {
+ MessageBoxA( 0, "The dbx_tree plugin cannot be loaded. It requires Miranda IM 0.8.0.0 or later.", gInternalName, MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND | MB_TOPMOST );
+ return NULL;
+ }
+ return &gPluginInfoEx;
+}
+
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return gInterfaces;
+}
+
+extern "C" __declspec(dllexport) int Load(PLUGINLINK * Link)
+{
+ return 1;
+}
+
+extern "C" __declspec(dllexport) int Unload(void)
+{
+ return 0;
+}
+
+
+BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD dwReason, LPVOID reserved)
+{
+ hInstance = hInstDLL;
+ return TRUE;
+}
diff --git a/dbx_tree/intrinsics.h b/dbx_tree/intrinsics.h new file mode 100644 index 0000000..7cb8af1 --- /dev/null +++ b/dbx_tree/intrinsics.h @@ -0,0 +1,407 @@ +#pragma once
+
+#ifdef _MSC_VER
+
+#include <intrin.h>
+#include "stdint.h"
+
+#ifdef _M_X64
+
+inline uint32_t XCHG_32(uint32_t volatile & Dest, uint32_t Exchange)
+{
+ return (uint32_t)_InterlockedExchange((long volatile*)&(Dest), (long)(Exchange));
+}
+inline int32_t XCHG_32(int32_t volatile & Dest, int32_t Exchange)
+{
+ return (int32_t)_InterlockedExchange((long volatile*)&(Dest), (long)(Exchange));
+}
+
+inline uint64_t XCHG_64(uint64_t volatile & Dest, uint64_t Exchange)
+{
+ return (uint64_t)_InterlockedExchange64((__int64 volatile*)&Dest, (__int64)Exchange);
+}
+inline int64_t XCHG_64(int64_t volatile & Dest, int64_t Exchange)
+{
+ return (int64_t)_InterlockedExchange64((__int64 volatile*)&Dest, (__int64)Exchange);
+}
+
+template <typename T>
+inline T * XCHG_Ptr(T * volatile & Dest, T * Exchange)
+{
+ return (T*)_InterlockedExchangePointer((void*volatile*)&Dest, (void*)Exchange);
+}
+
+
+inline uint32_t CMPXCHG_32(uint32_t volatile & Dest, uint32_t Exchange, uint32_t Comperand)
+{
+ return (uint64_t)_InterlockedCompareExchange((long volatile*)&(Dest), (long)(Exchange), (long)Comperand);
+}
+inline int32_t CMPXCHG_32(int32_t volatile & Dest, int32_t Exchange, int32_t Comperand)
+{
+ return (int32_t)_InterlockedCompareExchange((long volatile*)&(Dest), (long)(Exchange), (long)Comperand);
+}
+
+inline uint64_t CMPXCHG_64(uint64_t volatile & Dest, uint64_t Exchange, uint64_t Comperand)
+{
+ return (uint64_t)_InterlockedCompareExchange64((__int64 volatile*)&Dest, (__int64)Exchange, (__int64)Comperand);
+}
+inline int64_t CMPXCHG_64(int64_t volatile & Dest, int64_t Exchange, int64_t Comperand)
+{
+ return (int64_t)_InterlockedCompareExchange64((__int64 volatile*)&Dest, (__int64)Exchange, (__int64)Comperand);
+}
+
+template <typename T>
+inline T * CMPXCHG_Ptr(T * volatile & Dest, T * Exchange, T * Comperand)
+{
+ return (T*)_InterlockedCompareExchangePointer((void*volatile*)&Dest, (void*)Exchange, (void*)Comperand);
+}
+
+inline uint32_t XADD_32(uint32_t volatile & Dest, int32_t Addend)
+{
+ return (uint32_t)_InterlockedExchangeAdd((long volatile*)&Dest, (long)Addend);
+}
+inline int32_t XADD_32(int32_t volatile & Dest, int32_t Addend)
+{
+ return (int32_t)_InterlockedExchangeAdd((long volatile*)&Dest, (long)Addend);
+}
+
+inline uint64_t XADD_64(uint64_t volatile & Dest, int64_t Addend)
+{
+ return (uint64_t)_InterlockedExchangeAdd64((__int64 volatile*)&Dest, (__int64)Addend);
+}
+inline int64_t XADD_64(int64_t volatile & Dest, int64_t Addend)
+{
+ return (int64_t)_InterlockedExchangeAdd64((__int64 volatile*)&Dest, (__int64)Addend);
+}
+
+inline uint32_t DEC_32(uint32_t volatile & Dest)
+{
+ return (uint32_t)_InterlockedDecrement((long volatile*)&Dest);
+}
+inline int32_t DEC_32(int32_t volatile & Dest)
+{
+ return (int32_t)_InterlockedDecrement((long volatile*)&Dest);
+}
+
+inline uint64_t DEC_64(uint64_t volatile & Dest)
+{
+ return (uint64_t)_InterlockedDecrement64((__int64 volatile*)&Dest);
+}
+inline int64_t DEC_64(int64_t volatile & Dest)
+{
+ return (int64_t)_InterlockedDecrement64((__int64 volatile*)&Dest);
+}
+
+inline uint32_t INC_32(uint32_t volatile & Dest)
+{
+ return (uint32_t)_InterlockedIncrement((long volatile*)&Dest);
+}
+inline int32_t INC_32(int32_t volatile & Dest)
+{
+ return (int32_t)_InterlockedIncrement((long volatile*)&Dest);
+}
+
+inline uint64_t INC_64(uint64_t volatile & Dest)
+{
+ return (uint64_t)_InterlockedIncrement64((__int64 volatile*)&Dest);
+}
+inline int64_t INC_64(int64_t volatile & Dest)
+{
+ return (int64_t)_InterlockedIncrement64((__int64 volatile*)&Dest);
+}
+
+inline bool BTS_32(uint32_t volatile & Dest, uint8_t Offset)
+{
+ return !!_interlockedbittestandset((long volatile*)&Dest, Offset);
+}
+inline bool BTS_32(int32_t volatile & Dest, uint8_t Offset)
+{
+ return !!_interlockedbittestandset((long volatile*)&Dest, Offset);
+}
+inline bool BTS_64(uint64_t volatile & Dest, uint8_t Offset)
+{
+ return !!_interlockedbittestandset64((__int64 volatile*)&Dest, Offset);
+}
+inline bool BTS_64(int64_t volatile & Dest, uint8_t Offset)
+{
+ return !!_interlockedbittestandset64((__int64 volatile*)&Dest, Offset);
+}
+
+
+inline bool BTR_32(uint32_t volatile & Dest, uint8_t Offset)
+{
+ return !!_interlockedbittestandreset((long volatile*)&Dest, Offset);
+}
+inline bool BTR_32(int32_t volatile & Dest, uint8_t Offset)
+{
+ return !!_interlockedbittestandreset((long volatile*)&Dest, Offset);
+}
+inline bool BTR_64(uint64_t volatile & Dest, uint8_t Offset)
+{
+ return !!_interlockedbittestandreset64((__int64 volatile*)&Dest, Offset);
+}
+inline bool BTR_64(int64_t volatile & Dest, uint8_t Offset)
+{
+ return !!_interlockedbittestandreset64((__int64 volatile*)&Dest, Offset);
+}
+
+
+inline uint32_t OR_32(uint32_t volatile & Value, uint32_t Operator)
+{
+ return (uint32_t)_InterlockedOr((long volatile*)&Value, (long)Operator);
+}
+
+inline int32_t OR_32(int32_t volatile & Value, int32_t Operator)
+{
+ return (int32_t)_InterlockedOr((long volatile*)&Value, (long)Operator);
+}
+
+inline uint64_t OR_64(uint64_t volatile & Value, uint64_t Operator)
+{
+ return (uint64_t)_InterlockedOr64((__int64 volatile*)&Value, (__int64)Operator);
+}
+
+inline int64_t OR_64(int64_t volatile & Value, int64_t Operator)
+{
+ return (int64_t)_InterlockedOr64((__int64 volatile*)&Value, (__int64)Operator);
+}
+
+inline uint32_t AND_32(uint32_t volatile & Value, uint32_t Operator)
+{
+ return (uint32_t)_InterlockedAnd((long volatile*)&Value, (long)Operator);
+}
+
+inline int32_t AND_32(int32_t volatile & Value, int32_t Operator)
+{
+ return (int32_t)_InterlockedAnd((long volatile*)&Value, (long)Operator);
+}
+
+inline uint64_t AND_64(uint64_t volatile & Value, uint64_t Operator)
+{
+ return (uint64_t)_InterlockedAnd64((__int64 volatile*)&Value, (__int64)Operator);
+}
+
+inline int64_t AND_64(int64_t volatile & Value, int64_t Operator)
+{
+ return (int64_t)_InterlockedAnd64((__int64 volatile*)&Value, (__int64)Operator);
+}
+
+
+inline uint32_t XOR_32(uint32_t volatile & Value, uint32_t Operator)
+{
+ return (uint32_t)_InterlockedXor((long volatile*)&Value, (long)Operator);
+}
+
+inline int32_t XOR_32(int32_t volatile & Value, int32_t Operator)
+{
+ return (int32_t)_InterlockedXor((long volatile*)&Value, (long)Operator);
+}
+inline uint64_t XOR_64(uint64_t volatile & Value, uint64_t Operator)
+{
+ return (uint64_t)_InterlockedXor64((__int64 volatile*)&Value, (__int64)Operator);
+}
+
+inline int64_t XOR_64(int64_t volatile & Value, int64_t Operator)
+{
+ return (int64_t)_InterlockedXor64((__int64 volatile*)&Value, (__int64)Operator);
+}
+
+
+inline uint32_t BSWAP_32(uint32_t Value)
+{
+ return _byteswap_ulong(Value);
+}
+
+inline uint32_t ROL_32(uint32_t Value, uint8_t Shift)
+{
+ return _rotl(Value, Shift);
+}
+
+inline uint32_t ROR_32(uint32_t Value, uint8_t Shift)
+{
+ return _rotr(Value, Shift);
+}
+
+#elif defined(_M_IX86)
+
+inline uint32_t XCHG_32(uint32_t volatile & Dest, uint32_t Exchange)
+{
+ return (uint32_t)_InterlockedExchange((long volatile*)&(Dest), (long)(Exchange));
+}
+inline int32_t XCHG_32(int32_t volatile & Dest, int32_t Exchange)
+{
+ return (int32_t)_InterlockedExchange((long volatile*)&(Dest), (long)(Exchange));
+}
+/*
+inline uint64_t XCHG_64(uint64_t volatile & Dest, uint64_t Exchange)
+{
+ return (uint64_t)_InterlockedExchange64((__int64 volatile*)&Dest, (__int64)Exchange);
+}
+inline int64_t XCHG_64(int64_t volatile & Dest, int64_t Exchange)
+{
+ return (int64_t)_InterlockedExchange64((__int64 volatile*)&Dest, (__int64)Exchange);
+}
+*/
+template <typename T>
+inline T * XCHG_Ptr(T * volatile & Dest, T * Exchange)
+{
+ return (T*)_InterlockedExchange((long volatile*)&Dest, (long)Exchange);
+}
+
+
+inline uint32_t CMPXCHG_32(uint32_t volatile & Dest, uint32_t Exchange, uint32_t Comperand)
+{
+ return (uint64_t)_InterlockedCompareExchange((long volatile*)&(Dest), (long)(Exchange), (long)Comperand);
+}
+inline int32_t CMPXCHG_32(int32_t volatile & Dest, int32_t Exchange, int32_t Comperand)
+{
+ return (int32_t)_InterlockedCompareExchange((long volatile*)&(Dest), (long)(Exchange), (long)Comperand);
+}
+
+inline uint64_t CMPXCHG_64(uint64_t volatile & Dest, uint64_t Exchange, uint64_t Comperand)
+{
+ return (uint64_t)_InterlockedCompareExchange64((__int64 volatile*)&Dest, (__int64)Exchange, (__int64)Comperand);
+}
+inline int64_t CMPXCHG_64(int64_t volatile & Dest, int64_t Exchange, int64_t Comperand)
+{
+ return (int64_t)_InterlockedCompareExchange64((__int64 volatile*)&Dest, (__int64)Exchange, (__int64)Comperand);
+}
+
+template <typename T>
+inline T * CMPXCHG_Ptr(T * volatile & Dest, T * Exchange, T * Comperand)
+{
+ return (T*)_InterlockedCompareExchange((long volatile *)&Dest, (long)Exchange, (long)Comperand);
+}
+
+inline uint32_t XADD_32(uint32_t volatile & Dest, int32_t Addend)
+{
+ return (uint32_t)_InterlockedExchangeAdd((long volatile*)&Dest, (long)Addend);
+}
+inline int32_t XADD_32(int32_t volatile & Dest, int32_t Addend)
+{
+ return (int32_t)_InterlockedExchangeAdd((long volatile*)&Dest, (long)Addend);
+}
+
+inline uint32_t DEC_32(uint32_t volatile & Dest)
+{
+ return (uint32_t)_InterlockedDecrement((long volatile*)&Dest);
+}
+inline int32_t DEC_32(int32_t volatile & Dest)
+{
+ return (int32_t)_InterlockedDecrement((long volatile*)&Dest);
+}
+
+inline uint32_t INC_32(uint32_t volatile & Dest)
+{
+ return (uint32_t)_InterlockedIncrement((long volatile*)&Dest);
+}
+inline int32_t INC_32(int32_t volatile & Dest)
+{
+ return (int32_t)_InterlockedIncrement((long volatile*)&Dest);
+}
+
+inline bool BTS_32(uint32_t volatile & Dest, uint8_t Offset)
+{
+ return !!_interlockedbittestandset((long volatile*)&Dest, Offset);
+}
+inline bool BTS_32(int32_t volatile & Dest, uint8_t Offset)
+{
+ return !!_interlockedbittestandset((long volatile*)&Dest, Offset);
+}
+inline bool BTS_64(uint64_t volatile & Dest, uint8_t Offset)
+{
+ if (Offset > 31)
+ return !!_interlockedbittestandset((long volatile*)&Dest, Offset);
+ else
+ return !!_interlockedbittestandset(((long volatile*)&Dest) + 1, Offset - 32);
+}
+inline bool BTS_64(int64_t volatile & Dest, uint8_t Offset)
+{
+ if (Offset > 31)
+ return !!_interlockedbittestandset((long volatile*)&Dest, Offset);
+ else
+ return !!_interlockedbittestandset(((long volatile*)&Dest) + 1, Offset - 32);
+}
+
+
+inline bool BTR_32(uint32_t volatile & Dest, uint8_t Offset)
+{
+ return !!_interlockedbittestandreset((long volatile*)&Dest, Offset);
+}
+inline bool BTR_32(int32_t volatile & Dest, uint8_t Offset)
+{
+ return !!_interlockedbittestandreset((long volatile*)&Dest, Offset);
+}
+inline bool BTR_64(uint64_t volatile & Dest, uint8_t Offset)
+{
+ if (Offset > 31)
+ return !!_interlockedbittestandreset((long volatile*)&Dest, Offset);
+ else
+ return !!_interlockedbittestandreset(((long volatile*)&Dest) + 1, Offset - 32);
+}
+inline bool BTR_64(int64_t volatile & Dest, uint8_t Offset)
+{
+ if (Offset > 31)
+ return !!_interlockedbittestandreset((long volatile*)&Dest, Offset);
+ else
+ return !!_interlockedbittestandreset(((long volatile*)&Dest) + 1, Offset - 32);
+}
+
+inline uint32_t OR_32(uint32_t volatile & Value, uint32_t Operator)
+{
+ return (uint32_t)_InterlockedOr((long volatile*)&Value, (long)Operator);
+}
+
+inline int32_t OR_32(int32_t volatile & Value, int32_t Operator)
+{
+ return (int32_t)_InterlockedOr((long volatile*)&Value, (long)Operator);
+}
+
+inline uint32_t AND_32(uint32_t volatile & Value, uint32_t Operator)
+{
+ return (uint32_t)_InterlockedAnd((long volatile*)&Value, (long)Operator);
+}
+
+inline int32_t AND_32(int32_t volatile & Value, int32_t Operator)
+{
+ return (int32_t)_InterlockedAnd((long volatile*)&Value, (long)Operator);
+}
+
+inline uint32_t XOR_32(uint32_t volatile & Value, uint32_t Operator)
+{
+ return (uint32_t)_InterlockedXor((long volatile*)&Value, (long)Operator);
+}
+
+inline int32_t XOR_32(int32_t volatile & Value, int32_t Operator)
+{
+ return (int32_t)_InterlockedXor((long volatile*)&Value, (long)Operator);
+}
+
+
+inline uint32_t BSWAP_32(uint32_t Value)
+{
+ return _byteswap_ulong(Value);
+}
+
+inline uint32_t ROL_32(uint32_t Value, uint8_t Shift)
+{
+ return _rotl(Value, Shift);
+}
+inline uint32_t ROR_32(uint32_t Value, uint8_t Shift)
+{
+ return _rotr(Value, Shift);
+}
+
+
+
+#else
+
+#error unsupported architecture
+
+#endif
+
+#else
+
+#error unsupported compiler
+
+#endif
diff --git a/dbx_tree/inttypes.h b/dbx_tree/inttypes.h new file mode 100644 index 0000000..2554277 --- /dev/null +++ b/dbx_tree/inttypes.h @@ -0,0 +1,305 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_INTTYPES_H_ // [
+#define _MSC_INTTYPES_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include "stdint.h"
+
+// 7.8 Format conversion of integer types
+
+typedef struct {
+ intmax_t quot;
+ intmax_t rem;
+} imaxdiv_t;
+
+// 7.8.1 Macros for format specifiers
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
+
+// The fprintf macros for signed integers are:
+#define PRId8 "d"
+#define PRIi8 "i"
+#define PRIdLEAST8 "d"
+#define PRIiLEAST8 "i"
+#define PRIdFAST8 "d"
+#define PRIiFAST8 "i"
+
+#define PRId16 "hd"
+#define PRIi16 "hi"
+#define PRIdLEAST16 "hd"
+#define PRIiLEAST16 "hi"
+#define PRIdFAST16 "hd"
+#define PRIiFAST16 "hi"
+
+#define PRId32 "I32d"
+#define PRIi32 "I32i"
+#define PRIdLEAST32 "I32d"
+#define PRIiLEAST32 "I32i"
+#define PRIdFAST32 "I32d"
+#define PRIiFAST32 "I32i"
+
+#define PRId64 "I64d"
+#define PRIi64 "I64i"
+#define PRIdLEAST64 "I64d"
+#define PRIiLEAST64 "I64i"
+#define PRIdFAST64 "I64d"
+#define PRIiFAST64 "I64i"
+
+#define PRIdMAX "I64d"
+#define PRIiMAX "I64i"
+
+#define PRIdPTR "Id"
+#define PRIiPTR "Ii"
+
+// The fprintf macros for unsigned integers are:
+#define PRIo8 "o"
+#define PRIu8 "u"
+#define PRIx8 "x"
+#define PRIX8 "X"
+#define PRIoLEAST8 "o"
+#define PRIuLEAST8 "u"
+#define PRIxLEAST8 "x"
+#define PRIXLEAST8 "X"
+#define PRIoFAST8 "o"
+#define PRIuFAST8 "u"
+#define PRIxFAST8 "x"
+#define PRIXFAST8 "X"
+
+#define PRIo16 "ho"
+#define PRIu16 "hu"
+#define PRIx16 "hx"
+#define PRIX16 "hX"
+#define PRIoLEAST16 "ho"
+#define PRIuLEAST16 "hu"
+#define PRIxLEAST16 "hx"
+#define PRIXLEAST16 "hX"
+#define PRIoFAST16 "ho"
+#define PRIuFAST16 "hu"
+#define PRIxFAST16 "hx"
+#define PRIXFAST16 "hX"
+
+#define PRIo32 "I32o"
+#define PRIu32 "I32u"
+#define PRIx32 "I32x"
+#define PRIX32 "I32X"
+#define PRIoLEAST32 "I32o"
+#define PRIuLEAST32 "I32u"
+#define PRIxLEAST32 "I32x"
+#define PRIXLEAST32 "I32X"
+#define PRIoFAST32 "I32o"
+#define PRIuFAST32 "I32u"
+#define PRIxFAST32 "I32x"
+#define PRIXFAST32 "I32X"
+
+#define PRIo64 "I64o"
+#define PRIu64 "I64u"
+#define PRIx64 "I64x"
+#define PRIX64 "I64X"
+#define PRIoLEAST64 "I64o"
+#define PRIuLEAST64 "I64u"
+#define PRIxLEAST64 "I64x"
+#define PRIXLEAST64 "I64X"
+#define PRIoFAST64 "I64o"
+#define PRIuFAST64 "I64u"
+#define PRIxFAST64 "I64x"
+#define PRIXFAST64 "I64X"
+
+#define PRIoMAX "I64o"
+#define PRIuMAX "I64u"
+#define PRIxMAX "I64x"
+#define PRIXMAX "I64X"
+
+#define PRIoPTR "Io"
+#define PRIuPTR "Iu"
+#define PRIxPTR "Ix"
+#define PRIXPTR "IX"
+
+// The fscanf macros for signed integers are:
+#define SCNd8 "d"
+#define SCNi8 "i"
+#define SCNdLEAST8 "d"
+#define SCNiLEAST8 "i"
+#define SCNdFAST8 "d"
+#define SCNiFAST8 "i"
+
+#define SCNd16 "hd"
+#define SCNi16 "hi"
+#define SCNdLEAST16 "hd"
+#define SCNiLEAST16 "hi"
+#define SCNdFAST16 "hd"
+#define SCNiFAST16 "hi"
+
+#define SCNd32 "ld"
+#define SCNi32 "li"
+#define SCNdLEAST32 "ld"
+#define SCNiLEAST32 "li"
+#define SCNdFAST32 "ld"
+#define SCNiFAST32 "li"
+
+#define SCNd64 "I64d"
+#define SCNi64 "I64i"
+#define SCNdLEAST64 "I64d"
+#define SCNiLEAST64 "I64i"
+#define SCNdFAST64 "I64d"
+#define SCNiFAST64 "I64i"
+
+#define SCNdMAX "I64d"
+#define SCNiMAX "I64i"
+
+#ifdef _WIN64 // [
+# define SCNdPTR "I64d"
+# define SCNiPTR "I64i"
+#else // _WIN64 ][
+# define SCNdPTR "ld"
+# define SCNiPTR "li"
+#endif // _WIN64 ]
+
+// The fscanf macros for unsigned integers are:
+#define SCNo8 "o"
+#define SCNu8 "u"
+#define SCNx8 "x"
+#define SCNX8 "X"
+#define SCNoLEAST8 "o"
+#define SCNuLEAST8 "u"
+#define SCNxLEAST8 "x"
+#define SCNXLEAST8 "X"
+#define SCNoFAST8 "o"
+#define SCNuFAST8 "u"
+#define SCNxFAST8 "x"
+#define SCNXFAST8 "X"
+
+#define SCNo16 "ho"
+#define SCNu16 "hu"
+#define SCNx16 "hx"
+#define SCNX16 "hX"
+#define SCNoLEAST16 "ho"
+#define SCNuLEAST16 "hu"
+#define SCNxLEAST16 "hx"
+#define SCNXLEAST16 "hX"
+#define SCNoFAST16 "ho"
+#define SCNuFAST16 "hu"
+#define SCNxFAST16 "hx"
+#define SCNXFAST16 "hX"
+
+#define SCNo32 "lo"
+#define SCNu32 "lu"
+#define SCNx32 "lx"
+#define SCNX32 "lX"
+#define SCNoLEAST32 "lo"
+#define SCNuLEAST32 "lu"
+#define SCNxLEAST32 "lx"
+#define SCNXLEAST32 "lX"
+#define SCNoFAST32 "lo"
+#define SCNuFAST32 "lu"
+#define SCNxFAST32 "lx"
+#define SCNXFAST32 "lX"
+
+#define SCNo64 "I64o"
+#define SCNu64 "I64u"
+#define SCNx64 "I64x"
+#define SCNX64 "I64X"
+#define SCNoLEAST64 "I64o"
+#define SCNuLEAST64 "I64u"
+#define SCNxLEAST64 "I64x"
+#define SCNXLEAST64 "I64X"
+#define SCNoFAST64 "I64o"
+#define SCNuFAST64 "I64u"
+#define SCNxFAST64 "I64x"
+#define SCNXFAST64 "I64X"
+
+#define SCNoMAX "I64o"
+#define SCNuMAX "I64u"
+#define SCNxMAX "I64x"
+#define SCNXMAX "I64X"
+
+#ifdef _WIN64 // [
+# define SCNoPTR "I64o"
+# define SCNuPTR "I64u"
+# define SCNxPTR "I64x"
+# define SCNXPTR "I64X"
+#else // _WIN64 ][
+# define SCNoPTR "lo"
+# define SCNuPTR "lu"
+# define SCNxPTR "lx"
+# define SCNXPTR "lX"
+#endif // _WIN64 ]
+
+#endif // __STDC_FORMAT_MACROS ]
+
+// 7.8.2 Functions for greatest-width integer types
+
+// 7.8.2.1 The imaxabs function
+#define imaxabs _abs64
+
+// 7.8.2.2 The imaxdiv function
+
+// This is modified version of div() function from Microsoft's div.c found
+// in %MSVC.NET%\crt\src\div.c
+#ifdef STATIC_IMAXDIV // [
+static
+#else // STATIC_IMAXDIV ][
+_inline
+#endif // STATIC_IMAXDIV ]
+imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
+{
+ imaxdiv_t result;
+
+ result.quot = numer / denom;
+ result.rem = numer % denom;
+
+ if (numer < 0 && result.rem > 0) {
+ // did division wrong; must fix up
+ ++result.quot;
+ result.rem -= denom;
+ }
+
+ return result;
+}
+
+// 7.8.2.3 The strtoimax and strtoumax functions
+#define strtoimax _strtoi64
+#define strtoumax _strtoui64
+
+// 7.8.2.4 The wcstoimax and wcstoumax functions
+#define wcstoimax _wcstoi64
+#define wcstoumax _wcstoui64
+
+
+#endif // _MSC_INTTYPES_H_ ]
diff --git a/dbx_tree/lockfree_hashmap.h b/dbx_tree/lockfree_hashmap.h new file mode 100644 index 0000000..7ec2df3 --- /dev/null +++ b/dbx_tree/lockfree_hashmap.h @@ -0,0 +1,749 @@ +#pragma once
+
+/*
+
+lockfree hash-multi_map based on Ori Shalev and Nir Shavit
+
+implementation
+Copyright 2009-2010 Michael "Protogenes" Kunz
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include <utility>
+#include "Hash.h"
+#include "intrinsics.h"
+
+#define NodePointer(listitem) ((PListItem)(((uintptr_t)(listitem)) & ~1))
+#define NodeMark(listitem) ((bool) (((uintptr_t)(listitem)) & 1))
+
+#define HashTablePtr(hashtable) ((PHashTable)(((uintptr_t)(hashtable)) & ~31))
+#define HashTableSize(hashtable) ((uint32_t)(((uintptr_t)(hashtable)) & 31))
+#define HashTable(tableptr, tablesize) ((void*)(((uintptr_t)(tableptr)) | ((tablesize) & 31)))
+
+#define GCSelection(Sentinel) ((Sentinel) >> 63)
+#define GCRefCount0(Sentinel) ((Sentinel) & 0x7fffffff)
+#define GCRefCount1(Sentinel) (((Sentinel) >> 32) & 0x7fffffff)
+#define GCMakeSentinel(Sel, RefCount0, RefCount1) ((((uint64_t)(Sel) & 1) << 63) | (((uint64_t)(RefCount1)) << 32) | ((uint64_t)(RefCount0)))
+
+#define GCRef0 (1)
+#define GCRef1 (0x0000000100000000)
+
+namespace lockfree
+{
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t) = Hash>
+ class hash_map
+ {
+ public:
+ typedef std::pair<TKey, TData> value_type;
+
+ private:
+ typedef struct TListItem
+ {
+ TListItem * volatile Next;
+ TListItem * volatile NextPurge;
+ volatile uint32_t Hash;
+ value_type Value;
+ } TListItem, *PListItem;
+
+ typedef struct THashTable
+ {
+ volatile PListItem Table[256];
+ } THashTable, *PHashTable;
+
+ typedef struct {
+ volatile uint64_t Sentinel;
+ volatile PListItem Purge0;
+ volatile PListItem Purge1;
+ } THashTableReferences;
+
+ THashTableReferences m_GarbageCollector;
+
+ volatile uint32_t m_Count;
+ void * volatile m_HashTableData;
+
+ PListItem listInsert(PListItem BucketNode, PListItem Node);
+ PListItem listDelete(PListItem BucketNode, uint32_t Hash, const TKey & Key);
+
+ PListItem listDelete(PListItem BucketNode, PListItem Node);
+
+ bool listFind(const PListItem BucketNode, const uint32_t Hash, const TKey & Key, const PListItem Node, volatile PListItem * & Prev, PListItem & Curr, PListItem & Next);
+
+ uint32_t getMask(uint32_t Size)
+ {
+ const uint32_t mask[32] = {
+ 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
+ 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
+ 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
+ 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
+ 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
+ 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
+ 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
+ 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
+ };
+ return mask[Size - 1];
+ };
+
+ PHashTable makeNewTable()
+ {
+ void * block = malloc(sizeof(THashTable) + 32 + sizeof(void*));
+ PHashTable result = reinterpret_cast<PHashTable>((reinterpret_cast<uintptr_t>(block) + 31 + sizeof(void*)) & (~(uintptr_t)31));
+ *(reinterpret_cast<void**>(result)-1) = block;
+ memset(reinterpret_cast<void*>(result), 0, sizeof(THashTable));
+ return reinterpret_cast<PHashTable>(result);
+ };
+
+ void destroyTable(PHashTable Table)
+ {
+ free(*(reinterpret_cast<void**>(Table) - 1));
+ };
+
+ PListItem makeDummyNode(uint32_t Hash)
+ {
+ PListItem result = new TListItem;
+ result->Hash = Hash;
+ result->Next = NULL;
+ result->NextPurge = NULL;
+ return result;
+ };
+
+ bool DisposeNode(volatile PListItem * Prev, PListItem Curr, PListItem Next);
+
+ PListItem initializeBucket(uint32_t Bucket, uint32_t Mask);
+
+ PListItem getBucket(uint32_t Bucket);
+
+ void setBucket(uint32_t Bucket, PListItem Dummy);
+
+ void DeleteTable(void * Table, uint32_t Size)
+ {
+ if (Size > 8)
+ {
+ for (uint32_t i = 0; i < 256; ++i)
+ {
+ if (HashTablePtr(Table)->Table[i])
+ DeleteTable(HashTablePtr(Table)->Table[i], Size - 8);
+ }
+ }
+
+ destroyTable(HashTablePtr(Table));
+ };
+
+
+ int addRef(int GC = -1);
+ void delRef(int GC);
+
+ public:
+
+
+ class iterator
+ {
+ protected:
+ friend class hash_map<TKey, TData, FHash>;
+ PListItem m_Item;
+ typename hash_map<TKey, TData, FHash> * m_Owner;
+ int m_GC;
+
+ iterator(hash_map<TKey, TData, FHash> * Owner, PListItem Item, int GC)
+ : m_Owner(Owner)
+ {
+ m_GC = GC;
+ m_Item = Item;
+
+ while (m_Item && (!(m_Item->Hash & 1) || NodeMark(m_Item->Next)))
+ m_Item = NodePointer(m_Item->Next);
+
+ if (!m_Item && (m_GC != -1))
+ {
+ m_Owner->delRef(m_GC);
+ m_GC = -1;
+ }
+
+ };
+ public:
+ iterator(const iterator & Other)
+ : m_Owner(Other.m_Owner),
+ m_Item(Other.m_Item)
+ {
+ m_GC = -1;
+ if (Other.m_GC != -1)
+ m_GC = m_Owner->addRef(Other.m_GC);
+ };
+ ~iterator()
+ {
+ if (m_GC != -1)
+ m_Owner->delRef(m_GC);
+ };
+
+ operator bool() const
+ {
+ return m_Item != NULL;
+ };
+ bool operator !() const
+ {
+ return m_Item == NULL;
+ };
+
+ value_type * operator ->()
+ {
+ return &m_Item->Value;
+ };
+ value_type & operator *()
+ {
+ return m_Item->Value;
+ };
+
+ bool operator ==(iterator& Other)
+ {
+ return m_Item->Value.first == Other.m_Item->Value.first;
+ };
+ bool operator < (iterator & Other)
+ {
+ return m_Item->Value.first < Other.m_Item->Value.first;
+ };
+ bool operator > (iterator & Other)
+ {
+ return m_Item->Value.first > Other.m_Item->Value.first;
+ };
+
+ iterator& operator =(const iterator& Other)
+ {
+ m_Owner = Other.m_Owner;
+ m_Item = Other.m_Item;
+
+ if (Other.m_GC != m_GC)
+ {
+ if (m_GC != -1)
+ m_Owner->delRef(m_GC);
+
+ m_GC = Other.m_GC;
+
+ if (Other.m_GC != -1)
+ m_GC = m_Owner->addRef(Other.m_GC);
+
+ }
+
+ return *this;
+ };
+
+ iterator& operator ++() //pre ++i
+ {
+ if (!m_Item)
+ return *this;
+
+ int gc = m_GC;
+ m_GC = m_Owner->addRef();
+ do
+ {
+ m_Item = NodePointer(m_Item->Next);
+ } while (m_Item && (!(m_Item->Hash & 1) || NodeMark(m_Item->Next)));
+
+ m_Owner->delRef(gc);
+ if (!m_Item)
+ {
+ m_Owner->delRef(m_GC);
+ m_GC = -1;
+ }
+ return *this;
+ };
+ iterator operator ++(int) //post i++
+ {
+ iterator bak(*this);
+ ++(*this);
+ return bak;
+ };
+ };
+
+ iterator begin()
+ {
+ return iterator(this, getBucket(0), addRef());
+ };
+
+ iterator end()
+ {
+ return iterator(this, NULL, -1);
+ };
+
+ hash_map();
+ ~hash_map();
+
+ std::pair<iterator, bool> insert(const value_type & Val);
+
+ iterator find(const TKey & Key);
+
+ iterator erase(const iterator & Where);
+
+ size_t erase(const TKey & Key);
+
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ int hash_map<TKey, TData, FHash>::addRef(int GC = -1)
+ {
+ uint64_t old;
+ uint64_t newvalue;
+ int res;
+ do {
+ old = m_GarbageCollector.Sentinel;
+ if (GC == 0) // this is safe because refcount will never fall to zero because of the original reference
+ {
+ newvalue = old + GCRef0;
+ res = 0;
+ } else if (GC == 1)
+ {
+ newvalue = old + GCRef1;
+ res = 1;
+ } else {
+ if (GCSelection(old))
+ {
+ newvalue = old + GCRef1;
+ res = 1;
+ } else {
+ newvalue = old + GCRef0;
+ res = 0;
+ }
+ }
+ }
+ while (CMPXCHG_64(m_GarbageCollector.Sentinel, newvalue, old) != old);
+
+ return res;
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ void hash_map<TKey, TData, FHash>::delRef(int GC)
+ {
+ uint64_t old;
+ uint64_t newvalue;
+ PListItem purge = NULL;
+ do {
+ old = m_GarbageCollector.Sentinel;
+ if (GC)
+ {
+ newvalue = old - GCRef1;
+
+ if (!GCSelection(old) && (GCRefCount1(old) == 1)) // the other gc is activated and we are the last one
+ {
+ if (!purge) // check if we had to loop...
+ purge = m_GarbageCollector.Purge1;
+
+ m_GarbageCollector.Purge1 = NULL;
+ }
+
+ } else {
+ newvalue = old - GCRef0;
+
+ if (GCSelection(old) && (GCRefCount0(old) == 1)) // the other gc is activated and we are the last one
+ {
+ if (!purge) // check if we had to loop...
+ purge = m_GarbageCollector.Purge0;
+
+ m_GarbageCollector.Purge0 = NULL;
+ }
+
+ }
+ } while (CMPXCHG_64(m_GarbageCollector.Sentinel, newvalue, old) != old);
+
+ purge = NodePointer(purge);
+ while (purge)
+ {
+ PListItem tmp = purge;
+ purge = purge->NextPurge;
+ delete tmp;
+ };
+ };
+
+
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ bool hash_map<TKey, TData, FHash>::DisposeNode(volatile PListItem * Prev, PListItem Curr, PListItem Next)
+ {
+ if (NodePointer(Curr) == CMPXCHG_Ptr(*Prev, NodePointer(Next), NodePointer(Curr)))
+ {
+ uint64_t old = m_GarbageCollector.Sentinel;
+ PListItem del = NodePointer(Curr);
+
+ if (GCSelection(old))
+ {
+ del->NextPurge = (PListItem)XCHG_Ptr(m_GarbageCollector.Purge1, del);
+
+ if (!GCRefCount0(old))
+ BTR_64(m_GarbageCollector.Sentinel, 63); // switch
+
+ } else {
+
+ del->NextPurge = (PListItem)XCHG_Ptr(m_GarbageCollector.Purge0, del);
+
+ if (!GCRefCount1(old))
+ BTS_64(m_GarbageCollector.Sentinel, 63); // switch
+
+ }
+ return true;
+ }
+
+ return false;
+ };
+
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_map<TKey, TData, FHash>::PListItem hash_map<TKey, TData, FHash>::listInsert(PListItem BucketNode, PListItem Node)
+ {
+ PListItem volatile * prev;
+ PListItem curr, next;
+ do
+ {
+ if (listFind(BucketNode, Node->Hash, Node->Value.first, NULL, prev, curr, next))
+ return NodePointer(curr);
+
+ Node->Next = NodePointer(curr);
+
+ } while (NodePointer(curr) != CMPXCHG_Ptr(*prev, Node, NodePointer(curr)));
+ return Node;
+ };
+
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_map<TKey, TData, FHash>::PListItem hash_map<TKey, TData, FHash>::listDelete(PListItem BucketNode, uint32_t Hash, const TKey & Key)
+ {
+ PListItem volatile * prev;
+ PListItem curr, next;
+
+ if (!listFind(BucketNode, Hash, Key, NULL, prev, curr, next))
+ return NodePointer(curr);
+
+ do
+ {
+ if (!listFind(BucketNode, Hash, Key, NULL, prev, curr, next))
+ return NodePointer(curr);
+
+ } while (NodePointer(next) != CMPXCHG_Ptr(curr->Next, (PListItem)((uintptr_t)next | 1), NodePointer(next)));
+
+ if (!DisposeNode(prev, curr, next))
+ listFind(BucketNode, Hash, Key, NULL, prev, curr, next); // cleanup
+
+ return NodePointer(curr);
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_map<TKey, TData, FHash>::PListItem hash_map<TKey, TData, FHash>::listDelete(PListItem BucketNode, PListItem Node)
+ {
+ PListItem volatile * prev;
+ PListItem curr, next;
+ if (!listFind(BucketNode, Node->Hash, Node->Value.first, Node, prev, curr, next))
+ return NodePointer(curr);
+
+ do
+ {
+ if (!listFind(BucketNode, Node->Hash, Node->Value.first, Node, prev, curr, next))
+ return NodePointer(curr);
+
+ } while (NodePointer(next) != CMPXCHG_Ptr(curr->Next, (PListItem)((uintptr_t)next | 1), NodePointer(next)));
+
+ if (!DisposeNode(prev, curr, next))
+ listFind(BucketNode, Node->Hash, Node->Value.first, Node, prev, curr, next); // cleanup
+
+ return NodePointer(curr);
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ bool hash_map<TKey, TData, FHash>::listFind(const PListItem BucketNode, const uint32_t Hash, const TKey & Key, const PListItem Node, volatile PListItem * & Prev, PListItem & Curr, PListItem & Next)
+ {
+tryagain:
+ Prev = &(BucketNode->Next);
+ Curr = *Prev;
+ do
+ {
+ if (NodePointer(Curr) == NULL)
+ return false;
+
+ Next = NodePointer(Curr)->Next;
+ uint32_t h = NodePointer(Curr)->Hash;
+
+ if (*Prev != NodePointer(Curr))
+ goto tryagain; // don't judge me for that
+ //return listFind(BucketNode, Hash, Key, Node, Prev, Curr, Next); // it's the same but stack overflow can happen
+
+ if (!NodeMark(Next))
+ {
+ if (Node)
+ {
+ if ((h > Hash) || (Node == NodePointer(Curr)))
+ return NodePointer(Curr) == Node;
+ }
+ else if ((h > Hash) || ((h == Hash) && !(NodePointer(Curr)->Value.first < Key)))
+ {
+ return (h == Hash) && (NodePointer(Curr)->Value.first == Key);
+ }
+
+ Prev = &(NodePointer(Curr)->Next);
+ } else {
+ if (!DisposeNode(Prev, Curr, Next))
+ goto tryagain; // don't judge me for that
+ //return listFind(BucketNode, Hash, Key, Node, Prev, Curr, Next); // it's the same but stack overflow can happen
+ }
+ Curr = Next;
+ } while (true);
+
+ };
+
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_map<TKey, TData, FHash>::PListItem hash_map<TKey, TData, FHash>::initializeBucket(uint32_t Bucket, uint32_t Mask)
+ {
+ uint32_t parent = Bucket & (Mask << 1);
+ PListItem parentnode = getBucket(parent);
+ if (parentnode == NULL)
+ parentnode = initializeBucket(parent, Mask << 1);
+
+ PListItem dummy = makeDummyNode(Bucket);
+ PListItem bucketnode = listInsert(parentnode, dummy);
+ if (bucketnode != dummy)
+ {
+ delete dummy;
+ dummy = bucketnode;
+ }
+ setBucket(Bucket, dummy);
+
+ return dummy;
+ }
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_map<TKey, TData, FHash>::PListItem hash_map<TKey, TData, FHash>::getBucket(uint32_t Bucket)
+ {
+ void * table;
+ uint32_t mask;
+
+ table = (void*)m_HashTableData;
+ mask = getMask(HashTableSize(table));
+
+ uint32_t levelshift = (32 - HashTableSize(table)) & ~7;
+
+ while (levelshift < 24)
+ {
+ table = HashTablePtr(table)->Table[((Bucket & mask) >> levelshift) & 0xff];
+ levelshift = levelshift + 8;
+ if (!HashTablePtr(table))
+ return NULL;
+ }
+ return HashTablePtr(table)->Table[(Bucket & mask) >> 24];
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ void hash_map<TKey, TData, FHash>::setBucket(uint32_t Bucket, PListItem Dummy)
+ {
+ void * table;
+ void *volatile * last;
+ uint32_t mask;
+
+ table = m_HashTableData;
+ mask = getMask(HashTableSize(table));
+
+ uint32_t levelshift = (32 - HashTableSize(table)) & ~7;
+
+ while (levelshift < 24)
+ {
+ last = (void*volatile*)&HashTablePtr(table)->Table[((Bucket & mask) >> levelshift) & 0xff];
+ table = *last;
+ levelshift = levelshift + 8;
+ if (!table)
+ {
+ PHashTable newtable = makeNewTable();
+ table = CMPXCHG_Ptr<void>(*last, newtable, NULL);
+ if (table)
+ {
+ destroyTable(newtable);
+ } else {
+ table = newtable;
+ }
+ }
+ }
+ HashTablePtr(table)->Table[(Bucket & mask) >> 24] = Dummy;
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ hash_map<TKey, TData, FHash>::hash_map()
+ {
+ m_Count = 0;
+
+ m_GarbageCollector.Sentinel = GCMakeSentinel(0,0,0);
+ m_GarbageCollector.Purge0 = NULL;
+ m_GarbageCollector.Purge1 = NULL;
+
+ m_HashTableData = HashTable(makeNewTable(), 1);
+ setBucket(0x00000000, makeDummyNode(0x00000000));
+ setBucket(0x80000000, makeDummyNode(0x80000000));
+ HashTablePtr(m_HashTableData)->Table[0]->Next = getBucket(0x80000000);
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ hash_map<TKey, TData, FHash>::~hash_map()
+ {
+ PListItem h = getBucket(0);
+ DeleteTable(HashTablePtr(m_HashTableData), HashTableSize(m_HashTableData));
+
+ while (h)
+ {
+ PListItem tmp = h;
+ h = NodePointer(h->Next);
+ delete tmp;
+ };
+
+ h = m_GarbageCollector.Purge0;
+ while (h)
+ {
+ PListItem tmp = h;
+ h = h->NextPurge;
+ delete tmp;
+ };
+
+ h = m_GarbageCollector.Purge1;
+ while (h)
+ {
+ PListItem tmp = h;
+ h = h->NextPurge;
+ delete tmp;
+ };
+
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename std::pair<typename hash_map<TKey, TData, FHash>::iterator, bool> hash_map<TKey, TData, FHash>::insert(const value_type & Val)
+ {
+ int gc = addRef();
+ PListItem node = new TListItem;
+ node->Value = Val;
+ node->Hash = FHash(&node->Value.first, sizeof(TKey)) | 1;
+ node->NextPurge = NULL;
+ node->Next = NULL;
+
+ void * tmp;
+ void * newdata;
+ tmp = (void*)m_HashTableData;
+
+ uint32_t mask = getMask(HashTableSize(tmp));
+
+ uint32_t bucket = node->Hash & mask;
+ PListItem bucketnode = getBucket(bucket);
+
+ if (bucketnode == NULL)
+ bucketnode = initializeBucket(bucket, mask);
+ PListItem retnode = listInsert(bucketnode, node);
+ if (retnode != node)
+ {
+ delete node;
+ return std::make_pair(iterator(this, retnode, gc), false);
+ }
+
+ if ((INC_32(m_Count) > ((uint32_t)1 << (HashTableSize(tmp) + 3))) && (HashTableSize(tmp) < 31) && (HashTableSize(tmp) == HashTableSize(m_HashTableData)))
+ {
+ newdata = HashTable(HashTablePtr(tmp), HashTableSize(tmp) + 1);
+
+ if ((HashTableSize(tmp) & 0x7) == 0)
+ {
+ newdata = HashTable(makeNewTable(), HashTableSize(tmp) + 1);
+ HashTablePtr(newdata)->Table[0] = (TListItem*)HashTablePtr(tmp);
+
+ if (tmp != CMPXCHG_Ptr(m_HashTableData, newdata, tmp))
+ destroyTable(HashTablePtr(newdata)); // someone else expanded the table.
+ } else {
+ CMPXCHG_Ptr(m_HashTableData, newdata, tmp);
+ }
+
+ }
+
+ return std::make_pair(iterator(this, node, gc), true);
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_map<TKey, TData, FHash>::iterator hash_map<TKey, TData, FHash>::find(const TKey & Key)
+ {
+ int gc = addRef();
+ uint32_t hash = FHash(&Key, sizeof(TKey)) | 1;
+ uint32_t mask = getMask(HashTableSize(m_HashTableData));
+ uint32_t bucket = hash & mask;
+ PListItem bucketnode = getBucket(bucket);
+ if (bucketnode == NULL)
+ bucketnode = initializeBucket(bucket, mask);
+
+ PListItem volatile * prev;
+ PListItem curr, next;
+ if (listFind(bucketnode, hash, Key, NULL, prev, curr, next))
+ return iterator(this, NodePointer(curr), gc);
+
+ return iterator(this, NULL, gc);
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_map<TKey, TData, FHash>::iterator hash_map<TKey, TData, FHash>::erase(const iterator & Where)
+ {
+ int gc = addRef();
+ uint32_t hash = Where.m_Item->Hash;
+ uint32_t mask = getMask(HashTableSize(m_HashTableData));
+ uint32_t bucket = hash & mask;
+ PListItem bucketnode = getBucket(bucket);
+
+ if (bucketnode == NULL)
+ bucketnode = initializeBucket(bucket, mask);
+
+ PListItem res = listDelete(bucketnode, Where.m_Item);
+ if (Where.m_Item == res)
+ {
+ DEC_32(m_Count);
+ return iterator(this, NodePointer(res->Next), gc);
+ }
+ return iterator(this, res, gc);
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ size_t hash_map<TKey, TData, FHash>::erase(const TKey & Key)
+ {
+ int gc = addRef();
+ uint32_t hash = FHash(&Key, sizeof(TKey)) | 1;
+ uint32_t mask = getMask(HashTableSize(m_HashTableData));
+ uint32_t bucket = hash & mask;
+ PListItem bucketnode = getBucket(bucket);
+
+ if (bucketnode == NULL)
+ bucketnode = initializeBucket(bucket, mask);
+
+ PListItem result = listDelete(bucketnode, hash, Key);
+ if (result && (result->Value.first == Key))
+ {
+ DEC_32(m_Count);
+ delRef(gc);
+ return 1;
+ }
+
+ delRef(gc);
+ return 0;
+ };
+}
+
+#undef NodePointer
+#undef NodeMark
+
+#undef HashTablePtr
+#undef HashTableSize
+#undef HashTable
+
+#undef GCSelection
+#undef GCRefCount0
+#undef GCRefCount1
+#undef GCMakeSentinel
+
diff --git a/dbx_tree/lockfree_hashmultimap.h b/dbx_tree/lockfree_hashmultimap.h new file mode 100644 index 0000000..79981e5 --- /dev/null +++ b/dbx_tree/lockfree_hashmultimap.h @@ -0,0 +1,750 @@ +#pragma once
+
+/*
+
+lockfree hash-multi_map based on Ori Shalev and Nir Shavit
+
+implementation
+Copyright 2009-2010 Michael "Protogenes" Kunz
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+#include <utility>
+#include "Hash.h"
+#include "intrinsics.h"
+
+#define NodePointer(listitem) ((PListItem)(((uintptr_t)(listitem)) & ~1))
+#define NodeMark(listitem) ((bool) (((uintptr_t)(listitem)) & 1))
+
+#define HashTablePtr(hashtable) ((PHashTable)(((uintptr_t)(hashtable)) & ~31))
+#define HashTableSize(hashtable) ((uint32_t)(((uintptr_t)(hashtable)) & 31))
+#define HashTable(tableptr, tablesize) ((void*)(((uintptr_t)(tableptr)) | ((tablesize) & 31)))
+
+#define GCSelection(Sentinel) ((Sentinel) >> 63)
+#define GCRefCount0(Sentinel) ((Sentinel) & 0x7fffffff)
+#define GCRefCount1(Sentinel) (((Sentinel) >> 32) & 0x7fffffff)
+#define GCMakeSentinel(Sel, RefCount0, RefCount1) ((((uint64_t)(Sel) & 1) << 63) | (((uint64_t)(RefCount1)) << 32) | ((uint64_t)(RefCount0)))
+
+#define GCRef0 (1)
+#define GCRef1 (0x0000000100000000)
+
+namespace lockfree
+{
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t) = Hash>
+ class hash_multimap
+ {
+ public:
+ typedef std::pair<TKey, TData> value_type;
+
+ private:
+ typedef struct TListItem
+ {
+ TListItem * volatile Next;
+ TListItem * volatile NextPurge;
+ volatile uint32_t Hash;
+ value_type Value;
+ } TListItem, *PListItem;
+
+ typedef struct THashTable
+ {
+ volatile PListItem Table[256];
+ } THashTable, *PHashTable;
+
+ typedef struct {
+ volatile uint64_t Sentinel;
+ volatile PListItem Purge0;
+ volatile PListItem Purge1;
+ } THashTableReferences;
+
+ THashTableReferences m_GarbageCollector;
+
+ volatile uint32_t m_Count;
+ void * volatile m_HashTableData;
+
+ PListItem listInsert(PListItem BucketNode, PListItem Node);
+ PListItem listDelete(PListItem BucketNode, uint32_t Hash, const TKey & Key);
+
+ PListItem listDelete(PListItem BucketNode, PListItem Node);
+
+ bool listFind(const PListItem BucketNode, const uint32_t Hash, const TKey & Key, const PListItem Node, volatile PListItem * & Prev, PListItem & Curr, PListItem & Next);
+
+ uint32_t getMask(uint32_t Size)
+ {
+ const uint32_t mask[32] = {
+ 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
+ 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
+ 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
+ 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
+ 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
+ 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
+ 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
+ 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
+ };
+ return mask[Size - 1];
+ };
+
+ PHashTable makeNewTable()
+ {
+ void * block = malloc(sizeof(THashTable) + 32 + sizeof(void*));
+ PHashTable result = reinterpret_cast<PHashTable>((reinterpret_cast<uintptr_t>(block) + 31 + sizeof(void*)) & (~(uintptr_t)31));
+ *(reinterpret_cast<void**>(result)-1) = block;
+ memset(reinterpret_cast<void*>(result), 0, sizeof(THashTable));
+ return reinterpret_cast<PHashTable>(result);
+ };
+
+ void destroyTable(PHashTable Table)
+ {
+ free(*(reinterpret_cast<void**>(Table) - 1));
+ };
+
+ PListItem makeDummyNode(uint32_t Hash)
+ {
+ PListItem result = new TListItem;
+ result->Hash = Hash;
+ result->Next = NULL;
+ result->NextPurge = NULL;
+ return result;
+ };
+
+ bool DisposeNode(volatile PListItem * Prev, PListItem Curr, PListItem Next);
+
+ PListItem initializeBucket(uint32_t Bucket, uint32_t Mask);
+
+ PListItem getBucket(uint32_t Bucket);
+
+ void setBucket(uint32_t Bucket, PListItem Dummy);
+
+ void DeleteTable(void * Table, uint32_t Size)
+ {
+ if (Size > 8)
+ {
+ for (uint32_t i = 0; i < 256; ++i)
+ {
+ if (HashTablePtr(Table)->Table[i])
+ DeleteTable(HashTablePtr(Table)->Table[i], Size - 8);
+ }
+ }
+
+ destroyTable(HashTablePtr(Table));
+ };
+
+
+ int addRef(int GC = -1);
+ void delRef(int GC);
+
+ public:
+
+
+ class iterator
+ {
+ protected:
+ friend class hash_multimap<TKey, TData, FHash>;
+ PListItem m_Item;
+ typename hash_multimap<TKey, TData, FHash> * m_Owner;
+ int m_GC;
+
+ iterator(hash_multimap<TKey, TData, FHash> * Owner, PListItem Item, int GC)
+ : m_Owner(Owner)
+ {
+ m_GC = GC;
+ m_Item = Item;
+
+ while (m_Item && (!(m_Item->Hash & 1) || NodeMark(m_Item->Next)))
+ m_Item = NodePointer(m_Item->Next);
+
+ if (!m_Item && (m_GC != -1))
+ {
+ m_Owner->delRef(m_GC);
+ m_GC = -1;
+ }
+
+ };
+ public:
+ iterator(const iterator & Other)
+ : m_Owner(Other.m_Owner),
+ m_Item(Other.m_Item)
+ {
+ m_GC = -1;
+ if (Other.m_GC != -1)
+ m_GC = m_Owner->addRef(Other.m_GC);
+ };
+ ~iterator()
+ {
+ if (m_GC != -1)
+ m_Owner->delRef(m_GC);
+ };
+
+ operator bool() const
+ {
+ return m_Item != NULL;
+ };
+ bool operator !() const
+ {
+ return m_Item == NULL;
+ };
+
+ value_type * operator ->()
+ {
+ return &m_Item->Value;
+ };
+ value_type & operator *()
+ {
+ return m_Item->Value;
+ };
+
+ bool operator ==(iterator& Other)
+ {
+ return m_Item->Value.first == Other.m_Item->Value.first;
+ };
+ bool operator < (iterator & Other)
+ {
+ return m_Item->Value.first < Other.m_Item->Value.first;
+ };
+ bool operator > (iterator & Other)
+ {
+ return m_Item->Value.first > Other.m_Item->Value.first;
+ };
+
+ iterator& operator =(const iterator& Other)
+ {
+ m_Owner = Other.m_Owner;
+ m_Item = Other.m_Item;
+
+ if (Other.m_GC != m_GC)
+ {
+ if (m_GC != -1)
+ m_Owner->delRef(m_GC);
+
+ m_GC = Other.m_GC;
+
+ if (Other.m_GC != -1)
+ m_GC = m_Owner->addRef(Other.m_GC);
+
+ }
+
+ return *this;
+ };
+
+ iterator& operator ++() //pre ++i
+ {
+ if (!m_Item)
+ return *this;
+
+ int gc = m_GC;
+ m_GC = m_Owner->addRef();
+ do
+ {
+ m_Item = NodePointer(m_Item->Next);
+ } while (m_Item && (!(m_Item->Hash & 1) || NodeMark(m_Item->Next)));
+
+ m_Owner->delRef(gc);
+ if (!m_Item)
+ {
+ m_Owner->delRef(m_GC);
+ m_GC = -1;
+ }
+ return *this;
+ };
+ iterator operator ++(int) //post i++
+ {
+ iterator bak(*this);
+ ++(*this);
+ return bak;
+ };
+ };
+
+ iterator begin()
+ {
+ return iterator(this, getBucket(0), addRef());
+ };
+
+ iterator end()
+ {
+ return iterator(this, NULL, -1);
+ };
+
+ hash_multimap();
+ ~hash_multimap();
+
+ std::pair<iterator, bool> insert(const value_type & Val);
+
+ iterator find(const TKey & Key);
+
+ iterator erase(const iterator & Where);
+
+ size_t erase(const TKey & Key);
+
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ int hash_multimap<TKey, TData, FHash>::addRef(int GC = -1)
+ {
+ uint64_t old;
+ uint64_t newvalue;
+ int res;
+ do {
+ old = m_GarbageCollector.Sentinel;
+ if (GC == 0) // this is safe because refcount will never fall to zero because of the original reference
+ {
+ newvalue = old + GCRef0;
+ res = 0;
+ } else if (GC == 1)
+ {
+ newvalue = old + GCRef1;
+ res = 1;
+ } else {
+ if (GCSelection(old))
+ {
+ newvalue = old + GCRef1;
+ res = 1;
+ } else {
+ newvalue = old + GCRef0;
+ res = 0;
+ }
+ }
+ }
+ while (CMPXCHG_64(m_GarbageCollector.Sentinel, newvalue, old) != old);
+
+ return res;
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ void hash_multimap<TKey, TData, FHash>::delRef(int GC)
+ {
+ uint64_t old;
+ uint64_t newvalue;
+ PListItem purge = NULL;
+ do {
+ old = m_GarbageCollector.Sentinel;
+ if (GC)
+ {
+ newvalue = old - GCRef1;
+
+ if (!GCSelection(old) && (GCRefCount1(old) == 1)) // the other gc is activated and we are the last one
+ {
+ if (!purge) // check if we had to loop...
+ purge = m_GarbageCollector.Purge1;
+
+ m_GarbageCollector.Purge1 = NULL;
+ }
+
+ } else {
+ newvalue = old - GCRef0;
+
+ if (GCSelection(old) && (GCRefCount0(old) == 1)) // the other gc is activated and we are the last one
+ {
+ if (!purge) // check if we had to loop...
+ purge = m_GarbageCollector.Purge0;
+
+ m_GarbageCollector.Purge0 = NULL;
+ }
+
+ }
+ } while (CMPXCHG_64(m_GarbageCollector.Sentinel, newvalue, old) != old);
+
+ purge = NodePointer(purge);
+ while (purge)
+ {
+ PListItem tmp = purge;
+ purge = purge->NextPurge;
+ delete tmp;
+ };
+ };
+
+
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ bool hash_multimap<TKey, TData, FHash>::DisposeNode(volatile PListItem * Prev, PListItem Curr, PListItem Next)
+ {
+ if (NodePointer(Curr) == CMPXCHG_Ptr(*Prev, NodePointer(Next), NodePointer(Curr)))
+ {
+ uint64_t old = m_GarbageCollector.Sentinel;
+ PListItem del = NodePointer(Curr);
+
+ if (GCSelection(old))
+ {
+ del->NextPurge = (PListItem)XCHG_Ptr(m_GarbageCollector.Purge1, del);
+
+ if (!GCRefCount0(old))
+ BTR_64(m_GarbageCollector.Sentinel, 63); // switch
+
+ } else {
+
+ del->NextPurge = (PListItem)XCHG_Ptr(m_GarbageCollector.Purge0, del);
+
+ if (!GCRefCount1(old))
+ BTS_64(m_GarbageCollector.Sentinel, 63); // switch
+
+ }
+ return true;
+ }
+
+ return false;
+ };
+
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_multimap<TKey, TData, FHash>::PListItem hash_multimap<TKey, TData, FHash>::listInsert(PListItem BucketNode, PListItem Node)
+ {
+ PListItem volatile * prev;
+ PListItem curr, next;
+ do
+ {
+ listFind(BucketNode, Node->Hash, Node->Value.first, NULL, prev, curr, next);
+
+ Node->Next = NodePointer(curr);
+
+ } while (NodePointer(curr) != CMPXCHG_Ptr(*prev, Node, NodePointer(curr)));
+ return Node;
+ };
+
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_multimap<TKey, TData, FHash>::PListItem hash_multimap<TKey, TData, FHash>::listDelete(PListItem BucketNode, uint32_t Hash, const TKey & Key)
+ {
+ PListItem volatile * prev;
+ PListItem curr, next;
+
+ if (!listFind(BucketNode, Hash, Key, NULL, prev, curr, next))
+ return NodePointer(curr);
+
+ do
+ {
+ if (!listFind(BucketNode, Hash, Key, NULL, prev, curr, next))
+ return NodePointer(curr);
+
+ } while (NodePointer(next) != CMPXCHG_Ptr(curr->Next, (PListItem)((uintptr_t)next | 1), NodePointer(next)));
+
+ if (!DisposeNode(prev, curr, next))
+ listFind(BucketNode, Hash, Key, NULL, prev, curr, next); // cleanup
+
+ return NodePointer(curr);
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_multimap<TKey, TData, FHash>::PListItem hash_multimap<TKey, TData, FHash>::listDelete(PListItem BucketNode, PListItem Node)
+ {
+ PListItem volatile * prev;
+ PListItem curr, next;
+ if (!listFind(BucketNode, Node->Hash, Node->Value.first, Node, prev, curr, next))
+ return NodePointer(curr);
+
+ do
+ {
+ if (!listFind(BucketNode, Node->Hash, Node->Value.first, Node, prev, curr, next))
+ return NodePointer(curr);
+
+ } while (NodePointer(next) != CMPXCHG_Ptr(curr->Next, (PListItem)((uintptr_t)next | 1), NodePointer(next)));
+
+ if (!DisposeNode(prev, curr, next))
+ listFind(BucketNode, Node->Hash, Node->Value.first, Node, prev, curr, next); // cleanup
+
+ return NodePointer(curr);
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ bool hash_multimap<TKey, TData, FHash>::listFind(const PListItem BucketNode, const uint32_t Hash, const TKey & Key, const PListItem Node, volatile PListItem * & Prev, PListItem & Curr, PListItem & Next)
+ {
+tryagain:
+ Prev = &(BucketNode->Next);
+ Curr = *Prev;
+ do
+ {
+ if (NodePointer(Curr) == NULL)
+ return false;
+
+ Next = NodePointer(Curr)->Next;
+ uint32_t h = NodePointer(Curr)->Hash;
+
+ if (*Prev != NodePointer(Curr))
+ goto tryagain; // don't judge me for that
+ //return listFind(BucketNode, Hash, Key, Node, Prev, Curr, Next); // it's the same but stack overflow can happen
+
+ if (!NodeMark(Next))
+ {
+ if (Node)
+ {
+ if ((h > Hash) || (Node == NodePointer(Curr)))
+ return NodePointer(Curr) == Node;
+ }
+ else if ((h > Hash) || ((h == Hash) && !(NodePointer(Curr)->Value.first < Key)))
+ {
+ return (h == Hash) && (NodePointer(Curr)->Value.first == Key);
+ }
+
+ Prev = &(NodePointer(Curr)->Next);
+ } else {
+ if (!DisposeNode(Prev, Curr, Next))
+ goto tryagain; // don't judge me for that
+ //return listFind(BucketNode, Hash, Key, Node, Prev, Curr, Next); // it's the same but stack overflow can happen
+ }
+ Curr = Next;
+ } while (true);
+
+ };
+
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_multimap<TKey, TData, FHash>::PListItem hash_multimap<TKey, TData, FHash>::initializeBucket(uint32_t Bucket, uint32_t Mask)
+ {
+ uint32_t parent = Bucket & (Mask << 1);
+ PListItem parentnode = getBucket(parent);
+ if (parentnode == NULL)
+ parentnode = initializeBucket(parent, Mask << 1);
+
+ PListItem dummy = makeDummyNode(Bucket);
+ PListItem bucketnode = listInsert(parentnode, dummy);
+ if (bucketnode != dummy)
+ {
+ delete dummy;
+ dummy = bucketnode;
+ }
+ setBucket(Bucket, dummy);
+
+ return dummy;
+ }
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_multimap<TKey, TData, FHash>::PListItem hash_multimap<TKey, TData, FHash>::getBucket(uint32_t Bucket)
+ {
+ void * table;
+ uint32_t mask;
+
+ table = (void*)m_HashTableData;
+ mask = getMask(HashTableSize(table));
+
+ uint32_t levelshift = (32 - HashTableSize(table)) & ~7;
+
+ while (levelshift < 24)
+ {
+ table = HashTablePtr(table)->Table[((Bucket & mask) >> levelshift) & 0xff];
+ levelshift = levelshift + 8;
+ if (!HashTablePtr(table))
+ return NULL;
+ }
+ return HashTablePtr(table)->Table[(Bucket & mask) >> 24];
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ void hash_multimap<TKey, TData, FHash>::setBucket(uint32_t Bucket, PListItem Dummy)
+ {
+ void * table;
+ void *volatile * last;
+ uint32_t mask;
+
+ table = m_HashTableData;
+ mask = getMask(HashTableSize(table));
+
+ uint32_t levelshift = (32 - HashTableSize(table)) & ~7;
+
+ while (levelshift < 24)
+ {
+ last = (void*volatile*)&HashTablePtr(table)->Table[((Bucket & mask) >> levelshift) & 0xff];
+ table = *last;
+ levelshift = levelshift + 8;
+ if (!table)
+ {
+ PHashTable newtable = makeNewTable();
+ table = CMPXCHG_Ptr<void>(*last, newtable, NULL);
+ if (table)
+ {
+ destroyTable(newtable);
+ } else {
+ table = newtable;
+ }
+ }
+ }
+ HashTablePtr(table)->Table[(Bucket & mask) >> 24] = Dummy;
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ hash_multimap<TKey, TData, FHash>::hash_multimap()
+ {
+ m_Count = 0;
+
+ m_GarbageCollector.Sentinel = GCMakeSentinel(0,0,0);
+ m_GarbageCollector.Purge0 = NULL;
+ m_GarbageCollector.Purge1 = NULL;
+
+ m_HashTableData = HashTable(makeNewTable(), 1);
+ setBucket(0x00000000, makeDummyNode(0x00000000));
+ setBucket(0x80000000, makeDummyNode(0x80000000));
+ HashTablePtr(m_HashTableData)->Table[0]->Next = getBucket(0x80000000);
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ hash_multimap<TKey, TData, FHash>::~hash_multimap()
+ {
+ PListItem h = getBucket(0);
+ DeleteTable(HashTablePtr(m_HashTableData), HashTableSize(m_HashTableData));
+
+ while (h)
+ {
+ PListItem tmp = h;
+ h = NodePointer(h->Next);
+ delete tmp;
+ };
+
+ h = m_GarbageCollector.Purge0;
+ while (h)
+ {
+ PListItem tmp = h;
+ h = h->NextPurge;
+ delete tmp;
+ };
+
+ h = m_GarbageCollector.Purge1;
+ while (h)
+ {
+ PListItem tmp = h;
+ h = h->NextPurge;
+ delete tmp;
+ };
+
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename std::pair<typename hash_multimap<TKey, TData, FHash>::iterator, bool> hash_multimap<TKey, TData, FHash>::insert(const value_type & Val)
+ {
+ int gc = addRef();
+ PListItem node = new TListItem;
+ node->Value = Val;
+ node->Hash = FHash(&node->Value.first, sizeof(TKey)) | 1;
+ node->NextPurge = NULL;
+ node->Next = NULL;
+
+ void * tmp;
+ void * newdata;
+ tmp = (void*)m_HashTableData;
+
+ uint32_t mask = getMask(HashTableSize(tmp));
+
+ uint32_t bucket = node->Hash & mask;
+ PListItem bucketnode = getBucket(bucket);
+
+ if (bucketnode == NULL)
+ bucketnode = initializeBucket(bucket, mask);
+ PListItem retnode = listInsert(bucketnode, node);
+ if (retnode != node)
+ {
+ delete node;
+ return std::make_pair(iterator(this, retnode, gc), false);
+ }
+
+ if ((INC_32(m_Count) > ((uint32_t)1 << (HashTableSize(tmp) + 3))) && (HashTableSize(tmp) < 31) && (HashTableSize(tmp) == HashTableSize(m_HashTableData)))
+ {
+ newdata = HashTable(HashTablePtr(tmp), HashTableSize(tmp) + 1);
+
+ if ((HashTableSize(tmp) & 0x7) == 0)
+ {
+ newdata = HashTable(makeNewTable(), HashTableSize(tmp) + 1);
+ HashTablePtr(newdata)->Table[0] = (TListItem*)HashTablePtr(tmp);
+
+ if (tmp != CMPXCHG_Ptr(m_HashTableData, newdata, tmp))
+ destroyTable(HashTablePtr(newdata)); // someone else expanded the table.
+ } else {
+ CMPXCHG_Ptr(m_HashTableData, newdata, tmp);
+ }
+
+ }
+
+ return std::make_pair(iterator(this, node, gc), true);
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_multimap<TKey, TData, FHash>::iterator hash_multimap<TKey, TData, FHash>::find(const TKey & Key)
+ {
+ int gc = addRef();
+ uint32_t hash = FHash(&Key, sizeof(TKey)) | 1;
+ uint32_t mask = getMask(HashTableSize(m_HashTableData));
+ uint32_t bucket = hash & mask;
+ PListItem bucketnode = getBucket(bucket);
+ if (bucketnode == NULL)
+ bucketnode = initializeBucket(bucket, mask);
+
+ PListItem volatile * prev;
+ PListItem curr, next;
+ if (listFind(bucketnode, hash, Key, NULL, prev, curr, next))
+ return iterator(this, NodePointer(curr), gc);
+
+ return iterator(this, NULL, gc);
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ typename hash_multimap<TKey, TData, FHash>::iterator hash_multimap<TKey, TData, FHash>::erase(const iterator & Where)
+ {
+ int gc = addRef();
+ uint32_t hash = Where.m_Item->Hash;
+ uint32_t mask = getMask(HashTableSize(m_HashTableData));
+ uint32_t bucket = hash & mask;
+ PListItem bucketnode = getBucket(bucket);
+
+ if (bucketnode == NULL)
+ bucketnode = initializeBucket(bucket, mask);
+
+ PListItem res = listDelete(bucketnode, Where.m_Item);
+ if (Where.m_Item == res)
+ {
+ DEC_32(m_Count);
+ return iterator(this, NodePointer(res->Next), gc);
+ }
+ return iterator(this, res, gc);
+ };
+
+ template <typename TKey, typename TData, uint32_t (*FHash)(const void *, uint32_t)>
+ size_t hash_multimap<TKey, TData, FHash>::erase(const TKey & Key)
+ {
+ int gc = addRef();
+ int count = 0;
+ uint32_t hash = FHash(&Key, sizeof(TKey)) | 1;
+ uint32_t mask = getMask(HashTableSize(m_HashTableData));
+ uint32_t bucket = hash & mask;
+ PListItem bucketnode = getBucket(bucket);
+
+ if (bucketnode == NULL)
+ bucketnode = initializeBucket(bucket, mask);
+
+ PListItem volatile * prev;
+ PListItem curr, next;
+ while (listFind(bucketnode, hash, Key, NULL, prev, curr, next))
+ {
+ if (curr == listDelete(bucketnode, curr))
+ count++;
+ }
+
+ XADD_32(m_Count, -count);
+ delRef(gc);
+ return count;
+ };
+}
+
+#undef NodePointer
+#undef NodeMark
+
+#undef HashTablePtr
+#undef HashTableSize
+#undef HashTable
+
+#undef GCSelection
+#undef GCRefCount0
+#undef GCRefCount1
+#undef GCMakeSentinel
+
diff --git a/dbx_tree/m_dbx_tree.h b/dbx_tree/m_dbx_tree.h new file mode 100644 index 0000000..932b1bc --- /dev/null +++ b/dbx_tree/m_dbx_tree.h @@ -0,0 +1,688 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef M_DBX_TREE_H__
+
+#define M_DBX_TREE_H__ 1
+
+#ifndef _MSC_VER
+#include <stdint.h>
+#else
+#include "stdint.h"
+#endif
+#pragma pack(push, 8)
+
+
+/**
+ \brief general return value if invalid param or invalid combination of params specified
+**/
+static const unsigned int DBT_INVALIDPARAM = 0xFFFFFFFF;
+
+
+///////////////////////////////////////////////////////////
+// Entities
+///////////////////////////////////////////////////////////
+
+/**
+ \brief A handle to a Entity
+**/
+typedef uint32_t TDBTEntityHandle;
+
+static const uint32_t DBT_NF_IsRoot = 0x00000001; /// Entity is the Root
+static const uint32_t DBT_NF_IsGroup = 0x00000002; /// Entity is a group
+static const uint32_t DBT_NF_IsAccount = 0x00000004; /// Entity is an account
+
+static const uint32_t DBT_NF_HasChildren = 0x00010000; /// Entity has Children (for Groups and Metacontacts)
+static const uint32_t DBT_NF_HasVirtuals = 0x00020000; /// Entity has at least one Virtual duplicate
+static const uint32_t DBT_NF_IsVirtual = 0x00040000; /// Entity is a Virtual duplicate
+
+static const uint32_t DBT_NFM_SpecialEntity = DBT_NF_IsRoot | DBT_NF_IsGroup | DBT_NF_IsAccount | DBT_NF_IsVirtual;
+
+///////////////////////////////////////////////////////////
+// Entities
+///////////////////////////////////////////////////////////
+
+/**
+ \brief
+ \param wParam = 0
+ \param lParam = 0
+
+ \return Handle to root Entity
+**/
+#define MS_DBT_ENTITY_GETROOT "DBT/Entity/GetRoot"
+
+
+/**
+ \brief
+ \param wParam = hEntity
+ \param lParam = 0
+
+ \return ChildCount of specified Entity
+**/
+#define MS_DBT_ENTITY_CHILDCOUNT "DBT/Entity/ChildCount"
+
+
+/**
+ \brief
+ \param wParam = hEntity
+ \param lParam = 0
+
+ \return Parent hEntity of specified Entity
+**/
+#define MS_DBT_ENTITY_GETPARENT "DBT/Entity/GetParent"
+
+
+/**
+ \brief
+ \param wParam = hEntity
+ \param lParam = hNewEntity
+
+ \return 0 on success
+**/
+#define MS_DBT_ENTITY_MOVE "DBT/Entity/Move"
+
+/**
+ \brief
+ \param wParam = hEntity
+ \param lParam = hNewParent
+**/
+#define ME_DBT_ENTITY_MOVING "DBT/Entity/Moving"
+/**
+ \brief
+ \param wParam = hEntity
+ \param lParam = hOldParent
+**/
+#define ME_DBT_ENTITY_MOVED "DBT/Entity/Moved"
+
+/**
+ \brief Read the flags of an Entity
+ \param wParam = hEntity
+ \param lParam = 0
+
+ \return Flags
+**/
+#define MS_DBT_ENTITY_GETFLAGS "DBT/Entity/GetFlags"
+
+
+
+static const uint32_t DBT_NIFO_OSC_AC = 0x00000001; /// onStartEntity - AddChildren
+static const uint32_t DBT_NIFO_OSC_AP = 0x00000002; /// onStartEntity - AddParent
+static const uint32_t DBT_NIFO_OSC_AO = 0x00000004; /// onStartEntity - AddOriginal (only if Entity is virtual)
+static const uint32_t DBT_NIFO_OSC_AOC = 0x00000008 | DBT_NIFO_OSC_AO; /// onStartEntity - AddOriginalChildren (only if Entity is virtual)
+static const uint32_t DBT_NIFO_OSC_AOP = 0x00000010 | DBT_NIFO_OSC_AO; /// onStartEntity - AddOriginalParent (only if Entity is virtual)
+static const uint32_t DBT_NIFO_OSC_USEACCOUNT = 0x00000080; /// onStartEntity - use Account as fallback, only for settings
+
+static const uint32_t DBT_NIFO_OC_AC = 0x00000001 <<8; /// onChildEntity - AddChildren
+//static const uint32_t DBT_LC_OC_AP = 0x00000002 <<8; /// invalid for children
+static const uint32_t DBT_NIFO_OC_AO = 0x00000004 <<8; /// onChildEntity - AddOriginal (only if Entity is virtual)
+static const uint32_t DBT_NIFO_OC_AOC = 0x00000008 <<8 | DBT_NIFO_OC_AO; /// onChildEntity - AddOriginalChildren (only if Entity is virtual)
+static const uint32_t DBT_NIFO_OC_AOP = 0x00000010 <<8 | DBT_NIFO_OC_AO; /// onChildEntity - AddOriginalParent (only if Entity is virtual)
+static const uint32_t DBT_NIFO_OC_USEACCOUNT = 0x00000080 <<8; /// onStartEntity - use Account as fallback, only for settings
+
+static const uint32_t DBT_NIFO_OP_AC = 0x00000001 <<16; /// onParentEntity - AddChildren
+static const uint32_t DBT_NIFO_OP_AP = 0x00000002 <<16; /// onParentEntity - AddParent
+static const uint32_t DBT_NIFO_OP_AO = 0x00000004 <<16; /// onParentEntity - AddOriginal (only if Entity is virtual)
+static const uint32_t DBT_NIFO_OP_AOC = 0x00000008 <<16 | DBT_NIFO_OP_AO; /// onParentEntity - AddOriginalChildren (only if Entity is virtual)
+static const uint32_t DBT_NIFO_OP_AOP = 0x00000010 <<16 | DBT_NIFO_OP_AO; /// onParentEntity - AddOriginalParent (only if Entity is virtual)
+static const uint32_t DBT_NIFO_OP_USEACCOUNT = 0x00000080 <<16; /// onStartEntity - use Account as fallback, only for settings
+
+static const uint32_t DBT_NIFO_GF_DEPTHFIRST = 0x01000000; /// general flags - depth first iteration instead of breath first
+static const uint32_t DBT_NIFO_GF_USEROOT = 0x02000000; /// general flags - use root as fallback, only for settings
+static const uint32_t DBT_NIFO_GF_VL1 = 0x10000000; /// general flags - limit virtual lookup depth to 1
+static const uint32_t DBT_NIFO_GF_VL2 = 0x20000000; /// general flags - limit virtual lookup depth to 2
+static const uint32_t DBT_NIFO_GF_VL3 = 0x30000000; /// general flags - limit virtual lookup depth to 3
+static const uint32_t DBT_NIFO_GF_VL4 = 0x40000000; /// general flags - limit virtual lookup depth to 4
+
+/**
+ \brief Entityfilter options for Entity iteration
+**/
+typedef
+ struct TDBTEntityIterFilter
+ {
+ uint32_t cbSize; /// size of the structur in bytes
+ uint32_t Options; /// Options for iteration: DB_EIFO_*
+ uint32_t fHasFlags; /// flags an Entity must have to be iterated
+ uint32_t fDontHasFlags; /// flags an Entity have not to have to be iterated
+ } TDBTEntityIterFilter, *PDBTEntityIterFilter;
+
+/**
+ \brief Handle of an Entity-Iteration
+**/
+typedef uintptr_t TDBTEntityIterationHandle;
+/**
+ \brief initialize an iteration of Entities
+ \param wParam = PDBTEntityIterFilter, NULL to iterate all Entities (breadthfirst, all but root)
+ \param lParam = TDBTEntityHandle Entity, where iteration starts
+
+ \return EnumID
+**/
+#define MS_DBT_ENTITY_ITER_INIT "DBT/Entity/Iter/Init"
+
+
+/**
+ \brief get the next Entity
+ \param wParam = EnumID returned by MS_DBT_ENTITY_ITER_INIT
+ \param lParam = 0
+
+ \return hEntity, 0 at the end
+**/
+#define MS_DBT_ENTITY_ITER_NEXT "DBT/Entity/Iter/Next"
+
+/**
+ \brief closes an iteration and frees its ressourcs
+ \param wParam = IterationHandle returned by MS_DBT_ENTITY_ITER_INIT
+ \param lParam = 0
+
+ \return 0 on success
+**/
+#define MS_DBT_ENTITY_ITER_CLOSE "DBT/Entity/Iter/Close"
+
+/**
+ \brief Deletes an Entity.
+
+ All children will be moved to its parent.
+ If the Entity has virtual copies, history and settings will be transfered to the first duplicate.
+
+ \param wParam = hEntity
+ \param lParam = 0
+
+ \return 0 on success
+**/
+#define MS_DBT_ENTITY_DELETE "DBT/Entity/Delete"
+
+
+typedef struct TDBTEntity
+{
+ uint32_t bcSize;
+ TDBTEntityHandle hParentEntity;
+ uint32_t fFlags; /// Flags DBT_NF_
+ TDBTEntityHandle hAccountEntity; /// Needed for normal Entities, reference to AccountEntity for the created one
+} TDBTEntity, *PDBTEntity;
+
+/**
+ \brief Creates a new Entity.
+ \param wParam = PDBTEntity
+ \param lParam = 0
+
+ \return hEntity on success, 0 otherwise
+**/
+#define MS_DBT_ENTITY_CREATE "DBT/Entity/Create"
+
+
+/**
+ \brief returns the account entity handle specified during creation
+ \param wParam = TDBTEntityHandle
+ \param lParam = 0
+
+ \return hEntity on success, 0 otherwise
+**/
+#define MS_DBT_ENTITY_GETACCOUNT "DBT/Entity/GetAccount"
+
+
+///////////////////////////////////////////////////////////
+// Virtual Entities
+///////////////////////////////////////////////////////////
+
+/**
+ \brief Creates a virtual duplicate of an Entity
+ \param wParam = hEntity to duplicate, couldn't be a group (DBT_NF_IsGroup set to 0)
+ \param lParam = hParentEntity to place duplicate
+
+ \return hEntity of created duplicate
+**/
+#define MS_DBT_VIRTUALENTITY_CREATE "DBT/VirtualEntity/Create"
+
+/**
+ \brief Retrieves the original Entity, which this is a duplicate of
+ \param wParam = hEntity of virtual Entity
+ \param lParam = 0
+
+ \return hEntity of original Entity
+**/
+#define MS_DBT_VIRTUALENTITY_GETPARENT "DBT/VirtualEntity/GetParent"
+
+/**
+ \brief Retrieves the first virtual duplicate of an Entity (if any)
+ \param wParam = hEntity with virtual copies
+ \param lParam
+
+ \return hEntity of first virtual duplicate
+**/
+#define MS_DBT_VIRTUALENTITY_GETFIRST "DBT/VirtualEntity/GetFirst"
+
+/**
+ \brief Retrieves the following duplicate
+ \param wParam = hVirtualEntity of virtual Entity
+ \param lParam = 0
+
+ \return hEntity of next duplicate, 0 if hVirtualEntity was the last duplicate
+**/
+#define MS_DBT_VIRTUALENTITY_GETNEXT "DBT/VirtualEntity/GetNext"
+
+
+///////////////////////////////////////////////////////////
+// Settings
+///////////////////////////////////////////////////////////
+
+/**
+ \brief Handle of a Setting
+**/
+typedef uint32_t TDBTSettingHandle;
+
+
+static const uint16_t DBT_ST_BYTE = 0x01;
+static const uint16_t DBT_ST_WORD = 0x02;
+static const uint16_t DBT_ST_DWORD = 0x03;
+static const uint16_t DBT_ST_QWORD = 0x04;
+
+static const uint16_t DBT_ST_CHAR = 0x11;
+static const uint16_t DBT_ST_SHORT = 0x12;
+static const uint16_t DBT_ST_INT = 0x13;
+static const uint16_t DBT_ST_INT64 = 0x14;
+
+static const uint16_t DBT_ST_BOOL = 0x20;
+static const uint16_t DBT_ST_FLOAT = 0x21;
+static const uint16_t DBT_ST_DOUBLE = 0x22;
+
+static const uint16_t DBT_ST_ANSI = 0xff;
+static const uint16_t DBT_ST_BLOB = 0xfe;
+static const uint16_t DBT_ST_UTF8 = 0xfd;
+static const uint16_t DBT_ST_WCHAR = 0xfc;
+
+#if (defined(_UNICODE) || defined(UNICODE))
+ static const uint16_t DBT_ST_TCHAR = DBT_ST_WCHAR;
+#else
+ static const uint16_t DBT_ST_TCHAR = DBT_ST_ANSI;
+#endif
+
+static const uint16_t DBT_STF_Signed = 0x10;
+static const uint16_t DBT_STF_VariableLength = 0x80;
+
+
+
+static const uint32_t DBT_SDF_FoundValid = 0x00000001;
+static const uint32_t DBT_SDF_HashValid = 0x00000002;
+
+/**
+ \brief Describes a setting, its name and location
+**/
+typedef
+ struct TDBTSettingDescriptor {
+ uint32_t cbSize; /// size of the structure in bytes
+ TDBTEntityHandle Entity; /// Entityhandle where the setting can be found, or where searching starts
+ char * pszSettingName; /// Setting name
+ uint32_t Options; /// options describing where the setting can be found DBT_NIFO_*
+ uint32_t Flags; /// Valid Flags. DBT_SDF_* describes which following values are valid (internal use)
+
+ TDBTEntityHandle FoundInEntity; /// internal use to avoid to do the searching twice
+ uint32_t Hash; /// internal used HashValue for settingname
+ TDBTSettingHandle FoundHandle; /// internal used SettingHandle
+ } TDBTSettingDescriptor, * PDBTSettingDescriptor;
+
+/**
+ \brief Describes a settings value
+
+ it is never used alone, without a type qualifier
+**/
+typedef
+ union TDBTSettingValue {
+ bool Bool;
+ int8_t Char; uint8_t Byte;
+ int16_t Short; uint16_t Word;
+ uint32_t Int; uint32_t DWord;
+ int64_t Int64; uint64_t QWord;
+ float Float;
+ double Double;
+
+ struct {
+ uint32_t Length; // length in bytes of pBlob, length in characters of char types including trailing null
+ union {
+ uint8_t * pBlob;
+ char * pAnsi;
+ char * pUTF8;
+ wchar_t * pWide;
+ TCHAR * pTChar;
+ };
+ };
+ } TDBTSettingValue;
+
+/**
+ \brief Describes a setting
+**/
+typedef
+ struct TDBTSetting {
+ uint32_t cbSize; /// size of the structure in bytes
+ PDBTSettingDescriptor Descriptor; /// pointer to a Setting descriptor used to locate the setting
+ uint16_t Type; /// type of the setting, see DBT_ST_*
+ TDBTSettingValue Value; /// Value of the setting according to Type
+ } TDBTSetting, * PDBTSetting;
+
+
+
+/**
+ \brief retrieves the handle of the setting
+ \param wParam = PDBTSettingDescriptor
+ \param lParam = 0
+
+ \return hSetting when found, 0 otherwise
+**/
+#define MS_DBT_SETTING_FIND "DBT/Setting/Find"
+
+
+/**
+ \brief deletes the specified Setting
+ \param wParam = PDBTSettingDescriptor
+ \param lParam = 0
+
+ \return hSetting when found, 0 otherwise
+**/
+#define MS_DBT_SETTING_DELETE "DBT/Setting/Delete"
+
+/**
+ \brief deletes the specified Setting
+ \param wParam = TDBTSettingHandle
+ \param lParam = 0
+
+ \return 0 on success
+**/
+#define MS_DBT_SETTING_DELETEHANDLE "DBT/Setting/DeleteHandle"
+
+
+/**
+ \brief Write a setting (and creates it if neccessary)
+ \param wParam = PDBTSetting
+ \param lParam = 0
+
+ \return TDBTSettingHandle on success, 0 otherwise
+**/
+#define MS_DBT_SETTING_WRITE "DBT/Setting/Write"
+
+/**
+ \brief retrieves the handle of the setting
+ \param wParam = PDBTSetting
+ \param lParam = TDBTSettingHandle, could be 0 to create new setting, but needs wParam->Descriptor with valid data
+
+ \return hSetting when found or created, 0 otherwise
+**/
+#define MS_DBT_SETTING_WRITEHANDLE "DBT/Setting/WriteHandle"
+
+/**
+ \brief retrieves the value of the setting
+ \param wParam = PDBTSetting
+ \param lParam = 0
+
+ \return SettingHandle
+**/
+#define MS_DBT_SETTING_READ "DBT/Setting/Read"
+
+/**
+ \brief retrieves the value of the setting
+
+ Also retrieves the SettingDescriptor if it is set and prepared correctly (name buffers set etc)
+ \param wParam = PDBTSetting
+ \param lParam = TDBTSettingHandle
+
+ \return original settings type
+**/
+#define MS_DBT_SETTING_READHANDLE "DBT/Setting/ReadHandle"
+
+
+
+/**
+ \brief Settings Filter Options for setting iteration
+**/
+typedef
+ struct TDBTSettingIterFilter {
+ uint32_t cbSize; /// size in bytes of this structure
+ uint32_t Options; /// DBT_NIFO_* flags
+ TDBTEntityHandle hEntity; /// hEntity which settings should be iterated (or where iteration begins)
+ char * NameStart; /// if set != NULL the iteration will only return settings which name starts with this string
+ uint32_t ExtraCount; /// count of additional Entities which settings are enumerated, size of the array pointed by ExtraEntities
+ TDBTEntityHandle * ExtraEntities; /// pointer to an array with additional Entity handles in prioritized order
+
+ PDBTSettingDescriptor Descriptor; /// if set, the iteration will fill in the correct data, you may set SettingsNameLength and SettingName to a buffer to recieve the name of each setting
+ PDBTSetting Setting; /// if set, iteration loads every settings value, except variable length data (blob, strings) but returns their length
+
+ } TDBTSettingIterFilter, *PDBTSettingIterFilter;
+
+
+/**
+ \brief Handle of a Setting-Iteration
+**/
+typedef uintptr_t TDBTSettingIterationHandle;
+/**
+ \brief initialize an iteration of settings
+ \param wParam = PDBTSettingIterFilter
+ \param lParam = 0
+
+ \return EnumID
+**/
+#define MS_DBT_SETTING_ITER_INIT "DBT/Setting/Iter/Init"
+
+
+/**
+ \brief get the next setting
+ \param wParam = EnumID returned by MS_DBT_SETTING_ITER_INIT
+ \param lParam = 0
+
+ \return hSetting, 0 at the end
+**/
+#define MS_DBT_SETTING_ITER_NEXT "DBT/Setting/Iter/Next"
+
+/**
+ \brief closes an iteration and frees its ressourcs
+ \param wParam = IterationHandle returned by MS_DBT_SETTING_ITER_INIT
+ \param lParam = 0
+
+ \return 0 on success
+**/
+#define MS_DBT_SETTING_ITER_CLOSE "DBT/Setting/Iter/Close"
+
+
+///////////////////////////////////////////////////////////
+// Events
+///////////////////////////////////////////////////////////
+
+typedef uint32_t TDBTEventHandle;
+
+
+/**
+ \brief this event was sent by the user. If not set this event was received.
+**/
+static const uint32_t DBT_EF_SENT = 0x00000002;
+
+/**
+ \brief event has been read by the user. It does not need to be processed any more except for history.
+**/
+static const uint32_t DBT_EF_READ = 0x00000004;
+
+/**
+ \brief event contains the right-to-left aligned text
+**/
+static const uint32_t DBT_EF_RTL = 0x00000008;
+
+/**
+ \brief event contains a text in utf-8
+**/
+static const uint32_t DBT_EF_UTF = 0x00000010;
+
+/**
+ \brief event is virtual. it is not stored to db file yet.
+**/
+static const uint32_t DBT_EF_VIRTUAL = 0x00000020;
+
+/**
+ \brief describes an event
+**/
+typedef struct TDBTEvent {
+ uint32_t cbSize; /// size of the structure in bytes
+ char * ModuleName; ///
+ uint32_t Timestamp; /// seconds since 00:00, 01/01/1970. Gives us times until 2106 unless you use the standard C library which is signed and can only do until 2038. In GMT.
+ uint32_t Flags; /// the omnipresent flags
+ uint32_t EventType; /// module-unique event type ID
+ uint32_t cbBlob; /// size of pBlob in bytes
+ uint8_t * pBlob; /// pointer to buffer containing module-defined event data
+} TDBTEvent, *PDBTEvent;
+
+static const uint32_t DBT_EventType_Message = 0;
+static const uint32_t DBT_EventType_URL = 1;
+static const uint32_t DBT_EventType_Contacts = 2;
+static const uint32_t DBT_EventType_Added = 1000;
+static const uint32_t DBT_EventType_AuthRequest = 1001; //specific codes, hence the module-
+static const uint32_t DBT_EventType_File = 1002; //specific limit has been raised to 2000
+
+
+/**
+ \brief retrieves the blobsize of an event in bytes
+ \param wParam = hEvent
+ \param lParam = 0
+
+ \return blobsize
+**/
+#define MS_DBT_EVENT_GETBLOBSIZE "DBT/Event/GetBlobSize"
+
+
+
+/**
+ \brief retrieves all information of an event
+ \param wParam = hEvent
+ \param lParam = PDBTEvent
+
+ \return 0 on success
+**/
+#define MS_DBT_EVENT_GET "DBT/Event/Get"
+
+/**
+ \brief retrieves all information of an event
+ \param wParam = hEntity
+ \param lParam = 0
+
+ \return Event count of specified Entity on success, DBT_INVALIDPARAM on error
+**/
+#define MS_DBT_EVENT_GETCOUNT "DBT/Event/GetCount"
+
+
+/**
+ \brief Deletes the specfied event
+ \param wParam = hEntity
+ \param lParam = hEvent
+
+ \return 0 on success
+**/
+#define MS_DBT_EVENT_DELETE "DBT/Event/Delete"
+
+/**
+ \brief Creates a new Event
+ \param wParam = hEntity
+ \param lParam = PDBTEvent
+
+ \return hEvent on success, 0 otherwise
+**/
+
+#define MS_DBT_EVENT_ADD "DBT/Event/Add"
+
+
+/**
+ \brief Changes the flags for an event to mark it as read.
+ \param wParam = hEntity
+ \param lParam = hEvent
+
+ \return New flags
+**/
+#define MS_DBT_EVENT_MARKREAD "DBT/Event/MarkRead"
+
+/**
+ \brief Saves a virtual event to file and changes the flags.
+ \param wParam = hEntity
+ \param lParam = hEvent
+
+ \return 0 on success
+**/
+#define MS_DBT_EVENT_WRITETODISK "DBT/Event/WriteToDisk"
+
+/**
+ \brief Retrieves a handle to a Entity that owns hEvent.
+ \param wParam = hEvent
+ \param lParam = 0
+
+ \return NULL is a valid return value, meaning, as usual, the user.
+ DBT_INVALIDPARAM if hDbEvent is invalid, or the handle to the Entity on
+ success
+**/
+#define MS_DBT_EVENT_GETENTITY "DBT/Event/GetEntity"
+
+/**
+ \brief Event Filter Options for event iteration
+**/
+typedef
+ struct TDBTEventIterFilter {
+ uint32_t cbSize; /// size in bytes of this structure
+ uint32_t Options; /// DBT_NIFO_* flags
+ TDBTEntityHandle hEntity; /// hEntity which events should be iterated (or where iteration begins)
+ uint32_t ExtraCount; /// count of additional Entities which settings are enumerated, size of the array pointed by ExtraEntities
+ TDBTEntityHandle * ExtraEntities; /// pointer to an array with additional Entity handles in prioritized order
+
+ uint32_t tSince; /// timestamp when to start iteration, 0 for first item
+ uint32_t tTill; /// timestamp when to stop iteration, 0 for last item
+
+ PDBTEvent Event; /// if set every events data gets stored there
+
+ } TDBTEventIterFilter, *PDBTEventIterFilter;
+
+
+/**
+ \brief Handle of a Event-Iteration
+**/
+typedef uintptr_t TDBTEventIterationHandle;
+/**
+ \brief initialize an iteration of events
+ \param wParam = PDBTEventIterFilter
+ \param lParam = 0
+
+ \return EnumID
+**/
+#define MS_DBT_EVENT_ITER_INIT "DBT/Event/Iter/Init"
+
+
+/**
+ \brief get the next event
+ \param wParam = EnumID returned by MS_DBT_EVENT_ITER_INIT
+ \param lParam = 0
+
+ \return hSetting, 0 at the end
+**/
+#define MS_DBT_EVENT_ITER_NEXT "DBT/Event/Iter/Next"
+
+/**
+ \brief closes an iteration and frees its resourcs
+ \param wParam = IterationHandle returned by MS_DBT_EVENT_ITER_INIT
+ \param lParam = 0
+
+ \return 0 on success
+**/
+#define MS_DBT_EVENT_ITER_CLOSE "DBT/Event/Iter/Close"
+
+
+
+#pragma pack(pop)
+
+#endif
diff --git a/dbx_tree/savestrings_gcc.h b/dbx_tree/savestrings_gcc.h new file mode 100644 index 0000000..9da6808 --- /dev/null +++ b/dbx_tree/savestrings_gcc.h @@ -0,0 +1,127 @@ +/*
+
+dbx_tree: tree database driver for Miranda IM
+
+Copyright 2007-2010 Michael "Protogenes" Kunz,
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#pragma once
+
+inline int strcpy_s(
+ char *strDestination,
+ size_t numberOfElements,
+ const char *strSource
+)
+{
+ if (!strDestination) return EINVAL;
+ if (!strSource) {strDestination[0] = 0; return EINVAL;}
+ size_t l = strlen(strSource);
+ if (numberOfElements < l + 1) {strDestination[0] = 0; return ERANGE;}
+ memcpy(strDestination, strSource, l + 1);
+ return 0;
+}
+
+template <size_t size>
+inline int strcpy_s(
+ char (&strDestination)[size],
+ const char *strSource
+)
+{
+ if (!strDestination) return EINVAL;
+ if (!strSource) {strDestination[0] = 0; return EINVAL;}
+ size_t l = strlen(strSource);
+ if (size < l + 1) {strDestination[0] = 0; return ERANGE;}
+
+ memcpy(strDestination, strSource, l + 1);
+ return 0;
+}
+
+
+inline int strcat_s(
+ char *strDestination,
+ size_t numberOfElements,
+ const char *strSource
+)
+{
+ if (!strDestination) return EINVAL;
+ if (!strSource) {strDestination[0] = 0; return EINVAL;}
+ size_t l = strlen(strSource);
+ size_t m = strlen(strDestination);
+ if (numberOfElements < l + m + 1) {strDestination[0] = 0; return ERANGE;}
+
+ memcpy(&strDestination[m], strSource, l + 1);
+ return 0;
+}
+
+template <size_t size>
+inline int strcat_s(
+ char (&strDestination)[size],
+ const char *strSource
+)
+{
+ if (!strDestination) return EINVAL;
+ if (!strSource) {strDestination[0] = 0; return EINVAL;}
+ size_t l = strlen(strSource);
+ size_t m = strlen(strDestination);
+ if (size < l + m + 1) {strDestination[0] = 0; return ERANGE;}
+
+ memcpy(&strDestination[m], strSource, l + 1);
+ return 0;
+}
+
+inline int strncpy_s(
+ char *strDest,
+ size_t numberOfElements,
+ const char *strSource,
+ size_t count
+)
+{
+ if (count > numberOfElements)
+ return strcpy_s(strDest, numberOfElements, strSource);
+ else
+ return strcpy_s(strDest, count + 1, strSource);
+}
+
+
+template <size_t size>
+inline int sprintf_s(
+ char (&buffer)[size],
+ const char *format,
+ ...
+)
+{
+ va_list va;
+ va_start(va, format);
+ vsnprintf(buffer, size, format, va);
+ va_end(va);
+}
+
+template <size_t size>
+inline int swprintf_s(
+ wchar_t (&buffer)[size],
+ const wchar_t *format,
+ ...
+)
+{
+ va_list va;
+ va_start(va, format);
+ vsnwprintf(buffer, size, format, va);
+ va_end(va);
+}
+
+#define vsprintf_s vsnprintf
diff --git a/dbx_tree/sigslot.h b/dbx_tree/sigslot.h new file mode 100644 index 0000000..cdf17f3 --- /dev/null +++ b/dbx_tree/sigslot.h @@ -0,0 +1,2639 @@ +// sigslot.h: Signal/Slot classes +// +// Written by Sarah Thompson (sarah@telergy.com) 2002. +// +// License: Public domain. You are free to use this code however you like, with the proviso that +// the author takes on no responsibility or liability for any use. +// +// QUICK DOCUMENTATION +// +// (see also the full documentation at http://sigslot.sourceforge.net/) +// +// #define switches +// SIGSLOT_PURE_ISO - Define this to force ISO C++ compliance. This also disables +// all of the thread safety support on platforms where it is +// available. +// +// SIGSLOT_USE_POSIX_THREADS - Force use of Posix threads when using a C++ compiler other than +// gcc on a platform that supports Posix threads. (When using gcc, +// this is the default - use SIGSLOT_PURE_ISO to disable this if +// necessary) +// +// SIGSLOT_DEFAULT_MT_POLICY - Where thread support is enabled, this defaults to multi_threaded_global. +// Otherwise, the default is single_threaded. #define this yourself to +// override the default. In pure ISO mode, anything other than +// single_threaded will cause a compiler error. +// +// PLATFORM NOTES +// +// Win32 - On Win32, the WIN32 symbol must be #defined. Most mainstream +// compilers do this by default, but you may need to define it +// yourself if your build environment is less standard. This causes +// the Win32 thread support to be compiled in and used automatically. +// +// Unix/Linux/BSD, etc. - If you're using gcc, it is assumed that you have Posix threads +// available, so they are used automatically. You can override this +// (as under Windows) with the SIGSLOT_PURE_ISO switch. If you're using +// something other than gcc but still want to use Posix threads, you +// need to #define SIGSLOT_USE_POSIX_THREADS. +// +// ISO C++ - If none of the supported platforms are detected, or if +// SIGSLOT_PURE_ISO is defined, all multithreading support is turned off, +// along with any code that might cause a pure ISO C++ environment to +// complain. Before you ask, gcc -ansi -pedantic won't compile this +// library, but gcc -ansi is fine. Pedantic mode seems to throw a lot of +// errors that aren't really there. If you feel like investigating this, +// please contact the author. +// +// +// THREADING MODES +// +// single_threaded - Your program is assumed to be single threaded from the point of view +// of signal/slot usage (i.e. all objects using signals and slots are +// created and destroyed from a single thread). Behaviour if objects are +// destroyed concurrently is undefined (i.e. you'll get the occasional +// segmentation fault/memory exception). +// +// multi_threaded_global - Your program is assumed to be multi threaded. Objects using signals and +// slots can be safely created and destroyed from any thread, even when +// connections exist. In multi_threaded_global mode, this is achieved by a +// single global mutex (actually a critical section on Windows because they +// are faster). This option uses less OS resources, but results in more +// opportunities for contention, possibly resulting in more context switches +// than are strictly necessary. +// +// multi_threaded_local - Behaviour in this mode is essentially the same as multi_threaded_global, +// except that each signal, and each object that inherits has_slots, all +// have their own mutex/critical section. In practice, this means that +// mutex collisions (and hence context switches) only happen if they are +// absolutely essential. However, on some platforms, creating a lot of +// mutexes can slow down the whole OS, so use this option with care. +// +// USING THE LIBRARY +// +// See the full documentation at http://sigslot.sourceforge.net/ +// +// + +#ifndef SIGSLOT_H__ +#define SIGSLOT_H__ + +#include <set> +#include <list> + +#if defined(SIGSLOT_PURE_ISO) || (!defined(WIN32) && !defined(__GNUG__) && !defined(SIGSLOT_USE_POSIX_THREADS)) +# define _SIGSLOT_SINGLE_THREADED +#elif defined(WIN32) +# define _SIGSLOT_HAS_WIN32_THREADS +# include <windows.h> +#elif defined(__GNUG__) || defined(SIGSLOT_USE_POSIX_THREADS) +# define _SIGSLOT_HAS_POSIX_THREADS +# include <pthread.h> +#else +# define _SIGSLOT_SINGLE_THREADED +#endif + +#define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_global + +#ifndef SIGSLOT_DEFAULT_MT_POLICY +# ifdef _SIGSLOT_SINGLE_THREADED +# define SIGSLOT_DEFAULT_MT_POLICY single_threaded +# else +# define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local +# endif +#endif + + +namespace sigslot { + + class single_threaded + { + public: + single_threaded() + { + ; + } + + ~single_threaded() + { + ; + } + + void lock() + { + ; + } + + void unlock() + { + ; + } + }; + +#ifdef _SIGSLOT_HAS_WIN32_THREADS + // The multi threading policies only get compiled in if they are enabled. + class multi_threaded_global + { + public: + multi_threaded_global() + { + static bool isinitialised = false; + + if(!isinitialised) + { + InitializeCriticalSection(get_critsec()); + isinitialised = true; + } + } + + multi_threaded_global(const multi_threaded_global&) + { + ; + } + + ~multi_threaded_global() + { + ; + } + + void lock() + { + EnterCriticalSection(get_critsec()); + } + + void unlock() + { + LeaveCriticalSection(get_critsec()); + } + + private: + CRITICAL_SECTION* get_critsec() + { + static CRITICAL_SECTION g_critsec; + return &g_critsec; + } + }; + + class multi_threaded_local + { + public: + multi_threaded_local() + { + InitializeCriticalSection(&m_critsec); + } + + multi_threaded_local(const multi_threaded_local&) + { + InitializeCriticalSection(&m_critsec); + } + + ~multi_threaded_local() + { + DeleteCriticalSection(&m_critsec); + } + + void lock() + { + EnterCriticalSection(&m_critsec); + } + + void unlock() + { + LeaveCriticalSection(&m_critsec); + } + + private: + CRITICAL_SECTION m_critsec; + }; +#endif // _SIGSLOT_HAS_WIN32_THREADS + +#ifdef _SIGSLOT_HAS_POSIX_THREADS + // The multi threading policies only get compiled in if they are enabled. + class multi_threaded_global + { + public: + multi_threaded_global() + { + pthread_mutex_init(get_mutex(), NULL); + } + + multi_threaded_global(const multi_threaded_global&) + { + ; + } + + ~multi_threaded_global() + { + ; + } + + void lock() + { + pthread_mutex_lock(get_mutex()); + } + + void unlock() + { + pthread_mutex_unlock(get_mutex()); + } + + private: + pthread_mutex_t* get_mutex() + { + static pthread_mutex_t g_mutex; + return &g_mutex; + } + }; + + class multi_threaded_local + { + public: + multi_threaded_local() + { + pthread_mutex_init(&m_mutex, NULL); + } + + multi_threaded_local(const multi_threaded_local&) + { + pthread_mutex_init(&m_mutex, NULL); + } + + ~multi_threaded_local() + { + pthread_mutex_destroy(&m_mutex); + } + + void lock() + { + pthread_mutex_lock(&m_mutex); + } + + void unlock() + { + pthread_mutex_unlock(&m_mutex); + } + + private: + pthread_mutex_t m_mutex; + }; +#endif // _SIGSLOT_HAS_POSIX_THREADS + + template<class mt_policy> + class lock_block + { + public: + mt_policy *m_mutex; + + lock_block(mt_policy *mtx) + : m_mutex(mtx) + { + m_mutex->lock(); + } + + ~lock_block() + { + m_mutex->unlock(); + } + }; + + template<class mt_policy> + class has_slots; + + template<class mt_policy> + class _connection_base0 + { + public: + virtual ~_connection_base0() { ; } + virtual has_slots<mt_policy>* getdest() const = 0; + virtual void emit() = 0; + virtual _connection_base0* clone() = 0; + virtual _connection_base0* duplicate(has_slots<mt_policy>* pnewdest) = 0; + }; + + template<class arg1_type, class mt_policy> + class _connection_base1 + { + public: + virtual ~_connection_base1() { ; } + virtual has_slots<mt_policy>* getdest() const = 0; + virtual void emit(arg1_type) = 0; + virtual _connection_base1<arg1_type, mt_policy>* clone() = 0; + virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0; + }; + + template<class arg1_type, class arg2_type, class mt_policy> + class _connection_base2 + { + public: + virtual ~_connection_base2() { ; } + virtual has_slots<mt_policy>* getdest() const = 0; + virtual void emit(arg1_type, arg2_type) = 0; + virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone() = 0; + virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0; + }; + + template<class arg1_type, class arg2_type, class arg3_type, class mt_policy> + class _connection_base3 + { + public: + virtual ~_connection_base3() { ; } + virtual has_slots<mt_policy>* getdest() const = 0; + virtual void emit(arg1_type, arg2_type, arg3_type) = 0; + virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* clone() = 0; + virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0; + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy> + class _connection_base4 + { + public: + virtual ~_connection_base4() { ; } + virtual has_slots<mt_policy>* getdest() const = 0; + virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type) = 0; + virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* clone() = 0; + virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0; + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, + class arg5_type, class mt_policy> + class _connection_base5 + { + public: + virtual ~_connection_base5() { ; } + virtual has_slots<mt_policy>* getdest() const = 0; + virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type) = 0; + virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, mt_policy>* clone() = 0; + virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0; + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, + class arg5_type, class arg6_type, class mt_policy> + class _connection_base6 + { + public: + virtual ~_connection_base6() { ; } + virtual has_slots<mt_policy>* getdest() const = 0; + virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, + arg6_type) = 0; + virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, mt_policy>* clone() = 0; + virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0; + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, + class arg5_type, class arg6_type, class arg7_type, class mt_policy> + class _connection_base7 + { + public: + virtual ~_connection_base7() { ; } + virtual has_slots<mt_policy>* getdest() const = 0; + virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, + arg6_type, arg7_type) = 0; + virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, mt_policy>* clone() = 0; + virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0; + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, + class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy> + class _connection_base8 + { + public: + virtual ~_connection_base8() { ; } + virtual has_slots<mt_policy>* getdest() const = 0; + virtual void emit(arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, + arg6_type, arg7_type, arg8_type) = 0; + virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* clone() = 0; + virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) = 0; + }; + + template<class mt_policy> + class _signal_base : public mt_policy + { + public: + virtual void slot_disconnect(has_slots<mt_policy>* pslot) = 0; + virtual void slot_duplicate(const has_slots<mt_policy>* poldslot, has_slots<mt_policy>* pnewslot) = 0; + }; + + template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> + class has_slots : public mt_policy + { + private: + typedef typename std::set<_signal_base<mt_policy> *> sender_set; + typedef typename sender_set::const_iterator const_iterator; + + public: + has_slots() + { + ; + } + + has_slots(const has_slots& hs) + : mt_policy(hs) + { + lock_block<mt_policy> lock(this); + const_iterator it = hs.m_senders.begin(); + const_iterator itEnd = hs.m_senders.end(); + + while(it != itEnd) + { + (*it)->slot_duplicate(&hs, this); + m_senders.insert(*it); + ++it; + } + } + + void signal_connect(_signal_base<mt_policy>* sender) + { + lock_block<mt_policy> lock(this); + m_senders.insert(sender); + } + + void signal_disconnect(_signal_base<mt_policy>* sender) + { + lock_block<mt_policy> lock(this); + m_senders.erase(sender); + } + + virtual ~has_slots() + { + disconnect_all(); + } + + void disconnect_all() + { + lock_block<mt_policy> lock(this); + const_iterator it = m_senders.begin(); + const_iterator itEnd = m_senders.end(); + + while(it != itEnd) + { + (*it)->slot_disconnect(this); + ++it; + } + + m_senders.erase(m_senders.begin(), m_senders.end()); + } + + private: + sender_set m_senders; + }; + + template<class mt_policy> + class _signal_base0 : public _signal_base<mt_policy> + { + public: + typedef typename std::list<_connection_base0<mt_policy> *> connections_list; + typedef typename connections_list::const_iterator const_iterator; + typedef typename connections_list::iterator iterator; + + _signal_base0() + { + ; + } + + _signal_base0(const _signal_base0& s) + : _signal_base<mt_policy>(s) + { + lock_block<mt_policy> lock(this); + const_iterator it = s.m_connected_slots.begin(); + const_iterator itEnd = s.m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_connect(this); + m_connected_slots.push_back((*it)->clone()); + + ++it; + } + } + + ~_signal_base0() + { + disconnect_all(); + } + + void disconnect_all() + { + lock_block<mt_policy> lock(this); + const_iterator it = m_connected_slots.begin(); + const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_disconnect(this); + delete *it; + + ++it; + } + + m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); + } + + void disconnect(has_slots<mt_policy>* pclass) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == pclass) + { + delete *it; + m_connected_slots.erase(it); + pclass->signal_disconnect(this); + return; + } + + ++it; + } + } + + void slot_disconnect(has_slots<mt_policy>* pslot) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + iterator itNext = it; + ++itNext; + + if((*it)->getdest() == pslot) + { + delete *it; + m_connected_slots.erase(it); + // delete *it; + } + + it = itNext; + } + } + + void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == oldtarget) + { + m_connected_slots.push_back((*it)->duplicate(newtarget)); + } + + ++it; + } + } + + protected: + connections_list m_connected_slots; + }; + + template<class arg1_type, class mt_policy> + class _signal_base1 : public _signal_base<mt_policy> + { + public: + typedef typename std::list<_connection_base1<arg1_type, mt_policy> *> connections_list; + typedef typename connections_list::const_iterator const_iterator; + typedef typename connections_list::iterator iterator; + + _signal_base1() + { + ; + } + + _signal_base1(const _signal_base1<arg1_type, mt_policy>& s) + : _signal_base<mt_policy>(s) + { + lock_block<mt_policy> lock(this); + const_iterator it = s.m_connected_slots.begin(); + const_iterator itEnd = s.m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_connect(this); + m_connected_slots.push_back((*it)->clone()); + + ++it; + } + } + + void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == oldtarget) + { + m_connected_slots.push_back((*it)->duplicate(newtarget)); + } + + ++it; + } + } + + ~_signal_base1() + { + disconnect_all(); + } + + void disconnect_all() + { + lock_block<mt_policy> lock(this); + const_iterator it = m_connected_slots.begin(); + const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_disconnect(this); + delete *it; + + ++it; + } + + m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); + } + + void disconnect(has_slots<mt_policy>* pclass) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == pclass) + { + delete *it; + m_connected_slots.erase(it); + pclass->signal_disconnect(this); + return; + } + + ++it; + } + } + + void slot_disconnect(has_slots<mt_policy>* pslot) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + iterator itNext = it; + ++itNext; + + if((*it)->getdest() == pslot) + { + delete *it; + m_connected_slots.erase(it); + // delete *it; + } + + it = itNext; + } + } + + + protected: + connections_list m_connected_slots; + }; + + template<class arg1_type, class arg2_type, class mt_policy> + class _signal_base2 : public _signal_base<mt_policy> + { + public: + typedef typename std::list<_connection_base2<arg1_type, arg2_type, mt_policy> *> + connections_list; + typedef typename connections_list::const_iterator const_iterator; + typedef typename connections_list::iterator iterator; + + _signal_base2() + { + ; + } + + _signal_base2(const _signal_base2<arg1_type, arg2_type, mt_policy>& s) + : _signal_base<mt_policy>(s) + { + lock_block<mt_policy> lock(this); + const_iterator it = s.m_connected_slots.begin(); + const_iterator itEnd = s.m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_connect(this); + m_connected_slots.push_back((*it)->clone()); + + ++it; + } + } + + void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == oldtarget) + { + m_connected_slots.push_back((*it)->duplicate(newtarget)); + } + + ++it; + } + } + + ~_signal_base2() + { + disconnect_all(); + } + + void disconnect_all() + { + lock_block<mt_policy> lock(this); + const_iterator it = m_connected_slots.begin(); + const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_disconnect(this); + delete *it; + + ++it; + } + + m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); + } + + void disconnect(has_slots<mt_policy>* pclass) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == pclass) + { + delete *it; + m_connected_slots.erase(it); + pclass->signal_disconnect(this); + return; + } + + ++it; + } + } + + void slot_disconnect(has_slots<mt_policy>* pslot) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + iterator itNext = it; + ++itNext; + + if((*it)->getdest() == pslot) + { + delete *it; + m_connected_slots.erase(it); + // delete *it; + } + + it = itNext; + } + } + + protected: + connections_list m_connected_slots; + }; + + template<class arg1_type, class arg2_type, class arg3_type, class mt_policy> + class _signal_base3 : public _signal_base<mt_policy> + { + public: + typedef std::list<_connection_base3<arg1_type, arg2_type, arg3_type, mt_policy> *> + connections_list; + + typedef typename connections_list::const_iterator const_iterator; + typedef typename connections_list::iterator iterator; + _signal_base3() + { + ; + } + + _signal_base3(const _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>& s) + : _signal_base<mt_policy>(s) + { + lock_block<mt_policy> lock(this); + const_iterator it = s.m_connected_slots.begin(); + const_iterator itEnd = s.m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_connect(this); + m_connected_slots.push_back((*it)->clone()); + + ++it; + } + } + + void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == oldtarget) + { + m_connected_slots.push_back((*it)->duplicate(newtarget)); + } + + ++it; + } + } + + ~_signal_base3() + { + disconnect_all(); + } + + void disconnect_all() + { + lock_block<mt_policy> lock(this); + const_iterator it = m_connected_slots.begin(); + const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_disconnect(this); + delete *it; + + ++it; + } + + m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); + } + + void disconnect(has_slots<mt_policy>* pclass) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == pclass) + { + delete *it; + m_connected_slots.erase(it); + pclass->signal_disconnect(this); + return; + } + + ++it; + } + } + + void slot_disconnect(has_slots<mt_policy>* pslot) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + iterator itNext = it; + ++itNext; + + if((*it)->getdest() == pslot) + { + delete *it; + m_connected_slots.erase(it); + // delete *it; + } + + it = itNext; + } + } + + protected: + connections_list m_connected_slots; + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy> + class _signal_base4 : public _signal_base<mt_policy> + { + public: + typedef std::list<_connection_base4<arg1_type, arg2_type, arg3_type, + arg4_type, mt_policy> *> connections_list; + typedef typename connections_list::const_iterator const_iterator; + typedef typename connections_list::iterator iterator; + + _signal_base4() + { + ; + } + + _signal_base4(const _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>& s) + : _signal_base<mt_policy>(s) + { + lock_block<mt_policy> lock(this); + const_iterator it = s.m_connected_slots.begin(); + const_iterator itEnd = s.m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_connect(this); + m_connected_slots.push_back((*it)->clone()); + + ++it; + } + } + + void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == oldtarget) + { + m_connected_slots.push_back((*it)->duplicate(newtarget)); + } + + ++it; + } + } + + ~_signal_base4() + { + disconnect_all(); + } + + void disconnect_all() + { + lock_block<mt_policy> lock(this); + const_iterator it = m_connected_slots.begin(); + const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_disconnect(this); + delete *it; + + ++it; + } + + m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); + } + + void disconnect(has_slots<mt_policy>* pclass) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == pclass) + { + delete *it; + this->m_connected_slots.erase(it); + pclass->signal_disconnect(this); + return; + } + + ++it; + } + } + + void slot_disconnect(has_slots<mt_policy>* pslot) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + iterator itNext = it; + ++itNext; + + if((*it)->getdest() == pslot) + { + delete *it; + m_connected_slots.erase(it); + // delete *it; + } + + it = itNext; + } + } + + protected: + connections_list m_connected_slots; + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, + class arg5_type, class mt_policy> + class _signal_base5 : public _signal_base<mt_policy> + { + public: + typedef std::list<_connection_base5<arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, mt_policy> *> connections_list; + typedef typename connections_list::const_iterator const_iterator; + typedef typename connections_list::iterator iterator; + + _signal_base5() + { + ; + } + + _signal_base5(const _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, mt_policy>& s) + : _signal_base<mt_policy>(s) + { + lock_block<mt_policy> lock(this); + const_iterator it = s.m_connected_slots.begin(); + const_iterator itEnd = s.m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_connect(this); + m_connected_slots.push_back((*it)->clone()); + + ++it; + } + } + + void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == oldtarget) + { + m_connected_slots.push_back((*it)->duplicate(newtarget)); + } + + ++it; + } + } + + ~_signal_base5() + { + disconnect_all(); + } + + void disconnect_all() + { + lock_block<mt_policy> lock(this); + const_iterator it = m_connected_slots.begin(); + const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_disconnect(this); + delete *it; + + ++it; + } + + m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); + } + + void disconnect(has_slots<mt_policy>* pclass) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == pclass) + { + delete *it; + m_connected_slots.erase(it); + pclass->signal_disconnect(this); + return; + } + + ++it; + } + } + + void slot_disconnect(has_slots<mt_policy>* pslot) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + iterator itNext = it; + ++itNext; + + if((*it)->getdest() == pslot) + { + delete *it; + m_connected_slots.erase(it); + // delete *it; + } + + it = itNext; + } + } + + protected: + connections_list m_connected_slots; + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, + class arg5_type, class arg6_type, class mt_policy> + class _signal_base6 : public _signal_base<mt_policy> + { + public: + typedef std::list<_connection_base6<arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, arg6_type, mt_policy> *> connections_list; + typedef typename connections_list::const_iterator const_iterator; + typedef typename connections_list::iterator iterator; + + _signal_base6() + { + ; + } + + _signal_base6(const _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, mt_policy>& s) + : _signal_base<mt_policy>(s) + { + lock_block<mt_policy> lock(this); + const_iterator it = s.m_connected_slots.begin(); + const_iterator itEnd = s.m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_connect(this); + m_connected_slots.push_back((*it)->clone()); + + ++it; + } + } + + void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == oldtarget) + { + m_connected_slots.push_back((*it)->duplicate(newtarget)); + } + + ++it; + } + } + + ~_signal_base6() + { + disconnect_all(); + } + + void disconnect_all() + { + lock_block<mt_policy> lock(this); + const_iterator it = m_connected_slots.begin(); + const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_disconnect(this); + delete *it; + + ++it; + } + + m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); + } + + void disconnect(has_slots<mt_policy>* pclass) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == pclass) + { + delete *it; + m_connected_slots.erase(it); + pclass->signal_disconnect(this); + return; + } + + ++it; + } + } + + void slot_disconnect(has_slots<mt_policy>* pslot) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + iterator itNext = it; + ++itNext; + + if((*it)->getdest() == pslot) + { + delete *it; + m_connected_slots.erase(it); + // delete *it; + } + + it = itNext; + } + } + + protected: + connections_list m_connected_slots; + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, + class arg5_type, class arg6_type, class arg7_type, class mt_policy> + class _signal_base7 : public _signal_base<mt_policy> + { + public: + typedef std::list<_connection_base7<arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, arg6_type, arg7_type, mt_policy> *> connections_list; + typedef typename connections_list::const_iterator const_iterator; + typedef typename connections_list::iterator iterator; + + _signal_base7() + { + ; + } + + _signal_base7(const _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, mt_policy>& s) + : _signal_base<mt_policy>(s) + { + lock_block<mt_policy> lock(this); + const_iterator it = s.m_connected_slots.begin(); + const_iterator itEnd = s.m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_connect(this); + m_connected_slots.push_back((*it)->clone()); + + ++it; + } + } + + void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == oldtarget) + { + m_connected_slots.push_back((*it)->duplicate(newtarget)); + } + + ++it; + } + } + + ~_signal_base7() + { + disconnect_all(); + } + + void disconnect_all() + { + lock_block<mt_policy> lock(this); + const_iterator it = m_connected_slots.begin(); + const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_disconnect(this); + delete *it; + + ++it; + } + + m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); + } + + void disconnect(has_slots<mt_policy>* pclass) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == pclass) + { + delete *it; + m_connected_slots.erase(it); + pclass->signal_disconnect(this); + return; + } + + ++it; + } + } + + void slot_disconnect(has_slots<mt_policy>* pslot) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + iterator itNext = it; + ++itNext; + + if((*it)->getdest() == pslot) + { + delete *it; + m_connected_slots.erase(it); + // delete *it; + } + + it = itNext; + } + } + + protected: + connections_list m_connected_slots; + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, + class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy> + class _signal_base8 : public _signal_base<mt_policy> + { + public: + typedef std::list<_connection_base8<arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy> *> + connections_list; + typedef typename connections_list::const_iterator const_iterator; + typedef typename connections_list::iterator iterator; + + _signal_base8() + { + ; + } + + _signal_base8(const _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>& s) + : _signal_base<mt_policy>(s) + { + lock_block<mt_policy> lock(this); + const_iterator it = s.m_connected_slots.begin(); + const_iterator itEnd = s.m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_connect(this); + m_connected_slots.push_back((*it)->clone()); + + ++it; + } + } + + void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == oldtarget) + { + m_connected_slots.push_back((*it)->duplicate(newtarget)); + } + + ++it; + } + } + + ~_signal_base8() + { + disconnect_all(); + } + + void disconnect_all() + { + lock_block<mt_policy> lock(this); + const_iterator it = m_connected_slots.begin(); + const_iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + (*it)->getdest()->signal_disconnect(this); + delete *it; + + ++it; + } + + m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end()); + } + + void disconnect(has_slots<mt_policy>* pclass) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + if((*it)->getdest() == pclass) + { + delete *it; + m_connected_slots.erase(it); + pclass->signal_disconnect(this); + return; + } + + ++it; + } + } + + void slot_disconnect(has_slots<mt_policy>* pslot) + { + lock_block<mt_policy> lock(this); + iterator it = m_connected_slots.begin(); + iterator itEnd = m_connected_slots.end(); + + while(it != itEnd) + { + iterator itNext = it; + ++itNext; + + if((*it)->getdest() == pslot) + { + delete *it; + m_connected_slots.erase(it); + // delete *it; + } + + it = itNext; + } + } + + protected: + connections_list m_connected_slots; + }; + + + template<class dest_type, class mt_policy> + class _connection0 : public _connection_base0<mt_policy> + { + public: + _connection0() + { + this->pobject = NULL; + this->pmemfun = NULL; + } + + _connection0(dest_type* pobject, void (dest_type::*pmemfun)()) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection0() + { + ; + } + + virtual _connection_base0<mt_policy>* clone() + { + return new _connection0<dest_type, mt_policy>(*this); + } + + virtual _connection_base0<mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) + { + return new _connection0<dest_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); + } + + virtual void emit() + { + (m_pobject->*m_pmemfun)(); + } + + virtual has_slots<mt_policy>* getdest() const + { + return m_pobject; + } + + private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(); + }; + + template<class dest_type, class arg1_type, class mt_policy> + class _connection1 : public _connection_base1<arg1_type, mt_policy> + { + public: + _connection1() + { + this->pobject = NULL; + this->pmemfun = NULL; + } + + _connection1(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection1() + { + ; + } + + virtual _connection_base1<arg1_type, mt_policy>* clone() + { + return new _connection1<dest_type, arg1_type, mt_policy>(*this); + } + + virtual _connection_base1<arg1_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) + { + return new _connection1<dest_type, arg1_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); + } + + virtual void emit(arg1_type a1) + { + (m_pobject->*m_pmemfun)(a1); + } + + virtual has_slots<mt_policy>* getdest() const + { + return m_pobject; + } + + private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type); + }; + + template<class dest_type, class arg1_type, class arg2_type, class mt_policy> + class _connection2 : public _connection_base2<arg1_type, arg2_type, mt_policy> + { + public: + _connection2() + { + this->pobject = NULL; + this->pmemfun = NULL; + } + + _connection2(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection2() + { + ; + } + + + virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone() + { + return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>(*this); + } + + virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) + { + return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); + } + + virtual void emit(arg1_type a1, arg2_type a2) + { + (m_pobject->*m_pmemfun)(a1, a2); + } + + virtual has_slots<mt_policy>* getdest() const + { + return m_pobject; + } + + private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type); + }; + + template<class dest_type, class arg1_type, class arg2_type, class arg3_type, class mt_policy> + class _connection3 : public _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy> + { + public: + _connection3() + { + this->pobject = NULL; + this->pmemfun = NULL; + } + + _connection3(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type, arg3_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection3() + { + ; + } + + + virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* clone() + { + return new _connection3<dest_type, arg1_type, arg2_type, arg3_type, mt_policy>(*this); + } + + virtual _connection_base3<arg1_type, arg2_type, arg3_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) + { + return new _connection3<dest_type, arg1_type, arg2_type, arg3_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); + } + + virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3) + { + (m_pobject->*m_pmemfun)(a1, a2, a3); + } + + virtual has_slots<mt_policy>* getdest() const + { + return m_pobject; + } + + private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type); + }; + + template<class dest_type, class arg1_type, class arg2_type, class arg3_type, + class arg4_type, class mt_policy> + class _connection4 : public _connection_base4<arg1_type, arg2_type, + arg3_type, arg4_type, mt_policy> + { + public: + _connection4() + { + this->pobject = NULL; + this->pmemfun = NULL; + } + + _connection4(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection4() + { + ; + } + + virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* clone() + { + return new _connection4<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>(*this); + } + + virtual _connection_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) + { + return new _connection4<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); + } + + virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, + arg4_type a4) + { + (m_pobject->*m_pmemfun)(a1, a2, a3, a4); + } + + virtual has_slots<mt_policy>* getdest() const + { + return m_pobject; + } + + private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, + arg4_type); + }; + + template<class dest_type, class arg1_type, class arg2_type, class arg3_type, + class arg4_type, class arg5_type, class mt_policy> + class _connection5 : public _connection_base5<arg1_type, arg2_type, + arg3_type, arg4_type, arg5_type, mt_policy> + { + public: + _connection5() + { + this->pobject = NULL; + this->pmemfun = NULL; + } + + _connection5(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection5() + { + ; + } + + virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, mt_policy>* clone() + { + return new _connection5<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, mt_policy>(*this); + } + + virtual _connection_base5<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) + { + return new _connection5<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); + } + + virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5) + { + (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5); + } + + virtual has_slots<mt_policy>* getdest() const + { + return m_pobject; + } + + private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type); + }; + + template<class dest_type, class arg1_type, class arg2_type, class arg3_type, + class arg4_type, class arg5_type, class arg6_type, class mt_policy> + class _connection6 : public _connection_base6<arg1_type, arg2_type, + arg3_type, arg4_type, arg5_type, arg6_type, mt_policy> + { + public: + _connection6() + { + this->pobject = NULL; + this->pmemfun = NULL; + } + + _connection6(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type, arg6_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection6() + { + ; + } + + virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, mt_policy>* clone() + { + return new _connection6<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, mt_policy>(*this); + } + + virtual _connection_base6<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) + { + return new _connection6<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); + } + + virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6) + { + (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6); + } + + virtual has_slots<mt_policy>* getdest() const + { + return m_pobject; + } + + private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type); + }; + + template<class dest_type, class arg1_type, class arg2_type, class arg3_type, + class arg4_type, class arg5_type, class arg6_type, class arg7_type, class mt_policy> + class _connection7 : public _connection_base7<arg1_type, arg2_type, + arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, mt_policy> + { + public: + _connection7() + { + this->pobject = NULL; + this->pmemfun = NULL; + } + + _connection7(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, arg7_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection7() + { + ; + } + + virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, mt_policy>* clone() + { + return new _connection7<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, mt_policy>(*this); + } + + virtual _connection_base7<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) + { + return new _connection7<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); + } + + virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6, arg7_type a7) + { + (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7); + } + + virtual has_slots<mt_policy>* getdest() const + { + return m_pobject; + } + + private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type); + }; + + template<class dest_type, class arg1_type, class arg2_type, class arg3_type, + class arg4_type, class arg5_type, class arg6_type, class arg7_type, + class arg8_type, class mt_policy> + class _connection8 : public _connection_base8<arg1_type, arg2_type, + arg3_type, arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy> + { + public: + _connection8() + { + this->pobject = NULL; + this->pmemfun = NULL; + } + + _connection8(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, + arg7_type, arg8_type)) + { + m_pobject = pobject; + m_pmemfun = pmemfun; + } + + virtual ~_connection8() + { + ; + } + + virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* clone() + { + return new _connection8<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>(*this); + } + + virtual _connection_base8<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* duplicate(has_slots<mt_policy>* pnewdest) + { + return new _connection8<dest_type, arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>((dest_type *)pnewdest, m_pmemfun); + } + + virtual void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8) + { + (m_pobject->*m_pmemfun)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + virtual has_slots<mt_policy>* getdest() const + { + return m_pobject; + } + + private: + dest_type* m_pobject; + void (dest_type::* m_pmemfun)(arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, arg8_type); + }; + + template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> + class signal0 : public _signal_base0<mt_policy> + { + public: + typedef typename _signal_base0<mt_policy>::connections_list::const_iterator const_iterator; + signal0() + { + ; + } + + signal0(const signal0<mt_policy>& s) + : _signal_base0<mt_policy>(s) + { + ; + } + + virtual ~signal0() + { + ; + } + + template<class desttype> + void connect(desttype* pclass, void (desttype::*pmemfun)()) + { + lock_block<mt_policy> lock(this); + _connection0<desttype, mt_policy>* conn = + new _connection0<desttype, mt_policy>(pclass, pmemfun); + this->m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void emit() + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(); + + it = itNext; + } + } + + void operator()() + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(); + + it = itNext; + } + } + }; + + template<class arg1_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> + class signal1 : public _signal_base1<arg1_type, mt_policy> + { + public: + typedef typename _signal_base1<arg1_type, mt_policy>::connections_list::const_iterator const_iterator; + signal1() + { + ; + } + + signal1(const signal1<arg1_type, mt_policy>& s) + : _signal_base1<arg1_type, mt_policy>(s) + { + ; + } + + virtual ~signal1() + { + ; + } + + template<class desttype> + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type)) + { + lock_block<mt_policy> lock(this); + _connection1<desttype, arg1_type, mt_policy>* conn = + new _connection1<desttype, arg1_type, mt_policy>(pclass, pmemfun); + this->m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void emit(arg1_type a1) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1); + + it = itNext; + } + } + + void operator()(arg1_type a1) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1); + + it = itNext; + } + } + }; + + template<class arg1_type, typename arg2_type, typename mt_policy = SIGSLOT_DEFAULT_MT_POLICY> + class signal2 : public _signal_base2<arg1_type, arg2_type, mt_policy> + { + public: + typedef typename _signal_base2<arg1_type, arg2_type, mt_policy>::connections_list::const_iterator const_iterator; + signal2() + { + ; + } + + signal2(const signal2<arg1_type, arg2_type, mt_policy>& s) + : _signal_base2<arg1_type, arg2_type, mt_policy>(s) + { + ; + } + + virtual ~signal2() + { + ; + } + + template<class desttype> + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type)) + { + lock_block<mt_policy> lock(this); + _connection2<desttype, arg1_type, arg2_type, mt_policy>* conn = new + _connection2<desttype, arg1_type, arg2_type, mt_policy>(pclass, pmemfun); + this->m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void emit(arg1_type a1, arg2_type a2) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2); + + it = itNext; + } + } + }; + + template<class arg1_type, typename arg2_type, typename arg3_type, typename mt_policy = SIGSLOT_DEFAULT_MT_POLICY> + class signal3 : public _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy> + { + public: + typedef typename _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>::connections_list::const_iterator const_iterator; + signal3() + { + ; + } + + signal3(const signal3<arg1_type, arg2_type, arg3_type, mt_policy>& s) + : _signal_base3<arg1_type, arg2_type, arg3_type, mt_policy>(s) + { + ; + } + + virtual ~signal3() + { + ; + } + + template<class desttype> + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type, arg3_type)) + { + lock_block<mt_policy> lock(this); + _connection3<desttype, arg1_type, arg2_type, arg3_type, mt_policy>* conn = + new _connection3<desttype, arg1_type, arg2_type, arg3_type, mt_policy>(pclass, + pmemfun); + this->m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void emit(arg1_type a1, arg2_type a2, arg3_type a3) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2, a3); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2, arg3_type a3) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2, a3); + + it = itNext; + } + } + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> + class signal4 : public _signal_base4<arg1_type, arg2_type, arg3_type, + arg4_type, mt_policy> + { + public: + typedef typename _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>::connections_list::const_iterator const_iterator; + signal4() + { + ; + } + + signal4(const signal4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>& s) + : _signal_base4<arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>(s) + { + ; + } + + virtual ~signal4() + { + ; + } + + template<class desttype> + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type)) + { + lock_block<mt_policy> lock(this); + _connection4<desttype, arg1_type, arg2_type, arg3_type, arg4_type, mt_policy>* + conn = new _connection4<desttype, arg1_type, arg2_type, arg3_type, + arg4_type, mt_policy>(pclass, pmemfun); + this->m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2, a3, a4); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2, a3, a4); + + it = itNext; + } + } + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, + class arg5_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> + class signal5 : public _signal_base5<arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, mt_policy> + { + public: + typedef typename _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type, arg5_type, mt_policy>::connections_list::const_iterator const_iterator; + signal5() + { + ; + } + + signal5(const signal5<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, mt_policy>& s) + : _signal_base5<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, mt_policy>(s) + { + ; + } + + virtual ~signal5() + { + ; + } + + template<class desttype> + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type)) + { + lock_block<mt_policy> lock(this); + _connection5<desttype, arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, mt_policy>* conn = new _connection5<desttype, arg1_type, arg2_type, + arg3_type, arg4_type, arg5_type, mt_policy>(pclass, pmemfun); + this->m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2, a3, a4, a5); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2, a3, a4, a5); + + it = itNext; + } + } + }; + + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, + class arg5_type, class arg6_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> + class signal6 : public _signal_base6<arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, arg6_type, mt_policy> + { + public: + typedef typename _signal_base6<arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, arg6_type, mt_policy>::connections_list::const_iterator const_iterator; + signal6() + { + ; + } + + signal6(const signal6<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, mt_policy>& s) + : _signal_base6<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, mt_policy>(s) + { + ; + } + + virtual ~signal6() + { + ; + } + + template<class desttype> + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type, arg6_type)) + { + lock_block<mt_policy> lock(this); + _connection6<desttype, arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, mt_policy>* conn = + new _connection6<desttype, arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, arg6_type, mt_policy>(pclass, pmemfun); + this->m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2, a3, a4, a5, a6); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2, a3, a4, a5, a6); + + it = itNext; + } + } + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, + class arg5_type, class arg6_type, class arg7_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> + class signal7 : public _signal_base7<arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, arg6_type, arg7_type, mt_policy> + { + public: + typedef typename _signal_base7<arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>::connections_list::const_iterator const_iterator; + signal7() + { + ; + } + + signal7(const signal7<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, mt_policy>& s) + : _signal_base7<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, mt_policy>(s) + { + ; + } + + virtual ~signal7() + { + ; + } + + template<class desttype> + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, + arg7_type)) + { + lock_block<mt_policy> lock(this); + _connection7<desttype, arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, mt_policy>* conn = + new _connection7<desttype, arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, arg6_type, arg7_type, mt_policy>(pclass, pmemfun); + this->m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6, arg7_type a7) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2, a3, a4, a5, a6, a7); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6, arg7_type a7) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2, a3, a4, a5, a6, a7); + + it = itNext; + } + } + }; + + template<class arg1_type, class arg2_type, class arg3_type, class arg4_type, + class arg5_type, class arg6_type, class arg7_type, class arg8_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY> + class signal8 : public _signal_base8<arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy> + { + public: + typedef typename _signal_base8<arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>::connections_list::const_iterator const_iterator; + signal8() + { + ; + } + + signal8(const signal8<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>& s) + : _signal_base8<arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>(s) + { + ; + } + + virtual ~signal8() + { + ; + } + + template<class desttype> + void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type, + arg2_type, arg3_type, arg4_type, arg5_type, arg6_type, + arg7_type, arg8_type)) + { + lock_block<mt_policy> lock(this); + _connection8<desttype, arg1_type, arg2_type, arg3_type, arg4_type, + arg5_type, arg6_type, arg7_type, arg8_type, mt_policy>* conn = + new _connection8<desttype, arg1_type, arg2_type, arg3_type, + arg4_type, arg5_type, arg6_type, arg7_type, + arg8_type, mt_policy>(pclass, pmemfun); + this->m_connected_slots.push_back(conn); + pclass->signal_connect(this); + } + + void emit(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2, a3, a4, a5, a6, a7, a8); + + it = itNext; + } + } + + void operator()(arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, + arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8) + { + lock_block<mt_policy> lock(this); + const_iterator itNext, it = this->m_connected_slots.begin(); + const_iterator itEnd = this->m_connected_slots.end(); + + while(it != itEnd) + { + itNext = it; + ++itNext; + + (*it)->emit(a1, a2, a3, a4, a5, a6, a7, a8); + + it = itNext; + } + } + }; + +} // namespace sigslot + +#endif // SIGSLOT_H__ + diff --git a/dbx_tree/stdint.h b/dbx_tree/stdint.h new file mode 100644 index 0000000..59d0673 --- /dev/null +++ b/dbx_tree/stdint.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+// Copyright (c) 2006-2008 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. The name of the author may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+# include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+# define _W64 __w64
+# else
+# define _W64
+# endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+ typedef signed char int8_t;
+ typedef signed short int16_t;
+ typedef signed int int32_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+#else
+ typedef signed __int8 int8_t;
+ typedef signed __int16 int16_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int8 uint8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int32 uint32_t;
+#endif
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+ typedef signed __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+#else // _WIN64 ][
+ typedef _W64 signed int intptr_t;
+ typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t intmax_t;
+typedef uint64_t uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN ((int8_t)_I8_MIN)
+#define INT8_MAX _I8_MAX
+#define INT16_MIN ((int16_t)_I16_MIN)
+#define INT16_MAX _I16_MAX
+#define INT32_MIN ((int32_t)_I32_MIN)
+#define INT32_MAX _I32_MAX
+#define INT64_MIN ((int64_t)_I64_MIN)
+#define INT64_MAX _I64_MAX
+#define UINT8_MAX _UI8_MAX
+#define UINT16_MAX _UI16_MAX
+#define UINT32_MAX _UI32_MAX
+#define UINT64_MAX _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN INT8_MIN
+#define INT_FAST8_MAX INT8_MAX
+#define INT_FAST16_MIN INT16_MIN
+#define INT_FAST16_MAX INT16_MAX
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST8_MAX UINT8_MAX
+#define UINT_FAST16_MAX UINT16_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+# define INTPTR_MIN INT64_MIN
+# define INTPTR_MAX INT64_MAX
+# define UINTPTR_MAX UINT64_MAX
+#else // _WIN64 ][
+# define INTPTR_MIN INT32_MIN
+# define INTPTR_MAX INT32_MAX
+# define UINTPTR_MAX UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+# define PTRDIFF_MIN _I64_MIN
+# define PTRDIFF_MAX _I64_MAX
+#else // _WIN64 ][
+# define PTRDIFF_MIN _I32_MIN
+# define PTRDIFF_MAX _I32_MAX
+#endif // _WIN64 ]
+
+#define SIG_ATOMIC_MIN INT_MIN
+#define SIG_ATOMIC_MAX INT_MAX
+
+#ifndef SIZE_MAX // [
+# ifdef _WIN64 // [
+# define SIZE_MAX _UI64_MAX
+# else // _WIN64 ][
+# define SIZE_MAX _UI32_MAX
+# endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+# define WCHAR_MIN 0
+#endif // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+# define WCHAR_MAX _UI16_MAX
+#endif // WCHAR_MAX ]
+
+#define WINT_MIN 0
+#define WINT_MAX _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val) val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val) val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C INT64_C
+#define UINTMAX_C UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/lastseen-mod/file.c b/lastseen-mod/file.c new file mode 100644 index 0000000..8addcc4 --- /dev/null +++ b/lastseen-mod/file.c @@ -0,0 +1,119 @@ +/*
+"Last Seen mod" plugin for Miranda IM
+Copyright ( C ) 2002-03 micron-x
+Copyright ( C ) 2005-07 Y.B.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or ( at your option ) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+File name : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/file.c $
+Revision : $Rev: 1570 $
+Last change on : $Date: 2007-12-30 00:30:07 +0200 (Ð’Ñ, 30 дек 2007) $
+Last change by : $Author: y_b $
+*/
+
+#include "seen.h"
+/*
+Prepares the log file:
+- calculates the absolute path (and store it in the db)
+- creates the directory
+
+*/
+int InitFileOutput(void)
+{
+ char szfpath[256]="",szmpath[256]="",*str;
+ DBVARIANT dbv;
+
+ GetModuleFileName(NULL,szmpath,MAX_PATH);
+ strcpy(szfpath,!DBGetContactSetting(NULL,S_MOD,"FileName",&dbv)?dbv.pszVal:DEFAULT_FILENAME);
+
+ DBFreeVariant(&dbv);
+
+ if(szfpath[0]=='\\')
+ strcpy(szfpath,szfpath+1);
+
+ str=strrchr(szmpath,'\\');
+ if(str!=NULL)
+ *++str=0;
+
+ strcat(szmpath,szfpath);
+
+ strcpy(szfpath,szmpath);
+
+ str=strrchr(szmpath,'\\');
+ if(str!=NULL)
+ *++str=0;
+/*
+//we dont need this anylonger. the directory is created in filewrite
+ if(!CreateDirectory(szmpath,NULL))
+ {
+ if(!(GetFileAttributes(szmpath) & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ MessageBox(NULL,"Directory could not be created\nPlease choose another!","Last seen plugin",MB_OK|MB_ICONERROR);
+ DBWriteContactSettingByte(NULL,S_MOD,"FileOutput",0);
+ return 0;
+ }
+ }
+*/
+ DBWriteContactSettingString(NULL,S_MOD,"PathToFile",szfpath);
+
+ return 0;
+}
+
+//borrowed from netliblog.c
+static void CreateDirectoryTree(char *szDir)
+{
+ DWORD dwAttributes;
+ char *pszLastBackslash,szTestDir[MAX_PATH];
+
+ lstrcpynA(szTestDir,szDir,sizeof(szTestDir));
+ if((dwAttributes=GetFileAttributesA(szTestDir))!=0xffffffff && dwAttributes&FILE_ATTRIBUTE_DIRECTORY) return;
+ pszLastBackslash=strrchr(szTestDir,'\\');
+ if(pszLastBackslash==NULL) return;
+ *pszLastBackslash='\0';
+ CreateDirectoryTree(szTestDir);
+ CreateDirectoryA(szTestDir,NULL);
+}
+
+/*
+Writes a line into the log.
+*/
+void FileWrite(HANDLE hcontact)
+{
+ HANDLE fhout;
+ DWORD byteswritten;
+ char szout[1024],sznl[3]="\r\n";
+ DBVARIANT dbv;
+
+ DBGetContactSetting(NULL,S_MOD,"PathToFile",&dbv);
+ strcpy(szout,ParseString(dbv.pszVal,hcontact,1));
+ fhout=CreateFile(szout,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,0,NULL);
+ if (fhout==INVALID_HANDLE_VALUE){
+ CreateDirectoryTree(szout);
+ fhout=CreateFile(szout,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,0,NULL);
+ if (fhout==INVALID_HANDLE_VALUE) return;
+ }
+ DBFreeVariant(&dbv);
+ SetFilePointer(fhout,0,0,FILE_END);
+
+ strcpy(szout,ParseString(!DBGetContactSetting(NULL,S_MOD,"FileStamp",&dbv)?dbv.pszVal:DEFAULT_FILESTAMP,hcontact,1));
+ DBFreeVariant(&dbv);
+
+ WriteFile(fhout,szout,strlen(szout),&byteswritten,NULL);
+ WriteFile(fhout,sznl,strlen(sznl),&byteswritten,NULL);
+
+ CloseHandle(fhout);
+
+
+}
diff --git a/lastseen-mod/history.c b/lastseen-mod/history.c new file mode 100644 index 0000000..9917d95 --- /dev/null +++ b/lastseen-mod/history.c @@ -0,0 +1,347 @@ +/*
+"Last Seen mod" plugin for Miranda IM
+Copyright ( C ) 2002-03 micron-x
+Copyright ( C ) 2005-06 Y.B.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or ( at your option ) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+File name : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/history.c $
+Revision : $Rev: 1056 $
+Last change on : $Date: 2006-10-30 05:22:07 +0200 (Пн, 30 окт 2006) $
+Last change by : $Author: y_b $
+*/
+#include "seen.h"
+
+
+extern HINSTANCE hInstance;
+
+static HANDLE hWindowList;
+
+char* BuildSetting(int historyLast) {
+ static char setting[15];
+ static char sztemp[15];
+ *setting = '\0';
+ strcat(setting, "History_");
+ strcat(setting, itoa(historyLast, sztemp, 10));
+ return setting;
+}
+
+void HistoryWrite(HANDLE hContact)
+{
+ short historyFirst, historyLast, historyMax;
+ DBVARIANT dbv;
+
+ historyMax = DBGetContactSettingWord(NULL,S_MOD,"HistoryMax",10);
+ if (historyMax < 0) historyMax=0; else if (historyMax > 99) historyMax = 99;
+ if (historyMax == 0) return;
+ historyFirst = DBGetContactSettingWord(hContact,S_MOD,"HistoryFirst",0);
+ if (historyFirst >= historyMax) historyFirst = 0;
+ historyLast = DBGetContactSettingWord(hContact,S_MOD,"HistoryLast",0);
+ if (historyLast >= historyMax) historyLast = historyMax-1;
+
+ DBWriteContactSettingString(hContact,S_MOD,BuildSetting(historyLast),
+ ParseString(!DBGetContactSetting(NULL,S_MOD,"HistoryStamp",&dbv)?dbv.pszVal:DEFAULT_HISTORYSTAMP,hContact,0));
+ DBFreeVariant(&dbv);
+
+ historyLast = (historyLast+1) % historyMax;
+ DBWriteContactSettingWord(hContact,S_MOD,"HistoryLast",historyLast);
+ if (historyLast == historyFirst) {
+ DBWriteContactSettingWord(hContact,S_MOD,"HistoryFirst",(short) ((historyFirst+1) % historyMax));
+ }
+
+}
+
+void LoadHistoryList(HANDLE hContact, HWND hwnd, int nList) {
+ short historyFirst, historyLast, historyMax;
+ short i;
+ DBVARIANT dbv;
+
+
+ SendDlgItemMessage(hwnd, nList, LB_RESETCONTENT, 0, 0);
+ historyMax = DBGetContactSettingWord(NULL,S_MOD,"HistoryMax",10);
+ if (historyMax < 0) historyMax = 0; else if (historyMax > 99) historyMax = 99;
+ if (historyMax == 0) return;
+ historyFirst = DBGetContactSettingWord(hContact,S_MOD,"HistoryFirst",0);
+ if (historyFirst >= historyMax) historyFirst = 0;
+ historyLast = DBGetContactSettingWord(hContact,S_MOD,"HistoryLast",0);
+ if (historyLast >= historyMax) historyLast = historyMax-1;
+
+ i = historyLast;
+ while (i != historyFirst) {
+ i = (i-1+historyMax) % historyMax;
+ SendDlgItemMessage(hwnd, nList, LB_ADDSTRING, 0,
+ (LPARAM)(!DBGetContactSetting(hContact,S_MOD,BuildSetting(i),&dbv)?dbv.pszVal:""));
+ DBFreeVariant(&dbv);
+ }
+
+}
+
+
+HDWP MyResizeWindow (HDWP hDwp, HWND hwndDlg, HWND hwndControl,
+ int nHorizontalOffset, int nVerticalOffset,
+ int nWidthOffset, int nHeightOffset)
+{
+ POINT pt;
+ RECT rcinit;
+
+ // get current bounding rectangle
+ GetWindowRect(hwndControl, &rcinit);
+
+ // get current top left point
+ pt.x = rcinit.left;
+ pt.y = rcinit.top;
+ ScreenToClient(hwndDlg, &pt);
+
+ // resize control
+/* MoveWindow(hwndControl,
+ pt.x + nHorizontalOffset,
+ pt.y + nVerticalOffset,
+ rcinit.right - rcinit.left + nWidthOffset,
+ rcinit.bottom - rcinit.top + nHeightOffset,
+ FALSE);
+*/
+ return DeferWindowPos(hDwp, hwndControl, NULL,
+ pt.x + nHorizontalOffset,
+ pt.y + nVerticalOffset,
+ rcinit.right - rcinit.left + nWidthOffset,
+ rcinit.bottom - rcinit.top + nHeightOffset,
+ SWP_NOZORDER);
+
+
+}
+
+HDWP MyHorizCenterWindow (HDWP hDwp, HWND hwndDlg, HWND hwndControl,
+ int nClientWidth, int nVerticalOffset,
+ int nHeightOffset)
+{
+ POINT pt;
+ RECT rcinit;
+
+ // get current bounding rectangle
+ GetWindowRect(hwndControl, &rcinit);
+
+ // get current top left point
+ pt.x = rcinit.left;
+ pt.y = rcinit.top;
+ ScreenToClient(hwndDlg, &pt);
+
+ // resize control
+/* MoveWindow(hwndControl,
+ (int) ((nClientWidth - (rcinit.right - rcinit.left))/2),
+ pt.y + nVerticalOffset,
+ rcinit.right - rcinit.left,
+ rcinit.bottom - rcinit.top + nHeightOffset,
+ TRUE);
+*/
+ return DeferWindowPos(hDwp, hwndControl, NULL,
+ (int) ((nClientWidth - (rcinit.right - rcinit.left))/2),
+ pt.y + nVerticalOffset,
+ rcinit.right - rcinit.left,
+ rcinit.bottom - rcinit.top + nHeightOffset,
+ SWP_NOZORDER);
+
+}
+void MyResizeGetOffset (HWND hwndDlg, HWND hwndControl,
+ int nWidth, int nHeight,
+ int* nDx, int* nDy)
+{
+ RECT rcinit;
+
+ // get current bounding rectangle
+ GetWindowRect(hwndControl, &rcinit);
+
+ // calculate offsets
+ *nDx = nWidth - (rcinit.right - rcinit.left);
+ *nDy = nHeight - (rcinit.bottom - rcinit.top);
+}
+
+BOOL CALLBACK HistoryDlgProc(HWND hwndDlg, UINT Message, WPARAM wparam, LPARAM lparam)
+{
+ HANDLE hContact;
+ char sztemp[1024]="";
+ static HIMAGELIST hIml=NULL;
+
+ switch(Message)
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ hContact = (HANDLE)lparam;
+ SetWindowLong(hwndDlg,GWL_USERDATA,lparam);
+ strcpy(sztemp,(char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0));
+ strcat(sztemp, ": ");
+ strcat(sztemp, Translate("last seen history"));
+ SendMessage(hwndDlg, WM_SETTEXT, 0, (LPARAM)sztemp);
+ SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) LoadSkinnedIcon(SKINICON_OTHER_MIRANDA));
+ SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_SMALL, (LPARAM) LoadSkinnedIcon(SKINICON_OTHER_MIRANDA));
+
+// LoadHistoryList(hContact, hwndDlg, IDC_HISTORYLIST);
+
+ if (DBGetContactSettingByte(hContact,S_MOD,"OnlineAlert",0))
+ SendDlgItemMessage(hwndDlg, IDC_STATUSCHANGE, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
+ {
+ hIml=ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLOR32|ILC_MASK,3,3);
+ ImageList_AddIcon(hIml,LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_USERDETAILS)));
+ ImageList_AddIcon(hIml,LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_DOWNARROW)));
+ ImageList_AddIcon(hIml,LoadSkinnedIcon(SKINICON_EVENT_MESSAGE));
+ SendDlgItemMessage(hwndDlg,IDC_DETAILS,BM_SETIMAGE,IMAGE_ICON,(WPARAM)ImageList_GetIcon(hIml,0,ILD_NORMAL));
+ SendDlgItemMessage(hwndDlg,IDC_USERMENU,BM_SETIMAGE,IMAGE_ICON,(WPARAM)ImageList_GetIcon(hIml,1,ILD_NORMAL));
+ SendDlgItemMessage(hwndDlg,IDC_SENDMSG,BM_SETIMAGE,IMAGE_ICON,(WPARAM)ImageList_GetIcon(hIml,2,ILD_NORMAL));
+ }
+
+ //set-up tooltips
+ {
+ HWND hwndDlgToolTips;
+ TOOLINFO ti;
+
+ hwndDlgToolTips = CreateWindowEx(WS_EX_TOPMOST,TOOLTIPS_CLASS,"",WS_POPUP,0,0,0,0,NULL,NULL,GetModuleHandle(NULL),NULL);
+ ZeroMemory(&ti,sizeof(ti));
+ ti.cbSize=sizeof(ti);
+ ti.uFlags=TTF_IDISHWND|TTF_SUBCLASS;
+ ti.uId=(UINT)GetDlgItem(hwndDlg,IDC_USERMENU);
+ ti.lpszText=Translate("User Menu");
+ SendMessage(hwndDlgToolTips,TTM_ADDTOOL,0,(LPARAM)&ti);
+ ti.uId=(UINT)GetDlgItem(hwndDlg,IDC_DETAILS);
+ ti.lpszText=Translate("View User's Details");
+ SendMessage(hwndDlgToolTips,TTM_ADDTOOL,0,(LPARAM)&ti);
+ ti.uId=(UINT)GetDlgItem(hwndDlg,IDC_SENDMSG);
+ ti.lpszText=Translate("Send Instant Message");
+ SendMessage(hwndDlgToolTips,TTM_ADDTOOL,0,(LPARAM)&ti);
+ }
+
+
+ Utils_RestoreWindowPositionNoMove(hwndDlg,NULL,S_MOD,"History_");
+ ShowWindow(hwndDlg, SW_SHOW);
+ break;
+
+ case WM_MEASUREITEM:
+ return CallService(MS_CLIST_MENUMEASUREITEM,wparam,lparam);
+ case WM_DRAWITEM:
+ return CallService(MS_CLIST_MENUDRAWITEM,wparam,lparam);
+ case WM_COMMAND:
+ hContact=(HANDLE)GetWindowLong(hwndDlg,GWL_USERDATA);
+ if(CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wparam),MPCF_CONTACTMENU),(LPARAM)hContact))
+ break;
+ switch(LOWORD(wparam))
+ {
+ case IDCANCEL:
+ SendMessage(hwndDlg, WM_CLOSE, 0, 0);
+ break;
+ case IDOK:
+ if (SendDlgItemMessage(hwndDlg, IDC_STATUSCHANGE, BM_GETCHECK, 0, 0) == BST_CHECKED)
+ DBWriteContactSettingByte(hContact,S_MOD,"OnlineAlert",1);
+ else
+ DBWriteContactSettingByte(hContact,S_MOD,"OnlineAlert",0);
+ SendMessage(hwndDlg, WM_CLOSE, 0, 0);
+ break;
+ case IDC_USERMENU:
+ {
+ RECT rc;
+ HMENU hMenu=(HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)hContact,0);
+ GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU),&rc);
+ TrackPopupMenu(hMenu,0,rc.left,rc.bottom,0,hwndDlg,NULL);
+ DestroyMenu(hMenu);
+ }
+ break;
+ case IDC_DETAILS:
+ CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)hContact,0);
+ break;
+ case IDC_SENDMSG:
+ CallService(MS_MSG_SENDMESSAGE,(WPARAM)hContact,0);
+ break;
+ case IDC_TEST:
+ debug(ParseString("Date: %d.%m.%y(%Y) \n Date desc: %W - %w - %E - %e \n Time: %H:%M:%S (%h-%p) \n user: %n - %u \n Status: %s \n IP: %i - %r",hContact,0));
+ break;
+ }
+ break;
+ case WM_SIZE:
+ {
+ int dx, dy;
+ HDWP hDwp;
+
+ hDwp = BeginDeferWindowPos(6);
+ MyResizeGetOffset(hwndDlg, GetDlgItem(hwndDlg, IDC_HISTORYLIST),
+ LOWORD(lparam)-15, HIWORD(lparam)-99, &dx, &dy);
+ hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_USERMENU),
+ dx, 0, 0, 0);
+ hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_DETAILS),
+ dx, 0, 0, 0);
+ hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_SENDMSG),
+ dx, 0, 0, 0);
+ hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_HISTORYLIST),
+ 0, 0, dx, dy);
+ hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_STATUSCHANGE),
+ 0, dy, dx, 0);
+ hDwp = MyHorizCenterWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDOK),
+ LOWORD(lparam), dy, 0);
+ EndDeferWindowPos(hDwp);
+ }
+ break;
+ case WM_GETMINMAXINFO:
+ {
+ MINMAXINFO mmi;
+ CopyMemory (&mmi, (LPMINMAXINFO) lparam, sizeof (MINMAXINFO));
+
+ /* The minimum width in points*/
+ mmi.ptMinTrackSize.x = 200;
+ /* The minimum height in points*/
+ mmi.ptMinTrackSize.y = 190;
+
+ CopyMemory ((LPMINMAXINFO) lparam, &mmi, sizeof (MINMAXINFO));
+ }
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow(hwndDlg);
+ WindowList_Remove(hWindowList,hwndDlg);
+ break;
+ case WM_DESTROY:
+ Utils_SaveWindowPosition(hwndDlg,NULL,S_MOD,"History_");
+ ImageList_Destroy(hIml);
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void ShowHistory(HANDLE hContact, BYTE isAlert)
+{
+ HWND hHistoryDlg;
+
+ hHistoryDlg = WindowList_Find(hWindowList,hContact);
+ if (hHistoryDlg == NULL)
+ {
+ hHistoryDlg = CreateDialogParam(hInstance,MAKEINTRESOURCE(IDD_HISTORY),NULL,HistoryDlgProc,(LPARAM)hContact);
+ LoadHistoryList(hContact, hHistoryDlg, IDC_HISTORYLIST);
+ WindowList_Add(hWindowList,hHistoryDlg,hContact);
+ }
+ else
+ {
+ SetForegroundWindow(hHistoryDlg);
+ LoadHistoryList(hContact, hHistoryDlg, IDC_HISTORYLIST);
+ SetFocus(hHistoryDlg);
+ }
+
+ if (isAlert)
+ {
+ SkinPlaySound("LastSeenTrackedStatusChange");
+ }
+}
+
+
+void InitHistoryDialog(void)
+{
+ hWindowList=(HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST,0,0);
+}
diff --git a/lastseen-mod/main.c b/lastseen-mod/main.c new file mode 100644 index 0000000..362bad1 --- /dev/null +++ b/lastseen-mod/main.c @@ -0,0 +1,191 @@ +/*
+"Last Seen mod" plugin for Miranda IM
+Copyright ( C ) 2002-03 micron-x
+Copyright ( C ) 2005-07 Y.B.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or ( at your option ) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+File name : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/main.c $
+Revision : $Rev: 1571 $
+Last change on : $Date: 2007-12-30 03:55:51 +0200 (Ð’Ñ, 30 дек 2007) $
+Last change by : $Author: y_b $
+*/
+#include "seen.h"
+
+
+HINSTANCE hInstance;
+HANDLE ehdb=NULL,ehproto=NULL,ehmissed=NULL,ehuserinfo=NULL,ehmissed_proto=NULL;
+PLUGINLINK *pluginLink;
+char authemail[] = "fscking@spammer.oip.info";//the correct e-mail shall be constructed in DllMain
+PLUGININFOEX pluginInfo={
+ sizeof(PLUGININFOEX),
+#ifndef PERMITNSN
+ "Last seen plugin mod",
+#else
+ "Last seen plugin mod (NSNCompat)",
+#endif
+ PLUGIN_MAKE_VERSION(5,0,4,7),
+ "Log when a user was last seen online and which users were online while you were away",
+ "Heiko Schillinger, YB",
+ authemail,
+ "© 2001-2002 Heiko Schillinger, 2003 modified by Bruno Rino, 2005-7 Modified by YB",
+ "http://forums.miranda-im.org/showthread.php?t=2822",
+ 0,
+#ifndef PERMITNSN
+ DEFMOD_RNDUSERONLINE,
+ { 0x0beac488,0x578d,0x458d,{0xbb, 0x93, 0x8f, 0x2f, 0x53, 0x9b, 0x2a, 0xe4}}/* 0beac488-578d-458d-bb93-8f2f539b2ae4 */
+#else
+ 0,
+ { 0x2d506d46,0xc94e,0x4ef8,{0x85, 0x37, 0xf1, 0x12, 0x33, 0xa8, 0x03, 0x81}}/* 2d506d46-c94e-4ef8-8537-f11233a80381 */
+#endif
+};
+
+#define TRANSNUMBER 2
+DBVTranslation idleTr[TRANSNUMBER]={
+ {(TranslateFunc*)any_to_IdleNotidleUnknown, L"Any to Idle/Not Idle/Unknown",0},
+ {(TranslateFunc*)any_to_Idle, L"Any to /Idle or empty",0}
+};
+
+
+
+int OptionsInit(WPARAM,LPARAM);
+int UserinfoInit(WPARAM,LPARAM);
+int InitFileOutput(void);
+void InitMenuitem(void);
+int UpdateValues(WPARAM,LPARAM);
+int ModeChange(WPARAM,LPARAM);
+//int GetInfoAck(WPARAM,LPARAM);
+void SetOffline(void);
+int ModeChange_mo(WPARAM,LPARAM);
+int CheckIfOnline(void);
+
+BOOL includeIdle;
+logthread_info **contactQueue = NULL;
+int contactQueueSize = 0;
+
+
+int MainInit(WPARAM wparam,LPARAM lparam)
+{
+ contactQueueSize = 16*sizeof(logthread_info *);
+ contactQueue = (logthread_info **)malloc(contactQueueSize);
+ memset(&contactQueue[0], 0, contactQueueSize);
+ contactQueueSize = 16;
+ includeIdle = (BOOL )DBGetContactSettingByte(NULL,S_MOD,"IdleSupport",1);
+ HookEvent(ME_OPT_INITIALISE,OptionsInit);
+
+ if(DBGetContactSettingByte(NULL,S_MOD,"MenuItem",1)) {
+ InitMenuitem();
+ }
+
+ if(DBGetContactSettingByte(NULL,S_MOD,"UserinfoTab",1))
+ ehuserinfo=HookEvent(ME_USERINFO_INITIALISE,UserinfoInit);
+
+ if(DBGetContactSettingByte(NULL,S_MOD,"FileOutput",0))
+ InitFileOutput();
+
+ if(DBGetContactSettingByte(NULL,S_MOD,"MissedOnes",0))
+ ehmissed_proto=HookEvent(ME_PROTO_ACK,ModeChange_mo);
+
+// SetOffline();
+
+ ehdb=HookEvent(ME_DB_CONTACT_SETTINGCHANGED,UpdateValues);
+ ehproto=HookEvent(ME_PROTO_ACK,ModeChange);
+
+ SkinAddNewSoundEx("LastSeenTrackedStatusChange",Translate("LastSeen"),Translate("User status change"));
+ SkinAddNewSoundEx("LastSeenTrackedStatusOnline",Translate("LastSeen"),Translate("Changed to Online"));
+ SkinAddNewSoundEx("LastSeenTrackedStatusOffline",Translate("LastSeen"),Translate("User Logged Off"));
+ SkinAddNewSoundEx("LastSeenTrackedStatusFromOffline",Translate("LastSeen"),Translate("User Logged In"));
+ // known modules list
+ if (ServiceExists("DBEditorpp/RegisterSingleModule"))
+ CallService("DBEditorpp/RegisterSingleModule", (WPARAM)S_MOD, 0);
+ DBWriteContactSettingString(NULL,"Uninstall",Translate("Last seen"),S_MOD);
+
+#ifndef PERMITNSN
+ SkinAddNewSoundEx("UserOnline",Translate("Alerts"),Translate("Online"));
+#endif
+ if (ServiceExists(MS_TIPPER_ADDTRANSLATION)){
+ int i=0;
+ for (i=0;i<TRANSNUMBER;i++){
+ CallService(MS_TIPPER_ADDTRANSLATION,0,(LPARAM)&idleTr[i]);
+ }
+ }
+
+ return 0;
+}
+
+__declspec(dllexport) PLUGININFOEX * MirandaPluginInfo(DWORD mirandaVersion)
+{
+ if ( mirandaVersion < PLUGIN_MAKE_VERSION(0,5,2,0)) {
+ MessageBox( NULL, _T("The LastSeen-mod plugin cannot be loaded. Your Miranda is too old."), _T("SeenPlugin"), MB_OK|MB_ICONWARNING|MB_SETFOREGROUND|MB_TOPMOST );
+ return NULL;
+ }
+ if ( mirandaVersion < PLUGIN_MAKE_VERSION( 0,7,0,17 )) pluginInfo.cbSize = sizeof( PLUGININFO );
+ return &pluginInfo;
+}
+
+__declspec(dllexport) PLUGININFOEX * MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ pluginInfo.cbSize = sizeof( PLUGININFOEX );
+ return &pluginInfo;
+}
+
+#define MIID_LASTSEEN {0x0df23e71, 0x7950, 0x43d5, {0xb9, 0x86, 0x7a, 0xbf, 0xf5, 0xa5, 0x40, 0x18}}
+static const MUUID interfaces[] = {MIID_LASTSEEN,
+#ifndef PERMITNSN
+MIID_USERONLINE,
+#endif
+MIID_LAST};
+__declspec(dllexport) const MUUID * MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+__declspec(dllexport)int Unload(void)
+{
+ UnhookEvent(ehdb);
+ if(ehmissed!=NULL) UnhookEvent(ehmissed);
+ UnhookEvent(ehproto);
+ if(ehmissed_proto)UnhookEvent(ehmissed_proto);
+// free(contactQueue);
+ return 0;
+}
+
+
+
+BOOL WINAPI DllMain(HINSTANCE hinst,DWORD fdwReason,LPVOID lpvReserved)
+{
+ memcpy(pluginInfo.authorEmail,"y_b@saaplugin.no-",17);
+ hInstance=hinst;
+ return 1;
+}
+
+
+
+int __declspec(dllexport)Load(PLUGINLINK *link)
+{
+ pluginLink=link;
+ // this isn't required for most events
+ // but the ME_USERINFO_INITIALISE
+ // I decided to hook all events after
+ // everything is loaded because it seems
+ // to be safer in my opinion
+ HookEvent(ME_SYSTEM_MODULESLOADED,MainInit);
+ return 0;
+}
+
+
+
+
+
diff --git a/lastseen-mod/menu.c b/lastseen-mod/menu.c new file mode 100644 index 0000000..ff6540c --- /dev/null +++ b/lastseen-mod/menu.c @@ -0,0 +1,112 @@ +/*
+"Last Seen mod" plugin for Miranda IM
+Copyright ( C ) 2002-03 micron-x
+Copyright ( C ) 2005-07 Y.B.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or ( at your option ) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+File name : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/menu.c $
+Revision : $Rev: 1570 $
+Last change on : $Date: 2007-12-30 00:30:07 +0200 (Ð’Ñ, 30 дек 2007) $
+Last change by : $Author: y_b $
+*/
+#include "seen.h"
+
+HANDLE hmenuitem=NULL;
+
+void ShowHistory(HANDLE hContact, BYTE isAlert);
+void InitHistoryDialog(void);
+
+/*
+Handles the messages sent by clicking the contact's menu item
+*/
+int MenuitemClicked(WPARAM wparam,LPARAM lparam)
+{
+ ShowHistory((HANDLE)wparam, 0);
+ return 0;
+}
+
+
+
+int BuildContactMenu(WPARAM wparam,LPARAM lparam)
+{
+ CLISTMENUITEM cmi;
+ DBVARIANT dbv;
+ int id=-1,isetting;
+ HANDLE hContact;
+ char *szProto;
+
+ hContact = (HANDLE)wparam;
+ szProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0);
+
+
+ ZeroMemory(&cmi,sizeof(cmi));
+ cmi.cbSize=sizeof(cmi);
+ if(!IsWatchedProtocol(szProto) || !DBGetContactSettingByte(NULL,S_MOD,"MenuItem",1))
+ {
+ cmi.flags=CMIM_FLAGS|CMIF_HIDDEN;
+ }
+ else
+ {
+ cmi.flags=CMIM_NAME|CMIM_FLAGS|CMIM_ICON;
+ cmi.hIcon=NULL;
+ cmi.pszName=ParseString(!DBGetContactSetting(NULL,S_MOD,"MenuStamp",&dbv)?dbv.pszVal:DEFAULT_MENUSTAMP,(HANDLE)wparam,0);
+
+ if(!strcmp(cmi.pszName,Translate("<unknown>")))
+ {
+ if (IsWatchedProtocol(szProto))
+ cmi.flags|=CMIF_GRAYED;
+ else
+ cmi.flags|=CMIF_HIDDEN;
+ }
+ else if(DBGetContactSettingByte(NULL,S_MOD,"ShowIcon",1))
+ {
+ isetting=DBGetContactSettingWord((HANDLE)hContact,S_MOD,"StatusTriger",-1);
+ cmi.hIcon=LoadSkinnedProtoIcon(szProto,isetting|0x8000);
+
+ }
+ }
+
+ CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hmenuitem,(LPARAM)&cmi);
+ DBFreeVariant(&dbv);
+
+
+ return 0;
+}
+
+
+
+void InitMenuitem(void)
+{
+ CLISTMENUITEM cmi;
+
+ CreateServiceFunction("LastSeenUserDetails",MenuitemClicked);
+
+ ZeroMemory(&cmi,sizeof(cmi));
+ cmi.cbSize=sizeof(cmi);
+ cmi.flags=0;
+ cmi.hIcon=NULL;
+ cmi.hotKey=0;
+ cmi.position=-0x7FFFFFFF;
+ cmi.pszContactOwner=NULL;
+ cmi.pszName="<none>";
+ cmi.pszService="LastSeenUserDetails";
+
+ hmenuitem=(HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&cmi);
+
+ HookEvent(ME_CLIST_PREBUILDCONTACTMENU,BuildContactMenu);
+
+ InitHistoryDialog();
+}
diff --git a/lastseen-mod/missed.c b/lastseen-mod/missed.c new file mode 100644 index 0000000..05d72a0 --- /dev/null +++ b/lastseen-mod/missed.c @@ -0,0 +1,301 @@ +/*
+"Last Seen mod" plugin for Miranda IM
+Copyright ( C ) 2002-03 micron-x
+Copyright ( C ) 2005-07 Y.B.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or ( at your option ) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+File name : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/missed.c $
+Revision : $Rev: 1570 $
+Last change on : $Date: 2007-12-30 00:30:07 +0200 (Ð’Ñ, 30 дек 2007) $
+Last change by : $Author: y_b $
+*/
+#include "seen.h"
+
+#include <m_ignore.h>
+
+
+
+MISSEDCONTACTS mcs;
+extern HANDLE ehmissed;
+extern HINSTANCE hInstance;
+
+
+
+WPARAM IsUserMissed(WPARAM contact)
+{
+ int loop=0;
+
+ for(;loop<mcs.count;loop++)
+ {
+ if(mcs.wpcontact[loop]==contact)
+ return MAKEWPARAM(1,loop);
+ }
+
+ return 0;
+}
+
+
+
+int RemoveUser(int pos)
+{
+ int loop;
+
+ for(loop=pos;loop<mcs.count-1;loop++)
+ mcs.wpcontact[loop]=mcs.wpcontact[loop+1];
+
+ mcs.count--;
+
+ return 0;
+}
+
+
+
+int ResetMissed(void)
+{
+ HANDLE hcontact=NULL;
+
+ hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ while(hcontact!=NULL)
+ {
+ DBWriteContactSettingByte(hcontact,S_MOD,"Missed",0);
+ hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hcontact,0);
+ }
+
+ ZeroMemory(&mcs,sizeof(mcs));
+
+ return 0;
+}
+
+
+int CheckIfOnline(void)
+{
+ HANDLE hcontact;
+// char *szProto;
+// WORD status;
+
+ hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ while(hcontact!=NULL)
+ {
+/* szProto=(char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hcontact,0);
+ status=(szProto==NULL)?ID_STATUS_OFFLINE:DBGetContactSettingWord(hcontact,szProto,"Status",ID_STATUS_OFFLINE);
+ if(status!=ID_STATUS_OFFLINE)
+*/
+ if(CallService(MS_CLIST_GETCONTACTICON,(WPARAM)hcontact,0)!=ICON_OFFLINE)
+ DBWriteContactSettingByte(hcontact,S_MOD,"Missed",2);
+
+ hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hcontact,0);
+ }
+
+ return 0;
+}
+
+
+
+BOOL CALLBACK MissedDlgProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
+{
+ POINT pt;
+ RECT rcinit,rcresized,rcb,rcd;
+ HWND htemp;
+
+ switch(msg){
+
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hdlg);
+
+ htemp=GetDlgItem(hdlg,IDC_CONTACTS);
+ GetWindowRect(htemp,&rcinit);
+ SetWindowPos(htemp,NULL,0,0,rcinit.right-rcinit.left,mcs.count*(rcinit.bottom-rcinit.top)/2,SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
+ GetWindowRect(htemp,&rcresized);
+
+ htemp=GetDlgItem(hdlg,IDOK);
+ GetWindowRect(htemp,&rcb);
+ pt.x=rcb.left;
+ pt.y=rcb.top;
+
+ ScreenToClient(hdlg,&pt);
+ MoveWindow(htemp,pt.x,pt.y+(rcresized.bottom-rcinit.bottom),(rcb.right-rcb.left),(rcb.bottom-rcb.top),FALSE);
+ GetWindowRect(hdlg,&rcd);
+ SetWindowPos(hdlg,NULL,0,0,rcd.right-rcd.left,rcd.bottom-rcd.top+(rcresized.bottom-rcinit.bottom),SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
+
+ SetDlgItemText(hdlg,IDC_CONTACTS,(LPCSTR)lparam);
+ ShowWindow(hdlg,SW_SHOWNOACTIVATE);
+ break;
+
+ case WM_CLOSE:
+ EndDialog(hdlg,0);
+ break;
+
+ case WM_COMMAND:
+ if(LOWORD(wparam)==IDOK)
+ SendMessage(hdlg,WM_CLOSE,0,0);
+ break;
+ }
+
+ return 0;
+}
+
+
+
+
+int ShowMissed(void)
+{
+ int loop=0;
+ char sztemp[1024]="",szcount[7];
+
+ if(!mcs.count) return 0;
+
+ for(;loop<mcs.count;loop++)
+ {
+ strcat(sztemp,(const char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,mcs.wpcontact[loop],0));
+ if(DBGetContactSettingByte(NULL,S_MOD,"MissedOnes_Count",0))
+ {
+ wsprintf(szcount," [%i]",mcs.times[loop]);
+ strcat(sztemp,szcount);
+ }
+
+ strcat(sztemp,"\n");
+ }
+
+ CreateDialogParam(hInstance,MAKEINTRESOURCE(IDD_MISSED),NULL,MissedDlgProc,(LPARAM)&sztemp[0]);
+
+ return 0;
+}
+
+/*
+
+int LogStatus(WPARAM wparam,LPARAM lparam)
+{
+ DBCONTACTWRITESETTING *cws;
+ WPARAM wpvar;
+
+ cws=(DBCONTACTWRITESETTING *)lparam;
+
+ if(strcmp(cws->szSetting,"Status") || (strcmp(cws->szModule,"ICQ") && strcmp(cws->szModule,"MSN")) || (HANDLE)wparam==NULL) return 0;
+
+ if(CallService(MS_IGNORE_ISIGNORED,wparam,IGNOREEVENT_USERONLINE))
+ return 0;
+
+ if(cws->value.wVal==ID_STATUS_OFFLINE)
+ {
+ if(DBGetContactSettingByte((HANDLE)wparam,S_MOD,"Missed",0)==1)
+ {
+ mcs.times[mcs.count]++;
+ mcs.wpcontact[mcs.count++]=wparam;
+ DBWriteContactSettingByte((HANDLE)wparam,S_MOD,"Missed",0);
+ }
+
+ else if(DBGetContactSettingByte((HANDLE)wparam,S_MOD,"Missed",0)==3)
+ mcs.times[HIWORD(IsUserMissed(wparam))]++;
+
+ return 0;
+ }
+
+ wpvar=IsUserMissed(wparam);
+ if(LOWORD(wpvar))
+ DBWriteContactSettingByte((HANDLE)wparam,S_MOD,"Missed",3);
+
+ else
+ DBWriteContactSettingByte((HANDLE)wparam,S_MOD,"Missed",1);
+
+ return 0;
+}
+
+*/
+
+int Test(WPARAM wparam,LPARAM lparam)
+{
+ if(lparam<ICON_OFFLINE || lparam>ICON_INVIS)
+ return 0;
+
+ if(CallService(MS_IGNORE_ISIGNORED,wparam,IGNOREEVENT_USERONLINE))
+ return 0;
+
+ if(DBGetContactSettingByte((HANDLE)wparam,S_MOD,"Missed",0)==2)
+ return 0;
+
+ switch(lparam){
+
+ case ICON_OFFLINE:
+ if(DBGetContactSettingByte((HANDLE)wparam,S_MOD,"Missed",0)==1)
+ {
+ WORD missed=IsUserMissed(wparam);
+
+ if(!LOWORD(missed))
+ {
+ mcs.times[mcs.count]=1;
+ mcs.wpcontact[mcs.count++]=wparam;
+ }
+ else
+ mcs.times[HIWORD(missed)]++;
+
+ DBWriteContactSettingByte((HANDLE)wparam,S_MOD,"Missed",0);
+ }
+ break;
+
+ case ICON_ONLINE:
+ case ICON_AWAY:
+ case ICON_NA:
+ case ICON_OCC:
+ case ICON_DND:
+ case ICON_FREE:
+ case ICON_INVIS:
+ DBWriteContactSettingByte((HANDLE)wparam,S_MOD,"Missed",1);
+ break;
+ }
+
+ return 0;
+}
+
+
+
+int ModeChange_mo(WPARAM wparam,LPARAM lparam)
+{
+ ACKDATA *ack;
+ int isetting=0;
+
+ ack=(ACKDATA *)lparam;
+
+ if(ack->type!=ACKTYPE_STATUS || ack->result!=ACKRESULT_SUCCESS || ack->hContact!=NULL) return 0;
+
+ isetting=CallProtoService(ack->szModule,PS_GETSTATUS,0,0);
+
+ switch(isetting){
+
+ case ID_STATUS_AWAY:
+ case ID_STATUS_DND:
+ case ID_STATUS_NA:
+ if(ehmissed==NULL)
+ {
+ ZeroMemory(&mcs,sizeof(mcs));
+ CheckIfOnline();
+ //ehmissed=HookEvent(ME_DB_CONTACT_SETTINGCHANGED,LogStatus);
+ ehmissed=HookEvent(ME_CLIST_CONTACTICONCHANGED,Test);
+ }
+ break;
+
+ default:
+ if(ehmissed!=NULL)
+ {
+ UnhookEvent(ehmissed);
+ ehmissed=NULL;
+ ShowMissed();
+ ResetMissed();
+ }
+ break;
+ }
+
+ return 0;
+}
diff --git a/lastseen-mod/options.c b/lastseen-mod/options.c new file mode 100644 index 0000000..d4fbda6 --- /dev/null +++ b/lastseen-mod/options.c @@ -0,0 +1,608 @@ +/*
+"Last Seen mod" plugin for Miranda IM
+Copyright ( C ) 2002-03 micron-x
+Copyright ( C ) 2005-07 Y.B.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or ( at your option ) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+File name : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/options.c $
+Revision : $Rev: 1570 $
+Last change on : $Date: 2007-12-30 00:30:07 +0200 (Ð’Ñ, 30 дек 2007) $
+Last change by : $Author: y_b $
+*/
+#include "seen.h"
+
+
+
+extern HINSTANCE hInstance;
+extern HANDLE ehuserinfo,hmenuitem,ehmissed_proto;
+void BuildInfo(char *,char *,char *);
+int BuildContactMenu(WPARAM,LPARAM);
+int UserinfoInit(WPARAM,LPARAM);
+int InitFileOutput(void);
+void ShutdownFileOutput(void);
+void InitMenuitem(void);
+int ModeChange_mo(WPARAM,LPARAM);
+int CheckIfOnline(void);
+int ResetMissed(void);
+static BOOL (WINAPI *pfnEnableThemeDialogTexture)(HANDLE, DWORD) = 0;
+
+BOOL CALLBACK OptsPopUpsDlgProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
+{
+ DBVARIANT dbv;
+ int i;
+ char szstamp[256];
+ BOOL hasPopups;
+ switch(msg)
+ {
+ case WM_INITDIALOG:{
+ if (hasPopups = (ServiceExists(MS_POPUP_QUERY) != 0))
+ hasPopups = CallService(MS_POPUP_QUERY,PUQS_GETSTATUS,0);
+ TranslateDialogDefault(hdlg);
+ ShowWindow(GetDlgItem(hdlg,IDC_MISSPOPUP),hasPopups?SW_HIDE:SW_SHOW);
+ ShowWindow(GetDlgItem(hdlg,IDC_POPUPS),hasPopups?SW_SHOW:SW_HIDE);
+ ShowWindow(GetDlgItem(hdlg,IDC_POPUPSTAMP),hasPopups?SW_SHOW:SW_HIDE);
+ ShowWindow(GetDlgItem(hdlg,IDC_LABTEXT),hasPopups?SW_SHOW:SW_HIDE);
+ ShowWindow(GetDlgItem(hdlg,IDC_LABTTITLE),hasPopups?SW_SHOW:SW_HIDE);
+ ShowWindow(GetDlgItem(hdlg,IDC_POPUPSTAMPTEXT),hasPopups?SW_SHOW:SW_HIDE);
+ CheckDlgButton(hdlg,IDC_POPUPS,DBGetContactSettingByte(NULL,S_MOD,"UsePopups",0)&hasPopups);
+ EnableWindow(GetDlgItem(hdlg,IDC_POPUPS),hasPopups);
+ hasPopups = IsDlgButtonChecked(hdlg,IDC_POPUPS);
+ EnableWindow(GetDlgItem(hdlg,IDC_POPUPSTAMP),hasPopups);
+ EnableWindow(GetDlgItem(hdlg,IDC_POPUPSTAMPTEXT),hasPopups);
+ for (i=ID_STATUS_OFFLINE;i<=ID_STATUS_OUTTOLUNCH;i++){
+ DWORD sett;
+ COLORREF back, text;
+ sprintf(szstamp, "Col_%d",i-ID_STATUS_OFFLINE);
+ sett = DBGetContactSettingDword(NULL,S_MOD,szstamp,StatusColors15bits[i-ID_STATUS_OFFLINE]);
+ GetColorsFromDWord(&back, &text, sett);
+ SendDlgItemMessage(hdlg,i,CPM_SETCOLOUR,0,back);
+ SendDlgItemMessage(hdlg,i+20,CPM_SETCOLOUR,0,text);
+ EnableWindow(GetDlgItem(hdlg,i),hasPopups);
+ EnableWindow(GetDlgItem(hdlg,i+20),hasPopups);
+ }
+
+ SetDlgItemText(hdlg,IDC_POPUPSTAMP,!DBGetContactSetting(NULL,S_MOD,"PopupStamp",&dbv)?dbv.pszVal:DEFAULT_POPUPSTAMP);
+ DBFreeVariant(&dbv);
+ SetDlgItemText(hdlg,IDC_POPUPSTAMPTEXT,!DBGetContactSetting(NULL,S_MOD,"PopupStampText",&dbv)?dbv.pszVal:DEFAULT_POPUPSTAMPTEXT);
+ DBFreeVariant(&dbv);
+#ifndef PERMITNSN
+ i = DBGetContactSettingByte(NULL,S_MOD,"SuppCListOnline",3);
+ CheckDlgButton(hdlg,IDC_DISWATCHED,i&1);
+ CheckDlgButton(hdlg,IDC_DISNONWATCHED,i&2);
+#endif
+ }
+ break; //case WM_INITDIALOG
+ case WM_COMMAND:
+ if((HIWORD(wparam)==BN_CLICKED || HIWORD(wparam)==EN_CHANGE) && GetFocus()==(HWND)lparam)
+ SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
+ else if (HIWORD(wparam)==CPN_COLOURCHANGED){
+ WORD idText, idBack;
+ POPUPDATAEX ppd = {0};
+ DBVARIANT dbv = {0};
+ DWORD temp;
+ if (LOWORD(wparam)>ID_STATUS_OUTTOLUNCH){ // we have clicked a text color
+ idText = wparam; idBack = wparam-20;
+ } else {idText = wparam+20; idBack = wparam;}
+ ppd.colorBack = SendDlgItemMessage(hdlg,idBack,CPM_GETCOLOUR,0,0);
+ ppd.colorText = SendDlgItemMessage(hdlg,idText,CPM_GETCOLOUR,0,0);
+ temp = GetDWordFromColors(ppd.colorBack,ppd.colorText);
+ GetColorsFromDWord(&ppd.colorBack,&ppd.colorText,temp);
+ SendDlgItemMessage(hdlg,idBack,CPM_SETCOLOUR,0,ppd.colorBack);
+ SendDlgItemMessage(hdlg,idText,CPM_SETCOLOUR,0,ppd.colorText);
+ ppd.lchIcon = LoadSkinnedProtoIcon(NULL, idBack);
+ GetDlgItemText(hdlg,IDC_POPUPSTAMP,szstamp,255);
+ strncpy(ppd.lpzContactName,ParseString(szstamp,NULL,0),MAX_CONTACTNAME);
+ GetDlgItemText(hdlg,IDC_POPUPSTAMPTEXT,szstamp,255);
+ strncpy(ppd.lpzText,ParseString(szstamp,NULL,0),MAX_SECONDLINE);
+ CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0);
+
+ SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
+ }
+ if(HIWORD(wparam)==BN_CLICKED)
+ {
+ switch(LOWORD(wparam)){
+ case IDC_POPUPS:
+ hasPopups = IsDlgButtonChecked(hdlg,IDC_POPUPS);
+ EnableWindow(GetDlgItem(hdlg,IDC_POPUPSTAMP),hasPopups);
+ EnableWindow(GetDlgItem(hdlg,IDC_POPUPSTAMPTEXT),hasPopups);
+ for (i=ID_STATUS_OFFLINE;i<=ID_STATUS_OUTTOLUNCH;i++){
+ EnableWindow(GetDlgItem(hdlg,i),hasPopups);
+ EnableWindow(GetDlgItem(hdlg,i+20),hasPopups);
+ }
+ break;
+ case IDC_DEFAULTCOL:
+ for (i=ID_STATUS_OFFLINE;i<=ID_STATUS_OUTTOLUNCH;i++){
+ DWORD sett;
+ COLORREF back, text;
+ sprintf(szstamp, "Col_%d",i-ID_STATUS_OFFLINE);
+ sett = StatusColors15bits[i-ID_STATUS_OFFLINE];
+ GetColorsFromDWord(&back, &text, sett);
+ SendDlgItemMessage(hdlg,i,CPM_SETCOLOUR,0,back);
+ SendDlgItemMessage(hdlg,i+20,CPM_SETCOLOUR,0,text);
+ }
+ break;
+ }
+ }
+ break; //case WM_COMMAND
+
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lparam)->idFrom)
+ {
+ case 0:
+ switch (((LPNMHDR)lparam)->code)
+ {
+ BYTE checkValue;
+
+ case PSN_APPLY:
+ GetDlgItemText(hdlg,IDC_POPUPSTAMP,szstamp,256);
+ DBWriteContactSettingString(NULL,S_MOD,"PopupStamp",szstamp);
+ GetDlgItemText(hdlg,IDC_POPUPSTAMPTEXT,szstamp,256);
+ DBWriteContactSettingString(NULL,S_MOD,"PopupStampText",szstamp);
+
+ checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_POPUPS);
+ if (DBGetContactSettingByte(NULL,S_MOD,"UsePopups",0) != checkValue) {
+ DBWriteContactSettingByte(NULL,S_MOD,"UsePopups",checkValue);
+ }
+ for (i=ID_STATUS_OFFLINE;i<=ID_STATUS_OUTTOLUNCH;i++){
+ DWORD sett;
+ COLORREF back=0, text=0;
+ sprintf(szstamp, "Col_%d",i-ID_STATUS_OFFLINE);
+ back = SendDlgItemMessage(hdlg,i,CPM_GETCOLOUR,0,0);
+ text = SendDlgItemMessage(hdlg,i+20,CPM_GETCOLOUR,0,0);
+ sett=GetDWordFromColors(back,text);
+ if (sett!=StatusColors15bits[i-ID_STATUS_OFFLINE])
+ DBWriteContactSettingDword(NULL,S_MOD,szstamp,sett);
+ else DBDeleteContactSetting(NULL,S_MOD,szstamp);
+ }
+#ifndef PERMITNSN
+ checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_DISNONWATCHED)<<1;
+ checkValue |= (BYTE)IsDlgButtonChecked(hdlg,IDC_DISWATCHED);
+ if (3 == checkValue) DBDeleteContactSetting(NULL,S_MOD,"SuppCListOnline");
+ else DBWriteContactSettingByte(NULL,S_MOD,"SuppCListOnline",checkValue);
+#endif
+ break; //case PSN_APPLY
+ }
+ break; //case 0
+ }
+ break;//case WM_NOTIFY
+
+ }
+
+ return 0;
+}
+
+BOOL CALLBACK OptsSettingsDlgProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
+{
+ DBVARIANT dbv;
+ char szstamp[256];
+ BYTE bchecked=0;
+ WPARAM wpsend=0;
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:{
+ TranslateDialogDefault(hdlg);
+
+ CheckDlgButton(hdlg,IDC_MENUITEM,DBGetContactSettingByte(NULL,S_MOD,"MenuItem",1));
+ CheckDlgButton(hdlg,IDC_USERINFO,DBGetContactSettingByte(NULL,S_MOD,"UserinfoTab",1));
+ CheckDlgButton(hdlg,IDC_FILE,DBGetContactSettingByte(NULL,S_MOD,"FileOutput",0));
+ CheckDlgButton(hdlg,IDC_HISTORY,DBGetContactSettingByte(NULL,S_MOD,"KeepHistory",0));
+ CheckDlgButton(hdlg,IDC_IGNOREOFFLINE,DBGetContactSettingByte(NULL,S_MOD,"IgnoreOffline",1));
+ CheckDlgButton(hdlg,IDC_MISSEDONES,DBGetContactSettingByte(NULL,S_MOD,"MissedOnes",0));
+ CheckDlgButton(hdlg,IDC_SHOWICON,DBGetContactSettingByte(NULL,S_MOD,"ShowIcon",1));
+ CheckDlgButton(hdlg,IDC_COUNT,DBGetContactSettingByte(NULL,S_MOD,"MissedOnes_Count",0));
+ CheckDlgButton(hdlg,IDC_IDLESUPPORT,DBGetContactSettingByte(NULL,S_MOD,"IdleSupport",1));
+
+ EnableWindow(GetDlgItem(hdlg,IDC_MENUSTAMP),IsDlgButtonChecked(hdlg,IDC_MENUITEM));
+ EnableWindow(GetDlgItem(hdlg,IDC_SHOWICON),IsDlgButtonChecked(hdlg,IDC_MENUITEM));
+ EnableWindow(GetDlgItem(hdlg,IDC_USERSTAMP),IsDlgButtonChecked(hdlg,IDC_USERINFO));
+ EnableWindow(GetDlgItem(hdlg,IDC_FILESTAMP),IsDlgButtonChecked(hdlg,IDC_FILE));
+ EnableWindow(GetDlgItem(hdlg,IDC_FILENAME),IsDlgButtonChecked(hdlg,IDC_FILE));
+ EnableWindow(GetDlgItem(hdlg,IDC_HISTORYSIZE),IsDlgButtonChecked(hdlg,IDC_HISTORY));
+ EnableWindow(GetDlgItem(hdlg,IDC_HISTORYSTAMP),IsDlgButtonChecked(hdlg,IDC_HISTORY));
+ EnableWindow(GetDlgItem(hdlg,IDC_COUNT),IsDlgButtonChecked(hdlg,IDC_MISSEDONES));
+
+ SetDlgItemText(hdlg,IDC_MENUSTAMP,!DBGetContactSetting(NULL,S_MOD,"MenuStamp",&dbv)?dbv.pszVal:DEFAULT_MENUSTAMP);
+ DBFreeVariant(&dbv);
+ SetDlgItemText(hdlg,IDC_USERSTAMP,!DBGetContactSetting(NULL,S_MOD,"UserStamp",&dbv)?dbv.pszVal:DEFAULT_USERSTAMP);
+ DBFreeVariant(&dbv);
+ SetDlgItemText(hdlg,IDC_FILESTAMP,!DBGetContactSetting(NULL,S_MOD,"FileStamp",&dbv)?dbv.pszVal:DEFAULT_FILESTAMP);
+ DBFreeVariant(&dbv);
+ SetDlgItemText(hdlg,IDC_FILENAME,!DBGetContactSetting(NULL,S_MOD,"FileName",&dbv)?dbv.pszVal:DEFAULT_FILENAME);
+ DBFreeVariant(&dbv);
+ SetDlgItemInt(hdlg,IDC_HISTORYSIZE,DBGetContactSettingWord(NULL,S_MOD,"HistoryMax",10-1)-1,FALSE);
+ SetDlgItemText(hdlg,IDC_HISTORYSTAMP,!DBGetContactSetting(NULL,S_MOD,"HistoryStamp",&dbv)?dbv.pszVal:DEFAULT_HISTORYSTAMP);
+ DBFreeVariant(&dbv);
+
+ // load protocol list
+ SetWindowLong(GetDlgItem(hdlg,IDC_PROTOCOLLIST),GWL_STYLE,GetWindowLong(GetDlgItem(hdlg,IDC_PROTOCOLLIST),GWL_STYLE)|TVS_CHECKBOXES);
+ {
+ TVINSERTSTRUCT tvis;
+ int numberOfProtocols,i;
+ PROTOCOLDESCRIPTOR** protos;
+ char *protoName;
+ char *protoLabel;
+
+ tvis.hParent=NULL;
+ tvis.hInsertAfter=TVI_LAST;
+ tvis.item.mask=TVIF_TEXT | TVIF_HANDLE | TVIF_STATE | TVIF_PARAM;
+ tvis.item.stateMask = TVIS_STATEIMAGEMASK;
+
+ CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&numberOfProtocols,(LPARAM)&protos);
+ for (i=0; i<numberOfProtocols; i++) {
+ if(protos[i]->type!=PROTOTYPE_PROTOCOL || CallProtoService(protos[i]->szName,PS_GETCAPS,PFLAGNUM_2,0)==0) continue;
+ protoName = (char *)malloc(strlen(protos[i]->szName)+1);
+ strcpy(protoName,protos[i]->szName);
+//debug(protoName);
+ protoLabel = (char *)malloc(MAXMODULELABELLENGTH+1);
+ CallProtoService(protoName,PS_GETNAME,MAXMODULELABELLENGTH,(LPARAM)protoLabel);
+//debug(protoLabel);
+ tvis.item.pszText = protoLabel;
+ tvis.item.lParam = (LPARAM)protoName;
+ tvis.item.state = INDEXTOSTATEIMAGEMASK(IsWatchedProtocol(protoName)+1);
+ TreeView_InsertItem(GetDlgItem(hdlg,IDC_PROTOCOLLIST),&tvis);
+ free(protoLabel);
+
+ }
+ }
+ }
+ break; //case WM_INITDIALOG
+
+ case WM_COMMAND:
+ if((HIWORD(wparam)==BN_CLICKED || HIWORD(wparam)==EN_CHANGE) && GetFocus()==(HWND)lparam)
+ if (LOWORD(wparam)!=IDC_VARIABLES)SendMessage(GetParent(hdlg),PSM_CHANGED,0,0);
+
+ if(HIWORD(wparam)==BN_CLICKED)
+ {
+ switch(LOWORD(wparam)){
+ case IDC_MENUITEM:
+ EnableWindow(GetDlgItem(hdlg,IDC_MENUSTAMP),IsDlgButtonChecked(hdlg,IDC_MENUITEM));
+ EnableWindow(GetDlgItem(hdlg,IDC_SHOWICON),IsDlgButtonChecked(hdlg,IDC_MENUITEM));
+ break;
+ case IDC_USERINFO:
+ EnableWindow(GetDlgItem(hdlg,IDC_USERSTAMP),IsDlgButtonChecked(hdlg,IDC_USERINFO));
+ break;
+ case IDC_FILE:
+ EnableWindow(GetDlgItem(hdlg,IDC_FILESTAMP),IsDlgButtonChecked(hdlg,IDC_FILE));
+ EnableWindow(GetDlgItem(hdlg,IDC_FILENAME),IsDlgButtonChecked(hdlg,IDC_FILE));
+ break;
+ case IDC_HISTORY:
+ EnableWindow(GetDlgItem(hdlg,IDC_HISTORYSTAMP),IsDlgButtonChecked(hdlg,IDC_HISTORY));
+ EnableWindow(GetDlgItem(hdlg,IDC_HISTORYSIZE),IsDlgButtonChecked(hdlg,IDC_HISTORY));
+ break;
+ case IDC_MISSEDONES:
+ EnableWindow(GetDlgItem(hdlg,IDC_COUNT),IsDlgButtonChecked(hdlg,IDC_MISSEDONES));
+ break;
+ }
+ }
+
+ if (LOWORD(wparam)==IDC_VARIABLES)
+ {
+ char szout[2048]="";
+ wsprintf(szout,VARIABLE_LIST);
+ MessageBox(NULL,szout,"Last Seen Variables",MB_OK|MB_TOPMOST);
+ }
+
+ break; //case WM_COMMAND
+
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lparam)->idFrom)
+ {
+ case 0:
+ switch (((LPNMHDR)lparam)->code)
+ {
+ BYTE checkValue;
+
+ case PSN_APPLY:
+
+ GetDlgItemText(hdlg,IDC_MENUSTAMP,szstamp,256);
+ DBWriteContactSettingString(NULL,S_MOD,"MenuStamp",szstamp);
+
+ GetDlgItemText(hdlg,IDC_USERSTAMP,szstamp,256);
+ DBWriteContactSettingString(NULL,S_MOD,"UserStamp",szstamp);
+
+ GetDlgItemText(hdlg,IDC_FILESTAMP,szstamp,256);
+ DBWriteContactSettingString(NULL,S_MOD,"FileStamp",szstamp);
+
+ GetDlgItemText(hdlg,IDC_FILENAME,szstamp,256);
+ DBWriteContactSettingString(NULL,S_MOD,"FileName",szstamp);
+
+ GetDlgItemText(hdlg,IDC_HISTORYSTAMP,szstamp,256);
+ DBWriteContactSettingString(NULL,S_MOD,"HistoryStamp",szstamp);
+
+ DBWriteContactSettingWord(NULL,S_MOD,"HistoryMax",(WORD)(GetDlgItemInt(hdlg,IDC_HISTORYSIZE,NULL,FALSE)+1));
+
+ checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_MENUITEM);
+ if (DBGetContactSettingByte(NULL,S_MOD,"MenuItem",1) != checkValue) {
+ DBWriteContactSettingByte(NULL,S_MOD,"MenuItem",checkValue);
+ if(hmenuitem==NULL && checkValue) {
+ InitMenuitem();
+ }
+ }
+
+ checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_USERINFO);
+ if (DBGetContactSettingByte(NULL,S_MOD,"UserinfoTab",1) != checkValue) {
+ DBWriteContactSettingByte(NULL,S_MOD,"UserinfoTab",checkValue);
+ if(checkValue) {
+ ehuserinfo=HookEvent(ME_USERINFO_INITIALISE,UserinfoInit);
+ } else {
+ UnhookEvent(ehuserinfo);
+ }
+ }
+
+ checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_FILE);
+ if (DBGetContactSettingByte(NULL,S_MOD,"FileOutput",0) != checkValue) {
+ DBWriteContactSettingByte(NULL,S_MOD,"FileOutput",checkValue);
+ if(checkValue) {
+ InitFileOutput();
+ }
+ }
+
+ checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_HISTORY);
+ if (DBGetContactSettingByte(NULL,S_MOD,"KeepHistory",0) != checkValue) {
+ DBWriteContactSettingByte(NULL,S_MOD,"KeepHistory",checkValue);
+ }
+
+ checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_IGNOREOFFLINE);
+ if (DBGetContactSettingByte(NULL,S_MOD,"IgnoreOffline",1) != checkValue) {
+ DBWriteContactSettingByte(NULL,S_MOD,"IgnoreOffline",checkValue);
+ }
+
+ checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_MISSEDONES);
+ if (DBGetContactSettingByte(NULL,S_MOD,"MissedOnes",0) != checkValue) {
+ DBWriteContactSettingByte(NULL,S_MOD,"MissedOnes",checkValue);
+ if(checkValue) {
+ ehmissed_proto=HookEvent(ME_PROTO_ACK,ModeChange_mo);
+ } else {
+ UnhookEvent(ehmissed_proto);
+ }
+ }
+
+ checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_SHOWICON);
+ if (DBGetContactSettingByte(NULL,S_MOD,"ShowIcon",1) != checkValue) {
+ DBWriteContactSettingByte(NULL,S_MOD,"ShowIcon",checkValue);
+ }
+
+ checkValue = (BYTE)IsDlgButtonChecked(hdlg,IDC_COUNT);
+ if (DBGetContactSettingByte(NULL,S_MOD,"MissedOnes_Count",0) != checkValue) {
+ DBWriteContactSettingByte(NULL,S_MOD,"MissedOnes_Count",checkValue);
+ }
+
+ includeIdle = (BYTE)IsDlgButtonChecked(hdlg,IDC_IDLESUPPORT);
+ if (DBGetContactSettingByte(NULL,S_MOD,"IdleSupport",1) != includeIdle) {
+ DBWriteContactSettingByte(NULL,S_MOD,"IdleSupport",(BYTE)includeIdle);
+ }
+
+ // save protocol list
+ {
+ HWND hwndTreeView = GetDlgItem(hdlg,IDC_PROTOCOLLIST);
+ HTREEITEM hItem;
+ TVITEM tvItem;
+ char *watchedProtocols;
+ char *protocol;
+ int size=1;
+
+ watchedProtocols = (char *)malloc(sizeof(char));
+ *watchedProtocols = '\0';
+ hItem = TreeView_GetRoot(hwndTreeView);
+ tvItem.mask = TVIF_HANDLE | TVIF_STATE | TVIF_PARAM;
+ tvItem.stateMask = TVIS_STATEIMAGEMASK;
+
+ while (hItem != NULL) {
+ tvItem.hItem = hItem;
+ TreeView_GetItem(hwndTreeView, &tvItem);
+ protocol = (char*)tvItem.lParam;
+ if ((BOOL)(tvItem.state >> 12) -1) {
+ size = (size + strlen(protocol)+2) * sizeof(char);
+ watchedProtocols = (char *)realloc(watchedProtocols, size);
+ strcat(watchedProtocols, protocol);
+ strcat(watchedProtocols, " ");
+ }
+ hItem = TreeView_GetNextSibling(hwndTreeView, hItem);
+ }
+ DBWriteContactSettingString(NULL,S_MOD,"WatchedProtocols",watchedProtocols);
+ free(watchedProtocols);
+ }
+
+ break; //case PSN_APPLY
+ }
+ break; //case 0
+
+ case IDC_PROTOCOLLIST:
+ switch (((LPNMHDR)lparam)->code)
+ {
+ case NM_CLICK:
+ {
+ HWND hTree=((LPNMHDR)lparam)->hwndFrom;
+ TVHITTESTINFO hti;
+ HTREEITEM hItem;
+
+ hti.pt.x=(short)LOWORD(GetMessagePos());
+ hti.pt.y=(short)HIWORD(GetMessagePos());
+ ScreenToClient(hTree,&hti.pt);
+ if(hItem=TreeView_HitTest(hTree,&hti))
+ {
+ if (hti.flags & TVHT_ONITEM)
+ TreeView_SelectItem(hTree,hItem);
+ if (hti.flags & TVHT_ONITEMSTATEICON)
+ SendMessage(GetParent(hdlg), PSM_CHANGED, 0, 0);
+
+ }
+ }
+ break;
+ }
+ break; //case IDC_PROTOCOLLIST
+ }
+ break;//case WM_NOTIFY
+
+ case WM_DESTROY:
+ // free protocol list
+ {
+ HWND hwndTreeView = GetDlgItem(hdlg,IDC_PROTOCOLLIST);
+ HTREEITEM hItem;
+ TVITEM tvItem;
+
+ hItem = TreeView_GetRoot(hwndTreeView);
+ tvItem.mask = TVIF_HANDLE | TVIF_PARAM;
+
+ while (hItem != NULL) {
+ tvItem.hItem = hItem;
+ TreeView_GetItem(hwndTreeView, &tvItem);
+ free((void *)tvItem.lParam);
+ hItem = TreeView_GetNextSibling(hwndTreeView, hItem);
+ }
+ }
+ break;
+
+ }
+
+ return 0;
+}
+
+long OptsSettingsDlg, OptsPopUpsDlg;
+
+ BOOL CALLBACK OptTabDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TCITEMA tci;
+ RECT theTabSpace;
+ RECT rcClient;
+ {
+ RECT rcTab, rcDlg;
+ HWND hwndTab = GetDlgItem(hwndDlg, IDC_OPTIONSTAB);
+ TabCtrl_GetItemRect(hwndTab,0,&rcTab);
+ TabCtrl_DeleteAllItems(hwndTab);
+ theTabSpace.top = rcTab.bottom; // the size of the tab
+ GetWindowRect(GetDlgItem(hwndDlg, IDC_OPTIONSTAB), &rcTab);
+ GetWindowRect(hwndDlg, &rcDlg);
+ theTabSpace.bottom = rcTab.bottom -rcTab.top -theTabSpace.top;
+ theTabSpace.top = rcTab.top -rcDlg.top +theTabSpace.top;
+ theTabSpace.left = rcTab.left - rcDlg.left;
+ theTabSpace.right = rcTab.right-rcTab.left;
+ }
+ tci.mask = TCIF_PARAM|TCIF_TEXT;
+ if (!OptsPopUpsDlg) OptsPopUpsDlg = (long)CreateDialog(hInstance,MAKEINTRESOURCE(IDD_POPUPS), hwndDlg, OptsPopUpsDlgProc);
+ if(pfnEnableThemeDialogTexture) {
+ if(OptsPopUpsDlg)
+ pfnEnableThemeDialogTexture((HANDLE)OptsPopUpsDlg, ETDT_ENABLETAB);
+ }
+ tci.lParam = OptsPopUpsDlg;
+ GetClientRect((HWND)tci.lParam,&rcClient);
+ tci.pszText = Translate("Popups");
+ SendMessage(GetDlgItem(hwndDlg, IDC_OPTIONSTAB), TCM_INSERTITEMA, (WPARAM)0, (LPARAM)&tci);
+ MoveWindow((HWND)tci.lParam,theTabSpace.left+(theTabSpace.right-rcClient.right)/2,
+ theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2,
+ rcClient.right,rcClient.bottom,1);
+ ShowWindow((HWND)tci.lParam, SW_HIDE);
+
+ if (!OptsSettingsDlg) OptsSettingsDlg = (long)CreateDialog(hInstance,MAKEINTRESOURCE(IDD_SETTINGS), hwndDlg, OptsSettingsDlgProc);
+ if(pfnEnableThemeDialogTexture) {
+ if(OptsSettingsDlg)
+ pfnEnableThemeDialogTexture((HANDLE)OptsSettingsDlg, ETDT_ENABLETAB);
+ }
+ tci.lParam = OptsSettingsDlg;
+ tci.pszText = Translate("Settings");
+ GetClientRect((HWND)tci.lParam,&rcClient);
+ SendMessage(GetDlgItem(hwndDlg, IDC_OPTIONSTAB), TCM_INSERTITEMA, (WPARAM)0, (LPARAM)&tci);
+ MoveWindow((HWND)tci.lParam,theTabSpace.left+(theTabSpace.right-rcClient.right)/2,
+ theTabSpace.top+(theTabSpace.bottom-rcClient.bottom)/2,
+ rcClient.right,rcClient.bottom,1);
+ ShowWindow((HWND)tci.lParam, SW_SHOW);
+ TabCtrl_SetCurSel(GetDlgItem(hwndDlg, IDC_OPTIONSTAB),0);
+ return TRUE;
+ }
+ case PSM_CHANGED:
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, (unsigned int)hwndDlg, 0);
+ break;
+ case WM_DESTROY:
+ OptsSettingsDlg = OptsPopUpsDlg = 0;
+ break;
+ case WM_NOTIFY:
+ {
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0: {
+ BOOL CommandApply = FALSE;
+ if ( (CommandApply = lParam && ((LPNMHDR)lParam)->code == PSN_APPLY) || (lParam && ((LPNMHDR)lParam)->code == PSN_RESET) ) {
+#ifdef _DEBUG
+ MessageBoxA(hwndDlg,CommandApply?"Apply":"Cancel","EventHapened",0);
+#endif
+ if (CommandApply) {
+ SendMessage((HWND)OptsSettingsDlg, WM_NOTIFY, wParam, lParam);
+ SendMessage((HWND)OptsPopUpsDlg, WM_NOTIFY, wParam, lParam);
+ return TRUE;
+ } else {
+ }
+ } //if PSN_APPLY
+ }
+ break;
+ case IDC_OPTIONSTAB:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case TCN_SELCHANGING:
+ {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(GetDlgItem(hwndDlg,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwndDlg,IDC_OPTIONSTAB)),&tci);
+ ShowWindow((HWND)tci.lParam,SW_HIDE);
+ }
+ break;
+ case TCN_SELCHANGE:
+ {
+ TCITEM tci;
+ short int t;
+ tci.mask = TCIF_PARAM;
+ t = TabCtrl_GetCurSel(GetDlgItem(hwndDlg,IDC_OPTIONSTAB));
+ TabCtrl_GetItem(GetDlgItem(hwndDlg,IDC_OPTIONSTAB),t,&tci);
+ ShowWindow((HWND)tci.lParam,SW_SHOW);
+ }
+ break;
+ }
+ break;
+ }
+ }//end case(LPNMHDR)lParam)->idFrom
+ break;
+ }
+ return FALSE;
+}
+
+
+
+int OptionsInit(WPARAM wparam,LPARAM lparam)
+{
+ OPTIONSDIALOGPAGE odp;
+ HMODULE hUxTheme = 0;
+
+ if(IsWinVerXPPlus()) {
+ hUxTheme = GetModuleHandle(_T("uxtheme.dll"));
+
+ if(hUxTheme)
+ pfnEnableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture");
+ }
+
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize=sizeof(odp);
+ odp.pszGroup=Translate("Plugins");
+ odp.hInstance=hInstance;
+ odp.pszTemplate=MAKEINTRESOURCE(IDD_OPTIONS);
+ odp.pszTitle=Translate("Last seen");
+ odp.pfnDlgProc=OptTabDlgProc;
+ odp.flags=ODPF_BOLDGROUPS;
+ CallService(MS_OPT_ADDPAGE,wparam,(LPARAM)&odp);
+ return 0;
+}
diff --git a/lastseen-mod/readme_src.txt b/lastseen-mod/readme_src.txt new file mode 100644 index 0000000..0769b49 --- /dev/null +++ b/lastseen-mod/readme_src.txt @@ -0,0 +1,23 @@ +This source code is licensed under the GPL (http://www.gnu.org/copyleft/gpl.html)
+
+Please notify me of any changes that improve the plugin or add
+new features.
+
+If you have any questions on the code, feel free to contact me at
+UIN: 46955367 or
+eMail: micron@nexgo.de
+Visit http://home.nexgo.de/micron/miranda for the latest source files
+
+micron-x
+
+
+
+Rebase information
+******************
+enotify.dll 0x67700000
+dbviewer.dll 0x67600000
+hotkey.dll 0x67500000
+pluginsweeper.dll 0x67400000
+seenplugin.dll 0x67300000
+tipinfo.dll 0x67200000
+visibility.dll 0x67100000
\ No newline at end of file diff --git a/lastseen-mod/resource.h b/lastseen-mod/resource.h new file mode 100644 index 0000000..24d5815 --- /dev/null +++ b/lastseen-mod/resource.h @@ -0,0 +1,98 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+
+#ifndef TVS_NOTOOLTIPS
+#define TVS_NOTOOLTIPS 0x0080
+#endif
+
+#define ID_STATUS_OFFLINE 40071
+#define ID_STATUS_ONLINE 40072
+#define ID_STATUS_AWAY 40073
+#define ID_STATUS_DND 40074
+#define ID_STATUS_NA 40075
+#define ID_STATUS_OCCUPIED 40076
+#define ID_STATUS_FREECHAT 40077
+#define ID_STATUS_INVISIBLE 40078
+#define ID_STATUS_ONTHEPHONE 40079
+#define ID_STATUS_OUTTOLUNCH 40080
+#define ID_STATUS_IDLE 40081 /* do not use as a status */
+
+
+#define IDD_OPTIONS 101
+#define IDD_USERINFO 102
+#define IDD_MISSED 103
+#define IDD_USERDETAILS 104
+#define IDD_HISTORY 105
+#define IDD_SETTINGS 106
+#define IDD_POPUPS 107
+#define IDC_SEENMENUITEM 1000
+#define IDC_MENUITEM 1001
+#define IDC_UINFOTAB 1002
+#define IDC_USERINFO 1003
+#define IDC_USERTIME 1004
+#define IDC_HISTORY 1005
+#define IDC_FILE 1006
+#define IDC_FILEGROUP 1007
+#define IDC_POPUPS 1008
+#define IDC_TIME 1009
+#define IDC_OWNSTATUS 1010
+#define IDC_TIMESTAMPGROUP 1011
+#define IDC_EDIT1 1012
+#define IDC_TIMESTAMP 1013
+#define IDC_FILESTAMP 1014
+#define IDC_CONTACTS 1015
+#define IDC_INFOTEXT 1016
+#define IDC_TIMESTAMPHELP 1017
+#define IDC_USERSTAMP 1018
+#define IDC_DELCHAR 1019
+#define IDC_HISTORYSTAMP 1020
+#define IDC_DELCHARHELP 1021
+#define IDC_POPUPSTAMP 1022
+#define IDC_MENUGROUP 1023
+#define IDC_POPUPSTAMPTEXT 1023
+#define IDC_MENUTIME 1024
+#define IDC_MENUSTATUS 1025
+#define IDC_MENUSTAMP 1026
+#define IDC_LABTEXT 1027
+#define IDC_MISSPOPUP 1028
+#define IDC_DEFAULTCOL 1029
+#define IDC_FILENAME 1030
+#define IDC_IGNOREOFFLINE 1031
+#define IDC_MISSEDONES 1032
+#define IDC_SHOWICON 1033
+#define IDC_COUNT 1034
+#define IDC_FILENAME2 1035
+#define IDC_HISTORYSIZE 1036
+#define IDC_LASTSEENLIST 1037
+#define IDC_HISTORYLIST 1038
+#define IDC_STATUSCHANGE 1039
+#define IDC_VARIABLES 1040
+#define IDC_PROTOCOLLIST 1041
+#define IDC_USERMENU 1042
+#define IDC_TEST 1043
+#define IDC_DETAILS 1044
+#define IDC_SENDMSG 1045
+#define IDC_LABTTITLE 1046
+#define IDC_OPTIONSTAB 1047
+#ifndef PERMITNSN
+#define IDC_DISWATCHED 1048
+#define IDC_DISNONWATCHED 1049
+#endif
+#define IDC_IDLESUPPORT 1050
+#define IDC_MAINGROUP -1
+#define IDC_INFO -1
+#define IDC_TEXT -1
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 112
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1051
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/lastseen-mod/resource.rc b/lastseen-mod/resource.rc new file mode 100644 index 0000000..d0fb879 --- /dev/null +++ b/lastseen-mod/resource.rc @@ -0,0 +1,301 @@ +//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <windows.h>
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// German (Germany) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
+#ifdef _WIN32
+LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include <windows.h>\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPTIONS DIALOGEX 0, 0, 320, 250
+STYLE DS_FIXEDSYS | DS_CENTER | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "Tab1",IDC_OPTIONSTAB,"SysTabControl32",WS_TABSTOP,0,3,319,246
+END
+
+IDD_SETTINGS DIALOGEX 0, 0, 300, 228
+STYLE DS_3DLOOK | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Last seen options",IDC_MAINGROUP,0,0,299,226,WS_GROUP
+ CONTROL "Last seen menuitem",IDC_MENUITEM,"Button",
+ BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,6,12,79,10
+ CONTROL "Show icon",IDC_SHOWICON,"Button",BS_AUTOCHECKBOX |
+ WS_GROUP | WS_TABSTOP,87,12,56,10
+ EDITTEXT IDC_MENUSTAMP,18,23,120,12,ES_AUTOHSCROLL | WS_GROUP
+ CONTROL "Userinfo tab",IDC_USERINFO,"Button",BS_AUTOCHECKBOX |
+ WS_GROUP | WS_TABSTOP,6,42,140,10
+ EDITTEXT IDC_USERSTAMP,18,52,275,12,ES_AUTOHSCROLL | WS_GROUP
+ CONTROL "Log to file",IDC_FILE,"Button",BS_AUTOCHECKBOX |
+ WS_GROUP | WS_TABSTOP,6,72,132,10
+ EDITTEXT IDC_FILENAME,149,69,144,12,ES_AUTOHSCROLL
+ EDITTEXT IDC_FILESTAMP,18,83,275,12,ES_AUTOHSCROLL | WS_GROUP
+ CONTROL "Log to history",IDC_HISTORY,"Button",BS_AUTOCHECKBOX |
+ WS_GROUP | WS_TABSTOP,7,104,131,10
+ LTEXT "Maximum size",IDC_STATIC,183,102,51,9
+ EDITTEXT IDC_HISTORYSIZE,149,100,30,12,ES_AUTOHSCROLL | ES_NUMBER
+ EDITTEXT IDC_HISTORYSTAMP,18,114,275,12,ES_AUTOHSCROLL | WS_GROUP
+ PUSHBUTTON "Variable list",IDC_VARIABLES,47,137,50,13
+ CONTROL "Enable Idle support",IDC_IDLESUPPORT,"Button",
+ BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,7,158,135,10
+ CONTROL "Ignore contacts going offline",IDC_IGNOREOFFLINE,"Button",
+ BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,7,174,135,10
+ CONTROL "Enable 'Missed Ones' feature",IDC_MISSEDONES,"Button",
+ BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,7,190,135,10
+ CONTROL "Count times",IDC_COUNT,"Button",BS_AUTOCHECKBOX |
+ WS_GROUP | WS_TABSTOP,18,202,100,10
+ LTEXT "Protocols to watch:",IDC_MAINGROUP,149,130,114,9
+ CONTROL "Tree1",IDC_PROTOCOLLIST,"SysTreeView32",TVS_NOTOOLTIPS |
+ WS_BORDER | WS_TABSTOP,149,140,144,81
+END
+
+IDD_POPUPS DIALOGEX 0, 0, 280, 208
+STYLE DS_3DLOOK | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "",IDC_STATIC,0,0,280,26,WS_GROUP
+ CTEXT "Popup interoperability missing or disabled. You need Popups plugin",IDC_MISSPOPUP,1,11,280,10,NOT WS_VISIBLE
+ CONTROL "Use popups",IDC_POPUPS,"Button",BS_AUTOCHECKBOX |
+ WS_GROUP | WS_TABSTOP,5,10,50,10
+ RTEXT "Title",IDC_LABTEXT,70,11,25,10
+ EDITTEXT IDC_POPUPSTAMP,100,9,50,12,ES_AUTOHSCROLL | WS_GROUP
+ RTEXT "Text",IDC_LABTTITLE,155,11,25,10
+ EDITTEXT IDC_POPUPSTAMPTEXT,185,9,88,12,ES_AUTOHSCROLL |
+ WS_GROUP
+ GROUPBOX "PopUp Colors",IDC_STATIC,0,30,280,136,WS_GROUP
+ RTEXT "Online",IDC_STATIC,10,43,60,10
+ CONTROL "",ID_STATUS_ONLINE,"ColourPicker",WS_TABSTOP,80,40,20,14
+ CONTROL "",ID_STATUS_ONLINE+20,"ColourPicker",WS_TABSTOP,105,40,20,14
+ RTEXT "Away",IDC_STATIC,10,63,60,10
+ CONTROL "",ID_STATUS_AWAY,"ColourPicker",WS_TABSTOP,80,60,20,14
+ CONTROL "",ID_STATUS_AWAY+20,"ColourPicker",WS_TABSTOP,105,60,20,14
+ RTEXT "N/A",IDC_STATIC,10,83,60,10
+ CONTROL "",ID_STATUS_NA,"ColourPicker",WS_TABSTOP,80,80,20,14
+ CONTROL "",ID_STATUS_NA+20,"ColourPicker",WS_TABSTOP,105,80,20,14
+ RTEXT "Occupied",IDC_STATIC,10,103,60,10
+ CONTROL "",ID_STATUS_OCCUPIED,"ColourPicker",WS_TABSTOP,80,100,20,14
+ CONTROL "",ID_STATUS_OCCUPIED+20,"ColourPicker",WS_TABSTOP,105,100,20,14
+ RTEXT "DND",IDC_STATIC,10,123,60,10
+ CONTROL "",ID_STATUS_DND,"ColourPicker",WS_TABSTOP,80,120,20,14
+ CONTROL "",ID_STATUS_DND+20,"ColourPicker",WS_TABSTOP,105,120,20,14
+
+ RTEXT "On the phone",IDC_STATIC,140,43,60,10
+ CONTROL "",ID_STATUS_ONTHEPHONE,"ColourPicker",WS_TABSTOP,210,40,20,14
+ CONTROL "",ID_STATUS_ONTHEPHONE+20,"ColourPicker",WS_TABSTOP,235,40,20,14
+ RTEXT "Out to lunch",IDC_STATIC,140,63,60,10
+ CONTROL "",ID_STATUS_OUTTOLUNCH,"ColourPicker",WS_TABSTOP,210,60,20,14
+ CONTROL "",ID_STATUS_OUTTOLUNCH+20,"ColourPicker",WS_TABSTOP,235,60,20,14
+ RTEXT "Free for chat",IDC_STATIC,140,83,60,10
+ CONTROL "",ID_STATUS_FREECHAT,"ColourPicker",WS_TABSTOP,210,80,20,14
+ CONTROL "",ID_STATUS_FREECHAT+20,"ColourPicker",WS_TABSTOP,235,80,20,14
+ RTEXT "Invisible",IDC_STATIC,140,103,60,10
+ CONTROL "",ID_STATUS_INVISIBLE,"ColourPicker",WS_TABSTOP,210,100,20,14
+ CONTROL "",ID_STATUS_INVISIBLE+20,"ColourPicker",WS_TABSTOP,235,100,20,14
+ RTEXT "Offline",IDC_STATIC,140,123,60,10
+ CONTROL "",ID_STATUS_OFFLINE,"ColourPicker",WS_TABSTOP,210,120,20,14
+ CONTROL "",ID_STATUS_OFFLINE+20,"ColourPicker",WS_TABSTOP,235,120,20,14
+ PUSHBUTTON "Reset colors",IDC_DEFAULTCOL,115,145,50,13
+#ifndef PERMITNSN
+ GROUPBOX "Disable CList Notifications",IDC_STATIC,0,170,280,38,WS_GROUP
+ CONTROL "For watched protocols",IDC_DISWATCHED,"Button", BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,180,100,10
+ CONTROL "For non-watched protocols",IDC_DISNONWATCHED,"Button", BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,10,193,100,10
+#endif
+END
+
+IDD_USERINFO DIALOGEX 0, 0, 222, 132
+STYLE DS_3DLOOK | DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ EDITTEXT IDC_INFOTEXT,6,6,210,122,ES_MULTILINE | ES_NOHIDESEL |
+ ES_READONLY | NOT WS_BORDER
+END
+
+IDD_MISSED DIALOGEX 0, 0, 160, 71
+STYLE DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP |
+ WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_CONTROLPARENT
+CAPTION "Last seen plugin"
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,55,48,50,14
+ LTEXT "You missed following contacts:",IDC_TEXT,6,6,148,10
+ CTEXT "Test\nTest",IDC_CONTACTS,6,22,148,16
+END
+
+IDD_HISTORY DIALOGEX 0, 0, 200, 120
+STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP |
+ WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+// PUSHBUTTON "Variablestest",IDC_TEST,5,5,52,13,NOT WS_VISIBLE
+ DEFPUSHBUTTON "OK",IDOK,75,101,50,14
+ PUSHBUTTON "",IDC_USERMENU,146,5,15,13,BS_ICON | WS_TABSTOP
+ PUSHBUTTON "",IDC_DETAILS,163,5,15,13,BS_ICON | WS_TABSTOP
+ PUSHBUTTON "",IDC_SENDMSG,180,5,15,13,BS_ICON | WS_TABSTOP
+ LISTBOX IDC_HISTORYLIST,5,20,190,59,LBS_NOINTEGRALHEIGHT |
+ WS_VSCROLL | WS_TABSTOP
+ CONTROL "Alert when user status changes",IDC_STATUSCHANGE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,5,86,190,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_OPTIONS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 293
+ VERTGUIDE, 18
+ VERTGUIDE, 149
+ VERTGUIDE, 161
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 225
+ HORZGUIDE, 22
+ END
+
+ IDD_USERINFO, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 215
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 125
+ END
+
+ IDD_MISSED, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 153
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 64
+ END
+
+ IDD_HISTORY, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 195
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 115
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 5,0,4,7
+ PRODUCTVERSION 5,0,4,7
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "Comments", "Last Seen Mod Plugin for Miranda IM\0"
+ VALUE "CompanyName", "Heiko Schillinger, YB\0"
+#ifdef PERMITNSN
+ VALUE "FileDescription", "Last Seen Plugin\0"
+#else
+ VALUE "FileDescription", "Last Seen Plugin (NSN Compatible)\0"
+#endif
+ VALUE "FileVersion", "5.0.4.7\0"
+ VALUE "InternalName", "Last Seen\0"
+ VALUE "LegalCopyright", "© 2001-2002 by Heiko Schillinger, 2003 by Bruno Rino, 2006 by YB\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "seenplugin.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", " Last Seen Plugin Mod\0"
+ VALUE "ProductVersion", "5.0.4.7\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
+
+#endif // !_MAC
+
+#endif // German (Germany) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/lastseen-mod/seen.h b/lastseen-mod/seen.h new file mode 100644 index 0000000..ad1a301 --- /dev/null +++ b/lastseen-mod/seen.h @@ -0,0 +1,123 @@ +/*
+"Last Seen mod" plugin for Miranda IM
+Copyright ( C ) 2002-03 micron-x
+Copyright ( C ) 2005-07 Y.B.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or ( at your option ) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+File name : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/seen.h $
+Revision : $Rev: 1570 $
+Last change on : $Date: 2007-12-30 00:30:07 +0200 (Ð’Ñ, 30 дек 2007) $
+Last change by : $Author: y_b $
+*/
+#ifndef _WIN32_IE
+#define _WIN32_IE 0x0300
+#endif
+#include <windows.h>
+#include <win2k.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <string.h>
+#include <uxtheme.h>
+
+#include "resource.h"
+#include <newpluginapi.h>
+#include <m_database.h>
+#include <m_langpack.h>
+
+#include <m_system.h>
+#include <m_skin.h>
+#include <m_utils.h>
+#include <m_options.h>
+#include <m_userinfo.h>
+#include <m_clist.h>
+#include <m_userinfo.h>
+#include <m_contacts.h>
+#include <m_message.h>
+#include <m_protosvc.h>
+#include <m_protocols.h>
+#include <m_popup.h>
+#include <m_system.h>
+
+#include "../tipper/docs/m_tipper.h"
+WCHAR *any_to_IdleNotidleUnknown(HANDLE hContact, const char *module_name, const char *setting_name, WCHAR *buff, int bufflen);
+WCHAR *any_to_Idle(HANDLE hContact, const char *module_name, const char *setting_name, WCHAR *buff, int bufflen);
+
+#ifdef __GNUC__
+#define NUM100NANOSEC 116444736000000000ULL
+#else
+#define NUM100NANOSEC 116444736000000000
+#endif
+
+#pragma optimize("gsy",on)
+
+#define S_MOD "SeenModule"
+
+//#define UM_CHECKHOOKS (WM_USER+1)
+
+#define debug(a) MessageBox(NULL,a,"Debug",MB_OK)
+
+#define IDI_USERDETAILS 160
+#define IDI_DOWNARROW 264
+#define IDI_RECVMSG 136
+
+#define ICON_OFFLINE 13
+#define ICON_ONLINE 14
+#define ICON_AWAY 15
+#define ICON_NA 16
+#define ICON_OCC 17
+#define ICON_DND 18
+#define ICON_FREE 19
+#define ICON_INVIS 20
+
+#define DEFAULT_MENUSTAMP "%d.%m.%Y - %H:%M [%s]"
+#define DEFAULT_POPUPSTAMP "%n is %s (%u)"
+#define DEFAULT_POPUPSTAMPTEXT "%i(%r)%bWas %o"
+#define DEFAULT_USERSTAMP "Name:%t%N%bStatus:%t%s%bDay:%t%d.%m.%Y%bTime:%t%H:%M:%S%bPrevious Status:%t%o%b%b%P ID:%t%u%bExternal IP:%t%i%bInternal IP:%t%r%bClientID: %t%C%b%bStatus Message:%t%T"
+#define DEFAULT_FILESTAMP "%d.%m.%Y %H:%M:%S%t%n%t%s%t%u%t%r | %i%t%N"
+#define DEFAULT_FILENAME "logs\\%P.txt"
+#define DEFAULT_HISTORYSTAMP "%d.%m.%Y - %H:%M [%s]"
+#define DEFAULT_WATCHEDPROTOCOLS ""
+
+#define VARIABLE_LIST "%s \n%%Y: \t %s \n%%y: \t %s \n%%m: \t %s \n%%E: \t %s \n%%e: \t %s \n%%d: \t %s \n%%W: \t %s \n%%w: \t %s \n\n%s \n%%H: \t %s \n%%h: \t %s \n%%p: \t %s \n%%M: \t %s \n%%S: \t %s \n\n%s \n%%n: \t %s \n%%N: \t %s \n%%u: \t %s \n%%G: \t %s \n%%s: \t %s \n%%T: \t %s \n%%o: \t %s \n%%i: \t %s \n%%r: \t %s \n%%C: \t %s \n%%P: \t %s \n\n%s \n%%t: \t %s \n%%b: \t %s\n\n%s\t%s \"#\" %s\n\t%s %s", Translate("-- Date --"), Translate("year (4 digits)"), Translate("year (2 digits)"), Translate("month"), Translate("name of month"), Translate("short name of month"), Translate("day"), Translate("weekday (full)"), Translate("weekday (abbreviated)"), Translate("-- Time --"), Translate("hours (24)"), Translate("hours (12)"), Translate("AM/PM"), Translate("minutes"), Translate("seconds"), Translate("-- User --"), Translate("username"), Translate("nick"), Translate("UIN/handle"), Translate("Group"), Translate("Status"), Translate("Status message"), Translate("Old status"), Translate("external IP"), Translate("internal IP"),Translate("Client info"),Translate("Protocol"), Translate("-- Format --"), Translate("tabulator"), Translate("line break"), Translate("Note:"),Translate("Use"),Translate("for empty string"),Translate("instead of"),Translate("<unknown>")
+
+#ifndef LPCOLORREF
+typedef DWORD *LPCOLORREF;
+#endif
+
+typedef struct{
+ int count;
+ WPARAM wpcontact[1024];
+ BYTE times[1024];
+} MISSEDCONTACTS;
+
+/* utils.c */
+int IsWatchedProtocol(const char* szProto);
+char *ParseString(char *,HANDLE,BYTE);
+extern DWORD StatusColors15bits[];
+void GetColorsFromDWord(LPCOLORREF First, LPCOLORREF Second, DWORD colDword);
+DWORD GetDWordFromColors(COLORREF First, COLORREF Second);
+
+BOOL includeIdle;
+typedef struct logthread_info {
+ char sProtoName[MAXMODULELABELLENGTH];
+ HANDLE hContact;
+ WORD courStatus;
+ int queueIndex;
+} logthread_info;
+
+extern logthread_info **contactQueue;
+extern int contactQueueSize;
+
diff --git a/lastseen-mod/seen_info.txt b/lastseen-mod/seen_info.txt new file mode 100644 index 0000000..02d064c --- /dev/null +++ b/lastseen-mod/seen_info.txt @@ -0,0 +1,216 @@ +Last Seen plugin
+****************
+This plugin logs when a contact was last seen online.
+You can choose between contactmenu item, userinfo page and file output.
+Second feature is to show which users were online while you were away.
+
+micron-x
+
+Questions and comments to:
+micron@nexgo.de
+
+Last Seen Mod
+*************
+I did some (quick'n'dirty) modifications to LastSeen plugin to fit better to my taste:
+
+ 1. ICQ IPs are logged correctly;
+ 2. Variables can be used in the log filename. You could have separate files for different protocols/contacts or create new file each month;
+ 3. Rewritten "Protocols to watch". Now selecting/deselecting protocols is easy ;)
+ 4. Solved enable/disable file logging bug
+ 5. Introduced 6 new variables:
+ * %P - protocol name (ICQ, ICQ1, MSN...);
+ * %N - nick on the server;
+ * %C - Client Info;
+ * %G - Group;
+ * %o - Old status;
+ * %T - Status message
+ 6. Option to use # instead of % to get empty strings instead of <unknown>
+ 7. extended support of multiple yahoo protocols(not tested);
+ 8. extended support for jabber/s.
+ 9. popup support
+ 10. delayed logging to wait for the protocols to update all the settings
+ 11. option to track idle statuses
+
+Y.B.
+http://saaplugin.no-ip.info/
+http://forums.miranda-im.org/showthread.php?t=2822
+
+
+Langpack strings
+****************
+
+see seen_langpack.txt
+
+
+
+Version history
+***************
+
+Last Seen Mod
+*************
+ * v. 5.0.4.7
+ o Added special sound for "Uses Logged In"
+ o Used the core service MS_SYSTEM_FORK_THREAD_EX
+
+ * v. 5.0.4.3
+ o Included seenTS DB setting
+ o "suppress online notification" affects only sounds and popups
+ o Sounds are working now. Two new are added.
+ * v. 5.0.4.2
+ o Implemented Idle support (Will include "/Idle" to the status if contact is idle)
+ * v. 5.0.4.1
+ o Enabled 32bit icons in lastseen history dialog (fixes the "transperancy bug")
+ o New variable: %T: Status Message
+ o Parser rewritten to be safer
+ o Click on popup will open message window
+ * v. 5.0.4.0
+ o Small memory leak in user info dialog fixed (thanks Tio Duke)
+ o Increased the delay to check offline contacts 2->10 seconds
+ o If the contact's status changer while we have been offline the time we went offline will be logged (not the current time)
+ o Fixed visual glitch in the "last seen history" dialog
+ o Suppress the DEFMOD_RNDUSERONLINE core functionality - LastSeenMod is not compatible with NewStatusNotify anylonger
+ o Option to enable clist online notify
+ * v. 5.0.3.2
+ o Better protocol type guessing (based on PFLAG_UNIQUEIDSETTING)
+ o Popups colors are configurable
+ o Tabbed interface of the option page
+ * v. 5.0.3.1 (never released)
+ o Avoid multiple popups on login - only those for contacts with different status before logoff
+ o implemented delayed logging of the status changes using thread
+ o Doesn't show popups is the contact is "hidden"
+ o Better tracking if the contact went offline while we were offline
+ o %i and %r are replaced by "resource" and "system" for Jabber/JGmail
+ * v. 5.0.3.0
+ o Enhanced PopUp support:
+ + separated fields for PopUp title and text
+ + Correct icon is chosen according to the protocol and status
+ o New Variable %o - "Old Status"
+ o JGmail is recognised as Jabber
+ * v. 5.0.2.6
+ o Basic PopUp support
+ * v. 5.0.2.5
+ o Added %G standing for "Group"
+ o Using variables in the path of the log file(s) is possible now
+ * v. 5.0.2.4
+ o Updated MSN capability bits according to this post
+ * v. 5.0.2.3
+ o Solved enable/disable file logging bug (hopefully)
+ o Option to use # instead of % to get empty strings instead of <unknown>
+ * v. 5.0.2.2
+ o Added %C (Client/version for ICQ; ClientID flags for MSN);
+ o Better support for multiple instances of same protocol;
+ o Logging contacts of protocol logon/off is back;
+ * v. 5.0.2.1
+ o Updated plugin info
+
+Last Seen plugin
+****************
+5.0.1.1:
+ - FIX: The protocol list now uses more uuser friendly names
+ - FIX: The "Missed Ones" feature options weren't saved correctly
+ - FIX: The "Offline" setting was added even to contacts whose protocol wasn't "watched"
+ - FIX: Minor cosmetics (icons and tooltips)
+ - UPDATE: seen_langpack.txt
+5.0.1.0:
+ - FIX: Some protocols added an offline entry for every contact when the user logoff the network
+ - FIX: An extra character (0 or 1) was added to each line of the file log.
+ - UPDATE: seen_langpack.txt now contains the strings added on version 5.0.0.0
+5.0.0.1:
+ - FIX: Removed some code that flooded the network with requests (see http://miranda-icq.sourceforge.net/forums/viewtopic.php?t=11579)
+ - CHANGE: History now defaults to a "pretier" format.
+5.0.0.0:
+ - FIX: Last statusmode icon displayed according to the contact's protocol
+ - NEW: Support for all protocols (user selectable)
+ - NEW: Added dialog showing the recent "seen history" of an user
+ - NEW: Added option to display an alert when a specified user changes its status
+
+4.1.6.2: - prevent plugin not loading & new base address
+
+4.1.6.1: - Silly bug with 4.1.6.0 fixed
+
+4.1.6.0: - Directory access fix
+
+4.1.5.0: - fixed 0AM/PM bug
+ - 'Missed Ones' window doesn't steal focus anymore
+ - 'Missed Ones' bugfixes
+
+4.1.4.0: - removed Miranda 0.1.2.0 support
+
+4.1.3.0: - 'Missed Ones' dismisses ignored contacts (online notification)
+ - reduced file size
+
+4.1.2.0: - Added support for Plugin sweeper
+
+4.1.1.0: - New option: count times a user was online while you were away
+ - Bug crashing Miranda on open userdetails fixed
+
+4.1.0.0: - 'Missed Ones' should finally work now
+
+4.0.9.0: - works now with Miranda v0.1.2.0
+ - unknown values grayed out
+
+4.0.8.0: - fixed bug crashing miranda on status change
+
+4.0.7.0: - two new variables: %E - name of month and %e abrreviated name of month
+ - empty userinfo page fixed
+
+4.0.6.0: - attempted fix for bad userinfo page
+ - two new variables: %W - weekday and %w - abbr. weekday
+
+4.0.5.0: - Two new variables: %h - 12 hour time and %p - AM/PM
+ - New 'Missed Ones' popup (Dialog instead of MessageBox)
+
+4.0.4.0: - Option to show last statusmode icon
+
+4.0.3.0: - 'Missed Ones' feature reimplemented
+ - Miranda crashing on close fixed
+
+4.0.2.0: - Option to keep track of contacts going offline
+ - fixed crashing when %u was used
+ - file output implemented
+ - one new langpack string
+
+4.0.1.0: - IP/RealIP variables working now
+
+4.0.0.0: - Initial release of the totally rewritten version
+ Please mail me any bug reports
+
+
+
+Rebase information
+******************
+seenplugin.dll 0x67300000
+
+enotify.dll 0x67700000
+dbviewer.dll 0x67600000
+hotkey.dll 0x67500000
+pluginsweeper.dll 0x67400000
+tipinfo.dll 0x67200000
+visibility.dll 0x67100000
+
+
+
+======================================
+"Last Seen mod" plugin for Miranda IM
+Copyright ( C ) 2002-03 micron-x
+Copyright ( C ) 2005-06 Y.B.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or ( at your option ) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+File name : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/seen_info.txt $
+Revision : $Rev: 1570 $
+Last change on : $Date: 2007-12-30 00:30:07 +0200 (Ð’Ñ, 30 дек 2007) $
+Last change by : $Author: y_b $
+
diff --git a/lastseen-mod/seen_langpack.txt b/lastseen-mod/seen_langpack.txt new file mode 100644 index 0000000..a46cb43 --- /dev/null +++ b/lastseen-mod/seen_langpack.txt @@ -0,0 +1,172 @@ +[Last seen]
+
+[Last seen options]
+
+[Last seen menuitem]
+
+[Userinfo tab]
+
+[Log to file]
+
+[year (4 digits)]
+
+[year (2 digits)]
+
+[month]
+
+[day]
+
+[minutes]
+
+[seconds]
+
+[username]
+
+[UIN/handle]
+
+[status]
+
+[external IP]
+
+[internal IP]
+
+[line break]
+
+[tabulator]
+
+[<unknown>]
+
+;New 4.0.2
+;--------------------
+[Ignore contacts going offline]
+
+;New 4.0.3
+;--------------------
+[Enable 'Missed Ones' feature]
+
+[You missed following contacts:]
+
+;New 4.0.4
+;--------------------
+[Show icon]
+
+;Modified 4.0.5
+;--------------------
+;[hours]
+[hours (24)]
+
+;New 4.0.5
+;--------------------
+[hours (12)]
+
+[AM/PM]
+
+;New 4.0.6
+;--------------------
+[weekday (full)]
+
+[weekday (abbreviated)]
+
+[Monday]
+
+[Tuesday]
+
+[Wednesday]
+
+[Thursday]
+
+[Friday]
+
+[Saturday]
+
+[Sunday]
+
+[Mon.]
+
+[Tue.]
+
+[Wed.]
+
+[Thu.]
+
+[Fri.]
+
+[Sat.]
+
+[Sun.]
+
+;New 4.0.7
+;--------------------
+[name of month]
+
+[short name of month]
+
+[January]
+
+[February]
+
+[March]
+
+[April]
+
+[May]
+
+[June]
+
+[July]
+
+[August]
+
+[September]
+
+[October]
+
+[November]
+
+[December]
+
+[Jan.]
+
+[Feb.]
+
+[Mar.]
+
+[Apr.]
+
+[May]
+
+[Jun.]
+
+[Jul.]
+
+[Aug.]
+
+[Sep.]
+
+[Oct.]
+
+[Nov.]
+
+[Dec.]
+
+;New 4.1.1
+;--------------------
+[Count times]
+
+;New 5.0.0.0
+;--------------------
+[last seen history]
+
+[Log to history]
+
+[Maximum size]
+
+[Variable list]
+
+[Protocols to watch:]
+
+[Alert when user status changes]
+
+;New 5.0.1.1
+;--------------------
+[Send Instant Message]
diff --git a/lastseen-mod/seenplugin.dev b/lastseen-mod/seenplugin.dev new file mode 100644 index 0000000..1ad28b8 --- /dev/null +++ b/lastseen-mod/seenplugin.dev @@ -0,0 +1,189 @@ +[Project]
+FileName=seenplugin.dev
+Name=seenplugin
+Ver=1
+IsCpp=1
+Type=3
+Compiler=-D__GNUWIN32__ -W -fexceptions_@@_
+CppCompiler=-D__GNUWIN32__ -W -fexceptions_@@_
+Includes=..\..\include
+Linker=-lws2_32 -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -ladvapi32 -lwinmm --image-base "0x67400000"_@@_
+Libs=
+UnitCount=14
+Folders="Header Files","Resource Files","Source Files"
+ObjFiles=
+PrivateResource=seenplugin_private.rc
+ResourceIncludes=
+MakeIncludes=
+Icon=
+ExeOutput=../../bin/release/plugins
+ObjectOutput=objs
+OverrideOutput=0
+OverrideOutputName=seenplugin.dll
+HostApplication=
+CommandLine=
+UseCustomMakefile=1
+CustomMakefile=seenplugin.win
+IncludeVersionInfo=0
+SupportXPThemes=0
+CompilerSet=0
+CompilerSettings=0010000001001000000100
+
+[Unit1]
+FileName=file.c
+Folder="Source Files"
+Compile=1
+CompileCpp=0
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit2]
+FileName=..\..\protocols\IcqOscarJ\forkthread.c
+Folder="Source Files"
+Compile=1
+CompileCpp=0
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit3]
+FileName=history.c
+Folder="Source Files"
+Compile=1
+CompileCpp=0
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit4]
+FileName=main.c
+Folder="Source Files"
+Compile=1
+CompileCpp=0
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit5]
+FileName=menu.c
+Folder="Source Files"
+Compile=1
+CompileCpp=0
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit6]
+FileName=missed.c
+Folder="Source Files"
+Compile=1
+CompileCpp=0
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit7]
+FileName=options.c
+Folder="Source Files"
+Compile=1
+CompileCpp=0
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit8]
+FileName=userinfo.c
+Folder="Source Files"
+Compile=1
+CompileCpp=0
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit9]
+FileName=utils.c
+Folder="Source Files"
+Compile=1
+CompileCpp=0
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit10]
+FileName=resource.h
+Folder="Header Files"
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit11]
+FileName=seen.h
+Folder="Header Files"
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit12]
+FileName=resource.rc
+Folder="Resource Files"
+Compile=1
+CompileCpp=1
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit13]
+FileName=seen_info.txt
+Folder=
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit14]
+FileName=seen_langpack.txt
+Folder=
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[VersionInfo]
+Major=0
+Minor=1
+Release=1
+Build=1
+LanguageID=1033
+CharsetID=1252
+CompanyName=
+FileVersion=0.1
+FileDescription=Developed using the Dev-C++ IDE
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=seenplugin.dll
+ProductName=seenplugin
+ProductVersion=0.1
+AutoIncBuildNr=0
+
diff --git a/lastseen-mod/seenplugin.dsp b/lastseen-mod/seenplugin.dsp new file mode 100644 index 0000000..b1a406c --- /dev/null +++ b/lastseen-mod/seenplugin.dsp @@ -0,0 +1,225 @@ +# Microsoft Developer Studio Project File - Name="seenplugin" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=seenplugin - Win32 Release
+!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 "seenplugin.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 "seenplugin.mak" CFG="seenplugin - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "seenplugin - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "seenplugin - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "seenplugin - Win32 PermNSN Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "seenplugin - Win32 PermNSN 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)" == "seenplugin - 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 0
+# 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 "MP_SEEN_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /Gi /GX /O1 /I "..\..\include\\" /Fr /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+# SUBTRACT MTL /mktyplib203
+# ADD BASE RSC /l 0x407 /d "NDEBUG"
+# ADD RSC /l 0x407 /d "NDEBUG"
+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 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib winmm.lib version.lib /nologo /base:"0x67400000" /dll /machine:I386 /out:"../../bin/upload/seen/seenplugin.dll" /filealign:0x200
+# SUBTRACT LINK32 /pdb:none /map
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Cmds=cd ../../bin/upload/ md5 -s -t -oseen/seenplugin.dll.md5 seen/seenplugin.dll
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "seenplugin - 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 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MP_SEEN_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MP_SEEN_EXPORTS" /FAcs /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib winmm.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib winmm.lib /nologo /base:"0x67400000" /dll /debug /machine:I386 /out:"../../bin/debug/Plugins/seenplugin.dll"
+# SUBTRACT LINK32 /profile /pdb:none /incremental:no /map
+
+!ELSEIF "$(CFG)" == "seenplugin - Win32 PermNSN Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "ReleasePermNSN"
+# PROP BASE Intermediate_Dir "ReleasePermNSN"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "releasePermNSN"
+# PROP Intermediate_Dir "releasePermNSN"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "PERMITNSN" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MP_SEEN_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /Gi /GX /O1 /I "..\..\include\\" /D "PERMITNSN" /Fr /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /win32
+# SUBTRACT MTL /mktyplib203
+# ADD BASE RSC /l 0x407 /d "NDEBUG"
+# ADD RSC /l 0x407 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib winmm.lib /nologo /dll /machine:I386
+# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib winmm.lib /nologo /base:"0x67400000" /dll /machine:I386 /out:"../../bin/upload/seen/NSNCompat/seenplugin.dll" /filealign:0x200
+# SUBTRACT LINK32 /pdb:none /map
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Cmds=cd ../../bin/upload/ md5 -s -t -oseen/NSNCompat/seenplugin.dll.md5 seen/NSNCompat/seenplugin.dll
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "seenplugin - Win32 PermNSN Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "DebugPermNSN"
+# PROP BASE Intermediate_Dir "DebugPermNSN"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "DebugPermNSN"
+# PROP Intermediate_Dir "DebugPermNSN"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MP_SEEN_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../include" /D "PERMITNSN" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MP_SEEN_EXPORTS" /FAcs /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib winmm.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib advapi32.lib winmm.lib /nologo /base:"0x67400000" /dll /debug /machine:I386 /out:"../../bin/debug/Plugins/NSNCompat/seenplugin.dll"
+# SUBTRACT LINK32 /profile /pdb:none /incremental:no /map
+
+!ENDIF
+
+# Begin Target
+
+# Name "seenplugin - Win32 Release"
+# Name "seenplugin - Win32 Debug"
+# Name "seenplugin - Win32 PermNSN Release"
+# Name "seenplugin - Win32 PermNSN Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\file.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\history.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\menu.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\missed.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\userinfo.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\utils.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\seen.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=.\resource.rc
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\seen_info.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\seen_langpack.txt
+# End Source File
+# End Target
+# End Project
diff --git a/lastseen-mod/seenplugin.dsw b/lastseen-mod/seenplugin.dsw new file mode 100644 index 0000000..bfadb79 --- /dev/null +++ b/lastseen-mod/seenplugin.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "seenplugin"=".\seenplugin.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/lastseen-mod/seenplugin.win b/lastseen-mod/seenplugin.win new file mode 100644 index 0000000..c62f4a4 --- /dev/null +++ b/lastseen-mod/seenplugin.win @@ -0,0 +1,63 @@ +# Project: seenplugin
+# Makefile created by Dev-C++ 4.9.9.2
+
+CPP = g++.exe
+CC = gcc.exe
+WINDRES = windres.exe
+RES = objs/resource.res
+OBJ = objs/file.o objs/forkthread.o objs/history.o objs/main.o objs/menu.o objs/missed.o objs/options.o objs/userinfo.o objs/utils.o $(RES)
+LINKOBJ = objs/file.o objs/forkthread.o objs/history.o objs/main.o objs/menu.o objs/missed.o objs/options.o objs/userinfo.o objs/utils.o $(RES)
+LIBS = -lws2_32 -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -ladvapi32 -lwinmm -s
+INCS = -I"../../include"
+CXXINCS = -I"../../include"
+BIN = ../../bin/release/plugins/seenplugin.dll
+CXXFLAGS = $(CXXINCS) -D__GNUWIN32__ -W -fexceptions -w -fexpensive-optimizations -Os -fweb -fmessage-length=0
+CFLAGS = $(INCS) -D__GNUWIN32__ -W -fexceptions -w -fexpensive-optimizations -Os -fweb -fmessage-length=0
+RM = rm -f
+
+.PHONY: all all-before all-after clean clean-custom
+
+all: all-before ../../bin/release/plugins/seenplugin.dll all-after
+
+
+clean: clean-custom
+ ${RM} $(OBJ) $(BIN)
+
+DLLWRAP=dllwrap.exe
+DEFFILE=../../bin/release/libseenplugin.def
+STATICLIB=../../bin/release/libseenplugin.a
+
+$(BIN): $(LINKOBJ)
+# $(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
+ $(CPP) $(LINKOBJ) $(LIBS) -mdll -o $(BIN)
+
+objs/file.o: file.c
+ $(CC) -c file.c -o objs/file.o $(CFLAGS)
+
+objs/forkthread.o: ../../protocols/IcqOscarJ/forkthread.c
+ $(CC) -c ../../protocols/IcqOscarJ/forkthread.c -o objs/forkthread.o $(CFLAGS)
+
+objs/history.o: history.c
+ $(CC) -c history.c -o objs/history.o $(CFLAGS)
+
+objs/main.o: main.c
+ $(CC) -c main.c -o objs/main.o $(CFLAGS)
+
+objs/menu.o: menu.c
+ $(CC) -c menu.c -o objs/menu.o $(CFLAGS)
+
+objs/missed.o: missed.c
+ $(CC) -c missed.c -o objs/missed.o $(CFLAGS)
+
+objs/options.o: options.c
+ $(CC) -c options.c -o objs/options.o $(CFLAGS)
+
+objs/userinfo.o: userinfo.c
+ $(CC) -c userinfo.c -o objs/userinfo.o $(CFLAGS)
+
+objs/utils.o: utils.c
+ $(CC) -c utils.c -o objs/utils.o $(CFLAGS)
+
+objs/resource.res: resource.rc
+ $(WINDRES) -i resource.rc --input-format=rc -o objs/resource.res -O coff
+
diff --git a/lastseen-mod/userinfo.c b/lastseen-mod/userinfo.c new file mode 100644 index 0000000..eb1bf57 --- /dev/null +++ b/lastseen-mod/userinfo.c @@ -0,0 +1,95 @@ +/*
+"Last Seen mod" plugin for Miranda IM
+Copyright ( C ) 2002-03 micron-x
+Copyright ( C ) 2005-07 Y.B.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or ( at your option ) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+File name : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/userinfo.c $
+Revision : $Rev: 1570 $
+Last change on : $Date: 2007-12-30 00:30:07 +0200 (Ð’Ñ, 30 дек 2007) $
+Last change by : $Author: y_b $
+*/
+#include "seen.h"
+
+
+
+WNDPROC MainProc;
+
+
+
+extern HINSTANCE hInstance;
+extern DWORD dwmirver;
+
+
+
+BOOL CALLBACK EditProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
+{
+ switch(msg){
+ case WM_SETCURSOR:
+ SetCursor(LoadCursor(NULL,IDC_ARROW));
+ return 1;
+
+ default:
+ break;
+ }
+ return CallWindowProc(MainProc,hdlg,msg,wparam,lparam);
+}
+
+
+
+BOOL CALLBACK UserinfoDlgProc(HWND hdlg,UINT msg,WPARAM wparam,LPARAM lparam)
+{
+ char *szout;
+ DBVARIANT dbv;
+
+ switch(msg){
+
+ case WM_INITDIALOG:
+ MainProc=(WNDPROC)SetWindowLong(GetDlgItem(hdlg,IDC_INFOTEXT),GWL_WNDPROC,(LONG)EditProc);
+ szout=strdup(ParseString((!DBGetContactSetting(NULL,S_MOD,"UserStamp",&dbv)?dbv.pszVal:DEFAULT_USERSTAMP),(HANDLE)lparam,0));
+ SetDlgItemText(hdlg,IDC_INFOTEXT,szout);
+ if(!strcmp(szout,Translate("<unknown>")))
+ EnableWindow(GetDlgItem(hdlg,IDC_INFOTEXT),FALSE);
+ free(szout);
+ DBFreeVariant(&dbv);
+ break;
+
+ case WM_COMMAND:
+ if(HIWORD(wparam)==EN_SETFOCUS)
+ SetFocus(GetParent(hdlg));
+ break;
+ }
+
+ return 0;
+}
+
+
+
+int UserinfoInit(WPARAM wparam,LPARAM lparam)
+{
+ char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,lparam,0);
+ if (IsWatchedProtocol(proto)){
+ OPTIONSDIALOGPAGE uip;
+ ZeroMemory(&uip,sizeof(uip));
+ uip.cbSize=sizeof(uip);
+ uip.hInstance=hInstance;
+ uip.pszTemplate=MAKEINTRESOURCE(IDD_USERINFO);
+ uip.pszTitle=Translate("Last seen");
+ uip.pfnDlgProc=UserinfoDlgProc;
+ CallService(MS_USERINFO_ADDPAGE,wparam,(LPARAM)&uip);
+ }
+ return 0;
+}
diff --git a/lastseen-mod/utils.c b/lastseen-mod/utils.c new file mode 100644 index 0000000..d99884a --- /dev/null +++ b/lastseen-mod/utils.c @@ -0,0 +1,967 @@ +/*
+"Last Seen mod" plugin for Miranda IM
+Copyright ( C ) 2002-03 micron-x
+Copyright ( C ) 2005-07 Y.B.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or ( at your option ) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+File name : $URL: http://svn.berlios.de/svnroot/repos/mgoodies/trunk/lastseen-mod/utils.c $
+Revision : $Rev: 1570 $
+Last change on : $Date: 2007-12-30 00:30:07 +0200 (Ð’Ñ, 30 дек 2007) $
+Last change by : $Author: y_b $
+*/
+#include "seen.h"
+#include <m_ignore.h>
+#include <time.h>
+
+
+void FileWrite(HANDLE);
+void HistoryWrite(HANDLE hcontact);
+//void SetOffline(void);
+void ShowHistory(HANDLE hContact, BYTE isAlert);
+
+char * courProtoName = 0;
+
+//copied from ..\..\miranda32\protocols\protocols\protocols.c
+PROTOCOLDESCRIPTOR* Proto_IsProtocolLoaded(const char* szProto)
+{
+ return (PROTOCOLDESCRIPTOR*) CallService(MS_PROTO_ISPROTOCOLLOADED, 0, (LPARAM)szProto);
+}
+
+
+/*
+Returns true if the protocols is to be monitored
+*/
+int IsWatchedProtocol(const char* szProto)
+{
+ DBVARIANT dbv;
+ char *szProtoPointer, *szWatched;
+ int iProtoLen, iWatchedLen;
+ int retval = 0;
+ PROTOCOLDESCRIPTOR *pd;
+
+ if (szProto == NULL)
+ return 0;
+
+ pd=Proto_IsProtocolLoaded(szProto);
+ if (pd==NULL || pd->type!=PROTOTYPE_PROTOCOL || CallProtoService(pd->szName,PS_GETCAPS,PFLAGNUM_2,0)==0)
+ return 0;
+
+ iProtoLen = strlen(szProto);
+ if(DBGetContactSetting(NULL, S_MOD, "WatchedProtocols", &dbv))
+ szWatched = DEFAULT_WATCHEDPROTOCOLS;
+ else
+ szWatched = dbv.pszVal;
+ iWatchedLen = strlen(szWatched);
+
+ if (*szWatched == '\0')
+ {
+ retval=1; //empty string: all protocols are watched
+ }
+ else
+ {
+ char sTemp [MAXMODULELABELLENGTH+1]="";
+ strcat(sTemp,szProto);
+ strcat(sTemp," ");
+ szProtoPointer = strstr(szWatched, sTemp);
+ if (szProtoPointer == NULL)
+ retval=0;
+ else
+ retval=1;
+ }
+
+ DBFreeVariant(&dbv);
+ return retval;
+}
+
+BOOL isYahoo(char * protoname){
+ if (protoname) {
+ char *pszUniqueSetting = (char*)CallProtoService(protoname, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
+ if (pszUniqueSetting){
+ return (!strcmp(pszUniqueSetting,"yahoo_id"));
+ } }
+ return FALSE;
+}
+BOOL isJabber(char * protoname){
+ if (protoname) {
+ char *pszUniqueSetting = (char*)CallProtoService(protoname, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
+ if (pszUniqueSetting){
+ return (!strcmp(pszUniqueSetting,"jid"));
+ } }
+ return FALSE;
+}
+BOOL isICQ(char * protoname){
+ if (protoname) {
+ char *pszUniqueSetting = (char*)CallProtoService(protoname, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
+ if (pszUniqueSetting){
+ return (!strcmp(pszUniqueSetting,"UIN"));
+ } }
+ return FALSE;
+}
+BOOL isMSN(char * protoname){
+ if (protoname) {
+ char *pszUniqueSetting = (char*)CallProtoService(protoname, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0);
+ if (pszUniqueSetting){
+ return (!strcmp(pszUniqueSetting,"e-mail"));
+ } }
+ return FALSE;
+}
+
+DWORD isSeen(HANDLE hcontact, SYSTEMTIME *st){
+ DWORD res = 0;
+ FILETIME ft;
+ ULONGLONG ll;
+ res = DBGetContactSettingDword(hcontact,S_MOD,"seenTS",0);
+ if (res){
+ if (st) {
+ ll = UInt32x32To64(CallService(MS_DB_TIME_TIMESTAMPTOLOCAL,res,0), 10000000) + NUM100NANOSEC;
+ ft.dwLowDateTime = (DWORD)ll;
+ ft.dwHighDateTime = (DWORD)(ll >> 32);
+ FileTimeToSystemTime(&ft, st);
+ }
+ return res;
+ } else {
+ SYSTEMTIME lst;
+ ZeroMemory(&lst,sizeof(lst));
+ if (lst.wYear = DBGetContactSettingWord(hcontact,S_MOD,"Year",0)) {
+ if (lst.wMonth = DBGetContactSettingWord(hcontact,S_MOD,"Month",0)) {
+ if (lst.wDay = DBGetContactSettingWord(hcontact,S_MOD,"Day",0)) {
+ lst.wDayOfWeek = DBGetContactSettingWord(hcontact,S_MOD,"WeekDay",0);
+ lst.wHour = DBGetContactSettingWord(hcontact,S_MOD,"Hours",0);
+ lst.wMinute = DBGetContactSettingWord(hcontact,S_MOD,"Minutes",0);
+ lst.wSecond = DBGetContactSettingWord(hcontact,S_MOD,"Seconds",0);
+ if (SystemTimeToFileTime(&lst,&ft)){
+ ll = ((LONGLONG)ft.dwHighDateTime<<32)|((LONGLONG)ft.dwLowDateTime);
+ ll -= NUM100NANOSEC;
+ ll /= 10000000;
+ //perform LOCALTOTIMESTAMP
+ res = (DWORD)ll - CallService(MS_DB_TIME_TIMESTAMPTOLOCAL,0,0);
+ //nevel look for Year/Month/Day/Hour/Minute/Second again
+ DBWriteContactSettingDword(hcontact,S_MOD,"seenTS",res);
+ }
+ } } }
+ if (st) CopyMemory (st, &lst, sizeof (SYSTEMTIME));
+ }
+ return res;
+}
+
+char *ParseString(char *szstring,HANDLE hcontact,BYTE isfile)
+{
+#define MAXSIZE 1024
+ static char sztemp[MAXSIZE+1];
+ int sztemplen = 0;
+ char szdbsetting[128]="";
+ char *charPtr;
+ UINT loop=0;
+ int isetting=0;
+ DWORD dwsetting=0;
+ struct in_addr ia;
+ char *weekdays[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
+ char *wdays_short[]={"Sun.","Mon.","Tue.","Wed.","Thu.","Fri.","Sat."};
+ char *monthnames[]={"January","February","March","April","May","June","July","August","September","October","November","December"};
+ char *mnames_short[]={"Jan.","Feb.","Mar.","Apr.","May","Jun.","Jul.","Aug.","Sep.","Oct.","Nov.","Dec."};
+ CONTACTINFO ci;
+ BOOL wantempty;
+ SYSTEMTIME st;
+
+ sztemp[0] = '\0';
+ if (!isSeen(hcontact,&st)){
+ strcat(sztemp,Translate("<never seen>"));
+ return sztemp;
+ }
+
+ ci.cbSize=sizeof(CONTACTINFO);
+ ci.hContact=hcontact;
+ ci.szProto=hcontact?(char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hcontact,0):courProtoName;
+ for(;loop<strlen(szstring);loop++)
+ {
+ if (sztemplen == MAXSIZE) break;
+ if((szstring[loop]!='%')&(szstring[loop]!='#'))
+ {
+ strncat(sztemp,szstring+loop,1);
+ sztemplen++;
+ continue;
+ }
+
+ else
+ {
+ wantempty = (szstring[loop]=='#');
+ switch(szstring[++loop]){
+ case 'Y':
+ if (!st.wYear) goto LBL_noData;
+ sztemplen += mir_snprintf(sztemp+sztemplen,MAXSIZE-sztemplen,"%04i",st.wYear);
+ break;
+
+ case 'y':
+ if (!st.wYear) goto LBL_noData;
+ wsprintf(szdbsetting,"%04i",st.wYear);
+ sztemplen += mir_snprintf(sztemp+sztemplen,MAXSIZE-sztemplen,"%s",szdbsetting+2);
+ break;
+
+ case 'm':
+ if (!(isetting=st.wMonth)) goto LBL_noData;
+LBL_2DigNum:
+ sztemplen += mir_snprintf(sztemp+sztemplen,MAXSIZE-sztemplen,"%02i",isetting);
+ break;
+
+ case 'd':
+ if (isetting=st.wDay) goto LBL_2DigNum;
+ else goto LBL_noData;
+
+ case 'W':
+ isetting=st.wDayOfWeek;
+ if(isetting==-1){
+LBL_noData:
+ charPtr = wantempty?"":Translate("<unknown>");
+ goto LBL_charPtr;
+ }
+ charPtr = Translate(weekdays[isetting]);
+LBL_charPtr:
+ sztemplen += mir_snprintf(sztemp+sztemplen,MAXSIZE-sztemplen,"%s",charPtr);
+ break;
+
+ case 'w':
+ isetting=st.wDayOfWeek;
+ if(isetting==-1)goto LBL_noData;
+ charPtr = Translate(wdays_short[isetting]);
+ goto LBL_charPtr;
+
+ case 'E':
+ if(!(isetting=st.wMonth))goto LBL_noData;
+ charPtr = Translate(monthnames[isetting-1]);
+ goto LBL_charPtr;
+
+ case 'e':
+ if(!(isetting=st.wMonth))goto LBL_noData;
+ charPtr = Translate(mnames_short[isetting-1]);
+ goto LBL_charPtr;
+
+ case 'H':
+ if((isetting=st.wHour)==-1)goto LBL_noData;
+ goto LBL_2DigNum;
+
+ case 'h':
+ if((isetting=st.wHour)==-1)goto LBL_noData;
+ if(!isetting) isetting=12;
+ isetting = isetting-((isetting>12)?12:0);
+ goto LBL_2DigNum;
+
+ case 'p':
+ if((isetting=st.wHour)==-1)goto LBL_noData;
+ charPtr = (isetting>=12)?"PM":"AM";
+ goto LBL_charPtr;
+
+ case 'M':
+ if((isetting=st.wMinute)==-1)goto LBL_noData;
+ goto LBL_2DigNum;
+
+ case 'S':
+ if((isetting=st.wHour)==-1)goto LBL_noData;
+ goto LBL_2DigNum;
+
+ case 'n':
+ charPtr = hcontact?(char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hcontact,0):(wantempty?"":"---");
+ goto LBL_charPtr;
+ case 'N':
+ ci.dwFlag=CNF_NICK;
+ if(!CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci)){
+ charPtr = ci.pszVal;
+ } else goto LBL_noData;
+ goto LBL_charPtr;
+ case 'G':
+ {
+ DBVARIANT dbv;
+ if (!DBGetContactSetting(hcontact,"CList","Group",&dbv)){
+ strcpy(szdbsetting,dbv.pszVal);
+ DBFreeVariant(&dbv);
+ charPtr = szdbsetting;
+ goto LBL_charPtr;
+ } else; //do nothing
+ }
+ break;
+
+ case 'u':
+ ci.dwFlag=CNF_UNIQUEID;
+ if(!CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci))
+ {
+ switch(ci.type)
+ {
+ case CNFT_BYTE:
+ ltoa(ci.bVal,szdbsetting,10);
+ break;
+ case CNFT_WORD:
+ ltoa(ci.wVal,szdbsetting,10);
+ break;
+ case CNFT_DWORD:
+ ltoa(ci.dVal,szdbsetting,10);
+ break;
+ case CNFT_ASCIIZ:
+ strcpy(szdbsetting,ci.pszVal);
+ break;
+ }
+
+ }
+ else if (ci.szProto != NULL)
+ {
+ if (isYahoo(ci.szProto)) // YAHOO support
+ {
+ DBVARIANT dbv;
+ DBGetContactSetting(hcontact,ci.szProto,"id",&dbv);
+ strcpy(szdbsetting,dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else if (isJabber(ci.szProto)) // JABBER support
+ {
+ DBVARIANT dbv;
+ if (DBGetContactSetting(hcontact,ci.szProto,"LoginName",&dbv)) goto LBL_noData;
+ strcpy(szdbsetting,dbv.pszVal);
+ DBFreeVariant(&dbv);
+ DBGetContactSetting(hcontact,ci.szProto,"LoginServer",&dbv);
+ strcat(szdbsetting,"@");
+ strcat(szdbsetting,dbv.pszVal);
+ DBFreeVariant(&dbv);
+ } else goto LBL_noData;
+ }
+ else goto LBL_noData;
+ charPtr = szdbsetting;
+ goto LBL_charPtr;
+
+ case 's':
+ if (isetting=DBGetContactSettingWord(hcontact,S_MOD,hcontact?"StatusTriger":courProtoName,0)){
+ strcpy(szdbsetting,Translate((const char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,(WPARAM)(isetting|0x8000),0)));
+ if (!(isetting&0x8000)){
+ strcat(szdbsetting,"/");
+ strcat(szdbsetting,Translate("Idle"));
+ }
+ charPtr = szdbsetting;
+ } else goto LBL_noData;
+ goto LBL_charPtr;
+ case 'T':
+ {
+ DBVARIANT dbv;
+ if (!DBGetContactSetting(hcontact,"CList","StatusMsg",&dbv)){
+ sztemplen += mir_snprintf(sztemp+sztemplen,MAXSIZE-sztemplen,"%s",dbv.pszVal);
+ DBFreeVariant(&dbv);
+ } else goto LBL_noData;
+ }
+ break;
+ case 'o':
+ if (isetting=DBGetContactSettingWord(hcontact,S_MOD,hcontact?"OldStatus":courProtoName,0)){
+ strcpy(szdbsetting,Translate((const char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,(WPARAM)isetting,0)));
+ if (includeIdle) if (hcontact) if (DBGetContactSettingByte(hcontact,S_MOD,"OldIdle",0)){
+ strcat(szdbsetting,"/");
+ strcat(szdbsetting,Translate("Idle"));
+ }
+ charPtr = szdbsetting;
+ } else goto LBL_noData;
+ goto LBL_charPtr;
+
+ case 'i':
+ case 'r': if (isJabber(ci.szProto)){
+ DBVARIANT dbv;
+ if (!DBGetContactSetting(hcontact,ci.szProto,szstring[loop]=='i'?"Resource":"System",&dbv)){
+ strcpy(szdbsetting,dbv.pszVal);
+ DBFreeVariant(&dbv);
+ charPtr = szdbsetting;
+ } else goto LBL_noData;
+ } else {
+ dwsetting=DBGetContactSettingDword(hcontact,ci.szProto,szstring[loop]=='i'?"IP":"RealIP",0);
+ if(dwsetting){
+ ia.S_un.S_addr=htonl(dwsetting);
+ charPtr = inet_ntoa(ia);
+ } else goto LBL_noData;
+ }
+ goto LBL_charPtr;
+ case 'P':if (ci.szProto) charPtr = ci.szProto; else charPtr = wantempty?"":"ProtoUnknown";
+ goto LBL_charPtr;
+ case 'b':
+ charPtr = /*"\n"*/"\x0D\x0A";
+ goto LBL_charPtr;
+ case 'C': // Get Client Info
+ if (isMSN(ci.szProto)) {
+ if (hcontact) {
+ dwsetting = (int)DBGetContactSettingDword(hcontact,ci.szProto,"FlagBits",0);
+ wsprintf(szdbsetting,"MSNC%i",(dwsetting&0x70000000)>>28);
+ if (dwsetting & 0x00000001) strcat(szdbsetting," MobD"); //Mobile Device
+ if (dwsetting & 0x00000004) strcat(szdbsetting," InkG"); //GIF Ink Send/Receive
+ if (dwsetting & 0x00000008) strcat(szdbsetting," InkI"); //ISF Ink Send/Receive
+ if (dwsetting & 0x00000010) strcat(szdbsetting," WCam"); //Webcam
+ if (dwsetting & 0x00000020) strcat(szdbsetting," MPkt"); //Multi packet messages
+ if (dwsetting & 0x00000040) strcat(szdbsetting," SMSr"); //Paging
+ if (dwsetting & 0x00000080) strcat(szdbsetting," DSMS"); //Using MSN Direct
+ if (dwsetting & 0x00000200) strcat(szdbsetting," WebM"); //WebMessenger
+ if (dwsetting & 0x00001000) strcat(szdbsetting," MS7+"); //Unknown (Msgr 7 always[?] sets it)
+ if (dwsetting & 0x00004000) strcat(szdbsetting," DirM"); //DirectIM
+ if (dwsetting & 0x00008000) strcat(szdbsetting," Wink"); //Send/Receive Winks
+ if (dwsetting & 0x00010000) strcat(szdbsetting," MSrc"); //MSN Search ??
+ if (dwsetting & 0x00040000) strcat(szdbsetting," VoiC"); //Voice Clips
+ } else strcpy(szdbsetting,"Miranda");
+ } else {
+ DBVARIANT dbv;
+ if (!DBGetContactSetting(hcontact,ci.szProto,"MirVer",&dbv)){
+ strcpy(szdbsetting,dbv.pszVal);
+ DBFreeVariant(&dbv);
+ } else goto LBL_noData;
+ }
+ charPtr = szdbsetting;
+ goto LBL_charPtr;
+ case 't':
+ charPtr = "\t";
+ goto LBL_charPtr;
+
+ default:
+ strncpy(szdbsetting,szstring+loop-1,2);
+ goto LBL_charPtr;
+ }
+ }
+ }
+
+ return sztemp;
+}
+
+
+
+void _DBWriteTime(SYSTEMTIME *st,HANDLE hcontact)
+{
+ DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"Day",st->wDay);
+ DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"Month",st->wMonth);
+ DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"Year",st->wYear);
+ DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"Hours",st->wHour);
+ DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"Minutes",st->wMinute);
+ DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"Seconds",st->wSecond);
+ DBWriteContactSettingWord((HANDLE)hcontact,S_MOD,"WeekDay",st->wDayOfWeek);
+
+}
+
+void DBWriteTimeTS(DWORD t, HANDLE hcontact){
+ SYSTEMTIME st;
+ FILETIME ft;
+ ULONGLONG ll = UInt32x32To64(CallService(MS_DB_TIME_TIMESTAMPTOLOCAL,t,0), 10000000) + NUM100NANOSEC;
+ ft.dwLowDateTime = (DWORD)ll;
+ ft.dwHighDateTime = (DWORD)(ll >> 32);
+ FileTimeToSystemTime(&ft, &st);
+ DBWriteContactSettingDword(hcontact,S_MOD,"seenTS",t);
+ _DBWriteTime(&st, hcontact);
+}
+void GetColorsFromDWord(LPCOLORREF First, LPCOLORREF Second, DWORD colDword){
+ WORD temp;
+ COLORREF res=0;
+ temp = (WORD)(colDword>>16);
+ res |= ((temp & 0x1F) <<3);
+ res |= ((temp & 0x3E0) <<6);
+ res |= ((temp & 0x7C00) <<9);
+ if (First) *First = res;
+ res = 0;
+ temp = (WORD)colDword;
+ res |= ((temp & 0x1F) <<3);
+ res |= ((temp & 0x3E0) <<6);
+ res |= ((temp & 0x7C00) <<9);
+ if (Second) *Second = res;
+}
+
+DWORD StatusColors15bits[] = {
+ 0x63180000, // 0x00C0C0C0, 0x00000000, Offline - LightGray
+ 0x7B350000, // 0x00F0C8A8, 0x00000000, Online - LightBlue
+ 0x33fe0000, // 0x0070E0E0, 0x00000000, Away -LightOrange
+ 0x295C0000, // 0x005050E0, 0x00000000, DND -DarkRed
+ 0x5EFD0000, // 0x00B8B8E8, 0x00000000, NA -LightRed
+ 0x295C0000, // 0x005050E0, 0x00000000, Occupied
+ 0x43900000, // 0x0080E080, 0x00000000, Free for chat - LightGreen
+ 0x76AF0000, // 0x00E8A878, 0x00000000, Invisible
+ 0x431C0000, // 0x0080C0E0, 0x00000000, On the phone
+ 0x5EFD0000, // 0x00B8B8E8, 0x00000000, Out to lunch
+};
+
+DWORD GetDWordFromColors(COLORREF First, COLORREF Second){
+ DWORD res = 0;
+ res |= (First&0xF8)>>3;
+ res |= (First&0xF800)>>6;
+ res |= (First&0xF80000)>>9;
+ res <<= 16;
+ res |= (Second&0xF8)>>3;
+ res |= (Second&0xF800)>>6;
+ res |= (Second&0xF80000)>>9;
+ return res;
+}
+
+LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
+
+ switch(message) {
+ case WM_COMMAND:
+ if (HIWORD(wParam) == STN_CLICKED){
+ HANDLE hContact = PUGetContact(hwnd);
+ if (hContact > 0) CallService(MS_MSG_SENDMESSAGE,(WPARAM)hContact,0);
+ }
+ case WM_CONTEXTMENU:
+ PUDeletePopUp(hwnd);
+ break;
+ case UM_INITPOPUP: return 0;
+ }
+ return DefWindowProc(hwnd, message, wParam, lParam);
+};
+
+void ShowPopup(HANDLE hcontact, const char * lpzProto, int newStatus){
+ if(CallService(MS_IGNORE_ISIGNORED,(WPARAM)hcontact,IGNOREEVENT_USERONLINE)) return;
+ if (ServiceExists(MS_POPUP_QUERY)){
+ if (DBGetContactSettingByte(NULL,S_MOD,"UsePopups",0)){
+ if (!DBGetContactSettingByte(hcontact,"CList","Hidden",0)){
+ POPUPDATAEX ppd = {0};
+ DBVARIANT dbv = {0};
+ char szstamp[10];
+ DWORD sett;
+ sprintf(szstamp, "Col_%d",newStatus-ID_STATUS_OFFLINE);
+ sett = DBGetContactSettingDword(NULL,S_MOD,szstamp,StatusColors15bits[newStatus-ID_STATUS_OFFLINE]);
+ GetColorsFromDWord(&ppd.colorBack,&ppd.colorText,sett);
+ ppd.lchContact = hcontact;
+ ppd.lchIcon = LoadSkinnedProtoIcon(lpzProto, newStatus);
+ strncpy(ppd.lpzContactName,ParseString(!DBGetContactSetting(NULL,S_MOD,"PopupStamp",&dbv)?dbv.pszVal:DEFAULT_POPUPSTAMP,hcontact,0),MAX_CONTACTNAME);
+ DBFreeVariant(&dbv);
+ strncpy(ppd.lpzText,ParseString(!DBGetContactSetting(NULL,S_MOD,"PopupStampText",&dbv)?dbv.pszVal:DEFAULT_POPUPSTAMPTEXT,hcontact,0),MAX_SECONDLINE);
+ DBFreeVariant(&dbv);
+ ppd.PluginWindowProc = (WNDPROC)PopupDlgProc;
+ CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)&ppd, 0);
+ }
+ }
+ }
+}
+
+void myPlaySound(HANDLE hcontact, WORD newStatus, WORD oldStatus){
+ if(CallService(MS_IGNORE_ISIGNORED,(WPARAM)hcontact,IGNOREEVENT_USERONLINE)) return;
+ //oldStatus and hcontact are not used yet
+ if (DBGetContactSettingByte(NULL,"Skin","UseSound",1)){
+ char * soundname=0;
+ if ((newStatus==ID_STATUS_ONLINE) || (newStatus==ID_STATUS_FREECHAT)) soundname = "LastSeenTrackedStatusOnline";
+ else if (newStatus==ID_STATUS_OFFLINE) soundname = "LastSeenTrackedStatusOffline";
+ else if (oldStatus==ID_STATUS_OFFLINE) soundname = "LastSeenTrackedStatusFromOffline";
+ else soundname = "LastSeenTrackedStatusChange";
+ if (!DBGetContactSettingByte(NULL,"SkinSoundsOff",soundname,0)){
+ DBVARIANT dbv;
+ if (!DBGetContactSetting(NULL,"SkinSounds",soundname,&dbv)){
+ PlaySoundA(dbv.pszVal, NULL, SND_ASYNC | SND_FILENAME | SND_NOWAIT);
+ DBFreeVariant(&dbv);
+} } } }
+
+//will give hContact position or zero
+int isContactQueueActive(HANDLE hContact){
+ int i = 0;
+ if (!hContact) {
+// MessageBox(0,"Is myself in the queue: never","LastSeen-Mod",0);
+ return 0;
+ }
+ for (i=1;i<contactQueueSize;i++){
+ if (contactQueue[i])
+ if (contactQueue[i]->hContact==hContact) return i;
+ }
+ return 0;
+}
+
+//will add hContact to queue and will return position;
+int addContactToQueue(HANDLE hContact){
+ int i = 0;
+ if (!hContact) {
+// MessageBox(0,"Adding myself to queue","LastSeen-Mod",0);
+ return 0;
+ }
+ for (i=1;i<contactQueueSize;i++){
+ if (!contactQueue[i]) {
+ contactQueue[i] = malloc(sizeof(logthread_info));
+ contactQueue[i]->queueIndex = i;
+ contactQueue[i]->hContact = hContact;
+ return i;
+ }
+ }
+ //no free space. Create some
+ //MessageBox(0,"Creating more space","LastSeen-Mod",0);
+ contactQueue = (logthread_info **)realloc(contactQueue,(contactQueueSize+16)*sizeof(logthread_info *));
+ memset(&contactQueue[contactQueueSize],0, 16*sizeof(logthread_info *));
+ i = contactQueueSize;
+ contactQueue[i] = malloc(sizeof(logthread_info));
+ contactQueue[i]->queueIndex = i;
+ contactQueue[i]->hContact = hContact;
+ contactQueueSize += 16;
+ return i;
+}
+
+static DWORD __stdcall waitThread(logthread_info* infoParam)
+{
+// char str[MAXMODULELABELLENGTH];
+// sprintf(str,"In Thread: %s; %s; %s\n",
+// infoParam->sProtoName,
+// (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)infoParam->hContact,0),
+// (const char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,(WPARAM)infoParam->courStatus,0)
+// );
+// OutputDebugStringA(str);
+ WORD prevStatus = DBGetContactSettingWord(infoParam->hContact,S_MOD,"StatusTriger",ID_STATUS_OFFLINE);
+ Sleep(1500); // I hope in 1.5 second all the needed info will be set
+ if (includeIdle){
+ if (DBGetContactSettingDword(infoParam->hContact,infoParam->sProtoName,"IdleTS",0)) {
+ infoParam->courStatus &=0x7FFF;
+ }
+ }
+ if (infoParam->courStatus != prevStatus){
+ DBWriteContactSettingWord(infoParam->hContact,S_MOD,"OldStatus",(WORD)(prevStatus|0x8000));
+ if (includeIdle){
+ DBWriteContactSettingByte(infoParam->hContact,S_MOD,"OldIdle",(BYTE)((prevStatus&0x8000)==0));
+ }
+ DBWriteContactSettingWord(infoParam->hContact,S_MOD,"StatusTriger",infoParam->courStatus);
+ }
+// sprintf(str,"OutThread: %s; %s; %s\n",
+// infoParam->sProtoName,
+// (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)infoParam->hContact,0),
+// (const char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,(WPARAM)infoParam->courStatus,0)
+// );
+// infoParam->hContact = 0; //declare the slot as empty
+ contactQueue[infoParam->queueIndex] = 0;
+ free(infoParam);
+// OutputDebugStringA(str);
+ return 0;
+}
+
+#ifndef PERMITNSN
+static int uniqueEventId=0;
+#endif
+
+int UpdateValues(HANDLE hContact,LPARAM lparam)
+{
+ FORK_THREADEX_PARAMS params;
+ DWORD dwThreadId;
+ DBCONTACTWRITESETTING *cws;
+ BOOL isIdleEvent;
+ // to make this code faster
+ if (!hContact) return 0;
+ cws=(DBCONTACTWRITESETTING *)lparam;
+ //if(CallService(MS_IGNORE_ISIGNORED,(WPARAM)hContact,IGNOREEVENT_USERONLINE)) return 0;
+ isIdleEvent = includeIdle?(strcmp(cws->szSetting,"IdleTS")==0):0;
+ if (strcmp(cws->szSetting,"Status") && strcmp(cws->szSetting,"StatusTriger") && (isIdleEvent==0)) return 0;
+ if (!strcmp(cws->szModule,S_MOD)){
+ //here we will come when Settings/SeenModule/StatusTriger is changed
+ WORD prevStatus=DBGetContactSettingWord(hContact,S_MOD,"OldStatus",ID_STATUS_OFFLINE);
+ if (includeIdle){
+ if (DBGetContactSettingByte(hContact,S_MOD,"OldIdle",0)) prevStatus &= 0x7FFF;
+ else prevStatus |= 0x8000;
+ }
+ if((cws->value.wVal|0x8000)<=ID_STATUS_OFFLINE)
+ {
+ char * proto;
+ // avoid repeating the offline status
+ if ((prevStatus|0x8000)<=ID_STATUS_OFFLINE)
+ return 0;
+ proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0);
+ DBWriteContactSettingByte(hContact,S_MOD,"Offline",1);
+ {
+ DWORD t;
+ char *str = malloc(MAXMODULELABELLENGTH+9);
+ mir_snprintf(str,MAXMODULELABELLENGTH+8,"OffTime-%s",proto);
+ t = DBGetContactSettingDword(NULL,S_MOD,str,0);
+ if (!t) t = time(NULL);
+ free(str);
+ DBWriteTimeTS(t,hContact);
+ }
+
+ if(!DBGetContactSettingByte(NULL,S_MOD,"IgnoreOffline",1))
+ {
+ char * sProto;
+ if(DBGetContactSettingByte(NULL,S_MOD,"FileOutput",0))
+ FileWrite(hContact);
+
+ if (CallProtoService(sProto =
+ (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0),
+ PS_GETSTATUS,0,0
+ )>ID_STATUS_OFFLINE) {
+ myPlaySound(hContact,ID_STATUS_OFFLINE,prevStatus);
+ if(DBGetContactSettingByte(NULL,S_MOD,"UsePopups",0)){
+ ShowPopup(hContact,sProto,ID_STATUS_OFFLINE);
+ } }
+
+ if(DBGetContactSettingByte(NULL,S_MOD,"KeepHistory",0))
+ HistoryWrite(hContact);
+
+ if(DBGetContactSettingByte(hContact,S_MOD,"OnlineAlert",0))
+ ShowHistory(hContact, 1);
+ }
+
+ } else {
+
+ if(cws->value.wVal==prevStatus && !DBGetContactSettingByte(hContact,S_MOD,"Offline",0))
+ return 0;
+
+ DBWriteTimeTS(time(NULL),hContact);
+
+ //DBWriteContactSettingWord(hContact,S_MOD,"StatusTriger",(WORD)cws->value.wVal);
+
+ if(DBGetContactSettingByte(NULL,S_MOD,"FileOutput",0)) FileWrite(hContact);
+ if (prevStatus != cws->value.wVal) myPlaySound(hContact,cws->value.wVal,prevStatus);
+ if(DBGetContactSettingByte(NULL,S_MOD,"UsePopups",0))
+ if (prevStatus != cws->value.wVal) ShowPopup(hContact,(char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0),cws->value.wVal|0x8000);
+
+ if(DBGetContactSettingByte(NULL,S_MOD,"KeepHistory",0)) HistoryWrite(hContact);
+ if(DBGetContactSettingByte(hContact,S_MOD,"OnlineAlert",0)) ShowHistory(hContact, 1);
+ DBWriteContactSettingByte(hContact,S_MOD,"Offline",0);
+ }
+ } else if (IsWatchedProtocol(cws->szModule)){
+ //here we will come when <User>/<module>/Status is changed or it is idle event and if <module> is watched
+ if (CallProtoService(cws->szModule,PS_GETSTATUS,0,0)>ID_STATUS_OFFLINE){
+ int index;
+ if (!(index = isContactQueueActive(hContact))){
+ index = addContactToQueue(hContact);
+ strncpy(contactQueue[index]->sProtoName,cws->szModule,MAXMODULELABELLENGTH);
+ //forkthreadex(NULL, 0, waitThread, contactQueue[index], 0, 0);
+ params.pFunc = waitThread;
+ params.arg = contactQueue[index];
+ params.iStackSize = 0;
+ params.threadID = &dwThreadId;
+ CallService(MS_SYSTEM_FORK_THREAD_EX, 0, (LPARAM)¶ms);
+
+
+// } else {
+// MessageBox(0,"Already in contact queue",cws->szModule,0);
+ }
+ contactQueue[index]->courStatus = isIdleEvent?DBGetContactSettingWord(hContact,cws->szModule,"Status",ID_STATUS_OFFLINE):cws->value.wVal;
+ } }
+#ifndef PERMITNSN
+ //Some useronline.c functionality
+ {
+ int newStatus,oldStatus;
+ newStatus=(cws->value.wVal|0x8000);
+ oldStatus=DBGetContactSettingWord(hContact,"UserOnline","OldStatus",ID_STATUS_OFFLINE);
+ DBWriteContactSettingWord(hContact,"UserOnline","OldStatus",(WORD)newStatus);
+ if(DBGetContactSettingByte(hContact,"CList","Hidden",0)) return 0;
+ if((newStatus==ID_STATUS_ONLINE || newStatus==ID_STATUS_FREECHAT) &&
+ oldStatus!=ID_STATUS_ONLINE && oldStatus!=ID_STATUS_FREECHAT) {
+ BYTE supp = db_byte_get(NULL, S_MOD, "SuppCListOnline", 3); //By default no online allert :P
+ BOOL willAlert = FALSE;
+ switch (supp) {
+ case 3: willAlert = FALSE; break;
+ case 2: willAlert = !IsWatchedProtocol(cws->szModule); break;
+ case 1: willAlert = IsWatchedProtocol(cws->szModule); break;
+ case 0: willAlert = TRUE; break;
+ }
+ if (willAlert) {
+ DWORD ticked = db_dword_get(NULL, "UserOnline", cws->szModule, GetTickCount());
+ // only play the sound (or show event) if this event happens at least 10 secs after the proto went from offline
+ if ( GetTickCount() - ticked > (1000*10) ) {
+ CLISTEVENT cle;
+ char tooltip[256];
+
+ ZeroMemory(&cle,sizeof(cle));
+ cle.cbSize=sizeof(cle);
+ cle.flags=CLEF_ONLYAFEW;
+ cle.hContact=hContact;
+ cle.hDbEvent=(HANDLE)(uniqueEventId++);
+ cle.hIcon=LoadSkinnedIcon(SKINICON_OTHER_USERONLINE);
+ cle.pszService="UserOnline/Description";
+ mir_snprintf(tooltip,256,Translate("%s is Online"),(char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,0));
+ cle.pszTooltip=tooltip;
+ CallService(MS_CLIST_ADDEVENT,0,(LPARAM)&cle);
+
+ SkinPlaySound("UserOnline");
+ }
+ }
+ }
+ }
+#endif
+ return 0;
+}
+
+static DWORD __stdcall cleanThread(logthread_info* infoParam)
+{
+ HANDLE hcontact=NULL;
+// char str[MAXMODULELABELLENGTH];
+// sprintf(str,"In Clean: %s; %s; %s\n",
+// infoParam->sProtoName,
+// (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)infoParam->hContact,0),
+// (const char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,(WPARAM)infoParam->courStatus,0)
+// );
+// OutputDebugStringA(str);
+ Sleep(10000); // I hope in 10 secons all logged-in contacts will be listed
+ //Searching for contact marked as online but now are offline
+
+ hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ while(hcontact!=NULL)
+ {
+ char * contactProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hcontact,0);
+ if (contactProto) {
+ if (!strncmp(infoParam->sProtoName,contactProto,MAXMODULELABELLENGTH)){
+ WORD oldStatus;
+ if ( (oldStatus = (DBGetContactSettingWord(hcontact,S_MOD,"StatusTriger",ID_STATUS_OFFLINE))|0x8000)>ID_STATUS_OFFLINE){
+ if (DBGetContactSettingWord(hcontact,contactProto,"Status",ID_STATUS_OFFLINE)==ID_STATUS_OFFLINE){
+ DBWriteContactSettingWord(hcontact,S_MOD,"OldStatus",(WORD)(oldStatus|0x8000));
+ if (includeIdle)DBWriteContactSettingByte(hcontact,S_MOD,"OldIdle",(BYTE)((oldStatus&0x8000)?0:1));
+ DBWriteContactSettingWord(hcontact,S_MOD,"StatusTriger",ID_STATUS_OFFLINE);
+ }
+ }
+ }
+ }
+ hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hcontact,0);
+ }
+
+// sprintf(str,"OutClean: %s; %s; %s\n",
+// infoParam->sProtoName,
+// (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)infoParam->hContact,0),
+// (const char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION,(WPARAM)infoParam->courStatus,0)
+// );
+ {
+ char *str = malloc(MAXMODULELABELLENGTH+9);
+ mir_snprintf(str,MAXMODULELABELLENGTH+8,"OffTime-%s",infoParam->sProtoName);
+ DBDeleteContactSetting(NULL,S_MOD,str);
+ free(str);
+ }
+ free(infoParam);
+// OutputDebugStringA(str);
+ return 0;
+}
+
+
+int ModeChange(WPARAM wparam,LPARAM lparam)
+{
+ ACKDATA *ack;
+ WORD isetting=0;
+ FORK_THREADEX_PARAMS params;
+ DWORD dwThreadId;
+
+ ack=(ACKDATA *)lparam;
+
+ if(ack->type!=ACKTYPE_STATUS || ack->result!=ACKRESULT_SUCCESS || ack->hContact!=NULL) return 0;
+ courProtoName = (char *)ack->szModule;
+ if (!IsWatchedProtocol(courProtoName) && strncmp(courProtoName,"MetaContacts",12))
+ {
+ //MessageBox(NULL,"Protocol not watched",courProtoName,0);
+ return 0;
+ }
+
+ DBWriteTimeTS(time(NULL),NULL);
+
+// isetting=CallProtoService(ack->szModule,PS_GETSTATUS,0,0);
+ isetting=(WORD)ack->lParam;
+ if (isetting<ID_STATUS_OFFLINE) isetting = ID_STATUS_OFFLINE;
+ if ((isetting>ID_STATUS_OFFLINE)&&((WORD)ack->hProcess<=ID_STATUS_OFFLINE)){
+ //we have just loged-in
+ db_dword_set(NULL, "UserOnline", ack->szModule, GetTickCount());
+ if (IsWatchedProtocol(ack->szModule)){
+ logthread_info *info;
+ info = (logthread_info *)malloc(sizeof(logthread_info));
+ strncpy(info->sProtoName,courProtoName,MAXMODULELABELLENGTH);
+ info->hContact = 0;
+ info->courStatus = 0;
+ //forkthreadex(NULL, 0, cleanThread, info, 0, 0);
+ params.pFunc = cleanThread;
+ params.arg = info;
+ params.iStackSize = 0;
+ params.threadID = &dwThreadId;
+ CallService(MS_SYSTEM_FORK_THREAD_EX, 0, (LPARAM)¶ms);
+
+ }
+ } else if ((isetting==ID_STATUS_OFFLINE)&&((WORD)ack->hProcess>ID_STATUS_OFFLINE)){
+ //we have just loged-off
+ if (IsWatchedProtocol(ack->szModule)){
+ char *str = malloc(MAXMODULELABELLENGTH+9);
+ DWORD t;
+ time(&t);
+ mir_snprintf(str,MAXMODULELABELLENGTH+8,"OffTime-%s",ack->szModule);
+ DBWriteContactSettingDword(NULL,S_MOD,str,t);
+ free(str);
+ } }
+ if (isetting==DBGetContactSettingWord(NULL,S_MOD,courProtoName,ID_STATUS_OFFLINE)) return 0;
+ DBWriteContactSettingWord(NULL,S_MOD,courProtoName,isetting);
+
+ // log "myself"
+ if(DBGetContactSettingByte(NULL,S_MOD,"FileOutput",0))
+ FileWrite(NULL);
+
+// if(isetting==ID_STATUS_OFFLINE) //this is removed 'cause I want other contacts to be logged only if the status changed while I was offline
+// SetOffline();
+
+ courProtoName = NULL;
+
+ return 0;
+}
+
+short int isDbZero(HANDLE hContact, const char *module_name, const char *setting_name){
+ DBVARIANT dbv;
+ if(!DBGetContactSetting(hContact, module_name, setting_name, &dbv)) {
+ short int res = 0;
+ switch (dbv.type) {
+ case DBVT_BYTE: res=dbv.bVal==0; break;
+ case DBVT_WORD: res=dbv.wVal==0; break;
+ case DBVT_DWORD: res=dbv.dVal==0; break;
+ case DBVT_BLOB: res=dbv.cpbVal==0; break;
+ default: res=dbv.pszVal[0]==0; break;
+ }
+ DBFreeVariant(&dbv);
+ return res;
+ } else return -1;
+}
+
+WCHAR *any_to_IdleNotidleUnknown(HANDLE hContact, const char *module_name, const char *setting_name, WCHAR *buff, int bufflen) {
+ short int r = isDbZero(hContact, module_name, setting_name);
+ if (r==-1){
+ wcsncpy(buff, TranslateW(L"Unknown"), bufflen);
+ } else {
+ wcsncpy(buff, TranslateW(r?L"Not Idle":L"Idle"), bufflen);
+ };
+ buff[bufflen - 1] = 0;
+ return buff;
+}
+WCHAR *any_to_Idle(HANDLE hContact, const char *module_name, const char *setting_name, WCHAR *buff, int bufflen) {
+ if(isDbZero(hContact, module_name, setting_name)==0) { //DB setting is NOT zero and exists
+ buff[0] = L'/';
+ wcsncpy((WCHAR *)&buff[1], TranslateW(L"Idle"), bufflen-1);
+ } else buff[0] = 0;
+ buff[bufflen - 1] = 0;
+ return buff;
+}
+
+
+/*int GetInfoAck(WPARAM wparam,LPARAM lparam)
+{
+ ACKDATA *ack;
+ DWORD dwsetting=0;
+
+ ack=(ACKDATA *)lparam;
+
+ if(ack->type!=ACKTYPE_GETINFO || ack->hContact==NULL) return 0;
+ if(((int)ack->hProcess-1)!=(int)ack->lParam) return 0;
+
+ dwsetting=DBGetContactSettingDword(ack->hContact,ack->szModule,"IP",0);
+ if(dwsetting)
+ DBWriteContactSettingDword(ack->hContact,S_MOD,"IP",dwsetting);
+
+ dwsetting=DBGetContactSettingDword(ack->hContact,ack->szModule,"RealIP",0);
+ if(dwsetting)
+ DBWriteContactSettingDword(ack->hContact,S_MOD,"RealIP",dwsetting);
+
+ return 0;
+}*/
+
+
+
+/*void SetOffline(void)
+{
+ HANDLE hcontact=NULL;
+ char * szProto;
+
+ hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ while(hcontact!=NULL)
+ {
+ szProto=(char *)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hcontact,0);
+ if (szProto != NULL && IsWatchedProtocol(szProto)) {
+ DBWriteContactSettingByte(hcontact,S_MOD,"Offline",1);
+ }
+ hcontact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hcontact,0);
+ }
+}*/
+
+
+
diff --git a/nudge/ChangeLog.txt b/nudge/ChangeLog.txt new file mode 100644 index 0000000..477a256 --- /dev/null +++ b/nudge/ChangeLog.txt @@ -0,0 +1,183 @@ +0.0.1.22
+===========
++ 64bit version
++ unhook hooks on exit
++ destroy services on exit
++ open message window on popup click
++ open message window on preview
++ moved sounds in "Nudge" section
+
+0.0.1.21
+===========
++ Traslation fo icon description
+
+0.0.1.20
+===========
+! Bug in options layout
+! Fix for crash when no protocol available (based on changed by Ivan)
+
+0.0.1.19
+===========
+! Patch by Drugwash : option page redesign and ansi buit fix
+* Change N/A to NA (requested by freak)
++ Patch for tabsrmm button api support (thx DaniOK)
+
+0.0.1.18
+===========
+! Fix autoresend save setting
++ Add a autoresend delay (must be between 1 and 10 sec)
+
+0.0.1.17
+===========
++ Add unicode aware flag
++ Support for miranda 0.8
+! Fix for icolib support
++ Added icons from angelika
+
+0.0.1.16
+===========
++ Add a service to hide/show "send nudge" context menu (for metacontact)
+
+0.0.1.15
+===========
+* Patch by Tioduke (offline nudge)
+
+0.0.1.14
+===========
+* Fix visual option
+
+0.0.1.13
+===========
+! Unicode patch by Ghazan
+! Fix options dialog size
+! Fix nudge text in unicode
+! Use DBGetContactSettingTString to read data
+
+0.0.1.12
+===========
++ Unicode supports (will need unicows.dll, thanks to sje - eblis)
+! Fix retreiving chat window (patch sje)
+
+0.0.1.11
+===========
+! Check for null handle to avoid crash in IRC mod
+! gdi leaks in option page (thx tioduke)
++ Auto send nudge option when received one.
+* New trigger plugin support (first step)
+* Use the text set in option page in popup.
+* Use find first contact service for popup preview
+* Set auto resend nudge to false by default
+
+0.0.1.10
+===========
+* Use popup for warning instead of message box.
++ Check if popup plugin is present if not use messagebox.
+
+0.0.1.9
+===========
+* Change options dialog (use tabsrmm uxtheme)
+
+0.0.1.8
+===========
++ Show a popup on sending nudge
+
+0.0.1.7
+===========
+! Change text for status log on receive.
+* Use flags = 0 for status notify.
+! Wrong section name in options saving.
+* Use winres.h in resource.
+
+0.0.1.6
+===========
++ Per contact limitation (no more per protocol cause too restrictive)
++ Privacy options to limit the number of nudge to receive
++ Options to show nudge as status change. (thx Tioduke)
+
+0.0.1.5
+===========
+! Memory leaks fix. (Patch by Ghazan)
+
+0.0.1.4
+===========
+! Bug fix, url for file in updater info points to source :-(.
+
+0.0.1.3
+===========
+! Bug fix, check time for default proto too ;)
+
+0.0.1.2
+===========
++ Add the right url for updater, now that nudge is on FL.
+
+0.0.1.1
+===========
+:( skipped
+
+0.0.1.0
+===========
+* Some modifications of the option page.
+* Redesign option page.
+! Bug fix with slider in shake option.
+! Bug fix with updater and stable version.
+
+0.0.0.12
+===========
++ Now possible to change the text shown when sending or receiving nudge ( [color=red]BUZZ!!![/color] for yahoo ;) )
+* Change options page.
+! Now apply button is enable when changing status.
+
+0.0.0.11
+===========
++ Status support (global or by protocol)
++ Limitation only sent 1 nudge every 30 sec per protocol.
+
+0.0.0.10
+===========
++ Multiprotocol options
+
+0.0.0.9
+===========
+Patch by Tioduke
+{
+ * Use the right protoname for treating nudge as event
+ * Take care of the message dialog (open or not) in treating nudge as event
+ + Registration in dbeditor ++
+}
+* Be aware of metacontact when sendig/receiving nudge (history).
+
+0.0.0.8
+===========
++ Shake options are now saved in DB
+! some code rewrite in order to easily change the algo of shaking
+! Patch by Tioduke for icons (non support of icolib)
++ Option to treat nudge as a message.
+! Recieved -> received.
+
+0.0.0.7
+===========
+! Wrong service call
+
+0.0.0.6
+===========
+* Change the return value for trigger functions
+! Bug sound file name was not set (thx TioDuke)
++ Add default Sound
+
+0.0.0.5
+===========
+! Trigger plugin bug fix
+
+0.0.0.4
+============
++ Icolib support
+! Option redesign to fix visual bug
++ First step in option page to by protocol option
++ Settings are now saved in DB :-)
+
+
+0.0.0.3
+============
+* Some mod in option page.
++ Support for trigger plugin from pboon.
+* Forced beta version in updater.
\ No newline at end of file diff --git a/nudge/headers.h b/nudge/headers.h new file mode 100644 index 0000000..f46e679 --- /dev/null +++ b/nudge/headers.h @@ -0,0 +1,75 @@ +// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows XP or later.
+#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
+#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.
+#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.
+#endif
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+// Windows Header Files:
+
+#include <windows.h>
+#include <commctrl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <stddef.h>
+#include <process.h>
+
+#define MIRANDA_VER 0x1000
+#include <newpluginapi.h> //CallService,UnHookEvent
+#include <m_utils.h> //window broadcasting
+#include <m_clist.h>
+#include <m_langpack.h>
+#include <m_system.h>
+#include <m_popup.h>
+#include <m_clui.h>
+#include <m_message.h>
+#include <m_contacts.h>
+#include <m_protocols.h>
+#include <m_protomod.h>
+#include <m_options.h>
+#include <m_skin.h>
+#include <m_database.h>
+#include <m_protosvc.h>
+#include "include\m_trigger.h"
+#include "include\m_metacontacts.h"
+#include "include\m_updater.h"
+#include <m_icolib.h>
+#include "resource.h"
+#include "m_nudge.h"
+
+
+/*
+*
+****************************/
+void InitOptions();
+void UninitOptions();
+
+/*
+*
+****************************/
+int Preview();
+
+/*
+*
+****************************/
+HANDLE Nudge_GethContact(HANDLE);
\ No newline at end of file diff --git a/nudge/include/IcoLib.h b/nudge/include/IcoLib.h new file mode 100644 index 0000000..a911ba5 --- /dev/null +++ b/nudge/include/IcoLib.h @@ -0,0 +1,26 @@ +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
+ char *pszDefaultFile; //default icon file to use
+ int iDefaultIndex;
+} SKINICONDESC;
+
+//
+// Add a icon into options UI
+// NB! pszName should be unique, e.g.: clistmw_apply, tabsrmm_history
+//
+// 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/nudge/include/m_folders.h b/nudge/include/m_folders.h new file mode 100644 index 0000000..5971cff --- /dev/null +++ b/nudge/include/m_folders.h @@ -0,0 +1,284 @@ +/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_CUSTOM_FOLDERS_H
+#define M_CUSTOM_FOLDERS_H
+
+#define FOLDERS_API 501 //dunno why it's here but it is :)
+
+#define PROFILE_PATH "%profile_path%"
+#define CURRENT_PROFILE "%current_profile%"
+#define MIRANDA_PATH "%miranda_path%"
+#define PLUGINS_PATH "%miranda_path%" "\\plugins"
+#define MIRANDA_USERDATA "%miranda_userdata%"
+
+#define TO_WIDE(x) L ## x
+
+#define PROFILE_PATHW L"%profile_path%"
+#define CURRENT_PROFILEW L"%current_profile%"
+#define MIRANDA_PATHW L"%miranda_path%"
+#define MIRANDA_USERDATAW L"%miranda_userdata%"
+
+#define FOLDER_AVATARS PROFILE_PATH "\\" CURRENT_PROFILE "\\avatars"
+#define FOLDER_VCARDS PROFILE_PATH "\\" CURRENT_PROFILE "\\vcards"
+#define FOLDER_LOGS PROFILE_PATH "\\" CURRENT_PROFILE "\\logs"
+#define FOLDER_RECEIVED_FILES PROFILE_PATH "\\" CURRENT_PROFILE "\\received files"
+#define FOLDER_DOCS MIRANDA_PATH "\\" "docs"
+
+#define FOLDER_CONFIG PLUGINS_PATH "\\" "config"
+
+#define FOLDER_SCRIPTS MIRANDA_PATH "\\" "scripts"
+
+#define FOLDER_UPDATES MIRANDA_PATH "\\" "updates"
+
+#define FOLDER_CUSTOMIZE MIRANDA_PATH "\\" "customize"
+#define FOLDER_CUSTOMIZE_SOUNDS FOLDER_CUSTOMIZE "\\sounds"
+#define FOLDER_CUSTOMIZE_ICONS FOLDER_CUSTOMIZE "\\icons"
+#define FOLDER_CUSTOMIZE_SMILEYS FOLDER_CUSTOMIZE "\\smileys"
+#define FOLDER_CUSTOMIZE_SKINS FOLDER_CUSTOMIZE "\\skins"
+#define FOLDER_CUSTOMIZE_THEMES FOLDER_CUSTOMIZE "\\themes"
+
+
+#define FOLDERS_NAME_MAX_SIZE 64 //maximum name and section size
+
+#define FF_UNICODE 0x00000001
+
+#if defined (UNICODE)
+ #define FF_TCHAR FF_UNICODE
+#else
+ #define FF_TCHAR 0
+#endif
+
+typedef struct{
+ int cbSize; //size of struct
+ char szSection[FOLDERS_NAME_MAX_SIZE]; //section name, if it doesn't exist it will be created otherwise it will just add this entry to it
+ char szName[FOLDERS_NAME_MAX_SIZE]; //entry name - will be shown in options
+ union{
+ const char *szFormat; //default string format. Fallback string in case there's no entry in the database for this folder. This should be the initial value for the path, users will be able to change it later.
+ const wchar_t *szFormatW; //String is dup()'d so you can free it later. If you set the unicode string don't forget to set the flag accordingly.
+ const TCHAR *szFormatT;
+ };
+ DWORD flags; //FF_* flags
+} FOLDERSDATA;
+
+/*Folders/Register/Path service
+ wParam - not used, must be 0
+ lParam - (LPARAM) (const FOLDERDATA *) - Data structure filled with
+ the necessary information.
+ Returns a handle to the registered path or 0 on error.
+ You need to use this to call the other services.
+*/
+#define MS_FOLDERS_REGISTER_PATH "Folders/Register/Path"
+
+/*Folders/Get/PathSize service
+ wParam - (WPARAM) (int) - handle to registered path
+ lParam - (LPARAM) (int *) - pointer to the variable that receives the size of the path
+ string (not including the null character). Depending on the flags set when creating the path
+ it will either call strlen() or wcslen() to get the length of the string.
+ Returns the size of the buffer.
+*/
+#define MS_FOLDERS_GET_SIZE "Folders/Get/PathSize"
+
+typedef struct{
+ int cbSize;
+ int nMaxPathSize; //maximum size of buffer. This represents the number of characters that can be copied to it (so for unicode strings you don't send the number of bytes but the length of the string).
+ union{
+ char *szPath; //pointer to the buffer that receives the path without the last "\\"
+ wchar_t *szPathW; //unicode version of the buffer.
+ TCHAR *szPathT;
+ };
+} FOLDERSGETDATA;
+
+/*Folders/Get/Path service
+ wParam - (WPARAM) (int) - handle to registered path
+ lParam - (LPARAM) (FOLDERSGETDATA *) pointer to a FOLDERSGETDATA that has all the relevant fields filled.
+ Should return 0 on success, or nonzero otherwise.
+*/
+#define MS_FOLDERS_GET_PATH "Folders/Get/Path"
+
+typedef struct{
+ int cbSize;
+ union{
+ char **szPath; //address of a string variable (char *) or (wchar_t*) where the path should be stored (the last \ won't be copied).
+ wchar_t **szPathW; //unicode version of string.
+ TCHAR **szPathT;
+ };
+} FOLDERSGETALLOCDATA;
+
+/*Folders/GetRelativePath/Alloc service
+ wParam - (WPARAM) (int) - Handle to registered path
+ lParam - (LPARAM) (FOLDERSALLOCDATA *) data
+ This service is the same as MS_FOLDERS_GET_PATH with the difference that this service
+ allocates the needed space for the buffer. It uses miranda's memory functions for that and you need
+ to use those to free the resulting buffer.
+ Should return 0 on success, or nonzero otherwise. Currently it only returns 0.
+*/
+#define MS_FOLDERS_GET_PATH_ALLOC "Folders/Get/Path/Alloc"
+
+
+/*Folders/On/Path/Changed
+ wParam - (WPARAM) 0
+ lParam - (LPARAM) 0
+ Triggered when the folders change, you should reget the paths you registered.
+*/
+#define ME_FOLDERS_PATH_CHANGED "Folders/On/Path/Changed"
+
+#ifndef FOLDERS_NO_HELPER_FUNCTIONS
+
+#ifndef M_UTILS_H__
+#error The helper functions require that m_utils.h be included in the project. Please include that file if you want to use the helper functions. If you don''t want to use the functions just define FOLDERS_NO_HELPER_FUNCTIONS.
+#endif
+//#include "../../../include/newpluginapi.h"
+
+__inline static HANDLE FoldersRegisterCustomPath(const char *section, const char *name, const char *defaultPath)
+{
+ FOLDERSDATA fd = {0};
+ if (!ServiceExists(MS_FOLDERS_REGISTER_PATH)) return 0;
+ fd.cbSize = sizeof(FOLDERSDATA);
+ strncpy(fd.szSection, section, FOLDERS_NAME_MAX_SIZE);
+ fd.szSection[FOLDERS_NAME_MAX_SIZE - 1] = '\0';
+ strncpy(fd.szName, name, FOLDERS_NAME_MAX_SIZE);
+ fd.szName[FOLDERS_NAME_MAX_SIZE - 1] = '\0';
+ fd.szFormat = defaultPath;
+ return (HANDLE) CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &fd);
+}
+
+__inline static HANDLE FoldersRegisterCustomPathW(const char *section, const char *name, const wchar_t *defaultPathW)
+{
+ FOLDERSDATA fd = {0};
+ if (!ServiceExists(MS_FOLDERS_REGISTER_PATH)) return 0;
+ fd.cbSize = sizeof(FOLDERSDATA);
+ strncpy(fd.szSection, section, FOLDERS_NAME_MAX_SIZE);
+ fd.szSection[FOLDERS_NAME_MAX_SIZE - 1] = '\0'; //make sure it's NULL terminated
+ strncpy(fd.szName, name, FOLDERS_NAME_MAX_SIZE);
+ fd.szName[FOLDERS_NAME_MAX_SIZE - 1] = '\0'; //make sure it's NULL terminated
+ fd.szFormatW = defaultPathW;
+ fd.flags = FF_UNICODE;
+ return (HANDLE) CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &fd);
+}
+
+__inline static INT_PTR FoldersGetCustomPath(HANDLE hFolderEntry, char *path, const int size, const char *notFound)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = size;
+ fgd.szPath = path;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ char buffer[MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM) notFound, (LPARAM) buffer);
+ mir_snprintf(path, size, "%s", buffer);
+ }
+
+ return res;
+}
+
+__inline static INT_PTR FoldersGetCustomPathW(HANDLE hFolderEntry, wchar_t *pathW, const int count, const wchar_t *notFoundW)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = count;
+ fgd.szPathW = pathW;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ wcsncpy(pathW, notFoundW, count);
+ pathW[count - 1] = '\0';
+ }
+
+ return res;
+}
+
+__inline static INT_PTR FoldersGetCustomPathEx(HANDLE hFolderEntry, char *path, const int size, char *notFound, char *fileName)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = size;
+ fgd.szPath = path;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ char buffer[MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM) notFound, (LPARAM) buffer);
+ mir_snprintf(path, size, "%s", buffer);
+ }
+ if (strlen(path) > 0)
+ {
+ strcat(path, "\\");
+ }
+ else{
+ path[0] = '\0';
+ }
+
+ if (fileName)
+ {
+ strcat(path, fileName);
+ }
+
+ return res;
+}
+
+__inline static INT_PTR FoldersGetCustomPathExW(HANDLE hFolderEntry, wchar_t *pathW, const int count, wchar_t *notFoundW, wchar_t *fileNameW)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = count;
+ fgd.szPathW = pathW;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ wcsncpy(pathW, notFoundW, count);
+ pathW[count - 1] = '\0';
+ }
+
+ if (wcslen(pathW) > 0)
+ {
+ wcscat(pathW, L"\\");
+ }
+ else{
+ pathW[0] = L'\0';
+ }
+
+ if (fileNameW)
+ {
+ wcscat(pathW, fileNameW);
+ }
+
+ return res;
+}
+
+# ifdef _UNICODE
+# define FoldersGetCustomPathT FoldersGetCustomPathW
+# define FoldersGetCustomPathExT FoldersGetCustomPathExW
+# define FoldersRegisterCustomPathT FoldersRegisterCustomPathW
+#else
+# define FoldersGetCustomPathT FoldersGetCustomPath
+# define FoldersGetCustomPathExT FoldersGetCustomPath
+# define FoldersRegisterCustomPathT FoldersRegisterCustomPath
+#endif
+
+#endif
+
+#endif //M_CUSTOM_FOLDERS_H
\ No newline at end of file diff --git a/nudge/include/m_kbdnotify.h b/nudge/include/m_kbdnotify.h new file mode 100644 index 0000000..2ab53fe --- /dev/null +++ b/nudge/include/m_kbdnotify.h @@ -0,0 +1,64 @@ +/*
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef _KBDNOTIFY_
+#define _KBDNOTIFY_
+
+//Enables all notifications (for use by BossKey)
+//wParam=0
+//lParam=0
+//returns 0
+#define MS_KBDNOTIFY_ENABLE "KeyboardNotify/Enable"
+
+
+//Disables all notifications (for use by BossKey)
+//wParam=0
+//lParam=0
+//returns 0
+#define MS_KBDNOTIFY_DISABLE "KeyboardNotify/Disable"
+
+
+//Makes the flashing begin
+//wParam=(unsigned int)eventCount
+//lParam=(char *)szFlashingSequence or NULL if you want the plugin to use current settings
+//returns 0
+#define MS_KBDNOTIFY_STARTBLINK "KeyboardNotify/StartBlinking"
+
+
+//Receives the number of events that were opened (usuful for the 'until events opened' setting)
+//wParam=(unsigned int)eventCount
+//lParam=0
+//returns 0
+#define MS_KBDNOTIFY_EVENTSOPENED "KeyboardNotify/EventsWereOpened"
+
+
+//Informs if the flashing is active
+//wParam=0
+//lParam=0
+//returns 0 if the flashing is inactive or a pointer to the string representing the sequence being used
+#define MS_KBDNOTIFY_FLASHINGACTIVE "KeyboardNotify/IsFlashingActive"
+
+
+//Normalizes the flashing sequence informed
+//wParam=0
+//lParam=(char *)szFlashingSequence <- it is rewritten
+//returns a pointer to the string representing the sequence normalized (which is in fact lParam)
+#define MS_KBDNOTIFY_NORMALSEQUENCE "KeyboardNotify/NormalizeSequence"
+
+
+#endif
\ No newline at end of file diff --git a/nudge/include/m_metacontacts.h b/nudge/include/m_metacontacts.h new file mode 100644 index 0000000..9f348bd --- /dev/null +++ b/nudge/include/m_metacontacts.h @@ -0,0 +1,166 @@ +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright © 2004 Universite Louis PASTEUR, STRASBOURG.
+Copyright © 2004 Scott Ellis (www.scottellis.com.au mail@scottellis.com.au)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_METACONTACTS_H__
+#define M_METACONTACTS_H__ 1
+
+#ifndef MIID_METACONTACTS
+#define MIID_METACONTACTS {0xc0325019, 0xc1a7, 0x40f5, { 0x83, 0x65, 0x4f, 0x46, 0xbe, 0x21, 0x86, 0x3e}}
+#endif
+
+//get the handle for a contact's parent metacontact
+//wParam=(HANDLE)hSubContact
+//lParam=0
+//returns a handle to the parent metacontact, or null if this contact is not a subcontact
+#define MS_MC_GETMETACONTACT "MetaContacts/GetMeta"
+
+//gets the handle for the default contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a handle to the default contact, or null on failure
+#define MS_MC_GETDEFAULTCONTACT "MetaContacts/GetDefault"
+
+//gets the contact number for the default contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a DWORD contact number, or -1 on failure
+#define MS_MC_GETDEFAULTCONTACTNUM "MetaContacts/GetDefaultNum"
+
+//gets the handle for the 'most online' contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a handle to the 'most online' contact
+#define MS_MC_GETMOSTONLINECONTACT "MetaContacts/GetMostOnline"
+
+//gets the number of subcontacts for a metacontact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a DWORD representing the number of subcontacts for the given metacontact
+#define MS_MC_GETNUMCONTACTS "MetaContacts/GetNumContacts"
+
+//gets the handle of a subcontact, using the subcontact's number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns a handle to the specified subcontact
+#define MS_MC_GETSUBCONTACT "MetaContacts/GetSubContact"
+
+//sets the default contact, using the subcontact's contact number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns 0 on success
+#define MS_MC_SETDEFAULTCONTACTNUM "MetaContacts/SetDefault"
+
+//sets the default contact, using the subcontact's handle
+//wParam=(HANDLE)hMetaContact
+//lParam=(HANDLE)hSubcontact
+//returns 0 on success
+#define MS_MC_SETDEFAULTCONTACT "MetaContacts/SetDefaultByHandle"
+
+//forces the metacontact to send using a specific subcontact, using the subcontact's contact number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns 0 on success
+#define MS_MC_FORCESENDCONTACTNUM "MetaContacts/ForceSendContact"
+
+//forces the metacontact to send using a specific subcontact, using the subcontact's handle
+//wParam=(HANDLE)hMetaContact
+//lParam=(HANDLE)hSubcontact
+//returns 0 on success (will fail if 'force default' is in effect)
+#define MS_MC_FORCESENDCONTACT "MetaContacts/ForceSendContactByHandle"
+
+//'unforces' the metacontact to send using a specific subcontact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns 0 on success (will fail if 'force default' is in effect)
+#define MS_MC_UNFORCESENDCONTACT "MetaContacts/UnforceSendContact"
+
+//'forces' or 'unforces' (i.e. toggles) the metacontact to send using it's default contact
+// overrides (and clears) 'force send' above, and will even force use of offline contacts
+// will send ME_MC_FORCESEND or ME_MC_UNFORCESEND event
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns 1(true) or 0(false) representing new state of 'force default'
+#define MS_MC_FORCEDEFAULT "MetaContacts/ForceSendDefault"
+
+// method to get state of 'force' for a metacontact
+// wParam=(HANDLE)hMetaContact
+// lParam= (DWORD)&contact_number or NULL
+//
+// if lparam supplied, the contact_number of the contatct 'in force' will be copied to the address it points to,
+// or if none is in force, the value (DWORD)-1 will be copied
+// (v0.8.0.8+ returns 1 if 'force default' is true with *lParam == default contact number, else returns 0 with *lParam as above)
+#define MS_MC_GETFORCESTATE "MetaContacts/GetForceState"
+
+// fired when a metacontact's default contact changes (fired upon creation of metacontact also, when default is initially set)
+// wParam=(HANDLE)hMetaContact
+// lParam=(HANDLE)hDefaultContact
+#define ME_MC_DEFAULTTCHANGED "MetaContacts/DefaultChanged"
+
+// fired when a metacontact's subcontacts change (fired upon creation of metacontact, when contacts are added or removed, and when
+// contacts are reordered) - a signal to re-read metacontact data
+// wParam=(HANDLE)hMetaContact
+// lParam=0
+#define ME_MC_SUBCONTACTSCHANGED "MetaContacts/SubcontactsChanged"
+
+// fired when a metacontact is forced to send using a specific subcontact
+// wParam=(HANDLE)hMetaContact
+// lParam=(HANDLE)hForceContact
+#define ME_MC_FORCESEND "MetaContacts/ForceSend"
+
+// fired when a metacontact is 'unforced' to send using a specific subcontact
+// wParam=(HANDLE)hMetaContact
+// lParam=0
+#define ME_MC_UNFORCESEND "MetaContacts/UnforceSend"
+
+// method to get protocol name - used to be sure you're dealing with a "real" metacontacts plugin :)
+// wParam=lParam=0
+#define MS_MC_GETPROTOCOLNAME "MetaContacts/GetProtoName"
+
+
+// added 0.9.5.0 (22/3/05)
+// wParam=(HANDLE)hContact
+// lParam=0
+// convert a given contact into a metacontact
+#define MS_MC_CONVERTTOMETA "MetaContacts/ConvertToMetacontact"
+
+// added 0.9.5.0 (22/3/05)
+// wParam=(HANDLE)hContact
+// lParam=(HANDLE)hMeta
+// add an existing contact to a metacontact
+#define MS_MC_ADDTOMETA "MetaContacts/AddToMetacontact"
+
+// added 0.9.5.0 (22/3/05)
+// wParam=0
+// lParam=(HANDLE)hContact
+// remove a contact from a metacontact
+#define MS_MC_REMOVEFROMMETA "MetaContacts/RemoveFromMetacontact"
+
+
+// added 0.9.13.2 (6/10/05)
+// wParam=(BOOL)disable
+// lParam=0
+// enable/disable the 'hidden group hack' - for clists that support subcontact hiding using 'IsSubcontact' setting
+// should be called once in the clist 'onmodulesloaded' event handler (which, since it's loaded after the db, will be called
+// before the metacontact onmodulesloaded handler where the subcontact hiding is usually done)
+#define MS_MC_DISABLEHIDDENGROUP "MetaContacts/DisableHiddenGroup"
+
+#endif
diff --git a/nudge/include/m_msg_buttonsbar.h b/nudge/include/m_msg_buttonsbar.h new file mode 100644 index 0000000..8a55627 --- /dev/null +++ b/nudge/include/m_msg_buttonsbar.h @@ -0,0 +1,120 @@ +#ifndef M_MSG_BUTTONSBAR_H__
+#define M_MSG_BUTTONSBAR_H__
+
+//////////////////////////////////////////////////////////////////////////
+// Services
+//
+//////////////////////////////////////////////////////////////////////////
+// Adding a button
+//
+// wParam = 0
+// lParam = (BBButton *) &description
+#define MS_BB_ADDBUTTON "TabSRMM/ButtonsBar/AddButton"
+
+//////////////////////////////////////////////////////////////////////////
+// Remove button
+//
+// wParam = 0
+// lParam = (BBButton *) &description, only button ID and ModuleName used
+#define MS_BB_REMOVEBUTTON "TabSRMM/ButtonsBar/RemoveButton"
+
+//////////////////////////////////////////////////////////////////////////
+// ModifyButton(global)
+//
+// wParam = 0
+// lParam = (BBButton *) &description
+#define MS_BB_MODIFYBUTTON "TabSRMM/ButtonsBar/ModifyButton"
+
+
+#define BBSF_HIDDEN (1<<0)
+#define BBSF_DISABLED (1<<1)
+#define BBSF_PUSHED (1<<2)
+#define BBSF_RELEASED (1<<3)
+
+//////////////////////////////////////////////////////////////////////////
+// GetButtonState(local)
+//
+// wParam = hContact
+// lParam = (BBButton *) &description , only ModuleName and ID used
+// Returns BBButton struct with BBSF_ bbbFlags:
+#define MS_BB_GETBUTTONSTATE "TabSRMM/ButtonsBar/GetButtonState"
+
+//////////////////////////////////////////////////////////////////////////
+// SetButtonState (local)
+//
+// wParam = hContact
+// lParam = (BBButton *) &description , ModuleName, ID,hIcon,Tooltip, and BBSF_ bbbFlags are used
+#define MS_BB_SETBUTTONSTATE "TabSRMM/ButtonsBar/SetButtonState"
+
+
+////////////////////////////////////////////////////////////////
+//Events
+//
+///////////////////////////////////////////////////
+// ToolBar loaded event
+// wParam = 0;
+// lParam = 0;
+// This event will be send after module loaded and after each toolbar reset
+// You should add your buttons on this event
+#define ME_MSG_TOOLBARLOADED "TabSRMM/ButtonsBar/ModuleLoaded"
+
+///////////////////////////////////////////////////
+// ButtonClicked event
+// wParam = (HANDLE)hContact;
+// lParam = (CustomButtonClickData *)&CustomButtonClickData;
+// catch to show a popup menu, etc.
+#define ME_MSG_BUTTONPRESSED "TabSRMM/ButtonsBar/ButtonPressed"
+
+
+//event flags
+#define BBCF_RIGHTBUTTON (1<<0)
+#define BBCF_SHIFTPRESSED (1<<1)
+#define BBCF_CONTROLPRESSED (1<<2)
+#define BBCF_ARROWCLICKED (1<<3)
+
+typedef struct {
+ int cbSize;
+ POINT pt; // screen coordinates for menus
+ char* pszModule; // button owners name
+ DWORD dwButtonId; // registered button ID
+ HWND hwndFrom; // button parents HWND
+ HANDLE hContact; //
+ DWORD flags; // BBCF_ flags
+ } CustomButtonClickData;
+
+
+//button flags
+#define BBBF_DISABLED (1<<0)
+#define BBBF_HIDDEN (1<<1)
+#define BBBF_ISPUSHBUTTON (1<<2)
+#define BBBF_ISARROWBUTTON (1<<3)
+#define BBBF_ISCHATBUTTON (1<<4)
+#define BBBF_ISIMBUTTON (1<<5)
+#define BBBF_ISLSIDEBUTTON (1<<6)
+#define BBBF_ISRSIDEBUTTON (1<<7)
+#define BBBF_CANBEHIDDEN (1<<8)
+#define BBBF_ISDUMMYBUTTON (1<<9)
+#define BBBF_ANSITOOLTIP (1<<10)
+
+#define BBBF_CREATEBYID (1<<11) //only for tabsrmm internal use
+
+typedef struct _tagBBButton
+ {
+ int cbSize; // size of structure
+
+ DWORD dwButtonID; // your button ID, will be combined with pszModuleName for storing settings, etc...
+
+ char* pszModuleName; //module name without spaces and underline symbols (e.g. "tabsrmm")
+ union{
+ char* pszTooltip; //button's tooltip
+ TCHAR* ptszTooltip;
+ };
+ DWORD dwDefPos; // default order pos of button, counted from window edge (left or right)
+ // use value >100, because internal buttons using 10,20,30... 80, etc
+ int iButtonWidth; // must be 0
+ DWORD bbbFlags; // combine of BBBF_ flags above
+ HANDLE hIcon; //Handle to icolib registered icon, it's better to register with pszSection = "TabSRMM/Toolbar"
+ }BBButton;
+
+
+#endif //M_MSG_BUTTONSBAR_H__
\ No newline at end of file diff --git a/nudge/include/m_popup.h b/nudge/include/m_popup.h new file mode 100644 index 0000000..9e5f179 --- /dev/null +++ b/nudge/include/m_popup.h @@ -0,0 +1,318 @@ +/*
+===============================================================================
+ PopUp plugin
+Plugin Name: PopUp
+Plugin authors: Luca Santarelli aka hrk (hrk@users.sourceforge.net)
+ Victor Pavlychko aka zazoo (nullbie@gmail.com)
+===============================================================================
+The purpose of this plugin is to give developers a common "platform/interface"
+to show PopUps. It is born from the source code of NewStatusNotify, another
+plugin I've made.
+
+Remember that users *must* have this plugin enabled, or they won't get any
+popup. Write this in the requirements, do whatever you wish ;-)... but tell
+them!
+===============================================================================
+*/
+#ifndef M_POPUP_H
+#define M_POPUP_H
+
+/*
+NOTE! Since Popup 1.0.1.2 there is a main meun group called "PopUps" where I
+have put a "Enable/Disable" item. You can add your own "enable/disable" items
+by adding these lines before you call MS_CLIST_ADDMAINMENUITEM:
+mi.pszPopUpName = Translate("PopUps");
+mi.position = 0; //You don't need it and it's better if you put it to zero.
+*/
+
+//#define MAX_CONTACTNAME 32
+//#define MAX_SECONDLINE 40
+#define MAX_CONTACTNAME 2048
+#define MAX_SECONDLINE 2048
+
+#define POPUP_USE_SKINNED_BG 0xffffffff
+
+//This is the basic data you'll need to fill and pass to the service function.
+typedef struct {
+ HANDLE lchContact; //Handle to the contact, can be NULL (main contact).
+ HICON lchIcon; //Handle to a icon to be shown. Cannot be NULL.
+ char lpzContactName[MAX_CONTACTNAME]; //This is the contact name or the first line in the plugin. Cannot be NULL.
+ char lpzText[MAX_SECONDLINE]; //This is the second line text. Users can choose to hide it. Cannot be NULL.
+ COLORREF colorBack; //COLORREF to be used for the background. Can be NULL, default will be used.
+ COLORREF colorText; //COLORREF to be used for the text. Can be NULL, default will be used.
+ WNDPROC PluginWindowProc; //Read below. Can be NULL; default will be used.
+ void * PluginData; //Read below. Can be NULL.
+} POPUPDATA, * LPPOPUPDATA;
+
+typedef struct {
+ HANDLE lchContact;
+ HICON lchIcon;
+ char lpzContactName[MAX_CONTACTNAME];
+ char lpzText[MAX_SECONDLINE];
+ COLORREF colorBack; //Set background to POPUP_USE_SKINNED_BG to turn on skinning
+ COLORREF colorText;
+ WNDPROC PluginWindowProc;
+ void * PluginData;
+ int iSeconds; //Custom delay time in seconds. -1 means "forever", 0 means "default time".
+// char cZero[16];
+ LPCTSTR lpzClass; //PopUp class. Used with skinning. See PopUp/AddClass for details
+ COLORREF skinBack; //Background color for colorizable skins
+ char cZero[16 - sizeof(LPCTSTR) - sizeof(COLORREF)];
+ //some unused bytes which may come useful in the future.
+} POPUPDATAEX, *LPPOPUPDATAEX;
+
+/*
+When you call MS_POPUP_ADDPOPUP, my plugin will check if the given POPUPDATA structure is filled with acceptable values. If not, the data will be rejected and no popup will be shown.
+
+- lpzText should be given, because it's really bad if a user chooses to have the second line displayed
+and it's empty :-) Just write it and let the user choose if it will be displayed or not.
+
+- PluginWindowProc is a WNDPROC address you have to give me. Why? What? Where? Calm down 8)
+My plugin will take care of the creation of the popup, of the destruction of the popup, of the come into
+view and the hiding of the popup. Transparency, animations... all this stuff.
+My plugin will not (as example) open the MessageWindow when you left click on a popup.
+Why? Because I don't know if your popup desires to open the MessageWindow :))))
+This means that you need to make a WNDPROC which takes care of the WM_messages you need.
+For example, WM_COMMAND or WM_CONTEXTMENU or WM_LMOUSEUP or whatever.
+At the end of your WNDPROC remember to "return DefWindowProc(hwnd, msg, wParam, lParam);"
+When you process a message that needs a return value (an example could be WM_CTLCOLORSTATIC,
+but you don't need to catch it 'cause it's my plugin's job), simply return the nedeed value. :)
+The default WNDPROC does nothing.
+
+- PluginData is a pointer to a void, which means a pointer to anything. You can make your own structure
+to store the data you need (example: a status information, a date, your name, whatever) and give me a
+pointer to that struct.
+You will need to destroy that structure and free the memory when the PopUp is going to be destroyed. You'll know this when you receive a UM_FREEPLUGINDATA. The name tells it all: free your own plugin data.
+
+Appendix A: Messages my plugin will handle and your WNDPROC will never see.
+WM_CREATE, WM_DESTROY, WM_TIMER, WM_ERASEBKGND
+WM_CTLCOLOR* [whatever it may be: WM_CTLCOLORDLG, WM_CTLCOLORSTATIC...]
+WM_PAINT, WM_PRINT, WM_PRINTCLIENT
+
+Appendix B: "What do I need to do?!?".
+Here is an example in C.
+
+//Your plugin is in /plugins/myPlugin/ or in miranda32/something/
+#include "../../plugins/PopUp/m_popup.h"
+
+Define your own plugin data if you need it. In this example, we need it and we'll use NewStatusNotify as example: thsi plugin shows a popup when someone in your contact list changes his/hers status. We'll need to know his status, both current and old one.
+typedef struct {
+ WORD oldStatus;
+ WORD newStatus;
+} MY_PLUGIN_DATA;
+
+When we need to show the popup, we do:
+{
+ POPUPDATA ppd;
+ hContact = A_VALID_HANDLE_YOU_GOT_FROM_SOMEWHERE;
+ hIcon = A_VALID_HANDLE_YOU_GOT_SOMEWHERE;
+ char * lpzContactName = (char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)lhContact,0);
+ //99% of the times you'll just copy this line.
+ //1% of the times you may wish to change the contact's name. I don't know why you should, but you can.
+ char * lpzText;
+ //The text for the second line. You could even make something like: char lpzText[128]; lstrcpy(lpzText, "Hello world!"); It's your choice.
+ COLORREF colorBack = GetSysColor(COLOR_BTNFACE); //The colour of Miranda's option Pages (and many other windows...)
+ COLORREF colorText = RGB(255,255,255); //White.
+ MY_PLUGIN_DATA * mpd = (MY_PLUGIN_DATA*)malloc(sizeof(MY_PLUGIN_DATA));
+
+ ZeroMemory(ppd, sizeof(ppd)); //This is always a good thing to do.
+ ppd.lchContact = (HANDLE)hContact; //Be sure to use a GOOD handle, since this will not be checked.
+ ppd.lchIcon = hIcon;
+ lstrcpy(ppd.lpzContactName, lpzContactName);
+ lstrcpy(ppd.lpzText, lpzText);
+ ppd.colorBack = colorBack;
+ ppd.colorText = colorText;
+ ppd.PluginWindowProc = (WNDPROC)PopupDlgProc;
+
+ //Now the "additional" data.
+ mpd->oldStatus = ID_STATUS_OFFLINE;
+ mpd->newStatus = ID_STATUS_ONLINE;
+
+ //Now that the plugin data has been filled, we add it to the PopUpData.
+ ppd.PluginData = mpd;
+
+ //Now that every field has been filled, we want to see the popup.
+ CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0);
+}
+
+Obviously, you have previously declared some:
+static int CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message) {
+ case WM_COMMAND:
+ if ((HIWORD)wParam == STN_CLICKED) { //It was a click on the Popup.
+ PUDeletePopUp(hWnd);
+ return TRUE;
+ }
+ break;
+ case UM_FREEPLUGINDATA: {
+ MY_PLUGIN_DATA * mpd = NULL;
+ mpd = (MY_PLUGIN_DATA*)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd,(LPARAM)mpd);
+ if (mdp > 0) free(mpd);
+ return TRUE; //TRUE or FALSE is the same, it gets ignored.
+ }
+ default:
+ break;
+ }
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+*/
+
+/*
+Creates, adds and shows a popup, given a (valid) POPUPDATA structure pointer.
+wParam = (WPARAM)(*POPUPDATA)PopUpDataAddress
+lParam = 0
+Returns: > 0 on success, 0 if creation went bad, -1 if the PopUpData contained unacceptable values.
+NOTE: it returns -1 if the PopUpData was not valid, if there were already too many popups, if the module was disabled.
+Otherwise, it can return anything else...
+*/
+#define MS_POPUP_ADDPOPUP "PopUp/AddPopUp"
+static int __inline PUAddPopUp(POPUPDATA* ppdp) {
+ return CallService(MS_POPUP_ADDPOPUP, (WPARAM)ppdp,0);
+}
+
+#define MS_POPUP_ADDPOPUPEX "PopUp/AddPopUpEx"
+static int __inline PUAddPopUpEx(POPUPDATAEX* ppdp) {
+ return CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)ppdp,0);
+}
+
+/*
+Returns the handle to the contact associated to the specified PopUpWindow.
+You will probably need to know this handle inside your WNDPROC. Exampole: you want to open the MessageWindow. :-)
+Call MS_POPUP_GETCONTACT on the hWnd you were given in the WNDPROC.
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = 0;
+Returns: the HANDLE of the contact. Can return NULL, meaning it's the main contact. -1 means failure.
+*/
+#define MS_POPUP_GETCONTACT "PopUp/GetContact"
+static HANDLE __inline PUGetContact(HWND hPopUpWindow) {
+ return (HANDLE)CallService(MS_POPUP_GETCONTACT, (WPARAM)hPopUpWindow,0);
+}
+
+/*
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = (LPARAM)(PLUGINDATA*)PluginDataAddress;
+Returns: the address of the PLUGINDATA structure. Can return NULL, meaning nothing was given. -1 means failure.
+IMPORTANT NOTE: it doesn't seem to work if you do:
+CallService(..., (LPARAM)aPointerToAStruct);
+and then use that struct.
+Do this, instead:
+aPointerToStruct = CallService(..., (LPARAM)aPointerToAStruct);
+and it will work. Just look at the example I've written above (PopUpDlgProc).
+*/
+#define MS_POPUP_GETPLUGINDATA "PopUp/GetPluginData"
+static void __inline * PUGetPluginData(HWND hPopUpWindow) {
+ long * uselessPointer = NULL;
+ return (void*)CallService(MS_POPUP_GETPLUGINDATA,(WPARAM)hPopUpWindow,(LPARAM)uselessPointer);
+}
+
+/*
+wParam = 0
+lParam = 0
+Returns: 0 if the user has chosen not to have the second line, 1 if he choose to have the second line.
+*/
+#define MS_POPUP_ISSECONDLINESHOWN "PopUp/IsSecondLineShown"
+static BOOL __inline PUIsSecondLineShown() {
+ return (BOOL)CallService(MS_POPUP_ISSECONDLINESHOWN,0,0);
+}
+
+/*
+Requests an action or an answer from PopUp module.
+wParam = (WPARAM)wpQuery
+returns 0 on success, -1 on error, 1 on stupid calls ;-)
+*/
+#define PUQS_ENABLEPOPUPS 1 //returns 0 if state was changed, 1 if state wasn't changed
+#define PUQS_DISABLEPOPUPS 2 // " "
+#define PUQS_GETSTATUS 3 //Returns 1 (TRUE) if popups are enabled, 0 (FALSE) if popups are disabled.
+
+#define MS_POPUP_QUERY "PopUp/Query"
+
+/*
+UM_FREEPLUGINDATA
+wParam = lParam = 0. Process this message if you have allocated your own memory. (i.e.: POPUPDATA.PluginData != NULL)
+*/
+#define UM_FREEPLUGINDATA (WM_USER + 0x0200)
+
+/*
+UM_DESTROYPOPUP
+wParam = lParam = 0. Send this message when you want to destroy the popup, or use the function below.
+*/
+#define UM_DESTROYPOPUP (WM_USER + 0x0201)
+static int __inline PUDeletePopUp(HWND hWndPopUp) {
+ return (int)SendMessage(hWndPopUp, UM_DESTROYPOPUP,0,0);
+}
+
+/*
+UM_INITPOPUP
+wParam = (WPARAM)(HWND)hPopUpWindow (but this is useless, since I'll directly send it to your hPopUpWindow
+lParam = 0.
+This message is sent to the PopUp when its creation has been finished, so POPUPDATA (and thus your PluginData) is reachable.
+Catch it if you needed to catch WM_CREATE or WM_INITDIALOG, which you'll never ever get in your entire popup-life.
+Return value: if you process this message, return 0. If you don't process it, return 0. Do whatever you like ;-)
+*/
+#define UM_INITPOPUP (WM_USER + 0x0202)
+
+/*
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = (LPARAM)(char*)lpzNewText
+returns: > 0 for success, -1 for failure, 0 if the failure is due to second line not being shown. (but you could call PUIsSecondLineShown() before changing the text...)
+Changes the text displayed in the second line of the popup.
+*/
+#define MS_POPUP_CHANGETEXT "PopUp/Changetext"
+static int __inline PUChangeText(HWND hWndPopUp, LPCTSTR lpzNewText) {
+ return (int)CallService(MS_POPUP_CHANGETEXT, (WPARAM)hWndPopUp, (LPARAM)lpzNewText);
+}
+
+/*
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = (LPARAM)(POPUPDATAEX*)newData
+Changes the entire popup
+*/
+#define MS_POPUP_CHANGE "PopUp/Change"
+static int __inline PUChange(HWND hWndPopUp, POPUPDATAEX *newData) {
+ return (int)CallService(MS_POPUP_CHANGE, (WPARAM)hWndPopUp, (LPARAM)newData);
+}
+
+/*
+This is mainly for developers.
+Shows a warning message in a PopUp. It's useful if you need a "MessageBox" like function, but you don't want a modal window (which will interfere with a DialogProcedure. MessageBox steals focus and control, this one not.
+wParam = (char*) lpzMessage
+lParam = 0;
+Returns: 0 if the popup was shown, -1 in case of failure.
+*/
+#define SM_WARNING 0x01 //Triangle icon.
+#define SM_NOTIFY 0x02 //Exclamation mark icon.
+#define MS_POPUP_SHOWMESSAGE "PopUp/ShowMessage"
+
+static int __inline PUShowMessage(char* lpzText, BYTE kind) {
+ return (int)CallService(MS_POPUP_SHOWMESSAGE, (WPARAM)lpzText,(LPARAM)kind);
+}
+
+/*
+Each skinned popup (e.g. with colorBack == POPUP_USE_SKINNED_BG) should have
+class set. Then you can choose separate skin for each class (for example, you
+can create separate class for your plugin and use it for all ypu popups. User
+would became able to choose skin for your popups independently from others)
+
+You have to register popup class before using it. To do so call "PopUp/AddClass"
+with lParam = (LPARAM)(const char *)popUpClassName.
+
+All class names are translated (via Translate()) before being added to list. You
+should use english names for them.
+
+There are three predefined classes and one for backward compatability.
+
+Note that you can add clases after popup wal loaded, e.g. you shoul intercept
+ME_SYSTEM_MODULESLOADED event
+*/
+#define MS_POPUP_ADDCLASS "PopUp/AddClass"
+#define POPUP_CLASS_DEFAULT "Default"
+#define POPUP_CLASS_WARNING "Warning"
+#define POPUP_CLASS_NOTIFY "Notify"
+#define POPUP_CLASS_OLDAPI "PopUp 1.0.1.x compatability" // for internal purposes
+
+static void __inline PUAddClass(const char *lpzClass){
+ CallService(MS_POPUP_ADDCLASS, 0, (LPARAM)lpzClass);
+}
+
+#endif
diff --git a/nudge/include/m_popupw.h b/nudge/include/m_popupw.h new file mode 100644 index 0000000..c0cac41 --- /dev/null +++ b/nudge/include/m_popupw.h @@ -0,0 +1,56 @@ +/*
+===============================================================================
+ PopUp plugin
+Plugin Name: PopUp
+Plugin authors: Luca Santarelli aka hrk (hrk@users.sourceforge.net)
+ Victor Pavlychko aka zazoo (nullbie@gmail.com)
+===============================================================================
+The purpose of this plugin is to give developers a common "platform/interface"
+to show PopUps. It is born from the source code of NewStatusNotify, another
+plugin I've made.
+
+Remember that users *must* have this plugin enabled, or they won't get any
+popup. Write this in the requirements, do whatever you wish ;-)... but tell
+them!
+===============================================================================
+*/
+#ifndef M_POPUPW_H
+#define M_POPUPW_H
+
+#ifndef MAX_CONTACTNAME
+ #define MAX_CONTACTNAME 2048
+#endif
+
+#ifndef MAX_SECONDLINE
+ #define MAX_SECONDLINE 2048
+#endif
+
+// Unicode Popup Info
+typedef struct {
+ HANDLE lchContact;
+ HICON lchIcon;
+ WCHAR lpwzContactName[MAX_CONTACTNAME];
+ WCHAR lpwzText[MAX_SECONDLINE];
+ COLORREF colorBack;
+ COLORREF colorText;
+ WNDPROC PluginWindowProc;
+ void * PluginData;
+ int iSeconds; //Custom delay time in seconds. -1 means "forever", 0 means "default time".
+ char cZero[16]; //some unused bytes which may come useful in the future.
+} POPUPDATAW, *LPPOPUPDATAW;
+
+// Create Popup
+#define MS_POPUP_ADDPOPUPW "PopUp/AddPopUpW"
+
+static int __inline PUAddPopUpW(POPUPDATAW* ppdp) {
+ return CallService(MS_POPUP_ADDPOPUPW, (WPARAM)ppdp,0);
+}
+
+// Change Text
+#define MS_POPUP_CHANGETEXTW "PopUp/ChangetextW"
+
+static int __inline PUChangeTextW(HWND hWndPopUp, LPCWSTR lpwzNewText) {
+ return (int)CallService(MS_POPUP_CHANGETEXTW, (WPARAM)hWndPopUp, (LPARAM)lpwzNewText);
+}
+
+#endif
diff --git a/nudge/include/m_toptoolbar.h b/nudge/include/m_toptoolbar.h new file mode 100644 index 0000000..22aef67 --- /dev/null +++ b/nudge/include/m_toptoolbar.h @@ -0,0 +1,105 @@ +
+#ifndef M_TOPTOOLBAR_H
+#define M_TOPTOOLBAR_H
+
+//button flags
+#define TTBBF_DISABLED 1
+#define TTBBF_VISIBLE 2
+#define TTBBF_PUSHED 4
+#define TTBBF_SHOWTOOLTIP 8
+#define TTBBF_DRAWBORDER 16//draw border for bitmap,bitmap must be WxH 16x12
+
+
+typedef struct {
+ int cbSize;
+ HBITMAP hbBitmapUp;
+ HBITMAP hbBitmapDown;
+ char *pszServiceUp;
+ char *pszServiceDown;
+ DWORD dwFlags;
+ LPARAM lParamUp;
+ WPARAM wParamUp;
+ LPARAM lParamDown;
+ WPARAM wParamDown;
+ char *name;
+
+} TTBButton, * lpTTBButton;
+
+//=== EVENTS ===
+/*
+toptoolbar/moduleloaded event
+wParam = lParam = 0
+Called when the toolbar services are available
+
+!!!Warning you may work with TTB services only in this event or later.
+
+Im use settimer() - so notify appear in miranda message loop
+after all onmodulesload calls.
+*/
+#define ME_TTB_MODULELOADED "TopToolBar/ModuleLoaded"
+
+
+
+//=== SERVICES ===
+/*
+toptoolbar/addbutton service
+wparam = (TTBButton*)lpTTBButton
+lparam = 0
+returns: hTTBButton - handle of added button on success, -1 on failure.
+*/
+#define MS_TTB_ADDBUTTON "TopToolBar/AddButton"
+
+/*
+toptoolbar/removebutton service
+wparam = (HANDLE)hTTButton
+lparam = 0
+returns: 0 on success, -1 on failure.
+*/
+#define MS_TTB_REMOVEBUTTON "TopToolBar/RemoveButton"
+
+/*
+toptoolbar/setstate service
+wparam = (HANDLE)hTTButton
+lparam = (LPARAM) state
+returns: 0 on success, -1 on failure.
+*/
+#define TTBST_PUSHED 1
+#define TTBST_RELEASED 2
+
+#define MS_TTB_SETBUTTONSTATE "TopToolBar/SetState"
+
+/*
+toptoolbar/getstate service
+wparam = (HANDLE)hTTButton
+lparam = 0
+returns: state on success, -1 on failure.
+*/
+#define MS_TTB_GETBUTTONSTATE "TopToolBar/GetState"
+
+/*
+toptoolbar/getoptions service
+(HIWORD)wparam = (HANDLE)hTTButton
+(LOWORD)wparam = TTBO_FLAG
+lparam = 0,or lparam=lpTTBButton if flag=TTBO_ALLDATA
+returns: value on success, -1 on failure.
+*/
+#define TTBO_FLAGS 0 //get/set all flags
+#define TTBO_POS 1 //position
+#define TTBO_WIDTH 2 //not impemented
+#define TTBO_HEIGHT 3 //not impemented
+#define TTBO_TIPNAME 4 //tool tip name
+#define TTBO_ALLDATA 5 //change all data via lparam=lpTTBButton
+
+
+#define MS_TTB_GETBUTTONOPTIONS "TopToolBar/GetOptions"
+
+/*
+toptoolbar/setoptions service
+(HIWORD)wparam = (HANDLE)hTTButton
+(LOWORD)wparam = TTBO_FLAG
+lparam = value
+returns: 1 on success, -1 on failure.
+*/
+#define MS_TTB_SETBUTTONOPTIONS "TopToolBar/SetOptions"
+
+#endif
\ No newline at end of file diff --git a/nudge/include/m_trigger.h b/nudge/include/m_trigger.h new file mode 100644 index 0000000..b5294bd --- /dev/null +++ b/nudge/include/m_trigger.h @@ -0,0 +1,1004 @@ +#ifndef __M_TRIGGER_H__
+#define __M_TRIGGER_H__
+
+#if !defined(_TCHAR_DEFINED)
+#include <tchar.h>
+#endif
+#include "m_utils.h"
+
+// --------------------------------------------------------------------------
+// Triggers
+// --------------------------------------------------------------------------
+
+// This section explains how to create your own trigger. A trigger can be seen
+// as an event which can result in a set of actions that will be performed.
+// Implementing a trigger consists of two parts. First, you register a trigger
+// with MS_TRIGGER_REGISTERTRIGGER to allow a user to configure it in the
+// options dialog. Second, when the event occurs belonging to your registered
+// trigger, you inform the trigger plugin with MS_TRIGGER_REPORTEVENT. You can
+// send a 'payload' together with this notification. This payload, called
+// 'TriggerData', can consist of a certain contact, protocol, status and/or a
+// piece of text.
+
+// --------------------------------------------------------------------------
+// Triggers: Register a trigger
+// --------------------------------------------------------------------------
+
+#define MS_TRIGGER_REGISTERTRIGGER "/TriggerPlugin/RegisterTrigger"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)0
+// lParam = (LPARAM)(TRIGGERREGISTER *)&tr
+// Pointer to a structure describing the trigger to add (see below).
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nozero otherwise. Registering an already existing
+// trigger will replace this previously registered trigger.
+
+typedef struct {
+ int cbSize; // Set to sizeof(TRIGGERREGISTER).
+ char *pszName; // Used as identifier and shown in the options dialog, must
+ // be unique.
+ HINSTANCE hInstance; // Only needed when options screen is available.
+ DLGPROC pfnDlgProc; // Optional, the callback procedure for the options page.
+ char *pszTemplate; // Optional, template for the options page; must be
+ // WS_CHILD.
+ int flags; // Flags, see below.
+ int dFlags; // Specify the default DF_* flags which your trigger can send
+ // (see below).
+} TRIGGERREGISTER;
+
+// Flags
+#define TRF_NOEXPORT 0x01 // This trigger cannot be exported. Set this flag
+ // in case you stored settings not using the helper
+ // functions at the end of this header. On export,
+ // TriggerPlugin will search for these settings
+ // and export them automatically. Contact-specific
+ // settings are never exported.
+
+// Please specify the dFlags to indicate what kind of data your trigger is
+// able to send as TriggerData. Please specify the maximum set, if your trigger
+// does not always send a certain data, please specify it anyway.
+
+#define DF_CONTACT 0x01 // The trigger might send a contact handle with the
+ // TriggerData.
+#define DF_PROTO 0x02 // The trigger might send a protocol ID with the
+ // TriggerData.
+#define DF_STATUS 0x04 // The trigger might send a status code with the
+ // TriggerData.
+#define DF_TEXT 0x08 // The trigger might send a string with the
+ // TriggerData.
+#define DF_LPARAM 0x10 // The trigger might send a custom parameter with the
+ // TriggerData.
+#define DF_UNICODE 0x20 // The trigger processes WCHAR strings.
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define DF_TCHAR DF_UNICODE // Strings in structure are TCHAR*.
+#else
+#define DF_TCHAR 0
+#endif
+
+// Dialog Messages
+// The following message should be processed by your options dialog procedure,
+// if available. You can create an options dialog to give the user the
+// possibility to report your event only under certain circumstances. Each
+// trigger is assigned a certain ID. This ID can be used to store the settings
+// for your trigger.
+
+// WM_INITDIALOG
+
+// Parameters:
+// ------------------------
+// lParam = (LPARAM)(DWORD)triggerID
+// The trigger ID for which the options are to be set. This can be a new ID
+// or an ID of a trigger which is being edited. Initialize your options
+// dialog accordingly. There are helper function at the end of this header
+// file to read your settings for a certain trigger ID.
+
+#define TM_ADDTRIGGER WM_APP+10
+
+// TM_ADDTRIGGER
+// 'OK' is pressed and a new trigger will be added. Save your settings using
+// the given trigger ID.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)triggerID
+// The trigger ID for which the settings are to be stored. There are helper
+// function at the end of this header file to store your settings with a
+// certain trigger ID.
+// lParam = 0
+
+#define TM_DELTRIGGER WM_APP+11
+
+// TM_DELTRIGGER
+// The trigger addociated with the given trigger ID will be removed.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)triggerID
+// The trigger ID for which the settings are to be removed. There is a
+// helper service at the end of this header file to easily cleanup settings
+// for a certain trigger ID.
+// lParam = 0
+
+// --------------------------------------------------------------------------
+// Triggers: Report the Event
+// --------------------------------------------------------------------------
+
+// When the event occurs, you report it with MS_TRIGGER_REPORTEVENT. If your
+// trigger is configurable, so it has an options screen, you might want to
+// report your trigger for certain trigger ID's only. Please use the
+// MS_TRIGGER_FINDNEXTTRIGGERID to enumerate over the trigger ID's associated
+// with your trigger in the correct order as specified by the user. It's up
+// to you to found out whether or not the trigger is to be reported for a
+// certain ID.
+
+#define MS_TRIGGER_FINDNEXTTRIGGERID "/TriggerPlugin/FindNextTriggerID"
+
+// Enumerate over the associated trigger ID's for your trigger in the correct
+// order.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)triggerID
+// 0 to retrieve the first trigger ID for your trigger or the previous ID
+// returned by this service to get the next one.
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Returns the next trigger ID given the parameter or 0 if no more trigger IDs
+// are available.
+
+#define MS_TRIGGER_REPORTEVENT "/TriggerPlugin/ReportEvent"
+
+// Report your event for further processing. This can be a general event for
+// which no individual settings exist, or a specific event for a given
+// trigger ID.
+
+// Parameters:
+// ------------------------
+// wParam = 0
+// lParam = (LPARAM)(REPORTINFO *)&ri
+// See below.
+
+// Return Value:
+// ------------------------
+// Returns CRV_TRUE if all conditions specific to this trigger hold and the
+// chain was executed. Returns CRV_FALSE if these conditions did not hold and
+// the chain were not processed.
+
+// The structure below can be used to send TriggerData with your trigger. This
+// can be used by the associated conditions and actions.
+
+typedef struct {
+ int cbSize; // Set to sizeof(TRIGGERDATA)
+ int dFlags; // Indicate which members are valid using the DF_* flags (see
+ // above).
+ HANDLE hContact; // Associate a contact handle to this event.
+ char *szProto; // Associate a protocol ID to this event.
+ int status; // Associcate a status code to this event.
+ union {
+ char *szText; // Associate a string to this event.
+ TCHAR *tszText;
+ WCHAR *wszText;
+ };
+ LPARAM lParam; // Associate custom data to this trigger.
+} TRIGGERDATA;
+
+typedef struct {
+ int cbSize; // Set to sizeof(REPORTINFO).
+ DWORD triggerID; // The trigger ID of the event to trigger or 0 if this does
+ // not apply.
+ char *pszName; // The name of the trigger (this may be NULL if triggerID is
+ // not 0).
+ int flags; // On of the TRG_* flags, see below.
+ TRIGGERDATA *td; // Optional, the associated TriggerData, see above.
+} REPORTINFO;
+
+#define TRG_PERFORM 0x01 // Indicates the event for this trigger actually
+ // occured and needs to be processed accordingly.
+#define TRG_CLEANUP 0x02 // Indicates the trigger instructs to remove the
+ // itself and all associated information. This can
+ // be used for "one time triggers". Remove your own
+ // settings by yourself.
+
+// --------------------------------------------------------------------------
+// Actions
+// --------------------------------------------------------------------------
+
+// An actions might be performed as a reaction to a reported event by a
+// trigger. You first register your action so it can be associated to a
+// trigger in the options screen. Next, your provided service or function
+// will be called when necessary.
+
+#define MS_TRIGGER_REGISTERACTION "/TriggerPlugin/RegisterAction"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)0
+// lParam = (LPARAM)(ACTIONREGISTER *)&ar
+// Pointer to a structure describing the action to add (see below).
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nozero otherwise. Registering an already existing
+// action will replace this previously registered action.
+
+typedef struct {
+ int cbSize; // Set to sizeof(ACTIONREGISTER).
+ char *pszName; // The name of this action, it must be a unique string.
+ union {
+ char *pszService; // A service (called with wParam =
+ // (WPARAM)(DWORD)actionID, lParam =
+ // (LPARAM)(REPORTINFO *)&ri) or function to be called
+ // when the action has to be performed.
+ int (*actionFunction)(DWORD actionID, REPORTINFO *ri);
+ };
+ HINSTANCE hInstance; // Only needed when an options screen is available.
+ DLGPROC pfnDlgProc; // Optional, the callback procedure for the options
+ // dialog.
+ char *pszTemplate; // Optional, template for the options dialog, must be
+ // WS_CHILD.
+ int flags; // One of the ARF_* flags, see below.
+} ACTIONREGISTER;
+
+#define ARF_UNICODE 0x01 // This action processes unicode strings.
+#define ARF_FUNCTION 0x02 // The actionFunction will be called instead of
+ // the service.
+#define ARF_NOEXPORT 0x04 // This action cannot be exported. Set this flag in
+ // case you stored settings not using the helper
+ // functions at the end of this header. On export,
+ // TriggerPlugin will search for these settings
+ // and export them automatically. Contact-specific
+ // settings are never exported.
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define ARF_TCHAR ARF_UNICODE
+#else
+#define ARF_TCHAR 0
+#endif
+
+// The service or actionFunction will be called with a pointer to a REPORTINFO
+// struct, containing information about the trigger event. If you can use
+// TriggerData from this struct, always check the ri->td->dFlags before using
+// it. It's up to you to deal with an action in case the expected TriggerData
+// is not available. It's recommened though, to cancel your action. The
+// ri->flags is a combination of the ACT_* flags, indicating how to process the
+// call, see below.
+
+#define ACT_PERFORM 0x01 // Your action is to be performed.
+#define ACT_CLEANUP 0x02 // The settings associated to this action should be
+ // removed.
+
+// Dialog Messages
+// The following messages are to be processed by the options dialog, if there
+// is one.
+
+// WM_INITDIALOG
+
+// Parameters:
+// ------------------------
+// lParam = (LPARAM)(DWORD)actionID
+// The action ID for which the options are to be set. This can be a new ID
+// or an ID of an action which is being edited. Initialize your options
+// dialog accordingly. There are helper function at the end of this header
+// file to read your settings for a certain action ID.
+
+#define TM_ADDACTION WM_APP+12
+
+// TM_ADDACTION
+// 'OK' is pressed and a new action will be added. Save your settings using
+// the given action ID. Helper functions can be found at the end of this
+// header file.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)actionID
+// The action ID for which the settings are to be saved. There are helper
+// functions at the end of this header file to store settings with a certain
+// action ID.
+// lParam = 0
+
+// Dialog Messages
+// You can send the following messages to the parent window of your dialog.
+// When initalizing your dialog, you might be interested in the TriggerData
+// the associated trigger is able to provide, you can do so by sending the
+// folowing message to the parent of your dialog.
+
+#define TM_GETTRIGGERINFO WM_APP+13
+
+// Parameters:
+// ------------------------
+// wParam = 0
+// lParam = (LPARAM)(TRIGGERINFO *)&ti
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, the struct given will be filled with the requested
+// information. Returns any other value on error.
+
+typedef struct {
+ int cbSize; // (in) Set to sizeof(TRIGGERINFO).
+ int dFlags; // (out) The default DF_* flags used by the trigger (as indicated
+ // by its TRIGGERREGISTER).
+} TRIGGERINFO;
+
+// --------------------------------------------------------------------------
+// Conditions
+// --------------------------------------------------------------------------
+
+// Depending on the configuration of the user, a condition may need to hold
+// for an action to be performed. A condition function is called and its
+// return value specifies whether or not the condition holds. A condition
+// needs to be registered. After its registered, the condition function might
+// be called to check whether or not the condition holds.
+
+#define MS_TRIGGER_REGISTERCONDITION "/TriggerPlugin/RegisterCondition"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)0
+// lParam = (LPARAM)(CONDITIONREGISTER *)&cr
+// Pointer to a structure describing the condition to add (see below).
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nozero otherwise. Registering an already existing
+// condition will replace this previously registered condition.
+
+typedef struct {
+ int cbSize; // Set to sizeof(CONDITIONREGISTER).
+ char *pszName; // The name identifying this condition, must be unique.
+ union {
+ char *pszService; // The service (wParam = (WPARAM)(DWORD)conditionID,
+ // lParam = (LPARAM)(REPORTINFO *)&ri) or function which
+ // is called to see whether the condition holds. Must
+ // return CRV_TRUE if the condition holds, CRV_FALSE
+ // otherwise.
+ int (*conditionFunction)(DWORD conditionID, REPORTINFO *ri);
+ };
+ HINSTANCE hInstance; // Only needed when an options dialog is available.
+ DLGPROC pfnDlgProc; // Optional, the dialog procedure for the options
+ // dialog.
+ char *pszTemplate; // Optional, template for the options dialog, must be
+ // WS_CHILD.
+ int flags; // CRF_* flags, see below.
+} CONDITIONREGISTER;
+
+// The flags that can be used to register the condition.
+
+#define CRF_UNICODE 0x01 // The condition function or service processes
+ // unicode strings.
+#define CRF_FUNCTION 0x02 // The conditionFunction will be called instead of
+ // the service.
+#define CRF_NOEXPORT 0x04 // This condition cannot be exported. Set this flag
+ // in case you stored settings not using the helper
+ // functions at the end of this header. On export,
+ // TriggerPlugin will search for these settings
+ // and export them automatically. Contact-specific
+ // settings are never exported.
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define CRF_TCHAR CRF_UNICODE
+#else
+#define CRF_TCHAR 0
+#endif
+
+// The service or conditionFunction will be called with a pointer to a
+// REPORTINFO struct, containing information about the trigger event. If you
+// can use TriggerData from this struct, always check the ri->td->dFlags before
+// using it. It's up to you to deal with an condition in case the expected
+// TriggerData is not available. It's recommened though, to return CRV_FALSE in
+// those cases. The ri->flags is a combination of the CND_* flags, indicating
+// how to process the call, see below.
+
+// Return values for the condition function or service. The condition service
+// or function is expected to return one of the following.
+
+#define CRV_FALSE 0 // The condition does not hold.
+#define CRV_TRUE 1 // The condition does hold.
+
+// REPORTINFO flags, received by the condition function or service. These
+// indicate how to process the call.
+
+#define CND_PERFORM 0x01 // Perform your condition and return either
+ // CRV_TRUE or CRV_FALSE to indicate whether or not
+ // your condition holds at this moment.
+#define CND_CLEANUP 0x02 // The condition is deleted. Remove your settings
+ // from the DB. There is a helper service below to
+ // easily remove settings given a condition ID.
+
+// Dialog Messages
+// The following messages are to be processed by the options dialog, if there
+// is one.
+
+// WM_INITDIALOG
+
+// Parameters:
+// ------------------------
+// lParam = (LPARAM)(DWORD)conditionID
+// The condition ID for which the options are to be set. This can be a new ID
+// or an ID of a condition which is being edited. Initialize your options
+// dialog accordingly. There are helper function at the end of this header
+// file to read your settings for a certain condition ID.
+
+#define TM_ADDCONDITION WM_APP+14
+
+// TM_ADDCONDITION
+// 'OK' is pressed and a new condition will be added. Save your settings using
+// the given condition ID. Helper functions can be found at the end of this
+// header file.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)conditionID
+// The condition ID for which the settings are to be saved. There are helper
+// functions at the end of this header file to store settings with a certain
+// condition ID.
+// lParam = 0
+
+// When initalizing your dialog, you might be interested in the TriggerData the
+// associated trigger is able to provide, you can find out by sending a
+// TM_GETTRIGGERINFO message to the parent of your dialog. See the section on
+// dialog messages for actions for more information (above).
+
+// --------------------------------------------------------------------------
+// Misc. Services
+// --------------------------------------------------------------------------
+
+#define MS_TRIGGER_ENABLETRIGGER "/TriggerPlugin/EnableTrigger"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(DWORD)triggerID
+// The triggerID to set or get the state from or 0 for the global state.
+// lParam = (LPARAM)(int)type
+// One of ETT_* (see below).
+// Pointer to a structure describing the settings to remove (see below).
+
+// Return Value:
+// ------------------------
+// Returns the state (0=disabled) if ETT_GETSTATE is given as lParam.
+// Otherwise, it returns 0 if setting the state was succesful or any other on
+// failure. The global state must be enabled if a single state is to be
+// changed.
+
+#define ETT_DISABLE 0 // Disable the trigger(s).
+#define ETT_ENABLE 1 // Enable the trigger(s).
+#define ETT_TOGGLE 2 // Toggle the state of the trigger(s).
+#define ETT_GETSTATE 3 // Retrieve the state of the trigger (0=disabled).
+
+// --------------------------------------------------------------------------
+// Database Helper Services
+// --------------------------------------------------------------------------
+
+// The rest of this header file defines helper services and functions to easily
+// store and retrieve settings for a certain trigger, action or condition.
+
+#define MS_TRIGGER_REMOVESETTINGS "/TriggerPlugin/RemoveSettings"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)0
+// lParam = (LPARAM)(REMOVETRIGGERSETTINGS *)&rts
+// Pointer to a structure describing the settings to remove (see below).
+
+// Return Value:
+// ------------------------
+// Returns the number of settings removed from the database.
+
+// This service helps you remove all settings you have written with the DB
+// helper functions, defined at the end of this header file.
+
+typedef struct {
+ int cbSize; // Set to sizeof(REMOVETRIGGERSETTINGS).
+ char *prefix; // A string indicating what kind of setting are to be removed,
+ // see below.
+ DWORD id; // The ID of the set of settings to be removed.
+ char *szModule; // The module where the settings are stored.
+ HANDLE hContact; // The contact for which the setting are to be removed. Can
+ // be INVALID_HANDLE_VALUE to remove the settings for all
+ // contacts and NULL.
+} REMOVETRIGGERSETTINGS;
+
+// The following prefixes indicate what kind of settings are to be removed from
+// the database.
+
+#define PREFIX_ACTIONID "aid" // The prefix for a DB setting associated to
+ // an action.
+#define PREFIX_TRIGGERID "tid" // The prefix for a DB setting associated to
+ // a trigger.
+#define PREFIX_CONDITIONID "cid" // The prefix for a DB setting associated
+ // to a condition.
+
+#ifndef TRIGGER_NOHELPER
+
+// Helper #1: RemoveAllTriggerSettings
+// ------------------------
+// Remove all settings from the DB given the triggerID and module.
+
+static __inline int RemoveAllTriggerSettings(DWORD triggerID, char *szModule) {
+
+ REMOVETRIGGERSETTINGS rts;
+
+ rts.cbSize = sizeof(REMOVETRIGGERSETTINGS);
+ rts.prefix = PREFIX_TRIGGERID;
+ rts.id = triggerID;
+ rts.szModule = szModule;
+ rts.hContact = INVALID_HANDLE_VALUE;
+
+ return CallService(MS_TRIGGER_REMOVESETTINGS, 0, (LPARAM)&rts);
+}
+
+// Helper #2: RemoveAllActionSettings
+// ------------------------
+// Remove all settings from the DB given the actionID and module.
+
+static __inline int RemoveAllActionSettings(DWORD actionID, char *szModule) {
+
+ REMOVETRIGGERSETTINGS rts;
+
+ rts.cbSize = sizeof(REMOVETRIGGERSETTINGS);
+ rts.prefix = PREFIX_ACTIONID;
+ rts.id = actionID;
+ rts.szModule = szModule;
+ rts.hContact = INVALID_HANDLE_VALUE;
+
+ return CallService(MS_TRIGGER_REMOVESETTINGS, 0, (LPARAM)&rts);
+}
+
+// Helper #1: RemoveAllConditionSettings
+// ------------------------
+// Remove all settings from the DB given the conditionID and module.
+
+static __inline int RemoveAllConditionSettings(DWORD conditionID, char *szModule) {
+
+ REMOVETRIGGERSETTINGS rts;
+
+ rts.cbSize = sizeof(REMOVETRIGGERSETTINGS);
+ rts.prefix = PREFIX_CONDITIONID;
+ rts.id = conditionID;
+ rts.szModule = szModule;
+ rts.hContact = INVALID_HANDLE_VALUE;
+
+ return CallService(MS_TRIGGER_REMOVESETTINGS, 0, (LPARAM)&rts);
+}
+
+// --------------------------------------------------------------------------
+// Database Helper Functions
+// --------------------------------------------------------------------------
+
+// Basically, these function work the same as Miranda's helper functions for
+// getting/setting DB settings. There is one extra parameter, the ID for the
+// trigger/action/condition. The settings are named as follows:
+
+// DBWriteTriggerSetting*(DWORD triggerID, ...) to write a setting given a
+// trigger ID.
+// DBGetTriggerSetting*(DWORD triggerID, ...) to read a setting given a
+// trigger ID.
+// DBWriteActionSetting*(DWORD actionID, ...) to write a setting given an
+// action ID.
+// DBGetActionSetting*(DWORD actionID, ...) to read a setting given an
+// action ID.
+// DBWriteConditionSetting*(DWORD conditionID, ...) to write a setting given a
+// condition ID.
+// DBGetConditionSetting*(DWORD conditionID, ...) to read a setting given a
+// condition ID.
+
+#define MAX_SETTING_LEN 255 // Max. length of a DB setting including the
+ // prefix and ID.
+
+// --------------------------------------------------------------------------
+// Database Helper Functions: Triggers
+// --------------------------------------------------------------------------
+
+static int __inline DBWriteTriggerSettingByte(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,BYTE val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingByte(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteTriggerSettingWord(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,WORD val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingWord(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteTriggerSettingDword(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,DWORD val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingDword(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteTriggerSettingString(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteTriggerSettingTString(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,const TCHAR *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingTString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteTriggerSettingWString(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,const WCHAR *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingWString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteTriggerSettingStringUtf(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBWriteContactSettingStringUtf(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBGetTriggerSettingByte(DWORD triggerID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingByte(hContact, szModule, dbSetting, errorValue);
+}
+
+static WORD __inline DBGetTriggerSettingWord(DWORD triggerID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingWord(hContact, szModule, dbSetting, errorValue);
+}
+
+static DWORD __inline DBGetTriggerSettingDword(DWORD triggerID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingDword(hContact, szModule, dbSetting, errorValue);
+}
+
+static int __inline DBGetTriggerSetting(DWORD triggerID, HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSetting(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetTriggerSettingW(DWORD triggerID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingW(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetTriggerSettingTString(DWORD triggerID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingTString(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetTriggerSettingWString(DWORD triggerID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingWString(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetTriggerSettingStringUtf(DWORD triggerID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBGetContactSettingStringUtf(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBDeleteTriggerSetting(DWORD triggerID, HANDLE hContact,const char *szModule,const char *szSetting) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_TRIGGERID, triggerID, szSetting);
+ return DBDeleteContactSetting(hContact, szModule, dbSetting);
+}
+
+// --------------------------------------------------------------------------
+// Database Helper Functions: Actions
+// --------------------------------------------------------------------------
+
+static int __inline DBWriteActionSettingByte(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,BYTE val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingByte(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteActionSettingWord(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,WORD val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingWord(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteActionSettingDword(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,DWORD val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingDword(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteActionSettingString(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteActionSettingTString(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,const TCHAR *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingTString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteActionSettingWString(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,const WCHAR *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingWString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteActionSettingStringUtf(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBWriteContactSettingStringUtf(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBGetActionSettingByte(DWORD actionID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingByte(hContact, szModule, dbSetting, errorValue);
+}
+
+static WORD __inline DBGetActionSettingWord(DWORD actionID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingWord(hContact, szModule, dbSetting, errorValue);
+}
+
+static DWORD __inline DBGetActionSettingDword(DWORD actionID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingDword(hContact, szModule, dbSetting, errorValue);
+}
+
+static int __inline DBGetActionSetting(DWORD actionID, HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSetting(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetActionSettingW(DWORD actionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingW(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetActionSettingTString(DWORD actionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingTString(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetActionSettingWString(DWORD actionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingWString(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetActionSettingStringUtf(DWORD actionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBGetContactSettingStringUtf(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBDeleteActionSetting(DWORD actionID, HANDLE hContact,const char *szModule,const char *szSetting) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_ACTIONID, actionID, szSetting);
+ return DBDeleteContactSetting(hContact, szModule, dbSetting);
+}
+
+// --------------------------------------------------------------------------
+// Database Helper Functions: Conditions
+// --------------------------------------------------------------------------
+
+static int __inline DBWriteConditionSettingByte(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,BYTE val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingByte(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteConditionSettingWord(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,WORD val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingWord(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteConditionSettingDword(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,DWORD val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingDword(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteConditionSettingString(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteConditionSettingTString(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,const TCHAR *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingTString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteConditionSettingWString(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,const WCHAR *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingWString(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBWriteConditionSettingStringUtf(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting,const char *val) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBWriteContactSettingStringUtf(hContact, szModule, dbSetting, val);
+}
+
+static int __inline DBGetConditionSettingByte(DWORD conditionID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingByte(hContact, szModule, dbSetting, errorValue);
+}
+
+static WORD __inline DBGetConditionSettingWord(DWORD conditionID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingWord(hContact, szModule, dbSetting, errorValue);
+}
+
+static DWORD __inline DBGetConditionSettingDword(DWORD conditionID, HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingDword(hContact, szModule, dbSetting, errorValue);
+}
+
+static int __inline DBGetConditionSetting(DWORD conditionID, HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv) {
+
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSetting(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetConditionSettingW(DWORD conditionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingW(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetConditionSettingTString(DWORD conditionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingTString(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetConditionSettingWString(DWORD conditionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingWString(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBGetConditionSettingStringUtf(DWORD conditionID, HANDLE hContact,const char *szModule, const char *szSetting,DBVARIANT *dbv) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBGetContactSettingStringUtf(hContact, szModule, dbSetting, dbv);
+}
+
+static int __inline DBDeleteConditionSetting(DWORD conditionID, HANDLE hContact,const char *szModule,const char *szSetting) {
+
+ char dbSetting[MAX_SETTING_LEN];
+
+ mir_snprintf(dbSetting, sizeof(dbSetting), "%s%u_%s", PREFIX_CONDITIONID, conditionID, szSetting);
+ return DBDeleteContactSetting(hContact, szModule, dbSetting);
+}
+
+#endif // nohelper
+#endif // m_trigger
diff --git a/nudge/include/m_uninstaller.h b/nudge/include/m_uninstaller.h new file mode 100644 index 0000000..e26f55c --- /dev/null +++ b/nudge/include/m_uninstaller.h @@ -0,0 +1,700 @@ +/*
+
+ PluginUninstaller 1.1.2.1 for Miranda IM 0.3.3a and +
+ ------------------------------------------------------------------------
+ Developers - C/C++ Header File
+
+ Plugin Info: ----------------------------
+ | Version: 1.1.2.1
+ | Filename: uninstaller.dll
+ | Author: H. Herkenrath (hrathh@users.sourceforge.net)
+ | Description: Extends the plugin options and offers the possibility
+ | to directly remove plugins and delete all associated
+ | settings and files.
+
+ Contents: -------------------------------
+ | > General Info:
+ | - Uninstall Example/Template
+ | - Changing displayed icon
+ | - Changing displayed docs
+ | - Message boxes on uninstall
+ | - Service Accesibility
+ | - Including this file
+ |
+ | > Structs:
+ | - Uninstall Params (PLUGINUNINSTALLPARAMS)
+ |
+ | > Helpers:
+ | - Macro: Run service while uninstalling (PUICallService)
+ | - Function: Remove some files in directory (PUIRemoveFilesInDirectory)
+ |
+ | > Events:
+ | - Allow to uninstall a plugin (ME_PLUGINUNINSTALLER_OKTOUNINSTALL)
+ | - Plugin gets uninstalled (ME_PLUGINUNINSTALLER_UNINSTALL)
+ |
+ | > Services:
+ | - Remove database module (MS_PLUGINUNINSTALLER_REMOVEDBMODULE)
+ | - Remove a setting globally (MS_PLUGINUNINSTALLER_REMOVEDBSETTINGGLOBALLY)
+ | - Remove skinned sound (MS_PLUGINUNINSTALLER_REMOVESKINSOUND)
+ | - Uninstall a plugin (MS_PLUGINUNISTALLER_UNISTALLPLUGIN)
+ | - Getting handles (MS_PLUGINUNINSTALLER_GETHANDLE)
+ |
+
+
+ This file is only thought for plugin developers.
+ If you only want to use "PluginUninstaller" and don't want to develop a plugin
+ or something with it you don't need this file.
+
+ If there are any problems or bugs with or in this file or something else
+ please mail me. My e-mail address is: hrathh@users.sourceforge.net
+ For more documentation you can use this address, too. :-)
+
+ If you have any whishes on some plugin uninstalling for your
+ plugin you can mail me, too. :-)
+
+*/
+#ifndef M_UNINSTALLER_H
+#define M_UNINSTALLER_H
+
+#ifndef CallService
+ #pragma message("Mistake Alert!: "m_uninstaller.h" needs to be included after "newpluginapi.h"!\n The following errors are resulting of this mistake.\n")
+#endif
+
+
+// | General Info
+// -----------------------------
+
+// Uninstall Example/Template
+// ---------------------------
+// Making your plugin uninstallable is very easy.
+// Just add the following "Uninstall" function near the "Unload" function
+// in your plugin.
+// A template plugin is available in the source code package.
+
+// Old:
+// int __declspec(dllexport) Uninstall(BOOL bIsMirandaRunning, BOOL bDoDeleteSettings, char* pszPluginPath);
+
+// New:
+//int __declspec(dllexport) UninstallEx(PLUGINUNINSTALLPARAMS* ppup)
+//{
+ // Available Variables:
+ // -----------------------------
+ // ppup->bIsMirandaRunning:
+ // Contains if Miranda is running
+ // (Currently this is always TRUE).
+
+ // ppup->bDoDeleteSettings:
+ // Contains if the users selected
+ // that he wants all settings be deleted.
+
+ // ppup->pszPluginsPath:
+ // Contains the plugins directory name.
+
+
+ // Notes:
+ // -----------------------------
+
+ // Run before "Unload" function:
+ // -> IMPORTANT: Be careful not to write to the database or to files in "Unload" again!!!
+ // -> Perhaps create a global BOOL variable which is set to TRUE when your plugin gets uninstalled
+ // or check of a database setting "IsInstalled" in Unload() or sth. like that
+
+ // All Miranda is still loaded
+
+ // Here you can do:
+ // - Delete settings group in database
+ // - Delete registry items
+ // - Delete ini-files and other settings files
+ // - Delete other files
+
+ // Your plugin dll gets automatically deleted
+
+ // Services to remove are offered:
+ // MS_PLUGINUNINSTALLER_REMOVEDBMODULE
+ // MS_PLUGINUNINSTALLER_REMOVEDBSETTINGGLOBALLY
+ // MS_PLUGINUNINSTALLER_REMOVESKINSOUND
+
+
+ // Getting other useful paths:
+ // -----------------------------
+
+ // System directory:
+
+ //char szSysPath[MAX_PATH];
+ //GetSystemDirectory(szSysPath, MAX_PATH);
+
+
+ // Windows directory:
+
+ //char szWinPath[MAX_PATH];
+ //GetWindowsDirectory(szWinPath, MAX_PATH);
+
+
+ // Other directories:
+
+ // char szPath[MAX_PATH];
+ // SHGetSpecialFolderPath(NULL, szPath, CSIDL_* , FALSE);
+
+ // Some available dirs:
+ // CSIDL_APPDATA CSIDL_SENDTO CSIDL_FAVORITES
+ // CSIDL_STARTUP CSIDL_PROFILE CSIDL_DESKTOPDIRECTORY
+
+
+ // Delete Files
+ //const char* apszFiles[] = {"MyPlugin_Readme.txt", "MyPlugin_License.txt", "MyPlugin_Developer.txt", "MyPlugin_Translation.txt"};
+ //PUIRemoveFilesInPath(ppup->pszPluginsPath, apszFiles);
+
+ // Delete Settings
+ //if(ppup->bDoDeleteSettings == TRUE)
+ //{
+ //if (ppup->bIsMirandaRunning == TRUE) // Check if it is possible to access services
+ //{
+ // Remove plugin's module
+ //PUIRemoveDbModule("MyPlugin");
+
+ // Remove plugin's sounds
+ //PUIRemoveSkinSound("MySoundSetting1");
+ //PUIRemoveSkinSound("MySoundSetting2");
+ //}
+ //}
+
+ // Remember:
+ // Do not forget to remove your (eventually) created registry items here, too.
+
+
+ // The plugin's dll file gets deleted after returning.
+
+ // Remember:
+ // If your DLL file is additionally in use by another application (eg. Windows)
+ // you need to free the DLL *here* completely. Otherwise it can't be deleted.
+
+// return 0;
+//}
+
+
+
+// Changing displayed icon
+// ---------------------------
+// The icon that gets displayed on the options page is always the "first"
+// icon in your DLL file.
+// An icon in your DLL file is the first icon when it has the lowest recource ID.
+// If you would like to have an other icon shown in the options please change your
+// icon resource IDs so that the icon you would like to have has the lowest one.
+// For example if you use MS Visual C++, open "resource.h" and change the resource define
+// of your prefered icon to the lowest icon number.
+
+
+// Changing displayed docs
+// ---------------------------
+// The items "License" and "More Information" on the plugin details page
+// are created when the a license and/or a readme file for the plugin exists.
+// The files get detected automatically and need a special name
+// so that they get detected.
+// The text files need to be either placed in the "Plugins" directory or
+// in the "Docs" directory. Whereof the last one is the better one :-)
+//
+// For the license file the following file name formatings are possible:
+// PluginName-License.txt (I personally think that this is the best naming solution... :-) )
+// PluginName_License.txt,
+//
+// For the readme file the following ones are possible:
+// PluginName-Readme.txt (Again...I like this one :-D ),
+// PluginName_Readme.txt,
+
+// Message boxes on uninstall
+// ---------------------------
+// If you would like to ask the user for something to remove/uninstall
+// please hook the event ME_PLUGINUNINSTALLER_UNINSTALL and show your
+// message box there. Save the action the user chose in a
+// global BOOL variable and do the chosen action in "UninstallEx".
+// You can get the plugins options window handle with MS_PLUGINUNINSTALLER_GETHANDLE.
+
+
+// Service Accessibility
+// ---------------------------
+// Remember that you only can use these functions after the event ME_SYSTEM_MODULESLOADED
+// or later because "PluginUninstaller" needs to be loaded first.
+// Normally you only use them in your "UninstallEx" function.
+//
+// IMPORTANT!:
+// Please make sure that you always use the macro PUICallService
+// in the "UninstallEx" function instead of the CallService function.
+
+
+// Including this file
+// ---------------------------
+// To use some of the uninstalling functionality you have to include this file
+// into your project.
+//
+// IMPORTANT!:
+// Please make sure that you include the file "newpluginapi.h" before this one.
+// If this isn't the case there may some compile errors come up.
+
+ // -> Example:
+ // If your plugin is in the directory "Plugins/MyPlugin/" and
+ // this include file is in the directory "Plugins/PluginUninstaller"
+ // you can use the following:
+
+ //#include "../PluginUninstaller/m_uninstaller.h"
+
+ // If your plugin is in an directory that is different to that one just
+ // change the include path to the one you want.
+
+
+
+
+
+// | Structs
+// -----------------------------
+
+// ---------------------------------------------
+// -- Struct: Uninstall Params -----------------
+// ---------------------------------------------
+
+// Struct: PLUGINUNINSTALLPARAMS
+// (Gets passed to "UninstallEx" function)
+
+typedef int (*HELPERPROC)(const char*, WPARAM, LPARAM); // Used internally (for pHelperProcAddress)
+
+typedef struct {
+ BOOL bIsMirandaRunning; // Is TRUE when Miranda is loaded and services are available (Please use PUICallService instead of CallService)
+ BOOL bDoDeleteSettings; // Is TRUE when user wants to delete settings (If this is FALSE, please only delete your files)
+ char* pszPluginsPath; // Contains the plugin directory path
+ char* pszDocsPath; // Contains the document directory for plugins documentation (Added in version 1.1.1.0)
+ char* pszIconsPath; // Contains the icon directory for icon dlls (Added in version 1.1.2.0)
+ HELPERPROC pHelperProcAddress; // Used internally (Contains proc address for PUICallService)
+} PLUGINUNINSTALLPARAMS;
+
+
+
+
+
+// | Helper
+// -----------------------------
+
+
+// ---------------------------------------------
+// -- Macro: Run service while uninstalling ----
+// ---------------------------------------------
+
+// Macro: PUICallService
+
+#define PUICallService(service, wParam, lParam) (ppup->pHelperProcAddress) (service, wParam, lParam);
+
+// Description:
+// -------------
+// This service provides the possibility to call a Miranda
+// service in the "UninstallEx" function.
+// Important!: Use this macro always instead of "CallService",
+// because else a crash occurs when the plugin was decativated
+// and gets uninstalled
+
+// Parameters:
+// -------------
+// Same parameters as CallService of Miranda Core.
+
+// Return Values:
+// --------------
+// Return values are the same as the CallService function of Miranda Core.
+// Additionaly returns CALLSERVICE_NOTFOUND if Miranda is not loaded
+// which means the services are not accessable.
+
+
+ // Example:
+ // ----------------------------------
+
+ //if ( (bIsMirandaRunning == TRUE) && (bDoDeleteSettings == TRUE) )
+ //{
+ // Remove plugin's module
+ //PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBMODULE, (WPARAM)"MyPlugin", 0);
+ //}
+
+
+
+
+// ---------------------------------------------
+// -- Function: Remove some files in directory -
+// ---------------------------------------------
+
+// Function: PUIRemoveFilesInDirectory
+
+static BOOL __inline PUIRemoveFilesInDirectory(char* pszPath, const char* apszFiles[]);
+
+// Description:
+// -------------
+// This helper provides the possibility to easily
+// remove specified files in a specified directory.
+
+// Note: The last version of this helper (PUIRemoveFilesInPath)
+// did not work correctly.
+// Please do now always append a NULL slot to the end of your array.
+
+// Parameters:
+// -------------
+// char* pszPath = Path to the files in array
+// const LPCSTR apszFiles[] = NULL-terminated array of files to be deleted.
+
+// Return Values:
+// --------------
+// Returns TRUE if the files could be deleted.
+// FALSE if the files could not be deleted or did not exist.
+
+
+static BOOL __inline PUIRemoveFilesInDirectory(char* pszPath, const char* apszFiles[])
+{
+ char szFile[MAX_PATH];
+ BOOL bReturn = FALSE;
+ int iFile = 0;
+
+ while (apszFiles[iFile] != NULL)
+ {
+ strncpy(szFile, pszPath, sizeof(szFile));
+ strncat(szFile, apszFiles[iFile], sizeof(szFile)-strlen(szFile));
+
+ if ((BOOL)DeleteFile(szFile) == TRUE) bReturn = TRUE;
+ iFile++;
+ }
+
+ return bReturn;
+}
+
+ // Example:
+ // ----------------------------------
+
+ //const char* apszFiles[] = {"File1.txt", "File2.txt", "File3.txt", NULL};
+ //PUIRemoveFilesInDirectory(ppup->pszPluginsPath, apszFiles);
+
+
+
+
+// | Events
+// -----------------------------
+
+
+// ---------------------------------------------
+// -- Event: Allow to uninstall a plugin -------
+// ---------------------------------------------
+
+// Event: ME_PLUGINUNINSTALLER_OKTOUNINSTALL
+
+#define ME_PLUGINUNINSTALLER_OKTOUNINSTALL "PluginUninstaller/OkToUninstall"
+
+// Submitted Values:
+// -----------------
+// wParam = pszPluginName (String containing the translated plugin name)
+// lParam = pszPluginFile (String containing the plugin dll file name in lower case)
+
+// Return Values:
+// -----------------
+// Returning 1 on this event causes the "Remove Plugin" button to be disabled.
+
+
+
+// ---------------------------------------------
+// -- Event: Plugin gets uninstalled -----------
+// ---------------------------------------------
+
+// Event: ME_PLUGINUNINSTALLER_UNINSTALL
+
+#define ME_PLUGINUNINSTALLER_UNINSTALL "PluginUninstaller/Uninstall"
+
+// Submitted Values:
+// -----------------
+// wParam = pszPluginName (String containing the translated plugin name)
+// lParam = pszPluginFile (String containing the plugin dll file name in lower case)
+
+// Return Values:
+// -----------------
+// Returning 1 on this event causes the uninstall process to be canceled.
+
+// Notice:
+// Hook this event if you would like to ask the user for something to remove/uninstall
+// and show your message box on this event. Save the action the user chose in a
+// global BOOL variable and do the chosen action in "UninstallEx".
+// You can get the plugins options window handle with MS_PLUGINUNINSTALLER_GETHANDLE.
+
+// Other plugins can use this event to be noticed that another plugin isn't installed anylonger.
+
+
+
+
+// | Services
+// -----------------------------
+
+
+// ---------------------------------------------
+// -- Service: Remove database module ----------
+// ---------------------------------------------
+
+// Service: MS_PLUGINUNINSTALLER_REMOVEDBMODULE
+
+#define MS_PLUGINUNINSTALLER_REMOVEDBMODULE "PluginUninstaller/RemoveDbModule"
+
+// Description:
+// -------------
+// This service provides the possibility to delete all database modules
+// associated to your plugin.
+// The specified database module will be removed in all contacts
+// including the NULL contact.
+// Remember to call it always with PUICallService in "UninstallEx" function.
+
+// Parameters:
+// -------------
+// wParam = (char*)pszModule // Pointer to a string containd module name. Can't be NULL
+// lParam = (const char*)apszIgnoreSettings // NULL terminated array of strings. Can be 0 if no settings should be ignored.
+ // See example 3 for more details
+
+// Return Values:
+// --------------
+// Returns 0 on success.
+// Nonzero if the module was not present in database.
+
+
+#ifndef UNINSTALLER_NOHELPERS
+
+// Can only be used in "UninstallEx" function
+#define PUIRemoveDbModule(pszModule) PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBMODULE, (WPARAM)pszModule, 0);
+
+#endif
+
+
+ // Example 1:
+ // ----------------------------------
+
+ //PUIRemoveDbModule("MyPlugin");
+
+
+ // Example 2:
+ // ----------------------------------
+
+ //char szModule[] = "MyModule";
+ //PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBMODULE, (WPARAM)szModule, 0);
+
+
+ // Example 3:
+ // ----------------------------------
+
+ // This deletes all settings in the specified module exept
+ // the specified settings: "Setting1",..."Setting4"
+
+ // char szModule[] = "MyModule";
+ // const char* apszIgnoreSettings[] = {"Setting1", "Setting2", "Setting3", "Setting4", NULL};
+ // PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBMODULE, (WPARAM)szModule, (LPARAM)&apszIgnoreSettings);
+
+
+
+// ---------------------------------------------
+// -- Service: Remove a setting globally -------
+// ---------------------------------------------
+
+// Service: MS_PLUGINUNINSTALLER_REMOVEDBSETTINGGLOBALLY
+
+#define MS_PLUGINUNINSTALLER_REMOVEDBSETTINGGLOBALLY "PluginUninstaller/RemoveDbSettingGlobally"
+
+// Description:
+// -------------
+// This service provides the possibility to delete a specific
+// setting in database in all contacts including the NULL contact.
+// Remember to call it always with PUICallService in "UninstallEx" function.
+
+// Parameters:
+// -------------
+// wParam = (char*)pszModule
+// lParam = (char*)pszSetting
+
+// Return Values:
+// --------------
+// Returns 0 on success.
+// Nonzero if the setting was not present in database.
+
+
+#ifndef UNINSTALLER_NOHELPERS
+
+// Can only be used in "UninstallEx" function
+#define PUIRemoveDbSettingGlobally(pszModule, pszSetting) PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBSETTINGGLOBALLY, (WPARAM)pszModule, (LPARAM)pszSetting);
+
+
+#endif
+
+
+ // Example 1:
+ // ----------------------------------
+
+ //PUIRemoveDbSettingGlobally("MyPlugin", "MySetting");
+
+
+ // Example 2:
+ // ----------------------------------
+
+ //szModule[] = "MyPlugin";
+ //szSetting[] = "MySetting";
+ //PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBSETTINGGLOBALLY, (WPARAM)szModule, (LPARAM)szSetting);
+
+
+
+
+
+
+// ---------------------------------------------
+// -- Service: Remove skinned sound ------------
+// ---------------------------------------------
+
+// Service: MS_PLUGINUNINSTALLER_REMOVESKINSOUND
+
+#define MS_PLUGINUNINSTALLER_REMOVESKINSOUND "PluginUninstaller/RemoveSkinSound"
+
+// Description:
+// -------------
+// This service provides the possibility to delete all your sound settings
+// associated to your plugin.
+// The specified sound will be be removed.
+// Remember to call it always with PUICallService in "UninstallEx" function.
+
+// Parameters:
+// -------------
+// wParam = (char*)pszSoundSetting
+// lParam = 0
+
+// Return Values:
+// --------------
+// Returns 0 on success.
+// Nonzero if the sound was not present in database.
+
+
+#ifndef UNINSTALLER_NOHELPERS
+
+// Can only be used in "UninstallEx" function
+#define PUIRemoveSkinSound(pszSoundSetting) PUICallService(MS_PLUGINUNINSTALLER_REMOVESKINSOUND, (WPARAM)pszSoundSetting, 0);
+
+#endif
+
+
+ // Example 1:
+ // ----------------------------------
+
+ //PUIRemoveSkinSound("MySoundSetting");
+
+
+ // Example 2:
+ // ----------------------------------
+
+ //szSoundModule[] = "MySoundSetting";
+ //PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBMODULE, (WPARAM)szSoundSetting, 0);
+
+
+
+
+
+// ---------------------------------------------
+// -- Service: Uninstall a plugin --------------
+// ---------------------------------------------
+
+// Service: MS_PLUGINUNINSTALLER_UNINSTALLPLUGIN
+
+#define MS_PLUGINUNINSTALLER_UNINSTALLPLUGIN "PluginUninstaller/UninstallPlugin"
+
+// Description:
+// -------------
+// This service marks a plugin to be uninstalled at next restart of Miranda IM.
+// It uses the default value for "Delete all settings".
+// You can use this service for example when you want that your sub-plugin gets
+// also removed when your main-plugin is uninstalled.
+// Note: This service is not needed for the normal uninstalling functionality.
+
+// Parameters:
+// -------------
+// wParam = (char*)pszPluginName // do not translate this!
+// lParam = (char*)pszPluginFile // without path, only file name!
+
+// Return Values:
+// --------------
+// Returns always 0.
+
+
+#ifndef UNINSTALLER_NOHELPERS
+
+int __inline PUIUninstallPlugin(char* pszPluginName, char* pszPluginFile)
+{
+ return CallService(MS_PLUGINUNINSTALLER_UNINSTALLPLUGIN, (WPARAM)pszPluginName, (LPARAM)pszPluginFile);
+}
+
+#endif
+
+
+ // Example 1:
+ // ----------------------------------
+
+ //PUIUninstallPlugin("PluginName", "plugin.dll");
+
+
+ // Example 2:
+ // ----------------------------------
+
+ // hInst => Handle of a specific (your?) plugin
+ // char szPluginName[] = "YourPluginName";
+
+ //char* pFileName;
+ //char szPath[MAX_PATH];
+
+ //GetModuleFileName(hInst, szPath, sizeof(szPath));
+ //pFileName = strrchr(szPath, '\\');
+ //pFileName = pFileName+1; // Pointer arithmetic
+
+ //CallService(MS_PLUGINUNINSTALLER_UNINSTALLPLUGIN, (WPARAM)szPluginName, (LPARAM)pFileName);
+
+
+
+
+// ---------------------------------------------
+// -- Service: Getting handles -----------------
+// ---------------------------------------------
+
+// Service: MS_PLUGINUNINSTALLER_GETHANDLE
+
+#define MS_PLUGINUNINSTALLER_GETHANDLE "PluginUninstaller/GetHandle"
+
+// Description:
+// -------------
+// This service gets a specified window/instance handle.
+
+// Note: This service must not be used in "UninstallEx" function.
+// It is mainly thought for being used in ME_PLUGINUNINSTALLER_UNINSTALL event
+// to give out a MessageBox or something like that.
+
+// Parameters:
+// -------------
+// wParam = UINT uHandleType;
+// lParam = 0
+
+// Possible values for wParam:
+#define PUIHT_HINST_PLUGIN_INSTANCE 0 // HINSTANCE of the PluginUninstaller plugin
+#define PUIHT_HWND_PLUGIN_OPTIONS 1 // HWND of the plugin options dialog (if it is loaded; else NULL)
+
+// Return Values:
+// --------------
+// Returns the specified handle value.
+// If no handle type is specified it returns NULL.
+// The handle doesn't need to be destroyed.
+
+
+#ifndef UNINSTALLER_NOHELPERS
+
+HANDLE __inline PUIGetHandle(UINT uHandleType)
+{
+ return (HANDLE)CallService(MS_PLUGINUNINSTALLER_GETHANDLE, uHandleType, 0);
+}
+
+#endif
+
+
+ // Example
+ // ----------------------------------
+
+ //HWND hwndDlg;
+ //hwndDlg = (HWND)PUIGetHandle(PUIHT_HWND_PLUGIN_OPTIONS);
+
+
+
+
+
+#endif // M_UNINSTALLER_H
diff --git a/nudge/include/m_updater.h b/nudge/include/m_updater.h new file mode 100644 index 0000000..488d372 --- /dev/null +++ b/nudge/include/m_updater.h @@ -0,0 +1,150 @@ +#ifndef _M_UPDATER_H
+#define _M_UPDATER_H
+
+// NOTES:
+// - For langpack updates, include a string of the following format in the langpack text file:
+// ";FLID: <file listing name> <version>"
+// version must be four numbers seperated by '.', in the range 0-255 inclusive
+// - Updater will disable plugins that are downloaded but were not active prior to the update (this is so that, if an archive contains e.g. ansi and
+// unicode versions, the correct plugin will be the only one active after the new version is installed)...so if you add a support plugin, you may need
+// to install an ini file to make the plugin activate when miranda restarts after the update
+// - Updater will replace all dlls that have the same internal shortName as a downloaded update dll (this is so that msn1.dll and msn2.dll, for example,
+// will both be updated) - so if you have a unicode and a non-unicode version of a plugin in your archive, you should make the internal names different (which will break automatic
+// updates from the file listing if there is only one file listing entry for both versions, unless you use the 'MS_UPDATE_REGISTER' service below)
+// - Updater will install all files in the root of the archive into the plugins folder, except for langpack files that contain the FLID string which go into the root folder (same
+// folder as miranda32.exe)...all folders in the archive will also be copied to miranda's root folder, and their contents transferred into the new folders. The only exception is a
+// special folder called 'root_files' - if there is a folder by that name in the archive, it's contents will also be copied into miranda's root folder - this is intended to be used
+// to install additional dlls etc that a plugin may require)
+
+// if you set Update.szUpdateURL to the following value when registering, as well as setting your beta site and version data,
+// Updater will ignore szVersionURL and pbVersionPrefix, and attempt to find the file listing URL's from the backend XML data.
+// for this to work, the plugin name in pluginInfo.shortName must match the file listing exactly (except for case)
+#define UPDATER_AUTOREGISTER "UpdaterAUTOREGISTER"
+// Updater will also use the backend xml data if you provide URL's that reference the miranda file listing for updates (so you can use that method
+// if e.g. your plugin shortName does not match the file listing) - it will grab the file listing id from the end of these URLs
+
+typedef struct Update_tag {
+ int cbSize;
+ char *szComponentName; // component name as it will appear in the UI (will be translated before displaying)
+
+ char *szVersionURL; // URL where the current version can be found (NULL to disable)
+ BYTE *pbVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ // (note that this URL could point at a binary file - dunno why, but it could :)
+ int cpbVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szUpdateURL; // URL where dll/zip is located
+ // set to UPDATER_AUTOREGISTER if you want Updater to find the file listing URLs (ensure plugin shortName matches file listing!)
+
+ char *szBetaVersionURL; // URL where the beta version can be found (NULL to disable betas)
+ BYTE *pbBetaVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ int cpbBetaVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szBetaUpdateURL; // URL where dll/zip is located
+
+ BYTE *pbVersion; // bytes of current version, used for comparison with those in VersionURL
+ int cpbVersion; // number of bytes pointed to by pbVersion
+
+ char *szBetaChangelogURL; // url for displaying changelog for beta versions
+} Update;
+
+// register a comonent with Updater
+//
+// wparam = 0
+// lparam = (LPARAM)&Update
+#define MS_UPDATE_REGISTER "Update/Register"
+
+// utility functions to create a version string from a DWORD or from pluginInfo
+// point buf at a buffer at least 16 chars wide - but note the version string returned may be shorter
+//
+__inline static char *CreateVersionString(DWORD version, char *buf) {
+ mir_snprintf(buf, 16, "%d.%d.%d.%d", (version >> 24) & 0xFF, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);
+ return buf;
+}
+
+__inline static char *CreateVersionStringPlugin(PLUGININFO *pluginInfo, char *buf) {
+ return CreateVersionString(pluginInfo->version, buf);
+}
+
+__inline static char *CreateVersionStringPluginEx(PLUGININFOEX *pluginInfo, char *buf) {
+ return CreateVersionString(pluginInfo->version, buf);
+}
+
+
+// register the 'easy' way - use this method if you have no beta URL and the plugin is on the miranda file listing
+// NOTE: the plugin version string on the file listing must be the string version of the version in pluginInfo (i.e. 0.0.0.1,
+// four numbers between 0 and 255 inclusivem, so no letters, brackets, etc.)
+//
+// wParam = (int)fileID - this is the file ID from the file listing (i.e. the number at the end of the download link)
+// lParam = (PLUGININFO*)&pluginInfo
+#define MS_UPDATE_REGISTERFL "Update/RegisterFL"
+
+// this function can be used to 'unregister' components - useful for plugins that register non-plugin/langpack components and
+// may need to change those components on the fly
+// lParam = (char *)szComponentName
+#define MS_UPDATE_UNREGISTER "Update/Unregister"
+
+// this event is fired when the startup process is complete, but NOT if a restart is imminent
+// it is designed for status managment plugins to use as a trigger for beggining their own startup process
+// wParam = lParam = 0 (unused)
+// (added in version 0.1.6.0)
+#define ME_UPDATE_STARTUPDONE "Update/StartupDone"
+
+// this service can be used to enable/disable Updater's global status control
+// it can be called from the StartupDone event handler
+// wParam = (BOOL)enable
+// lParam = 0
+// (added in version 0.1.6.0)
+#define MS_UPDATE_ENABLESTATUSCONTROL "Update/EnableStatusControl"
+
+// An description of usage of the above service and event:
+// Say you are a status control plugin that normally sets protocol or global statuses in your ModulesLoaded event handler.
+// In order to make yourself 'Updater compatible', you would move the status control code from ModulesLoaded to another function,
+// say DoStartup. Then, in ModulesLoaded you would check for the existence of the MS_UPDATE_ENABLESTATUSCONTROL service.
+// If it does not exist, call DoStartup. If it does exist, hook the ME_UPDATE_STARTUPDONE event and call DoStartup from there. You may
+// also wish to call MS_UPDATE_ENABLESTATUSCONTROL with wParam == FALSE at this time, to disable Updater's own status control feature.
+
+// this service can be used to determine whether updates are possible for a component with the given name
+// wParam = 0
+// lParam = (char *)szComponentName
+// returns TRUE if updates are supported, FALSE otherwise
+#define MS_UPDATE_ISUPDATESUPPORTED "Update/IsUpdateSupported"
+
+#endif
+
+
+/////////////// Usage Example ///////////////
+
+#ifdef EXAMPLE_CODE
+
+// you need to #include "m_updater.h" and HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded) in your Load function...
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam) {
+
+ Update update = {0}; // for c you'd use memset or ZeroMemory...
+ char szVersion[16];
+
+ update.cbSize = sizeof(Update);
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionString(&pluginInfo, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+
+ // these are the three lines that matter - the archive, the page containing the version string, and the text (or data)
+ // before the version that we use to locate it on the page
+ // (note that if the update URL and the version URL point to standard file listing entries, the backend xml
+ // data will be used to check for updates rather than the actual web page - this is not true for beta urls)
+ update.szUpdateURL = "http://scottellis.com.au:81/test/updater.zip";
+ update.szVersionURL = "http://scottellis.com.au:81/test/updater_test.html";
+ update.pbVersionPrefix = (BYTE *)"Updater version ";
+
+ update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix);
+
+ // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+
+ // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing...
+ // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo);
+
+ return 0;
+}
+
+#endif
diff --git a/nudge/m_nudge.h b/nudge/m_nudge.h new file mode 100644 index 0000000..e80215e --- /dev/null +++ b/nudge/m_nudge.h @@ -0,0 +1,10 @@ +#define MS_SHAKE_CLIST "SHAKE/Service/ShakeClist"
+#define MS_SHAKE_CHAT "SHAKE/Service/ShakeChat"
+#define MS_NUDGE_SEND "NUDGE/Send"
+
+// Hide or Show the context menu "send nudge"
+// wParam = char *szProto
+// lParam = BOOL show
+#define MS_NUDGE_SHOWMENU "NudgeShowMenu"
+
+#define MUUID_NUDGE_SEND { 0x9c66a9a, 0x57dc, 0x454d, { 0xa9, 0x30, 0xf8, 0xc0, 0x4f, 0xe2, 0x98, 0x38 } }
diff --git a/nudge/main.cpp b/nudge/main.cpp new file mode 100644 index 0000000..e31d8c5 --- /dev/null +++ b/nudge/main.cpp @@ -0,0 +1,1020 @@ +#include "headers.h"
+#include "main.h"
+#include "shake.h"
+#include "include\m_msg_buttonsbar.h"
+
+
+static INT_PTR CALLBACK DlgProcOptsTrigger(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+LRESULT CALLBACK NudgePopUpProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
+
+int nProtocol = 0;
+static HANDLE g_hEventModulesLoaded = NULL, g_hEventIconsChanged = NULL,hEventOptionsInitialize, g_hIcon = NULL, g_hEventDbWindowEvent = NULL, g_hEventToolbarLoaded = NULL, g_hEventButtonPressed = NULL;
+HINSTANCE hInst;
+PLUGINLINK *pluginLink;
+NudgeElementList *NudgeList;
+CNudgeElement DefaultNudge;
+CShake shake;
+CNudge GlobalNudge;
+
+MM_INTERFACE mmi;
+int hLangpack = 0;
+
+BOOL (WINAPI *MyEnableThemeDialogTexture)(HANDLE, DWORD) = 0;
+HMODULE hUxTheme = 0;
+
+// function pointers, use typedefs for casting to shut up the compiler when using GetProcAddress()
+
+typedef BOOL (WINAPI *PITA)();
+typedef HANDLE (WINAPI *POTD)(HWND, LPCWSTR);
+typedef UINT (WINAPI *PDTB)(HANDLE, HDC, int, int, RECT *, RECT *);
+typedef UINT (WINAPI *PCTD)(HANDLE);
+typedef UINT (WINAPI *PDTT)(HANDLE, HDC, int, int, LPCWSTR, int, DWORD, DWORD, RECT *);
+
+PITA pfnIsThemeActive = 0;
+POTD pfnOpenThemeData = 0;
+PDTB pfnDrawThemeBackground = 0;
+PCTD pfnCloseThemeData = 0;
+PDTT pfnDrawThemeText = 0;
+
+#define FIXED_TAB_SIZE 100 // default value for fixed width tabs
+
+/*
+ * visual styles support (XP+)
+ * returns 0 on failure
+ */
+
+int InitVSApi()
+{
+ if((hUxTheme = LoadLibraryA("uxtheme.dll")) == 0)
+ return 0;
+
+ pfnIsThemeActive = (PITA)GetProcAddress(hUxTheme, "IsThemeActive");
+ pfnOpenThemeData = (POTD)GetProcAddress(hUxTheme, "OpenThemeData");
+ pfnDrawThemeBackground = (PDTB)GetProcAddress(hUxTheme, "DrawThemeBackground");
+ pfnCloseThemeData = (PCTD)GetProcAddress(hUxTheme, "CloseThemeData");
+ pfnDrawThemeText = (PDTT)GetProcAddress(hUxTheme, "DrawThemeText");
+
+ MyEnableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture");
+ if(pfnIsThemeActive != 0 && pfnOpenThemeData != 0 && pfnDrawThemeBackground != 0 && pfnCloseThemeData != 0 && pfnDrawThemeText != 0) {
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * unload uxtheme.dll
+ */
+
+int FreeVSApi()
+{
+ if(hUxTheme != 0)
+ FreeLibrary(hUxTheme);
+ return 0;
+}
+
+DWORD MirVer;
+
+
+//========================
+// MirandaPluginInfo
+//========================
+PLUGININFOEX pluginInfo={
+ sizeof(PLUGININFOEX),
+ "Nudge",
+ PLUGIN_MAKE_VERSION(0,0,1,19),
+ "Plugin to shake the clist and chat window",
+ "Tweety/GouZ",
+ "francois.mean@skynet.be / Sylvain.gougouzian@gmail.com ",
+ "copyright to the miranda community",
+ "http://addons.miranda-im.org/details.php?action=viewfile&id=2708", // www
+ UNICODE_AWARE,
+ 0, //doesn't replace anything built-in
+ { 0x9ceee701, 0x35cd, 0x4ff7, { 0x8c, 0xc4, 0xef, 0x7d, 0xd2, 0xac, 0x53, 0x5c } } // {9CEEE701-35CD-4ff7-8CC4-EF7DD2AC535C}
+};
+
+
+
+void RegisterToUpdate(void)
+{
+ //Use for the Updater plugin
+ if(ServiceExists(MS_UPDATE_REGISTER))
+ {
+ Update update = {0};
+ char szVersion[16];
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionStringPluginEx(&pluginInfo, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+ update.szUpdateURL = UPDATER_AUTOREGISTER;
+ update.szVersionURL = "http://addons.miranda-im.org/details.php?action=viewfile&id=2708";
+ update.pbVersionPrefix = (BYTE *)"<span class=\"fileNameHeader\">Nudge ";
+ update.szBetaUpdateURL = "http://www.miranda-fr.net/tweety/Nudge/Nudge.zip";
+ update.szBetaVersionURL = "http://www.miranda-fr.net/tweety/Nudge/Nudge_beta.html";
+ update.pbBetaVersionPrefix = (BYTE *)"Nudge version ";
+
+ update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix);
+ update.cpbBetaVersionPrefix = strlen((char *)update.pbBetaVersionPrefix);
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+
+ }
+}
+
+INT_PTR NudgeShowMenu(WPARAM wParam,LPARAM lParam)
+{
+
+ NudgeElementList *n;
+ for(n = NudgeList;n != NULL; n = n->next)
+ {
+ if(!strcmp((char *) wParam,n->item.ProtocolName))
+ {
+ return n->item.ShowContactMenu(lParam != 0);
+ }
+ }
+ return 0;
+}
+
+INT_PTR NudgeSend(WPARAM wParam,LPARAM lParam)
+{
+
+ char *protoName = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO,wParam,0);
+ int diff = time(NULL) - DBGetContactSettingDword((HANDLE) wParam, "Nudge", "LastSent", time(NULL)-30);
+
+ if(diff < GlobalNudge.sendTimeSec)
+ {
+ TCHAR msg[500];
+ mir_sntprintf(msg,500, TranslateT("You are not allowed to send too much nudge (only 1 each %d sec, %d sec left)"),GlobalNudge.sendTimeSec, 30 - diff);
+ //MessageBox(NULL,msg,NULL,0);
+ if(GlobalNudge.useByProtocol)
+ {
+ NudgeElementList *n;
+ for(n = NudgeList;n != NULL; n = n->next)
+ {
+ if(!strcmp(protoName,n->item.ProtocolName))
+ {
+ Nudge_ShowPopup(n->item, (HANDLE) wParam, msg);
+ }
+ }
+ }
+ else
+ {
+ Nudge_ShowPopup(DefaultNudge, (HANDLE) wParam, msg);
+ }
+ return 0;
+ }
+
+ DBWriteContactSettingDword((HANDLE) wParam, "Nudge", "LastSent", time(NULL));
+
+ if(GlobalNudge.useByProtocol)
+ {
+ NudgeElementList *n;
+ for(n = NudgeList;n != NULL; n = n->next)
+ {
+ if(!strcmp(protoName,n->item.ProtocolName))
+ {
+ if(n->item.showPopup)
+ Nudge_ShowPopup(n->item, (HANDLE) wParam, n->item.senText);
+ if(n->item.showEvent)
+ Nudge_SentEvent(n->item, (HANDLE) wParam);
+ if(n->item.showStatus)
+ Nudge_SentStatus(n->item, (HANDLE) wParam);
+ }
+ }
+ }
+ else
+ {
+ if(DefaultNudge.showPopup)
+ Nudge_ShowPopup(DefaultNudge, (HANDLE) wParam, DefaultNudge.senText);
+ if(DefaultNudge.showEvent)
+ Nudge_SentEvent(DefaultNudge, (HANDLE) wParam);
+ if(DefaultNudge.showStatus)
+ Nudge_SentStatus(DefaultNudge, (HANDLE) wParam);
+ }
+
+ char servicefunction[ 100 ];
+ sprintf(servicefunction, "%s/SendNudge", protoName);
+
+ CallService(servicefunction, wParam, lParam);
+
+ return 0;
+}
+
+int NudgeRecieved(WPARAM wParam,LPARAM lParam)
+{
+
+ char *protoName = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO,wParam,0);
+
+ DWORD currentTimestamp = time(NULL);
+ DWORD nudgeSentTimestamp = lParam ? (DWORD)lParam : currentTimestamp;
+
+ int diff = currentTimestamp - DBGetContactSettingDword((HANDLE) wParam, "Nudge", "LastReceived", currentTimestamp-30);
+ int diff2 = nudgeSentTimestamp - DBGetContactSettingDword((HANDLE) wParam, "Nudge", "LastReceived2", nudgeSentTimestamp-30);
+
+ if(diff >= GlobalNudge.recvTimeSec)
+ DBWriteContactSettingDword((HANDLE) wParam, "Nudge", "LastReceived", currentTimestamp);
+ if(diff2 >= GlobalNudge.recvTimeSec)
+ DBWriteContactSettingDword((HANDLE) wParam, "Nudge", "LastReceived2", nudgeSentTimestamp);
+
+ if(GlobalNudge.useByProtocol)
+ {
+ NudgeElementList *n;
+ for(n = NudgeList;n != NULL; n = n->next)
+ {
+ if(!strcmp(protoName,n->item.ProtocolName))
+ {
+
+ if(n->item.enabled)
+ {
+ DWORD Status = CallProtoService(protoName,PS_GETSTATUS,0,0);
+
+ if( ((n->item.statusFlags & NUDGE_ACC_ST0) && (Status<=ID_STATUS_OFFLINE)) ||
+ ((n->item.statusFlags & NUDGE_ACC_ST1) && (Status==ID_STATUS_ONLINE)) ||
+ ((n->item.statusFlags & NUDGE_ACC_ST2) && (Status==ID_STATUS_AWAY)) ||
+ ((n->item.statusFlags & NUDGE_ACC_ST3) && (Status==ID_STATUS_DND)) ||
+ ((n->item.statusFlags & NUDGE_ACC_ST4) && (Status==ID_STATUS_NA)) ||
+ ((n->item.statusFlags & NUDGE_ACC_ST5) && (Status==ID_STATUS_OCCUPIED)) ||
+ ((n->item.statusFlags & NUDGE_ACC_ST6) && (Status==ID_STATUS_FREECHAT)) ||
+ ((n->item.statusFlags & NUDGE_ACC_ST7) && (Status==ID_STATUS_INVISIBLE)) ||
+ ((n->item.statusFlags & NUDGE_ACC_ST8) && (Status==ID_STATUS_ONTHEPHONE)) ||
+ ((n->item.statusFlags & NUDGE_ACC_ST9) && (Status==ID_STATUS_OUTTOLUNCH)))
+ {
+ if(diff >= GlobalNudge.recvTimeSec)
+ {
+ if(n->item.showPopup)
+ Nudge_ShowPopup(n->item, (HANDLE) wParam, n->item.recText);
+ if(n->item.shakeClist)
+ ShakeClist(wParam,lParam);
+ if(n->item.shakeChat)
+ ShakeChat(wParam,lParam);
+ if(n->item.autoResend)
+ mir_forkthread(AutoResendNudge,(void *)wParam);
+
+ SkinPlaySound( n->item.NudgeSoundname );
+ }
+ }
+ if(diff2 >= GlobalNudge.recvTimeSec)
+ {
+ if(n->item.showEvent)
+ Nudge_ShowEvent(n->item, (HANDLE) wParam, nudgeSentTimestamp);
+ if(n->item.showStatus)
+ Nudge_ShowStatus(n->item, (HANDLE) wParam, nudgeSentTimestamp);
+ }
+
+ }
+ }
+ }
+ }
+ else
+ {
+ if(DefaultNudge.enabled)
+ {
+ DWORD Status = CallService(MS_CLIST_GETSTATUSMODE,0,0);
+ if( ((DefaultNudge.statusFlags & NUDGE_ACC_ST0) && (Status<=ID_STATUS_OFFLINE)) ||
+ ((DefaultNudge.statusFlags & NUDGE_ACC_ST1) && (Status==ID_STATUS_ONLINE)) ||
+ ((DefaultNudge.statusFlags & NUDGE_ACC_ST2) && (Status==ID_STATUS_AWAY)) ||
+ ((DefaultNudge.statusFlags & NUDGE_ACC_ST3) && (Status==ID_STATUS_DND)) ||
+ ((DefaultNudge.statusFlags & NUDGE_ACC_ST4) && (Status==ID_STATUS_NA)) ||
+ ((DefaultNudge.statusFlags & NUDGE_ACC_ST5) && (Status==ID_STATUS_OCCUPIED)) ||
+ ((DefaultNudge.statusFlags & NUDGE_ACC_ST6) && (Status==ID_STATUS_FREECHAT)) ||
+ ((DefaultNudge.statusFlags & NUDGE_ACC_ST7) && (Status==ID_STATUS_INVISIBLE)) ||
+ ((DefaultNudge.statusFlags & NUDGE_ACC_ST8) && (Status==ID_STATUS_ONTHEPHONE)) ||
+ ((DefaultNudge.statusFlags & NUDGE_ACC_ST9) && (Status==ID_STATUS_OUTTOLUNCH)))
+ {
+ if(diff >= GlobalNudge.recvTimeSec)
+ {
+ if(DefaultNudge.showPopup)
+ Nudge_ShowPopup(DefaultNudge, (HANDLE) wParam, DefaultNudge.recText);
+ if(DefaultNudge.shakeClist)
+ ShakeClist(wParam,lParam);
+ if(DefaultNudge.shakeChat)
+ ShakeChat(wParam,lParam);
+ if(DefaultNudge.autoResend)
+ mir_forkthread(AutoResendNudge,(void *)wParam);
+
+ SkinPlaySound( DefaultNudge.NudgeSoundname );
+ }
+ }
+ if(diff2 >= GlobalNudge.recvTimeSec)
+ {
+ if(DefaultNudge.showEvent)
+ Nudge_ShowEvent(DefaultNudge, (HANDLE) wParam, nudgeSentTimestamp);
+ if(DefaultNudge.showStatus)
+ Nudge_ShowStatus(DefaultNudge, (HANDLE) wParam, nudgeSentTimestamp);
+ }
+ }
+ }
+ return 0;
+}
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ hInst=hinstDLL;
+ return TRUE;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ MirVer = mirandaVersion;
+ return &pluginInfo;
+}
+
+static const MUUID interfaces[] = {MUUID_NUDGE_SEND, MIID_LAST};
+extern "C" __declspec(dllexport) const MUUID * MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+int MainInit(WPARAM wParam,LPARAM lParam)
+{
+ return 0;
+}
+
+static INT_PTR CALLBACK DlgProcOptsTrigger(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+
+ switch (msg) {
+ case WM_INITDIALOG: {
+ // lParam = (LPARAM)(DWORD)actionID or 0 if this is a new trigger entry
+ DWORD actionID;
+ BOOL bshakeClist,bshakeChat;
+
+ actionID = (DWORD)lParam;
+ TranslateDialogDefault(hwnd);
+ // Initialize the dialog according to the action ID
+ bshakeClist = DBGetActionSettingByte(actionID, NULL, "Nudge", "ShakeClist",FALSE);
+ bshakeChat = DBGetActionSettingByte(actionID, NULL, "Nudge", "ShakeChat",FALSE);
+ CheckDlgButton(hwnd, IDC_TRIGGER_SHAKECLIST, bshakeClist ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwnd, IDC_TRIGGER_SHAKECHAT, bshakeChat ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ }
+
+ case TM_ADDACTION: {
+ // save your settings
+ // wParam = (WPARAM)(DWORD)actionID
+ DWORD actionID;
+ bool bshakeClist,bshakeChat;
+
+ actionID = (DWORD)wParam;
+ bshakeClist = (IsDlgButtonChecked(hwnd,IDC_TRIGGER_SHAKECLIST)==BST_CHECKED);
+ bshakeChat = (IsDlgButtonChecked(hwnd,IDC_TRIGGER_SHAKECHAT)==BST_CHECKED);
+ DBWriteActionSettingByte(actionID, NULL, "Nudge", "ShakeClist",bshakeClist);
+ DBWriteActionSettingByte(actionID, NULL, "Nudge", "ShakeChat",bshakeChat);
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+int TriggerActionRecv( DWORD actionID, REPORTINFO *ri)
+{
+ // check how to process this call
+ if (ri->flags&ACT_PERFORM) {
+ BOOL bshakeClist,bshakeChat;
+ HANDLE hContact = ((ri->td!=NULL)&&(ri->td->dFlags&DF_CONTACT))?ri->td->hContact:NULL;
+ bshakeClist = DBGetActionSettingByte(actionID, NULL, "Nudge", "ShakeClist",FALSE);
+ bshakeChat = DBGetActionSettingByte(actionID, NULL, "Nudge", "ShakeChat",FALSE);
+
+ if(bshakeClist)
+ ShakeClist(NULL,NULL);
+ if(bshakeChat && (hContact != NULL))
+ ShakeChat((WPARAM)hContact,NULL);
+
+ /* // Actually show the message box
+ DBVARIANT dbv;
+ TCHAR *tszMsg;
+
+ // Retrieve the correct settings for this action ID
+ if (!DBGetActionSettingTString(actionID, NULL, MODULENAME, SETTING_TEXT, &dbv)) {
+ // Parse by Variables, if available (notice extratext and subject are given).
+ tszMsg = variables_parsedup(dbv.ptszVal, ((ri->td!=NULL)&&(ri->td->dFlags&DF_TEXT))?ri->td->tszText:NULL, ((ri->td!=NULL)&&(ri->td->dFlags&DF_CONTACT))?ri->td->hContact:NULL);
+ if (tszMsg != NULL) {
+ // Show the message box
+ MessageBox(NULL, tszMsg, TranslateT("ExampleAction"), MB_OK);
+ free(tszMsg);
+ }
+ DBFreeVariant(&dbv);
+ }
+ */
+ }
+ if (ri->flags&ACT_CLEANUP) { // request to delete all associated settings
+ RemoveAllActionSettings(actionID, "Nudge");
+ }
+ return FALSE;
+}
+
+int TriggerActionSend( DWORD actionID, REPORTINFO *ri)
+{
+ if (ri->flags&ACT_PERFORM) {
+ HANDLE hContact = ((ri->td!=NULL)&&(ri->td->dFlags&DF_CONTACT))?ri->td->hContact:NULL;
+ if(hContact != NULL)
+ NudgeSend((WPARAM)hContact,NULL);
+ }
+
+ return FALSE;
+}
+
+void LoadProtocols(void)
+{
+ //Load the default nudge
+ sprintf(DefaultNudge.ProtocolName,"Default");
+ sprintf(DefaultNudge.NudgeSoundname,"Nudge : Default");
+ SkinAddNewSoundEx( DefaultNudge.NudgeSoundname, LPGEN("Nudge"),DefaultNudge.NudgeSoundname);
+ DefaultNudge.Load();
+
+ GlobalNudge.Load();
+
+ int numberOfProtocols,ret;
+ char str[MAXMODULELABELLENGTH + 10];
+ HANDLE NudgeEvent = NULL;
+ PROTOCOLDESCRIPTOR ** ppProtocolDescriptors;
+ ret = CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM) &numberOfProtocols,(LPARAM)&ppProtocolDescriptors);
+ if(ret == 0)
+ {
+ for(int i = 0; i < numberOfProtocols ; i++)
+ {
+ if(ppProtocolDescriptors[i]->type == PROTOTYPE_PROTOCOL)
+ {
+ sprintf(str,"%s/Nudge",ppProtocolDescriptors[i]->szName);
+ NudgeEvent = HookEvent(str, NudgeRecieved);
+ if(NudgeEvent != NULL)
+ Nudge_AddElement(ppProtocolDescriptors[i]->szName, NudgeEvent);
+
+ NudgeEvent = NULL;
+ }
+ }
+
+ }
+
+ shake.Load();
+
+ /*CNudgeElement *n;
+ for(n = NudgeList;n != NULL; n = n->next)
+ {
+ MessageBox(NULL,n->ProtocolName,n->NudgeSoundname,0);
+ }*/
+}
+
+void RegisterToTrigger(void)
+{
+ if( ServiceExists(MS_TRIGGER_REGISTERACTION))
+ {
+ ACTIONREGISTER ar;
+ ZeroMemory(&ar, sizeof(ar));
+ ar.cbSize = sizeof(ar);
+ ar.hInstance = hInst;
+ ar.flags = ARF_TCHAR|ARF_FUNCTION;
+ ar.actionFunction = TriggerActionRecv;
+ ar.pfnDlgProc = DlgProcOptsTrigger;
+ ar.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_TRIGGER);
+ ar.pszName = Translate("Nudge : Shake contact list/chat window");
+
+ // register the action
+ CallService(MS_TRIGGER_REGISTERACTION, 0, (LPARAM)&ar);
+
+ ar.actionFunction = TriggerActionSend;
+ ar.pszName = Translate("Nudge : Send a nudge");
+ ar.pfnDlgProc = NULL;
+ ar.pszTemplate = NULL;
+
+ // register the action
+ CallService(MS_TRIGGER_REGISTERACTION, 0, (LPARAM)&ar);
+ }
+}
+
+void RegisterToDbeditorpp(void)
+{
+ // known modules list
+ if (ServiceExists("DBEditorpp/RegisterSingleModule"))
+ CallService("DBEditorpp/RegisterSingleModule", (WPARAM)"Nudge", 0);
+}
+
+void LoadIcons(void)
+{
+ //Load icons
+ if(ServiceExists(MS_SKIN2_ADDICON))
+ {
+ SKINICONDESC sid = {0};
+ TCHAR szFilename[MAX_PATH];
+ char iconName[MAXMODULELABELLENGTH + 10];
+ char iconDesc[MAXMODULELABELLENGTH + 10];
+ GetModuleFileName(hInst,szFilename,MAX_PATH);
+
+ sid.cbSize = SKINICONDESC_SIZE;
+ sid.flags = SIDF_PATH_TCHAR;
+ sid.pszSection = "Nudge";
+ sid.ptszDefaultFile = szFilename;
+
+ for(NudgeElementList *n = NudgeList;n != NULL; n = n->next)
+ {
+ sprintf(iconName,"Nudge_%s",n->item.ProtocolName);
+ sid.pszName = iconName;
+ sprintf(iconDesc,"%s %s",Translate("Nudge for"),n->item.ProtocolName);
+ sid.pszDescription = iconDesc;
+ sid.iDefaultIndex = -IDI_NUDGE;
+ sid.hDefaultIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_NUDGE));
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+
+ n->item.hIcon = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) iconName);
+ }
+
+ sprintf(iconName,"Nudge_Default");
+ sid.pszName = iconName;
+ sprintf(iconDesc,Translate("Nudge as Default"));
+ sid.pszDescription = iconDesc;
+ sid.iDefaultIndex = -IDI_NUDGE;
+ sid.hDefaultIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_NUDGE));
+ g_hIcon = (HANDLE)CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+
+ DefaultNudge.hIcon = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) iconName);
+ }
+ else // Do not forget people not using IcoLib!!!!
+ {
+ for(NudgeElementList *n = NudgeList;n != NULL; n = n->next)
+ {
+ n->item.hIcon = (HICON)CallProtoService(n->item.ProtocolName, PS_LOADICON, PLI_PROTOCOL|PLIF_SMALL, 0);
+ if(n->item.hIcon == NULL || (int)n->item.hIcon == CALLSERVICE_NOTFOUND)
+ n->item.hIcon = (HICON)CallProtoService(n->item.ProtocolName, PS_LOADICON, PLI_PROTOCOL, 0);
+ if(n->item.hIcon == NULL || (int)n->item.hIcon == CALLSERVICE_NOTFOUND)
+ n->item.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_NUDGE));
+ }
+ DefaultNudge.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_NUDGE));
+ }
+}
+
+static int LoadChangedIcons(WPARAM wParam, LPARAM lParam)
+{
+ //Load icons
+ if(ServiceExists(MS_SKIN2_ADDICON))
+ {
+ NudgeElementList *n;
+ char iconName[MAXMODULELABELLENGTH + 10];
+
+ for(n = NudgeList;n != NULL; n = n->next)
+ {
+ sprintf(iconName,"Nudge_%s",n->item.ProtocolName);
+ n->item.hIcon = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) iconName);
+ }
+ sprintf(iconName,"Nudge_Default");
+ DefaultNudge.hIcon = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) iconName);
+ }
+ return 0;
+}
+
+// Nudge support
+static int TabsrmmButtonPressed(WPARAM wParam, LPARAM lParam)
+{
+ CustomButtonClickData *cbcd=(CustomButtonClickData *)lParam;
+
+ if(!strcmp(cbcd->pszModule,"Nudge"))
+ NudgeSend(wParam, 0);
+
+ return 0;
+}
+
+static int TabsrmmButtonInit(WPARAM wParam, LPARAM lParam)
+{
+ BBButton bbd = {0};
+
+ bbd.cbSize = sizeof(BBButton);
+ bbd.pszModuleName = "Nudge";
+ bbd.ptszTooltip = LPGENT("Nudge");
+ bbd.dwDefPos = 300;
+ bbd.bbbFlags = BBBF_ISIMBUTTON|BBBF_ISLSIDEBUTTON|BBBF_CANBEHIDDEN;
+ bbd.hIcon = g_hIcon;
+ bbd.dwButtonID = 6000;
+ bbd.iButtonWidth = 0;
+ CallService (MS_BB_ADDBUTTON, 0, (LPARAM)&bbd);
+
+ return 0;
+}
+
+void HideNudgeButton(HANDLE hContact)
+{
+ char str[MAXMODULELABELLENGTH + 12] = {0};
+ CONTACTINFO ci = { 0 };
+
+ ci.cbSize = sizeof(ci);
+ ci.hContact = hContact;
+
+ CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM) & ci);
+ mir_snprintf(str,MAXMODULELABELLENGTH + 12,"%s/SendNudge", ci.szProto);
+
+ if (!ServiceExists(str))
+ {
+ BBButton bbd={0};
+ bbd.cbSize=sizeof(BBButton);
+ bbd.bbbFlags=BBSF_HIDDEN|BBSF_DISABLED;
+ bbd.pszModuleName="Nudge";
+ bbd.dwButtonID = 6000;
+ CallService(MS_BB_SETBUTTONSTATE, (WPARAM)hContact, (LPARAM)&bbd);
+ }
+}
+
+static int ContactWindowOpen(WPARAM wparam,LPARAM lParam)
+{
+ MessageWindowEventData *MWeventdata = (MessageWindowEventData*)lParam;
+
+ if(MWeventdata->uType == MSG_WINDOW_EVT_OPENING&&MWeventdata->hContact)
+ {
+ HideNudgeButton(MWeventdata->hContact);
+ }
+ return 0;
+}
+
+int ModulesLoaded(WPARAM,LPARAM)
+{
+ RegisterToUpdate();
+ RegisterToTrigger();
+ RegisterToDbeditorpp();
+ LoadProtocols();
+ LoadIcons();
+ g_hEventToolbarLoaded = HookEvent(ME_MSG_TOOLBARLOADED, TabsrmmButtonInit);
+ if (g_hEventToolbarLoaded)
+ {
+ g_hEventButtonPressed = HookEvent(ME_MSG_BUTTONPRESSED, TabsrmmButtonPressed);
+ g_hEventDbWindowEvent = HookEvent(ME_MSG_WINDOWEVENT,ContactWindowOpen);
+ }
+ return 0;
+}
+
+HANDLE hShakeClist=NULL,hShakeChat=NULL,hNudgeSend=NULL,hNudgeShowMenu=NULL;
+extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+ pluginLink = link;
+ mir_getMMI(&mmi);
+ mir_getLP(&pluginInfo);
+ NudgeList = NULL;
+ g_hEventModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED,ModulesLoaded);
+ if(ServiceExists(MS_SKIN2_ADDICON))
+ g_hEventIconsChanged = HookEvent(ME_SKIN2_ICONSCHANGED, LoadChangedIcons);
+
+ InitOptions();
+ InitVSApi();
+
+ //Create function for plugins
+ hShakeClist=CreateServiceFunction(MS_SHAKE_CLIST,ShakeClist);
+ hShakeChat=CreateServiceFunction(MS_SHAKE_CHAT,ShakeChat);
+ hNudgeSend=CreateServiceFunction(MS_NUDGE_SEND,NudgeSend);
+ hNudgeShowMenu=CreateServiceFunction(MS_NUDGE_SHOWMENU,NudgeShowMenu);
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ if(g_hEventToolbarLoaded) UnhookEvent(g_hEventToolbarLoaded);
+ if(g_hEventDbWindowEvent) UnhookEvent(g_hEventButtonPressed);
+ if(g_hEventDbWindowEvent) UnhookEvent(g_hEventDbWindowEvent);
+
+ if(g_hEventModulesLoaded) UnhookEvent(g_hEventModulesLoaded);
+ if(g_hEventIconsChanged) UnhookEvent(g_hEventIconsChanged);
+
+ DestroyServiceFunction(hShakeClist);
+ DestroyServiceFunction(hShakeChat);
+ DestroyServiceFunction(hNudgeSend);
+ DestroyServiceFunction(hNudgeShowMenu);
+
+ UninitOptions();
+
+ FreeVSApi();
+ NudgeElementList* p = NudgeList;
+ while ( p != NULL )
+ {
+ if(p->item.hEvent) UnhookEvent(p->item.hEvent);
+ NudgeElementList* p1 = p->next;
+ //free( p );
+ delete p;
+ p = p1;
+ }
+ return 0;
+}
+
+LRESULT CALLBACK NudgePopUpProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_COMMAND:
+ {
+ HANDLE hContact = PUGetContact(hWnd);
+ CallService(MS_MSG_SENDMESSAGET, (WPARAM)hContact, 0);
+ PUDeletePopUp(hWnd);
+ break;
+ }
+
+ case WM_CONTEXTMENU:
+ PUDeletePopUp(hWnd);
+ break;
+ case UM_FREEPLUGINDATA:
+ //Here we'd free our own data, if we had it.
+ return FALSE;
+ case UM_INITPOPUP:
+ break;
+ case UM_DESTROYPOPUP:
+ break;
+ case WM_NOTIFY:
+ default:
+ break;
+ }
+ return DefWindowProc(hWnd,msg,wParam,lParam);
+}
+
+int Preview()
+{
+ if( GlobalNudge.useByProtocol )
+ {
+ HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+
+ for(NudgeElementList *n = NudgeList;n != NULL; n = n->next)
+ {
+ if(n->item.enabled)
+ {
+ SkinPlaySound( n->item.NudgeSoundname );
+ if(n->item.showPopup)
+ Nudge_ShowPopup(n->item, hContact, n->item.recText);
+ if(n->item.shakeClist)
+ ShakeClist(0,0);
+ if(n->item.shakeChat)
+ {
+ CallService(MS_MSG_SENDMESSAGET,(WPARAM)hContact,NULL);
+ ShakeChat((WPARAM)hContact,(LPARAM)time(NULL));
+ }
+ }
+ }
+ }
+ else
+ {
+ if(DefaultNudge.enabled)
+ {
+ HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+
+ SkinPlaySound( DefaultNudge.NudgeSoundname );
+ if(DefaultNudge.showPopup)
+ Nudge_ShowPopup(DefaultNudge, hContact, DefaultNudge.recText);
+ if(DefaultNudge.shakeClist)
+ ShakeClist(0,0);
+ if(DefaultNudge.shakeChat)
+ {
+ CallService(MS_MSG_SENDMESSAGET,(WPARAM)hContact,NULL);
+ ShakeChat((WPARAM)hContact,(LPARAM)time(NULL));
+ }
+ }
+ }
+ return 0;
+}
+
+void Nudge_ShowPopup(CNudgeElement n, HANDLE hCont, TCHAR * Message)
+{
+ HANDLE hContact;
+
+ hContact = Nudge_GethContact(hCont);
+ TCHAR * lpzContactName = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GCDNF_TCHAR);
+
+ if(ServiceExists(MS_POPUP_ADDPOPUPT))
+ {
+ POPUPDATAT NudgePopUp;
+
+ if(hContact == NULL) //no contact at all
+ NudgePopUp.lchContact = (HANDLE) &n;
+
+ NudgePopUp.lchContact = hContact;
+ NudgePopUp.lchIcon = n.hIcon;
+ NudgePopUp.colorBack = ! n.popupWindowColor ? n.popupBackColor : GetSysColor(COLOR_BTNFACE);
+ NudgePopUp.colorText = ! n.popupWindowColor ? n.popupTextColor : GetSysColor(COLOR_WINDOWTEXT);
+ NudgePopUp.iSeconds = n.popupTimeSec;
+ NudgePopUp.PluginWindowProc = (WNDPROC)NudgePopUpProc;
+ NudgePopUp.PluginData = (void *)1;
+
+ //lstrcpy(NudgePopUp.lpzText, Translate(Message));
+ lstrcpy(NudgePopUp.lptzText, Message);
+
+ lstrcpy(NudgePopUp.lptzContactName, lpzContactName);
+
+ CallService(MS_POPUP_ADDPOPUPT,(WPARAM)&NudgePopUp,0);
+ }
+ else
+ {
+ MessageBox(NULL,Message,lpzContactName,0);
+ }
+}
+
+BOOL CheckMsgWnd(HANDLE hContact)
+{
+ if (ServiceExists(MS_MSG_GETWINDOWDATA)) // use the new Window API
+ {
+ MessageWindowData mwd;
+ MessageWindowInputData mwid;
+
+ mwid.cbSize = sizeof(MessageWindowInputData);
+ mwid.hContact = Nudge_GethContact(hContact);
+ mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+ mwd.cbSize = sizeof(MessageWindowData);
+ mwd.hContact = Nudge_GethContact(hContact);
+ if (!CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&mwid, (LPARAM)&mwd) && mwd.hwndWindow)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void Nudge_SentEvent(CNudgeElement n, HANDLE hCont)
+{
+ DBEVENTINFO NudgeEvent = { 0 };;
+ HANDLE hContact;
+ HANDLE hMetaContact = NULL;
+
+ hContact = hCont;
+
+ NudgeEvent.cbSize = sizeof(NudgeEvent);
+ NudgeEvent.szModule = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ NudgeEvent.flags = DBEF_SENT;
+ NudgeEvent.timestamp = ( DWORD )time(NULL);
+ NudgeEvent.eventType = EVENTTYPE_MESSAGE;
+ #if defined( _UNICODE )
+ char buff[TEXT_LEN];
+ WideCharToMultiByte(code_page, 0, n.senText, -1, buff, TEXT_LEN, 0, 0);
+ buff[TEXT_LEN] = 0;
+ NudgeEvent.cbBlob = strlen(buff) + 1;
+ NudgeEvent.pBlob = ( PBYTE ) buff;
+ #else
+ NudgeEvent.cbBlob = _tcsclen(n.senText) + 1;
+ NudgeEvent.pBlob = ( PBYTE ) n.senText;
+ #endif
+
+ if(ServiceExists(MS_MC_GETMETACONTACT)) //try to retrieve the metacontact if some
+ hMetaContact = (HANDLE) CallService( MS_MC_GETMETACONTACT, (WPARAM)hContact, 0 );
+
+ if(hMetaContact != NULL) //metacontact
+ CallService(MS_DB_EVENT_ADD,(WPARAM)hMetaContact,(LPARAM)&NudgeEvent);
+
+ CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&NudgeEvent);
+}
+
+void Nudge_SentStatus(CNudgeElement n, HANDLE hCont)
+{
+ DBEVENTINFO NudgeEvent = { 0 };;
+ HANDLE hContact;
+ HANDLE hMetaContact = NULL;
+
+ hContact = hCont;
+
+ NudgeEvent.cbSize = sizeof(NudgeEvent);
+ NudgeEvent.szModule = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ NudgeEvent.flags = 0;
+ NudgeEvent.timestamp = ( DWORD )time(NULL);
+ NudgeEvent.eventType = EVENTTYPE_STATUSCHANGE;
+ #if defined( _UNICODE )
+ char buff[TEXT_LEN];
+ WideCharToMultiByte(code_page, 0, n.senText, -1, buff, TEXT_LEN, 0, 0);
+ buff[TEXT_LEN] = 0;
+ NudgeEvent.cbBlob = strlen(buff) + 1;
+ NudgeEvent.pBlob = ( PBYTE ) buff;
+ #else
+ NudgeEvent.cbBlob = _tcsclen(n.senText) + 1;
+ NudgeEvent.pBlob = ( PBYTE ) n.senText;
+ #endif
+
+ if(ServiceExists(MS_MC_GETMETACONTACT)) //try to retrieve the metacontact if some
+ hMetaContact = (HANDLE) CallService( MS_MC_GETMETACONTACT, (WPARAM)hContact, 0 );
+
+ if(hMetaContact != NULL) //metacontact
+ CallService(MS_DB_EVENT_ADD,(WPARAM)hMetaContact,(LPARAM)&NudgeEvent);
+
+ CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&NudgeEvent);
+}
+
+void Nudge_ShowStatus(CNudgeElement n, HANDLE hCont, DWORD timestamp)
+{
+ DBEVENTINFO NudgeEvent = { 0 };;
+ HANDLE hContact;
+ HANDLE hMetaContact = NULL;
+
+ hContact = hCont;
+
+ NudgeEvent.cbSize = sizeof(NudgeEvent);
+ NudgeEvent.szModule = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ NudgeEvent.flags = 0;
+ NudgeEvent.timestamp = timestamp;
+ NudgeEvent.eventType = EVENTTYPE_STATUSCHANGE;
+ #if defined( _UNICODE )
+ char buff[TEXT_LEN];
+ WideCharToMultiByte(code_page, 0, n.recText, -1, buff, TEXT_LEN, 0, 0);
+ buff[TEXT_LEN] = 0;
+ NudgeEvent.cbBlob = strlen(buff) + 1;
+ NudgeEvent.pBlob = ( PBYTE ) buff;
+ #else
+ NudgeEvent.cbBlob = _tcsclen(n.recText) + 1;
+ NudgeEvent.pBlob = ( PBYTE ) n.recText;
+ #endif
+
+ if(ServiceExists(MS_MC_GETMETACONTACT)) //try to retrieve the metacontact if some
+ hMetaContact = (HANDLE) CallService( MS_MC_GETMETACONTACT, (WPARAM)hContact, 0 );
+
+ if(hMetaContact != NULL) //metacontact
+ {
+ CallService(MS_DB_EVENT_ADD,(WPARAM)hMetaContact,(LPARAM)&NudgeEvent);
+ NudgeEvent.flags = DBEF_READ;
+ }
+
+ CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&NudgeEvent);
+}
+
+void Nudge_ShowEvent(CNudgeElement n, HANDLE hCont, DWORD timestamp)
+{
+ DBEVENTINFO NudgeEvent = { 0 };
+ HANDLE hContact;
+ HANDLE hMetaContact = NULL;
+
+ hContact = hCont;
+
+ NudgeEvent.cbSize = sizeof(NudgeEvent);
+ NudgeEvent.szModule = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ NudgeEvent.flags = CheckMsgWnd(hContact) ? DBEF_READ : 0;
+ NudgeEvent.timestamp = timestamp;
+ NudgeEvent.eventType = EVENTTYPE_MESSAGE;
+ #if defined( _UNICODE )
+ char buff[TEXT_LEN];
+ WideCharToMultiByte(code_page, 0, n.recText, -1, buff, TEXT_LEN, 0, 0);
+ buff[TEXT_LEN] = 0;
+ NudgeEvent.cbBlob = strlen(buff) + 1;
+ NudgeEvent.pBlob = ( PBYTE ) buff;
+ #else
+ NudgeEvent.cbBlob = _tcsclen(n.recText) + 1;
+ NudgeEvent.pBlob = ( PBYTE ) n.recText;
+ #endif
+
+
+ if(ServiceExists(MS_MC_GETMETACONTACT)) //try to retrieve the metacontact if some
+ hMetaContact = (HANDLE) CallService( MS_MC_GETMETACONTACT, (WPARAM)hContact, 0 );
+
+ if(hMetaContact != NULL) //metacontact
+ {
+ CallService(MS_DB_EVENT_ADD,(WPARAM)hMetaContact,(LPARAM)&NudgeEvent);
+ NudgeEvent.flags = DBEF_READ;
+ }
+
+ CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&NudgeEvent);
+}
+
+int Nudge_AddElement(char *protoName, HANDLE hevent)
+{
+ nProtocol ++;
+ //Add contact menu entry
+ CLISTMENUITEM mi;
+
+ memset( &mi, 0, sizeof( mi ));
+ mi.popupPosition = 500085000;
+ mi.pszContactOwner = protoName;
+ mi.pszPopupName = protoName;
+ mi.cbSize = sizeof( mi );
+ mi.flags = (CMIF_NOTOFFLINE & CMIF_HIDDEN) | CMIF_TCHAR;
+ mi.position = -500050004;
+ mi.hIcon = LoadIcon( hInst, MAKEINTRESOURCE( IDI_NUDGE ));
+ mi.ptszName = LPGENT( "Send &Nudge" );
+ mi.pszService = MS_NUDGE_SEND;
+
+
+ //Add a specific sound per protocol
+ char nudgesoundtemp[ 512 ];
+ NudgeElementList *newNudge;
+ //newNudge = (NudgeElementList*) malloc(sizeof(NudgeElementList));
+ newNudge = new NudgeElementList;
+ strcpy( nudgesoundtemp, protoName );
+ strcat( nudgesoundtemp, ": " );
+ strcat( nudgesoundtemp, Translate( "Nudge" ));
+ strncpy( newNudge->item.NudgeSoundname, nudgesoundtemp, sizeof(newNudge->item.NudgeSoundname) );
+
+ strcpy( newNudge->item.ProtocolName, protoName );
+
+ newNudge->item.hContactMenu = (HANDLE) CallService( MS_CLIST_ADDCONTACTMENUITEM, 0, ( LPARAM )&mi );
+
+ newNudge->item.Load();
+
+ newNudge->item.hEvent = hevent;
+
+ SkinAddNewSoundEx( newNudge->item.NudgeSoundname, LPGEN("Nudge") , newNudge->item.NudgeSoundname);
+
+ newNudge->next = NudgeList;
+ NudgeList = newNudge;
+
+ return 0;
+}
+
+HANDLE Nudge_GethContact(HANDLE hCont)
+{
+ HANDLE hContact;
+ hContact = hCont;
+
+ if(ServiceExists(MS_MC_GETMETACONTACT)) //try to retrieve the metacontact if some
+ hContact = (HANDLE) CallService( MS_MC_GETMETACONTACT, (WPARAM)hContact, 0 );
+
+ if(hContact == NULL) //no metacontact
+ hContact = hCont;
+
+ return hContact;
+}
+
+void AutoResendNudge(void *wParam)
+{
+
+ Sleep(GlobalNudge.resendDelaySec * 1000);
+ NudgeSend((WPARAM) wParam,NULL);
+}
diff --git a/nudge/main.h b/nudge/main.h new file mode 100644 index 0000000..74cbc9a --- /dev/null +++ b/nudge/main.h @@ -0,0 +1,96 @@ +#include "nudge.h"
+
+/*
+*
+****************************/
+void RegisterToUpdate(void);
+
+/*
+*
+****************************/
+void RegisterToTrigger(void);
+
+/*
+*
+****************************/
+void LoadProtocols(void);
+
+/*
+*
+****************************/
+void LoadIcons(void);
+
+/*
+*
+****************************/
+static int LoadChangedIcons(WPARAM, LPARAM);
+
+/*
+*
+****************************/
+DWORD WINAPI ShakeClistWindow(LPVOID);
+
+/*
+*
+****************************/
+DWORD WINAPI ShakeChatWindow(LPVOID);
+
+/*
+*
+****************************/
+int ModulesLoaded(WPARAM,LPARAM);
+
+/*
+*
+****************************/
+void Nudge_ShowPopup(CNudgeElement, HANDLE, TCHAR *);
+
+/*
+*
+****************************/
+void Nudge_ShowEvent(CNudgeElement, HANDLE, DWORD timestamp);
+
+/*
+*
+****************************/
+void Nudge_SentEvent(CNudgeElement, HANDLE);
+
+/*
+*
+****************************/
+void Nudge_ShowStatus(CNudgeElement, HANDLE, DWORD timestamp);
+
+/*
+*
+****************************/
+void Nudge_SentStatus(CNudgeElement, HANDLE);
+
+/*
+*
+****************************/
+int Nudge_AddElement(char*, HANDLE);
+
+/*
+*
+****************************/
+int FreeVSApi();
+
+/*
+*
+****************************/
+int InitVSApi();
+
+/*
+*
+****************************/
+int TriggerActionRecv( DWORD actionID, REPORTINFO *ri);
+
+/*
+*
+****************************/
+int TriggerActionSend( DWORD actionID, REPORTINFO *ri);
+
+/*
+*
+****************************/
+void AutoResendNudge(void *wParam) ;
\ No newline at end of file diff --git a/nudge/miranda.ico b/nudge/miranda.ico Binary files differnew file mode 100644 index 0000000..4fba0d4 --- /dev/null +++ b/nudge/miranda.ico diff --git a/nudge/nudge.cpp b/nudge/nudge.cpp new file mode 100644 index 0000000..9455ec6 --- /dev/null +++ b/nudge/nudge.cpp @@ -0,0 +1,135 @@ +#include "headers.h"
+#include "nudge.h"
+
+void CNudge::Save(void)
+{
+ char SectionName[512];
+ mir_snprintf(SectionName,512,"useByProtocol");
+ DBWriteContactSettingByte(NULL, "Nudge", SectionName, this->useByProtocol);
+ mir_snprintf(SectionName,512,"RecvTimeSec");
+ DBWriteContactSettingDword(NULL, "Nudge", SectionName, this->recvTimeSec);
+ mir_snprintf(SectionName,512,"SendTimeSec");
+ DBWriteContactSettingDword(NULL, "Nudge", SectionName, this->sendTimeSec);
+ mir_snprintf(SectionName,512,"ResendDelaySec");
+ DBWriteContactSettingDword(NULL, "Nudge", SectionName, this->resendDelaySec);
+}
+
+
+void CNudge::Load(void)
+{
+ char SectionName[512];
+ mir_snprintf(SectionName,512,"useByProtocol");
+ this->useByProtocol = DBGetContactSettingByte(NULL, "Nudge", SectionName, FALSE) != 0;
+ mir_snprintf(SectionName,512,"RecvTimeSec");
+ this->recvTimeSec = DBGetContactSettingDword(NULL, "Nudge", SectionName, 30);
+ mir_snprintf(SectionName,512,"SendTimeSec");
+ this->sendTimeSec = DBGetContactSettingDword(NULL, "Nudge", SectionName, 30);
+ mir_snprintf(SectionName,512,"ResendDelaySec");
+ this->resendDelaySec = DBGetContactSettingDword(NULL, "Nudge", SectionName, 3);
+}
+
+int CNudgeElement::ShowContactMenu(bool show)
+{
+
+ CLISTMENUITEM mi;
+ memset( &mi, 0, sizeof( mi ));
+ mi.cbSize = sizeof( mi );
+ mi.flags = show? CMIM_FLAGS : CMIM_FLAGS | CMIF_HIDDEN ;
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hContactMenu, (LPARAM)&mi);
+
+ return 0;
+}
+
+void CNudgeElement::Save(void)
+{
+ char SectionName[512];
+ mir_snprintf(SectionName,512,"%s-popupBackColor", ProtocolName);
+ DBWriteContactSettingDword(NULL, "Nudge", SectionName, this->popupBackColor);
+ mir_snprintf(SectionName,512,"%s-popupTextColor", ProtocolName);
+ DBWriteContactSettingDword(NULL, "Nudge", SectionName, this->popupTextColor);
+ mir_snprintf(SectionName,512,"%s-popupTimeSec", ProtocolName);
+ DBWriteContactSettingDword(NULL, "Nudge", SectionName, this->popupTimeSec);
+ mir_snprintf(SectionName,512,"%s-popupWindowColor", ProtocolName);
+ DBWriteContactSettingByte(NULL, "Nudge", SectionName, this->popupWindowColor);
+ mir_snprintf(SectionName,512,"%s-showEvent", ProtocolName);
+ DBWriteContactSettingByte(NULL, "Nudge", SectionName, this->showEvent);
+ mir_snprintf(SectionName,512,"%s-showStatus", ProtocolName);
+ DBWriteContactSettingByte(NULL, "Nudge", SectionName, this->showStatus);
+ mir_snprintf(SectionName,512,"%s-showPopup", ProtocolName);
+ DBWriteContactSettingByte(NULL, "Nudge", SectionName, this->showPopup);
+ mir_snprintf(SectionName,512,"%s-shakeClist", ProtocolName);
+ DBWriteContactSettingByte(NULL, "Nudge", SectionName, this->shakeClist);
+ mir_snprintf(SectionName,512,"%s-shakeChat", ProtocolName);
+ DBWriteContactSettingByte(NULL, "Nudge", SectionName, this->shakeChat);
+ mir_snprintf(SectionName,512,"%s-enabled", ProtocolName);
+ DBWriteContactSettingByte(NULL, "Nudge", SectionName, this->enabled);
+ mir_snprintf(SectionName,512,"%s-autoResend", ProtocolName);
+ DBWriteContactSettingByte(NULL, "Nudge", SectionName, this->autoResend);
+ mir_snprintf(SectionName,512,"%s-statusFlags", ProtocolName);
+ DBWriteContactSettingDword(NULL, "Nudge", SectionName, this->statusFlags);
+ mir_snprintf(SectionName,512,"%s-recText", ProtocolName);
+ if(DBWriteContactSettingTString(NULL, "Nudge", SectionName, this->recText)) {
+ #if defined( _UNICODE )
+ char buff[TEXT_LEN];
+ WideCharToMultiByte(code_page, 0, this->recText, -1, buff, TEXT_LEN, 0, 0);
+ buff[TEXT_LEN] = 0;
+ DBWriteContactSettingString(0, "Nudge", SectionName, buff);
+ #endif
+ }
+ mir_snprintf(SectionName,512,"%s-senText", ProtocolName);
+ if(DBWriteContactSettingTString(NULL, "Nudge", SectionName, this->senText)) {
+ #if defined( _UNICODE )
+ char buff[TEXT_LEN];
+ WideCharToMultiByte(code_page, 0, this->senText, -1, buff, TEXT_LEN, 0, 0);
+ buff[TEXT_LEN] = 0;
+ DBWriteContactSettingString(0, "Nudge", SectionName, buff);
+ #endif
+ }
+}
+
+
+void CNudgeElement::Load(void)
+{
+ DBVARIANT dbv;
+ char SectionName[512];
+ mir_snprintf(SectionName,512,"%s-popupBackColor", ProtocolName);
+ this->popupBackColor = DBGetContactSettingDword(NULL, "Nudge", SectionName, GetSysColor(COLOR_BTNFACE));
+ mir_snprintf(SectionName,512,"%s-popupTextColor", ProtocolName);
+ this->popupTextColor = DBGetContactSettingDword(NULL, "Nudge", SectionName, GetSysColor(COLOR_WINDOWTEXT));
+ mir_snprintf(SectionName,512,"%s-popupTimeSec", ProtocolName);
+ this->popupTimeSec = DBGetContactSettingDword(NULL, "Nudge", SectionName, 4);
+ mir_snprintf(SectionName,512,"%s-popupWindowColor", ProtocolName);
+ this->popupWindowColor = DBGetContactSettingByte(NULL, "Nudge", SectionName, TRUE) != 0;
+ mir_snprintf(SectionName,512,"%s-showEvent", ProtocolName);
+ this->showEvent = DBGetContactSettingByte(NULL, "Nudge", SectionName, TRUE) != 0;
+ mir_snprintf(SectionName,512,"%s-showStatus", ProtocolName);
+ this->showStatus = DBGetContactSettingByte(NULL, "Nudge", SectionName, TRUE) != 0;
+ mir_snprintf(SectionName,512,"%s-showPopup", ProtocolName);
+ this->showPopup = DBGetContactSettingByte(NULL, "Nudge", SectionName, TRUE) != 0;
+ mir_snprintf(SectionName,512,"%s-shakeClist", ProtocolName);
+ this->shakeClist = DBGetContactSettingByte(NULL, "Nudge", SectionName, TRUE) != 0;
+ mir_snprintf(SectionName,512,"%s-shakeChat", ProtocolName);
+ this->shakeChat = DBGetContactSettingByte(NULL, "Nudge", SectionName, TRUE) != 0;
+ mir_snprintf(SectionName,512,"%s-enabled", ProtocolName);
+ this->enabled = DBGetContactSettingByte(NULL, "Nudge", SectionName, TRUE) != 0;
+ mir_snprintf(SectionName,512,"%s-autoResend", ProtocolName);
+ this->autoResend = DBGetContactSettingByte(NULL, "Nudge", SectionName, FALSE) != 0;
+ mir_snprintf(SectionName,512,"%s-statusFlags", ProtocolName);
+ this->statusFlags = DBGetContactSettingDword(NULL, "Nudge", SectionName, 967);
+ mir_snprintf(SectionName,512,"%s-recText", ProtocolName);
+ if(!DBGetContactSettingTString(NULL,"Nudge",SectionName,&dbv))
+ {
+ _tcsncpy(this->recText,dbv.ptszVal,TEXT_LEN);
+ if(_tcsclen(this->recText) < 1)
+ _tcsncpy(this->recText,TranslateT("You received a nudge"),TEXT_LEN);
+ DBFreeVariant(&dbv);
+ }
+ mir_snprintf(SectionName,512,"%s-senText", ProtocolName);
+ if(!DBGetContactSettingTString(NULL,"Nudge",SectionName,&dbv))
+ {
+ _tcsncpy(this->senText,dbv.ptszVal,TEXT_LEN);
+ if(_tcsclen(this->senText) < 1)
+ _tcsncpy(this->senText,TranslateT("You sent a nudge"),TEXT_LEN);
+ DBFreeVariant(&dbv);
+ }
+}
\ No newline at end of file diff --git a/nudge/nudge.dsp b/nudge/nudge.dsp new file mode 100644 index 0000000..ab46397 --- /dev/null +++ b/nudge/nudge.dsp @@ -0,0 +1,241 @@ +# Microsoft Developer Studio Project File - Name="nudge" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=nudge - Win32 Debug Unicode
+!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 "nudge.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 "nudge.mak" CFG="nudge - Win32 Debug Unicode"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "nudge - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "nudge - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "nudge - Win32 Release Unicode" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "nudge - Win32 Debug Unicode" (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)" == "nudge - 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 0
+# 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 "nudge_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "nudge_EXPORTS" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x402 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+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 msvcrt.lib kernel32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib comctl32.lib /nologo /dll /debug /machine:I386 /nodefaultlib /out:"../../bin/release ansi/plugins/nudge.dll"
+
+!ELSEIF "$(CFG)" == "nudge - 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 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "nudge_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "nudge_EXPORTS" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x402 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+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 kernel32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib comctl32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "nudge - Win32 Release Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "nudge___Win32_Release_Unicode"
+# PROP BASE Intermediate_Dir "nudge___Win32_Release_Unicode"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release_Unicode"
+# PROP Intermediate_Dir "Release_Unicode"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "nudge_EXPORTS" /D "_UNICODE" /D "UNICODE" /FR /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "nudge_EXPORTS" /D "_UNICODE" /D "UNICODE" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 ws2_32.lib kernel32.lib user32.lib shell32.lib msvcrt.lib comdlg32.lib gdi32.lib comctl32.lib /nologo /dll /debug /machine:I386 /nodefaultlib /out:"../../bin/release/plugins/nudge.dll"
+# ADD LINK32 msvcrt.lib kernel32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib comctl32.lib /nologo /dll /debug /machine:I386 /nodefaultlib /out:"../../bin/release/plugins/nudge.dll"
+
+!ELSEIF "$(CFG)" == "nudge - Win32 Debug Unicode"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "nudge___Win32_Debug_Unicode"
+# PROP BASE Intermediate_Dir "nudge___Win32_Debug_Unicode"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_Unicode"
+# PROP Intermediate_Dir "Debug_Unicode"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "nudge_EXPORTS" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "nudge_EXPORTS" /FR /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+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 kernel32.lib user32.lib gdi32.lib shell32.lib comdlg32.lib comctl32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "nudge - Win32 Release"
+# Name "nudge - Win32 Debug"
+# Name "nudge - Win32 Release Unicode"
+# Name "nudge - Win32 Debug Unicode"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\nudge.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\shake.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\headers.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\m_nudge.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\nudge.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\shake.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=.\miranda.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\nudge.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resources\Nudge.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resources\NudgeIRC.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resources\NudgeMeta.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resources\NudgeMSN.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resources\NudgeTlen.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resources\NudgeYahoo.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\ChangeLog.txt
+# End Source File
+# End Target
+# End Project
diff --git a/nudge/nudge.dsw b/nudge/nudge.dsw new file mode 100644 index 0000000..48fb8f2 --- /dev/null +++ b/nudge/nudge.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "nudge"="nudge.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/nudge/nudge.h b/nudge/nudge.h new file mode 100644 index 0000000..c1e6c70 --- /dev/null +++ b/nudge/nudge.h @@ -0,0 +1,72 @@ +#ifndef NUDGE_H
+#define NUDGE_H
+
+
+
+static int code_page = CP_ACP;
+
+// NUDGE account status flags
+#define NUDGE_ACC_ST0 0x00000001 //Check (countdown) when Offline
+#define NUDGE_ACC_ST1 0x00000002 //Check (countdown) when Online
+#define NUDGE_ACC_ST2 0x00000004 //Check (countdown) when Away
+#define NUDGE_ACC_ST3 0x00000008 //Check (countdown) when N/A
+#define NUDGE_ACC_ST4 0x00000010 //Check (countdown) when Occupied
+#define NUDGE_ACC_ST5 0x00000020 //Check (countdown) when DND
+#define NUDGE_ACC_ST6 0x00000040 //Check (countdown) when Free for chat
+#define NUDGE_ACC_ST7 0x00000080 //Check (countdown) when Invisible
+#define NUDGE_ACC_ST8 0x00000100 //Check (countdown) when On the phone
+#define NUDGE_ACC_ST9 0x00000200 //Check (countdown) when Out to lunch
+
+// For status log
+#define EVENTTYPE_STATUSCHANGE 25368
+
+#define TEXT_LEN 1024
+
+class CNudge
+{
+public:
+ bool useByProtocol;
+ int sendTimeSec;
+ int recvTimeSec;
+ int resendDelaySec;
+
+ void Load(void);
+ void Save(void);
+};
+
+class CNudgeElement
+{
+public:
+ char ProtocolName[64];
+ char NudgeSoundname[100];
+ TCHAR recText[TEXT_LEN];
+ TCHAR senText[TEXT_LEN];
+ bool showPopup;
+ bool showEvent;
+ bool showStatus;
+ bool popupWindowColor;
+ bool shakeClist;
+ bool shakeChat;
+ bool enabled;
+ bool autoResend;
+ DWORD statusFlags;
+ unsigned int popupBackColor;
+ unsigned int popupTextColor;
+ int popupTimeSec;
+ int iProtoNumber;
+ HICON hIcon;
+ HANDLE hEvent;
+ HANDLE hContactMenu;
+
+ void Load(void);
+ void Save(void);
+ int ShowContactMenu(bool show);
+};
+
+typedef struct NudgeElementList
+{
+ CNudgeElement item;
+ NudgeElementList *next;
+} NUDGEELEMENTLIST;
+
+#endif
\ No newline at end of file diff --git a/nudge/nudge.vcproj b/nudge/nudge.vcproj new file mode 100644 index 0000000..3ddce10 --- /dev/null +++ b/nudge/nudge.vcproj @@ -0,0 +1,353 @@ +<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="nudge"
+ ProjectGUID="{8190CFAA-3B73-43D8-9101-8368E21F1864}"
+ RootNamespace="nudge"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="../../bin7/Debug/Plugins"
+ IntermediateDirectory="../../bin7/Debug/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ 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/nudge.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;nudge_EXPORTS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="2060"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="0"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug/nudge.pdb"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary=".\Debug/nudge.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="../../tweety_bin9/Release Unicode/Plugins"
+ IntermediateDirectory="../../tweety_bin9/Release Unicode/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/nudge.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="1"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="../../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;nudge_EXPORTS"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="2060"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib Delayimp.lib gdiplus.lib version.lib"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ IgnoreAllDefaultLibraries="false"
+ DelayLoadDLLs=""
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <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="main.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\nudge.cpp"
+ >
+ </File>
+ <File
+ RelativePath="options.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="shake.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath="headers.h"
+ >
+ </File>
+ <File
+ RelativePath="m_nudge.h"
+ >
+ </File>
+ <File
+ RelativePath="main.h"
+ >
+ </File>
+ <File
+ RelativePath=".\nudge.h"
+ >
+ </File>
+ <File
+ RelativePath=".\options.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath="shake.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ <File
+ RelativePath="miranda.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\nudge.ico"
+ >
+ </File>
+ <File
+ RelativePath="resource.rc"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\ChangeLog.txt"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/nudge/nudge_10.vcxproj b/nudge/nudge_10.vcxproj new file mode 100644 index 0000000..f334b2d --- /dev/null +++ b/nudge/nudge_10.vcxproj @@ -0,0 +1,482 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|x64">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>nudge</ProjectName>
+ <ProjectGuid>{8190CFAA-3B73-43D8-9101-8368E21F1864}</ProjectGuid>
+ <RootNamespace>nudge</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../bin7/Debug/Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../bin7/Debug/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../bin7/Debug/Obj/$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../../bin7/Debug/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)Release/Plugins\</OutDir>
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)Release/Plugins\</OutDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)Release/Obj/$(ProjectName)\</IntDir>
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)Release/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</LinkIncremental>
+ <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Debug/nudge.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x080c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>.\Debug/nudge.pdb</ProgramDatabaseFile>
+ <ImportLibrary>.\Debug/nudge.lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Midl>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Debug/nudge.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x080c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>.\Debug/nudge.pdb</ProgramDatabaseFile>
+ <ImportLibrary>.\Debug/nudge.lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Release/nudge.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x080c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>unicows.lib;comctl32.lib;Delayimp.lib;gdiplus.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(SolutionDir)Release/Plugins/nudge.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AssemblyDebug>
+ </AssemblyDebug>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Release/nudge.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x080c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>unicows.lib;comctl32.lib;Delayimp.lib;gdiplus.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(SolutionDir)Release/Plugins/nudge.dll</OutputFile>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AssemblyDebug>
+ </AssemblyDebug>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ <TypeLibraryName>.\Release/nudge.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x080c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>unicows.lib;comctl32.lib;Delayimp.lib;gdiplus.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AssemblyDebug>
+ </AssemblyDebug>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">
+ <Midl>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <TypeLibraryName>.\Release/nudge.tlb</TypeLibraryName>
+ <HeaderFileName>
+ </HeaderFileName>
+ </Midl>
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <OmitFramePointers>false</OmitFramePointers>
+ <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_WIN64;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <BrowseInformation>true</BrowseInformation>
+ <WarningLevel>Level3</WarningLevel>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>Default</CompileAs>
+ <DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x080c</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>comctl32.lib;Delayimp.lib;gdiplus.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AssemblyDebug>
+ </AssemblyDebug>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</BrowseInformation>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</BrowseInformation>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="nudge.cpp">
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <ClCompile Include="options.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</BrowseInformation>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</BrowseInformation>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</BrowseInformation>
+ </ClCompile>
+ <ClCompile Include="shake.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS</PreprocessorDefinitions>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
+ <BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</BrowseInformation>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</BrowseInformation>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">MaxSpeed</Optimization>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">MaxSpeed</Optimization>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</BrowseInformation>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</BrowseInformation>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">true</BrowseInformation>
+ <BrowseInformation Condition="'$(Configuration)|$(Platform)'=='Release Unicode|x64'">true</BrowseInformation>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="headers.h" />
+ <ClInclude Include="m_nudge.h" />
+ <ClInclude Include="main.h" />
+ <ClInclude Include="nudge.h" />
+ <ClInclude Include="options.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="shake.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="miranda.ico" />
+ <None Include="nudge.ico" />
+ <None Include="ChangeLog.txt" />
+ <None Include="resources\Nudge.ico" />
+ <None Include="resources\NudgeIRC.ico" />
+ <None Include="resources\NudgeMeta.ico" />
+ <None Include="resources\NudgeMSN.ico" />
+ <None Include="resources\NudgeTlen.ico" />
+ <None Include="resources\NudgeYahoo.ico" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
diff --git a/nudge/nudge_8.sln b/nudge/nudge_8.sln new file mode 100644 index 0000000..d9d46ee --- /dev/null +++ b/nudge/nudge_8.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual C++ Express 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nudge", "nudge_8.vcproj", "{8190CFAA-3B73-43D8-9101-8368E21F1864}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8190CFAA-3B73-43D8-9101-8368E21F1864}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8190CFAA-3B73-43D8-9101-8368E21F1864}.Debug|Win32.Build.0 = Debug|Win32
+ {8190CFAA-3B73-43D8-9101-8368E21F1864}.Release|Win32.ActiveCfg = Release|Win32
+ {8190CFAA-3B73-43D8-9101-8368E21F1864}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/nudge/nudge_8.vcproj b/nudge/nudge_8.vcproj new file mode 100644 index 0000000..838a427 --- /dev/null +++ b/nudge/nudge_8.vcproj @@ -0,0 +1,368 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="nudge"
+ ProjectGUID="{8190CFAA-3B73-43D8-9101-8368E21F1864}"
+ RootNamespace="nudge"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="../../bin7/Debug/Plugins"
+ IntermediateDirectory="../../bin7/Debug/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ 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/nudge.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;nudge_EXPORTS"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="2060"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib"
+ LinkIncremental="0"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug/nudge.pdb"
+ ImportLibrary=".\Debug/nudge.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)Release/Plugins"
+ IntermediateDirectory="$(SolutionDir)Release/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="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/nudge.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="1"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="false"
+ AdditionalIncludeDirectories="../../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="2060"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="unicows.lib comctl32.lib Delayimp.lib gdiplus.lib version.lib"
+ OutputFile="$(SolutionDir)Release/Plugins/nudge.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ IgnoreAllDefaultLibraries="false"
+ DelayLoadDLLs=""
+ GenerateDebugInformation="true"
+ AssemblyDebug="0"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <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="main.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\nudge.cpp"
+ >
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="options.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="shake.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;nudge_EXPORTS;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_UNICODE;UNICODE;MICROSOFT_LAYER_FOR_UNICODE=1;nudge_EXPORTS"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath="headers.h"
+ >
+ </File>
+ <File
+ RelativePath="m_nudge.h"
+ >
+ </File>
+ <File
+ RelativePath="main.h"
+ >
+ </File>
+ <File
+ RelativePath=".\nudge.h"
+ >
+ </File>
+ <File
+ RelativePath=".\options.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath="shake.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ <File
+ RelativePath="miranda.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\nudge.ico"
+ >
+ </File>
+ <File
+ RelativePath="resource.rc"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\ChangeLog.txt"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/nudge/options.cpp b/nudge/options.cpp new file mode 100644 index 0000000..4ffe6f2 --- /dev/null +++ b/nudge/options.cpp @@ -0,0 +1,578 @@ +#include "headers.h"
+#include "uxtheme.h"
+#include "main.h"
+#include "shake.h"
+#include "options.h"
+
+CNudgeElement* ActualNudge = NULL;
+
+extern BOOL (WINAPI *MyEnableThemeDialogTexture)(HANDLE, DWORD);
+
+
+int NudgeOptInit(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp = { 0 };
+ odp.cbSize = sizeof(odp);
+ odp.position = -790000000;
+ odp.hInstance = hInst;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS);
+ odp.ptszTitle = LPGENT("Nudge");
+ odp.ptszGroup = LPGENT("Events");
+ odp.flags = ODPF_BOLDGROUPS|ODPF_TCHAR;
+// odp.nIDBottomSimpleControl = IDC_STMSNGROUP;
+ odp.pfnDlgProc = OptionsDlgProc;
+ CallService( MS_OPT_ADDPAGE, wParam,( LPARAM )&odp );
+ return 0;
+}
+
+
+HANDLE hOptionsInit;
+void InitOptions()
+{
+ hOptionsInit = HookEvent(ME_OPT_INITIALISE, NudgeOptInit);
+}
+
+void UninitOptions()
+{
+ UnhookEvent(hOptionsInit);
+}
+
+static INT_PTR CALLBACK OptionsDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ static int iInit = TRUE;
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TCITEM tci;
+ RECT rcClient;
+ GetClientRect(hwnd, &rcClient);
+
+ iInit = TRUE;
+ tci.mask = TCIF_PARAM|TCIF_TEXT;
+ tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_NUDGE), hwnd, DlgProcNudgeOpt);
+ tci.pszText = TranslateT("Nudge");
+ TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 0, &tci);
+ MoveWindow((HWND)tci.lParam,1,28,rcClient.right-3,rcClient.bottom-33,1);
+ if(MyEnableThemeDialogTexture)
+ MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB);
+
+ tci.lParam = (LPARAM)CreateDialog(hInst,MAKEINTRESOURCE(IDD_OPT_SHAKE),hwnd,DlgProcShakeOpt);
+ tci.pszText = TranslateT("Window Shaking");
+ TabCtrl_InsertItem(GetDlgItem(hwnd, IDC_OPTIONSTAB), 1, &tci);
+ MoveWindow((HWND)tci.lParam,1,28,rcClient.right-3,rcClient.bottom-33,1);
+ ShowWindow((HWND)tci.lParam, SW_HIDE);
+ if(MyEnableThemeDialogTexture)
+ MyEnableThemeDialogTexture((HWND)tci.lParam, ETDT_ENABLETAB);
+ iInit = FALSE;
+ return FALSE;
+ }
+
+ case PSM_CHANGED: // used so tabs dont have to call SendMessage(GetParent(GetParent(hwnd)), PSM_CHANGED, 0, 0);
+ if(!iInit)
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ break;
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom) {
+ case 0:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ TCITEM tci;
+ int i,count;
+ tci.mask = TCIF_PARAM;
+ count = TabCtrl_GetItemCount(GetDlgItem(hwnd,IDC_OPTIONSTAB));
+ for (i=0;i<count;i++)
+ {
+ TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),i,&tci);
+ SendMessage((HWND)tci.lParam,WM_NOTIFY,0,lParam);
+ }
+
+ NudgeElementList *n;
+ for(n = NudgeList;n != NULL; n = n->next)
+ {
+ n->item.Save();
+ }
+ DefaultNudge.Save();
+ }
+ break;
+ }
+ break;
+ case IDC_OPTIONSTAB:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case TCN_SELCHANGING:
+ {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci);
+ ShowWindow((HWND)tci.lParam,SW_HIDE);
+ }
+ break;
+ case TCN_SELCHANGE:
+ {
+ TCITEM tci;
+ tci.mask = TCIF_PARAM;
+ TabCtrl_GetItem(GetDlgItem(hwnd,IDC_OPTIONSTAB),TabCtrl_GetCurSel(GetDlgItem(hwnd,IDC_OPTIONSTAB)),&tci);
+ ShowWindow((HWND)tci.lParam,SW_SHOW);
+ }
+ break;
+ }
+ break;
+
+ }
+ break;
+ }
+ return FALSE;
+}
+
+INT_PTR CALLBACK DlgProcShakeOpt(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ char szBuf[20];
+ TranslateDialogDefault(hwnd);
+ _snprintf(szBuf, 10, "%d", shake.nMoveClist);
+ SetWindowTextA(GetDlgItem(hwnd, IDC_LNUMBER_CLIST), szBuf);
+ _snprintf(szBuf, 10, "%d", shake.nMoveChat);
+ SetWindowTextA(GetDlgItem(hwnd, IDC_LNUMBER_CHAT), szBuf);
+
+ _snprintf(szBuf, 10, "%d", shake.nScaleClist);
+ SetWindowTextA(GetDlgItem(hwnd, IDC_LSCALE_CLIST), szBuf);
+ _snprintf(szBuf, 10, "%d", shake.nScaleChat);
+ SetWindowTextA(GetDlgItem(hwnd, IDC_LSCALE_CHAT), szBuf);
+
+ SendDlgItemMessage(hwnd, IDC_SNUMBER_CLIST, TBM_SETRANGE, 0, (LPARAM)MAKELONG(1, 60));
+ SendDlgItemMessage(hwnd, IDC_SNUMBER_CHAT, TBM_SETRANGE, 0, (LPARAM)MAKELONG(1, 60));
+
+ SendDlgItemMessage(hwnd, IDC_SSCALE_CLIST, TBM_SETRANGE, 0, (LPARAM)MAKELONG(1, 40));
+ SendDlgItemMessage(hwnd, IDC_SSCALE_CHAT, TBM_SETRANGE, 0, (LPARAM)MAKELONG(1, 40));
+
+ SendDlgItemMessage(hwnd, IDC_SNUMBER_CLIST, TBM_SETPOS, TRUE, shake.nMoveClist);
+ SendDlgItemMessage(hwnd, IDC_SNUMBER_CHAT, TBM_SETPOS, TRUE, shake.nMoveChat);
+
+ SendDlgItemMessage(hwnd, IDC_SSCALE_CLIST, TBM_SETPOS, TRUE, shake.nScaleClist);
+ SendDlgItemMessage(hwnd, IDC_SSCALE_CHAT, TBM_SETPOS, TRUE, shake.nScaleChat);
+
+ break;
+ case WM_COMMAND:
+ {
+ WORD wNotifyCode = HIWORD(wParam);
+ switch(LOWORD(wParam))
+ {
+ case IDC_PREVIEW:
+ ShakeClist(0,0);
+ //SendMessage(GetParent(hwnd),PSM_CHANGED,0,0);
+ break;
+ }
+ break;
+ }
+ case WM_HSCROLL:
+ if((HWND)lParam == GetDlgItem(hwnd, IDC_SNUMBER_CLIST) || (HWND)lParam == GetDlgItem(hwnd, IDC_SNUMBER_CHAT)
+ || (HWND)lParam == GetDlgItem(hwnd, IDC_SSCALE_CLIST) || (HWND)lParam == GetDlgItem(hwnd, IDC_SSCALE_CHAT))
+ {
+ char szBuf[20];
+ DWORD dwPos = SendMessage((HWND) lParam, TBM_GETPOS, 0, 0);
+ _snprintf(szBuf, 10, "%d", dwPos);
+ if ((HWND)lParam == GetDlgItem(hwnd, IDC_SNUMBER_CLIST))
+ SetWindowTextA(GetDlgItem(hwnd, IDC_LNUMBER_CLIST), szBuf);
+ if ((HWND)lParam == GetDlgItem(hwnd, IDC_SNUMBER_CHAT))
+ SetWindowTextA(GetDlgItem(hwnd, IDC_LNUMBER_CHAT), szBuf);
+ if ((HWND)lParam == GetDlgItem(hwnd, IDC_SSCALE_CLIST))
+ SetWindowTextA(GetDlgItem(hwnd, IDC_LSCALE_CLIST), szBuf);
+ if ((HWND)lParam == GetDlgItem(hwnd, IDC_SSCALE_CHAT))
+ SetWindowTextA(GetDlgItem(hwnd, IDC_LSCALE_CHAT), szBuf);
+ SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
+ }
+ break;
+
+ case WM_SHOWWINDOW:
+ break;
+
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ switch(((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ shake.nMoveClist = (int) SendMessage((HWND) GetDlgItem(hwnd, IDC_SNUMBER_CLIST), TBM_GETPOS, 0, 0);
+ shake.nMoveChat = (int) SendMessage((HWND) GetDlgItem(hwnd, IDC_SNUMBER_CHAT), TBM_GETPOS, 0, 0);
+ shake.nScaleClist = (int) SendMessage((HWND) GetDlgItem(hwnd, IDC_SSCALE_CLIST), TBM_GETPOS, 0, 0);
+ shake.nScaleChat = (int) SendMessage((HWND) GetDlgItem(hwnd, IDC_SSCALE_CHAT), TBM_GETPOS, 0, 0);
+ shake.Save();
+ }
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+void CreateImageList(HWND hWnd)
+{
+ // Create and populate image list
+ HIMAGELIST hImList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK | ILC_COLOR32, nProtocol, 0);
+
+ NudgeElementList *n;
+ for(n = NudgeList;n != NULL; n = n->next)
+ {
+ HICON hIcon = NULL;
+ hIcon=(HICON)CallProtoService(n->item.ProtocolName, PS_LOADICON,PLI_PROTOCOL | PLIF_SMALL, 0);
+ if (hIcon == NULL || (int)hIcon == CALLSERVICE_NOTFOUND)
+ {
+ hIcon=(HICON)CallProtoService(n->item.ProtocolName, PS_LOADICON, PLI_PROTOCOL, 0);
+ }
+
+ if (hIcon == NULL || (int)hIcon == CALLSERVICE_NOTFOUND)
+ hIcon = (HICON) LoadImage(hInst, MAKEINTRESOURCE(IDI_NUDGE), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
+
+ ImageList_AddIcon(hImList, hIcon);
+ DestroyIcon(hIcon);
+ }
+ //ADD default Icon for nudge
+ HICON hIcon = NULL;
+ hIcon = (HICON) LoadImage(hInst, MAKEINTRESOURCE(IDI_NUDGE), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
+ ImageList_AddIcon(hImList, hIcon);
+ DestroyIcon(hIcon);
+
+ HWND hLstView = GetDlgItem(hWnd, IDC_PROTOLIST);
+ TreeView_SetImageList(hLstView, hImList, TVSIL_NORMAL);
+}
+
+void PopulateProtocolList(HWND hWnd)
+{
+ bool useOne = IsDlgButtonChecked(hWnd, IDC_USEBYPROTOCOL) == BST_UNCHECKED;
+
+ HWND hLstView = GetDlgItem(hWnd, IDC_PROTOLIST);
+
+ TreeView_DeleteAllItems(hLstView);
+
+ TVINSERTSTRUCT tvi = {0};
+ tvi.hParent = TVI_ROOT;
+ tvi.hInsertAfter = TVI_LAST;
+ tvi.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_STATE | TVIF_SELECTEDIMAGE;
+ tvi.item.stateMask = TVIS_STATEIMAGEMASK;
+
+ NudgeElementList *n;
+ int i = 0;
+ if (GlobalNudge.useByProtocol)
+ {
+ #ifdef _UNICODE
+ wchar_t buff[256];
+ #endif
+ for(n = NudgeList;n != NULL; n = n->next)
+ {
+ #ifdef _UNICODE
+ MultiByteToWideChar(CP_ACP, 0, n->item.ProtocolName, -1, buff, 256);
+ tvi.item.pszText = buff;
+ #else
+ tvi.item.pszText = n->item.ProtocolName;
+ #endif
+ tvi.item.iImage = i;
+ n->item.iProtoNumber = i;
+ tvi.item.iSelectedImage = i;
+ tvi.item.state = INDEXTOSTATEIMAGEMASK(n->item.enabled?2:1);
+ TreeView_InsertItem(hLstView, &tvi);
+ i++;
+ }
+ }
+ else
+ {
+ tvi.item.pszText = TranslateT("Nudge");
+ tvi.item.iImage = nProtocol;
+ DefaultNudge.iProtoNumber = nProtocol;
+ tvi.item.iSelectedImage = nProtocol;
+ tvi.item.state = INDEXTOSTATEIMAGEMASK(DefaultNudge.enabled?2:1);
+ TreeView_InsertItem(hLstView, &tvi);
+
+ }
+ TreeView_SelectItem(hLstView, TreeView_GetRoot(hLstView));
+ //TreeView_SetCheckState(hLstView, TreeView_GetRoot(hLstView), TRUE)
+}
+
+
+INT_PTR CALLBACK DlgProcNudgeOpt(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwnd);
+ CreateImageList(hwnd);
+ PopulateProtocolList(hwnd);
+ UpdateControls(hwnd);
+ break;
+ case WM_DESTROY:
+ {
+ HIMAGELIST hImList = TreeView_GetImageList(GetDlgItem(hwnd, IDC_PROTOLIST), TVSIL_NORMAL);
+ if (hImList)
+ {
+ TreeView_SetImageList(GetDlgItem(hwnd, IDC_PROTOLIST), NULL, TVSIL_NORMAL); // Avoiding Access Violation in CommonControls DLL
+ ImageList_Destroy(hImList);
+ }
+ break;
+ }
+ case WM_COMMAND:
+ {
+ WORD wNotifyCode = HIWORD(wParam);
+ switch(LOWORD(wParam))
+ {
+ case IDC_PREVIEW:
+ Preview();
+ break;
+ case IDC_POPUPTIME:
+ SendMessage(GetParent(hwnd),PSM_CHANGED,0,0);
+ break;
+ case IDC_POPUPTEXTCOLOR:
+ case IDC_POPUPBACKCOLOR:
+ if (ActualNudge)// fix NULL pointer then no nudge support protocols
+ {
+ ActualNudge->popupBackColor = SendDlgItemMessage(hwnd,IDC_POPUPBACKCOLOR,CPM_GETCOLOUR,0,0);
+ ActualNudge->popupTextColor = SendDlgItemMessage(hwnd,IDC_POPUPTEXTCOLOR,CPM_GETCOLOUR,0,0);
+ }
+ SendMessage(GetParent(hwnd),PSM_CHANGED,0,0);
+ break;
+ case IDC_USEWINCOLORS:
+ if (ActualNudge)// fix NULL pointer then no nudge support protocols
+ {
+ ActualNudge->popupWindowColor = (IsDlgButtonChecked(hwnd,IDC_USEWINCOLORS)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR), ActualNudge->showPopup && ! ActualNudge->popupWindowColor);
+ EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR), ActualNudge->showPopup && ! ActualNudge->popupWindowColor);
+ }
+ SendMessage(GetParent(hwnd),PSM_CHANGED,0,0);
+ break;
+ case IDC_CHECKPOP:
+ if (ActualNudge)// fix NULL pointer then no nudge support protocols
+ {
+ ActualNudge->showPopup = (IsDlgButtonChecked(hwnd,IDC_CHECKPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hwnd,IDC_USEWINCOLORS),ActualNudge->showPopup);
+ EnableWindow(GetDlgItem(hwnd,IDC_POPUPBACKCOLOR),ActualNudge->showPopup && ! ActualNudge->popupWindowColor);
+ EnableWindow(GetDlgItem(hwnd,IDC_POPUPTEXTCOLOR),ActualNudge->showPopup && ! ActualNudge->popupWindowColor);
+ EnableWindow(GetDlgItem(hwnd,IDC_POPUPTIME),ActualNudge->showPopup);
+ }
+ SendMessage(GetParent(hwnd),PSM_CHANGED,0,0);
+ break;
+ case IDC_USEBYPROTOCOL:
+ GlobalNudge.useByProtocol = (IsDlgButtonChecked(hwnd,IDC_USEBYPROTOCOL)==BST_CHECKED);
+ PopulateProtocolList(hwnd);
+ UpdateControls(hwnd);
+ SendMessage(GetParent(hwnd),PSM_CHANGED,0,0);
+ break;
+ case IDC_CHECKEVENT:
+ case IDC_CHECKCLIST:
+ case IDC_CHECKCHAT:
+ case IDC_CHECKSTATUS:
+ case IDC_AUTORESEND:
+ if (ActualNudge)// fix NULL pointer then no nudge support protocols
+ {
+ ActualNudge->shakeClist = (IsDlgButtonChecked(hwnd,IDC_CHECKCLIST)==BST_CHECKED);
+ ActualNudge->shakeChat = (IsDlgButtonChecked(hwnd,IDC_CHECKCHAT)==BST_CHECKED);
+ ActualNudge->showEvent = (IsDlgButtonChecked(hwnd,IDC_CHECKEVENT)==BST_CHECKED);
+ ActualNudge->showStatus = (IsDlgButtonChecked(hwnd,IDC_CHECKSTATUS)==BST_CHECKED);
+ ActualNudge->autoResend = (IsDlgButtonChecked(hwnd,IDC_AUTORESEND)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hwnd,IDC_RESENDDELAY),ActualNudge->autoResend);
+ }
+ SendMessage(GetParent(hwnd),PSM_CHANGED,0,0);
+ break;
+ case IDC_CHECKST0:
+ case IDC_CHECKST1:
+ case IDC_CHECKST2:
+ case IDC_CHECKST3:
+ case IDC_CHECKST4:
+ case IDC_CHECKST5:
+ case IDC_CHECKST6:
+ case IDC_CHECKST7:
+ case IDC_CHECKST8:
+ case IDC_CHECKST9:
+ case IDC_SENDTEXT:
+ case IDC_RECVTEXT:
+ case IDC_SENDTIME:
+ case IDC_RECVTIME:
+ SendMessage(GetParent(hwnd),PSM_CHANGED,0,0);
+ break;
+ }
+ break;
+ }
+ case WM_SHOWWINDOW:
+ break;
+
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ switch(((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ BOOL Translated;
+ GlobalNudge.sendTimeSec = GetDlgItemInt(hwnd,IDC_SENDTIME,&Translated,FALSE);
+ GlobalNudge.recvTimeSec = GetDlgItemInt(hwnd,IDC_RECVTIME,&Translated,FALSE);
+ GlobalNudge.resendDelaySec = GetDlgItemInt(hwnd,IDC_RESENDDELAY,&Translated,FALSE);
+ if(GlobalNudge.resendDelaySec > 10 ) GlobalNudge.resendDelaySec = 10;
+ if(GlobalNudge.resendDelaySec < 1 ) GlobalNudge.resendDelaySec = 1;
+ if (ActualNudge)// fix NULL pointer then no nudge support protocols
+ {
+ ActualNudge->popupTimeSec = GetDlgItemInt(hwnd,IDC_POPUPTIME,&Translated,FALSE);
+ ActualNudge->popupWindowColor = (IsDlgButtonChecked(hwnd,IDC_USEWINCOLORS)==BST_CHECKED);
+ ActualNudge->showPopup = (IsDlgButtonChecked(hwnd,IDC_CHECKPOP)==BST_CHECKED);
+ ActualNudge->statusFlags =
+ ((IsDlgButtonChecked(hwnd,IDC_CHECKST0)==BST_CHECKED) ? NUDGE_ACC_ST0 : 0) |
+ ((IsDlgButtonChecked(hwnd,IDC_CHECKST1)==BST_CHECKED) ? NUDGE_ACC_ST1 : 0) |
+ ((IsDlgButtonChecked(hwnd,IDC_CHECKST2)==BST_CHECKED) ? NUDGE_ACC_ST2 : 0) |
+ ((IsDlgButtonChecked(hwnd,IDC_CHECKST3)==BST_CHECKED) ? NUDGE_ACC_ST3 : 0) |
+ ((IsDlgButtonChecked(hwnd,IDC_CHECKST4)==BST_CHECKED) ? NUDGE_ACC_ST4 : 0) |
+ ((IsDlgButtonChecked(hwnd,IDC_CHECKST5)==BST_CHECKED) ? NUDGE_ACC_ST5 : 0) |
+ ((IsDlgButtonChecked(hwnd,IDC_CHECKST6)==BST_CHECKED) ? NUDGE_ACC_ST6 : 0) |
+ ((IsDlgButtonChecked(hwnd,IDC_CHECKST7)==BST_CHECKED) ? NUDGE_ACC_ST7 : 0) |
+ ((IsDlgButtonChecked(hwnd,IDC_CHECKST8)==BST_CHECKED) ? NUDGE_ACC_ST8 : 0) |
+ ((IsDlgButtonChecked(hwnd,IDC_CHECKST9)==BST_CHECKED) ? NUDGE_ACC_ST9 : 0) ;
+
+ GetDlgItemText(hwnd,IDC_SENDTEXT,ActualNudge->senText,TEXT_LEN);
+ GetDlgItemText(hwnd,IDC_RECVTEXT,ActualNudge->recText,TEXT_LEN);
+ ActualNudge->Save();
+ }
+ GlobalNudge.Save();
+ }
+ }
+ case IDC_PROTOLIST:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case NM_CLICK:
+ {
+ TVHITTESTINFO ht = {0};
+
+ DWORD dwpos = GetMessagePos();
+ POINTSTOPOINT(ht.pt, MAKEPOINTS(dwpos));
+ MapWindowPoints(HWND_DESKTOP, ((LPNMHDR)lParam)->hwndFrom, &ht.pt, 1);
+
+ TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom, &ht);
+ /*if (TVHT_ONITEM & ht.flags)
+ CheckChange(hwnd,ht.hItem);*/
+ if (TVHT_ONITEMSTATEICON & ht.flags)
+ CheckChange(hwnd,ht.hItem);
+ SendMessage(GetParent(hwnd),PSM_CHANGED,0,0);
+ }
+
+ case TVN_KEYDOWN:
+ if (((LPNMTVKEYDOWN) lParam)->wVKey == VK_SPACE)
+ CheckChange(hwnd, TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom));
+ break;
+
+ case TVN_SELCHANGEDA:
+ case TVN_SELCHANGEDW:
+ {
+ LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) lParam;
+ if (pnmtv->itemNew.state & TVIS_SELECTED)
+ UpdateControls(hwnd);
+ }
+ break;
+ }
+ break;
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+void CheckChange(HWND hwnd, HTREEITEM hItem)
+{
+ HWND hLstView = GetDlgItem(hwnd, IDC_PROTOLIST);
+ bool isChecked = !TreeView_GetCheckState(hLstView, hItem);
+
+ TreeView_SelectItem(hLstView, hItem);
+
+ int proto = nProtocol;
+ NudgeElementList *n;
+ if (GlobalNudge.useByProtocol)
+ {
+ proto = GetSelProto(hwnd, hItem);
+ ActualNudge = NULL;
+ for(n = NudgeList;n != NULL; n = n->next)
+ {
+ if(n->item.iProtoNumber == proto)
+ ActualNudge = &n->item;
+ }
+ }
+ else
+ ActualNudge = &DefaultNudge;
+
+ if (ActualNudge)// fix NULL pointer then no nudge support protocols
+ ActualNudge->enabled = isChecked;
+
+ UpdateControls(hwnd);
+}
+
+void UpdateControls(HWND hwnd)
+{
+ int proto = nProtocol;
+ NudgeElementList *n;
+ if (GlobalNudge.useByProtocol)
+ {
+ proto = GetSelProto(hwnd,NULL);
+ ActualNudge = NULL;
+ for(n = NudgeList;n != NULL; n = n->next)
+ {
+ if(n->item.iProtoNumber == proto)
+ ActualNudge = &n->item;
+ }
+ }
+ else
+ ActualNudge = &DefaultNudge;
+
+ SetDlgItemInt(hwnd, IDC_SENDTIME, GlobalNudge.sendTimeSec,FALSE);
+ SetDlgItemInt(hwnd, IDC_RECVTIME, GlobalNudge.recvTimeSec,FALSE);
+ SetDlgItemInt(hwnd, IDC_RESENDDELAY, GlobalNudge.resendDelaySec,FALSE);
+ CheckDlgButton(hwnd, IDC_USEBYPROTOCOL, (WPARAM) GlobalNudge.useByProtocol);
+ SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLOR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_BTNFACE));
+ SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLOR, CPM_SETDEFAULTCOLOUR, 0, GetSysColor(COLOR_WINDOWTEXT));
+
+ if (ActualNudge)// fix NULL pointer then no nudge support protocols
+ {
+ CheckDlgButton(hwnd, IDC_CHECKPOP, (WPARAM) ActualNudge->showPopup);
+ CheckDlgButton(hwnd, IDC_USEWINCOLORS, (WPARAM) ActualNudge->popupWindowColor);
+ CheckDlgButton(hwnd, IDC_CHECKCLIST, (WPARAM) ActualNudge->shakeClist);
+ CheckDlgButton(hwnd, IDC_CHECKCHAT, (WPARAM) ActualNudge->shakeChat);
+ CheckDlgButton(hwnd, IDC_CHECKEVENT, (WPARAM) ActualNudge->showEvent);
+ CheckDlgButton(hwnd, IDC_CHECKSTATUS, (WPARAM) ActualNudge->showStatus);
+ CheckDlgButton(hwnd, IDC_AUTORESEND, (WPARAM) ActualNudge->autoResend);
+ SetDlgItemInt(hwnd, IDC_POPUPTIME, ActualNudge->popupTimeSec,FALSE);
+ SendDlgItemMessage(hwnd, IDC_POPUPBACKCOLOR, CPM_SETCOLOUR,0, ActualNudge->popupBackColor);
+ SendDlgItemMessage(hwnd, IDC_POPUPTEXTCOLOR, CPM_SETCOLOUR,0, ActualNudge->popupTextColor);
+ EnableWindow(GetDlgItem(hwnd, IDC_USEWINCOLORS), ActualNudge->showPopup);
+ EnableWindow(GetDlgItem(hwnd, IDC_POPUPBACKCOLOR), ActualNudge->showPopup && ! ActualNudge->popupWindowColor);
+ EnableWindow(GetDlgItem(hwnd, IDC_POPUPTEXTCOLOR), ActualNudge->showPopup && ! ActualNudge->popupWindowColor);
+ EnableWindow(GetDlgItem(hwnd, IDC_POPUPTIME), ActualNudge->showPopup);
+ EnableWindow(GetDlgItem(hwnd,IDC_RESENDDELAY),ActualNudge->autoResend);
+ CheckDlgButton(hwnd,IDC_CHECKST0,ActualNudge->statusFlags & NUDGE_ACC_ST0 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwnd,IDC_CHECKST1,ActualNudge->statusFlags & NUDGE_ACC_ST1 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwnd,IDC_CHECKST2,ActualNudge->statusFlags & NUDGE_ACC_ST2 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwnd,IDC_CHECKST3,ActualNudge->statusFlags & NUDGE_ACC_ST3 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwnd,IDC_CHECKST4,ActualNudge->statusFlags & NUDGE_ACC_ST4 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwnd,IDC_CHECKST5,ActualNudge->statusFlags & NUDGE_ACC_ST5 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwnd,IDC_CHECKST6,ActualNudge->statusFlags & NUDGE_ACC_ST6 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwnd,IDC_CHECKST7,ActualNudge->statusFlags & NUDGE_ACC_ST7 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwnd,IDC_CHECKST8,ActualNudge->statusFlags & NUDGE_ACC_ST8 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hwnd,IDC_CHECKST9,ActualNudge->statusFlags & NUDGE_ACC_ST9 ? BST_CHECKED : BST_UNCHECKED);
+ SetWindowText(GetDlgItem(hwnd, IDC_SENDTEXT), ActualNudge->senText);
+ SetWindowText(GetDlgItem(hwnd, IDC_RECVTEXT), ActualNudge->recText);
+ }
+}
+
+int GetSelProto(HWND hwnd, HTREEITEM hItem)
+{
+ HWND hLstView = GetDlgItem(hwnd, IDC_PROTOLIST);
+ TVITEM tvi = {0};
+
+ tvi.mask = TVIF_IMAGE;
+ tvi.hItem = hItem == NULL ? TreeView_GetSelection(hLstView) : hItem;
+
+ TreeView_GetItem(hLstView, &tvi);
+
+ return tvi.iImage;
+}
\ No newline at end of file diff --git a/nudge/options.h b/nudge/options.h new file mode 100644 index 0000000..ae658a1 --- /dev/null +++ b/nudge/options.h @@ -0,0 +1,17 @@ +extern HINSTANCE hInst;
+extern NudgeElementList* NudgeList;
+extern int nProtocol;
+extern bool useByProtocol;
+extern CNudgeElement DefaultNudge;
+extern CShake shake;
+extern CNudge GlobalNudge;
+
+static INT_PTR CALLBACK OptionsDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+static INT_PTR CALLBACK DlgProcNudgeOpt(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+static INT_PTR CALLBACK DlgProcShakeOpt(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
+
+void CreateImageList(HWND hWnd);
+void PopulateProtocolList(HWND hWnd);
+void UpdateControls(HWND hwnd);
+int GetSelProto(HWND hwnd, HTREEITEM hItem);
+void CheckChange(HWND hwnd, HTREEITEM hItem);
diff --git a/nudge/resource.h b/nudge/resource.h new file mode 100644 index 0000000..d7691a9 --- /dev/null +++ b/nudge/resource.h @@ -0,0 +1,88 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDD_DIALOG1 101
+#define IDI_NUDGE 102
+#define IDI_NUGDE_YAHOO 107
+#define IDI_NUDGE_IRC 109
+#define IDI_NUDGE_MSN 110
+#define IDI_NUDGE_TLEN 111
+#define IDI_NUDGE_META 113
+#define IDD_SHAKEOPT 126
+#define IDD_OPT_NUDGE 126
+#define IDD_OPTIONS 127
+#define IDD_OPT_SHAKE 128
+#define IDD_OPT_TRIGGER 129
+#define IDC_BUTTON1 1000
+#define IDC_PREVIEW 1000
+#define IDC_EDIT1 1001
+#define IDC_SENDTEXT 1001
+#define IDC_BUTTON2 1002
+#define IDC_SENDTEXT2 1002
+#define IDC_RECVTEXT 1002
+#define IDC_BUTTON3 1003
+#define IDC_BUTTON4 1004
+#define IDC_BUTTON5 1005
+#define IDC_BUTTON6 1006
+#define IDC_BUTTON7 1007
+#define IDC_USEWINCOLORS 1007
+#define IDC_LABEL_FN 1008
+#define IDC_LABEL_IMAGESIZE 1009
+#define IDC_SLIDER_CLIST 1009
+#define IDC_SNUMBER_CLIST 1009
+#define IDC_SLIDER_CHAT 1010
+#define IDC_SNUMBER_CHAT 1010
+#define IDC_LABEL_ERRSTATE 1011
+#define IDC_OPTIONSTAB 1011
+#define IDC_SSCALE_CLIST 1011
+#define IDC_LABEL_TOTALBLOCKS 1012
+#define IDC_LNUMBER_CLIST 1012
+#define IDC_LABEL_WRITTENBLOCKS 1013
+#define IDC_LABEL_RESULT 1013
+#define IDC_LNUMBER_CHAT 1013
+#define IDC_LSCALE_CLIST 1014
+#define IDC_SSCALE_CHAT 1015
+#define IDC_LSCALE_CHAT 1016
+#define IDC_CHECKCLIST 1018
+#define IDC_CHECKST0 1019
+#define IDC_CHECKST1 1020
+#define IDC_CHECKST2 1021
+#define IDC_CHECKST3 1022
+#define IDC_CHECKST4 1023
+#define IDC_CHECKST5 1024
+#define IDC_CHECKST6 1025
+#define IDC_CHECKST7 1026
+#define IDC_POPUPTEXTCOLOR 1027
+#define IDC_CHECKST8 1028
+#define IDC_CHECKST9 1029
+#define IDC_BGCOLOUR 1030
+#define IDC_PROTOLIST 1031
+#define IDC_TEXTCOLOUR 1032
+#define IDC_USEBYPROTOCOL 1033
+#define IDC_CHECKCHAT2 1034
+#define IDC_CHECKCHAT 1034
+#define IDC_CHECKCOL 1035
+#define IDC_CHECKEVENT 1035
+#define IDC_POPUPBACKCOLOR 1036
+#define IDC_CHECKPOP 1037
+#define IDC_POPUPTIME 1038
+#define IDC_SENDTIME 1039
+#define IDC_RECVTIME 1040
+#define IDC_TRIGGER_SHAKECLIST 1040
+#define IDC_CHECKEVENT2 1041
+#define IDC_CHECKSTATUS 1041
+#define IDC_TRIGGER_SHAKECHAT 1041
+#define IDC_AUTORESEND 1042
+#define IDC_RESENDDELAY 1043
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 114
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1041
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/nudge/resource.rc b/nudge/resource.rc new file mode 100644 index 0000000..b100be9 --- /dev/null +++ b/nudge/resource.rc @@ -0,0 +1,370 @@ +//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Bulgarian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_BGR)
+#ifdef _WIN32
+LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
+#pragma code_page(1251)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "#include ""winres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Bulgarian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPT_NUDGE DIALOGEX 0, 0, 313, 240
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "Allow nudges when you're:",IDC_STATIC,8,133,157,63
+ CONTROL "Offline",IDC_CHECKST0,"Button",BS_AUTOCHECKBOX |
+ BS_NOTIFY | WS_TABSTOP,13,143,65,9
+ CONTROL "Online",IDC_CHECKST1,"Button",BS_AUTOCHECKBOX |
+ BS_NOTIFY | WS_TABSTOP,13,153,65,9
+ CONTROL "Away",IDC_CHECKST2,"Button",BS_AUTOCHECKBOX | BS_NOTIFY |
+ WS_TABSTOP,13,163,65,9
+ CONTROL "NA",IDC_CHECKST3,"Button",BS_AUTOCHECKBOX | BS_NOTIFY |
+ WS_TABSTOP,13,173,65,9
+ CONTROL "Occupied",IDC_CHECKST4,"Button",BS_AUTOCHECKBOX |
+ BS_NOTIFY | WS_TABSTOP,13,183,65,9
+ CONTROL "DND",IDC_CHECKST5,"Button",BS_AUTOCHECKBOX | BS_NOTIFY |
+ WS_TABSTOP,85,143,70,9
+ CONTROL "Free for chat",IDC_CHECKST6,"Button",BS_AUTOCHECKBOX |
+ BS_NOTIFY | WS_TABSTOP,85,153,70,9
+ CONTROL "Invisible",IDC_CHECKST7,"Button",BS_AUTOCHECKBOX |
+ BS_NOTIFY | WS_TABSTOP,85,163,70,9
+ CONTROL "On the phone",IDC_CHECKST8,"Button",BS_AUTOCHECKBOX |
+ BS_NOTIFY | WS_TABSTOP,85,173,70,9
+ CONTROL "Out to lunch",IDC_CHECKST9,"Button",BS_AUTOCHECKBOX |
+ BS_NOTIFY | WS_TABSTOP,85,183,70,9
+ PUSHBUTTON "Preview",IDC_PREVIEW,265,207,39,12
+ GROUPBOX "Popup options",IDC_STATIC,169,133,140,88
+ CONTROL "Popup notification",IDC_CHECKPOP,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,174,143,121,9
+ EDITTEXT IDC_POPUPTIME,174,163,20,12,ES_AUTOHSCROLL
+ LTEXT "s",IDC_STATIC,196,165,12,8
+ LTEXT "Popup duration",IDC_STATIC,216,165,79,8
+ CONTROL "",IDC_POPUPBACKCOLOR,"ColourPicker",WS_TABSTOP,174,177,
+ 39,12
+ LTEXT "Background colour",IDC_STATIC,216,179,80,8,
+ SS_CENTERIMAGE
+ CONTROL "",IDC_POPUPTEXTCOLOR,"ColourPicker",WS_TABSTOP,174,192,
+ 39,12
+ LTEXT "Text colour",IDC_STATIC,216,193,80,8,SS_CENTERIMAGE
+ CONTROL "&Use Windows colours",IDC_USEWINCOLORS,"Button",
+ BS_AUTOCHECKBOX | BS_NOTIFY | BS_FLAT | WS_TABSTOP,174,
+ 153,121,9
+ CONTROL "",IDC_PROTOLIST,"SysTreeView32",TVS_DISABLEDRAGDROP |
+ TVS_SHOWSELALWAYS | TVS_CHECKBOXES | WS_BORDER |
+ WS_TABSTOP,8,12,105,84
+ GROUPBOX "Protocol options",IDC_STATIC,4,1,309,224
+ CONTROL "Specify options for each protocol",IDC_USEBYPROTOCOL,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,121,10,162,8
+ CONTROL "Enable clist shaking",IDC_CHECKCLIST,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,132,20,147,8
+ CONTROL "Enable message window shaking",IDC_CHECKCHAT,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,132,30,147,8
+ CONTROL "Treat nudge as a message",IDC_CHECKEVENT,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,132,60,147,8
+ EDITTEXT IDC_SENDTEXT,205,70,102,12,ES_AUTOHSCROLL
+ EDITTEXT IDC_RECVTEXT,205,85,102,12,ES_AUTOHSCROLL
+ RTEXT "Sending text",IDC_STATIC,131,73,70,8
+ RTEXT "Receiving text",IDC_STATIC,131,87,70,8
+ RTEXT "Allow sending* one nudge to the same contact every :",
+ IDC_STATIC,13,106,256,8
+ RTEXT "Allow receiving one nudge from the same contact every :",
+ IDC_STATIC,13,120,257,8
+ EDITTEXT IDC_SENDTIME,274,104,17,12,ES_AUTOHSCROLL | ES_READONLY |
+ WS_DISABLED
+ EDITTEXT IDC_RECVTIME,274,118,18,12,ES_AUTOHSCROLL
+ LTEXT "s",IDC_STATIC,293,106,8,8
+ LTEXT "s",IDC_STATIC,293,120,8,8
+ GROUPBOX "Privacy",IDC_STATIC,8,97,301,36
+ CONTROL "Show as status change",IDC_CHECKSTATUS,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,132,40,147,8
+ CONTROL "Auto resend nudge after",IDC_AUTORESEND,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,132,50,147,8
+ EDITTEXT IDC_RESENDDELAY,281,48,18,12,ES_AUTOHSCROLL | ES_NUMBER
+ LTEXT "s",IDC_STATIC,301,50,8,8
+ CTEXT "* Nudge sending delay is hardcoded and cannot be changed.",
+ IDC_STATIC,15,199,141,22,NOT WS_GROUP
+END
+
+IDD_OPTIONS DIALOGEX 0, 0, 319, 249
+STYLE DS_FIXEDSYS | DS_CENTER | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "Tab1",IDC_OPTIONSTAB,"SysTabControl32",WS_TABSTOP,0,3,
+ 319,246
+END
+
+IDD_OPT_SHAKE DIALOGEX 0, 0, 300, 240
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Shaking Clist Options",IDC_STATIC,7,10,291,96
+ GROUPBOX "Shaking Message Window Options",IDC_STATIC,7,111,291,
+ 101
+ CONTROL "Slider1",IDC_SNUMBER_CLIST,"msctls_trackbar32",
+ TBS_AUTOTICKS | TBS_BOTH | WS_TABSTOP,81,25,179,21
+ RTEXT "Number of moves",IDC_STATIC,13,31,67,9
+ RTEXT "Number of moves",IDC_STATIC,13,140,67,9
+ CONTROL "Slider1",IDC_SNUMBER_CHAT,"msctls_trackbar32",
+ TBS_AUTOTICKS | TBS_BOTH | WS_TABSTOP,81,134,179,21
+ LTEXT "Static",IDC_LNUMBER_CLIST,260,32,25,8
+ LTEXT "Static",IDC_LNUMBER_CHAT,260,141,24,8
+ CONTROL "",IDC_SSCALE_CLIST,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_TABSTOP,81,47,179,21
+ RTEXT "Width of move",IDC_STATIC,13,52,67,9
+ LTEXT "Static",IDC_LSCALE_CLIST,260,52,25,8
+ CONTROL "",IDC_SSCALE_CHAT,"msctls_trackbar32",TBS_AUTOTICKS |
+ TBS_BOTH | WS_TABSTOP,81,152,179,21
+ RTEXT "Width of move",IDC_STATIC,13,158,67,9
+ LTEXT "Static",IDC_LSCALE_CHAT,260,159,25,8
+END
+
+IDD_OPT_TRIGGER DIALOGEX 0, 0, 319, 249
+STYLE DS_FIXEDSYS | DS_CENTER | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "Shake the contact list",IDC_TRIGGER_SHAKECLIST,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,20,270,10
+ CONTROL "Shake the chat window",IDC_TRIGGER_SHAKECHAT,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,13,35,270,10
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO MOVEABLE PURE
+BEGIN
+ IDD_OPT_NUDGE, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ VERTGUIDE, 8
+ VERTGUIDE, 85
+ VERTGUIDE, 165
+ VERTGUIDE, 174
+ TOPMARGIN, 1
+ BOTTOMMARGIN, 231
+ HORZGUIDE, 4
+ HORZGUIDE, 10
+ HORZGUIDE, 189
+ HORZGUIDE, 204
+ HORZGUIDE, 225
+ END
+
+ IDD_OPTIONS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 312
+ VERTGUIDE, 13
+ VERTGUIDE, 85
+ VERTGUIDE, 160
+ VERTGUIDE, 307
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 243
+ HORZGUIDE, 5
+ HORZGUIDE, 20
+ HORZGUIDE, 147
+ HORZGUIDE, 157
+ HORZGUIDE, 173
+ HORZGUIDE, 184
+ HORZGUIDE, 207
+ HORZGUIDE, 217
+ HORZGUIDE, 228
+ HORZGUIDE, 239
+ HORZGUIDE, 243
+ END
+
+ IDD_OPT_SHAKE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 293
+ VERTGUIDE, 13
+ VERTGUIDE, 85
+ VERTGUIDE, 160
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 216
+ HORZGUIDE, 5
+ HORZGUIDE, 20
+ HORZGUIDE, 147
+ HORZGUIDE, 157
+ HORZGUIDE, 169
+ HORZGUIDE, 184
+ HORZGUIDE, 207
+ HORZGUIDE, 217
+ END
+
+ IDD_OPT_TRIGGER, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 312
+ VERTGUIDE, 13
+ VERTGUIDE, 85
+ VERTGUIDE, 160
+ VERTGUIDE, 307
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 243
+ HORZGUIDE, 5
+ HORZGUIDE, 20
+ HORZGUIDE, 147
+ HORZGUIDE, 157
+ HORZGUIDE, 173
+ HORZGUIDE, 184
+ HORZGUIDE, 207
+ HORZGUIDE, 217
+ HORZGUIDE, 228
+ HORZGUIDE, 239
+ HORZGUIDE, 243
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// French (Belgium) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRB)
+#ifdef _WIN32
+LANGUAGE LANG_FRENCH, SUBLANG_FRENCH_BELGIAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,0,1,19
+ PRODUCTVERSION 0,0,1,19
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "Comments", "Plugin that render nudge events from different protocols\0"
+ VALUE "CompanyName", "Miranda community\0"
+ VALUE "FileDescription", "Nudge plugin for Miranda-IM\0"
+ VALUE "FileVersion", "0, 0, 1, 19\0"
+ VALUE "InternalName", "Nudge\0"
+ VALUE "LegalCopyright", "Copyright © 2006\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "nudge.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "nudge\0"
+ VALUE "ProductVersion", "0, 0, 1, 19\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_NUDGE ICON DISCARDABLE "resources\\Nudge.ico"
+IDI_NUGDE_YAHOO ICON DISCARDABLE "resources\\NudgeYahoo.ico"
+IDI_NUDGE_IRC ICON DISCARDABLE "resources\\NudgeIRC.ico"
+IDI_NUDGE_MSN ICON DISCARDABLE "resources\\NudgeMSN.ico"
+IDI_NUDGE_TLEN ICON DISCARDABLE "resources\\NudgeTlen.ico"
+IDI_NUDGE_META ICON DISCARDABLE "resources\\NudgeMeta.ico"
+#endif // French (Belgium) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/nudge/resources/Nudge.ico b/nudge/resources/Nudge.ico Binary files differnew file mode 100644 index 0000000..29d9911 --- /dev/null +++ b/nudge/resources/Nudge.ico diff --git a/nudge/resources/NudgeIRC.ico b/nudge/resources/NudgeIRC.ico Binary files differnew file mode 100644 index 0000000..f950403 --- /dev/null +++ b/nudge/resources/NudgeIRC.ico diff --git a/nudge/resources/NudgeMSN.ico b/nudge/resources/NudgeMSN.ico Binary files differnew file mode 100644 index 0000000..c52057b --- /dev/null +++ b/nudge/resources/NudgeMSN.ico diff --git a/nudge/resources/NudgeMeta.ico b/nudge/resources/NudgeMeta.ico Binary files differnew file mode 100644 index 0000000..fabd329 --- /dev/null +++ b/nudge/resources/NudgeMeta.ico diff --git a/nudge/resources/NudgeTlen.ico b/nudge/resources/NudgeTlen.ico Binary files differnew file mode 100644 index 0000000..d4a2c06 --- /dev/null +++ b/nudge/resources/NudgeTlen.ico diff --git a/nudge/resources/NudgeYahoo.ico b/nudge/resources/NudgeYahoo.ico Binary files differnew file mode 100644 index 0000000..7bed3ca --- /dev/null +++ b/nudge/resources/NudgeYahoo.ico diff --git a/nudge/resources/nudge msn.ico b/nudge/resources/nudge msn.ico Binary files differnew file mode 100644 index 0000000..77ad817 --- /dev/null +++ b/nudge/resources/nudge msn.ico diff --git a/nudge/shake.cpp b/nudge/shake.cpp new file mode 100644 index 0000000..16fca0a --- /dev/null +++ b/nudge/shake.cpp @@ -0,0 +1,195 @@ +#include "headers.h"
+#include "shake.h"
+
+extern CShake shake;
+
+void CShake::Load(void)
+{
+
+ Shaking = false;
+ ShakingChat = false;
+ nScaleClist = DBGetContactSettingDword(NULL, "Nudge", "ScaleClist", 5);
+ nScaleChat = DBGetContactSettingDword(NULL, "Nudge", "ScaleChat", 2);
+ nMoveClist = DBGetContactSettingDword(NULL, "Nudge", "MoveClist", 15);
+ nMoveChat = DBGetContactSettingDword(NULL, "Nudge", "MoveChat", 15);
+}
+void CShake::Save(void)
+{
+ DBWriteContactSettingDword(NULL, "Nudge", "ScaleClist", this->nScaleClist);
+ DBWriteContactSettingDword(NULL, "Nudge", "ScaleChat", this->nScaleChat);
+ DBWriteContactSettingDword(NULL, "Nudge", "MoveClist", this->nMoveClist);
+ DBWriteContactSettingDword(NULL, "Nudge", "MoveChat", this->nMoveChat);
+}
+
+DWORD WINAPI ShakeChatWindow(LPVOID Param)
+{
+ HWND hWnd;
+ hWnd = (HWND) Param;
+ shake.ShakeChat(hWnd);
+ return 1;
+}
+
+DWORD WINAPI ShakeClistWindow(LPVOID Param)
+{
+ HWND hWnd;
+ hWnd = (HWND) Param;
+ shake.ShakeClist(hWnd);
+ return 0;
+}
+
+INT_PTR ShakeClist( WPARAM wParam, LPARAM lParam )
+{
+ DWORD tid;
+ HWND hWnd;
+ hWnd = (HWND) CallService( MS_CLUI_GETHWND, 0, 0 );
+
+ CreateThread(NULL,0,ShakeClistWindow,(LPVOID) hWnd,0,&tid);
+ return 0;
+}
+
+INT_PTR ShakeChat( WPARAM wParam, LPARAM lParam )
+{
+ if(((HANDLE) wParam) == NULL) return -1;
+
+ DWORD tid;
+ HWND hWnd;
+ //char srmmName[100];
+ MessageWindowData mwd;
+ MessageWindowInputData mwid;
+
+ mwd.cbSize = sizeof(MessageWindowData);
+ mwd.hContact = Nudge_GethContact((HANDLE) wParam);
+ mwd.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+
+ mwid.cbSize = sizeof(MessageWindowInputData);
+ mwid.hContact = mwd.hContact;
+ mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+
+
+ CallService( MS_MSG_GETWINDOWDATA, (WPARAM)&mwid, (LPARAM)&mwd );
+ //CallService(MS_MSG_GETWINDOWCLASS,(WPARAM)srmmName,(LPARAM)100 );
+
+ HWND parent;
+ hWnd = mwd.hwndWindow;
+ while((parent = GetParent(hWnd)) != 0) hWnd = parent; // ensure we have the top level window (need parent window for scriver & tabsrmm)
+
+ CreateThread(NULL,0,ShakeChatWindow,(LPVOID) hWnd,0,&tid);
+ return 0;
+}
+
+/*
+
+int TriggerShakeClist( WPARAM wParam, LPARAM lParam )
+{
+ DWORD tid;
+ HWND hWnd;
+ int flags;
+ flags = (int)wParam;
+
+ if (!flags&ACT_PERFORM)
+ return 0;
+
+ hWnd = (HWND) CallService( MS_CLUI_GETHWND, 0, 0 );
+
+ CreateThread(NULL,0,ShakeClistWindow,(LPVOID) hWnd,0,&tid);
+ return 0;
+}
+
+int TriggerShakeChat( WPARAM wParam, LPARAM lParam )
+{
+ DWORD tid;
+ HWND hWnd;
+ char srmmName[100];
+ MessageWindowData mwd;
+ MessageWindowInputData mwid;
+ int flags;
+ flags = (int)wParam;
+
+ if (!flags&ACT_PERFORM)
+ return 0;
+
+ SPECIFICACTIONINFO *sai;
+ HANDLE hContact;
+
+
+ sai = (SPECIFICACTIONINFO *) lParam;
+
+ if ( (sai->td != NULL) && (sai->td->dFlags&DF_CONTACT) )
+ hContact = sai->td->hContact;
+ else
+ return 0;
+
+ mwd.cbSize = sizeof(MessageWindowData);
+ mwd.hContact = Nudge_GethContact((HANDLE) hContact);
+ mwd.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+
+ mwid.cbSize = sizeof(MessageWindowInputData);
+ mwid.hContact = Nudge_GethContact((HANDLE) hContact);
+ mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH;
+
+ CallService( MS_MSG_GETWINDOWDATA, (WPARAM)&mwid, (LPARAM)&mwd );
+ CallService(MS_MSG_GETWINDOWCLASS,(WPARAM)srmmName,(LPARAM)100 );
+
+ if ( !strnicmp( srmmName,"tabSRMM ", 7 ))
+ hWnd = GetParent(GetParent(mwd.hwndWindow));
+
+ if ( !strnicmp( srmmName,"SRMM ", 4))
+ hWnd = mwd.hwndWindow;
+
+ if ( !strnicmp( srmmName,"Scriver ", 7 ))
+ hWnd = GetParent(mwd.hwndWindow);
+
+ CreateThread(NULL,0,ShakeChatWindow,(LPVOID) hWnd,0,&tid);
+ return 0;
+}
+*/
+
+int CShake::ShakeChat(HWND hWnd)
+{
+ if(!ShakingChat)
+ {
+ Shaking = true;
+ int i;
+ RECT rect;
+ GetWindowRect(hWnd, &rect);
+ for(i = 0; i < nMoveChat; i++)
+ {
+ SetWindowPos(hWnd, 0, rect.left - nScaleChat, rect.top, 0, 0, SWP_NOSIZE);
+ Sleep(10);
+ SetWindowPos(hWnd, 0, rect.left, rect.top - nScaleChat, 0, 0, SWP_NOSIZE);
+ Sleep(10);
+ SetWindowPos(hWnd, 0, rect.left + nScaleChat, rect.top, 0, 0, SWP_NOSIZE);
+ Sleep(10);
+ SetWindowPos(hWnd, 0, rect.left, rect.top + nScaleChat, 0, 0, SWP_NOSIZE);
+ Sleep(10);
+ }
+ SetWindowPos(hWnd, 0, rect.left, rect.top, 0, 0, SWP_NOSIZE); //SWP_DRAWFRAME
+ ShakingChat = false;
+ }
+ return 0;
+}
+
+int CShake::ShakeClist(HWND hWnd)
+{
+ if(!Shaking)
+ {
+ Shaking = true;
+ int i;
+ RECT rect;
+ GetWindowRect(hWnd, &rect);
+ for(i = 0; i < nMoveClist; i++)
+ {
+ SetWindowPos(hWnd, 0, rect.left - nScaleClist, rect.top, 0, 0, SWP_NOSIZE);
+ Sleep(10);
+ SetWindowPos(hWnd, 0, rect.left, rect.top - nScaleClist, 0, 0, SWP_NOSIZE);
+ Sleep(10);
+ SetWindowPos(hWnd, 0, rect.left + nScaleClist, rect.top, 0, 0, SWP_NOSIZE);
+ Sleep(10);
+ SetWindowPos(hWnd, 0, rect.left, rect.top + nScaleClist, 0, 0, SWP_NOSIZE);
+ Sleep(10);
+ }
+ SetWindowPos(hWnd, 0, rect.left, rect.top, 0, 0, SWP_NOSIZE);
+ Shaking = false;
+ }
+ return 0;
+}
\ No newline at end of file diff --git a/nudge/shake.h b/nudge/shake.h new file mode 100644 index 0000000..73e460c --- /dev/null +++ b/nudge/shake.h @@ -0,0 +1,27 @@ +#ifndef SHAKE_H
+#define SHAKE_H
+
+class CShake
+{
+public:
+ bool Shaking;
+ bool ShakingChat;
+ int nScaleClist;
+ int nScaleChat;
+ int nMoveClist;
+ int nMoveChat;
+
+ void Load(void);
+ void Save(void);
+ int ShakeClist(HWND hWnd);
+ int ShakeChat(HWND hWnd);
+};
+
+INT_PTR ShakeClist(WPARAM,LPARAM);
+INT_PTR ShakeChat(WPARAM,LPARAM);
+/*
+int TriggerShakeChat(WPARAM,LPARAM);
+int TriggerShakeClist(WPARAM,LPARAM);
+int TriggerAction(WPARAM,LPARAM);*/
+
+#endif
\ No newline at end of file diff --git a/yamn/ChangeLog.txt b/yamn/ChangeLog.txt new file mode 100644 index 0000000..6a85810 --- /dev/null +++ b/yamn/ChangeLog.txt @@ -0,0 +1,243 @@ +0.1.2.5
+=======
+! fix many memory leaks patch by Merlin
+* x64 support by Merlin
+* Resource patch by mataes (for translations)
+
+0.1.2.4
+=======
+* Only show popup tab if popup plugin is present
+! Wrong time displayed in mailbrower (fix by y_b)
+
+0.1.2.3
+=======
+* New design for the options pages (Thanks Eyecue)
+
+0.1.2.2
+=======
+* using, with updater, the correct file id in file listing (yamn 2in1)
++ added folders plugin support
++ Support for miranda 0.8
+
+0.1.2.1
+=======
+! Don't close MailBrowser when e-mails are updated if it is manually open
++ Discard the new Event when message is shown or is deleted from the server
++ Option to disable the CList events per account
++ Contact status change also happens when e-mail are being deleted
+
+0.1.2.0
+=======
+! patch by TioDuke for icolib and status and status icons handling. Thanks!
+! code cleaning (properly destroy services and hooks)
++ Contact status changes accordingly the action (Ready, Working, Error)
+
+0.1.1.0
+=======
++ Show message is open in new thread
++ Click on individual new e-mail popups shows the message window
+
+0.1.0.2
+============
++ Pressing "Space" key will show the selected message
+! Delete message is done by DELETE key, not by '.'
+! removed some repeated code
+! "Ok" and "Select All" buttons in mail browser are translatable
+
+0.1.0.1
+============
++ Message body shown in separate edit box.
++ Support for Content-transfer-encoding: Quoted-Printable and base64
++ Recursive Content-type: multipart/ support
++ Option to auto retrieve body
+
+0.0.1.11
+============
++ Option to use yamn as a protocol.
+* Patch by Tioduke (code cleaning)
+! Fixed the crash parsing invalid "Date" header (SPAMs or silly e-mail client) (y_b)
+! ShowMessage dialog follows Content-type header to chose the codepage (y_b)
++ Only supported codepages are shown in the options (y_b)
++ Enhance codepages support (y_b)
+
+0.0.1.10
+============
+! Icons are based on single bitmap image (y_b)
+* Show full feaders on double click in mailbrowser (y_b)
+* Dates are shown localized and sorted correctly (y_b)
+* To show long/short date and seconds (y_b)
+! Solved a rare/random crash on unstable connection (y_b)
+! Enabled tabstop on new tabcontrol and reordered tabstop in option pages (y_b)
+* Enable TAB selection in mailbrowser dialog (patch by -pv-)
++ introducing 2in1 build - can be used both in win9x and NT/XP
+* Options redesign.
+
+0.0.1.9
+============
+* Patch by Perf (visual patch)
+
+0.0.1.8
+============
++ add ctr-A to select all mails
++ del key delete selected mail
++ add a select all button
+
+0.0.1.7
+============
+* Change options dialog (use tabsrmm uxtheme)
+! Invert back and text color for no new mail popup in option page.
+* New default icon reworked by Faith Healer.
+
+0.0.1.6
+============
+* Try to update all icons when changing in icolib.
+! Allow scrolling in list of email account. (Patch by Jazzy)
+! Memory leak in stls fix (y_b)
+
+0.0.1.5
+============
+! Bug fix with help.dll problem. (Patch by Jazzy)
+ (http://developer.berlios.de/bugs/?func=detailbug&bug_id=6692&group_id=3292)
+! Remove merge in agressiveoptimize.h
+
+0.0.1.4
+============
+! Option page bug (patch by y_b)
+* Allow to edit the application text
+
+0.0.1.3
+============
+! Bug fix with new icolib
+
+0.0.1.2
+============
+! Bug fix with updater and stable version
++ Using new m_icolib.h
++ New context menu entry to launch application
++ Patch by y_b
+{
+ + Start TLS support
+ + Better icolib support
+ + SSL Logging
+}
+
+0.0.1.1
+============
+! Bug fix on left click popup.
+
+0.0.1.0
+============
+Time for release.
+
+0.0.0.18
+============
+! Visual bug in option page
+! Recompilation for win 9x users.
+
+0.0.0.17
+============
+* Redesign option page to have only one entry in plugins options
+! Bug fix when there is no date set in the header (spam mails) (Thx Egres)
+
+0.0.0.16
+============
+* Right click on error popup close the popup.
+! Missing break; in nonewmail popup in switch.
++ Add option to rename contact according to new mail.
+! Patch by pescuma on delete accounts
+
+0.0.0.15
+============
+! Fixed dismiss event by right click on new mail popup crash
+* Change string for the status choose button
+! use CallServiceSync() instead of CallService() for adding clistevent (now icon blinks)
+
+0.0.0.14
+============
+! Tooltip on the clist event will now show correct text
+! Remove the messagebox on double clik on mail
+* Change options dialog add dialog for status choose.
+
+0.0.0.13
+============
++ Use of event count for the keyboard flashing
+
+0.0.0.12
+============
+- Remove message body retrieving due to bug.
+
+0.0.0.11
+============
++ Add a function to retrieve the whole mail source.
++ Show the mail source when double clicking on it in mail browser.
++ Add a version resource.
+
+0.0.0.10
+============
++ Now able to pass hContact handle to popup so can show avatar if set.
+* Change folder structure in svn SDK\import replace by include
+
+0.0.0.9
+============
++ Sorting asc and desc of the mail browser listview
++ Use the format yyyy-mm-dd hh:mm:ss for date comparaison in sorting
++ Doubleclick on list view to show the mail body but it seems to be empty :(
+
+0.0.0.8
+============
++ Add date field in mail browser
+* Modify the tooltip text for the clist event (add account name)
+* Rename Contact member of CAccount by hContact since it is an HANDLE
++ Updater support for BETA
+* Using the right headers (no more the one in SDK)
+
+0.0.0.7
+============
++ Added changelog txt file.
++ Check presence of icolib to choose the right icon to show in clist
++ Status message will show all message pending in mail box (until they get retrieve by your email client)
+
+0.0.0.6
+============
+* Options page redesign.
++ Right click on popup close the clist event too.
++ Update status message if no new mail.
++ Right click on popup^with no new mail close the popup.
+* No more delete of contact (avoid group affectation bug).
+
+0.0.0.5
+============
++ Add contact context menu entry to check for new mail.
++ Catch double click event on contact to shown the mail browser.
+
+0.0.0.4
+============
++ Add per account option to be show as contact or not.
++ Gestion de la suppression d'un compte
++ Use of the status message for showing number of emails.
++ Refresh yamn contact on the click on apply in options dialog.
+* Better condition for the ^contact loop (ouuppsss)
+
+0.0.0.3
+============
++ Now account are shown as a contact.
++ Source code modification and use of yamn.h
++ Wait the event moduleloaded before loading the icons (support icolib).
+
+0.0.0.2
+============
++ Use of patch by Q (From file listing) (Memory cleaning, empty mail browser even if there are mails, yamn freeze sometime)
++ Use of thread access function.
++ Possibility to change toptoolbar icons via icolib.
++ Icon in main menu entry (Asked by a7)
++ New Icons set by Manudevil.
++ Change version number to be compatible with updater plugin
+
+0.01
+============
+
++ icolib support.
++ keyboard flash support (just 10 sec) (thx TioDuke) needs Keyboard Notify Ext. 1.5.4.4
++ list of email can be sorted.
+* left click on popup shows email list.
+* better toptoolbar support.
\ No newline at end of file diff --git a/yamn/YAMN.dsp b/yamn/YAMN.dsp new file mode 100644 index 0000000..b8dc6f3 --- /dev/null +++ b/yamn/YAMN.dsp @@ -0,0 +1,376 @@ +# Microsoft Developer Studio Project File - Name="YAMN" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=YAMN - Win32 Release Win2in1
+!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 "YAMN.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 "YAMN.mak" CFG="YAMN - Win32 Release Win2in1"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "YAMN - Win32 Release Win2in1" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "YAMN - Win32 Debug Win2in1" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "YAMN - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "YAMN - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "YAMN - Win32 Release Win9x" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "YAMN - Win32 Debug Win9x" (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)" == "YAMN - Win32 Release Win2in1"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release\Win2in1"
+# PROP BASE Intermediate_Dir "Release\Win2in1"
+# PROP BASE Ignore_Export_Lib 1
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release\Win2in1"
+# PROP Intermediate_Dir "Release\Win2in1"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "WIN2IN1" /YX /FD /c
+# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../include" /I "../../include/msapi" /I "../../include_API" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "WIN2IN1" /FR /YX /FD /c
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /machine:I386 /out:"../../bin/release/plugins/YAMN.dll" /filealign:512
+# ADD LINK32 libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /pdb:"../../bin/release/plugins/yamn.pdb" /debug /machine:I386 /out:"../../bin/release/plugins/yamn.dll" /filealign:512
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug\Win2in1"
+# PROP BASE Intermediate_Dir "Debug\Win2in1"
+# PROP BASE Ignore_Export_Lib 1
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug\Win2in1"
+# PROP Intermediate_Dir "Debug\Win2in1"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN2IN1" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../include" /I "../../include/msapi" /I "../../include_API" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN2IN1" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x417 /d "_DEBUG"
+# ADD RSC /l 0x417 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/Debug/plugins/YAMN.dll"
+# ADD LINK32 libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /pdb:"../../bin/Debug/plugins/yamn.pdb" /debug /machine:I386 /out:"../../bin/Debug/plugins/yamn.dll" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release/WinNT"
+# PROP BASE Intermediate_Dir "Release/WinNT"
+# PROP BASE Ignore_Export_Lib 1
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release/WinNT"
+# PROP Intermediate_Dir "Release/WinNT"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../include" /I "../../include/msapi" /I "../../include_API" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE RSC /l 0x405 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /machine:I386 /out:"../../bin/release/plugins/YAMN-NT/YAMN.dll" /filealign:512
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/release/plugins/YAMN-NT/yamn.dll" /filealign:512
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug/WinNT"
+# PROP BASE Intermediate_Dir "Debug/WinNT"
+# PROP BASE Ignore_Export_Lib 1
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug/WinNT"
+# PROP Intermediate_Dir "Debug/WinNT"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../include" /I "../../include/msapi" /I "../../include_API" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x417 /d "_DEBUG"
+# ADD RSC /l 0x417 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/Debug/plugins/YAMN-NT/YAMN.dll"
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/Debug/plugins/YAMN-NT/YAMN.dll" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release\Win9x"
+# PROP BASE Intermediate_Dir "Release\Win9x"
+# PROP BASE Ignore_Export_Lib 1
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release\Win9x"
+# PROP Intermediate_Dir "Release\Win9x"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "WIN9X" /YX /FD /c
+# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../include" /I "../../include/msapi" /I "../../include_API" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "WIN9X" /YX /FD /c
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /machine:I386 /out:"../../bin/Release/plugins/YAMN-9x/YAMN.dll" /filealign:512
+# ADD LINK32 libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/Release/plugins/YAMN-9x/YAMN.dll" /filealign:512
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug\Win9x"
+# PROP BASE Intermediate_Dir "Debug\Win9x"
+# PROP BASE Ignore_Export_Lib 1
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug\Win9x"
+# PROP Intermediate_Dir "Debug\Win9x"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN9X" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../include" /I "../../include/msapi" /I "../../include_API" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN9X" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x417 /d "_DEBUG"
+# ADD RSC /l 0x417 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/Debug/plugins/YAMN-9x/YAMN.dll"
+# ADD LINK32 libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/Debug/plugins/YAMN-9x/YAMN.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "YAMN - Win32 Release Win2in1"
+# Name "YAMN - Win32 Debug Win2in1"
+# Name "YAMN - Win32 Release"
+# Name "YAMN - Win32 Debug"
+# Name "YAMN - Win32 Release Win9x"
+# Name "YAMN - Win32 Debug Win9x"
+# Begin Group "YAMN"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Group "Mail browser, dialogs"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\browser\badconnect.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\browser\mailbrowser.cpp
+# End Source File
+# End Group
+# Begin Group "Mails"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\mails\decode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mails\mails.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\mails\mime.cpp
+# End Source File
+# End Group
+# Begin Group "POP3 plugin"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\proto\md5.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\proto\netlib.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\proto\pop3\pop3.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\proto\pop3\pop3comm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\proto\pop3\pop3opt.cpp
+# End Source File
+# End Group
+# Begin Group "Header"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\debug.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\proto\pop3\pop3.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\proto\pop3\pop3comm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\proto\pop3\pop3opt.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\yamn.h
+# End Source File
+# End Group
+# Begin Group "include"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\include\IcoLib.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\include\m_kbdnotify.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\include\m_popup.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\include\m_toptoolbar.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\include\m_uninstaller.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\include\m_updater.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\account.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ChangeLog.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\debug.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\filterplugin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\main.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\protoplugin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\services.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\synchro.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\yamn.cpp
+# 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=.\resources\iconeutral.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resources\iconttbdown.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resources\icooffline.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resources\icoyamn3.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\resources\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resources\yamn.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\resources\YAMN.rc
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/yamn/YAMN.dsw b/yamn/YAMN.dsw new file mode 100644 index 0000000..ea0dcf1 --- /dev/null +++ b/yamn/YAMN.dsw @@ -0,0 +1,65 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "Base"=".\filter\Base\Base.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "YAMN"=".\YAMN.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "proto_YAMN"=".\icons\proto_YAMN.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "simple"=".\filter\simple\simple.dsp" - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/yamn/YAMN.mak b/yamn/YAMN.mak new file mode 100644 index 0000000..221fe20 --- /dev/null +++ b/yamn/YAMN.mak @@ -0,0 +1,1736 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on YAMN.dsp
+!IF "$(CFG)" == ""
+CFG=YAMN - Win32 Release Win2in1
+!MESSAGE No configuration specified. Defaulting to YAMN - Win32 Release Win2in1.
+!ENDIF
+
+!IF "$(CFG)" != "YAMN - Win32 Release Win2in1" && "$(CFG)" != "YAMN - Win32 Debug Win2in1" && "$(CFG)" != "YAMN - Win32 Release" && "$(CFG)" != "YAMN - Win32 Debug" && "$(CFG)" != "YAMN - Win32 Release Win9x" && "$(CFG)" != "YAMN - Win32 Debug Win9x"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!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 "YAMN.mak" CFG="YAMN - Win32 Release Win2in1"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "YAMN - Win32 Release Win2in1" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "YAMN - Win32 Debug Win2in1" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "YAMN - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "YAMN - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "YAMN - Win32 Release Win9x" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "YAMN - Win32 Debug Win9x" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+OUTDIR=.\Release\Win2in1
+INTDIR=.\Release\Win2in1
+# Begin Custom Macros
+OutDir=.\Release\Win2in1
+# End Custom Macros
+
+ALL : "..\..\bin\release\plugins\yamn.dll"
+
+
+
+CLEAN :
+ -@erase "$(INTDIR)\account.obj"
+ -@erase "$(INTDIR)\account.sbr"
+ -@erase "$(INTDIR)\badconnect.obj"
+ -@erase "$(INTDIR)\badconnect.sbr"
+ -@erase "$(INTDIR)\debug.obj"
+ -@erase "$(INTDIR)\debug.sbr"
+ -@erase "$(INTDIR)\decode.obj"
+ -@erase "$(INTDIR)\decode.sbr"
+ -@erase "$(INTDIR)\filterplugin.obj"
+ -@erase "$(INTDIR)\filterplugin.sbr"
+ -@erase "$(INTDIR)\mailbrowser.obj"
+ -@erase "$(INTDIR)\mailbrowser.sbr"
+ -@erase "$(INTDIR)\mails.obj"
+ -@erase "$(INTDIR)\mails.sbr"
+ -@erase "$(INTDIR)\main.obj"
+ -@erase "$(INTDIR)\main.sbr"
+ -@erase "$(INTDIR)\md5.obj"
+ -@erase "$(INTDIR)\md5.sbr"
+ -@erase "$(INTDIR)\mime.obj"
+ -@erase "$(INTDIR)\mime.sbr"
+ -@erase "$(INTDIR)\netlib.obj"
+ -@erase "$(INTDIR)\netlib.sbr"
+ -@erase "$(INTDIR)\pop3.obj"
+ -@erase "$(INTDIR)\pop3.sbr"
+ -@erase "$(INTDIR)\pop3comm.obj"
+ -@erase "$(INTDIR)\pop3comm.sbr"
+ -@erase "$(INTDIR)\pop3opt.obj"
+ -@erase "$(INTDIR)\pop3opt.sbr"
+ -@erase "$(INTDIR)\protoplugin.obj"
+ -@erase "$(INTDIR)\protoplugin.sbr"
+ -@erase "$(INTDIR)\services.obj"
+ -@erase "$(INTDIR)\services.sbr"
+ -@erase "$(INTDIR)\ssl.obj"
+ -@erase "$(INTDIR)\ssl.sbr"
+ -@erase "$(INTDIR)\synchro.obj"
+ -@erase "$(INTDIR)\synchro.sbr"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\yamn.obj"
+ -@erase "$(INTDIR)\YAMN.res"
+ -@erase "$(INTDIR)\yamn.sbr"
+ -@erase "$(OUTDIR)\YAMN.bsc"
+ -@erase "$(OUTDIR)\yamn.exp"
+ -@erase "..\..\bin\release\plugins\yamn.dll"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "WIN2IN1" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\YAMN.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=
+RSC=rc.exe
+RSC_PROJ=/l 0x417 /fo"$(INTDIR)\YAMN.res" /d "NDEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\YAMN.bsc"
+BSC32_SBRS= \
+ "$(INTDIR)\badconnect.sbr" \
+ "$(INTDIR)\mailbrowser.sbr" \
+ "$(INTDIR)\decode.sbr" \
+ "$(INTDIR)\mails.sbr" \
+ "$(INTDIR)\mime.sbr" \
+ "$(INTDIR)\md5.sbr" \
+ "$(INTDIR)\netlib.sbr" \
+ "$(INTDIR)\pop3.sbr" \
+ "$(INTDIR)\pop3comm.sbr" \
+ "$(INTDIR)\pop3opt.sbr" \
+ "$(INTDIR)\ssl.sbr" \
+ "$(INTDIR)\account.sbr" \
+ "$(INTDIR)\debug.sbr" \
+ "$(INTDIR)\filterplugin.sbr" \
+ "$(INTDIR)\main.sbr" \
+ "$(INTDIR)\protoplugin.sbr" \
+ "$(INTDIR)\services.sbr" \
+ "$(INTDIR)\synchro.sbr" \
+ "$(INTDIR)\yamn.sbr"
+
+"$(OUTDIR)\YAMN.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+LINK32_FLAGS=libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\yamn.pdb" /machine:I386 /out:"../../bin/release/plugins/yamn.dll" /implib:"$(OUTDIR)\yamn.lib" /filealign:512
+LINK32_OBJS= \
+ "$(INTDIR)\badconnect.obj" \
+ "$(INTDIR)\mailbrowser.obj" \
+ "$(INTDIR)\decode.obj" \
+ "$(INTDIR)\mails.obj" \
+ "$(INTDIR)\mime.obj" \
+ "$(INTDIR)\md5.obj" \
+ "$(INTDIR)\netlib.obj" \
+ "$(INTDIR)\pop3.obj" \
+ "$(INTDIR)\pop3comm.obj" \
+ "$(INTDIR)\pop3opt.obj" \
+ "$(INTDIR)\account.obj" \
+ "$(INTDIR)\debug.obj" \
+ "$(INTDIR)\filterplugin.obj" \
+ "$(INTDIR)\main.obj" \
+ "$(INTDIR)\protoplugin.obj" \
+ "$(INTDIR)\services.obj" \
+ "$(INTDIR)\synchro.obj" \
+ "$(INTDIR)\yamn.obj" \
+ "$(INTDIR)\YAMN.res"
+
+"..\..\bin\release\plugins\yamn.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+OUTDIR=.\Debug\Win2in1
+INTDIR=.\Debug\Win2in1
+# Begin Custom Macros
+OutDir=.\Debug\Win2in1
+# End Custom Macros
+
+ALL : "..\..\bin\Debug\plugins\YAMN.dll" "$(OUTDIR)\YAMN.bsc"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\account.obj"
+ -@erase "$(INTDIR)\account.sbr"
+ -@erase "$(INTDIR)\badconnect.obj"
+ -@erase "$(INTDIR)\badconnect.sbr"
+ -@erase "$(INTDIR)\debug.obj"
+ -@erase "$(INTDIR)\debug.sbr"
+ -@erase "$(INTDIR)\decode.obj"
+ -@erase "$(INTDIR)\decode.sbr"
+ -@erase "$(INTDIR)\filterplugin.obj"
+ -@erase "$(INTDIR)\filterplugin.sbr"
+ -@erase "$(INTDIR)\mailbrowser.obj"
+ -@erase "$(INTDIR)\mailbrowser.sbr"
+ -@erase "$(INTDIR)\mails.obj"
+ -@erase "$(INTDIR)\mails.sbr"
+ -@erase "$(INTDIR)\main.obj"
+ -@erase "$(INTDIR)\main.sbr"
+ -@erase "$(INTDIR)\md5.obj"
+ -@erase "$(INTDIR)\md5.sbr"
+ -@erase "$(INTDIR)\mime.obj"
+ -@erase "$(INTDIR)\mime.sbr"
+ -@erase "$(INTDIR)\netlib.obj"
+ -@erase "$(INTDIR)\netlib.sbr"
+ -@erase "$(INTDIR)\pop3.obj"
+ -@erase "$(INTDIR)\pop3.sbr"
+ -@erase "$(INTDIR)\pop3comm.obj"
+ -@erase "$(INTDIR)\pop3comm.sbr"
+ -@erase "$(INTDIR)\pop3opt.obj"
+ -@erase "$(INTDIR)\pop3opt.sbr"
+ -@erase "$(INTDIR)\protoplugin.obj"
+ -@erase "$(INTDIR)\protoplugin.sbr"
+ -@erase "$(INTDIR)\services.obj"
+ -@erase "$(INTDIR)\services.sbr"
+ -@erase "$(INTDIR)\synchro.obj"
+ -@erase "$(INTDIR)\synchro.sbr"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\vc60.pdb"
+ -@erase "$(INTDIR)\yamn.obj"
+ -@erase "$(INTDIR)\YAMN.res"
+ -@erase "$(INTDIR)\yamn.sbr"
+ -@erase "$(OUTDIR)\YAMN.bsc"
+ -@erase "$(OUTDIR)\YAMN.exp"
+ -@erase "$(OUTDIR)\YAMN.pdb"
+ -@erase "..\..\bin\Debug\plugins\YAMN.dll"
+ -@erase "..\..\bin\Debug\plugins\YAMN.ilk"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN2IN1" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\YAMN.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=
+RSC=rc.exe
+RSC_PROJ=/l 0x417 /fo"$(INTDIR)\YAMN.res" /d "_DEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\YAMN.bsc"
+BSC32_SBRS= \
+ "$(INTDIR)\badconnect.sbr" \
+ "$(INTDIR)\mailbrowser.sbr" \
+ "$(INTDIR)\decode.sbr" \
+ "$(INTDIR)\mails.sbr" \
+ "$(INTDIR)\mime.sbr" \
+ "$(INTDIR)\md5.sbr" \
+ "$(INTDIR)\netlib.sbr" \
+ "$(INTDIR)\pop3.sbr" \
+ "$(INTDIR)\pop3comm.sbr" \
+ "$(INTDIR)\pop3opt.sbr" \
+ "$(INTDIR)\account.sbr" \
+ "$(INTDIR)\debug.sbr" \
+ "$(INTDIR)\filterplugin.sbr" \
+ "$(INTDIR)\main.sbr" \
+ "$(INTDIR)\protoplugin.sbr" \
+ "$(INTDIR)\services.sbr" \
+ "$(INTDIR)\synchro.sbr" \
+ "$(INTDIR)\yamn.sbr"
+
+"$(OUTDIR)\YAMN.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+LINK32_FLAGS=libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /incremental:yes /pdb:"$(OUTDIR)\YAMN.pdb" /debug /machine:I386 /out:"../../bin/Debug/plugins/YAMN.dll" /implib:"$(OUTDIR)\YAMN.lib"
+LINK32_OBJS= \
+ "$(INTDIR)\badconnect.obj" \
+ "$(INTDIR)\mailbrowser.obj" \
+ "$(INTDIR)\decode.obj" \
+ "$(INTDIR)\mails.obj" \
+ "$(INTDIR)\mime.obj" \
+ "$(INTDIR)\md5.obj" \
+ "$(INTDIR)\netlib.obj" \
+ "$(INTDIR)\pop3.obj" \
+ "$(INTDIR)\pop3comm.obj" \
+ "$(INTDIR)\pop3opt.obj" \
+ "$(INTDIR)\account.obj" \
+ "$(INTDIR)\debug.obj" \
+ "$(INTDIR)\filterplugin.obj" \
+ "$(INTDIR)\main.obj" \
+ "$(INTDIR)\protoplugin.obj" \
+ "$(INTDIR)\services.obj" \
+ "$(INTDIR)\synchro.obj" \
+ "$(INTDIR)\yamn.obj" \
+ "$(INTDIR)\YAMN.res"
+
+"..\..\bin\Debug\plugins\YAMN.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+OUTDIR=.\Release/WinNT
+INTDIR=.\Release/WinNT
+
+ALL : "..\..\bin\release\plugins\YAMN-NT\yamn.dll"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\account.obj"
+ -@erase "$(INTDIR)\badconnect.obj"
+ -@erase "$(INTDIR)\debug.obj"
+ -@erase "$(INTDIR)\decode.obj"
+ -@erase "$(INTDIR)\filterplugin.obj"
+ -@erase "$(INTDIR)\mailbrowser.obj"
+ -@erase "$(INTDIR)\mails.obj"
+ -@erase "$(INTDIR)\main.obj"
+ -@erase "$(INTDIR)\md5.obj"
+ -@erase "$(INTDIR)\mime.obj"
+ -@erase "$(INTDIR)\netlib.obj"
+ -@erase "$(INTDIR)\pop3.obj"
+ -@erase "$(INTDIR)\pop3comm.obj"
+ -@erase "$(INTDIR)\pop3opt.obj"
+ -@erase "$(INTDIR)\protoplugin.obj"
+ -@erase "$(INTDIR)\services.obj"
+ -@erase "$(INTDIR)\synchro.obj"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\yamn.obj"
+ -@erase "$(INTDIR)\YAMN.res"
+ -@erase "$(OUTDIR)\yamn.exp"
+ -@erase "..\..\bin\release\plugins\YAMN-NT\yamn.dll"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\YAMN.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=
+RSC=rc.exe
+RSC_PROJ=/l 0x417 /fo"$(INTDIR)\YAMN.res" /d "NDEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\YAMN.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\yamn.pdb" /machine:I386 /out:"../../bin/release/plugins/YAMN-NT/yamn.dll" /implib:"$(OUTDIR)\yamn.lib" /filealign:512
+LINK32_OBJS= \
+ "$(INTDIR)\badconnect.obj" \
+ "$(INTDIR)\mailbrowser.obj" \
+ "$(INTDIR)\decode.obj" \
+ "$(INTDIR)\mails.obj" \
+ "$(INTDIR)\mime.obj" \
+ "$(INTDIR)\md5.obj" \
+ "$(INTDIR)\netlib.obj" \
+ "$(INTDIR)\pop3.obj" \
+ "$(INTDIR)\pop3comm.obj" \
+ "$(INTDIR)\pop3opt.obj" \
+ "$(INTDIR)\account.obj" \
+ "$(INTDIR)\debug.obj" \
+ "$(INTDIR)\filterplugin.obj" \
+ "$(INTDIR)\main.obj" \
+ "$(INTDIR)\protoplugin.obj" \
+ "$(INTDIR)\services.obj" \
+ "$(INTDIR)\synchro.obj" \
+ "$(INTDIR)\yamn.obj" \
+ "$(INTDIR)\YAMN.res"
+
+"..\..\bin\release\plugins\YAMN-NT\yamn.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+OUTDIR=.\Debug/WinNT
+INTDIR=.\Debug/WinNT
+# Begin Custom Macros
+OutDir=.\Debug/WinNT
+# End Custom Macros
+
+ALL : "..\..\bin\Debug\plugins\YAMN-NT\YAMN.dll" "$(OUTDIR)\YAMN.bsc"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\account.obj"
+ -@erase "$(INTDIR)\account.sbr"
+ -@erase "$(INTDIR)\badconnect.obj"
+ -@erase "$(INTDIR)\badconnect.sbr"
+ -@erase "$(INTDIR)\debug.obj"
+ -@erase "$(INTDIR)\debug.sbr"
+ -@erase "$(INTDIR)\decode.obj"
+ -@erase "$(INTDIR)\decode.sbr"
+ -@erase "$(INTDIR)\filterplugin.obj"
+ -@erase "$(INTDIR)\filterplugin.sbr"
+ -@erase "$(INTDIR)\mailbrowser.obj"
+ -@erase "$(INTDIR)\mailbrowser.sbr"
+ -@erase "$(INTDIR)\mails.obj"
+ -@erase "$(INTDIR)\mails.sbr"
+ -@erase "$(INTDIR)\main.obj"
+ -@erase "$(INTDIR)\main.sbr"
+ -@erase "$(INTDIR)\md5.obj"
+ -@erase "$(INTDIR)\md5.sbr"
+ -@erase "$(INTDIR)\mime.obj"
+ -@erase "$(INTDIR)\mime.sbr"
+ -@erase "$(INTDIR)\netlib.obj"
+ -@erase "$(INTDIR)\netlib.sbr"
+ -@erase "$(INTDIR)\pop3.obj"
+ -@erase "$(INTDIR)\pop3.sbr"
+ -@erase "$(INTDIR)\pop3comm.obj"
+ -@erase "$(INTDIR)\pop3comm.sbr"
+ -@erase "$(INTDIR)\pop3opt.obj"
+ -@erase "$(INTDIR)\pop3opt.sbr"
+ -@erase "$(INTDIR)\protoplugin.obj"
+ -@erase "$(INTDIR)\protoplugin.sbr"
+ -@erase "$(INTDIR)\services.obj"
+ -@erase "$(INTDIR)\services.sbr"
+ -@erase "$(INTDIR)\synchro.obj"
+ -@erase "$(INTDIR)\synchro.sbr"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\vc60.pdb"
+ -@erase "$(INTDIR)\yamn.obj"
+ -@erase "$(INTDIR)\YAMN.res"
+ -@erase "$(INTDIR)\yamn.sbr"
+ -@erase "$(OUTDIR)\YAMN.bsc"
+ -@erase "$(OUTDIR)\YAMN.exp"
+ -@erase "$(OUTDIR)\YAMN.pdb"
+ -@erase "..\..\bin\Debug\plugins\YAMN-NT\YAMN.dll"
+ -@erase "..\..\bin\Debug\plugins\YAMN-NT\YAMN.ilk"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\YAMN.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=
+RSC=rc.exe
+RSC_PROJ=/l 0x417 /fo"$(INTDIR)\YAMN.res" /d "_DEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\YAMN.bsc"
+BSC32_SBRS= \
+ "$(INTDIR)\badconnect.sbr" \
+ "$(INTDIR)\mailbrowser.sbr" \
+ "$(INTDIR)\decode.sbr" \
+ "$(INTDIR)\mails.sbr" \
+ "$(INTDIR)\mime.sbr" \
+ "$(INTDIR)\md5.sbr" \
+ "$(INTDIR)\netlib.sbr" \
+ "$(INTDIR)\pop3.sbr" \
+ "$(INTDIR)\pop3comm.sbr" \
+ "$(INTDIR)\pop3opt.sbr" \
+ "$(INTDIR)\account.sbr" \
+ "$(INTDIR)\debug.sbr" \
+ "$(INTDIR)\filterplugin.sbr" \
+ "$(INTDIR)\main.sbr" \
+ "$(INTDIR)\protoplugin.sbr" \
+ "$(INTDIR)\services.sbr" \
+ "$(INTDIR)\synchro.sbr" \
+ "$(INTDIR)\yamn.sbr"
+
+"$(OUTDIR)\YAMN.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /incremental:yes /pdb:"$(OUTDIR)\YAMN.pdb" /debug /machine:I386 /out:"../../bin/Debug/plugins/YAMN-NT/YAMN.dll" /implib:"$(OUTDIR)\YAMN.lib"
+LINK32_OBJS= \
+ "$(INTDIR)\badconnect.obj" \
+ "$(INTDIR)\mailbrowser.obj" \
+ "$(INTDIR)\decode.obj" \
+ "$(INTDIR)\mails.obj" \
+ "$(INTDIR)\mime.obj" \
+ "$(INTDIR)\md5.obj" \
+ "$(INTDIR)\netlib.obj" \
+ "$(INTDIR)\pop3.obj" \
+ "$(INTDIR)\pop3comm.obj" \
+ "$(INTDIR)\pop3opt.obj" \
+ "$(INTDIR)\account.obj" \
+ "$(INTDIR)\debug.obj" \
+ "$(INTDIR)\filterplugin.obj" \
+ "$(INTDIR)\main.obj" \
+ "$(INTDIR)\protoplugin.obj" \
+ "$(INTDIR)\services.obj" \
+ "$(INTDIR)\synchro.obj" \
+ "$(INTDIR)\yamn.obj" \
+ "$(INTDIR)\YAMN.res"
+
+"..\..\bin\Debug\plugins\YAMN-NT\YAMN.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+OUTDIR=.\Release\Win9x
+INTDIR=.\Release\Win9x
+
+ALL : "..\..\bin\Release\plugins\YAMN-9x\YAMN.dll"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\account.obj"
+ -@erase "$(INTDIR)\badconnect.obj"
+ -@erase "$(INTDIR)\debug.obj"
+ -@erase "$(INTDIR)\decode.obj"
+ -@erase "$(INTDIR)\filterplugin.obj"
+ -@erase "$(INTDIR)\mailbrowser.obj"
+ -@erase "$(INTDIR)\mails.obj"
+ -@erase "$(INTDIR)\main.obj"
+ -@erase "$(INTDIR)\md5.obj"
+ -@erase "$(INTDIR)\mime.obj"
+ -@erase "$(INTDIR)\netlib.obj"
+ -@erase "$(INTDIR)\pop3.obj"
+ -@erase "$(INTDIR)\pop3comm.obj"
+ -@erase "$(INTDIR)\pop3opt.obj"
+ -@erase "$(INTDIR)\protoplugin.obj"
+ -@erase "$(INTDIR)\services.obj"
+ -@erase "$(INTDIR)\synchro.obj"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\yamn.obj"
+ -@erase "$(INTDIR)\YAMN.res"
+ -@erase "$(OUTDIR)\YAMN.exp"
+ -@erase "..\..\bin\Release\plugins\YAMN-9x\YAMN.dll"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "WIN9X" /Fp"$(INTDIR)\YAMN.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=
+RSC=rc.exe
+RSC_PROJ=/l 0x417 /fo"$(INTDIR)\YAMN.res" /d "NDEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\YAMN.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\YAMN.pdb" /machine:I386 /out:"../../bin/Release/plugins/YAMN-9x/YAMN.dll" /implib:"$(OUTDIR)\YAMN.lib" /filealign:512
+LINK32_OBJS= \
+ "$(INTDIR)\badconnect.obj" \
+ "$(INTDIR)\mailbrowser.obj" \
+ "$(INTDIR)\decode.obj" \
+ "$(INTDIR)\mails.obj" \
+ "$(INTDIR)\mime.obj" \
+ "$(INTDIR)\md5.obj" \
+ "$(INTDIR)\netlib.obj" \
+ "$(INTDIR)\pop3.obj" \
+ "$(INTDIR)\pop3comm.obj" \
+ "$(INTDIR)\pop3opt.obj" \
+ "$(INTDIR)\account.obj" \
+ "$(INTDIR)\debug.obj" \
+ "$(INTDIR)\filterplugin.obj" \
+ "$(INTDIR)\main.obj" \
+ "$(INTDIR)\protoplugin.obj" \
+ "$(INTDIR)\services.obj" \
+ "$(INTDIR)\synchro.obj" \
+ "$(INTDIR)\yamn.obj" \
+ "$(INTDIR)\YAMN.res"
+
+"..\..\bin\Release\plugins\YAMN-9x\YAMN.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+OUTDIR=.\Debug\Win9x
+INTDIR=.\Debug\Win9x
+# Begin Custom Macros
+OutDir=.\Debug\Win9x
+# End Custom Macros
+
+ALL : "..\..\bin\Debug\plugins\YAMN-9x\YAMN.dll" "$(OUTDIR)\YAMN.bsc"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\account.obj"
+ -@erase "$(INTDIR)\account.sbr"
+ -@erase "$(INTDIR)\badconnect.obj"
+ -@erase "$(INTDIR)\badconnect.sbr"
+ -@erase "$(INTDIR)\debug.obj"
+ -@erase "$(INTDIR)\debug.sbr"
+ -@erase "$(INTDIR)\decode.obj"
+ -@erase "$(INTDIR)\decode.sbr"
+ -@erase "$(INTDIR)\filterplugin.obj"
+ -@erase "$(INTDIR)\filterplugin.sbr"
+ -@erase "$(INTDIR)\mailbrowser.obj"
+ -@erase "$(INTDIR)\mailbrowser.sbr"
+ -@erase "$(INTDIR)\mails.obj"
+ -@erase "$(INTDIR)\mails.sbr"
+ -@erase "$(INTDIR)\main.obj"
+ -@erase "$(INTDIR)\main.sbr"
+ -@erase "$(INTDIR)\md5.obj"
+ -@erase "$(INTDIR)\md5.sbr"
+ -@erase "$(INTDIR)\mime.obj"
+ -@erase "$(INTDIR)\mime.sbr"
+ -@erase "$(INTDIR)\netlib.obj"
+ -@erase "$(INTDIR)\netlib.sbr"
+ -@erase "$(INTDIR)\pop3.obj"
+ -@erase "$(INTDIR)\pop3.sbr"
+ -@erase "$(INTDIR)\pop3comm.obj"
+ -@erase "$(INTDIR)\pop3comm.sbr"
+ -@erase "$(INTDIR)\pop3opt.obj"
+ -@erase "$(INTDIR)\pop3opt.sbr"
+ -@erase "$(INTDIR)\protoplugin.obj"
+ -@erase "$(INTDIR)\protoplugin.sbr"
+ -@erase "$(INTDIR)\services.obj"
+ -@erase "$(INTDIR)\services.sbr"
+ -@erase "$(INTDIR)\synchro.obj"
+ -@erase "$(INTDIR)\synchro.sbr"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\vc60.pdb"
+ -@erase "$(INTDIR)\yamn.obj"
+ -@erase "$(INTDIR)\YAMN.res"
+ -@erase "$(INTDIR)\yamn.sbr"
+ -@erase "$(OUTDIR)\YAMN.bsc"
+ -@erase "$(OUTDIR)\YAMN.exp"
+ -@erase "$(OUTDIR)\YAMN.pdb"
+ -@erase "..\..\bin\Debug\plugins\YAMN-9x\YAMN.dll"
+ -@erase "..\..\bin\Debug\plugins\YAMN-9x\YAMN.ilk"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN9X" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\YAMN.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=
+RSC=rc.exe
+RSC_PROJ=/l 0x417 /fo"$(INTDIR)\YAMN.res" /d "_DEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\YAMN.bsc"
+BSC32_SBRS= \
+ "$(INTDIR)\badconnect.sbr" \
+ "$(INTDIR)\mailbrowser.sbr" \
+ "$(INTDIR)\decode.sbr" \
+ "$(INTDIR)\mails.sbr" \
+ "$(INTDIR)\mime.sbr" \
+ "$(INTDIR)\md5.sbr" \
+ "$(INTDIR)\netlib.sbr" \
+ "$(INTDIR)\pop3.sbr" \
+ "$(INTDIR)\pop3comm.sbr" \
+ "$(INTDIR)\pop3opt.sbr" \
+ "$(INTDIR)\account.sbr" \
+ "$(INTDIR)\debug.sbr" \
+ "$(INTDIR)\filterplugin.sbr" \
+ "$(INTDIR)\main.sbr" \
+ "$(INTDIR)\protoplugin.sbr" \
+ "$(INTDIR)\services.sbr" \
+ "$(INTDIR)\synchro.sbr" \
+ "$(INTDIR)\yamn.sbr"
+
+"$(OUTDIR)\YAMN.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+LINK32_FLAGS=libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib /nologo /base:"0x60010000" /subsystem:windows /dll /incremental:yes /pdb:"$(OUTDIR)\YAMN.pdb" /debug /machine:I386 /out:"../../bin/Debug/plugins/YAMN-9x/YAMN.dll" /implib:"$(OUTDIR)\YAMN.lib"
+LINK32_OBJS= \
+ "$(INTDIR)\badconnect.obj" \
+ "$(INTDIR)\mailbrowser.obj" \
+ "$(INTDIR)\decode.obj" \
+ "$(INTDIR)\mails.obj" \
+ "$(INTDIR)\mime.obj" \
+ "$(INTDIR)\md5.obj" \
+ "$(INTDIR)\netlib.obj" \
+ "$(INTDIR)\pop3.obj" \
+ "$(INTDIR)\pop3comm.obj" \
+ "$(INTDIR)\pop3opt.obj" \
+ "$(INTDIR)\account.obj" \
+ "$(INTDIR)\debug.obj" \
+ "$(INTDIR)\filterplugin.obj" \
+ "$(INTDIR)\main.obj" \
+ "$(INTDIR)\protoplugin.obj" \
+ "$(INTDIR)\services.obj" \
+ "$(INTDIR)\synchro.obj" \
+ "$(INTDIR)\yamn.obj" \
+ "$(INTDIR)\YAMN.res"
+
+"..\..\bin\Debug\plugins\YAMN-9x\YAMN.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("YAMN.dep")
+!INCLUDE "YAMN.dep"
+!ELSE
+!MESSAGE Warning: cannot find "YAMN.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1" || "$(CFG)" == "YAMN - Win32 Debug Win2in1" || "$(CFG)" == "YAMN - Win32 Release" || "$(CFG)" == "YAMN - Win32 Debug" || "$(CFG)" == "YAMN - Win32 Release Win9x" || "$(CFG)" == "YAMN - Win32 Debug Win9x"
+SOURCE=.\browser\badconnect.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\badconnect.obj" "$(INTDIR)\badconnect.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\badconnect.obj" "$(INTDIR)\badconnect.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\badconnect.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\badconnect.obj" "$(INTDIR)\badconnect.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\badconnect.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\badconnect.obj" "$(INTDIR)\badconnect.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\browser\mailbrowser.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\mailbrowser.obj" "$(INTDIR)\mailbrowser.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\mailbrowser.obj" "$(INTDIR)\mailbrowser.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\mailbrowser.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\mailbrowser.obj" "$(INTDIR)\mailbrowser.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\mailbrowser.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\mailbrowser.obj" "$(INTDIR)\mailbrowser.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mails\decode.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\decode.obj" "$(INTDIR)\decode.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\decode.obj" "$(INTDIR)\decode.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\decode.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\decode.obj" "$(INTDIR)\decode.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\decode.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\decode.obj" "$(INTDIR)\decode.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mails\mails.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\mails.obj" "$(INTDIR)\mails.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\mails.obj" "$(INTDIR)\mails.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\mails.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\mails.obj" "$(INTDIR)\mails.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\mails.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\mails.obj" "$(INTDIR)\mails.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\mails\mime.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\mime.obj" "$(INTDIR)\mime.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\mime.obj" "$(INTDIR)\mime.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\mime.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\mime.obj" "$(INTDIR)\mime.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\mime.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\mime.obj" "$(INTDIR)\mime.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\proto\md5.c
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\md5.obj" "$(INTDIR)\md5.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\md5.obj" "$(INTDIR)\md5.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\md5.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\md5.obj" "$(INTDIR)\md5.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\md5.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\md5.obj" "$(INTDIR)\md5.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\proto\netlib.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\netlib.obj" "$(INTDIR)\netlib.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\netlib.obj" "$(INTDIR)\netlib.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\netlib.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\netlib.obj" "$(INTDIR)\netlib.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\netlib.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\netlib.obj" "$(INTDIR)\netlib.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\proto\pop3\pop3.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\pop3.obj" "$(INTDIR)\pop3.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\pop3.obj" "$(INTDIR)\pop3.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\pop3.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\pop3.obj" "$(INTDIR)\pop3.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\pop3.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\pop3.obj" "$(INTDIR)\pop3.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\proto\pop3\pop3comm.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\pop3comm.obj" "$(INTDIR)\pop3comm.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\pop3comm.obj" "$(INTDIR)\pop3comm.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\pop3comm.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\pop3comm.obj" "$(INTDIR)\pop3comm.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\pop3comm.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\pop3comm.obj" "$(INTDIR)\pop3comm.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\proto\pop3\pop3opt.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\pop3opt.obj" "$(INTDIR)\pop3opt.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\pop3opt.obj" "$(INTDIR)\pop3opt.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\pop3opt.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\pop3opt.obj" "$(INTDIR)\pop3opt.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\pop3opt.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\pop3opt.obj" "$(INTDIR)\pop3opt.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\proto\ssl.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\ssl.obj" "$(INTDIR)\ssl.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\ssl.obj" "$(INTDIR)\ssl.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\ssl.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\ssl.obj" "$(INTDIR)\ssl.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\ssl.obj" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\ssl.obj" "$(INTDIR)\ssl.sbr" : $(SOURCE) "$(INTDIR)"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+!ENDIF
+
+SOURCE=.\account.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\account.obj" "$(INTDIR)\account.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\account.obj" "$(INTDIR)\account.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\account.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\account.obj" "$(INTDIR)\account.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\account.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\account.obj" "$(INTDIR)\account.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+SOURCE=.\debug.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\debug.obj" "$(INTDIR)\debug.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\debug.obj" "$(INTDIR)\debug.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\debug.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\debug.obj" "$(INTDIR)\debug.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\debug.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\debug.obj" "$(INTDIR)\debug.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+SOURCE=.\filterplugin.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\filterplugin.obj" "$(INTDIR)\filterplugin.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\filterplugin.obj" "$(INTDIR)\filterplugin.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\filterplugin.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\filterplugin.obj" "$(INTDIR)\filterplugin.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\filterplugin.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\filterplugin.obj" "$(INTDIR)\filterplugin.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+SOURCE=.\main.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\main.obj" "$(INTDIR)\main.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\main.obj" "$(INTDIR)\main.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\main.obj" "$(INTDIR)\main.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\main.obj" "$(INTDIR)\main.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+SOURCE=.\protoplugin.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\protoplugin.obj" "$(INTDIR)\protoplugin.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\protoplugin.obj" "$(INTDIR)\protoplugin.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\protoplugin.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\protoplugin.obj" "$(INTDIR)\protoplugin.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\protoplugin.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\protoplugin.obj" "$(INTDIR)\protoplugin.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+SOURCE=.\services.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\services.obj" "$(INTDIR)\services.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\services.obj" "$(INTDIR)\services.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\services.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\services.obj" "$(INTDIR)\services.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\services.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\services.obj" "$(INTDIR)\services.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+SOURCE=.\synchro.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\synchro.obj" "$(INTDIR)\synchro.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\synchro.obj" "$(INTDIR)\synchro.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\synchro.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\synchro.obj" "$(INTDIR)\synchro.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\synchro.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\synchro.obj" "$(INTDIR)\synchro.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+SOURCE=.\yamn.cpp
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\yamn.obj" "$(INTDIR)\yamn.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\yamn.obj" "$(INTDIR)\yamn.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\yamn.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\yamn.obj" "$(INTDIR)\yamn.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\yamn.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\yamn.obj" "$(INTDIR)\yamn.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+SOURCE=.\resources\YAMN.rc
+
+!IF "$(CFG)" == "YAMN - Win32 Release Win2in1"
+
+
+"$(INTDIR)\YAMN.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x417 /fo"$(INTDIR)\YAMN.res" /i "resources" /d "NDEBUG" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win2in1"
+
+
+"$(INTDIR)\YAMN.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x417 /fo"$(INTDIR)\YAMN.res" /i "resources" /d "_DEBUG" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release"
+
+
+"$(INTDIR)\YAMN.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x417 /fo"$(INTDIR)\YAMN.res" /i "resources" /d "NDEBUG" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug"
+
+
+"$(INTDIR)\YAMN.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x417 /fo"$(INTDIR)\YAMN.res" /i "resources" /d "_DEBUG" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Release Win9x"
+
+
+"$(INTDIR)\YAMN.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x417 /fo"$(INTDIR)\YAMN.res" /i "resources" /d "NDEBUG" $(SOURCE)
+
+
+!ELSEIF "$(CFG)" == "YAMN - Win32 Debug Win9x"
+
+
+"$(INTDIR)\YAMN.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) /l 0x417 /fo"$(INTDIR)\YAMN.res" /i "resources" /d "_DEBUG" $(SOURCE)
+
+
+!ENDIF
+
+
+!ENDIF
+
diff --git a/yamn/YAMN.vcproj b/yamn/YAMN.vcproj new file mode 100644 index 0000000..7406854 --- /dev/null +++ b/yamn/YAMN.vcproj @@ -0,0 +1,1593 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="YAMN"
+ ProjectGUID="{8F13F353-8DEC-4E87-AD17-EFA427425B29}"
+ RootNamespace="YAMN"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ 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/YAMN.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../include"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;YAMN_DEBUG"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile=".\Debug/YAMN.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1029"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="odbc32.lib odbccp32.lib ws2_32.lib msvcrt.lib comctl32.lib"
+ OutputFile="$(OutDir)\$(ProjectName).dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ IgnoreAllDefaultLibraries="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug/YAMN.pdb"
+ GenerateMapFile="true"
+ MapFileName=".\Debug/YAMN.map"
+ BaseAddress="0x60010000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary=".\Debug/YAMN.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Win9x|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <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\Win9x/YAMN.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="../../../include"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile=".\Release\Win9x/YAMN.pch"
+ AssemblerListingLocation=".\Release\Win9x/"
+ ObjectFile=".\Release\Win9x/"
+ ProgramDataBaseFileName=".\Release\Win9x/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1029"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/filealign:512"
+ AdditionalDependencies="./libs/unicows.lib ws2_32.lib msvcrt.lib"
+ OutputFile="$(OutDir)\$(ProjectName).dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ IgnoreAllDefaultLibraries="true"
+ ProgramDatabaseFile=".\Release\Win9x/YAMN.pdb"
+ SubSystem="2"
+ BaseAddress="0x60020000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary=".\Release\Win9x/YAMN.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="../../tweety_bin9/Release Unicode/Plugins"
+ IntermediateDirectory="../../tweety_bin9/Release Unicode/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ >
+ <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/YAMN.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="../../include"
+ PreprocessorDefinitions="WIN32,NDEBUG,_WINDOWS,WIN2IN1"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile=".\Release/YAMN.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1029"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib msvcrt.lib libs/unicows.lib kernel32.lib user32.lib gdi32.lib comctl32.lib comdlg32.lib shell32.lib wsock32.lib "
+ OutputFile="$(OutDir)/YAMN.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ IgnoreAllDefaultLibraries="true"
+ ProgramDatabaseFile="$(OutDir)/YAMN.pdb"
+ SubSystem="2"
+ BaseAddress=""
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(OutDir)/YAMN.lib"
+ MergeSections=""
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug Win9x|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)/Plugins"
+ IntermediateDirectory="$(SolutionDir)$(ConfigurationName)/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ 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\Win9x/YAMN.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../include"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile=".\Debug\Win9x/YAMN.pch"
+ AssemblerListingLocation=".\Debug\Win9x/"
+ ObjectFile=".\Debug\Win9x/"
+ ProgramDataBaseFileName=".\Debug\Win9x/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1029"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="odbc32.lib odbccp32.lib ws2_32.lib msvcrt.lib"
+ OutputFile="$(OutDir)\$(ProjectName).dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ IgnoreAllDefaultLibraries="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug\Win9x/YAMN.pdb"
+ BaseAddress="0x60020000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary=".\Debug\Win9x/YAMN.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="YAMN"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="account.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="ChangeLog.txt"
+ >
+ </File>
+ <File
+ RelativePath="debug.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="filterplugin.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="main.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="protoplugin.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="services.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="synchro.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="yamn.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <Filter
+ Name="Mail browser, dialogs"
+ >
+ <File
+ RelativePath="browser\badconnect.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="browser\mailbrowser.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Mails"
+ >
+ <File
+ RelativePath="mails\decode.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="mails\mails.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="mails\mime.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="POP3 plugin"
+ >
+ <File
+ RelativePath="proto\md5.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="proto\netlib.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="proto\pop3\pop3.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="proto\pop3\pop3comm.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="proto\pop3\pop3opt.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;YAMN_DEBUG;$(NoInherit)"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA;$(NoInherit)"
+ BasicRuntimeChecks="3"
+ BrowseInformation="1"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Header"
+ >
+ <File
+ RelativePath="debug.h"
+ >
+ </File>
+ <File
+ RelativePath="main.h"
+ >
+ </File>
+ <File
+ RelativePath="proto\pop3\pop3.h"
+ >
+ </File>
+ <File
+ RelativePath="proto\pop3\pop3comm.h"
+ >
+ </File>
+ <File
+ RelativePath="proto\pop3\pop3opt.h"
+ >
+ </File>
+ <File
+ RelativePath="yamn.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="include"
+ >
+ <File
+ RelativePath="include\IcoLib.h"
+ >
+ </File>
+ <File
+ RelativePath="include\m_kbdnotify.h"
+ >
+ </File>
+ <File
+ RelativePath="include\m_popup.h"
+ >
+ </File>
+ <File
+ RelativePath="include\m_toptoolbar.h"
+ >
+ </File>
+ <File
+ RelativePath="include\m_uninstaller.h"
+ >
+ </File>
+ <File
+ RelativePath="include\m_updater.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ <File
+ RelativePath="resources\bmttb.bmp"
+ >
+ </File>
+ <File
+ RelativePath="resources\icon1.ico"
+ >
+ </File>
+ <File
+ RelativePath="resources\iconeutral.ico"
+ >
+ </File>
+ <File
+ RelativePath="resources\iconttb.ico"
+ >
+ </File>
+ <File
+ RelativePath="resources\iconttbdown.ico"
+ >
+ </File>
+ <File
+ RelativePath="resources\iconttbup.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\resources\icooffline.ico"
+ >
+ </File>
+ <File
+ RelativePath="resources\icoyamn1.ico"
+ >
+ </File>
+ <File
+ RelativePath="resources\icoyamn2.ico"
+ >
+ </File>
+ <File
+ RelativePath="resources\icoyamn3.ico"
+ >
+ </File>
+ <File
+ RelativePath="resources\ttbcheck.ico"
+ >
+ </File>
+ <File
+ RelativePath="resources\ttbfcheck.bmp"
+ >
+ </File>
+ <File
+ RelativePath=".\resources\yamn.bmp"
+ >
+ </File>
+ <File
+ RelativePath="resources\YAMN.rc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ AdditionalIncludeDirectories="resources"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Win9x|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ AdditionalIncludeDirectories="resources"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release Unicode|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ AdditionalIncludeDirectories="resources"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug Win9x|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ AdditionalIncludeDirectories="resources"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Documentation"
+ >
+ <File
+ RelativePath="docs\changelog.txt"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="docs\language.pop3.txt"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="docs\language.txt"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="docs\YAMN-License.txt"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="docs\YAMN-Readme.developers.txt"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="docs\YAMN-Readme.txt"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ ExcludedFromBuild="true"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/yamn/YAMN_9.vcproj b/yamn/YAMN_9.vcproj new file mode 100644 index 0000000..1178eae --- /dev/null +++ b/yamn/YAMN_9.vcproj @@ -0,0 +1,915 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="_YAMN"
+ ProjectGUID="{C5A87409-F08C-4A07-A8F9-1F5D52BA6D72}"
+ RootNamespace="yamn"
+ TargetFrameworkVersion="0"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug Unicode|Win32"
+ OutputDirectory="$(SolutionDir)Debug 2in1/Plugins"
+ IntermediateDirectory="$(SolutionDir)Debug 2in1/Obj/$(ProjectName)/YAMN-2in1"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ DeleteExtensionsOnClean="*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pch;*.pgc;*.pgd;*.meta;$(TargetPath);$(TargetDir)$(ProjectName).*;$(TargetDir)$(RootNamespace).*"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include;../../include_API"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;_DEBUG;YAMN_DEBUG"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ StructMemberAlignment="3"
+ AssemblerListingLocation=""
+ ObjectFile="$(IntDir)/"
+ ProgramDataBaseFileName="$(IntDir)/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="./libs/unicows.lib comctl32.lib wsock32.lib"
+ OutputFile="$(OutDir)\$(RootNamespace).dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ BaseAddress="0x60010000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ OutputFile="$(OutDir)/$(TargetName).bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug Unicode|x64"
+ OutputDirectory="$(SolutionDir)Debug Unicode64/Plugins"
+ IntermediateDirectory="$(SolutionDir)Debug Unicode64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ DeleteExtensionsOnClean="*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pch;*.pgc;*.pgd;*.meta;$(TargetPath);$(TargetDir)$(ProjectName).*;$(TargetDir)$(RootNamespace).*"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include;../../include_API"
+ PreprocessorDefinitions="WIN32;_WINDOWS;_USRDLL;_DEBUG;YAMN_DEBUG"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ AssemblerListingLocation=""
+ ObjectFile="$(IntDir)/"
+ ProgramDataBaseFileName="$(IntDir)/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib wsock32.lib"
+ OutputFile="$(OutDir)\$(RootNamespace).dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ BaseAddress="0x60010000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ OutputFile="$(OutDir)/$(TargetName).bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)Release 2in1/Plugins/YAMN-9x"
+ IntermediateDirectory="$(SolutionDir)Release 2in1/Obj/$(ProjectName)/YAMN-9x"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ DeleteExtensionsOnClean="*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pch;*.pgc;*.pgd;*.meta;$(TargetPath);$(TargetDir)$(ProjectName).*;$(TargetDir)$(RootNamespace).*"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="0"
+ AdditionalIncludeDirectories="../../include;../../include_API"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN9X"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ StructMemberAlignment="3"
+ EnableFunctionLevelLinking="true"
+ AssemblerListingLocation=""
+ ObjectFile="$(IntDir)/"
+ ProgramDataBaseFileName="$(IntDir)/"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/filealign:512"
+ AdditionalDependencies="./libs/unicows.lib comctl32.lib wsock32.lib"
+ OutputFile="$(OutDir)\$(RootNamespace).dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ BaseAddress="0x60010000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ OutputFile="$(OutDir)/$(TargetName).bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)Release64/Plugins"
+ IntermediateDirectory="$(SolutionDir)Release64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ DeleteExtensionsOnClean="*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pch;*.pgc;*.pgd;*.meta;$(TargetPath);$(TargetDir)$(ProjectName).*;$(TargetDir)$(RootNamespace).*"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="0"
+ AdditionalIncludeDirectories="../../include;../../include_API"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;WIN9X;_USRDLL"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ AssemblerListingLocation=""
+ ObjectFile="$(IntDir)/"
+ ProgramDataBaseFileName="$(IntDir)/"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/filealign:512"
+ AdditionalDependencies="comctl32.lib wsock32.lib"
+ OutputFile="$(OutDir)\$(RootNamespace).dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ BaseAddress="0x60010000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ OutputFile="$(OutDir)/$(TargetName).bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|Win32"
+ OutputDirectory="$(SolutionDir)Release 2in1/Plugins"
+ IntermediateDirectory="$(SolutionDir)Release 2in1/Obj/$(ProjectName)/YAMN-2in1"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ DeleteExtensionsOnClean="*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pch;*.pgc;*.pgd;*.meta;$(TargetPath);$(TargetDir)$(ProjectName).*;$(TargetDir)$(RootNamespace).*"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="0"
+ AdditionalIncludeDirectories="../../include;../../include_API"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN2IN1;_CRT_SECURE_NO_WARNINGS"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ StructMemberAlignment="3"
+ EnableFunctionLevelLinking="true"
+ AssemblerListingLocation=""
+ ObjectFile="$(IntDir)/"
+ ProgramDataBaseFileName="$(IntDir)/"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="./libs/unicows.lib comctl32.lib wsock32.lib"
+ OutputFile="$(OutDir)\$(RootNamespace).dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ BaseAddress="0x60010000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ OutputFile="$(OutDir)/$(TargetName).bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release Unicode|x64"
+ OutputDirectory="$(SolutionDir)Release Unicode64/Plugins"
+ IntermediateDirectory="$(SolutionDir)Release Unicode64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ DeleteExtensionsOnClean="*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pch;*.pgc;*.pgd;*.meta;$(TargetPath);$(TargetDir)$(ProjectName).*;$(TargetDir)$(RootNamespace).*"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="1"
+ InlineFunctionExpansion="0"
+ AdditionalIncludeDirectories="../../include;../../include_API"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;WIN2IN1;_CRT_SECURE_NO_WARNINGS"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ AssemblerListingLocation=""
+ ObjectFile="$(IntDir)/"
+ ProgramDataBaseFileName="$(IntDir)/"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib wsock32.lib"
+ OutputFile="$(OutDir)\$(RootNamespace).dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ BaseAddress="0x60010000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ OutputFile="$(OutDir)/$(TargetName).bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)Debug 2in1/Plugins/YAMN-9x"
+ IntermediateDirectory="$(SolutionDir)Debug 2in1/Obj/$(ProjectName)/YAMN-9x"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ DeleteExtensionsOnClean="*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pch;*.pgc;*.pgd;*.meta;$(TargetPath);$(TargetDir)$(ProjectName).*;$(TargetDir)$(RootNamespace).*"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include;../../include_API"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ StructMemberAlignment="3"
+ AssemblerListingLocation=""
+ ObjectFile="$(IntDir)/"
+ ProgramDataBaseFileName="$(IntDir)/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="./libs/unicows.lib comctl32.lib wsock32.lib"
+ OutputFile="$(OutDir)\$(RootNamespace).dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ BaseAddress="0x60010000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ OutputFile="$(OutDir)/$(TargetName).bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)Debug64/Plugins"
+ IntermediateDirectory="$(SolutionDir)Debug64/Obj/$(ProjectName)"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ DeleteExtensionsOnClean="*.obj;*.ilk;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pch;*.pgc;*.pgd;*.meta;$(TargetPath);$(TargetDir)$(ProjectName).*;$(TargetDir)$(RootNamespace).*"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include;../../include_API"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;YAMN_DEBUG;WIN9X;YAMN_VER_BETA"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ AssemblerListingLocation=""
+ ObjectFile="$(IntDir)/"
+ ProgramDataBaseFileName="$(IntDir)/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ DisableSpecificWarnings="4996"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1033"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="comctl32.lib wsock32.lib"
+ OutputFile="$(OutDir)\$(RootNamespace).dll"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ BaseAddress="0x60010000"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ ImportLibrary="$(IntDir)/$(TargetName).lib"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ OutputFile="$(OutDir)/$(TargetName).bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <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="account.cpp"
+ >
+ </File>
+ <File
+ RelativePath="debug.cpp"
+ >
+ </File>
+ <File
+ RelativePath="filterplugin.cpp"
+ >
+ </File>
+ <File
+ RelativePath="main.cpp"
+ >
+ </File>
+ <File
+ RelativePath="protoplugin.cpp"
+ >
+ </File>
+ <File
+ RelativePath="services.cpp"
+ >
+ </File>
+ <File
+ RelativePath="synchro.cpp"
+ >
+ </File>
+ <File
+ RelativePath="yamn.cpp"
+ >
+ </File>
+ <Filter
+ Name="Mail browser, dialogs"
+ >
+ <File
+ RelativePath="browser\badconnect.cpp"
+ >
+ </File>
+ <File
+ RelativePath="browser\mailbrowser.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Mails"
+ >
+ <File
+ RelativePath="mails\decode.cpp"
+ >
+ </File>
+ <File
+ RelativePath="mails\mails.cpp"
+ >
+ </File>
+ <File
+ RelativePath="mails\mime.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="POP3 plugin"
+ >
+ <File
+ RelativePath="proto\md5.c"
+ >
+ </File>
+ <File
+ RelativePath="proto\netlib.cpp"
+ >
+ </File>
+ <File
+ RelativePath="proto\pop3\pop3.cpp"
+ >
+ </File>
+ <File
+ RelativePath="proto\pop3\pop3comm.cpp"
+ >
+ </File>
+ <File
+ RelativePath="proto\pop3\pop3opt.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ <File
+ RelativePath="resources\iconeutral.ico"
+ >
+ </File>
+ <File
+ RelativePath="resources\iconttbdown.ico"
+ >
+ </File>
+ <File
+ RelativePath="resources\icooffline.ico"
+ >
+ </File>
+ <File
+ RelativePath="resources\icoyamn3.ico"
+ >
+ </File>
+ <File
+ RelativePath=".\resources\resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resources\yamn.bmp"
+ >
+ </File>
+ <File
+ RelativePath="resources\YAMN.rc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ >
+ <File
+ RelativePath="debug.h"
+ >
+ </File>
+ <File
+ RelativePath="main.h"
+ >
+ </File>
+ <File
+ RelativePath="proto\pop3\pop3.h"
+ >
+ </File>
+ <File
+ RelativePath="proto\pop3\pop3comm.h"
+ >
+ </File>
+ <File
+ RelativePath="proto\pop3\pop3opt.h"
+ >
+ </File>
+ <File
+ RelativePath="yamn.h"
+ >
+ </File>
+ <Filter
+ Name="include"
+ >
+ <File
+ RelativePath="include\m_kbdnotify.h"
+ >
+ </File>
+ <File
+ RelativePath="include\m_toptoolbar.h"
+ >
+ </File>
+ <File
+ RelativePath="include\m_uninstaller.h"
+ >
+ </File>
+ <File
+ RelativePath="include\m_updater.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <File
+ RelativePath="ChangeLog.txt"
+ >
+ </File>
+ <File
+ RelativePath=".\version.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/yamn/YAMNopts.cpp b/yamn/YAMNopts.cpp new file mode 100644 index 0000000..99a8091 --- /dev/null +++ b/yamn/YAMNopts.cpp @@ -0,0 +1,2 @@ +
+
diff --git a/yamn/account.cpp b/yamn/account.cpp new file mode 100644 index 0000000..255f9cf --- /dev/null +++ b/yamn/account.cpp @@ -0,0 +1,1539 @@ +/*
+ * This code implements manipulation with accounts
+ * such as reading accounts from file, writing them to file,
+ * finding account by name etc.
+ *
+ * (c) majvan 2002-2004
+ */
+
+#include "yamn.h"
+#include "mails/m_mails.h"
+#if defined(DEBUG_FILEREAD) || defined(DEBUG_FILEREADMESSAGES) || defined(DEBUG_SYNCHRO)
+ #include <stdio.h>
+#endif
+
+//- imported ---------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+extern PSWMRG PluginBrowserSO;
+extern TCHAR AccountFileName[];
+extern TCHAR *CurDir;
+extern PLUGININFO pluginInfo;
+extern YAMN_VARIABLES YAMNVar;
+
+extern BOOL WINAPI SWMRGInitialize(PSWMRG pSWMRG,TCHAR *Name);
+extern void WINAPI SWMRGDelete(PSWMRG pSWMRG);
+extern DWORD WINAPI SWMRGWaitToWrite(PSWMRG pSWMRG,DWORD dwTimeout);
+extern void WINAPI SWMRGDoneWriting(PSWMRG pSWMRG);
+extern DWORD WINAPI SWMRGWaitToRead(PSWMRG pSWMRG, DWORD dwTimeout);
+extern void WINAPI SWMRGDoneReading(PSWMRG pSWMRG);
+extern DWORD WINAPI WaitToReadFcn(PSWMRG SObject);
+extern void WINAPI ReadDoneFcn(PSWMRG SObject);
+extern HYAMNPROTOPLUGIN FindPlugin(DWORD PluginID);
+
+extern void WINAPI DeleteMessagesToEndFcn(HACCOUNT Account,HYAMNMAIL From);
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+// SMALL INTRO
+// Accounts are queued in a queue (chained list). Pointer to first account is called "FirstAccount"
+// Account queue is ended with NULL- pointered account (NULL handle)
+// FirstAccount has every plugin in its own YAMN_PLUGIN structure
+
+//Account status CS
+//When we check some account, thread should change status of account to idle, connecting etc.
+//So if we want to read status, we have to successfully write and then read.
+LPCRITICAL_SECTION AccountStatusCS;
+
+//File Writing CS
+//When 2 threads want to write to file...
+LPCRITICAL_SECTION FileWritingCS;
+
+// Creates new account, which has plugin specified structure
+INT_PTR CreatePluginAccountSvc(WPARAM wParam,LPARAM lParam);
+
+// Deletes account from memory
+INT_PTR DeletePluginAccountSvc(WPARAM wParam,LPARAM);
+
+// Initializes standard YAMN account parameters
+int InitAccount(HACCOUNT Which);
+
+// Deinitializes (deletes) standard YAMN account parameters
+void DeInitAccount(HACCOUNT Which);
+
+// Sends signal (sets event) in AccountAccessSO and MessagesAccessSO
+// This event makes that all calls to ...WaitToRead or ...WaitToWrite are returned to WAIT_FAILED
+void StopSignalFcn(HACCOUNT Which);
+
+// Function used to encrypt password (codes / decodes string)
+// There's a problem when a character is going to be encrypted to (TCHAR)0, (end of string)
+// Dest- input and output string (input/output length of string is 1:1)
+// Encrypt- TRUE for encryption, FALSE for decryption
+void CodeDecodeString(TCHAR *Dest,BOOL Encrypt);
+
+// Only do the main work for FileToMemoryX functions. FileToMemoryX only opens file.
+static DWORD PostFileToMemory(HANDLE File,TCHAR **MemFile,TCHAR **End);
+
+// Reads the file and stores the content to allocated memory
+// FileName- name of file
+// MemFile- pointer to the pointer of TCHAR, new allocated memory by this function
+// End- where new allocated memory filled with file contents ends
+DWORD FileToMemoryA(char *FileName,TCHAR **MemFile,TCHAR **End);
+
+// Same as FileToMemoryA, but Unicode filename
+DWORD FileToMemoryW(char *FileName,TCHAR **MemFile,TCHAR **End);
+
+// Reads string that ends with character 0 and copies it to new allocated memory
+// Parser-pointer to memory with string
+// function sets this parameter to point at the next char after read string
+// End-information how long this string can be (in pointer to last possible char)
+// StoreTo-function allocates memory and copies the string, allocated memory returned in StoreTo
+// DebugString-the debug message showed in debug version
+#if defined(DEBUG_FILEREAD) || defined(DEBUG_FILEREADMESSAGES)
+DWORD ReadStringFromMemory(TCHAR **Parser,TCHAR *End,TCHAR **StoreTo,TCHAR *DebugString);
+#endif
+DWORD ReadStringFromMemory(TCHAR **Parser,TCHAR *End,TCHAR **StoreTo);
+#ifndef UNICODE
+ #if defined(DEBUG_FILEREAD) || defined(DEBUG_FILEREADMESSAGES)
+DWORD ReadStringFromMemoryW(WCHAR **Parser,TCHAR *End,WCHAR **StoreTo,WCHAR *DebugString);
+ #endif //if defined(DEBUG...)
+DWORD ReadStringFromMemoryW(WCHAR **Parser,TCHAR *End,WCHAR **StoreTo);
+#endif //ifdef Unicode
+
+// Reads notification parameters from memory
+// Parser-pointer to memory with string
+// function sets this parameter to point at the next char after read string
+// End-information how long this string can be (in pointer to last possible char)
+// Which-pointer to notification structure to fill with read parameters
+static DWORD ReadNotificationFromMemory(TCHAR **Parser,TCHAR *End,YAMN_NOTIFICATION *Which);
+
+// Reads messages from memory
+// Which- address of account that mails (messages) belong to
+// Parser- pointer to data from memory, function changes it to the next char after messages read
+// End- the last possible char of messages
+DWORD ReadMessagesFromMemory(HACCOUNT Which,TCHAR **Parser,TCHAR *End);
+
+// Does all needed operations to read account
+static INT_PTR PerformAccountReading(HYAMNPROTOPLUGIN Plugin,TCHAR *MemFile,TCHAR *End);
+
+// Read one account from memory
+// Which- address of account
+// Parser- pointer to data from memory, function changes it to the next char after account read
+// End- the last possible char of account
+DWORD ReadAccountFromMemory(HACCOUNT Which,TCHAR **Parser,TCHAR *End);
+
+// Inserts accounts read from file to actual account queue
+INT_PTR AddAccountsFromFileASvc(WPARAM wParam,LPARAM lParam);
+
+// Same as AddAccountsFromFileA, but filename is (WCHAR *) type- Unicode string
+INT_PTR AddAccountsFromFileWSvc(WPARAM,LPARAM);
+
+// Writes simple string to file
+// File- handle of open file for writing
+// Source- string to write, ended with zero character
+DWORD WriteStringToFile(HANDLE File,TCHAR *Source);
+#ifndef UNICODE
+DWORD WriteStringToFileW(HANDLE File,WCHAR *Source);
+#else
+#define ReadStringFromMemoryW ReadStringFromMemory
+#endif
+
+// Writes mails to file
+// File- handle of file
+// Which- address of account that mails belong to
+DWORD WriteMessagesToFile(HANDLE File,HACCOUNT Which);
+
+// Does all needed operations to write account to file
+static INT_PTR PerformAccountWriting(HYAMNPROTOPLUGIN Plugin,HANDLE File);
+
+// Writes accounts to file
+// Accounts are read from plugin's account queue
+// Function writes account data and calls WriteMessagesToFile to store account mails
+INT_PTR WriteAccountsToFileASvc(WPARAM wParam,LPARAM lParam);
+
+// Same as WriteAccountsToFileA, but filename is (WCHAR *) type- Unicode string
+INT_PTR WriteAccountsToFileWSvc(WPARAM wParam,LPARAM lParam);
+
+// Finds account by name and returns a pointer to it, or NULL when not found
+// we do not have to synchronize accounts for read access, because we never change name of account
+// (so if we want to change name of account we have to delete and create the new one)
+INT_PTR FindAccountByNameSvc(WPARAM wParam,LPARAM lParam);
+
+// Allocates a new account, and returns pointer to it
+// calling function should have write access (using AccountBrowserSO)
+// because new account is queues do account queue
+INT_PTR GetNextFreeAccountSvc(WPARAM wParam,LPARAM lParam);
+
+// Finds account for plugin
+//int FindPluginAccount(WPARAM wParam,LPARAM lParam);
+
+// Removes requested account from queue
+// and deletes it in memory calling new thread function, that does it in the background
+// This is very easy and the most secure way for plugins to delete account
+INT_PTR DeleteAccountSvc(WPARAM wParam,LPARAM);
+
+// This function is used as a thread function, that waits to signal for deleting account from memory
+// This signal is signaled in UsingAccount.Event (this signales that no thread will be use account in the future)
+DWORD WINAPI DeleteAccountInBackground(LPVOID Which);
+
+// Sends signal that all works with Plugin accounts should be stopped and accounts should not be used anymore.
+int StopAccounts(HYAMNPROTOPLUGIN Plugin);
+
+// Wait for accounts to finish its work
+int WaitForAllAccounts(HYAMNPROTOPLUGIN Plugin,BOOL GetAccountBrowserAccess=FALSE);
+
+// Deletes protocol accounts using protocol defined delete function.
+int DeleteAccounts(HYAMNPROTOPLUGIN Plugin);
+
+// If you want to get directly account status, call this function
+// You don't have to be in read-access to account and you can call this to retrieve status
+void WINAPI GetStatusFcn(HACCOUNT Which,char *Value);
+
+// If you want to set directly account status, call this function
+// You don't have to be in write-access to account and you can call this to retrieve status
+void WINAPI SetStatusFcn(HACCOUNT Which,char *Value);
+
+struct CExportedFunctions AccountExportedFcn[]=
+{
+ {YAMN_GETSTATUSID,(void *)GetStatusFcn},
+ {YAMN_SETSTATUSID,(void *)SetStatusFcn},
+};
+
+struct CExportedServices AccountExportedSvc[]=
+{
+ {MS_YAMN_CREATEPLUGINACCOUNT,CreatePluginAccountSvc},
+ {MS_YAMN_DELETEPLUGINACCOUNT,DeletePluginAccountSvc},
+ {MS_YAMN_FINDACCOUNTBYNAME,FindAccountByNameSvc},
+ {MS_YAMN_GETNEXTFREEACCOUNT,GetNextFreeAccountSvc},
+ {MS_YAMN_DELETEACCOUNT,DeletePluginAccountSvc},
+ {MS_YAMN_READACCOUNTSA,AddAccountsFromFileASvc},
+ {MS_YAMN_READACCOUNTSW,AddAccountsFromFileWSvc},
+ {MS_YAMN_WRITEACCOUNTSA,WriteAccountsToFileASvc},
+ {MS_YAMN_WRITEACCOUNTSW,WriteAccountsToFileWSvc},
+};
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+INT_PTR CreatePluginAccountSvc(WPARAM wParam,LPARAM lParam)
+{
+ HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
+ DWORD AccountVersion=(DWORD)lParam;
+ HACCOUNT NewAccount;
+
+//test if we are going to initialize members of suitable structure (structures of plugin and YAMN must match)
+ if(AccountVersion!=YAMN_ACCOUNTVERSION)
+ return NULL;
+
+ if(Plugin!=NULL)
+ {
+ if(Plugin->Fcn->NewAccountFcnPtr!=NULL)
+ {
+//Let plugin create its own structure, which can be derived from CAccount structure
+ NewAccount=Plugin->Fcn->NewAccountFcnPtr(Plugin,YAMN_ACCOUNTVERSION);
+ NewAccount->Plugin=Plugin;
+ }
+ else
+ {
+//We suggest plugin uses standard CAccount structure, so we create it
+ NewAccount=new struct CAccount;
+ NewAccount->Plugin=Plugin;
+ }
+//If not created successfully
+ if(NewAccount==NULL)
+ return NULL;
+//Init every members of structure, used by YAMN
+ InitAccount(NewAccount);
+
+ return (INT_PTR)NewAccount;
+ }
+ return NULL;
+}
+
+INT_PTR DeletePluginAccountSvc(WPARAM wParam,LPARAM)
+{
+ HACCOUNT OldAccount=(HACCOUNT)wParam;
+
+ if(OldAccount->Plugin->Fcn!=NULL)
+ {
+//Deinit every members and allocated fields of structure used by YAMN
+ DeInitAccount(OldAccount);
+ if(OldAccount->Plugin->Fcn->DeleteAccountFcnPtr!=NULL)
+ {
+//Let plugin delete its own CAccount derived structure
+ OldAccount->Plugin->Fcn->DeleteAccountFcnPtr(OldAccount);
+ }
+ else
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeletePluginAccountSvc:delete OldAccount\n");
+#endif
+ delete OldAccount; //consider account as standard YAMN HACCOUNT and use its own destructor
+ }
+ return 1;
+ }
+ delete OldAccount; //consider account as standard YAMN HACCOUNT, not initialized before and use its own destructor
+ return 1;
+}
+
+int InitAccount(HACCOUNT Which)
+{
+//initialize synchronizing objects
+ Which->AccountAccessSO=new SWMRG;
+ SWMRGInitialize(Which->AccountAccessSO,NULL);
+ Which->MessagesAccessSO=new SWMRG;
+ SWMRGInitialize(Which->MessagesAccessSO,NULL);
+ Which->UsingThreads=new SCOUNTER;
+ SWMRGInitialize(Which->MessagesAccessSO,NULL);
+
+//zero memory, where timestamps are stored
+ ZeroMemory(&Which->LastChecked,sizeof(Which->LastChecked));
+ ZeroMemory(&Which->LastSChecked,sizeof(Which->LastSChecked));
+ ZeroMemory(&Which->LastSynchronised,sizeof(Which->LastSynchronised));
+ ZeroMemory(&Which->LastMail,sizeof(Which->LastMail));
+
+ Which->Name=NULL;
+ Which->Mails=NULL;
+ Which->Interval=0;
+ Which->Flags=0;
+ Which->StatusFlags=0;
+ Which->Next=NULL;
+
+ Which->Server=new struct CServer;
+ Which->AbleToWork=TRUE;
+
+ return 1;
+}
+
+void DeInitAccount(HACCOUNT Which)
+{
+//delete YAMN allocated fields
+ if(Which->Name!=NULL)
+ delete[] Which->Name;
+ if(Which->Server->Name!=NULL)
+ delete[] Which->Server->Name;
+ if(Which->Server->Login!=NULL)
+ delete[] Which->Server->Login;
+ if(Which->Server->Passwd!=NULL)
+ delete[] Which->Server->Passwd;
+ if(Which->Server!=NULL)
+ delete[] Which->Server;
+
+ SWMRGDelete(Which->AccountAccessSO);
+ delete Which->AccountAccessSO;
+ SWMRGDelete(Which->MessagesAccessSO);
+ delete Which->MessagesAccessSO;
+ delete Which->UsingThreads;
+ DeleteMessagesToEndFcn(Which,(HYAMNMAIL)Which->Mails);
+}
+
+void StopSignalFcn(HACCOUNT Which)
+//set event that we are going to delete account
+{
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tStopSignalFcn:stop account: %x\n",Which);
+#endif
+ Which->AbleToWork=FALSE;
+//do not use synchronizing objects anymore
+//any access to these objects then ends with WAIT_FAILED
+ SetEvent(Which->AccountAccessSO->hFinishEV);
+ SetEvent(Which->MessagesAccessSO->hFinishEV);
+}
+
+void CodeDecodeString(TCHAR *Dest,BOOL Encrypt)
+{
+ TCHAR Code=STARTCODEPSW;
+
+ if(Dest==NULL)
+ return;
+
+ for(;*Dest!=(TCHAR)0;Dest++)
+ {
+ if(Encrypt)
+ *Dest=*Dest+Code;
+ else
+ *Dest=*Dest-Code;
+ Code+=(TCHAR)ADDCODEPSW;
+ }
+}
+
+static DWORD PostFileToMemory(HANDLE File,TCHAR **MemFile,TCHAR **End)
+{
+ DWORD FileSize,ReadBytes;
+
+ if(!(FileSize=GetFileSize(File,NULL)))
+ {
+ CloseHandle(File);
+ return EACC_FILESIZE;
+ }
+//allocate space in memory, where we copy the whole file
+ if(NULL==(*MemFile=(char *)new char[FileSize]))
+ {
+ CloseHandle(File);
+ return EACC_ALLOC;
+ }
+//copy file to memory
+ if(!ReadFile(File,(LPVOID)*MemFile,FileSize,&ReadBytes,NULL))
+ {
+ CloseHandle(File);
+ delete[] *MemFile;
+ return EACC_SYSTEM;
+ }
+ CloseHandle(File);
+ *End=*MemFile+FileSize/sizeof(TCHAR);
+ return 0;
+}
+
+DWORD FileToMemoryA(char *FileName,TCHAR **MemFile,TCHAR **End)
+{
+ HANDLE File;
+
+ if(INVALID_HANDLE_VALUE==(File=CreateFile(FileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)))
+ return EACC_SYSTEM;
+
+ return PostFileToMemory(File,MemFile,End);
+}
+
+DWORD FileToMemoryW(WCHAR *FileName,TCHAR **MemFile,TCHAR **End)
+{
+ HANDLE File;
+
+ if(INVALID_HANDLE_VALUE==(File=CreateFileW(FileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)))
+ return EACC_SYSTEM;
+
+ return PostFileToMemory(File,MemFile,End);
+}
+
+#if defined(DEBUG_FILEREAD) || defined(DEBUG_FILEREADMESSAGES)
+DWORD ReadStringFromMemory(TCHAR **Parser,TCHAR *End,TCHAR **StoreTo,TCHAR *DebugString)
+{
+//This is the debug version of ReadStringFromMemory function. This version shows MessageBox where
+//read string is displayed
+ TCHAR *Dest,*Finder;
+ DWORD Size;
+ TCHAR Debug[65536];
+
+ Finder=*Parser;
+ while((*Finder!=(TCHAR)0) && (Finder<=End)) Finder++;
+ _stprintf(Debug,_T("%s: %s,length is %d, remaining %d chars"),DebugString,*Parser,Finder-*Parser,End-Finder);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+ if(Finder>=End)
+ return EACC_FILECOMPATIBILITY;
+ if(Size=Finder-*Parser)
+ {
+ if(NULL==(Dest=*StoreTo=new TCHAR[Size+1]))
+ return EACC_ALLOC;
+ for(;*Parser<=Finder;(*Parser)++,Dest++)
+ *Dest=**Parser;
+ }
+ else
+ {
+ *StoreTo=NULL;
+ (*Parser)++;
+ }
+ return 0;
+}
+#endif
+
+DWORD ReadStringFromMemory(TCHAR **Parser,TCHAR *End,TCHAR **StoreTo)
+{
+ TCHAR *Dest,*Finder;
+ DWORD Size;
+
+ Finder=*Parser;
+ while((*Finder!=(TCHAR)0) && (Finder<=End)) Finder++;
+ if(Finder>=End)
+ return EACC_FILECOMPATIBILITY;
+ if(Size=Finder-*Parser)
+ {
+ if(NULL==(Dest=*StoreTo=new TCHAR[Size+1]))
+ return EACC_ALLOC;
+ for(;*Parser<=Finder;(*Parser)++,Dest++)
+ *Dest=**Parser;
+ }
+ else
+ {
+ *StoreTo=NULL;
+ (*Parser)++;
+ }
+ return 0;
+}
+
+#ifndef UNICODE
+ #if defined(DEBUG_FILEREAD) || defined(DEBUG_FILEREADMESSAGES)
+DWORD ReadStringFromMemoryW(WCHAR **Parser,TCHAR *End,WCHAR **StoreTo,WCHAR *DebugString)
+{
+//This is the debug version of ReadStringFromMemoryW function. This version shows MessageBox where
+//read string is displayed
+ WCHAR *Dest,*Finder;
+ DWORD Size;
+ WCHAR Debug[65536];
+
+ Finder=*Parser;
+ while((*Finder!=(WCHAR)0) && (Finder<=(WCHAR *)End)) Finder++;
+ swprintf(Debug,L"%s: %s,length is %d, remaining %d chars",DebugString,*Parser,Finder-*Parser,(WCHAR *)End-Finder);
+ MessageBoxW(NULL,Debug,L"debug",MB_OK);
+ if(Finder>=(WCHAR *)End)
+ return EACC_FILECOMPATIBILITY;
+ if(Size=Finder-*Parser)
+ {
+ if(NULL==(Dest=*StoreTo=new WCHAR[Size+1]))
+ return EACC_ALLOC;
+ for(;*Parser<=Finder;(*Parser)++,Dest++)
+ *Dest=**Parser;
+ }
+ else
+ {
+ *StoreTo=NULL;
+ (*Parser)++;
+ }
+ return 0;
+}
+ #endif //if defined(DEBUG...)
+
+DWORD ReadStringFromMemoryW(WCHAR **Parser,TCHAR *End,WCHAR **StoreTo)
+{
+ WCHAR *Dest,*Finder;
+ DWORD Size;
+
+ Finder=*Parser;
+ while((*Finder!=(WCHAR)0) && (Finder<=(WCHAR *)End)) Finder++;
+ if(Finder>=(WCHAR *)End)
+ return EACC_FILECOMPATIBILITY;
+ if(Size=Finder-*Parser)
+ {
+ if(NULL==(Dest=*StoreTo=new WCHAR[Size+1]))
+ return EACC_ALLOC;
+ for(;*Parser<=Finder;(*Parser)++,Dest++)
+ *Dest=**Parser;
+ }
+ else
+ {
+ *StoreTo=NULL;
+ (*Parser)++;
+ }
+ return 0;
+}
+#endif //ifdef unicode
+
+static DWORD ReadNotificationFromMemory(TCHAR **Parser,TCHAR *End,YAMN_NOTIFICATION *Which)
+{
+ DWORD Stat;
+#ifdef DEBUG_FILEREAD
+ TCHAR Debug[65536];
+#endif
+
+ Which->Flags=*(DWORD *)(*Parser);
+ (*Parser)+=sizeof(DWORD)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("NFlags: %04x, remaining %d chars"),Which->Flags,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+
+ Which->PopUpB=*(COLORREF *)(*Parser);
+ (*Parser)+=sizeof(COLORREF)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("PopUpB: %04x, remaining %d chars"),Which->PopUpB,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+ Which->PopUpT=*(COLORREF *)(*Parser);
+ (*Parser)+=sizeof(COLORREF)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("PopUpT: %04x, remaining %d chars"),Which->PopUpT,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+ Which->PopUpTime=*(DWORD *)(*Parser);
+ (*Parser)+=sizeof(DWORD)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("PopUpTime: %04x, remaining %d chars"),Which->PopUpTime,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+
+#ifdef DEBUG_FILEREAD
+ if(Stat=ReadStringFromMemoryW((WCHAR **)Parser,End,&Which->App,L"App"))
+#else
+ if(Stat=ReadStringFromMemoryW((WCHAR **)Parser,End,&Which->App))
+#endif
+ return Stat;
+#ifdef DEBUG_FILEREAD
+ if(Stat=ReadStringFromMemoryW((WCHAR **)Parser,End,&Which->AppParam,L"AppParam"))
+#else
+ if(Stat=ReadStringFromMemoryW((WCHAR **)Parser,End,&Which->AppParam))
+#endif
+ return Stat;
+ return 0;
+}
+
+DWORD ReadMessagesFromMemory(HACCOUNT Which,TCHAR **Parser,TCHAR *End)
+{
+ TCHAR *Finder;
+ DWORD Size,Stat;
+ HYAMNMAIL ActualMail=NULL;
+ struct CMimeItem *items;
+ char *ReadString;
+
+#ifdef DEBUG_FILEREAD
+ MessageBox(NULL,_T("going to read messages, if any..."),_T("debug"),MB_OK);
+#endif
+ do
+ {
+ Finder=*Parser;
+ while((*Finder!=(TCHAR)0) && (Finder<=End)) Finder++;
+ if(Finder>=End)
+ return EACC_FILECOMPATIBILITY;
+ if(Size=Finder-*Parser)
+ {
+ if(Which->Mails==NULL) //First message in queue
+ {
+ if(NULL==(Which->Mails=ActualMail=CreateAccountMail(Which)))
+ return EACC_ALLOC;
+ }
+ else
+ {
+ if(NULL==(ActualMail->Next=CreateAccountMail(Which))){
+ return EACC_ALLOC;
+ }
+ ActualMail=ActualMail->Next;
+ }
+ items=NULL;
+#ifdef DEBUG_FILEREADMESSAGES
+ if(Stat=ReadStringFromMemory(Parser,End,&ActualMail->ID,_T("ID")))
+#else
+ if(Stat=ReadStringFromMemory(Parser,End,&ActualMail->ID))
+#endif
+ return Stat;
+// ActualMail->MailData=new MAILDATA; !!! mem leake !!! this is alloc by CreateAccountMail, no need for doubble alloc !!!!
+
+ ActualMail->MailData->Size=*(DWORD *)(*Parser);
+ (*Parser)+=sizeof(DWORD)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+ ActualMail->Flags=*(DWORD *)(*Parser);
+ (*Parser)+=sizeof(DWORD)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+ ActualMail->Number=*(DWORD *)(*Parser);
+ (*Parser)+=sizeof(DWORD)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+
+ if((NULL!=Which->Plugin->MailFcn) && (NULL!=Which->Plugin->MailFcn->ReadMailOptsFcnPtr))
+ Which->Plugin->MailFcn->ReadMailOptsFcnPtr(ActualMail,Parser,End); //read plugin mail settings from file
+
+ do
+ {
+#ifdef DEBUG_FILEREADMESSAGES
+ if(Stat=ReadStringFromMemory(Parser,End,&ReadString,_T("Name")))
+#else
+ if(Stat=ReadStringFromMemory(Parser,End,&ReadString))
+#endif
+ return Stat;
+ if(ReadString==NULL)
+ break;
+
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<read name>%s</read name>",ReadString);
+#endif
+
+ if(items==NULL)
+ items=ActualMail->MailData->TranslatedHeader=new struct CMimeItem;
+ else
+ {
+ items->Next=new struct CMimeItem;
+ items=items->Next;
+ }
+ if(items==NULL)
+ return EACC_ALLOC;
+ items->name=ReadString;
+
+#ifdef DEBUG_FILEREADMESSAGES
+ if(Stat=ReadStringFromMemory(Parser,End,&ReadString,_T("Value")))
+#else
+ if(Stat=ReadStringFromMemory(Parser,End,&ReadString))
+#endif
+ return Stat;
+ items->value=ReadString;
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<read value>%s</read value>\n",ReadString);
+#endif
+ }while(1);
+ }
+ else
+ break; //no next messages, new account!
+
+ }while(1);
+ (*Parser)++;
+ return 0;
+}
+
+DWORD ReadAccountFromMemory(HACCOUNT Which,TCHAR **Parser,TCHAR *End)
+{
+ DWORD Stat;
+#ifdef DEBUG_FILEREAD
+ TCHAR Debug[65536];
+#endif
+//Read name of account
+#ifdef DEBUG_FILEREAD
+ if(Stat=ReadStringFromMemory(Parser,End,&Which->Name,_T("Name")))
+#else
+ if(Stat=ReadStringFromMemory(Parser,End,&Which->Name))
+#endif
+ return Stat;
+ if(Which->Name==NULL)
+ return EACC_FILECOMPATIBILITY;
+
+//Read server parameters
+#ifdef DEBUG_FILEREAD
+ if(Stat=ReadStringFromMemory(Parser,End,&Which->Server->Name,_T("Server")))
+#else
+ if(Stat=ReadStringFromMemory(Parser,End,&Which->Server->Name))
+#endif
+ return Stat;
+ Which->Server->Port=*(WORD *)(*Parser);
+ (*Parser)+=sizeof(WORD)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("Port: %d, remaining %d chars"),Which->Server->Port,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+#ifdef DEBUG_FILEREAD
+ if(Stat=ReadStringFromMemory(Parser,End,&Which->Server->Login,_T("Login")))
+#else
+ if(Stat=ReadStringFromMemory(Parser,End,&Which->Server->Login))
+#endif
+ return Stat;
+#ifdef DEBUG_FILEREAD
+ if(Stat=ReadStringFromMemory(Parser,End,&Which->Server->Passwd,_T("Password")))
+#else
+ if(Stat=ReadStringFromMemory(Parser,End,&Which->Server->Passwd))
+#endif
+ return Stat;
+ CodeDecodeString(Which->Server->Passwd,FALSE);
+
+//Read account flags
+ Which->Flags=*(DWORD *)(*Parser);
+ (*Parser)+=sizeof(DWORD)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("Flags: %04x, remaining %d chars"),Which->Flags,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+ Which->StatusFlags=*(DWORD *)(*Parser);
+ (*Parser)+=sizeof(DWORD)/sizeof(TCHAR);
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("STFlags: %04x, remaining %d chars"),Which->StatusFlags,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+ Which->PluginFlags=*(DWORD *)(*Parser);
+ (*Parser)+=sizeof(DWORD)/sizeof(TCHAR);
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("PFlags: %04x, remaining %d chars"),Which->PluginFlags,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+
+//Read account miscellaneous parameters
+ Which->Interval=*(WORD *)(*Parser);
+ Which->TimeLeft=Which->Interval; //check on loading
+ (*Parser)+=sizeof(WORD)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("Interval: %d, remaining %d chars"),Which->Interval,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+
+//Read notification parameters
+ if(Stat=ReadNotificationFromMemory(Parser,End,&Which->NewMailN))
+ return Stat;
+ if(Stat=ReadNotificationFromMemory(Parser,End,&Which->NoNewMailN))
+ return Stat;
+ if(Stat=ReadNotificationFromMemory(Parser,End,&Which->BadConnectN))
+ return Stat;
+
+//Let plugin read its own data stored in file
+ if(Which->Plugin->Fcn!=NULL && Which->Plugin->Fcn->ReadPluginOptsFcnPtr!=NULL)
+ if(Stat=Which->Plugin->Fcn->ReadPluginOptsFcnPtr(Which,Parser,End))
+ return Stat;
+//Read mails
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ReadAccountFromMemory:ActualAccountMsgsSO-write wait\n");
+#endif
+ WaitToWriteFcn(Which->MessagesAccessSO);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ReadAccountFromMemory:ActualAccountMsgsSO-write enter\n");
+#endif
+ if(Stat=ReadMessagesFromMemory(Which,Parser,End))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ReadAccountFromMemory:ActualAccountMsgsSO-write done\n");
+#endif
+ WriteDoneFcn(Which->MessagesAccessSO);
+ return Stat;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ReadAccountFromMemory:ActualAccountMsgsSO-write done\n");
+#endif
+ WriteDoneFcn(Which->MessagesAccessSO);
+
+//Read timestamps
+ Which->LastChecked=*(SYSTEMTIME *)(*Parser);
+ (*Parser)+=sizeof(SYSTEMTIME)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("LastChecked: %04x, remaining %d chars"),Which->LastChecked,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+ Which->LastSChecked=*(SYSTEMTIME *)(*Parser);
+ (*Parser)+=sizeof(SYSTEMTIME)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("LastSChecked: %04x, remaining %d chars"),Which->LastSChecked,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+ Which->LastSynchronised=*(SYSTEMTIME *)(*Parser);
+ (*Parser)+=sizeof(SYSTEMTIME)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("LastSynchronised: %04x, remaining %d chars"),Which->LastSynchronised,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+ Which->LastMail=*(SYSTEMTIME *)(*Parser);
+ (*Parser)+=sizeof(SYSTEMTIME)/sizeof(TCHAR);
+ if(*Parser>End) //WARNING! There's only > at the end of testing
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("LastMail: %04x, remaining %d chars"),Which->LastMail,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+ if(*Parser==End)
+ return EACC_ENDOFFILE;
+ return 0;
+
+}
+
+static INT_PTR PerformAccountReading(HYAMNPROTOPLUGIN Plugin,TCHAR *MemFile,TCHAR *End)
+{
+//Retrieve info for account from memory
+ TCHAR *Parser;
+ DWORD Ver,Stat;
+
+ HACCOUNT ActualAccount,FirstAllocatedAccount;
+
+ Ver=*(DWORD *)MemFile;
+ if(Ver>YAMN_ACCOUNTFILEVERSION)
+ {
+ delete[] MemFile;
+ return EACC_FILEVERSION;
+ }
+ Parser=MemFile+sizeof(Ver)/sizeof(TCHAR);
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"AddAccountsFromFile:AccountBrowserSO-write wait\n");
+#endif
+ SWMRGWaitToWrite(Plugin->AccountBrowserSO,INFINITE);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"AddAccountsFromFile:AccountBrowserSO-write enter\n");
+#endif
+ if(NULL==(ActualAccount=(HACCOUNT)CallService(MS_YAMN_GETNEXTFREEACCOUNT,(WPARAM)Plugin,(LPARAM)YAMN_ACCOUNTVERSION)))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"AddAccountsFromFile:AccountBrowserSO-write done\n");
+#endif
+ SWMRGDoneWriting(Plugin->AccountBrowserSO);
+ delete[] MemFile;
+ return EACC_ALLOC;
+ }
+ FirstAllocatedAccount=ActualAccount;
+
+ do
+ {
+ HACCOUNT Temp;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"AddAccountsFromFile:ActualAccountSO-write wait\n");
+#endif
+ WaitToWriteFcn(ActualAccount->AccountAccessSO);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"AddAccountsFromFile:ActualAccountSO-write enter\n");
+#endif
+ Stat=ReadAccountFromMemory(ActualAccount,&Parser,End);
+
+ if(ActualAccount->StatusFlags & (YAMN_ACC_STARTA | YAMN_ACC_STARTS))
+ ActualAccount->TimeLeft=1; //check on loading
+
+ if(Stat && (Stat!=EACC_ENDOFFILE))
+ {
+ for(ActualAccount=FirstAllocatedAccount;ActualAccount!=NULL;ActualAccount=Temp)
+ {
+ Temp=ActualAccount->Next;
+ delete ActualAccount;
+ }
+ delete[] MemFile;
+ if(Plugin->FirstAccount==FirstAllocatedAccount)
+ Plugin->FirstAccount=NULL;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"AddAccountsFromFile:ActualAccountSO-write done\n");
+#endif
+ SWMRGDoneWriting(Plugin->AccountBrowserSO);
+ return (INT_PTR)Stat;
+ }
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"AddAccountsFromFile:ActualAccountSO-write done\n");
+#endif
+ WriteDoneFcn(ActualAccount->AccountAccessSO);
+
+ if((Stat!=EACC_ENDOFFILE) && (NULL==(ActualAccount=(HACCOUNT)CallService(MS_YAMN_GETNEXTFREEACCOUNT,(WPARAM)Plugin,(LPARAM)YAMN_ACCOUNTVERSION))))
+ {
+ for(ActualAccount=FirstAllocatedAccount;ActualAccount!=NULL;ActualAccount=Temp)
+ {
+ Temp=ActualAccount->Next;
+ delete ActualAccount;
+ }
+ delete[] MemFile;
+ if(Plugin->FirstAccount==FirstAllocatedAccount)
+ Plugin->FirstAccount=NULL;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"AddAccountsFromFile:AccountBrowserSO-write done\n");
+#endif
+ SWMRGDoneWriting(Plugin->AccountBrowserSO);
+ return EACC_ALLOC;
+ }
+ }while(Stat!=EACC_ENDOFFILE);
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"AddAccountsFromFile:AccountBrowserSO-write done\n");
+#endif
+ SWMRGDoneWriting(Plugin->AccountBrowserSO);
+ delete[] MemFile;
+
+ return 0;
+}
+
+INT_PTR AddAccountsFromFileASvc(WPARAM wParam,LPARAM lParam)
+//Add accounts from file to memory
+{
+ DWORD Stat;
+ TCHAR *MemFile,*End;
+
+ if(Stat=FileToMemoryA((char *)lParam,&MemFile,&End))
+ return (INT_PTR)Stat;
+
+ return PerformAccountReading((HYAMNPROTOPLUGIN)wParam,MemFile,End);
+
+}
+
+INT_PTR AddAccountsFromFileWSvc(WPARAM wParam,LPARAM lParam)
+//Add accounts from file to memory
+{
+ DWORD Stat;
+ TCHAR *MemFile,*End;
+
+ if(Stat=FileToMemoryW((WCHAR *)lParam,&MemFile,&End))
+ return (INT_PTR)Stat;
+
+ return PerformAccountReading((HYAMNPROTOPLUGIN)wParam,MemFile,End);
+
+}
+
+DWORD WriteStringToFile(HANDLE File,TCHAR *Source)
+{
+ DWORD Length,WrittenBytes;
+ TCHAR null=(TCHAR)0;
+
+ if((Source==NULL) || !(Length=(DWORD)_tcslen(Source)))
+ {
+ if(!WriteFile(File,&null,sizeof(TCHAR),&WrittenBytes,NULL))
+ {
+ CloseHandle(File);
+ return EACC_SYSTEM;
+ }
+ }
+ else if(!WriteFile(File,Source,(Length+1)*sizeof(TCHAR),&WrittenBytes,NULL))
+ {
+ CloseHandle(File);
+ return EACC_SYSTEM;
+ }
+ return 0;
+}
+
+#ifndef UNICODE
+DWORD WriteStringToFileW(HANDLE File,WCHAR *Source)
+{
+ DWORD Length,WrittenBytes;
+ WCHAR null=(WCHAR)0;
+
+ if((Source==NULL) || !(Length=(DWORD)wcslen(Source)))
+ {
+ if(!WriteFile(File,&null,sizeof(WCHAR),&WrittenBytes,NULL))
+ {
+ CloseHandle(File);
+ return EACC_SYSTEM;
+ }
+ }
+ else if(!WriteFile(File,Source,(Length+1)*sizeof(WCHAR),&WrittenBytes,NULL))
+ return EACC_SYSTEM;
+ return 0;
+}
+#endif
+
+DWORD WriteMessagesToFile(HANDLE File,HACCOUNT Which)
+{
+ DWORD WrittenBytes,Stat;
+ HYAMNMAIL ActualMail=(HYAMNMAIL)Which->Mails;
+ struct CMimeItem *items;
+
+ while(ActualMail!=NULL)
+ {
+ if(Stat=WriteStringToFile(File,ActualMail->ID))
+ return Stat;
+ if(!WriteFile(File,(char *)&ActualMail->MailData->Size,sizeof(ActualMail->MailData->Size),&WrittenBytes,NULL) ||
+ !WriteFile(File,(char *)&ActualMail->Flags,sizeof(ActualMail->Flags),&WrittenBytes,NULL) ||
+ !WriteFile(File,(char *)&ActualMail->Number,sizeof(ActualMail->Number),&WrittenBytes,NULL))
+ return EACC_SYSTEM;
+ if((NULL!=Which->Plugin->MailFcn) && (NULL!=Which->Plugin->MailFcn->WriteMailOptsFcnPtr))
+ Which->Plugin->MailFcn->WriteMailOptsFcnPtr(File,ActualMail); //write plugin mail options to file
+ for(items=ActualMail->MailData->TranslatedHeader;items!=NULL;items=items->Next)
+ {
+ if(Stat=WriteStringToFile(File,items->name))
+ return Stat;
+ if(Stat=WriteStringToFile(File,items->value))
+ return Stat;
+ }
+ if(Stat=WriteStringToFile(File,_T("")))
+ return Stat;
+ ActualMail=ActualMail->Next;
+ }
+ if(Stat=WriteStringToFile(File,_T("")))
+ return Stat;
+ return 0;
+}
+
+static INT_PTR PerformAccountWriting(HYAMNPROTOPLUGIN Plugin,HANDLE File)
+{
+ DWORD WrittenBytes,Stat;
+ HACCOUNT ActualAccount;
+ DWORD Ver=YAMN_ACCOUNTFILEVERSION;
+ BOOL Writed=FALSE;
+ DWORD ReturnValue=0,EnterCode;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:AccountBrowserSO-read wait\n");
+#endif
+ SWMRGWaitToRead(Plugin->AccountBrowserSO,INFINITE);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:AccountBrowserSO-read enter\n");
+#endif
+ try
+ {
+ for(ActualAccount=Plugin->FirstAccount;ActualAccount!=NULL;ActualAccount=ActualAccount->Next)
+ {
+/* TCHAR DEBUG[100];
+ Beep(3000,100);Sleep(200);
+ _stprintf(DEBUG,_T("Browsing account %s"),ActualAccount->Name==NULL ? _T("(null)") : ActualAccount->Name);
+ MessageBox(NULL,DEBUG,_T("debug- WriteAccount..."),MB_OK);
+*/
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:ActualAccountSO-read wait\n");
+#endif
+ EnterCode=WaitToReadFcn(ActualAccount->AccountAccessSO);
+ if(EnterCode==WAIT_FINISH) //account is about to delete
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:ActualAccountSO-read wait failed\n");
+#endif
+ ActualAccount=ActualAccount->Next;
+ continue;
+ }
+ if(EnterCode==WAIT_FAILED) //account is deleted
+ break;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:ActualAccountSO-read enter\n");
+#endif
+ if((ActualAccount->Name==NULL) || (*ActualAccount->Name==(TCHAR)0))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:ActualAccountSO-read done\n");
+#endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ continue;
+ }
+
+ if(!Writed && !WriteFile(File,&Ver,sizeof(Ver),&WrittenBytes,NULL))
+ throw (DWORD)EACC_SYSTEM;
+ Writed=TRUE;
+
+ if(Stat=WriteStringToFile(File,ActualAccount->Name))
+ throw (DWORD)Stat;
+
+ if(Stat=WriteStringToFile(File,ActualAccount->Server->Name))
+ throw (DWORD)Stat;
+
+ if(!WriteFile(File,(char *)&ActualAccount->Server->Port,2,&WrittenBytes,NULL))
+ throw (DWORD)EACC_SYSTEM;
+
+ if((Stat=WriteStringToFile(File,ActualAccount->Server->Login)))
+ throw (DWORD)Stat;
+
+ CodeDecodeString(ActualAccount->Server->Passwd,TRUE);
+
+ if(Stat=WriteStringToFile(File,ActualAccount->Server->Passwd))
+ {
+ CodeDecodeString(ActualAccount->Server->Passwd,FALSE);
+ throw (DWORD)Stat;
+ }
+ CodeDecodeString(ActualAccount->Server->Passwd,FALSE);
+
+ if((!WriteFile(File,(char *)&ActualAccount->Flags,sizeof(DWORD),&WrittenBytes,NULL) ||
+ (!WriteFile(File,(char *)&ActualAccount->StatusFlags,sizeof(DWORD),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->PluginFlags,sizeof(DWORD),&WrittenBytes,NULL))))
+ throw (DWORD)EACC_SYSTEM;
+
+ if(!WriteFile(File,(char *)&ActualAccount->Interval,sizeof(WORD),&WrittenBytes,NULL))
+ throw (DWORD)EACC_SYSTEM;
+
+ if((!WriteFile(File,(char *)&ActualAccount->NewMailN.Flags,sizeof(DWORD),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->NewMailN.PopUpB,sizeof(COLORREF),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->NewMailN.PopUpT,sizeof(COLORREF),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->NewMailN.PopUpTime,sizeof(DWORD),&WrittenBytes,NULL)))
+ throw (DWORD)EACC_SYSTEM;
+
+ if((Stat=WriteStringToFileW(File,ActualAccount->NewMailN.App)) ||
+ (Stat=WriteStringToFileW(File,ActualAccount->NewMailN.AppParam)))
+ throw (DWORD)Stat;
+
+ if((!WriteFile(File,(char *)&ActualAccount->NoNewMailN.Flags,sizeof(DWORD),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->NoNewMailN.PopUpB,sizeof(COLORREF),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->NoNewMailN.PopUpT,sizeof(COLORREF),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->NoNewMailN.PopUpTime,sizeof(DWORD),&WrittenBytes,NULL)))
+ throw (DWORD)EACC_SYSTEM;
+
+ if((Stat=WriteStringToFileW(File,ActualAccount->NoNewMailN.App)) ||
+ (Stat=WriteStringToFileW(File,ActualAccount->NoNewMailN.AppParam)))
+ throw (DWORD)Stat;
+
+ if((!WriteFile(File,(char *)&ActualAccount->BadConnectN.Flags,sizeof(DWORD),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->BadConnectN.PopUpB,sizeof(COLORREF),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->BadConnectN.PopUpT,sizeof(COLORREF),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->BadConnectN.PopUpTime,sizeof(DWORD),&WrittenBytes,NULL)))
+ throw (DWORD)EACC_SYSTEM;
+
+ if((Stat=WriteStringToFileW(File,ActualAccount->BadConnectN.App)) ||
+ (Stat=WriteStringToFileW(File,ActualAccount->BadConnectN.AppParam)))
+ throw (DWORD)Stat;
+
+//Let plugin write its own values into file
+ if(ActualAccount->Plugin->Fcn!=NULL && ActualAccount->Plugin->Fcn->WritePluginOptsFcnPtr!=NULL)
+ if(Stat=ActualAccount->Plugin->Fcn->WritePluginOptsFcnPtr(File,ActualAccount))
+ throw (DWORD)Stat;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:ActualAccountMsgsSO-read wait\n");
+#endif
+ WaitToReadFcn(ActualAccount->MessagesAccessSO);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:ActualAccountMsgsSO-read enter\n");
+#endif
+ if(Stat=WriteMessagesToFile(File,ActualAccount))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:ActualAccountMsgsSO-read done\n");
+#endif
+ ReadDoneFcn(ActualAccount->MessagesAccessSO);
+ throw (DWORD)Stat;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:ActualAccountMsgsSO-read done\n");
+#endif
+ ReadDoneFcn(ActualAccount->MessagesAccessSO);
+
+ if((!WriteFile(File,(char *)&ActualAccount->LastChecked,sizeof(SYSTEMTIME),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->LastSChecked,sizeof(SYSTEMTIME),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->LastSynchronised,sizeof(SYSTEMTIME),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&ActualAccount->LastMail,sizeof(SYSTEMTIME),&WrittenBytes,NULL)))
+ throw (DWORD)Stat;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:ActualAccountSO-read done\n");
+#endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+ }
+ catch(DWORD ErrorCode)
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:ActualAccountSO-read done\n");
+#endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ ReturnValue=ErrorCode;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WriteAccountsToFile:AccountBrowserSO-read done\n");
+#endif
+ SWMRGDoneReading(Plugin->AccountBrowserSO);
+ CloseHandle(File);
+ return 0;
+}
+
+INT_PTR WriteAccountsToFileASvc(WPARAM wParam,LPARAM lParam)
+//Writes accounts to file
+{
+ HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
+ char *FileName=(char *)lParam;
+
+ HANDLE File;
+
+ EnterCriticalSection(FileWritingCS);
+ if(INVALID_HANDLE_VALUE==(File=CreateFileA(FileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)))
+ {
+ LeaveCriticalSection(FileWritingCS);
+ return EACC_SYSTEM;
+ }
+ LeaveCriticalSection(FileWritingCS);
+
+ return PerformAccountWriting(Plugin,File);
+}
+
+INT_PTR WriteAccountsToFileWSvc(WPARAM wParam,LPARAM lParam)
+//Writes accounts to file
+{
+ HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
+ WCHAR *FileName=(WCHAR *)lParam;
+ INT_PTR rv;
+
+ HANDLE File;
+
+ EnterCriticalSection(FileWritingCS);
+ if(INVALID_HANDLE_VALUE==(File=CreateFileW(FileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)))
+ {
+ LeaveCriticalSection(FileWritingCS);
+ return EACC_SYSTEM;
+ }
+
+ rv=PerformAccountWriting(Plugin,File);
+
+ LeaveCriticalSection(FileWritingCS);
+
+ return rv;
+}
+
+INT_PTR FindAccountByNameSvc(WPARAM wParam,LPARAM lParam)
+{
+ HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
+ TCHAR *SearchedAccount=(TCHAR *)lParam;
+ HACCOUNT Finder;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"FindAccountByName:AccountBrowserSO-read wait\n");
+#endif
+ SWMRGWaitToRead(Plugin->AccountBrowserSO,INFINITE);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"FindAccountByName:AccountBrowserSO-read enter\n");
+#endif
+ for(Finder=Plugin->FirstAccount;Finder!=NULL;Finder=Finder->Next)
+ if((Finder->Name!=NULL) && (0==_tcscmp(SearchedAccount,Finder->Name)))
+ break;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"FindAccountByName:AccountBrowserSO-read done\n");
+#endif
+ SWMRGDoneReading(Plugin->AccountBrowserSO);
+ return (INT_PTR)Finder;
+}
+
+INT_PTR GetNextFreeAccountSvc(WPARAM wParam,LPARAM lParam)
+{
+ HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
+ HACCOUNT Finder;
+
+ if(Plugin->FirstAccount==NULL)
+ {
+ Plugin->FirstAccount=(HACCOUNT)CallService(MS_YAMN_CREATEPLUGINACCOUNT,wParam,lParam);
+ return (INT_PTR)Plugin->FirstAccount;
+ }
+ for(Finder=Plugin->FirstAccount;Finder->Next!=NULL;Finder=Finder->Next);
+ Finder->Next=(HACCOUNT)CallService(MS_YAMN_CREATEPLUGINACCOUNT,wParam,lParam);
+ return (INT_PTR)Finder->Next;
+}
+
+/*
+int FindPluginAccount(WPARAM wParam,LPARAM lParam)
+{
+ HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
+ HACCOUNT Finder=(HACCOUNT)lParam;
+
+ if(Finder=NULL) Finder=Plugin->FirstAccount;
+
+// for(;Finder!=NULL && Finder->PluginID!=Plugin->PluginInfo->PluginID;Finder=(HACCOUNT)Finder->Next);
+ return (int)Finder;
+}
+*/
+INT_PTR DeleteAccountSvc(WPARAM wParam,LPARAM lParam)
+{
+//Deleting account works on these steps:
+//1. set signal that account should stop activity (set event)
+// setting this event we achieve, that any access to account is failed,
+// so threads do not start any work with accounts (better saying threads of plugins should not start)
+//2. wait to get write access to chained list of accounts
+//3. we can write to chained list, so we change chain not to show to actual account
+// now, any thread browsing list of accounts does not browse through actual account
+// actual account seems to be hidden (it exists, but it is not in accounts chained list (chained list=queue))
+//Now, we should delete account from memory, BUT!!!
+// Any thread can still be waked up and start asking account synchronizing object
+// If account is deleted, asking about access to read account can throw memory exception (reading for
+// a synchronizing object from memory, that was deleted)
+//So, we cannot now delete account. We have to wait until we are sure no thread will be using account anymore
+// (or to the end of Miranda, but problem is in allocated memory- it is allocated and Miranda is SMALLER, faster, easier, isn't it?)
+// This deleting is achieved in 2 ways:
+// We have event in UsingThreads synchronization objects. This event signals that no thread will use actual account
+// 1. Any thread using account first increment UsingThread, so we know that account is used
+// 2. If thread is about to close, it should decrement UsingThread
+// 3. If thread creates another thread, that will use account, caller has to wait until the new thread does not
+// increment UsingThreads (imagine that caller ends before the new thread set it: if no other thread is using
+// account, account is automaticaly (decreasing UsingThreads) signaled as "not used" and we delete it. But then
+// new thread is going to read account...).
+//4. wait until UsingThread Event is signaled
+//5. delete account from memory
+
+ HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
+ HACCOUNT Which=(HACCOUNT)lParam;
+ HACCOUNT Finder;
+ DWORD tid;
+
+//1. set stop signal
+ StopSignalFcn(Which);
+ WindowList_BroadcastAsync(YAMNVar.MessageWnds,WM_YAMN_STOPACCOUNT,(WPARAM)Which,(LPARAM)0);
+ if(Plugin->Fcn->StopAccountFcnPtr!=NULL)
+ Plugin->Fcn->StopAccountFcnPtr(Which);
+
+//2. wait to get write access
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteAccount:AccountBrowserSO-write wait\n");
+#endif
+ SWMRGWaitToWrite(Plugin->AccountBrowserSO,INFINITE);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteAccount:AccountBrowserSO-write enter\n");
+#endif
+
+//3. remove from queue (chained list)
+ if(Plugin->FirstAccount==NULL)
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteAccount:AccountBrowserSO-write done\n");
+#endif
+ SWMRGDoneWriting(Plugin->AccountBrowserSO);
+ return 0;
+ }
+ if(Plugin->FirstAccount==Which)
+ {
+ Finder=Plugin->FirstAccount->Next;
+ Plugin->FirstAccount=Finder;
+ }
+ else
+ {
+ for(Finder=Plugin->FirstAccount;Which!=Finder->Next;Finder=Finder->Next);
+ Finder->Next=Finder->Next->Next;
+ }
+//leave write access
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteAccount:AccountBrowserSO-write done\n");
+#endif
+ SWMRGDoneWriting(Plugin->AccountBrowserSO);
+
+//4. wait while event "UsingThread" is not signaled
+// And what to do, if this event will be signaled in 1 hour? (Although it's paranoia, because we have sent "delete signal", so
+// other threads do not start any new work with actual account) We will wait in blocked state?
+// No, of course not. We will create new thread, that will wait and additionally remove our thread in background.
+//5. So, the last point (deleting from memory) is performed in new DeleteAccountInBackground thread
+
+ if((Plugin->Fcn!=NULL) && (Plugin->Fcn->WriteAccountsFcnPtr!=NULL))
+ Plugin->Fcn->WriteAccountsFcnPtr();
+ CloseHandle(CreateThread(NULL,0,DeleteAccountInBackground,(LPVOID)Which,0,&tid));
+
+//Now, plugin can consider account as deleted, but plugin really can achieve deleting this account from memory when using
+//event UsingThreads.
+ return 1;
+}
+
+DWORD WINAPI DeleteAccountInBackground(LPVOID Value)
+{
+ HACCOUNT Which=(HACCOUNT)Value;
+ WaitForSingleObject(Which->UsingThreads->Event,INFINITE);
+ CallService(MS_YAMN_DELETEPLUGINACCOUNT,(WPARAM)Which,(LPARAM)0);
+ return 0;
+}
+
+int StopAccounts(HYAMNPROTOPLUGIN Plugin)
+{
+ HACCOUNT Finder;
+
+//1. wait to get write access
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"StopAccounts:AccountBrowserSO-write wait\n");
+#endif
+ SWMRGWaitToWrite(Plugin->AccountBrowserSO,INFINITE);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"StopAccounts:AccountBrowserSO-write enter\n");
+#endif
+ for(Finder=Plugin->FirstAccount;Finder!=NULL;Finder=Finder->Next)
+ {
+//2. set stop signal
+ StopSignalFcn(Finder);
+ WindowList_BroadcastAsync(YAMNVar.MessageWnds,WM_YAMN_STOPACCOUNT,(WPARAM)Finder,(LPARAM)0);
+ if(Plugin->Fcn->StopAccountFcnPtr!=NULL)
+ Plugin->Fcn->StopAccountFcnPtr(Finder);
+ }
+
+//leave write access
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"StopAccounts:AccountBrowserSO-write done\n");
+#endif
+ SWMRGDoneWriting(Plugin->AccountBrowserSO);
+
+//Now, account is stopped. It can be removed from memory...
+ return 1;
+}
+
+int WaitForAllAccounts(HYAMNPROTOPLUGIN Plugin,BOOL GetAccountBrowserAccess)
+{
+ HACCOUNT Finder;
+
+ if(GetAccountBrowserAccess)
+ {
+//1. wait to get write access
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WaitForAllAccounts:AccountBrowserSO-write wait\n");
+#endif
+ SWMRGWaitToWrite(Plugin->AccountBrowserSO,INFINITE);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WaitForAllAccounts:AccountBrowserSO-write enter\n");
+#endif
+ }
+ for(Finder=Plugin->FirstAccount;Finder!=NULL;Finder=Finder->Next)
+ {
+//2. wait for signal that account is not in use
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WaitForAllAccounts:waiting for UsingThreadEV %x (account %x)\n",Finder->UsingThreads,Finder);
+#endif
+ WaitForSingleObject(Finder->UsingThreads->Event,INFINITE);
+ SetEvent(Finder->UsingThreads->Event);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WaitForAllAccounts:UsingThreadEV signaled\n");
+#endif
+ }
+ if(GetAccountBrowserAccess)
+ {
+//leave write access
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"WaitForAllAccounts:AccountBrowserSO-write done\n");
+#endif
+ SWMRGDoneWriting(Plugin->AccountBrowserSO);
+ }
+
+ return 1;
+}
+
+int DeleteAccounts(HYAMNPROTOPLUGIN Plugin)
+{
+ HACCOUNT Finder;
+
+ //1. wait to get write access
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteAccounts:AccountBrowserSO-write wait\n");
+ #endif
+ SWMRGWaitToWrite(Plugin->AccountBrowserSO,INFINITE);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteAccounts:AccountBrowserSO-write enter\n");
+ #endif
+
+ WaitForAllAccounts(Plugin,FALSE);
+
+ for(Finder=Plugin->FirstAccount;Finder!=NULL;)
+ {
+ HACCOUNT Next = Finder->Next;
+ DeletePluginAccountSvc((WPARAM)Finder,(LPARAM)0);
+ Finder = Next;
+ }
+
+ //leave write access
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteAccounts:AccountBrowserSO-write done\n");
+ #endif
+ SWMRGDoneWriting(Plugin->AccountBrowserSO);
+
+ return 1;
+}
+
+void WINAPI GetStatusFcn(HACCOUNT Which,char *Value)
+{
+ if(Which==NULL)
+ return;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tGetStatus:AccountStatusCS-cs wait\n");
+#endif
+ EnterCriticalSection(AccountStatusCS);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tGetStatus:AccountStatusCS-cs enter\n");
+#endif
+ lstrcpy(Value,Which->Status);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tGetStatus:AccountStatusCS-cs done\n");
+#endif
+ LeaveCriticalSection(AccountStatusCS);
+ return;
+}
+
+void WINAPI SetStatusFcn(HACCOUNT Which,char *Value)
+{
+ if(Which==NULL)
+ return;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tSetStatus:AccountStatusCS-cs wait\n");
+#endif
+ EnterCriticalSection(AccountStatusCS);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tSetStatus:AccountStatusCS-cs enter\n");
+#endif
+ lstrcpy(Which->Status,Value);
+ WindowList_BroadcastAsync(YAMNVar.MessageWnds,WM_YAMN_CHANGESTATUS,(WPARAM)Which,(LPARAM)0);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tSetStatus:AccountStatusCS-cs done\n");
+#endif
+ LeaveCriticalSection(AccountStatusCS);
+}
+
+/*
+#ifdef DEBUG_ACCOUNTS
+int GetAccounts()
+{
+ HACCOUNT Finder;
+ int cnt=0;
+
+ for(Finder=Account;Finder!=NULL;Finder=Finder->Next)
+ cnt++;
+ return cnt;
+}
+
+void WriteAccounts()
+{
+ HACCOUNT Finder;
+
+ for(Finder=Account;Finder!=NULL;Finder=Finder->Next)
+ MessageBoxA(NULL,Finder->Name,"Browsing account",MB_OK);
+}
+#endif
+*/
diff --git a/yamn/browser/badconnect.cpp b/yamn/browser/badconnect.cpp new file mode 100644 index 0000000..0da087d --- /dev/null +++ b/yamn/browser/badconnect.cpp @@ -0,0 +1,391 @@ +/*
+ * This code implements window handling (connection error)
+ *
+ * (c) majvan 2002,2004
+ */
+#include <windows.h>
+#include <stdio.h>
+#include <newpluginapi.h>
+#include <m_utils.h>
+#include <m_skin.h>
+#include <m_langpack.h>
+#include <m_database.h>
+#include <m_popup.h>
+#include "../main.h"
+#include "../m_protoplugin.h"
+#include "../m_account.h"
+#include "../debug.h"
+#include "../m_messages.h"
+#include "../mails/m_mails.h"
+#include "../m_yamn.h"
+#include "../resources/resource.h"
+#include "m_browser.h"
+#include <win2k.h>
+
+#define BADCONNECTTITLE "%s - connection error"
+#define BADCONNECTMSG "An error occured. Error code: %d"
+
+//- imported ---------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+extern YAMN_VARIABLES YAMNVar;
+
+//From synchro.cpp
+extern DWORD WINAPI WaitToWriteFcn(PSWMRG SObject,PSCOUNTER SCounter=NULL);
+extern void WINAPI WriteDoneFcn(PSWMRG SObject,PSCOUNTER SCounter=NULL);
+extern DWORD WINAPI WaitToReadFcn(PSWMRG SObject);
+extern void WINAPI ReadDoneFcn(PSWMRG SObject);
+extern DWORD WINAPI SCIncFcn(PSCOUNTER SCounter);
+extern DWORD WINAPI SCDecFcn(PSCOUNTER SCounter);
+
+
+extern HICON hYamnIcons[];
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+//Window callback procedure for popup window (created by popup plugin)
+LRESULT CALLBACK BadConnectPopUpProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) ;
+
+//Dialog callback procedure for bad connection message
+LRESULT CALLBACK DlgProcYAMNBadConnection(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam);
+
+//BadConnection thread function creates window for BadConnection message
+DWORD WINAPI BadConnection(LPVOID Param);
+
+INT_PTR RunBadConnectionSvc(WPARAM wParam,LPARAM lParam);
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+LRESULT CALLBACK BadConnectPopUpProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ DWORD PluginParam;
+ switch(msg)
+ {
+ case WM_COMMAND:
+ if((HIWORD(wParam)==STN_CLICKED) && (CallService(MS_POPUP_GETPLUGINDATA,(WPARAM)hWnd,(LPARAM)&PluginParam))) //if clicked and it's new mail popup window
+ {
+ PROCESS_INFORMATION pi;
+ STARTUPINFOW si;
+ HACCOUNT ActualAccount;
+
+ ZeroMemory(&si,sizeof(si));
+ si.cb=sizeof(si);
+ ActualAccount=(HACCOUNT)CallService(MS_POPUP_GETCONTACT,(WPARAM)hWnd,(LPARAM)0);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"PopUpProc:LEFTCLICK:ActualAccountSO-read wait\n");
+#endif
+ if(WAIT_OBJECT_0==WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"PopUpProc:LEFTCLICK:ActualAccountSO-read enter\n");
+#endif
+ if(ActualAccount->BadConnectN.App!=NULL)
+ {
+ WCHAR *Command;
+ if(ActualAccount->BadConnectN.AppParam!=NULL)
+ Command=new WCHAR[wcslen(ActualAccount->BadConnectN.App)+wcslen(ActualAccount->BadConnectN.AppParam)+6];
+ else
+ Command=new WCHAR[wcslen(ActualAccount->BadConnectN.App)+6];
+
+ if(Command!=NULL)
+ {
+ lstrcpyW(Command,L"\"");
+ lstrcatW(Command,ActualAccount->BadConnectN.App);
+ lstrcatW(Command,L"\" ");
+ if(ActualAccount->BadConnectN.AppParam!=NULL)
+ lstrcatW(Command,ActualAccount->BadConnectN.AppParam);
+ CreateProcessW(NULL,Command,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
+ delete[] Command;
+ }
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"PopUpProc:LEFTCLICK:ActualAccountSO-read done\n");
+#endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+#ifdef DEBUG_SYNCHRO
+ else
+ DebugLog(SynchroFile,"PopUpProc:LEFTCLICK:ActualAccountSO-read enter failed\n");
+#endif
+ SendMessage(hWnd,UM_DESTROYPOPUP,0,0);
+ }
+ break;
+ case UM_FREEPLUGINDATA:
+ //Here we'd free our own data, if we had it.
+ return FALSE;
+ case UM_INITPOPUP:
+ //This is the equivalent to WM_INITDIALOG you'd get if you were the maker of dialog popups.
+ break;
+ case WM_CONTEXTMENU:
+ SendMessage(hWnd,UM_DESTROYPOPUP,0,0);
+ break;
+ case WM_NOTIFY:
+/* switch(((LPNMHDR)lParam)->code)
+ {
+ case NM_CLICK:
+ {
+ }
+ }
+ break;
+*/ default:
+ break;
+ }
+ return DefWindowProc(hWnd,msg,wParam,lParam);
+}
+
+LRESULT CALLBACK DlgProcYAMNBadConnection(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ BOOL ShowPopUp,ShowMsg,ShowIco;
+ HACCOUNT ActualAccount;
+ DWORD ErrorCode;
+ char *TitleStrA;
+ char *Message1A=NULL;
+ WCHAR *Message1W=NULL;
+ POPUPDATAEX BadConnectPopUp;
+
+ ActualAccount=((struct BadConnectionParam *)lParam)->account;
+ ErrorCode=((struct BadConnectionParam *)lParam)->errcode;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read wait\n");
+#endif
+ if(WAIT_OBJECT_0!=WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read wait failed\n");
+#endif
+ return FALSE;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read enter\n");
+#endif
+ TitleStrA=new char[strlen(ActualAccount->Name)+strlen(Translate(BADCONNECTTITLE))];
+ sprintf(TitleStrA,Translate(BADCONNECTTITLE),ActualAccount->Name);
+
+ ShowPopUp=ActualAccount->BadConnectN.Flags & YAMN_ACC_POP;
+ ShowMsg=ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG;
+ ShowIco=ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO;
+
+ if(ShowPopUp)
+ {
+ BadConnectPopUp.lchContact=ActualAccount;
+ BadConnectPopUp.lchIcon=hYamnIcons[3];
+ BadConnectPopUp.colorBack=ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? ActualAccount->BadConnectN.PopUpB : GetSysColor(COLOR_BTNFACE);
+ BadConnectPopUp.colorText=ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? ActualAccount->BadConnectN.PopUpT : GetSysColor(COLOR_WINDOWTEXT);
+ BadConnectPopUp.iSeconds=ActualAccount->BadConnectN.PopUpTime;
+
+ BadConnectPopUp.PluginWindowProc=(WNDPROC)BadConnectPopUpProc;
+ BadConnectPopUp.PluginData=0; //it's bad connect popup
+ lstrcpyn(BadConnectPopUp.lpzContactName,ActualAccount->Name,sizeof(BadConnectPopUp.lpzContactName));
+ }
+
+ if(ActualAccount->Plugin->Fcn!=NULL && ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr!=NULL)
+ {
+ Message1W=ActualAccount->Plugin->Fcn->GetErrorStringWFcnPtr(ErrorCode);
+ SendMessageW(GetDlgItem(hDlg,IDC_STATICMSG),WM_SETTEXT,(WPARAM)0,(LPARAM)Message1W);
+ WideCharToMultiByte(CP_ACP,0,Message1W,-1,(char *)BadConnectPopUp.lpzText,sizeof(BadConnectPopUp.lpzText),NULL,NULL);
+ if(ShowPopUp)
+ CallService(MS_POPUP_ADDPOPUPEX,(WPARAM)&BadConnectPopUp,0);
+ }
+ else if(ActualAccount->Plugin->Fcn!=NULL && ActualAccount->Plugin->Fcn->GetErrorStringAFcnPtr!=NULL)
+ {
+ Message1A=ActualAccount->Plugin->Fcn->GetErrorStringAFcnPtr(ErrorCode);
+ SendMessageA(GetDlgItem(hDlg,IDC_STATICMSG),WM_SETTEXT,(WPARAM)0,(LPARAM)Message1A);
+ lstrcpyn(BadConnectPopUp.lpzText,Message1A,sizeof(BadConnectPopUp.lpzText));
+ if(ShowPopUp)
+ CallService(MS_POPUP_ADDPOPUPEX,(WPARAM)&BadConnectPopUp,0);
+ }
+ else
+ {
+ Message1A=Translate("Unknown error");
+ SendMessageA(GetDlgItem(hDlg,IDC_STATICMSG),WM_SETTEXT,(WPARAM)0,(LPARAM)Message1A);
+ lstrcpyn(BadConnectPopUp.lpzText,Message1A,sizeof(BadConnectPopUp.lpzText));
+ if(ShowPopUp)
+ CallService(MS_POPUP_ADDPOPUPEX,(WPARAM)&BadConnectPopUp,0);
+ }
+
+ if(!ShowMsg && !ShowIco)
+ DestroyWindow(hDlg);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read done\n");
+#endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+
+ SendMessage(hDlg,WM_SETTEXT,(WPARAM)0,(LPARAM)TitleStrA);
+ delete[] TitleStrA;
+ if(Message1A!=NULL)
+ delete[] Message1A;
+ if(ActualAccount->Plugin->Fcn!=NULL && ActualAccount->Plugin->Fcn->DeleteErrorStringFcnPtr!=NULL && Message1A!=NULL)
+ ActualAccount->Plugin->Fcn->DeleteErrorStringFcnPtr(Message1A);
+ if(ActualAccount->Plugin->Fcn!=NULL && ActualAccount->Plugin->Fcn->DeleteErrorStringFcnPtr!=NULL && Message1W!=NULL)
+ ActualAccount->Plugin->Fcn->DeleteErrorStringFcnPtr(Message1W);
+ return 0;
+ }
+ case WM_DESTROY:
+ {
+ NOTIFYICONDATA nid;
+
+ ZeroMemory(&nid,sizeof(NOTIFYICONDATA));
+ nid.cbSize=sizeof(NOTIFYICONDATA);
+ nid.hWnd=hDlg;
+ nid.uID=0;
+ Shell_NotifyIcon(NIM_DELETE,&nid);
+ PostQuitMessage(0);
+ break;
+ }
+ case WM_YAMN_NOTIFYICON:
+ switch (lParam)
+ {
+ case WM_LBUTTONDBLCLK:
+ ShowWindow(hDlg,SW_SHOWNORMAL);
+ SetForegroundWindow(hDlg);
+ break;
+ }
+ return 0;
+ case WM_CHAR:
+ switch((TCHAR)wParam)
+ {
+ case 27:
+ case 13:
+ DestroyWindow(hDlg);
+ break;
+ }
+ break;
+ case WM_SYSCOMMAND:
+ switch(wParam)
+ {
+ case SC_CLOSE:
+ DestroyWindow(hDlg);
+ break;
+ }
+ case WM_COMMAND:
+ {
+ WORD wNotifyCode = HIWORD(wParam);
+ switch(LOWORD(wParam))
+ {
+ case IDC_BTNOK:
+ DestroyWindow(hDlg);
+ break;
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+DWORD WINAPI BadConnection(LPVOID Param)
+{
+ MSG msg;
+ HWND hBadConnect;
+ HACCOUNT ActualAccount;
+ struct BadConnectionParam MyParam;
+ NOTIFYICONDATA nid;
+ TCHAR *NotIconText=Translate(" - connection error");
+ TCHAR *src,*dest;
+ int i;
+
+ MyParam=*(struct BadConnectionParam *)Param;
+ ActualAccount=MyParam.account;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"BadConnect:Incrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+#endif
+ SCIncFcn(ActualAccount->UsingThreads);
+
+// we will not use params in stack anymore
+ SetEvent(MyParam.ThreadRunningEV);
+
+ __try
+ {
+ hBadConnect=CreateDialogParam(YAMNVar.hInst,MAKEINTRESOURCE(IDD_DLGBADCONNECT),NULL,(DLGPROC)DlgProcYAMNBadConnection,(LPARAM)&MyParam);
+ SendMessage(hBadConnect,WM_SETICON,ICON_BIG,(LPARAM)hYamnIcons[3]);
+ SendMessage(hBadConnect,WM_SETICON,ICON_SMALL,(LPARAM)hYamnIcons[3]);
+
+ ZeroMemory(&nid,sizeof(nid));
+ nid.cbSize=sizeof(NOTIFYICONDATA);
+ nid.hWnd=hBadConnect;
+ nid.hIcon=hYamnIcons[3];
+ nid.uID=0;
+ nid.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;
+ nid.uCallbackMessage=WM_YAMN_NOTIFYICON;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read wait\n");
+#endif
+ if(WAIT_OBJECT_0!=WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read wait failed\n");
+#endif
+ return 0;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read enter\n");
+#endif
+ for(src=ActualAccount->Name,dest=nid.szTip,i=0;(*src!=(TCHAR)0) && (i+1<sizeof(nid.szTip));*dest++=*src++);
+ for(src=NotIconText;(*src!=(TCHAR)0) && (i+1<sizeof(nid.szTip));*dest++=*src++);
+ *dest=(TCHAR)0;
+
+ if(ActualAccount->BadConnectN.Flags & YAMN_ACC_SND)
+ CallService(MS_SKIN_PLAYSOUND,0,(LPARAM)YAMN_CONNECTFAILSOUND);
+ if(ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG)
+ ShowWindow(hBadConnect,SW_SHOWNORMAL);
+ if(ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO)
+ Shell_NotifyIcon(NIM_ADD,&nid);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"BadConnect:ActualAccountSO-read done\n");
+#endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+
+ UpdateWindow(hBadConnect);
+ while(GetMessage(&msg,NULL,0,0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+// now, write to file. Why? Because we want to write when was new mail last checked
+ if((ActualAccount->Plugin->Fcn!=NULL) && (ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr!=NULL) && ActualAccount->AbleToWork)
+ ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr();
+ }
+ __finally
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"BadConnect:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+#endif
+ SCDecFcn(ActualAccount->UsingThreads);
+ }
+ return 0;
+}
+
+
+INT_PTR RunBadConnectionSvc(WPARAM wParam,LPARAM lParam)
+{
+ DWORD tid;
+//an event for successfull copy parameters to which point a pointer in stack for new thread
+ HANDLE ThreadRunningEV;
+ PYAMN_BADCONNECTIONPARAM Param=(PYAMN_BADCONNECTIONPARAM)wParam;
+
+ if((DWORD)lParam!=YAMN_BADCONNECTIONVERSION)
+ return 0;
+
+ if(NULL!=(ThreadRunningEV=CreateEvent(NULL,FALSE,FALSE,NULL)))
+ {
+ HANDLE NewThread;
+
+ Param->ThreadRunningEV=ThreadRunningEV;
+ if(NULL!=(NewThread=CreateThread(NULL,0,BadConnection,Param,0,&tid)))
+ {
+ WaitForSingleObject(ThreadRunningEV,INFINITE);
+ CloseHandle(NewThread);
+ }
+ CloseHandle(ThreadRunningEV);
+
+ return 1;
+ }
+ return 0;
+}
diff --git a/yamn/browser/m_browser.h b/yamn/browser/m_browser.h new file mode 100644 index 0000000..d4c5191 --- /dev/null +++ b/yamn/browser/m_browser.h @@ -0,0 +1,42 @@ +#ifndef __MAILBROWSER_H
+#define __MAILBROWSER_H
+
+#include "../m_account.h"
+#include "../debug.h"
+
+typedef struct MailBrowserWinParam
+{
+#define YAMN_MAILBROWSERVERSION 1
+ HANDLE ThreadRunningEV;
+ HACCOUNT account;
+ DWORD nflags; //flags YAMN_ACC_??? when new mails
+ DWORD nnflags; //flags YAMN_ACC_??? when no new mails
+ void *Param;
+} YAMN_MAILBROWSERPARAM,*PYAMN_MAILBROWSERPARAM;
+
+typedef struct MailShowMsgWinParam
+{
+ HANDLE ThreadRunningEV;
+ HACCOUNT account;
+ HYAMNMAIL mail;
+} YAMN_MAILSHOWPARAM, *PYAMN_MAILSHOWPARAM;
+
+typedef struct NoNewMailParam
+{
+#define YAMN_NONEWMAILVERSION 1
+ HANDLE ThreadRunningEV;
+ HACCOUNT account;
+ DWORD flags;
+ void *Param;
+} YAMN_NONEWMAILPARAM,*PYAMN_NONEWMAILPARAM;
+
+typedef struct BadConnectionParam
+{
+#define YAMN_BADCONNECTIONVERSION 1
+ HANDLE ThreadRunningEV;
+ HACCOUNT account;
+ UINT_PTR errcode;
+ void *Param;
+} YAMN_BADCONNECTIONPARAM,*PYAMN_BADCONNECTIONPARAM;
+
+#endif
diff --git a/yamn/browser/mailbrowser.cpp b/yamn/browser/mailbrowser.cpp new file mode 100644 index 0000000..aaa1fbb --- /dev/null +++ b/yamn/browser/mailbrowser.cpp @@ -0,0 +1,2692 @@ +/*
+ * This code implements window handling (new mail)
+ *
+ * (c) majvan 2002-2004
+ */
+/* There can be problems when compiling this file, because in this file
+ * we are using both unicode and no-unicode functions and compiler does not
+ * like it in one file
+ * When you got errors, try to comment the #define <stdio.h> and compile, then
+ * put it back to uncommented and compile again :)
+ */
+#ifndef _WIN32_IE
+ #define _WIN32_IE 0x0400
+#endif
+#ifndef _WIN32_WINNT
+ #define _WIN32_WINNT 0x0501
+#endif
+
+
+#include <windows.h>
+#include <stdio.h>
+#include <stddef.h>
+#undef UNICODE
+#include <newpluginapi.h>
+#include <m_utils.h>
+#include <m_skin.h>
+#include <m_langpack.h>
+#include <m_database.h>
+#include <m_clist.h>
+#include <m_popup.h>
+#include "../include/m_kbdnotify.h"
+#include "../main.h"
+#include "../m_protoplugin.h"
+#include "../m_account.h"
+#include "../debug.h"
+#include "../m_messages.h"
+#include "../mails/m_mails.h"
+#include "../m_yamn.h"
+#include "../resources/resource.h"
+#include <win2k.h>
+
+#undef UNICODE
+#include "m_browser.h"
+
+#ifndef UNICODE
+ #define UNICODE
+ #define _UNICODE
+ #include <commctrl.h> //we need to have unicode commctrl.h
+ #include <stdio.h>
+ #undef _UNICODE
+ #undef UNICODE
+#else
+ #include <commctrl.h>
+ #undef _UNICODE
+ #undef UNICODE
+#endif
+
+
+#ifndef SIZEOF
+ #ifdef UNICODE
+ #define SIZEOF(x) (sizeof(x)/sizeof(WCHAR))
+ #else
+ #define SIZEOF(x) sizeof(x)
+ #endif
+#endif
+
+#define TIMER_FLASHING 0x09061979
+#define MAILBROWSER_MINXSIZE 200 //min size of mail browser window
+#define MAILBROWSER_MINYSIZE 130
+
+//- imported ---------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+extern char *ProtoName;
+extern HYAMNPROTOPLUGIN POP3Plugin;
+
+extern HANDLE hNewMailHook;
+extern HANDLE WriteToFileEV;
+extern YAMN_VARIABLES YAMNVar;
+extern HICON hYamnIcons[];
+//From synchro.cpp
+extern DWORD WINAPI WaitToWriteFcn(PSWMRG SObject,PSCOUNTER SCounter=NULL);
+extern void WINAPI WriteDoneFcn(PSWMRG SObject,PSCOUNTER SCounter=NULL);
+extern DWORD WINAPI WaitToReadFcn(PSWMRG SObject);
+extern void WINAPI ReadDoneFcn(PSWMRG SObject);
+extern DWORD WINAPI SCIncFcn(PSCOUNTER SCounter);
+extern DWORD WINAPI SCDecFcn(PSCOUNTER SCounter);
+//From mails.cpp
+extern void WINAPI DeleteMessageFromQueueFcn(HYAMNMAIL *From,HYAMNMAIL Which,int mode);
+extern void WINAPI SetRemoveFlagsInQueueFcn(HYAMNMAIL From,DWORD FlagsSet,DWORD FlagsNotSet,DWORD FlagsToSet,int mode);
+//From mime.cpp
+void ExtractHeader(struct CMimeItem *items,int &CP,struct CHeader *head);
+void ExtractShortHeader(struct CMimeItem *items,struct CShortHeader *head);
+void DeleteHeaderContent(struct CHeader *head);
+void DeleteShortHeaderContent(struct CShortHeader *head);
+char *ExtractFromContentType(char *ContentType,char *value);
+WCHAR *ParseMultipartBody(char *src, char *bond);
+//From account.cpp
+void WINAPI GetStatusFcn(HACCOUNT Which,char *Value);
+//from decode.cpp
+int DecodeQuotedPrintable(char *Src,char *Dst,int DstLen, BOOL isQ);
+int DecodeBase64(char *Src,char *Dst,int DstLen);
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+char* s_MonthNames[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+bool bDate = false,bSub=false,bSize=false,bFrom=false;
+int PosX=0,PosY=0,SizeX=460,SizeY=100;
+int HeadSizeX = 0x2b2, HeadSizeY = 0x0b5, HeadPosX = 100, HeadPosY = 100;
+int HeadSplitPos=250; // per-mils of the size
+static int FromWidth=250,SubjectWidth=280,SizeWidth=50,SizeDate=205;
+unsigned char optDateTime = (SHOWDATELONG | SHOWDATENOTODAY);
+
+static WNDPROC OldListViewSubclassProc;
+
+struct CMailNumbersSub
+{
+ int Total; //any mail
+ int New; //uses YAMN_MSG_NEW flag
+ int UnSeen; //uses YAMN_MSG_UNSEEN flag
+// int Browser; //uses YAMN_MSG_BROWSER flag
+ int BrowserUC; //uses YAMN_MSG_BROWSER flag and YAMN_MSG_UNSEEN flag
+ int Display; //uses YAMN_MSG_DISPLAY flag
+ int DisplayTC; //uses YAMN_MSG_DISPLAY flag and YAMN_MSG_DISPLAYC flag
+ int DisplayUC; //uses YAMN_MSG_DISPLAY flag and YAMN_MSG_DISPLAYC flag and YAMN_MSG_UNSEEN flag
+ int PopUp; //uses YAMN_MSG_POPUP flag
+ int PopUpTC; //uses YAMN_MSG_POPUPC flag
+ int PopUpNC; //uses YAMN_MSG_POPUPC flag and YAMN_MSG_NEW flag
+ int PopUpRun; //uses YAMN_MSG_POPUP flag and YAMN_MSG_NEW flag
+ int PopUpSL2NC; //uses YAMN_MSG_SPAML2 flag and YAMN_MSG_NEW flag
+ int PopUpSL3NC; //uses YAMN_MSG_SPAML3 flag and YAMN_MSG_NEW flag
+// int SysTray; //uses YAMN_MSG_SYSTRAY flag
+ int SysTrayUC; //uses YAMN_MSG_SYSTRAY flag and YAMN_MSG_UNSEEN flag
+// int Sound; //uses YAMN_MSG_SOUND flag
+ int SoundNC; //uses YAMN_MSG_SOUND flag and YAMN_MSG_NEW flag
+// int App; //uses YAMN_MSG_APP flag
+ int AppNC; //uses YAMN_MSG_APP flag and YAMN_MSG_NEW flag
+ int EventNC; //uses YAMN_MSG_NEVENT flag and YAMN_MSG_NEW flag
+};
+
+struct CMailNumbers
+{
+ struct CMailNumbersSub Real;
+ struct CMailNumbersSub Virtual;
+};
+
+struct CMailWinUserInfo
+{
+ HACCOUNT Account;
+ int TrayIconState;
+ BOOL UpdateMailsMessagesAccess;
+ BOOL Seen;
+ BOOL RunFirstTime;
+};
+
+struct CChangeContent
+{
+ DWORD nflags;
+ DWORD nnflags;
+};
+
+struct CUpdateMails
+{
+ struct CChangeContent *Flags;
+ BOOL Waiting;
+ HANDLE Copied;
+};
+struct CSortList
+{
+ HWND hDlg;
+ int iSubItem;
+};
+
+//Retrieves HACCOUNT, whose mails are displayed in ListMails
+// hLM- handle of dialog window
+// returns handle of account
+inline HACCOUNT GetWindowAccount(HWND hDialog);
+
+//Looks to mail flags and increment mail counter (e.g. if mail is new, increments the new mail counter
+// msgq- mail, which increments the counters
+// MN- counnters structure
+void IncrementMailCounters(HYAMNMAIL msgq,struct CMailNumbers *MN);
+
+enum
+{
+ UPDATE_FAIL=0, //function failed
+ UPDATE_NONE, //none update has been performed
+ UPDATE_OK, //some changes occured, update performed
+};
+//Just looks for mail changes in account and update the mail browser window
+// hDlg- dialog handle
+// ActualAccount- account handle
+// nflags- flags what to do when new mail arrives
+// nnflags- flags what to do when no new mail arrives
+// returns one of UPDATE_XXX value(not implemented yet)
+int UpdateMails(HWND hDlg,HACCOUNT ActualAccount,DWORD nflags,DWORD nnflags);
+
+//When new mail occurs, shows window, plays sound, runs application...
+// hDlg- dialog handle. Dialog of mailbrowser is already created and actions are performed over this window
+// ActualAccount- handle of account, whose mails are to be notified
+// MN- statistics of mails in account
+// nflags- what to do or not to do (e.g. to show mailbrowser window or prohibit to show)
+// nflags- flags what to do when new mail arrives
+// nnflags- flags what to do when no new mail arrives
+void DoMailActions(HWND hDlg,HACCOUNT ActualAccount,struct CMailNumbers *MN,DWORD nflags,DWORD nnflags);
+
+//Looks for items in mailbrowser and if they were deleted, delete them from browser window
+// hListView- handle of listview window
+// ActualAccount- handle of account, whose mails are show
+// MailNumbers- pointer to structure, in which function stores numbers of mails with some property
+// returns one of UPDATE_XXX value (not implemented yet)
+int ChangeExistingMailStatus(HWND hListView,HACCOUNT ActualAccount,struct CMailNumbers *MN);
+
+//Adds new mails to ListView and if any new, shows multi popup (every new message is new popup window created by popup plugin)
+// hListView- handle of listview window
+// ActualAccount- handle of account, whose mails are show
+// NewMailPopUp- pointer to prepared structure for popup plugin, can be NULL if no popup show
+// MailNumbers- pointer to structure, in which function stores numbers of mails with some property
+// nflags- flags what to do when new mail arrives
+// returns one of UPDATE_XXX value (not implemented yet)
+int AddNewMailsToListView(HWND hListView,HACCOUNT ActualAccount,struct CMailNumbers *MailNumbers,DWORD nflags);
+
+//Window callback procedure for popup window (created by popup plugin)
+LRESULT CALLBACK NewMailPopUpProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
+
+//Window callback procedure for popup window (created by popup plugin)
+LRESULT CALLBACK NoNewMailPopUpProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
+
+//Dialog callback procedure for mail browser
+BOOL CALLBACK DlgProcYAMNMailBrowser(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam);
+
+//MailBrowser thread function creates window if needed, tray icon and plays sound
+DWORD WINAPI MailBrowser(LPVOID Param);
+
+LRESULT CALLBACK ListViewSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//Runs mail browser in new thread
+INT_PTR RunMailBrowserSvc(WPARAM,LPARAM);
+
+#define YAMN_BROWSER_SHOWPOPUP 0x01
+
+ // list view items' order criteria
+ #define LVORDER_NOORDER -1
+ #define LVORDER_STRING 0
+ #define LVORDER_NUMERIC 1
+ #define LVORDER_DATETIME 2
+
+ // list view order direction
+ #define LVORDER_ASCENDING 1
+ #define LVORDER_NONE 0
+ #define LVORDER_DESCENDING -1
+
+ // list view sort type
+ #define LVSORTPRIORITY_NONE -1
+
+ // List view column info.
+ typedef struct _SAMPLELISTVIEWCOLUMN
+ {
+ UINT uCXCol; // index
+ int nSortType; // sorting type (STRING = 0, NUMERIC, DATE, DATETIME)
+ int nSortOrder; // sorting order (ASCENDING = -1, NONE, DESCENDING)
+ int nPriority; // sort priority (-1 for none, 0, 1, ..., nColumns - 1 maximum)
+ TCHAR lpszName[128]; // column name
+ } SAMPLELISTVIEWCOLUMN;
+
+ // Compare priority
+ typedef struct _LVCOMPAREINFO
+ {
+ int iIdx; // Index
+ int iPriority; // Priority
+ } LVCOMPAREINFO, *LPLVCOMPAREINFO;
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+LPARAM readItemLParam(HWND hwnd,DWORD iItem)
+{
+ LVITEM item;
+
+ item.mask = LVIF_PARAM;
+ item.iItem = iItem;
+ item.iSubItem = 0;
+ SendMessage(hwnd,LVM_GETITEM,0,(LPARAM)&item);
+ return item.lParam;
+}
+
+inline HACCOUNT GetWindowAccount(HWND hDlg)
+{
+ struct CMailWinUserInfo *mwui;
+
+ if(NULL==(mwui=(struct CMailWinUserInfo *)GetWindowLongPtr(hDlg,DWLP_USER)))
+ return NULL;
+ return mwui->Account;
+}
+
+void IncrementMailCounters(HYAMNMAIL msgq,struct CMailNumbers *MN)
+{
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.Total++;
+ else
+ MN->Real.Total++;
+
+ if(msgq->Flags & YAMN_MSG_NEW)
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.New++;
+ else
+ MN->Real.New++;
+ if(msgq->Flags & YAMN_MSG_UNSEEN)
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.UnSeen++;
+ else
+ MN->Real.UnSeen++;
+ if((msgq->Flags & (YAMN_MSG_UNSEEN | YAMN_MSG_BROWSER)) == (YAMN_MSG_UNSEEN | YAMN_MSG_BROWSER))
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.BrowserUC++;
+ else
+ MN->Real.BrowserUC++;
+ if(msgq->Flags & YAMN_MSG_DISPLAY)
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.Display++;
+ else
+ MN->Real.Display++;
+ if((msgq->Flags & (YAMN_MSG_DISPLAYC | YAMN_MSG_DISPLAY)) == (YAMN_MSG_DISPLAYC | YAMN_MSG_DISPLAY))
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.DisplayTC++;
+ else
+ MN->Real.DisplayTC++;
+ if((msgq->Flags & (YAMN_MSG_UNSEEN | YAMN_MSG_DISPLAYC | YAMN_MSG_DISPLAY)) == (YAMN_MSG_UNSEEN | YAMN_MSG_DISPLAYC | YAMN_MSG_DISPLAY))
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.DisplayUC++;
+ else
+ MN->Real.DisplayUC++;
+ if(msgq->Flags & YAMN_MSG_POPUP)
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.PopUp++;
+ else
+ MN->Real.PopUp++;
+ if((msgq->Flags & YAMN_MSG_POPUPC) == YAMN_MSG_POPUPC)
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.PopUpTC++;
+ else
+ MN->Real.PopUpTC++;
+ if((msgq->Flags & (YAMN_MSG_NEW | YAMN_MSG_POPUPC)) == (YAMN_MSG_NEW | YAMN_MSG_POPUPC))
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.PopUpNC++;
+ else
+ MN->Real.PopUpNC++;
+ if((msgq->Flags & (YAMN_MSG_NEW | YAMN_MSG_POPUP)) == (YAMN_MSG_NEW | YAMN_MSG_POPUP))
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.PopUpRun++;
+ else
+ MN->Real.PopUpRun++;
+ if((msgq->Flags & YAMN_MSG_NEW) && YAMN_MSG_SPAML(msgq->Flags,YAMN_MSG_SPAML2))
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.PopUpSL2NC++;
+ else
+ MN->Real.PopUpSL2NC++;
+ if((msgq->Flags & YAMN_MSG_NEW) && YAMN_MSG_SPAML(msgq->Flags,YAMN_MSG_SPAML3))
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.PopUpSL3NC++;
+ else
+ MN->Real.PopUpSL3NC++;
+/* if(msgq->MailData->Flags & YAMN_MSG_SYSTRAY)
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.SysTray++;
+ else
+ MN->Real.SysTray++;
+*/ if((msgq->Flags & (YAMN_MSG_UNSEEN | YAMN_MSG_SYSTRAY)) == (YAMN_MSG_UNSEEN|YAMN_MSG_SYSTRAY))
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.SysTrayUC++;
+ else
+ MN->Real.SysTrayUC++;
+/* if(msgq->MailData->Flags & YAMN_MSG_SOUND)
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.Sound++;
+ else
+ MN->Real.Sound++;
+*/ if((msgq->Flags & (YAMN_MSG_NEW|YAMN_MSG_SOUND)) == (YAMN_MSG_NEW|YAMN_MSG_SOUND))
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.SoundNC++;
+ else
+ MN->Real.SoundNC++;
+/* if(msgq->MailData->Flags & YAMN_MSG_APP)
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.App++;
+ else
+ MN->Real.App++;
+*/ if((msgq->Flags & (YAMN_MSG_NEW|YAMN_MSG_APP)) == (YAMN_MSG_NEW|YAMN_MSG_APP))
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.AppNC++;
+ else
+ MN->Real.AppNC++;
+ if((msgq->Flags & (YAMN_MSG_NEW|YAMN_MSG_NEVENT)) == (YAMN_MSG_NEW|YAMN_MSG_NEVENT))
+ if(msgq->Flags & YAMN_MSG_VIRTUAL)
+ MN->Virtual.EventNC++;
+ else
+ MN->Real.EventNC++;
+}
+
+int UpdateMails(HWND hDlg,HACCOUNT ActualAccount,DWORD nflags,DWORD nnflags)
+{
+#define MAILBROWSERTITLE "%s - %d new mail messages, %d total"
+
+ struct CMailWinUserInfo *mwui;
+ struct CMailNumbers MN;
+
+ HYAMNMAIL msgq;
+ BOOL Loaded;
+ BOOL RunMailBrowser,RunPopUps;
+
+ mwui=(struct CMailWinUserInfo *)GetWindowLongPtr(hDlg,DWLP_USER);
+ //now we ensure read access for account and write access for its mails
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"UpdateMails:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"UpdateMails:ActualAccountSO-read wait failed\n");
+ #endif
+ PostMessage(hDlg,WM_DESTROY,(WPARAM)0,(LPARAM)0);
+
+ return UPDATE_FAIL;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"UpdateMails:ActualAccountSO-read enter\n");
+ #endif
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"UpdateMails:ActualAccountMsgsSO-write wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=WaitToWriteFcn(ActualAccount->MessagesAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"UpdateMails:ActualAccountMsgsSO-write wait failed\n");
+ DebugLog(SynchroFile,"UpdateMails:ActualAccountSO-read done\n");
+ #endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+
+ PostMessage(hDlg,WM_DESTROY,(WPARAM)0,(LPARAM)0);
+ return UPDATE_FAIL;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"UpdateMails:ActualAccountMsgsSO-write enter\n");
+ #endif
+
+ ZeroMemory(&MN,sizeof(MN));
+
+ for(msgq=(HYAMNMAIL)ActualAccount->Mails;msgq!=NULL;msgq=msgq->Next)
+ {
+ if(!LoadedMailData(msgq)) //check if mail is already in memory
+ {
+ Loaded=false;
+ if(NULL==LoadMailData(msgq)) //if we could not load mail to memory, consider this mail deleted and do not display it
+ continue;
+ }
+ else
+ Loaded=true;
+
+ IncrementMailCounters(msgq,&MN);
+
+ if(!Loaded)
+ UnloadMailData(msgq); //do not keep data for mail in memory
+ }
+
+ if(mwui!=NULL)
+ mwui->UpdateMailsMessagesAccess=TRUE;
+
+ //Now we are going to check if extracting data from mail headers are needed.
+ //If popups will be displayed or mailbrowser window
+ if ((((mwui!=NULL) && !(mwui->RunFirstTime)) &&
+ (
+ ((nnflags & YAMN_ACC_MSGP) && !(MN.Real.BrowserUC+MN.Virtual.BrowserUC)) ||
+ ((nflags & YAMN_ACC_MSGP) && (MN.Real.BrowserUC+MN.Virtual.BrowserUC))
+ )
+ ) || //if mail window was displayed before and flag YAMN_ACC_MSGP is set
+ ((nnflags & YAMN_ACC_MSG) && !(MN.Real.BrowserUC+MN.Virtual.BrowserUC)) || //if needed to run mailbrowser when no unseen and no unseen mail found
+ ((nflags & YAMN_ACC_MSG) && (MN.Real.BrowserUC+MN.Virtual.BrowserUC)) || //if unseen mails found, we sure run mailbrowser
+ ((nflags & YAMN_ACC_ICO) && (MN.Real.SysTrayUC+MN.Virtual.SysTrayUC))
+ ) //if needed to run systray
+ RunMailBrowser=TRUE;
+ else RunMailBrowser=FALSE;
+
+ if( (nflags & YAMN_ACC_POP) &&
+ (ActualAccount->Flags & YAMN_ACC_POPN) &&
+ (MN.Real.PopUpNC+MN.Virtual.PopUpNC) ) //if some popups with mails are needed to show
+ RunPopUps=TRUE;
+ else RunPopUps=FALSE;
+
+ if(RunMailBrowser)
+ ChangeExistingMailStatus(GetDlgItem(hDlg,IDC_LISTMAILS),ActualAccount,&MN);
+ if(RunMailBrowser || RunPopUps)
+ AddNewMailsToListView(hDlg==NULL ? NULL : GetDlgItem(hDlg,IDC_LISTMAILS),ActualAccount,&MN,nflags);
+
+ if(RunMailBrowser)
+ {
+ WCHAR *TitleStrW;
+ char *TitleStrA;
+ size_t len = strlen(ActualAccount->Name)+strlen(Translate(MAILBROWSERTITLE))+10; //+10 chars for numbers
+ TitleStrA=new char[len];
+ TitleStrW=new WCHAR[len];
+
+ sprintf(TitleStrA,Translate(MAILBROWSERTITLE),ActualAccount->Name,MN.Real.DisplayUC+MN.Virtual.DisplayUC,MN.Real.Display+MN.Virtual.Display);
+ MultiByteToWideChar(CP_ACP,MB_USEGLYPHCHARS,TitleStrA,-1,TitleStrW,(int)strlen(TitleStrA)+1);
+ SendMessageW(hDlg,WM_SETTEXT,(WPARAM)0,(LPARAM)TitleStrW);
+ delete[] TitleStrA;
+ delete[] TitleStrW;
+ }
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"UpdateMails:Do mail actions\n");
+ #endif
+
+ DoMailActions(hDlg,ActualAccount,&MN,nflags,nnflags);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"UpdateMails:Do mail actions done\n");
+ #endif
+
+ SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails,YAMN_MSG_NEW,0,YAMN_MSG_NEW,YAMN_FLAG_REMOVE); //rempve the new flag
+ if(!RunMailBrowser)
+ SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails,YAMN_MSG_UNSEEN,YAMN_MSG_STAYUNSEEN,YAMN_MSG_UNSEEN,YAMN_FLAG_REMOVE); //remove the unseen flag when it was not displayed and it has not "stay unseen" flag set
+
+ if(mwui!=NULL)
+ {
+ mwui->UpdateMailsMessagesAccess=FALSE;
+ mwui->RunFirstTime=FALSE;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"UpdateMails:ActualAccountMsgsSO-write done\n");
+ DebugLog(SynchroFile,"UpdateMails:ActualAccountSO-read done\n");
+ #endif
+ WriteDoneFcn(ActualAccount->MessagesAccessSO);
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+
+ if(RunMailBrowser)
+ UpdateWindow(GetDlgItem(hDlg,IDC_LISTMAILS));
+ else if(hDlg!=NULL)
+ DestroyWindow(hDlg);
+
+ return 1;
+}
+
+int ChangeExistingMailStatus(HWND hListView,HACCOUNT ActualAccount,struct CMailNumbers *MN)
+{
+ int i,in;
+ LVITEMW item;
+ HYAMNMAIL mail,msgq;
+
+ in=ListView_GetItemCount(hListView);
+ item.mask=LVIF_PARAM;
+
+ for(i=0;i<in;i++)
+ {
+ item.iItem=i;
+ item.iSubItem=0;
+ if(TRUE==ListView_GetItem(hListView,&item))
+ mail=(HYAMNMAIL)item.lParam;
+ else
+ continue;
+ for(msgq=(HYAMNMAIL)ActualAccount->Mails;(msgq!=NULL)&&(msgq!=mail);msgq=msgq->Next); //found the same mail in account queue
+ if(msgq==NULL) //if mail was not found
+ if(TRUE==ListView_DeleteItem(hListView,i))
+ {
+ in--;i--;
+ continue;
+ }
+ }
+
+ return TRUE;
+}
+
+void MimeDateToLocalizedDateTime(char *datein, WCHAR *dateout, int lendateout);
+int AddNewMailsToListView(HWND hListView,HACCOUNT ActualAccount,struct CMailNumbers *MN,DWORD nflags)
+{
+ HYAMNMAIL msgq;
+ POPUPDATAEX NewMailPopUp = {0};
+
+ WCHAR *FromStr;
+ WCHAR SizeStr[20];
+ WCHAR LocalDateStr[128];
+
+ LVITEMW item;
+ LVFINDINFO fi;
+
+ int foundi,lfoundi;
+ struct CHeader UnicodeHeader;
+ BOOL Loaded,Extracted,FromStrNew=FALSE;
+
+ ZeroMemory(&item,sizeof(item));
+ ZeroMemory(&UnicodeHeader,sizeof(UnicodeHeader));
+
+ if(hListView!=NULL)
+ {
+ item.mask=LVIF_TEXT | LVIF_PARAM;
+ item.iItem=0;
+ ZeroMemory(&fi,sizeof(fi));
+ fi.flags=LVFI_PARAM; //let's go search item by lParam number
+ lfoundi=0;
+ }
+
+ NewMailPopUp.lchContact=(ActualAccount->hContact != NULL) ? ActualAccount->hContact : ActualAccount;
+ NewMailPopUp.lchIcon=hYamnIcons[2];
+ NewMailPopUp.colorBack=nflags & YAMN_ACC_POPC ? ActualAccount->NewMailN.PopUpB : GetSysColor(COLOR_BTNFACE);
+ NewMailPopUp.colorText=nflags & YAMN_ACC_POPC ? ActualAccount->NewMailN.PopUpT : GetSysColor(COLOR_WINDOWTEXT);
+ NewMailPopUp.iSeconds=ActualAccount->NewMailN.PopUpTime;
+
+ NewMailPopUp.PluginWindowProc=(WNDPROC)NewMailPopUpProc;
+ NewMailPopUp.PluginData=(void *)0; //it's new mail popup
+
+ for(msgq=(HYAMNMAIL)ActualAccount->Mails;msgq!=NULL;msgq=msgq->Next,lfoundi++)
+ {
+// now we hide mail pointer to item's lParam member. We can later use it to retrieve mail datas
+
+ Extracted=FALSE;FromStr=NULL;FromStrNew=FALSE;
+
+ if(hListView!=NULL)
+ {
+ fi.lParam=(LPARAM)msgq;
+ if(-1!=(foundi=ListView_FindItem(hListView,-1,&fi))) //if mail is already in window
+ {
+ lfoundi=foundi;
+ continue; //do not insert any item
+ }
+
+ item.iItem=lfoundi; //insert after last found item
+ item.lParam=(LPARAM)msgq;
+ }
+
+ if(!LoadedMailData(msgq)) //check if mail is already in memory
+ {
+ Loaded=false;
+ if(NULL==LoadMailData(msgq)) //if we could not load mail to memory, consider this mail deleted and do not display it
+ continue;
+ }
+ else
+ Loaded=true;
+
+ if(((hListView!=NULL) && (msgq->Flags & YAMN_MSG_DISPLAY)) ||
+ ((nflags & YAMN_ACC_POP) && (ActualAccount->Flags & YAMN_ACC_POPN) && (msgq->Flags & YAMN_MSG_POPUP) && (msgq->Flags & YAMN_MSG_NEW)))
+ {
+
+ if(!Extracted) ExtractHeader(msgq->MailData->TranslatedHeader,msgq->MailData->CP,&UnicodeHeader);
+ Extracted=TRUE;
+
+ if((UnicodeHeader.From!=NULL) && (UnicodeHeader.FromNick!=NULL))
+ {
+ FromStr=new WCHAR[wcslen(UnicodeHeader.From)+wcslen(UnicodeHeader.FromNick)+4];
+ swprintf(FromStr,L"%s <%s>",UnicodeHeader.FromNick,UnicodeHeader.From);
+ FromStrNew=TRUE;
+ }
+ else if(UnicodeHeader.From!=NULL)
+ FromStr=UnicodeHeader.From;
+ else if(UnicodeHeader.FromNick!=NULL)
+ FromStr=UnicodeHeader.FromNick;
+ else if(UnicodeHeader.ReturnPath!=NULL)
+ FromStr=UnicodeHeader.ReturnPath;
+
+ if(NULL==FromStr)
+ {
+ FromStr=L"";
+ FromStrNew=FALSE;
+ }
+ }
+
+
+ if((hListView!=NULL) && (msgq->Flags & YAMN_MSG_DISPLAY))
+ {
+ item.iSubItem=0;
+ item.pszText=FromStr;
+ item.iItem=SendMessageW(hListView,LVM_INSERTITEMW,(WPARAM)0,(LPARAM)&item);
+
+ item.iSubItem=1;
+ item.pszText=(NULL!=UnicodeHeader.Subject ? UnicodeHeader.Subject : (WCHAR*)L"");
+ SendMessageW(hListView,LVM_SETITEMTEXTW,(WPARAM)item.iItem,(LPARAM)&item);
+
+ item.iSubItem=2;
+ swprintf(SizeStr,L"%d kB",msgq->MailData->Size/1024);
+ item.pszText=SizeStr;
+ SendMessageW(hListView,LVM_SETITEMTEXTW,(WPARAM)item.iItem,(LPARAM)&item);
+
+ item.iSubItem=3;
+ item.pszText=L"";
+ { CMimeItem *heads;
+ for(heads=msgq->MailData->TranslatedHeader;heads!=NULL;heads=heads->Next) {
+ if (!_stricmp(heads->name,"Date")){
+ MimeDateToLocalizedDateTime(heads->value,LocalDateStr,128);
+ item.pszText=LocalDateStr;
+ break;
+ } } }
+ SendMessageW(hListView,LVM_SETITEMTEXTW,(WPARAM)item.iItem,(LPARAM)&item);
+ }
+
+ if((nflags & YAMN_ACC_POP) && (ActualAccount->Flags & YAMN_ACC_POPN) && (msgq->Flags & YAMN_MSG_POPUP) && (msgq->Flags & YAMN_MSG_NEW))
+ {
+ WideCharToMultiByte(CP_ACP,0,FromStr,-1,(char *)NewMailPopUp.lpzContactName,sizeof(NewMailPopUp.lpzContactName),NULL,NULL);
+ if(!WideCharToMultiByte(CP_ACP,0,UnicodeHeader.Subject,-1,(char *)NewMailPopUp.lpzText,sizeof(NewMailPopUp.lpzText),NULL,NULL))
+ NewMailPopUp.lpzText[0]=0;
+ PYAMN_MAILSHOWPARAM MailParam = (PYAMN_MAILSHOWPARAM)malloc(sizeof(YAMN_MAILSHOWPARAM));
+ if(MailParam) {
+ MailParam->account = ActualAccount;
+ MailParam->mail = msgq;
+ MailParam->ThreadRunningEV = 0;
+ NewMailPopUp.PluginData=MailParam;
+ CallService(MS_POPUP_ADDPOPUPEX,(WPARAM)&NewMailPopUp,0);
+ }
+ }
+
+ if((msgq->Flags & YAMN_MSG_UNSEEN) && (ActualAccount->NewMailN.Flags & YAMN_ACC_KBN))
+ CallService(MS_KBDNOTIFY_EVENTSOPENED,(WPARAM)1,NULL);
+
+ if(FromStrNew)
+ delete[] FromStr;
+
+ if(Extracted)
+ {
+ DeleteHeaderContent(&UnicodeHeader);
+ ZeroMemory(&UnicodeHeader,sizeof(UnicodeHeader));
+ }
+
+ if(!Loaded)
+ {
+ SaveMailData(msgq);
+ UnloadMailData(msgq); //do not keep data for mail in memory
+ }
+ }
+
+ return TRUE;
+}
+
+void DoMailActions(HWND hDlg,HACCOUNT ActualAccount,struct CMailNumbers *MN,DWORD nflags,DWORD nnflags)
+{
+ TCHAR *NotIconText=Translate("- new mail message(s)");
+ NOTIFYICONDATA nid;
+
+ ZeroMemory(&nid,sizeof(nid));
+
+ if(MN->Real.EventNC+MN->Virtual.EventNC)
+ NotifyEventHooks(hNewMailHook,0,0);
+
+ if((nflags & YAMN_ACC_KBN) && (MN->Real.PopUpRun+MN->Virtual.PopUpRun))
+ {
+ CallService(MS_KBDNOTIFY_STARTBLINK,(WPARAM)MN->Real.PopUpNC+MN->Virtual.PopUpNC,NULL);
+ }
+
+ if((nflags & YAMN_ACC_CONT) && (MN->Real.PopUpRun+MN->Virtual.PopUpRun))
+ {
+ char sMsg[250];
+ _snprintf(sMsg,249,Translate("%s : %d new mail message(s), %d total"),ActualAccount->Name,MN->Real.PopUpNC+MN->Virtual.PopUpNC,MN->Real.PopUpTC+MN->Virtual.PopUpTC);
+ if (!(nflags & YAMN_ACC_CONTNOEVENT)){
+ CLISTEVENT cEvent;
+ cEvent.cbSize = sizeof(CLISTEVENT);
+ cEvent.hContact = ActualAccount->hContact;
+ cEvent.hIcon = hYamnIcons[2];
+ cEvent.hDbEvent = (HANDLE)ActualAccount->hContact;
+ cEvent.lParam = (LPARAM) ActualAccount->hContact;
+ cEvent.pszService = MS_YAMN_CLISTDBLCLICK;
+ cEvent.pszTooltip = sMsg;
+ cEvent.flags = 0;
+ CallServiceSync(MS_CLIST_ADDEVENT, 0,(LPARAM)&cEvent);
+ }
+ DBWriteContactSettingString(ActualAccount->hContact, "CList", "StatusMsg", sMsg);
+
+ if(nflags & YAMN_ACC_CONTNICK)
+ {
+ DBWriteContactSettingString(ActualAccount->hContact, ProtoName, "Nick",sMsg);
+ }
+ }
+
+ if((nflags & YAMN_ACC_POP) &&
+ !(ActualAccount->Flags & YAMN_ACC_POPN) &&
+ (MN->Real.PopUpRun+MN->Virtual.PopUpRun))
+ {
+ POPUPDATAEX NewMailPopUp ={0};
+
+ NewMailPopUp.lchContact=(ActualAccount->hContact != NULL) ? ActualAccount->hContact : ActualAccount;
+ NewMailPopUp.lchIcon=hYamnIcons[2];
+ NewMailPopUp.colorBack=nflags & YAMN_ACC_POPC ? ActualAccount->NewMailN.PopUpB : GetSysColor(COLOR_BTNFACE);
+ NewMailPopUp.colorText=nflags & YAMN_ACC_POPC ? ActualAccount->NewMailN.PopUpT : GetSysColor(COLOR_WINDOWTEXT);
+ NewMailPopUp.iSeconds=ActualAccount->NewMailN.PopUpTime;
+
+ NewMailPopUp.PluginWindowProc=(WNDPROC)NewMailPopUpProc;
+ NewMailPopUp.PluginData=(void *)0; //multiple popups
+
+ lstrcpyn(NewMailPopUp.lpzContactName,ActualAccount->Name,sizeof(NewMailPopUp.lpzContactName));
+ sprintf(NewMailPopUp.lpzText,Translate("%d new mail message(s), %d total"),MN->Real.PopUpNC+MN->Virtual.PopUpNC,MN->Real.PopUpTC+MN->Virtual.PopUpTC);
+ CallService(MS_POPUP_ADDPOPUPEX,(WPARAM)&NewMailPopUp,0);
+ }
+
+ //destroy tray icon if no new mail
+ if((MN->Real.SysTrayUC+MN->Virtual.SysTrayUC==0) && (hDlg!=NULL))
+ {
+ nid.hWnd=hDlg;
+ nid.uID=0;
+ Shell_NotifyIcon(NIM_DELETE,&nid);
+ }
+
+ //and remove the event
+ if((nflags & YAMN_ACC_CONT) && (!(nflags & YAMN_ACC_CONTNOEVENT)) && (MN->Real.UnSeen + MN->Virtual.UnSeen==0)) {
+ CallService(MS_CLIST_REMOVEEVENT,(WPARAM)ActualAccount->hContact,(LPARAM)ActualAccount->hContact);
+ }
+
+ if((MN->Real.BrowserUC+MN->Virtual.BrowserUC==0) && (hDlg!=NULL))
+ {
+ if(!IsWindowVisible(hDlg) && !(nflags & YAMN_ACC_MSG))
+ PostMessage(hDlg,WM_DESTROY,(WPARAM)0,(LPARAM)0); //destroy window if no new mail and window is not visible
+ if(nnflags & YAMN_ACC_MSG) //if no new mail and msg should be executed
+ {
+ SetForegroundWindow(hDlg);
+ ShowWindow(hDlg,SW_SHOWNORMAL);
+ }
+ }
+ else
+ if(hDlg!=NULL) //else insert icon and set window if new mails
+ {
+ SendMessageW(GetDlgItem(hDlg,IDC_LISTMAILS),LVM_SCROLL,(WPARAM)0,(LPARAM)0x7ffffff);
+
+ if((nflags & YAMN_ACC_ICO) && (MN->Real.SysTrayUC+MN->Virtual.SysTrayUC))
+ {
+ TCHAR *src,*dest;
+ int i;
+
+ for(src=ActualAccount->Name,dest=nid.szTip,i=0;(*src!=(TCHAR)0) && (i+1<sizeof(nid.szTip));*dest++=*src++);
+ for(src=NotIconText;(*src!=(TCHAR)0) && (i+1<sizeof(nid.szTip));*dest++=*src++);
+ *dest=(TCHAR)0;
+ nid.cbSize=sizeof(NOTIFYICONDATA);
+ nid.hWnd=hDlg;
+ nid.hIcon=hYamnIcons[2];
+ nid.uID=0;
+ nid.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;
+ nid.uCallbackMessage=WM_YAMN_NOTIFYICON;
+ Shell_NotifyIcon(NIM_ADD,&nid);
+ SetTimer(hDlg,TIMER_FLASHING,500,NULL);
+ }
+ if(nflags & YAMN_ACC_MSG) //if no new mail and msg should be executed
+ ShowWindow(hDlg,SW_SHOWNORMAL);
+ }
+
+ if(MN->Real.AppNC+MN->Virtual.AppNC!=0)
+ {
+ if(nflags & YAMN_ACC_APP)
+ {
+ PROCESS_INFORMATION pi;
+ STARTUPINFOW si;
+ ZeroMemory(&si,sizeof(si));
+ si.cb=sizeof(si);
+
+ if(ActualAccount->NewMailN.App!=NULL)
+ {
+ WCHAR *Command;
+ if(ActualAccount->NewMailN.AppParam!=NULL)
+ Command=new WCHAR[wcslen(ActualAccount->NewMailN.App)+wcslen(ActualAccount->NewMailN.AppParam)+6];
+ else
+ Command=new WCHAR[wcslen(ActualAccount->NewMailN.App)+6];
+
+ if(Command!=NULL)
+ {
+ lstrcpyW(Command,L"\"");
+ lstrcatW(Command,ActualAccount->NewMailN.App);
+ lstrcatW(Command,L"\" ");
+ if(ActualAccount->NewMailN.AppParam!=NULL)
+ lstrcatW(Command,ActualAccount->NewMailN.AppParam);
+ CreateProcessW(NULL,Command,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
+ delete[] Command;
+ }
+ }
+ }
+ }
+
+ if(MN->Real.SoundNC+MN->Virtual.SoundNC!=0)
+ if(nflags & YAMN_ACC_SND)
+ CallService(MS_SKIN_PLAYSOUND,0,(LPARAM)YAMN_NEWMAILSOUND);
+
+ if((nnflags & YAMN_ACC_POP) && (MN->Real.PopUpRun+MN->Virtual.PopUpRun==0))
+ {
+ POPUPDATAEX NoNewMailPopUp;
+
+ NoNewMailPopUp.lchContact=(ActualAccount->hContact != NULL) ? ActualAccount->hContact : ActualAccount;
+ NoNewMailPopUp.lchIcon=hYamnIcons[1];
+ NoNewMailPopUp.colorBack=ActualAccount->NoNewMailN.Flags & YAMN_ACC_POPC ? ActualAccount->NoNewMailN.PopUpB : GetSysColor(COLOR_BTNFACE);
+ NoNewMailPopUp.colorText=ActualAccount->NoNewMailN.Flags & YAMN_ACC_POPC ? ActualAccount->NoNewMailN.PopUpT : GetSysColor(COLOR_WINDOWTEXT);
+ NoNewMailPopUp.iSeconds=ActualAccount->NoNewMailN.PopUpTime;
+
+ NoNewMailPopUp.PluginWindowProc=(WNDPROC)NoNewMailPopUpProc;
+ NoNewMailPopUp.PluginData=(void *)0; //it's not new mail popup
+
+ lstrcpyn(NoNewMailPopUp.lpzContactName,ActualAccount->Name,sizeof(NoNewMailPopUp.lpzContactName));
+ if(MN->Real.PopUpSL2NC+MN->Virtual.PopUpSL2NC)
+ sprintf(NoNewMailPopUp.lpzText,Translate("No new mail message, %d spam(s)"),MN->Real.PopUpSL2NC+MN->Virtual.PopUpSL2NC);
+ else
+ lstrcpyn(NoNewMailPopUp.lpzText,Translate("No new mail message"),sizeof(NoNewMailPopUp.lpzText));
+ CallService(MS_POPUP_ADDPOPUPEX,(WPARAM)&NoNewMailPopUp,0);
+ }
+
+ if((nflags & YAMN_ACC_CONT) && (MN->Real.PopUpRun+MN->Virtual.PopUpRun==0))
+ {
+ if(ActualAccount->hContact != NULL)
+ {
+ if(MN->Real.PopUpTC+MN->Virtual.PopUpTC)
+ {
+ char tmp[255];
+ sprintf(tmp,Translate("%d new mail message(s), %d total"),MN->Real.PopUpNC+MN->Virtual.PopUpNC,MN->Real.PopUpTC+MN->Virtual.PopUpTC);
+ DBWriteContactSettingString(ActualAccount->hContact, "CList", "StatusMsg", tmp);
+ }
+ else
+ DBWriteContactSettingString(ActualAccount->hContact, "CList", "StatusMsg", Translate("No new mail message"));
+
+ if(nflags & YAMN_ACC_CONTNICK)
+ {
+ DBWriteContactSettingString(ActualAccount->hContact, ProtoName, "Nick", ActualAccount->Name);
+ }
+ }
+ }
+ return;
+}
+
+DWORD WINAPI ShowEmailThread(LPVOID Param);
+LRESULT CALLBACK NewMailPopUpProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ INT_PTR PluginParam=0;
+ switch(msg)
+ {
+ case WM_COMMAND:
+ //if clicked and it's new mail popup window
+ if((HIWORD(wParam)==STN_CLICKED) && (-1!=(PluginParam=CallService(MS_POPUP_GETPLUGINDATA,(WPARAM)hWnd,(LPARAM)&PluginParam))))
+ {
+ HANDLE hContact = 0;
+ HACCOUNT Account;
+ if (PluginParam){
+ PYAMN_MAILSHOWPARAM MailParam = new YAMN_MAILSHOWPARAM;
+ memcpy(MailParam,(PINT_PTR)PluginParam,sizeof(YAMN_MAILSHOWPARAM));
+ hContact = MailParam->account->hContact;
+ Account = MailParam->account;
+ if(NULL!=(MailParam->ThreadRunningEV=CreateEvent(NULL,FALSE,FALSE,NULL))){
+ HANDLE NewThread;
+ if(NULL!=(NewThread=CreateThread(NULL,0,ShowEmailThread,(LPVOID)MailParam,0,NULL)))
+ {
+ CloseHandle(NewThread);
+ }
+ CloseHandle(MailParam->ThreadRunningEV);
+ }
+ //delete MailParam;
+ } else {
+ DBVARIANT dbv;
+
+ hContact=(HANDLE)CallService(MS_POPUP_GETCONTACT,(WPARAM)hWnd,(LPARAM)0);
+
+ if(!DBGetContactSetting((HANDLE) hContact,ProtoName,"Id",&dbv))
+ {
+ Account=(HACCOUNT) CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else
+ Account = (HACCOUNT) hContact; //????
+
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"PopUpProc:LEFTCLICK:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0==WaitToReadFcn(Account->AccountAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"PopUpProc:LEFTCLICK:ActualAccountSO-read enter\n");
+ #endif
+ switch(msg)
+ {
+ case WM_COMMAND:
+ {
+ YAMN_MAILBROWSERPARAM Param={(HANDLE)0,Account,
+ (Account->NewMailN.Flags & ~YAMN_ACC_POP) | YAMN_ACC_MSGP | YAMN_ACC_MSG,
+ (Account->NoNewMailN.Flags & ~YAMN_ACC_POP) | YAMN_ACC_MSGP | YAMN_ACC_MSG};
+
+ RunMailBrowserSvc((WPARAM)&Param,(LPARAM)YAMN_MAILBROWSERVERSION);
+ }
+ break;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"PopUpProc:LEFTCLICK:ActualAccountSO-read done\n");
+ #endif
+ ReadDoneFcn(Account->AccountAccessSO);
+ }
+ #ifdef DEBUG_SYNCHRO
+ else
+ DebugLog(SynchroFile,"PopUpProc:LEFTCLICK:ActualAccountSO-read enter failed\n");
+ #endif
+ }
+ if ((Account->NewMailN.Flags & YAMN_ACC_CONT) && !(Account->NewMailN.Flags & YAMN_ACC_CONTNOEVENT)){
+ CallService(MS_CLIST_REMOVEEVENT,(WPARAM)hContact,(LPARAM)hContact);
+ }
+ }
+ // fall through
+ case WM_CONTEXTMENU:
+ SendMessageW(hWnd,UM_DESTROYPOPUP,0,0);
+ break;
+ case UM_FREEPLUGINDATA:{
+ PYAMN_MAILSHOWPARAM mpd = (PYAMN_MAILSHOWPARAM)PUGetPluginData(hWnd);
+ HANDLE hContact = 0;
+ if ((mpd) && (INT_PTR)mpd!=-1)free(mpd);
+ return FALSE;
+ }
+ case UM_INITPOPUP:
+ //This is the equivalent to WM_INITDIALOG you'd get if you were the maker of dialog popups.
+ WindowList_Add(YAMNVar.MessageWnds,hWnd,NULL);
+ break;
+ case UM_DESTROYPOPUP:
+ WindowList_Remove(YAMNVar.MessageWnds,hWnd);
+ break;
+ case WM_YAMN_STOPACCOUNT:
+ {
+ HACCOUNT ActualAccount;
+ HANDLE hContact;
+ DBVARIANT dbv;
+
+ hContact=(HANDLE)CallService(MS_POPUP_GETCONTACT,(WPARAM)hWnd,(LPARAM)0);
+
+ if(!DBGetContactSetting((HANDLE) hContact,ProtoName,"Id",&dbv))
+ {
+ ActualAccount=(HACCOUNT) CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else
+ ActualAccount = (HACCOUNT) hContact;
+
+ if((HACCOUNT)wParam!=ActualAccount)
+ break;
+ DestroyWindow(hWnd);
+ return 0;
+ }
+ case WM_NOTIFY:
+ default:
+ break;
+ }
+ return DefWindowProc(hWnd,msg,wParam,lParam);
+}
+
+LRESULT CALLBACK NoNewMailPopUpProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_COMMAND:
+ if((HIWORD(wParam)==STN_CLICKED) && (msg==WM_COMMAND))
+ {
+ HACCOUNT ActualAccount;
+ HANDLE hContact;
+ DBVARIANT dbv;
+
+ hContact=(HANDLE)CallService(MS_POPUP_GETCONTACT,(WPARAM)hWnd,(LPARAM)0);
+
+ if(!DBGetContactSetting((HANDLE) hContact,ProtoName,"Id",&dbv))
+ {
+ ActualAccount=(HACCOUNT) CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else
+ ActualAccount = (HACCOUNT) hContact;
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"PopUpProc:LEFTCLICK:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0==WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"PopUpProc:LEFTCLICK:ActualAccountSO-read enter\n");
+ #endif
+ switch(msg)
+ {
+ case WM_COMMAND:
+ {
+ YAMN_MAILBROWSERPARAM Param={(HANDLE)0,ActualAccount,ActualAccount->NewMailN.Flags,ActualAccount->NoNewMailN.Flags,0};
+
+ Param.nnflags=Param.nnflags | YAMN_ACC_MSG; //show mails in account even no new mail in account
+ Param.nnflags=Param.nnflags & ~YAMN_ACC_POP;
+
+ Param.nflags=Param.nflags | YAMN_ACC_MSG; //show mails in account even no new mail in account
+ Param.nflags=Param.nflags & ~YAMN_ACC_POP;
+
+ RunMailBrowserSvc((WPARAM)&Param,(LPARAM)YAMN_MAILBROWSERVERSION);
+ }
+ break;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"PopUpProc:LEFTCLICK:ActualAccountSO-read done\n");
+ #endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+ #ifdef DEBUG_SYNCHRO
+ else
+ DebugLog(SynchroFile,"PopUpProc:LEFTCLICK:ActualAccountSO-read enter failed\n");
+ #endif
+ SendMessageW(hWnd,UM_DESTROYPOPUP,0,0);
+ }
+ break;
+
+ case WM_CONTEXTMENU:
+ SendMessageW(hWnd,UM_DESTROYPOPUP,0,0);
+ break;
+
+ case UM_FREEPLUGINDATA:
+ //Here we'd free our own data, if we had it.
+ return FALSE;
+ case UM_INITPOPUP:
+ //This is the equivalent to WM_INITDIALOG you'd get if you were the maker of dialog popups.
+ WindowList_Add(YAMNVar.MessageWnds,hWnd,NULL);
+ break;
+ case UM_DESTROYPOPUP:
+ WindowList_Remove(YAMNVar.MessageWnds,hWnd);
+ break;
+ case WM_YAMN_STOPACCOUNT:
+ {
+ HACCOUNT ActualAccount;
+ HANDLE hContact;
+ DBVARIANT dbv;
+
+ hContact=(HANDLE)CallService(MS_POPUP_GETCONTACT,(WPARAM)hWnd,(LPARAM)0);
+
+ if(!DBGetContactSetting((HANDLE) hContact,ProtoName,"Id",&dbv))
+ {
+ ActualAccount=(HACCOUNT) CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)dbv.pszVal);
+ DBFreeVariant(&dbv);
+ }
+ else
+ ActualAccount = (HACCOUNT) hContact;
+
+ if((HACCOUNT)wParam!=ActualAccount)
+ break;
+
+ DestroyWindow(hWnd);
+ return 0;
+ }
+ case WM_NOTIFY:
+/* switch(((LPNMHDR)lParam)->code)
+ {
+ case NM_CLICK:
+ {
+ }
+ }
+ break;
+*/ default:
+ break;
+ }
+ return DefWindowProc(hWnd,msg,wParam,lParam);
+}
+
+#ifdef __GNUC__
+//number of 100 ns periods between FILETIME 0 (1601/01/01 00:00:00.0000000) and TIMESTAMP 0 (1970/01/01 00:00:00)
+#define NUM100NANOSEC 116444736000000000ULL
+//The biggest time Get[Date|Time]Format can handle (Fri, 31 Dec 30827 23:59:59.9999999)
+#define MAXFILETIME 0x7FFF35F4F06C7FFFULL
+#else
+#define NUM100NANOSEC 116444736000000000
+#define MAXFILETIME 0x7FFF35F4F06C7FFF
+#endif
+ULONGLONG MimeDateToFileTime(char *datein){
+ char *day=0, *month=0, *year=0, *time=0, *shift=0;
+ SYSTEMTIME st;
+ ULONGLONG res=0;
+ int wShiftSeconds = CallService(MS_DB_TIME_TIMESTAMPTOLOCAL,0,0);
+ GetLocalTime(&st);
+ //datein = "Xxx, 1 Jan 2060 5:29:1 +0530 XXX";
+ //datein = "Xxx, 1 Jan 2060 05:29:10 ";
+ //datein = " ManySpaces 1.5 Jan 2060 05::";
+ //datein = "Xxx, 35 February 20 :29:10 ";
+ //datein = "01.12.2007 (22:38:17)"; //
+ if (datein){
+ char tmp [64];
+ while ( datein[0]==' ') datein++; // eat leading spaces
+ strncpy(tmp,datein,63); tmp [63]=0;
+ if (atoi(tmp)) { // Parseable integer on DayOfWeek field? Buggy mime date.
+ day = tmp;
+ } else {
+ int i = 0;
+ while (tmp[i]==' ')i++; if (day = strchr(&tmp[i],' ')){day[0]=0; day++;}
+ }
+ if (day) {while ( day[0]==' ') day++;if (month= strchr(day, ' ')){month[0]=0; month++;}}
+ if (month) {while (month[0]==' ')month++;if (year = strchr(month,' ')){ year[0]=0; year++;}}
+ if (year) {while ( year[0]==' ') year++;if (time = strchr(year, ' ')){ time[0]=0; time++;}}
+ if (time) {while ( time[0]==' ') time++;if (shift= strchr(time, ' ')){shift[0]=0; shift++;shift[5]=0;}}
+
+ if (year){
+ st.wYear = atoi(year);
+ if (strlen(year)<4) if (st.wYear<70)st.wYear += 2000; else st.wYear += 1900;
+ };
+ if (month) for(int i=0;i<12;i++) if(strncmp(month,s_MonthNames[i],3)==0) {st.wMonth = i + 1; break;}
+ if (day) st.wDay = atoi(day);
+ if (time) {
+ char *h, *m, *s;
+ h = time;
+ if (m = strchr(h,':')){
+ m[0]=0; m++;
+ if (s = strchr(m,':')){s[0] = 0; s++;}
+ } else s=0;
+ st.wHour = atoi(h);
+ st.wMinute = m?atoi(m):0;
+ st.wSecond = s?atoi(s):0;
+ } else {st.wHour=st.wMinute=st.wSecond=0;}
+
+ if (shift){
+ if (strlen(shift)<4) {
+ //has only hour
+ wShiftSeconds = (atoi(shift))*3600;
+ } else {
+ char *smin = shift + strlen(shift)-2;
+ int ismin = atoi(smin);
+ smin[0] = 0;
+ int ishour = atoi(shift);
+ wShiftSeconds = (ishour*60+(ishour<0?-1:1)*ismin)*60;
+ }
+ }
+ } // if (datein)
+ FILETIME ft;
+ if (SystemTimeToFileTime(&st,&ft)){
+ res = ((ULONGLONG)ft.dwHighDateTime<<32)|((ULONGLONG)ft.dwLowDateTime);
+ LONGLONG w100nano = Int32x32To64((DWORD)wShiftSeconds,10000000);
+ res -= w100nano;
+ }else{
+ res=0;
+ }
+ return res;
+}
+void FileTimeToLocalizedDateTime(LONGLONG filetime, WCHAR *dateout, int lendateout){
+ int localeID = CallService(MS_LANGPACK_GETLOCALE,0,0);
+ //int localeID = MAKELCID(LANG_URDU, SORT_DEFAULT);
+ if (localeID==CALLSERVICE_NOTFOUND) localeID=LOCALE_USER_DEFAULT;
+ if (filetime>MAXFILETIME) filetime = MAXFILETIME;
+ else if (filetime<=0) {
+ wcsncpy(dateout,TranslateW(L"Invalid"),lendateout);
+ return;
+ }
+ SYSTEMTIME st;
+ WORD wTodayYear, wTodayMonth, wTodayDay;
+ FILETIME ft;
+ BOOL willShowDate = !(optDateTime&SHOWDATENOTODAY);
+ if (!willShowDate){
+ GetLocalTime(&st);
+ wTodayYear = st.wYear;
+ wTodayMonth = st.wMonth;
+ wTodayDay = st.wDay;
+ }
+ ft.dwLowDateTime = (DWORD)filetime;
+ ft.dwHighDateTime = (DWORD)(filetime >> 32);
+ FILETIME localft;
+ if (!FileTimeToLocalFileTime(&ft,&localft)){
+ // this should never happen
+ wcsncpy(dateout,L"Incorrect FileTime",lendateout);
+ } else {
+ if (!FileTimeToSystemTime(&localft,&st)){
+ // this should never happen
+ wcsncpy(dateout,L"Incorrect LocalFileTime",lendateout);
+ } else {
+ dateout[lendateout-1]=0;
+ int templen = 0;
+ if (!willShowDate) willShowDate = (wTodayYear!=st.wYear)||(wTodayMonth!=st.wMonth)||(wTodayDay!=st.wDay);
+ if (willShowDate){
+ templen = GetDateFormatW(localeID,(optDateTime&SHOWDATELONG)?DATE_LONGDATE:DATE_SHORTDATE,&st,NULL,dateout,lendateout-2);
+ dateout[templen-1] = ' ';
+ }
+ if (templen<(lendateout-1)){
+ GetTimeFormatW(localeID,(optDateTime&SHOWDATENOSECONDS)?TIME_NOSECONDS:0,&st,NULL,&dateout[templen],lendateout-templen-1);
+ }
+ }
+ }
+}
+void MimeDateToLocalizedDateTime(char *datein, WCHAR *dateout, int lendateout){
+ ULONGLONG ft = MimeDateToFileTime(datein);
+ FileTimeToLocalizedDateTime(ft,dateout,lendateout);
+}
+
+int CALLBACK ListViewCompareProc(LPARAM lParam1, LPARAM lParam2,LPARAM lParamSort ) {
+ if(lParam1 == NULL || lParam2 == NULL)
+ return 0;
+
+ int nResult = 0;
+ char *str1;
+ char *str2;
+ HYAMNMAIL email1 = (HYAMNMAIL)lParam1;
+ HYAMNMAIL email2 = (HYAMNMAIL)lParam2;
+ struct CShortHeader Header1;
+ struct CShortHeader Header2;
+ ZeroMemory(&Header1,sizeof(Header1));
+ ZeroMemory(&Header2,sizeof(Header2));
+
+ try {
+ ExtractShortHeader(email1->MailData->TranslatedHeader,&Header1);
+ ExtractShortHeader(email2->MailData->TranslatedHeader,&Header2);
+
+ switch((int)lParamSort)
+ {
+ case 0: //From
+ if(Header1.FromNick == NULL)
+ str1 = Header1.From;
+ else str1 = Header1.FromNick;
+
+ if(Header2.FromNick == NULL)
+ str2 = Header2.From;
+ else str2 = Header2.FromNick;
+
+ nResult = strcmp(str1, str2);
+
+ if(bFrom) nResult = -nResult;
+ break;
+ case 1: //Subject
+ if(Header1.Subject == NULL)
+ str1 = " ";
+ else str1 = Header1.Subject;
+
+ if(Header2.Subject == NULL)
+ str2 = " ";
+ else str2 = Header2.Subject;
+
+ nResult = strcmp(str1, str2);
+
+ if(bSub) nResult = -nResult;
+ break;
+ case 2: //Size
+ if(email1->MailData->Size == email2->MailData->Size) nResult = 0;
+ if(email1->MailData->Size > email2->MailData->Size) nResult = 1;
+ if(email1->MailData->Size < email2->MailData->Size) nResult = -1;
+
+ if(bSize) nResult = -nResult;
+ break;
+
+ case 3: //Date
+ {
+ ULONGLONG ts1 = 0, ts2 = 0;
+ ts1 = MimeDateToFileTime(Header1.Date);
+ ts2 = MimeDateToFileTime(Header2.Date);
+ if(ts1 > ts2) nResult = 1;
+ else if (ts1 < ts2) nResult = -1;
+ else nResult = 0;
+ }
+ if(bDate) nResult = -nResult;
+ break;
+
+ default:
+ if(Header1.Subject == NULL) str1 = " ";
+ else str1 = Header1.Subject;
+
+ if(Header2.Subject == NULL) str2 = " ";
+ else str2 = Header2.Subject;
+
+ nResult = strcmp(str1, str2);
+ break;
+ }
+ //MessageBox(NULL,str1,str2,0);
+ }
+ catch( ... )
+ {
+ }
+
+ //free mem
+ DeleteShortHeaderContent(&Header1);
+ DeleteShortHeaderContent(&Header2);
+ return nResult;
+
+}
+
+HCURSOR hCurSplitNS, hCurSplitWE;
+static WNDPROC OldSplitterProc;
+#define DM_SPLITTERMOVED (WM_USER+15)
+static LRESULT CALLBACK SplitterSubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg) {
+ case WM_NCHITTEST:
+ return HTCLIENT;
+ case WM_SETCURSOR:
+ {
+ SetCursor(hCurSplitNS);
+ return TRUE;
+ }
+ case WM_LBUTTONDOWN:
+ SetCapture(hwnd);
+ return 0;
+ case WM_MOUSEMOVE:
+ if (GetCapture() == hwnd) {
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+ SendMessage(GetParent(hwnd), DM_SPLITTERMOVED, (short) HIWORD(GetMessagePos()) + rc.bottom / 2, (LPARAM) hwnd);
+ }
+ return 0;
+ case WM_LBUTTONUP:
+ ReleaseCapture();
+ return 0;
+ }
+ return CallWindowProc(OldSplitterProc, hwnd, msg, wParam, lParam);
+}
+
+
+void ConvertCodedStringToUnicode(char *stream,WCHAR **storeto,DWORD cp,int mode);
+int ConvertStringToUnicode(char *stream,unsigned int cp,WCHAR **out);
+INT_PTR CALLBACK DlgProcYAMNShowMessage(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+// HIMAGELIST hIcons;
+ PYAMN_MAILSHOWPARAM MailParam = (PYAMN_MAILSHOWPARAM)lParam;
+ WCHAR *iHeaderW=NULL;
+ WCHAR *iValueW=NULL;
+ int StrLen;
+ HWND hListView = GetDlgItem(hDlg,IDC_LISTHEADERS);
+ OldSplitterProc = (WNDPROC) SetWindowLongPtr(GetDlgItem(hDlg, IDC_SPLITTER), GWLP_WNDPROC, (LONG_PTR) SplitterSubclassProc);
+ SetWindowLongPtr(hDlg,DWLP_USER,(LONG_PTR)MailParam);
+ SendMessageW(hDlg,WM_SETICON,(WPARAM)ICON_BIG,(LPARAM)hYamnIcons[2]);
+ SendMessageW(hDlg,WM_SETICON,(WPARAM)ICON_SMALL,(LPARAM)hYamnIcons[2]);
+
+ ListView_SetUnicodeFormat(hListView,TRUE);
+ ListView_SetExtendedListViewStyle(hListView,LVS_EX_FULLROWSELECT);
+
+ StrLen=MultiByteToWideChar(CP_ACP,MB_USEGLYPHCHARS,Translate("Header"),-1,NULL,0);
+ iHeaderW=new WCHAR[StrLen+1];
+ MultiByteToWideChar(CP_ACP,MB_USEGLYPHCHARS,Translate("Header"),-1,iHeaderW,StrLen);
+
+ StrLen=MultiByteToWideChar(CP_ACP,MB_USEGLYPHCHARS,Translate("Value"),-1,NULL,0);
+ iValueW=new WCHAR[StrLen+1];
+ MultiByteToWideChar(CP_ACP,MB_USEGLYPHCHARS,Translate("Value"),-1,iValueW,StrLen);
+
+ LVCOLUMNW lvc0={LVCF_FMT | LVCF_TEXT | LVCF_WIDTH,LVCFMT_LEFT,130,iHeaderW,0,0};
+ LVCOLUMNW lvc1={LVCF_FMT | LVCF_TEXT | LVCF_WIDTH,LVCFMT_LEFT,400,iValueW,0,0};
+ SendMessageW(hListView,LVM_INSERTCOLUMNW,(WPARAM)0,(LPARAM)&lvc0);
+ SendMessageW(hListView,LVM_INSERTCOLUMNW,(WPARAM)1,(LPARAM)&lvc1);
+ if(NULL!=iHeaderW)
+ delete[] iHeaderW;
+ if(NULL!=iValueW)
+ delete[] iValueW;
+
+ //WindowList_Add(YAMNVar.MessageWnds,hDlg,NULL);
+ //WindowList_Add(YAMNVar.NewMailAccountWnd,hDlg,ActualAccount);
+ SendMessage(hDlg,WM_YAMN_CHANGECONTENT,0,(LPARAM)MailParam);
+ MoveWindow(hDlg,HeadPosX,HeadPosY,HeadSizeX,HeadSizeY,0);
+ ShowWindow(hDlg,SW_SHOWNORMAL);
+ break;
+ }
+ case WM_YAMN_CHANGECONTENT:
+ {
+ PYAMN_MAILSHOWPARAM MailParam = (PYAMN_MAILSHOWPARAM)
+ (lParam?lParam:GetWindowLongPtr(hDlg,DWLP_USER));
+ HWND hListView = GetDlgItem(hDlg,IDC_LISTHEADERS);
+ HWND hEdit = GetDlgItem(hDlg,IDC_EDITBODY);
+ //do not redraw
+ SendMessage(hListView, WM_SETREDRAW, 0, 0);
+ ListView_DeleteAllItems(hListView);
+ struct CMimeItem *Header;
+ LVITEM item;
+ item.mask=LVIF_TEXT | LVIF_PARAM;
+ WCHAR *From=0,*Subj=0;
+ char *contentType=0, *transEncoding=0, *body=0; //should not be delete[]-ed
+ for(Header=MailParam->mail->MailData->TranslatedHeader;Header!=NULL;Header=Header->Next)
+ {
+ WCHAR *str1 = 0;
+ WCHAR *str2 = 0;
+ if (!body) if (!_stricmp(Header->name,"Body")) {body = Header->value; continue;}
+ if (!contentType) if (!_stricmp(Header->name,"Content-Type")) contentType = Header->value;
+ if (!transEncoding) if (!_stricmp(Header->name,"Content-Transfer-Encoding")) transEncoding = Header->value;
+ //ConvertCodedStringToUnicode(Header->name,&str1,MailParam->mail->MailData->CP,1);
+ {
+ int streamsize = MultiByteToWideChar(20127,0,Header->name,-1,NULL,0);
+ str1 = new WCHAR[streamsize+1];
+ MultiByteToWideChar(20127,0,Header->name,-1,str1,streamsize);//US-ASCII
+ }
+ ConvertCodedStringToUnicode(Header->value,&str2,MailParam->mail->MailData->CP,1);
+ if (!str2) { str2 = (WCHAR *)malloc(2); str2[0] = 0; }// the header value may be NULL
+ if (!From) if (!_stricmp(Header->name,"From")) {
+ From =new WCHAR[wcslen(str2)+1];
+ wcscpy(From,str2);
+ }
+ if (!Subj) if (!_stricmp(Header->name,"Subject")) {
+ Subj =new WCHAR[wcslen(str2)+1];
+ wcscpy(Subj,str2);
+ }
+ //if (!hasBody) if (!strcmp(Header->name,"Body")) hasBody = true;
+ int count = 0; WCHAR **split=0;
+ if (str2){
+ int ofs = 0;
+ while (str2[ofs]) {
+ if ((str2[ofs]==0x266A)||(str2[ofs]==0x25D9)||(str2[ofs]==0x25CB)||
+ (str2[ofs]==0x09)||(str2[ofs]==0x0A)||(str2[ofs]==0x0D))count++;
+ ofs++;
+ }
+ split=new WCHAR*[count+1];
+ count=0; ofs=0;
+ split[0]=str2;
+ while (str2[ofs]){
+ if ((str2[ofs]==0x266A)||(str2[ofs]==0x25D9)||(str2[ofs]==0x25CB)||
+ (str2[ofs]==0x09)||(str2[ofs]==0x0A)||(str2[ofs]==0x0D)) {
+ if (str2[ofs-1]){
+ count++;
+ }
+ split[count]=(WCHAR *)(str2+ofs+1);
+ str2[ofs]=0;
+ }
+ ofs++;
+ };
+ }
+ if (!_stricmp(Header->name,"From")||!_stricmp(Header->name,"To")||!_stricmp(Header->name,"Date")||!_stricmp(Header->name,"Subject"))
+ item.iItem = 0;
+ else
+ item.iItem = 999;
+ for (int i=0;i<=count;i++){
+ item.iSubItem=0;
+ if (i==0){
+ item.pszText=str1;
+ } else {
+ item.iItem++;
+ item.pszText=0;
+ }
+ item.iItem=SendMessageW(hListView,LVM_INSERTITEMW,(WPARAM)0,(LPARAM)&item);
+ item.iSubItem=1;
+ item.pszText=str2?split[i]:0;
+ SendMessageW(hListView,LVM_SETITEMTEXTW,(WPARAM)item.iItem,(LPARAM)&item);
+ }
+ if (split)delete[] split;
+
+ if (str1) free(str1);
+ if (str2) free(str2);
+ }
+ if (body){
+ WCHAR *bodyDecoded = 0;
+ char *localBody=0;
+ if (contentType) {
+ if (!_strnicmp(contentType,"text",4)) {
+ if (transEncoding){
+ if (!_stricmp(transEncoding,"base64")){
+ int size = (int)strlen(body)*3/4+5;
+ localBody = new char[size+1];
+ DecodeBase64(body,localBody,size);
+ } else if (!_stricmp(transEncoding,"quoted-printable")){
+ int size = (int)strlen(body)+2;
+ localBody = new char[size+1];
+ DecodeQuotedPrintable(body,localBody,size,FALSE);
+ }
+ }
+ } else if (!_strnicmp(contentType,"multipart/",10)) {
+ char *bondary=NULL;
+ if(NULL!=(bondary=ExtractFromContentType(contentType,"boundary=")))
+ {
+ bodyDecoded = ParseMultipartBody(body,bondary);
+ delete[] bondary;
+ }
+ }
+ }
+ if (!bodyDecoded)ConvertStringToUnicode(localBody?localBody:body,MailParam->mail->MailData->CP,&bodyDecoded);
+ SendMessageW(hEdit,WM_SETTEXT,(WPARAM)0,(LPARAM)bodyDecoded);
+ delete[] bodyDecoded;
+ if (localBody) delete[] localBody;
+ SetFocus(hEdit);
+ }
+ if (!(MailParam->mail->Flags & YAMN_MSG_BODYRECEIVED)) {
+ MailParam->mail->Flags |= YAMN_MSG_BODYREQUESTED;
+ CallService(MS_YAMN_ACCOUNTCHECK,(WPARAM)MailParam->account,0);
+ } else {
+ if (MailParam->mail->Flags & YAMN_MSG_UNSEEN){
+ MailParam->mail->Flags&=~YAMN_MSG_UNSEEN; //mark the message as seen
+ HWND hMailBrowser;
+ if (hMailBrowser=WindowList_Find(YAMNVar.NewMailAccountWnd,MailParam->account)){
+ struct CChangeContent Params={MailParam->account->NewMailN.Flags|YAMN_ACC_MSGP,MailParam->account->NoNewMailN.Flags|YAMN_ACC_MSGP};
+ SendMessageW(hMailBrowser,WM_YAMN_CHANGECONTENT,(WPARAM)MailParam->account,(LPARAM)&Params);
+ } else {
+ UpdateMails(NULL,MailParam->account,MailParam->account->NewMailN.Flags,MailParam->account->NoNewMailN.Flags);
+ }
+ }
+ }
+ ShowWindow(GetDlgItem(hDlg, IDC_SPLITTER),(MailParam->mail->Flags & YAMN_MSG_BODYRECEIVED)?SW_SHOW:SW_HIDE);
+ ShowWindow(hEdit,(MailParam->mail->Flags & YAMN_MSG_BODYRECEIVED)?SW_SHOW:SW_HIDE);
+ WCHAR *title=0;
+ title = new WCHAR[(From?wcslen(From):0)+(Subj?wcslen(Subj):0)+4];
+ if (From&&Subj) wsprintfW(title,L"%s (%s)",Subj,From);
+ else if (From)wsprintfW(title,L"%s",From);
+ else if (Subj)wsprintfW(title,L"%s",Subj);
+ else wsprintfW(title,L"none");
+ if (Subj) delete[] Subj;
+ if (From) delete[] From;
+ SendMessageW(hDlg,WM_SETTEXT,(WPARAM)0,(LPARAM)title);
+ delete[] title;
+ // turn on redrawing
+ SendMessage(hListView, WM_SETREDRAW, 1, 0);
+ SendMessage(hDlg, WM_SIZE, 0, HeadSizeY<<16|HeadSizeX);
+ } break;
+ case WM_YAMN_STOPACCOUNT:
+ {
+ PYAMN_MAILSHOWPARAM MailParam = (PYAMN_MAILSHOWPARAM)
+ (lParam?lParam:GetWindowLongPtr(hDlg,DWLP_USER));
+
+ if(NULL==MailParam)
+ break;
+ if((HACCOUNT)wParam!=MailParam->account)
+ break;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ShowMessage:STOPACCOUNT:sending destroy msg\n");
+ #endif
+ DestroyWindow(hDlg);
+ }
+ return 1;
+ case WM_CTLCOLORSTATIC:
+ //here should be check if this is our edittext control.
+ //but we have only one static control (for now);
+ SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW));
+ SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT));
+ return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);;
+ case WM_DESTROY:
+ {
+ RECT coord;
+ if(GetWindowRect(hDlg,&coord))
+ {
+ HeadPosX=coord.left;
+ HeadSizeX=coord.right-coord.left;
+ HeadPosY=coord.top;
+ HeadSizeY=coord.bottom-coord.top;
+ }
+
+ //if(!YAMNVar.Shutdown && GetWindowRect(hDlg,&coord)) //the YAMNVar.Shutdown testing is because M<iranda strange functionality at shutdown phase, when call to DBWriteContactSetting freezes calling thread
+ //{
+ // //HeadPosX=coord.left;
+ // //HeadSizeX=coord.right-coord.left;
+ // //HeadPosY=coord.top;
+ // //HeadSizeY=coord.bottom-coord.top;
+ // DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGPOSX,HeadPosX);
+ // DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGPOSY,HeadPosY);
+ // DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGSIZEX,HeadSizeX);
+ // DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGSIZEY,HeadSizeY);
+ // DBWriteContactSettingWord(NULL,YAMN_DBMODULE,YAMN_DBMSGPOSSPLIT,HeadSplitPos);
+ //}
+ //PYAMN_MAILSHOWPARAM MailParam = (PYAMN_MAILSHOWPARAM)(GetWindowLongPtr(hDlg,DWLP_USER));
+ //MailParam->mail->MsgWindow = NULL;
+ PostQuitMessage(1);
+ }
+ break;
+ case WM_SYSCOMMAND:
+ {
+ switch(wParam)
+ {
+ case SC_CLOSE:
+ DestroyWindow(hDlg);
+ break;
+ }
+ }
+ break;
+ case WM_MOVE:
+ HeadPosX=LOWORD(lParam); //((LPRECT)lParam)->right-((LPRECT)lParam)->left;
+ HeadPosY=HIWORD(lParam); //((LPRECT)lParam)->bottom-((LPRECT)lParam)->top;
+ return 0;
+ case DM_SPLITTERMOVED:
+ {
+ if ((HWND) lParam == GetDlgItem(hDlg, IDC_SPLITTER)) {
+ POINT pt;
+ pt.x = 0;
+ pt.y = wParam;
+ ScreenToClient(hDlg, &pt);
+ HeadSplitPos = (pt.y*1000)/HeadSizeY;//+rc.bottom-rc.top;
+ if (HeadSplitPos>=1000) HeadSplitPos = 999;
+ else if (HeadSplitPos<=0) HeadSplitPos = 1;
+ else SendMessage(hDlg, WM_SIZE, 0, HeadSizeY<<16|HeadSizeX);
+ }
+ return 0;
+ }
+ case WM_SIZE:
+ if(wParam==SIZE_RESTORED)
+ {
+ HWND hList = GetDlgItem(hDlg,IDC_LISTHEADERS);
+ HWND hEdit = GetDlgItem(hDlg,IDC_EDITBODY);
+ BOOL changeX = LOWORD(lParam)!=HeadSizeX;
+ BOOL isBodyShown = ((PYAMN_MAILSHOWPARAM)(GetWindowLongPtr(hDlg,DWLP_USER)))->mail->Flags & YAMN_MSG_BODYRECEIVED;
+ HeadSizeX=LOWORD(lParam); //((LPRECT)lParam)->right-((LPRECT)lParam)->left;
+ HeadSizeY=HIWORD(lParam); //((LPRECT)lParam)->bottom-((LPRECT)lParam)->top;
+ int localSplitPos = (HeadSplitPos*HeadSizeY)/1000;
+ int localSizeX;
+ RECT coord;
+ MoveWindow(GetDlgItem(hDlg,IDC_SPLITTER),5,localSplitPos,HeadSizeX-10,2,TRUE);
+ MoveWindow(hEdit,5,localSplitPos+6,HeadSizeX-10,HeadSizeY-localSplitPos-11,TRUE); //where to put text window while resizing
+ MoveWindow(hList, 5 ,5 ,HeadSizeX-10 ,(isBodyShown?localSplitPos:HeadSizeY)-10,TRUE); //where to put headers list window while resizing
+ //if (changeX){
+ if (GetClientRect(hList,&coord)){
+ localSizeX=coord.right-coord.left;
+ } else localSizeX=HeadSizeX;
+ LONG iNameWidth = ListView_GetColumnWidth(hList,0);
+ ListView_SetColumnWidth(hList,1,(localSizeX<=iNameWidth)?0:(localSizeX-iNameWidth));
+ //}
+ }
+// break;
+ return 0;
+ case WM_CONTEXTMENU:
+ {
+ if ( GetWindowLongPtr(( HWND )wParam, GWLP_ID ) == IDC_LISTHEADERS) {
+ //MessageBox(0,"LISTHEADERS","Debug",0);
+ HWND hList = GetDlgItem( hDlg, IDC_LISTHEADERS );
+ POINT pt = { (signed short)LOWORD( lParam ), (signed short)HIWORD( lParam ) };
+ HTREEITEM hItem = 0;
+ if (pt.x==-1) pt.x = 0;
+ if (pt.y==-1) pt.y = 0;
+ if (int numRows = ListView_GetItemCount(hList)){
+ HMENU hMenu = CreatePopupMenu();
+ AppendMenu(hMenu, MF_STRING, (UINT_PTR)1, TranslateT("Copy Selected"));
+ AppendMenu(hMenu, MF_STRING, (UINT_PTR)2, TranslateT("Copy All"));
+ AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
+ AppendMenu(hMenu, MF_STRING, (UINT_PTR)0, TranslateT("Cancel"));
+ int nReturnCmd = TrackPopupMenu( hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hDlg, NULL );
+ DestroyMenu( hMenu );
+ if (nReturnCmd>0){
+ int courRow=0;
+ size_t sizeNeeded = 0;
+ WCHAR headname[64]={0}, headvalue[256]={0};
+ for (courRow=0;courRow<numRows;courRow++){
+ if ((nReturnCmd==1) && (ListView_GetItemState(hList, courRow, LVIS_SELECTED)==0)) continue;
+ ListView_GetItemText(hList, courRow, 0, headname, SIZEOF(headname));
+ ListView_GetItemText(hList, courRow, 1, headvalue, SIZEOF(headvalue));
+ size_t headnamelen=wcslen(headname);
+ if (headnamelen) sizeNeeded += 1 + headnamelen;
+ sizeNeeded += 3+wcslen(headvalue);
+ }
+ if (!sizeNeeded) {
+#ifdef _DEBUG
+ MessageBox(hDlg,"Nothing To Copy","Debug ShowHeaders",0);
+#endif
+ } else if(OpenClipboard(hDlg)){
+ EmptyClipboard();
+ HGLOBAL hData=GlobalAlloc(GMEM_MOVEABLE,(sizeNeeded+1)*sizeof(WCHAR));
+ WCHAR *buff = (WCHAR *)GlobalLock(hData);
+ int courPos = 0;
+ for (courRow=0;courRow<numRows;courRow++){
+ if ((nReturnCmd==1) && (ListView_GetItemState(hList, courRow, LVIS_SELECTED)==0)) continue;
+ ListView_GetItemText(hList, courRow, 0, headname, SIZEOF(headname));
+ ListView_GetItemText(hList, courRow, 1, headvalue, SIZEOF(headvalue));
+ if (wcslen(headname)) courPos += swprintf(&buff[courPos],L"%s:\t%s\r\n",headname,headvalue);
+ else courPos += swprintf(&buff[courPos],L"\t%s\r\n",headvalue);
+ }
+ GlobalUnlock(hData);
+ SetClipboardData(CF_UNICODETEXT,hData);
+ CloseClipboard();
+ }
+ }
+ }
+ } }
+ break; // just in case
+ }
+ return 0;
+}
+
+DWORD WINAPI ShowEmailThread(LPVOID Param){
+ struct MailShowMsgWinParam MyParam;
+ MyParam=*(struct MailShowMsgWinParam *)Param;
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ShowMessage:Incrementing \"using threads\" %x (account %x)\n",MyParam.account->UsingThreads,MyParam.account);
+ #endif
+ SCIncFcn(MyParam.account->UsingThreads);
+ SetEvent(MyParam.ThreadRunningEV);
+ if (MyParam.mail->MsgWindow){
+ //if (!BringWindowToTop(MyParam.mail->MsgWindow)) {
+ if (!SetForegroundWindow(MyParam.mail->MsgWindow)) {
+ SendMessage(MyParam.mail->MsgWindow,WM_DESTROY,0,0);
+ MyParam.mail->MsgWindow = 0;
+ goto CREADTEVIEWMESSAGEWINDOW;
+ }else{
+ if (IsIconic(MyParam.mail->MsgWindow)){
+ OpenIcon(MyParam.mail->MsgWindow);
+ }
+ }
+ } else {
+CREADTEVIEWMESSAGEWINDOW:
+ MyParam.mail->MsgWindow = CreateDialogParamW(YAMNVar.hInst,MAKEINTRESOURCEW(IDD_DLGSHOWMESSAGE),NULL,(DLGPROC)DlgProcYAMNShowMessage,(LPARAM)&MyParam);
+ WindowList_Add(YAMNVar.MessageWnds,MyParam.mail->MsgWindow,NULL);
+ MSG msg;
+ while(GetMessage(&msg,NULL,0,0)){
+ if(!IsDialogMessage(MyParam.mail->MsgWindow, &msg)){
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ } }
+ WindowList_Remove(YAMNVar.MessageWnds,MyParam.mail->MsgWindow);
+ MyParam.mail->MsgWindow = NULL;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ShowMessage:Decrementing \"using threads\" %x (account %x)\n",MyParam.account->UsingThreads,MyParam.account);
+ #endif
+ SCDecFcn(MyParam.account->UsingThreads);
+ delete Param;
+ return 1;
+}
+
+BOOL CALLBACK DlgProcYAMNMailBrowser(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ HACCOUNT ActualAccount;
+ struct MailBrowserWinParam *MyParam=(struct MailBrowserWinParam *)lParam;
+ struct CMailWinUserInfo *mwui;
+
+ ListView_SetUnicodeFormat(GetDlgItem(hDlg,IDC_LISTMAILS),TRUE);
+ ListView_SetExtendedListViewStyle(GetDlgItem(hDlg,IDC_LISTMAILS),LVS_EX_FULLROWSELECT);
+
+ ActualAccount=MyParam->account;
+ mwui=new struct CMailWinUserInfo;
+ mwui->Account=ActualAccount;
+ mwui->TrayIconState=0;
+ mwui->UpdateMailsMessagesAccess=FALSE;
+ mwui->Seen=FALSE;
+ mwui->RunFirstTime=TRUE;
+
+ SetWindowLongPtr(hDlg,DWLP_USER,(LONG_PTR)mwui);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:INIT:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:INIT:ActualAccountSO-read enter failed\n");
+ #endif
+ DestroyWindow(hDlg);
+ return FALSE;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:INIT:ActualAccountSO-read enter\n");
+ #endif
+
+ SendMessageW(GetDlgItem(hDlg,IDC_BTNAPP),WM_SETTEXT,(WPARAM)0,(LPARAM)TranslateW(L"Run application"));
+ SendMessageW(GetDlgItem(hDlg,IDC_BTNDEL),WM_SETTEXT,(WPARAM)0,(LPARAM)TranslateW(L"Delete selected"));
+ SendMessageW(GetDlgItem(hDlg,IDC_BTNCHECKALL),WM_SETTEXT,(WPARAM)0,(LPARAM)TranslateW(L"Select All"));
+ SendMessageW(GetDlgItem(hDlg,IDC_BTNOK),WM_SETTEXT,(WPARAM)0,(LPARAM)TranslateW(L"OK"));
+
+ LVCOLUMNW lvc0={LVCF_FMT | LVCF_TEXT | LVCF_WIDTH,LVCFMT_LEFT,FromWidth,TranslateW(L"From"),0,0};
+ LVCOLUMNW lvc1={LVCF_FMT | LVCF_TEXT | LVCF_WIDTH,LVCFMT_LEFT,SubjectWidth,TranslateW(L"Subject"),0,0};
+ LVCOLUMNW lvc2={LVCF_FMT | LVCF_TEXT | LVCF_WIDTH,LVCFMT_LEFT,SizeWidth,TranslateW(L"Size"),0,0};
+ LVCOLUMNW lvc3={LVCF_FMT | LVCF_TEXT | LVCF_WIDTH,LVCFMT_LEFT,SizeDate,TranslateW(L"Date"),0,0};
+ SendMessageW(GetDlgItem(hDlg,IDC_LISTMAILS),LVM_INSERTCOLUMNW,(WPARAM)0,(LPARAM)&lvc0);
+ SendMessageW(GetDlgItem(hDlg,IDC_LISTMAILS),LVM_INSERTCOLUMNW,(WPARAM)1,(LPARAM)&lvc1);
+ SendMessageW(GetDlgItem(hDlg,IDC_LISTMAILS),LVM_INSERTCOLUMNW,(WPARAM)2,(LPARAM)&lvc2);
+ SendMessageW(GetDlgItem(hDlg,IDC_LISTMAILS),LVM_INSERTCOLUMNW,(WPARAM)3,(LPARAM)&lvc3);
+
+ if((ActualAccount->NewMailN.App!=NULL) && (wcslen(ActualAccount->NewMailN.App)))
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNAPP),(WPARAM)TRUE);
+ else
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNAPP),(WPARAM)FALSE);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:INIT:ActualAccountSO-read done\n");
+ #endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+
+ WindowList_Add(YAMNVar.MessageWnds,hDlg,NULL);
+ WindowList_Add(YAMNVar.NewMailAccountWnd,hDlg,ActualAccount);
+
+ {
+ char accstatus[512];
+
+ GetStatusFcn(ActualAccount,accstatus);
+ SetDlgItemTextA(hDlg,IDC_STSTATUS,accstatus);
+ }
+ SetTimer(hDlg,TIMER_FLASHING,500,NULL);
+
+ if(ActualAccount->hContact != NULL)
+ {
+ CallService(MS_CLIST_REMOVEEVENT,(WPARAM)ActualAccount->hContact,(LPARAM)"yamn new mail message");
+ }
+
+ OldListViewSubclassProc = (WNDPROC) SetWindowLongPtr(GetDlgItem(hDlg, IDC_LISTMAILS), GWLP_WNDPROC, (LONG_PTR) ListViewSubclassProc);
+
+ break;
+ }
+ case WM_DESTROY:
+ {
+ HACCOUNT ActualAccount;
+ RECT coord;
+ LVCOLUMNW ColInfo;
+ NOTIFYICONDATA nid;
+ HYAMNMAIL Parser;
+ struct CMailWinUserInfo *mwui;
+
+ mwui=(struct CMailWinUserInfo *)GetWindowLongPtr(hDlg,DWLP_USER);
+ if(NULL==(ActualAccount=GetWindowAccount(hDlg)))
+ break;
+ ColInfo.mask=LVCF_WIDTH;
+ if(ListView_GetColumn(GetDlgItem(hDlg,IDC_LISTMAILS),0,&ColInfo))
+ FromWidth=ColInfo.cx;
+ if(ListView_GetColumn(GetDlgItem(hDlg,IDC_LISTMAILS),1,&ColInfo))
+ SubjectWidth=ColInfo.cx;
+ if(ListView_GetColumn(GetDlgItem(hDlg,IDC_LISTMAILS),2,&ColInfo))
+ SizeWidth=ColInfo.cx;
+ if(ListView_GetColumn(GetDlgItem(hDlg,IDC_LISTMAILS),3,&ColInfo))
+ SizeDate=ColInfo.cx;
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DESTROY:save window position\n");
+ #endif
+ if(!YAMNVar.Shutdown && GetWindowRect(hDlg,&coord)) //the YAMNVar.Shutdown testing is because M<iranda strange functionality at shutdown phase, when call to DBWriteContactSetting freezes calling thread
+ {
+ PosX=coord.left;
+ SizeX=coord.right-coord.left;
+ PosY=coord.top;
+ SizeY=coord.bottom-coord.top;
+ DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBPOSX,PosX);
+ DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBPOSY,PosY);
+ DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBSIZEX,SizeX);
+ DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBSIZEY,SizeY);
+ }
+ KillTimer(hDlg,TIMER_FLASHING);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DESTROY:remove window from list\n");
+ #endif
+ WindowList_Remove(YAMNVar.NewMailAccountWnd,hDlg);
+ WindowList_Remove(YAMNVar.MessageWnds,hDlg);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DESTROY:ActualAccountMsgsSO-write wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=WaitToWriteFcn(ActualAccount->MessagesAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DESTROY:ActualAccountMsgsSO-write wait failed\n");
+ #endif
+ break;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DESTROY:ActualAccountMsgsSO-write enter\n");
+ #endif
+ //delete mails from queue, which are deleted from server (spam level 3 mails e.g.)
+ for(Parser=(HYAMNMAIL)ActualAccount->Mails;Parser!=NULL;Parser=Parser->Next)
+ {
+ if((Parser->Flags & YAMN_MSG_DELETED) && YAMN_MSG_SPAML(Parser->Flags,YAMN_MSG_SPAML3) && mwui->Seen) //if spaml3 was already deleted and user knows about it
+ {
+ DeleteMessageFromQueueFcn((HYAMNMAIL *)&ActualAccount->Mails,Parser,1);
+ CallService(MS_YAMN_DELETEACCOUNTMAIL,(WPARAM)ActualAccount->Plugin,(LPARAM)Parser);
+ }
+ }
+
+ //mark mails as read (remove "new" and "unseen" flags)
+ if(mwui->Seen)
+ SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails,YAMN_MSG_DISPLAY,0,YAMN_MSG_NEW | YAMN_MSG_UNSEEN,0);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DESTROY:ActualAccountMsgsSO-write done\n");
+ #endif
+ WriteDoneFcn(ActualAccount->MessagesAccessSO);
+
+ ZeroMemory(&nid,sizeof(NOTIFYICONDATA));
+
+ delete mwui;
+ SetWindowLongPtr(hDlg,DWLP_USER,(LONG_PTR)NULL);
+
+ nid.cbSize=sizeof(NOTIFYICONDATA);
+ nid.hWnd=hDlg;
+ nid.uID=0;
+ Shell_NotifyIcon(NIM_DELETE,&nid);
+ PostQuitMessage(0);
+ }
+ break;
+ case WM_SHOWWINDOW:
+ {
+ struct CMailWinUserInfo *mwui;
+
+ if(NULL==(mwui=(struct CMailWinUserInfo *)GetWindowLongPtr(hDlg,DWLP_USER)))
+ return 0;
+ mwui->Seen=TRUE;
+ }
+ case WM_YAMN_CHANGESTATUS:
+ {
+ HACCOUNT ActualAccount;
+ char accstatus[512];
+
+ if(NULL==(ActualAccount=GetWindowAccount(hDlg)))
+ break;
+ if((HACCOUNT)wParam!=ActualAccount)
+ break;
+ GetStatusFcn(ActualAccount,accstatus);
+ SetDlgItemTextA(hDlg,IDC_STSTATUS,accstatus);
+ }
+ return 1;
+ case WM_YAMN_CHANGECONTENT:
+ {
+ struct CUpdateMails UpdateParams;
+ BOOL ThisThreadWindow=(GetCurrentThreadId()==GetWindowThreadProcessId(hDlg,NULL));
+
+ if(NULL==(UpdateParams.Copied=CreateEvent(NULL,FALSE,FALSE,NULL)))
+ {
+ DestroyWindow(hDlg);
+ return 0;
+ }
+ UpdateParams.Flags=(struct CChangeContent *)lParam;
+ UpdateParams.Waiting=!ThisThreadWindow;
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:CHANGECONTENT:posting UPDATEMAILS\n");
+ #endif
+ if(ThisThreadWindow)
+ {
+ if(!UpdateMails(hDlg,(HACCOUNT)wParam,UpdateParams.Flags->nflags,UpdateParams.Flags->nnflags))
+ DestroyWindow(hDlg);
+ }
+ else if(PostMessage(hDlg,WM_YAMN_UPDATEMAILS,wParam,(LPARAM)&UpdateParams)) //this ensures UpdateMails will execute the thread who created the browser window
+ {
+ if(!ThisThreadWindow)
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:CHANGECONTENT:waiting for event\n");
+ #endif
+ WaitForSingleObject(UpdateParams.Copied,INFINITE);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:CHANGECONTENT:event signaled\n");
+ #endif
+ }
+ }
+
+ CloseHandle(UpdateParams.Copied);
+ }
+ return 1;
+ case WM_YAMN_UPDATEMAILS:
+ {
+ HACCOUNT ActualAccount;
+
+ struct CUpdateMails *um=(struct CUpdateMails *)lParam;
+ DWORD nflags,nnflags;
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:UPDATEMAILS\n");
+ #endif
+
+ if(NULL==(ActualAccount=GetWindowAccount(hDlg)))
+ return 0;
+ if((HACCOUNT)wParam!=ActualAccount)
+ return 0;
+
+ nflags=um->Flags->nflags;
+ nnflags=um->Flags->nnflags;
+
+ if(um->Waiting)
+ SetEvent(um->Copied);
+
+ if(!UpdateMails(hDlg,ActualAccount,nflags,nnflags))
+ DestroyWindow(hDlg);
+ }
+ return 1;
+ case WM_YAMN_STOPACCOUNT:
+ {
+ HACCOUNT ActualAccount;
+
+ if(NULL==(ActualAccount=GetWindowAccount(hDlg)))
+ break;
+ if((HACCOUNT)wParam!=ActualAccount)
+ break;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:STOPACCOUNT:sending destroy msg\n");
+ #endif
+ PostQuitMessage(0);
+ }
+ return 1;
+ case WM_YAMN_NOTIFYICON:
+ {
+ HACCOUNT ActualAccount;
+ if(NULL==(ActualAccount=GetWindowAccount(hDlg)))
+ break;
+
+ switch(lParam)
+ {
+ case WM_LBUTTONDBLCLK:
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DBLCLICKICON:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DBLCLICKICON:ActualAccountSO-read wait failed\n");
+ #endif
+ return 0;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DBLCLICKICON:ActualAccountSO-read enter\n");
+ #endif
+ if(ActualAccount->AbilityFlags & YAMN_ACC_BROWSE)
+ {
+ ShowWindow(hDlg,SW_SHOWNORMAL);
+ SetForegroundWindow(hDlg);
+ }
+ else
+ DestroyWindow(hDlg);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DBLCLICKICON:ActualAccountSO-read done\n");
+ #endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ break;
+ }
+ break;
+ }
+ case WM_YAMN_SHOWSELECTED:
+ {
+ int iSelect;
+ iSelect=SendMessage(GetDlgItem(hDlg,IDC_LISTMAILS),LVM_GETNEXTITEM,-1,MAKELPARAM((UINT)LVNI_FOCUSED,0)); // return item selected
+
+ if(iSelect!=-1)
+ {
+ LV_ITEMW item;
+ HYAMNMAIL ActualMail;
+
+ item.iItem=iSelect;
+ item.iSubItem=0;
+ item.mask=LVIF_PARAM | LVIF_STATE;
+ item.stateMask=0xFFFFFFFF;
+ ListView_GetItem(GetDlgItem(hDlg,IDC_LISTMAILS),&item);
+ ActualMail=(HYAMNMAIL)item.lParam;
+ if(NULL!=ActualMail)
+ {
+ //ShowEmailThread
+ PYAMN_MAILSHOWPARAM MailParam = new YAMN_MAILSHOWPARAM;
+ MailParam->account = GetWindowAccount(hDlg);
+ MailParam->mail = ActualMail;
+ if(NULL!=(MailParam->ThreadRunningEV=CreateEvent(NULL,FALSE,FALSE,NULL))){
+ HANDLE NewThread;
+ if(NULL!=(NewThread=CreateThread(NULL,0,ShowEmailThread,MailParam,0,NULL)))
+ {
+ //WaitForSingleObject(MailParam->ThreadRunningEV,INFINITE);
+ CloseHandle(NewThread);
+ }
+ CloseHandle(MailParam->ThreadRunningEV);
+ }
+ //delete MailParam;
+ }
+ }
+ } break;
+ case WM_SYSCOMMAND:
+ {
+ HACCOUNT ActualAccount;
+
+ if(NULL==(ActualAccount=GetWindowAccount(hDlg)))
+ break;
+ switch(wParam)
+ {
+ case SC_CLOSE:
+ DestroyWindow(hDlg);
+ break;
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ {
+ HACCOUNT ActualAccount;
+ int Items;
+
+ if(NULL==(ActualAccount=GetWindowAccount(hDlg)))
+ break;
+
+ switch(LOWORD(wParam))
+ {
+ case IDC_BTNCHECKALL:
+ ListView_SetItemState(GetDlgItem(hDlg,IDC_LISTMAILS), -1, 0, LVIS_SELECTED); // deselect all items
+ ListView_SetItemState(GetDlgItem(hDlg,IDC_LISTMAILS),-1, LVIS_SELECTED ,LVIS_SELECTED);
+ Items = ListView_GetItemCount(GetDlgItem(hDlg,IDC_LISTMAILS));
+ ListView_RedrawItems(GetDlgItem(hDlg,IDC_LISTMAILS), 0, Items);
+ UpdateWindow(GetDlgItem(hDlg,IDC_LISTMAILS));
+ SetFocus(GetDlgItem(hDlg,IDC_LISTMAILS));
+ break;
+
+ case IDC_BTNOK:
+ DestroyWindow(hDlg);
+ break;
+
+ case IDC_BTNAPP:
+ {
+ PROCESS_INFORMATION pi;
+ STARTUPINFOW si;
+
+ ZeroMemory(&si,sizeof(si));
+ si.cb=sizeof(si);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:BTNAPP:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0==WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:BTNAPP:ActualAccountSO-read enter\n");
+ #endif
+ if(ActualAccount->NewMailN.App!=NULL)
+ {
+ WCHAR *Command;
+ if(ActualAccount->NewMailN.AppParam!=NULL)
+ Command=new WCHAR[wcslen(ActualAccount->NewMailN.App)+wcslen(ActualAccount->NewMailN.AppParam)+6];
+ else
+ Command=new WCHAR[wcslen(ActualAccount->NewMailN.App)+6];
+
+ if(Command!=NULL)
+ {
+ lstrcpyW(Command,L"\"");
+ lstrcatW(Command,ActualAccount->NewMailN.App);
+ lstrcatW(Command,L"\" ");
+ if(ActualAccount->NewMailN.AppParam!=NULL)
+ lstrcatW(Command,ActualAccount->NewMailN.AppParam);
+ CreateProcessW(NULL,Command,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
+ delete[] Command;
+ }
+ }
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:BTNAPP:ActualAccountSO-read done\n");
+ #endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+ #ifdef DEBUG_SYNCHRO
+ else
+ DebugLog(SynchroFile,"MailBrowser:BTNAPP:ActualAccountSO-read enter failed\n");
+ #endif
+ if(!(GetKeyState(VK_SHIFT) & 0x8000) && !(GetKeyState(VK_CONTROL) & 0x8000))
+ DestroyWindow(hDlg);
+
+ }
+ break;
+ case IDC_BTNDEL:
+ {
+ LVITEMW item;
+ HYAMNMAIL FirstMail=NULL,ActualMail;
+ HANDLE ThreadRunningEV;
+ DWORD tid,Total=0;
+
+ // we use event to signal, that running thread has all needed stack parameters copied
+ if(NULL==(ThreadRunningEV=CreateEvent(NULL,FALSE,FALSE,NULL)))
+ break;
+ int Items=ListView_GetItemCount(GetDlgItem(hDlg,IDC_LISTMAILS));
+
+ item.stateMask=0xFFFFFFFF;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:BTNDEL:ActualAccountMsgsSO-write wait\n");
+ #endif
+ if(WAIT_OBJECT_0==WaitToWriteFcn(ActualAccount->MessagesAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:BTNDEL:ActualAccountMsgsSO-write enter\n");
+ #endif
+ for(int i=0;i<Items;i++)
+ {
+ item.iItem=i;
+ item.iSubItem=0;
+ item.mask=LVIF_PARAM | LVIF_STATE;
+ item.stateMask=0xFFFFFFFF;
+ ListView_GetItem(GetDlgItem(hDlg,IDC_LISTMAILS),&item);
+ ActualMail=(HYAMNMAIL)item.lParam;
+ if(NULL==ActualMail)
+ break;
+ if(item.state & LVIS_SELECTED)
+ {
+ ActualMail->Flags|=YAMN_MSG_USERDELETE; //set to mail we are going to delete it
+ Total++;
+ }
+ }
+
+ // Enable write-access to mails
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:BTNDEL:ActualAccountMsgsSO-write done\n");
+ #endif
+ WriteDoneFcn(ActualAccount->MessagesAccessSO);
+
+ if(Total)
+ {
+ char DeleteMsg[1024];
+
+ sprintf(DeleteMsg,Translate("Do you really want to delete %d selected mails?"),Total);
+ if(IDOK==MessageBox(hDlg,DeleteMsg,Translate("Delete confirmation"),MB_OKCANCEL | MB_ICONWARNING))
+ {
+ struct DeleteParam ParamToDeleteMails={YAMN_DELETEVERSION,ThreadRunningEV,ActualAccount,NULL};
+
+ // Find if there's mail marked to delete, which was deleted before
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:BTNDEL:ActualAccountMsgsSO-write wait\n");
+ #endif
+ if(WAIT_OBJECT_0==WaitToWriteFcn(ActualAccount->MessagesAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:BTNDEL:ActualAccountMsgsSO-write enter\n");
+ #endif
+ for(ActualMail=(HYAMNMAIL)ActualAccount->Mails;ActualMail!=NULL;ActualMail=ActualMail->Next)
+ {
+ if((ActualMail->Flags & YAMN_MSG_DELETED) && ((ActualMail->Flags & YAMN_MSG_USERDELETE))) //if selected mail was already deleted
+ {
+ DeleteMessageFromQueueFcn((HYAMNMAIL *)&ActualAccount->Mails,ActualMail,1);
+ CallService(MS_YAMN_DELETEACCOUNTMAIL,(WPARAM)ActualAccount->Plugin,(LPARAM)ActualMail); //delete it from memory
+ continue;
+ }
+ }
+ // Set flag to marked mails that they can be deleted
+ SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails,YAMN_MSG_DISPLAY | YAMN_MSG_USERDELETE,0,YAMN_MSG_DELETEOK,1);
+ // Create new thread which deletes marked mails.
+ HANDLE NewThread;
+
+ if(NULL!=(NewThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ActualAccount->Plugin->Fcn->DeleteMailsFcnPtr,(LPVOID)&ParamToDeleteMails,0,&tid)))
+ {
+ WaitForSingleObject(ThreadRunningEV,INFINITE);
+ CloseHandle(NewThread);
+ }
+ // Enable write-access to mails
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:BTNDEL:ActualAccountMsgsSO-write done\n");
+ #endif
+ WriteDoneFcn(ActualAccount->MessagesAccessSO);
+ }
+ }
+ else
+ //else mark messages that they are not to be deleted
+ SetRemoveFlagsInQueueFcn((HYAMNMAIL)ActualAccount->Mails,YAMN_MSG_DISPLAY | YAMN_MSG_USERDELETE,0,YAMN_MSG_USERDELETE,0);
+ }
+ }
+ CloseHandle(ThreadRunningEV);
+ if(DBGetContactSettingByte(NULL, YAMN_DBMODULE, YAMN_CLOSEDELETE, 0))
+ DestroyWindow(hDlg);
+
+ }
+ break;
+ }
+ }
+ break;
+ case WM_SIZE:
+ if(wParam==SIZE_RESTORED)
+ {
+ LONG x=LOWORD(lParam); //((LPRECT)lParam)->right-((LPRECT)lParam)->left;
+ LONG y=HIWORD(lParam); //((LPRECT)lParam)->bottom-((LPRECT)lParam)->top;
+ MoveWindow(GetDlgItem(hDlg,IDC_BTNDEL), 5 ,y-5-25,(x-20)/3,25,TRUE); //where to put DELETE button while resizing
+ MoveWindow(GetDlgItem(hDlg,IDC_BTNCHECKALL),10+ (x-20)/3,y-5-25,(x-20)/6,25,TRUE); //where to put CHECK ALL button while resizing
+ MoveWindow(GetDlgItem(hDlg,IDC_BTNAPP), 15+ (x-20)/3 + (x-20)/6,y-5-25,(x-20)/3,25,TRUE); //where to put RUN APP button while resizing
+ MoveWindow(GetDlgItem(hDlg,IDC_BTNOK), 20+2*(x-20)/3 + (x-20)/6 ,y-5-25,(x-20)/6,25,TRUE); //where to put OK button while resizing
+ MoveWindow(GetDlgItem(hDlg,IDC_LISTMAILS), 5 ,5 ,x-10 ,y-55,TRUE); //where to put list mail window while resizing
+ MoveWindow(GetDlgItem(hDlg,IDC_STSTATUS), 5 ,y-5-45 ,x-10 ,15,TRUE); //where to put account status text while resizing
+ }
+// break;
+ return 0;
+ case WM_GETMINMAXINFO:
+ ((LPMINMAXINFO)lParam)->ptMinTrackSize.x=MAILBROWSER_MINXSIZE;
+ ((LPMINMAXINFO)lParam)->ptMinTrackSize.y=MAILBROWSER_MINYSIZE;
+ return 0;
+ case WM_TIMER:
+ {
+ NOTIFYICONDATA nid;
+ struct CMailWinUserInfo *mwui=(struct CMailWinUserInfo *)GetWindowLongPtr(hDlg,DWLP_USER);
+
+ ZeroMemory(&nid,sizeof(nid));
+ nid.cbSize=sizeof(NOTIFYICONDATA);
+ nid.hWnd=hDlg;
+ nid.uID=0;
+ nid.uFlags=NIF_ICON;
+ if(mwui->TrayIconState==0)
+ nid.hIcon=hYamnIcons[0];
+ else
+ nid.hIcon=hYamnIcons[2];
+ Shell_NotifyIcon(NIM_MODIFY,&nid);
+ mwui->TrayIconState=!mwui->TrayIconState;
+// UpdateWindow(hDlg);
+ }
+ break;
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+
+ case IDC_LISTMAILS:
+ {
+
+ switch(((LPNMHDR)lParam)->code)
+ {
+ case NM_DBLCLK:
+ SendMessage(hDlg,WM_YAMN_SHOWSELECTED,0,0);
+ break;
+ case LVN_COLUMNCLICK:
+ HACCOUNT ActualAccount;
+ if(NULL!=(ActualAccount=GetWindowAccount(hDlg))){
+ NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)lParam;
+ if(WAIT_OBJECT_0==WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:COLUMNCLICK:ActualAccountSO-read enter\n");
+ #endif
+ switch((int)pNMListView->iSubItem)
+ {
+ case 0:
+ bFrom = !bFrom;
+ break;
+ case 1:
+ bSub = !bSub;
+ break;
+ case 2:
+ bSize = !bSize;
+ break;
+ case 3:
+ bDate = !bDate;
+ break;
+ default:
+ break;
+ }
+ ListView_SortItems(pNMListView->hdr.hwndFrom,ListViewCompareProc,pNMListView->iSubItem);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:BTNAPP:ActualAccountSO-read done\n");
+ #endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ } }
+ break;
+
+ case NM_CUSTOMDRAW:
+ {
+ HACCOUNT ActualAccount;
+ LPNMLVCUSTOMDRAW cd=(LPNMLVCUSTOMDRAW)lParam;
+ LONG_PTR PaintCode;
+
+ if(NULL==(ActualAccount=GetWindowAccount(hDlg)))
+ break;
+
+ switch(cd->nmcd.dwDrawStage)
+ {
+ case CDDS_PREPAINT:
+ PaintCode=CDRF_NOTIFYITEMDRAW;
+ break;
+ case CDDS_ITEMPREPAINT:
+ PaintCode=CDRF_NOTIFYSUBITEMDRAW;
+ break;
+ case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
+ {
+// COLORREF crText, crBkgnd;
+// crText= RGB(128,128,255);
+ HYAMNMAIL ActualMail;
+ BOOL umma;
+
+ {
+ struct CMailWinUserInfo *mwui;
+ mwui=(struct CMailWinUserInfo *)GetWindowLongPtr(hDlg,DWLP_USER);
+ umma= mwui->UpdateMailsMessagesAccess;
+ }
+ ActualMail=(HYAMNMAIL)cd->nmcd.lItemlParam;
+ if(!ActualMail)
+ ActualMail=(HYAMNMAIL)readItemLParam(cd->nmcd.hdr.hwndFrom,cd->nmcd.dwItemSpec);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DRAWITEM:ActualAccountMsgsSO-read wait\n");
+ #endif
+ if(!umma)
+ if(WAIT_OBJECT_0!=WaitToReadFcn(ActualAccount->MessagesAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DRAWITEM:ActualAccountMsgsSO-read wait failed\n");
+ #endif
+ return 0;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DRAWITEM:ActualAccountMsgsSO-read enter\n");
+ #endif
+ switch(ActualMail->Flags & YAMN_MSG_SPAMMASK)
+ {
+ case YAMN_MSG_SPAML1:
+ case YAMN_MSG_SPAML2:
+ cd->clrText=RGB(150,150,150);
+ break;
+ case YAMN_MSG_SPAML3:
+ cd->clrText=RGB(200,200,200);
+ cd->clrTextBk=RGB(160,160,160);
+ break;
+ case 0:
+ if(cd->nmcd.dwItemSpec & 1)
+ cd->clrTextBk=RGB(230,230,230);
+ break;
+ default:
+ break;
+ }
+ if(ActualMail->Flags & YAMN_MSG_UNSEEN)
+ cd->clrTextBk=RGB(220,235,250);
+ PaintCode=CDRF_DODEFAULT;
+
+ if(!umma)
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:DRAWITEM:ActualAccountMsgsSO-read done\n");
+ #endif
+ ReadDoneFcn(ActualAccount->MessagesAccessSO);
+ }
+
+ break;
+ }
+ }
+ SetWindowLongPtr(hDlg,DWLP_MSGRESULT,PaintCode);
+ return 1;
+ }
+ }
+ }
+ }
+ break;
+ case WM_CONTEXTMENU:
+ {
+ if ( GetWindowLongPtr(( HWND )wParam, GWLP_ID ) == IDC_LISTMAILS) {
+ //MessageBox(0,"LISTHEADERS","Debug",0);
+ HWND hList = GetDlgItem( hDlg, IDC_LISTMAILS );
+ POINT pt = { (signed short)LOWORD( lParam ), (signed short)HIWORD( lParam ) };
+ HTREEITEM hItem = 0;
+ if (pt.x==-1) pt.x = 0;
+ if (pt.y==-1) pt.y = 0;
+ if (int numRows = ListView_GetItemCount(hList)){
+ HMENU hMenu = CreatePopupMenu();
+ AppendMenu(hMenu, MF_STRING, (UINT_PTR)1, TranslateT("Copy Selected"));
+ AppendMenu(hMenu, MF_STRING, (UINT_PTR)2, TranslateT("Copy All"));
+ AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
+ AppendMenu(hMenu, MF_STRING, (UINT_PTR)0, TranslateT("Cancel"));
+ int nReturnCmd = TrackPopupMenu( hMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hDlg, NULL );
+ DestroyMenu( hMenu );
+ if (nReturnCmd>0){
+ int courRow=0;
+ size_t sizeNeeded = 0;
+ WCHAR from[128]={0}, subject[256]={0}, size[16]={0}, date[64]={0};
+ for (courRow=0;courRow<numRows;courRow++){
+ if ((nReturnCmd==1) && (ListView_GetItemState(hList, courRow, LVIS_SELECTED)==0)) continue;
+ ListView_GetItemText(hList, courRow, 0, from, SIZEOF(from));
+ ListView_GetItemText(hList, courRow, 1, subject, SIZEOF(subject));
+ ListView_GetItemText(hList, courRow, 2, size, SIZEOF(size));
+ ListView_GetItemText(hList, courRow, 3, date, SIZEOF(date));
+ sizeNeeded += 5+wcslen(from)+wcslen(subject)+wcslen(size)+wcslen(date);
+ }
+ if (!sizeNeeded) {
+#ifdef _DEBUG
+ MessageBox(hDlg,"Nothing To Copy","Debug MailBrowser",0);
+#endif
+ } else if(OpenClipboard(hDlg)){
+ EmptyClipboard();
+ HGLOBAL hData=GlobalAlloc(GMEM_MOVEABLE,(sizeNeeded+1)*sizeof(WCHAR));
+ WCHAR *buff = (WCHAR *)GlobalLock(hData);
+ int courPos = 0;
+ for (courRow=0;courRow<numRows;courRow++){
+ if ((nReturnCmd==1) && (ListView_GetItemState(hList, courRow, LVIS_SELECTED)==0)) continue;
+ ListView_GetItemText(hList, courRow, 0, from, SIZEOF(from));
+ ListView_GetItemText(hList, courRow, 1, subject, SIZEOF(subject));
+ ListView_GetItemText(hList, courRow, 2, size, SIZEOF(size));
+ ListView_GetItemText(hList, courRow, 3, date, SIZEOF(date));
+ courPos += swprintf(&buff[courPos],L"%s\t%s\t%s\t%s\r\n",from,subject,size,date);
+ }
+ GlobalUnlock(hData);
+ SetClipboardData(CF_UNICODETEXT,hData);
+ CloseClipboard();
+ }
+ }
+ }
+ } }
+ break; // just in case
+ default:
+ return 0;
+ }
+// return DefWindowProc(hDlg,msg,wParam,lParam);
+ return 0;
+}
+
+LRESULT CALLBACK ListViewSubclassProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ HWND hwndParent = GetParent(hDlg);
+
+ switch(msg) {
+ case WM_GETDLGCODE :
+ {
+ LPMSG lpmsg;
+ if ( ( lpmsg = (LPMSG)lParam ) != NULL ) {
+ if ( lpmsg->message == WM_KEYDOWN
+ && lpmsg->wParam == VK_RETURN)
+ return DLGC_WANTALLKEYS;
+ }
+ break;
+ }
+ case WM_KEYDOWN:
+ {
+
+ BOOL isCtrl = GetKeyState(VK_CONTROL) & 0x8000;
+ BOOL isShift = GetKeyState(VK_SHIFT) & 0x8000;
+ BOOL isAlt = GetKeyState(VK_MENU) & 0x8000;
+
+ switch (wParam)
+ {
+ case 'A': // ctrl-a
+ if(!isAlt && !isShift && isCtrl) SendMessage(hwndParent,WM_COMMAND,IDC_BTNCHECKALL,0);
+ break;
+ case VK_RETURN:
+ case VK_SPACE:
+ if(!isAlt && !isShift && !isCtrl) SendMessage(hwndParent,WM_YAMN_SHOWSELECTED,0,0);
+ break;
+ case VK_DELETE:
+ SendMessage(hwndParent,WM_COMMAND,IDC_BTNDEL,0);
+ break;
+ }
+
+ break;
+
+ }
+ }
+ return CallWindowProc(OldListViewSubclassProc, hDlg, msg, wParam, lParam);
+}
+
+DWORD WINAPI MailBrowser(LPVOID Param)
+{
+ MSG msg;
+
+ HWND hMailBrowser;
+ BOOL WndFound=FALSE;
+ HACCOUNT ActualAccount;
+ struct MailBrowserWinParam MyParam;
+
+ MyParam=*(struct MailBrowserWinParam *)Param;
+ ActualAccount=MyParam.account;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:Incrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+ #endif
+ SCIncFcn(ActualAccount->UsingThreads);
+
+// we will not use params in stack anymore
+ SetEvent(MyParam.ThreadRunningEV);
+
+ __try
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:ActualAccountSO-read wait failed\n");
+ #endif
+ return 0;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:ActualAccountSO-read enter\n");
+ #endif
+ if(!(ActualAccount->AbilityFlags & YAMN_ACC_BROWSE))
+ {
+ MyParam.nflags=MyParam.nflags & ~YAMN_ACC_MSG;
+ MyParam.nnflags=MyParam.nnflags & ~YAMN_ACC_MSG;
+ }
+ if(!(ActualAccount->AbilityFlags & YAMN_ACC_POPUP))
+ MyParam.nflags=MyParam.nflags & ~YAMN_ACC_POP;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:ActualAccountSO-read done\n");
+ #endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+
+ if(NULL!=(hMailBrowser=WindowList_Find(YAMNVar.NewMailAccountWnd,ActualAccount)))
+ WndFound=TRUE;
+ if((hMailBrowser==NULL) && ((MyParam.nflags & YAMN_ACC_MSG) || (MyParam.nflags & YAMN_ACC_ICO) || (MyParam.nnflags & YAMN_ACC_MSG)))
+ {
+ hMailBrowser=CreateDialogParamW(YAMNVar.hInst,MAKEINTRESOURCEW(IDD_DLGVIEWMESSAGES),NULL,(DLGPROC)DlgProcYAMNMailBrowser,(LPARAM)&MyParam);
+ SendMessageW(hMailBrowser,WM_SETICON,(WPARAM)ICON_BIG,(LPARAM)hYamnIcons[2]);
+ SendMessageW(hMailBrowser,WM_SETICON,(WPARAM)ICON_SMALL,(LPARAM)hYamnIcons[2]);
+ MoveWindow(hMailBrowser,PosX,PosY,SizeX,SizeY,TRUE);
+ }
+
+ if(hMailBrowser!=NULL)
+ {
+ struct CChangeContent Params={MyParam.nflags,MyParam.nnflags}; //if this thread created window, just post message to update mails
+
+ SendMessageW(hMailBrowser,WM_YAMN_CHANGECONTENT,(WPARAM)ActualAccount,(LPARAM)&Params); //we ensure this will do the thread who created the browser window
+ }
+ else
+ UpdateMails(NULL,ActualAccount,MyParam.nflags,MyParam.nnflags); //update mails without displaying or refreshing any window
+
+ if((hMailBrowser!=NULL) && !WndFound) //we process message loop only for thread that created window
+ {
+ while(GetMessage(&msg,NULL,0,0))
+ {
+ if(!IsDialogMessage(hMailBrowser, &msg))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ }
+
+ if((!WndFound) && (ActualAccount->Plugin->Fcn!=NULL) && (ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr!=NULL) && ActualAccount->AbleToWork)
+ ActualAccount->Plugin->Fcn->WriteAccountsFcnPtr();
+ }
+ __finally
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"MailBrowser:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+ #endif
+ SCDecFcn(ActualAccount->UsingThreads);
+ }
+ return 1;
+}
+
+INT_PTR RunMailBrowserSvc(WPARAM wParam,LPARAM lParam)
+{
+ DWORD tid;
+ //an event for successfull copy parameters to which point a pointer in stack for new thread
+ HANDLE ThreadRunningEV;
+ PYAMN_MAILBROWSERPARAM Param=(PYAMN_MAILBROWSERPARAM)wParam;
+
+ if((DWORD)lParam!=YAMN_MAILBROWSERVERSION)
+ return 0;
+
+ if(NULL!=(ThreadRunningEV=CreateEvent(NULL,FALSE,FALSE,NULL)))
+ {
+ HANDLE NewThread;
+
+ Param->ThreadRunningEV=ThreadRunningEV;
+ if(NULL!=(NewThread=CreateThread(NULL,0,MailBrowser,Param,0,&tid)))
+ {
+ WaitForSingleObject(ThreadRunningEV,INFINITE);
+ CloseHandle(NewThread);
+ }
+ CloseHandle(ThreadRunningEV);
+ return 1;
+ }
+ return 0;
+}
diff --git a/yamn/debug.cpp b/yamn/debug.cpp new file mode 100644 index 0000000..67fbf5c --- /dev/null +++ b/yamn/debug.cpp @@ -0,0 +1,142 @@ +/*
+ * YAMN plugin main file
+ * Miranda homepage: http://miranda-icq.sourceforge.net/
+ *
+ * Debug functions used in DEBUG release (you need to global #define DEBUG to get debug version)
+ *
+ * (c) majvan 2002-2004
+ */
+
+/*#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>*/
+#include "debug.h"
+#ifdef YAMN_DEBUG
+#include "yamn.h"
+#include "version.h"
+
+#if defined (WIN9X)
+ #define YAMN_VER "YAMN " YAMN_VERSION_C " (Win9x)"
+#elif defined(WIN2IN1)
+ #define YAMN_VER "YAMN " YAMN_VERSION_C " (2in1)"
+#else
+ #define YAMN_VER "YAMN " YAMN_VERSION_C " (WinNT)"
+#endif
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+TCHAR DebugUserDirectory[MAX_PATH]=".";
+LPCRITICAL_SECTION FileAccessCS;
+
+#ifdef DEBUG_SYNCHRO
+TCHAR DebugSynchroFileName2[]=_T("%s\\yamn-debug.synchro.log");
+HANDLE SynchroFile;
+#endif
+
+#ifdef DEBUG_COMM
+TCHAR DebugCommFileName2[]=_T("%s\\yamn-debug.comm.log");
+HANDLE CommFile;
+#endif
+
+#ifdef DEBUG_DECODE
+TCHAR DebugDecodeFileName2[]=_T("%s\\yamn-debug.decode.log");
+HANDLE DecodeFile;
+#endif
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+void InitDebug()
+{
+#if defined (DEBUG_SYNCHRO) || defined (DEBUG_COMM) || defined (DEBUG_DECODE)
+ TCHAR DebugFileName[MAX_PATH];
+#endif
+ if(FileAccessCS==NULL)
+ {
+ FileAccessCS=new CRITICAL_SECTION;
+ InitializeCriticalSection(FileAccessCS);
+ }
+
+#ifdef DEBUG_SYNCHRO
+ _stprintf(DebugFileName,DebugSynchroFileName2,DebugUserDirectory);
+
+ SynchroFile=CreateFile(DebugFileName,GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL);
+ DebugLog(SynchroFile,"Synchro debug file created by %s\n",YAMN_VER);
+#endif
+
+#ifdef DEBUG_COMM
+ _stprintf(DebugFileName,DebugCommFileName2,DebugUserDirectory);
+
+ CommFile=CreateFile(DebugFileName,GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL);
+ DebugLog(CommFile,"Communication debug file created by %s\n",YAMN_VER);
+#endif
+
+#ifdef DEBUG_DECODE
+ _stprintf(DebugFileName,DebugDecodeFileName2,DebugUserDirectory);
+
+ DecodeFile=CreateFile(DebugFileName,GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,CREATE_ALWAYS,0,NULL);
+ DebugLog(DecodeFile,"Decoding kernel debug file created by %s\n",YAMN_VER);
+#endif
+}
+
+void UnInitDebug()
+{
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"File is being closed normally.");
+ CloseHandle(SynchroFile);
+#endif
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"File is being closed normally.");
+ CloseHandle(CommFile);
+#endif
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"File is being closed normally.");
+ CloseHandle(DecodeFile);
+#endif
+}
+
+
+void DebugLog(HANDLE File,const char *fmt,...)
+{
+ char *str;
+ char tids[32];
+ va_list vararg;
+ int strsize;
+ DWORD Written;
+
+ va_start(vararg,fmt);
+ str=(char *)malloc(strsize=65536);
+ _stprintf(tids,_T("[%x]"),GetCurrentThreadId());
+ while(_vsnprintf(str,strsize,fmt,vararg)==-1)
+ str=(char *)realloc(str,strsize+=65536);
+ va_end(vararg);
+ EnterCriticalSection(FileAccessCS);
+ WriteFile(File,tids,(DWORD)strlen(tids),&Written,NULL);
+ WriteFile(File,str,(DWORD)strlen(str),&Written,NULL);
+ LeaveCriticalSection(FileAccessCS);
+ free(str);
+}
+
+void DebugLogW(HANDLE File,const WCHAR *fmt,...)
+{
+ WCHAR *str;
+ char tids[32];
+ va_list vararg;
+ int strsize;
+ DWORD Written;
+
+ va_start(vararg,fmt);
+ str=(WCHAR *)malloc((strsize=65536)*sizeof(WCHAR));
+ _stprintf(tids,_T("[%x]"),GetCurrentThreadId());
+ while(_vsnwprintf(str,strsize,fmt,vararg)==-1)
+ str=(WCHAR *)realloc(str,(strsize+=65536)*sizeof(WCHAR));
+ va_end(vararg);
+ EnterCriticalSection(FileAccessCS);
+ WriteFile(File,tids,(DWORD)strlen(tids),&Written,NULL);
+ WriteFile(File,str,(DWORD)wcslen(str)*sizeof(WCHAR),&Written,NULL);
+ LeaveCriticalSection(FileAccessCS);
+ free(str);
+}
+
+#endif //ifdef DEBUG
\ No newline at end of file diff --git a/yamn/debug.h b/yamn/debug.h new file mode 100644 index 0000000..df69772 --- /dev/null +++ b/yamn/debug.h @@ -0,0 +1,64 @@ +#ifndef __DEBUG_H
+#define __DEBUG_H
+
+// #define YAMN_DEBUG
+
+//#define YAMN_VER_BETA
+//#define YAMN_VER_BETA_CRASHONLY
+
+#ifdef YAMN_DEBUG
+
+//#pragma comment(lib, "th32.lib")
+
+#if !defined(_WIN32_WINNT)
+#define _WIN32_WINNT 0x0501 // WinXP only
+#endif
+#define VC_EXTRALEAN
+#include <windows.h>
+#include <tlhelp32.h>
+#include <stdio.h>
+#include <shlwapi.h>
+
+//#define DEBUG_SYNCHRO //debug synchro to a file
+//#define DEBUG_COMM //debug communiation to a file
+//#define DEBUG_DECODE //debug header decoding to a file
+//#define DEBUG_DECODECODEPAGE //add info about codepage used in conversion
+//#define DEBUG_DECODEBASE64 //add info about base64 result
+//#define DEBUG_DECODEQUOTED //add info about quoted printable result
+//#define DEBUG_FILEREAD //debug file reading to message boxes
+//#define DEBUG_FILEREADMESSAGES //debug file reading messages to message boxes
+
+void DebugLog(HANDLE,const char *fmt,...);
+void DebugLogW(HANDLE File,const WCHAR *fmt,...);
+
+#ifdef DEBUG_SYNCHRO
+// Used for synchronization debug
+extern HANDLE SynchroFile;
+#endif
+
+#ifdef DEBUG_COMM
+// Used for communication debug
+extern HANDLE CommFile;
+#endif
+
+#ifdef DEBUG_DECODE
+// Used for decoding debug
+extern HANDLE DecodeFile;
+#endif
+
+#if defined(DEBUG_FILEREAD) || defined(DEBUG_FILEREADMESSAGES)
+DWORD ReadStringFromMemory(TCHAR **Parser,TCHAR *End,TCHAR **StoreTo,TCHAR *DebugString);
+ #ifndef UNICODE
+DWORD ReadStringFromMemoryW(TCHAR **Parser,TCHAR *End,TCHAR **StoreTo,TCHAR *DebugString);
+ #else
+#define ReadStringFromMemoryW ReadStringFromMemory
+ #endif
+#endif
+
+//#ifdef DEBUG_ACCOUNTS
+//int GetAccounts();
+//void WriteAccounts();
+//#endif
+
+#endif //YAMN_DEBUG
+#endif //_DEBUG_H
diff --git a/yamn/docs/InstallScript.xml b/yamn/docs/InstallScript.xml new file mode 100644 index 0000000..33d8ac9 --- /dev/null +++ b/yamn/docs/InstallScript.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="ISO-8859-1"?>
+<installscript>
+ <info>
+ <name>Yet Another Mail Notifier</name>
+ <author>majvan</author>
+ <version>0.2.4.7</version>
+ <type>Plugin</type>
+ </info>
+
+ <packageinfo>
+ <title>Plugin</title>
+ <file>YAMN.dll</file>
+ </packageinfo>
+
+ <packageinfo>
+ <optional/>
+ <title>Documentation</title>
+ <file>YAMN-Readme.txt</file>
+ <file>YAMN-License.txt</file>
+ <document/>
+ </packageinfo>
+
+ <packageinfo>
+ <optional/>
+ <title>Developers Information</title>
+ <file>YAMN-Readme.developers.txt</file>
+ <document/>
+ </packageinfo>
+
+ <packageinfo>
+ <optional/>
+ <title>Simple filter plugin</title>
+ <file>YAMN\simple.dll</file>
+ <file>YAMN\simple-readme.txt</file>
+ </packageinfo>
+
+ <packageinfo>
+ <optional/>
+ <title>Base filter plugin</title>
+ <file>YAMN\base.dll</file>
+ <file>YAMN\base-readme.txt</file>
+ </packageinfo>
+
+ <autorun>
+ <file>YAMN-Readme.txt</file>
+ <document/>
+ </autorun>
+
+</installscript>
diff --git a/yamn/docs/YAMN-License.txt b/yamn/docs/YAMN-License.txt new file mode 100644 index 0000000..7f11610 --- /dev/null +++ b/yamn/docs/YAMN-License.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/yamn/docs/YAMN-Readme.developers.txt b/yamn/docs/YAMN-Readme.developers.txt new file mode 100644 index 0000000..fdb3387 --- /dev/null +++ b/yamn/docs/YAMN-Readme.developers.txt @@ -0,0 +1,205 @@ +==================================================================================
+= YAMN plugin for Miranda (short readme for developers) =
+==================================================================================
+Hello developer! :)
+I hope YAMN will give you what you find, but you can also improve YAMN.
+
+This readme gives you some info about YAMN. Please read it first before you are
+going to look at YAMN sources.
+
+YAMN provides two types of plugins now: protocol plugins and filter plugins.
+
+
+1. What do you need to make your protocol plugin cooperating with YAMN
+ -------------------------------------------------------------------
+
+ If you want to cooperate with YAMN, you have to do some things. YAMN offers you some services,
+ so your work is easier, but YAMN needs some things to be done for proper work. These limits go
+ according thread synchronization and memory mutual exclusion.
+
+ YAMN offers you two types of services. Exported functions and Miranda services. Miranda
+ services are described in header files, exported functions are described in cpp files. All
+ exported functions in YAMN have the suffix Fcn, so you can easy get if the function is
+ exported. Using exported functions is more difficult than using miranda services, but after
+ solving some definitions, the work with exported functions is more clear and easier. Miranda
+ services from YAMN are for miscellaneus functions. The fact Miranda service uses only two
+ parameters and therefore is sometimes very unsuitable leads us to make exported functions.
+ Exported functions are divided in several parts: synchronizing functions (used for thread
+ and account synchronization) and MIME functions (used to work with MIME
+ messages).
+
+ Miranda services are used through Miranda CallService function. YAMN exported functions are avialable
+ when registering plugin. Then YAMN gives you its table of exported functions.
+
+ How to write write your protocol plugin for YAMN? The best way for you is to look at
+ internal POP3 protocol, where all info about this is written. At start, you need to register
+ plugin (it is done in two steps- registering and inserting to YAMN), then get pointers to
+ YAMN's exported functions (using Miranda's service MS_YAMN_GETFCN) you will need in your
+ protocol plugin. These are the first steps you should do when implementing some plugin to
+ YAMN. Next, you should know how YAMN is stuctured. Structures of YAMN are described in
+ chapter 2. And, at the end, you should know something about account synchronizing and some
+ limitations you have to achieve, if you want your plugin works well.
+
+
+2. YAMN structures and memory organization
+ ---------------------------------------
+
+ YAMN uses its own structures, that can change in the future. The problem with change is,
+ that there can occur some incomapatibilities between YAMN and plugins written for old YAMN
+ versions. To avoid problems, YAMN defines versions for services or exported/imported
+ functions, where strucutre version information is passed to/from plugins.
+
+
+2.1. Structures of protcol plugin queue
+
+ (PYAMN_PROTOPLUGINQUEUE)FirstPlugin---> =(HYAMNPROTOPLUGIN)= ---> =(HYAMNPROTOPLUGIN)= ---> =(HYAMNPROTOPLUGIN)= ---> NULL
+ | | | | | | | | |
+ | . | | | . | | | . | |
+ | . | | | . | | | . | |
+ | . | | | . | | | . | |
+ -------------------- | |------------------| | |------------------| |
+ | Next |--| | Next |--| | Next |--|
+ ==================== ==================== ====================
+
+ This structure is not needed if you only create protocol plugin for YAMN. YAMN plugin does
+ not see and it is not important for it how YAMN works with plugins and how it stores plugins
+ data. For plugin is important only handle for its own plugin, returned from
+ MS_YAMN_REGISTERPLUGIN service.
+
+
+2.2. Structure of accounts
+
+ Every account in YAMN belongs to exact plugin and its members are allocated with
+ MS_YAMN_CREATEPLUGINACCOUNT service. This service cooperates with your function, which is
+ defined in your function import table. In your function (if you have defined it), you should
+ create the whole account. It is because YAMN cannot know which members in structure did you
+ add. So you create the whole derived structure. If your fcn is not implemented (NULL in
+ import table), YAMN creates standard account structure.
+
+ This structure contains information (members) related to YAMN, to plugin and members shared
+ between both (plugin and YAMN). Therefore it is needed to synchronize access to members (see
+ Ch. 3). Standard YAMN account is defined in m_account.h header file. There's also
+ description for every member how it is synchronised. YAMN creates two synchronizing objects
+ (SO) to synchronise access to members. In m_synchro.h file, there are definitions for easy
+ work with these SO.
+
+ Accounts are queued in plugin:
+
+ =(HYAMNPLUGIN)= ---> ===(HACCOUNT)=== ---> ===(HACCOUNT)=== ---> ===(HACCOUNT)=== ---> NULL
+ | | | | | | | | | | | |
+ | | | | | | | | | | | |
+ | . | | | | | | | | | | |
+ | . | | | | | | | | | | |
+ | . | | | | | | | | | | |
+ | | | |--------------| | |--------------| | |--------------| |
+ | (HACCOUNT) | | | Next |--| | Next |--| | Next |--|
+ | FirstAccount|--| ================ ================ ================
+ |-------------|
+ | |
+ ===============
+
+ Every account has its own back pointer to (HYAMNPLUGIN) in Plugin member, so you can easy
+ look at first account, when you have any other account (see m_account.h).
+
+
+2.3. Structure of mails
+
+ Account has a pointer to mails. Account's pointer to mails is pointer to first mail in fact
+ and mails are queued too:
+
+ ==(HACCOUNT)== ---> ==(HYAMNMAIL)== ---> ==(HYAMNMAIL)== ---> ==(HYAMNMAIL)== ---> NULL
+ | | | | | | | | | | | |
+ | . | | | | | | | | | | |
+ | . | | | | | | | | | | |
+ | . | | | | | | | | | | |
+ | | | |-------------| | |-------------| | |-------------| |
+ | (HYAMNMAIL)| | | Next |--| | Next |--| | Next |--|
+ | Mails|--| =============== =============== ===============
+ |------------|
+ | |
+ ==============
+
+ Standard MIME mail is defined in mails/m_mails.h file.
+
+ Plugin can work with accounts in its own way, but note it is needed to synchronize access.
+ For better work, YAMN offers you some services and exports functions. Description of
+ exported functions is in its declartation; for accounts functions see account.cpp, for mails
+ functions see mails/mails.cpp and so on.
+
+
+3. YAMN thread synchronization
+ ---------------------------
+
+ Because YAMN is multithreaded, more than one thread can access to any member of account
+ structure. Therefore access to these members should be synchronised. YAMN offers two types
+ of synchronization objects (SO): SCOUNTER (Synchronized Counter) and SWMRG (Single
+ Writer/Multiple Readers Guard). To use these objects, you can use exported functions:
+
+ SWMRG: WaitToWriteSO, WaitToWriteSOEx, WriteDoneSO, WaitToReadSO, WaitToReadSOEx, ReadDoneSO
+ SCOUNTER: SCGetNumber, SCInc, SCDec
+
+ To see description for these functions, see m_synchro.h header file and synchro.cpp. Note
+ that in HACCOUNT structure, there are 3 synchronizing members, which you have to use if you
+ want to access to any member of account structure. All access techniques (writing to members
+ and read from members) are used in POP3 protocol plugin. Now, it is important what we have
+ to do when we want to make our plugin be synchronized with YAMN (in POP3 protocol it is
+ described too).
+
+ 1. We have to use ThreadRunningEV event when YAMN calls our checking/deleting function. This
+ parameter is to stop YAMN called thread until we do not have copied datas from stack. After
+ that, we SetEvent(ThreadRunningEvent) to unblock YAMN to continue in its work.
+
+ 2. We have to use UsingThreads account's member. This is only for YAMN account deleting
+ prevention. We use this counter to set number of threads using account. If no thread is just
+ using account, account is signaled, that it can be deleted (and is deleted when needed).
+ This leads us to do some things: We use SCInc(UsingThreads) as the first thing we can do. We
+ cannot omit, that called thread finished before we call this function. UsingThreads should
+ have "continuous" value greater than zero when using account. E.g. if YAMN creates thread
+ for plugin that checks account for new mail, YAMN waits until we set ThreadRunningEV (see
+ point 1). After setting this event to signal, that YAMN can continue in its work, we
+ increase SCInc(UsingThreads), so we ensure that another thread uses account before YAMN
+ thread, that uses this account ends. And SCDec(UsingThreads) should be the last thing we do
+ in our thread. If we run another thread in our thread, we should wait until it does not
+ SCInc(UsingThreads) and after that we should continue (just like YAMN creates and calls our
+ thread).
+
+ 3. If we use account's SWMRG (AccountAccessSO, MessagesAccessSO), we should test what our
+ function returned. Use the same methods as POP3 protocol does while testing and accessing
+ critical section. Note that we cannot use WaitToWriteSO(MyAccount->AccountAccessSO), but in
+ easy way we can WaitToWrite(AccountAccess) and for mails
+ WaitToWriteSO(MyAccount->MessagesAccessSO) use MsgsWaitToWrite(AccountAccess) and so on. See
+ export.h file for these definitions.
+
+ 4. Deleting account is quite easy, but in YAMN, it is very problematic operation. If you use
+ MS_YAMN_DELETEACCOUNT service, it is the best way to avoid any problem. These problems raise
+ from the facts desribed in the point 2.
+
+ 5. You should use ctritical sections only for short time not to block other threads. You can
+ imagine that users can't browse through mails, because account is blocked by your thread...
+
+ All needed infos in POP3 internal protocol plugin (see proto/pop3/pop3comm.cpp), are
+ described.
+
+
+4. What do you need to make your filter plugin cooperating with YAMN
+ -----------------------------------------------------------------
+
+ Filter plugins are very easy to write in its own way, it much more easier than protocol
+ plugin. But some things are common: you have to register your plugin and insert to YAMN
+ (these are 2 steps, see sources of some filter plugin), You have to import to YAMN your
+ filter function. Filter function can do anything with mails, but the most important is, that
+ it can set Flags member of mail (see mails/m_mails.h file) to one of YAMN_MSG_SPAMLx.
+ Note Mail is in write-access, so your plugin can do anything with mail and avoid the
+ synchronization problem.
+
+ Now YAMN recognizes 4 spam levels:
+ 1. Notifies about this mail, but shows it in mailbrowser with other color than normally
+ 2. Does not notify about this mail, shows it in mailbrowser with other color than normally
+ 3. Deletes mail from server (depends on protocol), does not notify and shows "this spam was
+ deleted"
+ 4. Deletes mail from server (depends on protocol), does not notify, does not show in
+ mailbrowser
+
+ Your plugin can set data for mail in the TranslatedHeader structure, inserting it to the
+ queue. This information is stored, so it is reloaded after protocol read mails from book
+ file.
diff --git a/yamn/docs/YAMN-Readme.txt b/yamn/docs/YAMN-Readme.txt new file mode 100644 index 0000000..901ad22 --- /dev/null +++ b/yamn/docs/YAMN-Readme.txt @@ -0,0 +1,79 @@ +=========================================================
+= YAMN plugin for Miranda readme =
+=========================================================
+Yet Another Mail Notifier
+Checks pop3 accounts for new mail
+
+Advantages:
+- quite small
+- structured in two parts: notifier and protocols
+- unlimited number of accounts
+- international support in Unicode
+- open-source (GNU-GPL)
+POP3:
+- many switches for each account
+- support for MIME standard
+- support for Base64 and Quoted-Printable
+- 100% detection of new mail based on unique message ID
+- multithreaded checking (also with hotkey)
+- deleting mail from server
+- connecting through Miranda proxy
+- secure password authentification
+- SSL support through OpenSSL
+
+WIN9X SUPPORT
+-------------
+Win9x users, use unicows.dll library, download it at:
+http://libunicows.sf.net (whole package)
+or just visit http://www.majvan.host.sk/Projekty/YAMN
+and download zip-ed unicows.dll
+All you need is to copy unicows.dll to Windows system32
+directory (or to Miranda home directory). Use Win9x
+version of YAMN, not WinNT version.
+
+SSL SUPPORT
+-----------
+If you want to use SSL features, you have to download
+OpenSSL libraries on YAMN homepage
+http://www.majvan.host.sk/Projekty/YAMN
+or the latest (stable) version with installer on
+http://www.slproweb.com/products/Win32OpenSSL.html
+Copy *.dll files to Windows system32 directory (or to
+Miranda home directory).
+
+LATEST STABLE
+-------------
+Version of YAMN has following structure: w.x.y.z
+z- only some bug fixed or some changes
+y- some new feature added
+x- big feature added
+w- if this changes, YAMN becomes better than Outlook ;-)
+Latest stable plugin is always present to download from YAMN
+homepage.
+
+BETA
+----
+* YAMN-beta version is intended only for testing purposes.
+* Author waits for stability reports. Sometimes author waits not
+only for crash reports, but also for success reports (you are
+informed by message box on startup, if success reports are also
+needed). This is because he has no resources for testing.
+* Please do not send reports if newer beta version is available.
+* Please do not send reports without describing problem detailed.
+* Beta version produces debug files (yamn-debug.*.log) located
+in Miranda home directory (like every YAMN debug release). These
+files are usefull for author to locate the bug (although not
+100%). After Miranda restart, log files are rewritten. Log files
+can become very large (more than 10MB). Sometimes they can be
+cut at the end (contact author).
+IMPORTANT FOR BETA: yamn-debug.comm.log file contains your plain
+password. You should rewrite it.
+Thank you for comprehension.
+
+=========================================================
+ Do you want some FAQ? Visit HOMEPAGE:
+ http://www.majvan.host.sk/Projekty/YAMN
+ Still don't know answer? Write question to guestbook.
+
+ majvan
+=========================================================
diff --git a/yamn/docs/language.pop3.txt b/yamn/docs/language.pop3.txt new file mode 100644 index 0000000..03fb78e --- /dev/null +++ b/yamn/docs/language.pop3.txt @@ -0,0 +1,118 @@ +;
+; YAMN-POP3 0.2.4.7 translation file
+;
+;--------------------------------
+; NEW in 0.2.4.7
+;--------------------------------
+
+;--------------------------------
+; CHANGED in 0.2.4.7
+;--------------------------------
+
+;--------------------------------
+; OLD in 0.2.4.7
+;--------------------------------
+;
+; Main
+;
+[Found new version of account book, not compatible with this version of YAMN.]
+[Error reading account file. Account file corrupted.]
+[Memory allocation error while data reading]
+[Reading file error. File already in use?]
+[Error while copying data to disk occured. File in use?]
+[YAMN (internal POP3) read error]
+[POP3 plugin- write file error]
+[Error %d-%d-%d-%d:]
+[Memory allocation error.]
+[Account is about to be stopped.]
+[Cannot connect to POP3 server.]
+[Cannot allocate memory for received data.]
+[Cannot login to POP3 server.]
+[Bad user or password.]
+[Server does not support APOP authorization.]
+[Error while executing POP3 command.]
+[Cannot connect to server with NetLib.]
+[Cannot send data.]
+[Cannot receive data.]
+[Cannot allocate memory for received data.]
+[OpenSSL not loaded.]
+[Windows socket 2.0 init failed.]
+[DNS lookup error.]
+[Error while creating base socket.]
+[Error connecting to server with socket.]
+[Error while creating SSL structure.]
+[Error connecting socket with SSL.]
+[Server rejected connection with SSL.]
+[Cannot write SSL data.]
+[Cannot read SSL data.]
+[Cannot allocate memory for received data.]
+
+;
+; Options
+;
+[Please wait while account is in use.]
+[Please wait while no account is in use.]
+[Time left to next check [s]: %d]
+[Select executable used for notification]
+[Input error]
+[This is not a valid number value]
+[At least one mail notification event must be checked]
+[Please select application to run]
+[Delete]
+[Check this account]
+[Server:]
+[Port:]
+[User:]
+[Password:]
+[APOP auth]
+[Check interval [min]:]
+[Sound notification]
+[Message notification]
+[Tray icon notification]
+[Application execution:]
+[Persistant message]
+[Sound notification if failed]
+[Message notification if failed]
+[Tray icon notification if failed]
+[Default codepage:]
+[Check while:]
+;[Offline]
+;[Online]
+;[Away]
+;[N/A]
+;[Occupied]
+;[DND]
+;[Free for chat]
+;[Invisible]
+;[On the phone]
+;[Out to lunch]
+[Startup check]
+[Default]
+[Reset counter]
+[Account Test]
+[Account Test (failed)]
+[Account Test]
+[You have N new mails]
+[Connection failed message]
+[Popup notification]
+[Popup if no mail]
+[Single popup]
+[Multi popup]
+[Popup notification if failed]
+[Check from menu]
+[New mail notifications]
+[No new mail notifications]
+[Connection failure notifications]
+[Connecting to server]
+[Reading new mails (%d%% done)]
+[Disconnected]
+[Entering POP3 account]
+[Searching for new mail]
+[Deleting requested mails]
+[Deleting spam]
+[Delete account confirmation]
+[Do you really want to delete this account?]
+
+;--------------------------------
+; REMOVED in 0.2.4.7
+;--------------------------------
\ No newline at end of file diff --git a/yamn/docs/language.txt b/yamn/docs/language.txt new file mode 100644 index 0000000..72d1fcd --- /dev/null +++ b/yamn/docs/language.txt @@ -0,0 +1,75 @@ +;
+; YAMN 0.2.4.7 translation file
+;
+;--------------------------------
+; NEW in 0.2.4.7
+;--------------------------------
+
+;--------------------------------
+; CHANGED in 0.2.4.7
+;--------------------------------
+
+;--------------------------------
+; OLD in 0.2.4.7
+;--------------------------------
+;
+; Main
+;
+[YAMN: new mail]
+[YAMN: connect failed]
+[No new mail, %d spam(s)]
+[No new mail]
+[YAMN uninstalling]
+[Do you also want to remove native YAMN plugins settings?]
+
+;
+; Menu
+;
+[Check &mail (YAMN)]
+[Check mail] ;for TopToolBar plugin
+
+;
+; Options
+;
+[Hotkey for mail check:]
+[TopToolBar button "Check mail"]
+[Installed plugins]
+[Version:]
+[Description:]
+[Copyright:]
+[Contact:]
+[WWW:]
+
+;
+; Mail browser
+;
+[%s - %d new mails, %d total]
+[ - new mail(s)]
+[From]
+[Subject]
+[Size]
+[Run application]
+[Delete selected]
+[Delete confirmation]
+[Do you really want to delete %d selected mails?]
+
+;
+; Bad connection dialog
+;
+[ - connection error]
+[Cannot allocate memory for received data]
+[Bad user name or error while logging]
+[Bad user or password or error while logging]
+[Cannot get number of messages]
+[Cannot resolve message signatures]
+[Cannot get sizes of messages]
+[Cannot find server]
+[Cannot connect to server]
+[System error occured]
+[Cannot send data]
+[Cannot receive data]
+[Unknown error]
+
+;--------------------------------
+; REMOVED in 0.2.4.7
+;--------------------------------
\ No newline at end of file diff --git a/yamn/filter/Base/AggressiveOptimize.h b/yamn/filter/Base/AggressiveOptimize.h new file mode 100644 index 0000000..1bf0e19 --- /dev/null +++ b/yamn/filter/Base/AggressiveOptimize.h @@ -0,0 +1,168 @@ +
+//////////////////////////////
+// Version 1.40
+// October 22nd, 2002 - .NET (VC7, _MSC_VER=1300) support!
+// Version 1.30
+// Nov 24th, 2000
+// Version 1.20
+// Jun 9th, 2000
+// Version 1.10
+// Jan 23rd, 2000
+// Version 1.00
+// May 20th, 1999
+// Todd C. Wilson, Fresh Ground Software
+// (todd@nopcode.com)
+// This header file will kick in settings for Visual C++ 5 and 6 that will (usually)
+// result in smaller exe's.
+// The "trick" is to tell the compiler to not pad out the function calls; this is done
+// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads
+// out each and every function call. In one single 500k dll, I managed to cut out 120k
+// by this alone!
+// The other two "tricks" are telling the Linker to merge all data-type segments together
+// in the exe file. The relocation, read-only (constants) data, and code section (.text)
+// sections can almost always be merged. Each section merged can save 4k in exe space,
+// since each section is padded out to 4k chunks. This is very noticeable with smaller
+// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of
+// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! For larger
+// programs, this is less overall, but can save at least 4k.
+// Note that if you're using MFC static or some other 3rd party libs, you may get poor
+// results with merging the readonly (.rdata) section - the exe may grow larger.
+// To use this feature, define _MERGE_DATA_ in your project or before this header is used.
+// With Visual C++ 5, the program uses a file alignment of 512 bytes, which results
+// in a small exe. Under VC6, the program instead uses 4k, which is the same as the
+// section size. The reason (from what I understand) is that 4k is the chunk size of
+// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98)
+// will re-align the programs on this boundary. The problem with this is that all of
+// Microsoft's system exes and dlls are *NOT* tuned like this, and using 4k causes serious
+// exe bloat. This is very noticeable for smaller programs.
+// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the
+// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75%
+// depending on the size. Note that this is the same as using /OPT:NOWIN98, which *is*
+// a previously documented switch, but was left out of the docs for some reason in VC6 and
+// all of the current MSDN's - see KB:Q235956 for more information.
+// Microsoft does say that using the 4k alignment will "speed up process loading",
+// but I've been unable to notice a difference, even on my P180, with a very large (4meg) exe.
+// Please note, however, that this will probably not change the size of the COMPRESSED
+// file (either in a .zip file or in an install archive), since this 4k is all zeroes and
+// gets compressed away.
+// Also, the /ALIGN:4096 switch will "magically" do the same thing, even though this is the
+// default setting for this switch. Apparently this sets the same values as the above two
+// switches do. We do not use this in this header, since it smacks of a bug and not a feature.
+// Thanks to Michael Geary <Mike@Geary.com> for some additional tips!
+//
+// Notes about using this header in .NET
+// First off, VC7 does not allow a lot of the linker command options in pragma's. There is no
+// honest or good reason why Microsoft decided to make this change, it just doesn't.
+// So that is why there are a lot of <1300 #if's in the header.
+// If you want to take full advantage of the VC7 linker options, you will need to do it on a
+// PER PROJECT BASIS; you can no longer use a global header file like this to make it better.
+// Items I strongly suggest putting in all your VC7 project linker options command line settings:
+// /ignore:4078 /RELEASE
+// Compiler options:
+// /GL (Whole Program Optimization)
+// If you're making an .EXE and not a .DLL, consider adding in:
+// /GA (Optimize for Windows Application)
+// Some items to consider using in your VC7 projects (not VC6):
+// Link-time Code Generation - whole code optimization. Put this in your exe/dll project link settings.
+// /LTCG:NOSTATUS
+// The classic no-padding and no-bloat compiler C/C++ switch:
+// /opt:nowin98
+//
+// (C++ command line options: /GL /opt:nowin98 and /GA for .exe files)
+// (Link command line options: /ignore:4078 /RELEASE /LTCG:NOSTATUS)
+//
+// Now, notes on using these options in VC7 vs VC6.
+// VC6 consistently, for me, produces smaller code from C++ the exact same sources,
+// with or without this header. On average, VC6 produces 5% smaller binaries compared
+// to VC7 compiling the exact same project, *without* this header. With this header, VC6
+// will make a 13k file, while VC7 will make a 64k one. VC7 is just bloaty, pure and
+// simple - all that managed/unmanaged C++ runtimes, and the CLR stuff must be getting
+// in the way of code generation. However, template support is better, so there.
+// Both VC6 and VC7 show the same end kind of end result savings - larger binary output
+// will shave about 2% off, where as smaller projects (support DLL's, cpl's,
+// activex controls, ATL libs, etc) get the best result, since the padding is usually
+// more than the actual usable code. But again, VC7 does not compile down as small as VC6.
+//
+// The argument can be made that doing this is a waste of time, since the "zero bytes"
+// will be compressed out in a zip file or install archive. Not really - it doesn't matter
+// if the data is a string of zeroes or ones or 85858585 - it will still take room (20 bytes
+// in a zip file, 29 bytes if only *4* of them 4k bytes are not the same) and time to
+// compress that data and decompress it. Also, 20k of zeros is NOT 20k on disk - it's the
+// size of the cluster slop- for Fat32 systems, 20k can be 32k, NTFS could make it 24k if you're
+// just 1 byte over (round up). Most end users do not have the dual P4 Xeon systems with
+// two gigs of RDram and a Raid 0+1 of Western Digital 120meg Special Editions that all
+// worthy developers have (all six of us), so they will need any space and LOADING TIME
+// savings they will need; taking an extra 32k or more out of your end user's 64megs of
+// ram on Windows 98 is Not a Good Thing.
+//
+// Now, as a ADDED BONUS at NO EXTRA COST TO YOU! Under VC6, using the /merge:.text=.data
+// pragma will cause the output file to be un-disassembleable! (is that a word?) At least,
+// with the normal tools - WinDisam, DumpBin, and the like will not work. Try it - use the
+// header, compile release, and then use DUMPBIN /DISASM filename.exe - no code!
+// Thanks to Gëzim Pani <gpani@siu.edu> for discovering this gem - for a full writeup on
+// this issue and the ramifactions of it, visit www.nopcode.com for the Aggressive Optimize
+// article.
+
+#ifndef _AGGRESSIVEOPTIMIZE_H_
+#define _AGGRESSIVEOPTIMIZE_H_
+
+#pragma warning(disable:4711)
+
+#ifdef NDEBUG
+// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers)
+#pragma optimize("gsy",on)
+
+#if (_MSC_VER<1300)
+ #pragma comment(linker,"/RELEASE")
+#endif
+
+/*
+// Note that merging the .rdata section will result in LARGER exe's if you using
+// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project.
+#ifdef _MERGE_RDATA_
+#pragma comment(linker,"/merge:.rdata=.data")
+#endif // _MERGE_RDATA_
+
+#pragma comment(linker,"/merge:.text=.data")
+#if (_MSC_VER<1300)
+ // In VC7, this causes problems with the relocation and data tables, so best to not merge them
+ #pragma comment(linker,"/merge:.reloc=.data")
+#endif
+*/
+
+// Merging sections with different attributes causes a linker warning, so
+// turn off the warning. From Michael Geary. Undocumented, as usual!
+#if (_MSC_VER<1300)
+ // In VC7, you will need to put this in your project settings
+ #pragma comment(linker,"/ignore:4078")
+#endif
+
+// With Visual C++ 5, you already get the 512-byte alignment, so you will only need
+// it for VC6, and maybe later.
+#if _MSC_VER >= 1000
+
+// Option #1: use /filealign
+// Totally undocumented! And if you set it lower than 512 bytes, the program crashes.
+// Either leave at 0x200 or 0x1000
+//#pragma comment(linker,"/FILEALIGN:0x200")
+
+// Option #2: use /opt:nowin98
+// See KB:Q235956 or the READMEVC.htm in your VC directory for info on this one.
+// This is our currently preferred option, since it is fully documented and unlikely
+// to break in service packs and updates.
+#if (_MSC_VER<1300)
+ // In VC7, you will need to put this in your project settings
+ #pragma comment(linker,"/opt:nowin98")
+#else
+
+// Option #3: use /align:4096
+// A side effect of using the default align value is that it turns on the above switch.
+// Does nothing under Vc7 that /opt:nowin98 doesn't already give you
+// #pragma comment(linker,"/ALIGN:512")
+#endif
+
+#endif // _MSC_VER >= 1000
+
+#endif // NDEBUG
+
+#endif // _AGGRESSIVEOPTIMIZE_H_
diff --git a/yamn/filter/Base/Base.dsp b/yamn/filter/Base/Base.dsp new file mode 100644 index 0000000..7231712 --- /dev/null +++ b/yamn/filter/Base/Base.dsp @@ -0,0 +1,108 @@ +# Microsoft Developer Studio Project File - Name="Base" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=Base - Win32 Release
+!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
+!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
+!MESSAGE
+!MESSAGE NMAKE /f "Base.mak".
+!MESSAGE
+!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "Base.mak" CFG="Base - Win32 Release"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "Base - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Base - Win32 Debug" (basierend auf "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)" == "Base - 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 Ignore_Export_Lib 1
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /Zi /O1 /Ob0 /I "../../../../include" /I "../../../../include/msapi" /I "../../../../include_API" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib /nologo /dll /machine:I386 /out:"../../../../bin/release/plugins/YAMN-filter/Base.dll" /filealign:512
+# ADD LINK32 kernel32.lib user32.lib /nologo /dll /pdb:"../../../../bin/Release/plugins/YAMN/base.pdb" /debug /machine:I386 /out:"../../../../bin/Release/plugins/YAMN/base.dll" /filealign:512
+
+!ELSEIF "$(CFG)" == "Base - 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 0
+# 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 /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../../../include" /I "../../../../include/msapi" /I "../../../../include_API" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x417 /d "_DEBUG"
+# ADD RSC /l 0x417 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib /nologo /dll /debug /machine:I386 /out:"../../../../bin/Debug/plugins/YAMN-filter/Base.dll"
+# ADD LINK32 kernel32.lib user32.lib /nologo /dll /pdb:"../../../../bin/Debug/plugins/YAMN/base.pdb" /debug /machine:I386 /out:"../../../../bin/Debug/plugins/YAMN/base.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "Base - Win32 Release"
+# Name "Base - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\debug.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\maindll.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/yamn/filter/Base/Base.mak b/yamn/filter/Base/Base.mak new file mode 100644 index 0000000..75ec59d --- /dev/null +++ b/yamn/filter/Base/Base.mak @@ -0,0 +1,229 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on Base.dsp
+!IF "$(CFG)" == ""
+CFG=Base - Win32 Release
+!MESSAGE No configuration specified. Defaulting to Base - Win32 Release.
+!ENDIF
+
+!IF "$(CFG)" != "Base - Win32 Release" && "$(CFG)" != "Base - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!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 "Base.mak" CFG="Base - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "Base - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "Base - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "Base - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+
+ALL : "..\..\..\..\bin\release\plugins\YAMN-filter\base.dll"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\debug.obj"
+ -@erase "$(INTDIR)\maindll.obj"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(OUTDIR)\base.exp"
+ -@erase "..\..\..\..\bin\release\plugins\YAMN-filter\base.dll"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\Base.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=
+RSC=rc.exe
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\Base.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib user32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\base.pdb" /machine:I386 /out:"../../../../bin/release/plugins/YAMN-filter/base.dll" /implib:"$(OUTDIR)\base.lib" /filealign:512
+LINK32_OBJS= \
+ "$(INTDIR)\debug.obj" \
+ "$(INTDIR)\maindll.obj"
+
+"..\..\..\..\bin\release\plugins\YAMN-filter\base.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "Base - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+ALL : "..\..\..\..\bin\Debug\plugins\YAMN-filter\Base.dll" "$(OUTDIR)\Base.bsc"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\debug.obj"
+ -@erase "$(INTDIR)\debug.sbr"
+ -@erase "$(INTDIR)\maindll.obj"
+ -@erase "$(INTDIR)\maindll.sbr"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\vc60.pdb"
+ -@erase "$(OUTDIR)\Base.bsc"
+ -@erase "$(OUTDIR)\Base.exp"
+ -@erase "$(OUTDIR)\Base.pdb"
+ -@erase "..\..\..\..\bin\Debug\plugins\YAMN-filter\Base.dll"
+ -@erase "..\..\..\..\bin\Debug\plugins\YAMN-filter\Base.ilk"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\Base.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=
+RSC=rc.exe
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\Base.bsc"
+BSC32_SBRS= \
+ "$(INTDIR)\debug.sbr" \
+ "$(INTDIR)\maindll.sbr"
+
+"$(OUTDIR)\Base.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib user32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\Base.pdb" /debug /machine:I386 /out:"../../../../bin/Debug/plugins/YAMN-filter/Base.dll" /implib:"$(OUTDIR)\Base.lib"
+LINK32_OBJS= \
+ "$(INTDIR)\debug.obj" \
+ "$(INTDIR)\maindll.obj"
+
+"..\..\..\..\bin\Debug\plugins\YAMN-filter\Base.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("Base.dep")
+!INCLUDE "Base.dep"
+!ELSE
+!MESSAGE Warning: cannot find "Base.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "Base - Win32 Release" || "$(CFG)" == "Base - Win32 Debug"
+SOURCE=.\debug.cpp
+
+!IF "$(CFG)" == "Base - Win32 Release"
+
+
+"$(INTDIR)\debug.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "Base - Win32 Debug"
+
+
+"$(INTDIR)\debug.obj" "$(INTDIR)\debug.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+SOURCE=.\maindll.cpp
+
+!IF "$(CFG)" == "Base - Win32 Release"
+
+
+"$(INTDIR)\maindll.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "Base - Win32 Debug"
+
+
+"$(INTDIR)\maindll.obj" "$(INTDIR)\maindll.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+
+!ENDIF
+
diff --git a/yamn/filter/Base/debug.cpp b/yamn/filter/Base/debug.cpp new file mode 100644 index 0000000..654ece7 --- /dev/null +++ b/yamn/filter/Base/debug.cpp @@ -0,0 +1,73 @@ +/*
+ * Copied from YAMN plugin
+ *
+ * (c) majvan 2002-2004
+ */
+#ifdef DEBUG_FILTER
+
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+TCHAR DebugUserDirectory[MAX_PATH]=".";
+LPCRITICAL_SECTION FileAccessCS;
+
+void DebugLog(HANDLE File,const char *fmt,...);
+
+#ifdef DEBUG_FILTER
+TCHAR DebugFilterFileName2[]=_T("%s\\yamn-debug.basefilter.log");
+HANDLE FilterFile=INVALID_HANDLE_VALUE;
+#endif
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+void InitDebug()
+{
+ TCHAR DebugFileName[MAX_PATH];
+
+ if(FileAccessCS==NULL)
+ {
+ FileAccessCS=new CRITICAL_SECTION;
+ InitializeCriticalSection(FileAccessCS);
+ }
+
+ _stprintf(DebugFileName,DebugFilterFileName2,DebugUserDirectory);
+
+ FilterFile=CreateFile(DebugFileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,0,NULL);
+
+ DebugLog(FilterFile,"Base filter plugin for YAMN - debug file\n");
+}
+
+void UnInitDebug()
+{
+ DebugLog(FilterFile,"File is being closed normally.");
+ CloseHandle(FilterFile);
+}
+
+void DebugLog(HANDLE File,const char *fmt,...)
+{
+ char *str;
+ char tids[32];
+ va_list vararg;
+ int strsize;
+ DWORD Written;
+
+ va_start(vararg,fmt);
+ str=(char *)malloc(strsize=65536);
+ _stprintf(tids,_T("[%x]"),GetCurrentThreadId());
+ while(_vsnprintf(str,strsize,fmt,vararg)==-1)
+ str=(char *)realloc(str,strsize+=65536);
+ va_end(vararg);
+ EnterCriticalSection(FileAccessCS);
+ WriteFile(File,tids,(DWORD)strlen(tids),&Written,NULL);
+ WriteFile(File,str,(DWORD)strlen(str),&Written,NULL);
+ LeaveCriticalSection(FileAccessCS);
+ free(str);
+}
+
+#endif //ifdef DEBUG
\ No newline at end of file diff --git a/yamn/filter/Base/docs/base-readme.txt b/yamn/filter/Base/docs/base-readme.txt new file mode 100644 index 0000000..2e79bbb --- /dev/null +++ b/yamn/filter/Base/docs/base-readme.txt @@ -0,0 +1,63 @@ +========================
+= Base Filter for YAMN =
+========================
+
+Q: What???
+A: YAMN filter to classify incoming email.
+
+Q: How?
+A: Finding occurency of defiend MIME header item and its value from blacklist file.
+
+Q: Blacklist file?
+A: Yes. It is created by yourself and located in Miranda directory with name 'basefilterdeny.txt'
+
+Q: Created by myself?
+A: Just create the file and write there your header MIME items and its values.
+
+Q: What do you mean "header MIME items" and "its values"?
+A: Every mail has header consisting of MIME items like "Subject" or "Return-Path".
+
+Q: So I need to understand how the header looks like...
+A: Yes, if you want to use this filter, you should. Header MIME is defined in RFC822 standard.
+
+Q: Ok, I've just studied it. So how to set filter (write some rules to the blacklist file)?
+A: Each line is one rule: write the exact item, press <tab>, press the substring of value needed to be found, press <tab>, define spamlevel and then press <Enter>.
+
+Q: Spamlevel?
+A: Yes.
+ 0=do not notify
+ 1=notify, display with another color in mailbrowser
+ 2=do not notify, display with another color in mailbrowser
+ 3=delete, display in mailbrowser about deleted mail
+ 4=delete, do not display (mail's quick death, hehe)
+
+Q: So the rule has 3 parameters, that's it?
+A: Yes. This is the example:
+<------ start of file ------>
+From CrazyMail 1
+X-Importance low 0
+Subject LinuxMailList 0
+Return-Path cheapsoftware@junkmails.net 2
+X-TextClassification spam 3
+<------ end of file ------->
+
+Q: Wait while. Ok, but it does not work.
+A: Check if you have this plugin listed in Miranda/Options/Plugins/YAMN item
+
+Q: No, it is not listed in YAMN plugins.
+A: Then check if the dll residents in Plugins/YAMN direcotry.
+
+Q: This directory does not exists.
+A: Create it and put the dll there. Restart Miranda.
+
+Q: Hmmm, ok. But it is not still listed.
+A: Your version of YAMN and filter does not match.
+
+Q: And?
+A: Try to look to http://www.majvan.host.sk/Projekty/YAMN for updates.
+
+Q: Now, it is listed, but does not work anyway.
+A: Try to download debug version from YAMN homepage, if you are not using it (the name of filter must contain the word "debug")
+
+Q: What does debug version do?
+A: It creates debug log file in Miranda home directory where you can browse how does filter mark mails.
\ No newline at end of file diff --git a/yamn/filter/Base/maindll.cpp b/yamn/filter/Base/maindll.cpp new file mode 100644 index 0000000..6affd00 --- /dev/null +++ b/yamn/filter/Base/maindll.cpp @@ -0,0 +1,238 @@ +//---------------------------------------------------------------------------
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_langpack.h>
+#include <m_options.h>
+#include "../../m_filterplugin.h"
+#if !defined(_WIN64)
+ #include "aggressiveoptimize.h"
+#endif
+
+typedef INT_PTR(* MIRANDASERVICE)(WPARAM,LPARAM);
+
+DWORD WINAPI FilterMail(HACCOUNT Account,DWORD AccountVer,HYAMNMAIL Mail,DWORD MailVer);//Function marks mail as spam when it is spam...
+DWORD WINAPI UnLoadFilter(LPVOID);
+
+int LoadRules(); //Load rules from file
+int findsubstr(char *original,char *pattern); //finds if original contains substring
+
+YAMN_FILTERIMPORTFCN FilterFunctions= //we set for YAMN which is our filter function
+{
+ FilterMail,
+ UnLoadFilter,
+};
+
+struct cFilterTable
+{
+ char account[256];
+ char name[256];
+ char value[256];
+ unsigned char sl;
+} *ft=NULL;
+int fts=0;
+
+YAMN_FILTERREGISTRATION FilterRegistration= //classical YAMN registration
+{
+#ifdef DEBUG_FILTER
+ "Base filter plugin for YAMN (debug)",
+#else
+ "Base filter plugin for YAMN",
+#endif
+ __DATE__,
+ "© majvan",
+ "Classifies mails using the rules stored in file",
+ "om3tn@psg.sk",
+ "http://www.majvan.host.sk/Projekty/YAMN?fm=soft",
+};
+
+char *FilterPath=NULL;
+
+struct YAMNExportedFcn
+{
+ YAMN_SETFILTERPLUGINFCNIMPORTFCN SetFilterPluginFcnImportFcn;
+ MIRANDASERVICE RegisterFilterPlugin;
+} YAMNFcn,*pYAMNFcn; //exported functions from YAMN we will use
+
+HYAMNFILTERPLUGIN POPFilePlugin; //handle of this plugin for YAMN
+HINSTANCE hInst; //handle of this DLL for Windows
+
+#ifdef DEBUG_FILTER
+extern void InitDebug();
+extern void UnInitDebug();
+extern void DebugLog(HANDLE File,const char *fmt,...);
+extern HANDLE FilterFile;
+#endif
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
+{
+ hInst=hinstDLL;
+ return true;
+}
+
+extern "C" int __declspec(dllexport) LoadFilter(MIRANDASERVICE GetYAMNFcnPtr)
+{
+ FilterPath=new char[MAX_PATH];
+ char *delim;
+ pYAMNFcn=&YAMNFcn;
+
+ GetModuleFileName(GetModuleHandle(NULL),FilterPath,MAX_PATH);
+ if(NULL!=(delim=strrchr(FilterPath,'\\')))
+ *delim=0;
+ lstrcat(FilterPath,"\\basefilterdeny.txt");
+#ifdef DEBUG_FILTER
+ InitDebug();
+#endif
+
+ if(!LoadRules())
+ return 0;
+
+ pYAMNFcn->RegisterFilterPlugin=(MIRANDASERVICE)GetYAMNFcnPtr((WPARAM)MS_YAMN_REGISTERFILTERPLUGIN,(LPARAM)0);
+ pYAMNFcn->SetFilterPluginFcnImportFcn=(YAMN_SETFILTERPLUGINFCNIMPORTFCN)GetYAMNFcnPtr((WPARAM)YAMN_SETFILTERPLUGINFCNIMPORTID,(LPARAM)0);
+//Register our filter plugin to YAMN
+ if(NULL==(POPFilePlugin=(HYAMNFILTERPLUGIN)pYAMNFcn->RegisterFilterPlugin((WPARAM)&FilterRegistration,(LPARAM)YAMN_FILTERREGISTRATIONVERSION)))
+ return 0;
+//And add our imported functions for YAMN
+ if(!pYAMNFcn->SetFilterPluginFcnImportFcn(POPFilePlugin,0xb0000000,&FilterFunctions,YAMN_FILTERIMPORTFCNVERSION))
+ return 0;
+ return 1; //Load luccess
+}
+
+DWORD WINAPI UnLoadFilter(LPVOID)
+{
+#ifdef DEBUG_FILTER
+ UnInitDebug();
+#endif
+ if(FilterPath!=NULL)
+ delete[] FilterPath;
+ FilterPath=NULL;
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) UninstallFilter()
+{
+ if(FilterPath==NULL)
+ MessageBox(NULL,"Cannot delete blacklist file when Base Filter is not loaded. Please do it manually.","Base Filter uninstalling",MB_OK|MB_ICONWARNING);
+ else
+ DeleteFile(FilterPath);
+ return 0;
+}
+
+
+//And this is main filter function.
+DWORD WINAPI FilterMail(HACCOUNT Account,DWORD AccountVer,HYAMNMAIL Mail,DWORD MailVer)
+{
+ struct CMimeItem *Browser;
+
+ if(MailVer!=YAMN_MAILVERSION) //we test if we work with the right YAMNMAIL
+ return 0;
+ if(Mail->MailData==NULL) //MailData should be available
+ return 0;
+
+#ifdef DEBUG_FILTER
+ DebugLog(FilterFile,"<New mail>\n");
+#endif
+ if(!(Mail->Flags & YAMN_MSG_VIRTUAL))
+ for(Browser=Mail->MailData->TranslatedHeader;Browser!=NULL;Browser=Browser->Next) //we browse all header stored in Mail->TranslatedHeader
+ {
+#ifdef DEBUG_FILTER
+ DebugLog(FilterFile,"<Testing header item %s: %s>\n",Browser->name,Browser->value);
+#endif
+ for(int i=0;i<fts;i++)
+ if(!lstrcmpi(Browser->name,ft[i].name))
+ {
+#ifdef DEBUG_FILTER
+ DebugLog(FilterFile,"\t\t<Found appropriate selector %s>\n",Browser->name);
+#endif
+ if(findsubstr(Browser->value,ft[i].value)) //and if we find
+ {
+ if((ft[i].sl==0) && ((Mail->Flags & YAMN_MSG_SPAMMASK)==0))
+ {
+ Mail->Flags&=~(YAMN_MSG_POPUP | YAMN_MSG_SYSTRAY | YAMN_MSG_BROWSER | YAMN_MSG_SOUND | YAMN_MSG_APP | YAMN_MSG_NEVENT);
+#ifdef DEBUG_FILTER
+ DebugLog(FilterFile,"\t\tSetting individual flags not to notify mail, but does not consider as spam.");
+#endif
+ }
+ else if((Mail->Flags & YAMN_MSG_SPAMMASK) < ft[i].sl) //if some filter plugin set higher level of spam, we do nothing
+ {
+ Mail->Flags=(Mail->Flags & ~YAMN_MSG_SPAMMASK)+ft[i].sl; //else we set spam level 2 (clearing spam bits and then settting them to level 2
+#ifdef DEBUG_FILTER
+ DebugLog(FilterFile,"\t\tMail marked to be spam #%d\n",Mail->Flags & YAMN_MSG_SPAMMASK);
+#endif
+ }
+ }
+#ifdef DEBUG_FILTER
+ DebugLog(FilterFile,"\t\t</Found appropriate selector>\n");
+#endif
+ }
+#ifdef DEBUG_FILTER
+ DebugLog(FilterFile,"</Testing header>\n");
+#endif
+ }
+#ifdef DEBUG_FILTER
+ DebugLog(FilterFile,"</New mail>\n\n");
+#endif
+ return 1;
+}
+
+int LoadRules()
+{
+ char *account=NULL;
+ char name[256];
+ char value[256];
+ char BadCompiler[512+5];
+ unsigned char sl;
+ FILE *fp;
+
+#ifdef DEBUG_FILTER
+ DebugLog(FilterFile,"<Loading rules from file %s>\n",FilterPath);
+#endif
+
+ fp=fopen(FilterPath,"rt");
+ if(fp==NULL)
+ return 0;
+
+ while(!feof(fp))
+ {
+ if(fscanf(fp,"%255s",name) && !feof(fp) && (name[0]!=0))
+ {
+ if(fscanf(fp,"%255s",value) && !feof(fp) && (value[0]!=0))
+ {
+ if(fscanf(fp,"%d",&sl))
+ {
+ fts++;
+ ft=(struct cFilterTable *)realloc((void *)ft,sizeof(cFilterTable)*fts);
+ lstrcpy(ft[fts-1].name,name);
+ lstrcpy(ft[fts-1].value,value);
+ ft[fts-1].sl=sl;
+
+ sprintf(BadCompiler,"%s %s %d",name,value,sl);
+#ifdef DEBUG_FILTER
+ DebugLog(FilterFile,"\t<Rule><selector>%s</selector><value>%s</value><spamlevel>%d</spamlevel>\n",name,value,sl);
+#endif
+ }
+ }
+ }
+ }
+
+ fclose(fp);
+#ifdef DEBUG_FILTER
+ DebugLog(FilterFile,"</Loading rules>\n");
+#endif
+ return 1;
+}
+
+int findsubstr(char *original,char *pattern)
+{
+ int ol=lstrlen(original);
+ int pl=lstrlen(pattern);
+
+ for(int i=0;(i+pl)<=ol;i++)
+ if(!_strnicmp(original+i,pattern,pl))
+ return 1;
+ return 0;
+}
\ No newline at end of file diff --git a/yamn/filter/Simple/AggressiveOptimize.h b/yamn/filter/Simple/AggressiveOptimize.h new file mode 100644 index 0000000..1bf0e19 --- /dev/null +++ b/yamn/filter/Simple/AggressiveOptimize.h @@ -0,0 +1,168 @@ +
+//////////////////////////////
+// Version 1.40
+// October 22nd, 2002 - .NET (VC7, _MSC_VER=1300) support!
+// Version 1.30
+// Nov 24th, 2000
+// Version 1.20
+// Jun 9th, 2000
+// Version 1.10
+// Jan 23rd, 2000
+// Version 1.00
+// May 20th, 1999
+// Todd C. Wilson, Fresh Ground Software
+// (todd@nopcode.com)
+// This header file will kick in settings for Visual C++ 5 and 6 that will (usually)
+// result in smaller exe's.
+// The "trick" is to tell the compiler to not pad out the function calls; this is done
+// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads
+// out each and every function call. In one single 500k dll, I managed to cut out 120k
+// by this alone!
+// The other two "tricks" are telling the Linker to merge all data-type segments together
+// in the exe file. The relocation, read-only (constants) data, and code section (.text)
+// sections can almost always be merged. Each section merged can save 4k in exe space,
+// since each section is padded out to 4k chunks. This is very noticeable with smaller
+// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of
+// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! For larger
+// programs, this is less overall, but can save at least 4k.
+// Note that if you're using MFC static or some other 3rd party libs, you may get poor
+// results with merging the readonly (.rdata) section - the exe may grow larger.
+// To use this feature, define _MERGE_DATA_ in your project or before this header is used.
+// With Visual C++ 5, the program uses a file alignment of 512 bytes, which results
+// in a small exe. Under VC6, the program instead uses 4k, which is the same as the
+// section size. The reason (from what I understand) is that 4k is the chunk size of
+// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98)
+// will re-align the programs on this boundary. The problem with this is that all of
+// Microsoft's system exes and dlls are *NOT* tuned like this, and using 4k causes serious
+// exe bloat. This is very noticeable for smaller programs.
+// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the
+// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75%
+// depending on the size. Note that this is the same as using /OPT:NOWIN98, which *is*
+// a previously documented switch, but was left out of the docs for some reason in VC6 and
+// all of the current MSDN's - see KB:Q235956 for more information.
+// Microsoft does say that using the 4k alignment will "speed up process loading",
+// but I've been unable to notice a difference, even on my P180, with a very large (4meg) exe.
+// Please note, however, that this will probably not change the size of the COMPRESSED
+// file (either in a .zip file or in an install archive), since this 4k is all zeroes and
+// gets compressed away.
+// Also, the /ALIGN:4096 switch will "magically" do the same thing, even though this is the
+// default setting for this switch. Apparently this sets the same values as the above two
+// switches do. We do not use this in this header, since it smacks of a bug and not a feature.
+// Thanks to Michael Geary <Mike@Geary.com> for some additional tips!
+//
+// Notes about using this header in .NET
+// First off, VC7 does not allow a lot of the linker command options in pragma's. There is no
+// honest or good reason why Microsoft decided to make this change, it just doesn't.
+// So that is why there are a lot of <1300 #if's in the header.
+// If you want to take full advantage of the VC7 linker options, you will need to do it on a
+// PER PROJECT BASIS; you can no longer use a global header file like this to make it better.
+// Items I strongly suggest putting in all your VC7 project linker options command line settings:
+// /ignore:4078 /RELEASE
+// Compiler options:
+// /GL (Whole Program Optimization)
+// If you're making an .EXE and not a .DLL, consider adding in:
+// /GA (Optimize for Windows Application)
+// Some items to consider using in your VC7 projects (not VC6):
+// Link-time Code Generation - whole code optimization. Put this in your exe/dll project link settings.
+// /LTCG:NOSTATUS
+// The classic no-padding and no-bloat compiler C/C++ switch:
+// /opt:nowin98
+//
+// (C++ command line options: /GL /opt:nowin98 and /GA for .exe files)
+// (Link command line options: /ignore:4078 /RELEASE /LTCG:NOSTATUS)
+//
+// Now, notes on using these options in VC7 vs VC6.
+// VC6 consistently, for me, produces smaller code from C++ the exact same sources,
+// with or without this header. On average, VC6 produces 5% smaller binaries compared
+// to VC7 compiling the exact same project, *without* this header. With this header, VC6
+// will make a 13k file, while VC7 will make a 64k one. VC7 is just bloaty, pure and
+// simple - all that managed/unmanaged C++ runtimes, and the CLR stuff must be getting
+// in the way of code generation. However, template support is better, so there.
+// Both VC6 and VC7 show the same end kind of end result savings - larger binary output
+// will shave about 2% off, where as smaller projects (support DLL's, cpl's,
+// activex controls, ATL libs, etc) get the best result, since the padding is usually
+// more than the actual usable code. But again, VC7 does not compile down as small as VC6.
+//
+// The argument can be made that doing this is a waste of time, since the "zero bytes"
+// will be compressed out in a zip file or install archive. Not really - it doesn't matter
+// if the data is a string of zeroes or ones or 85858585 - it will still take room (20 bytes
+// in a zip file, 29 bytes if only *4* of them 4k bytes are not the same) and time to
+// compress that data and decompress it. Also, 20k of zeros is NOT 20k on disk - it's the
+// size of the cluster slop- for Fat32 systems, 20k can be 32k, NTFS could make it 24k if you're
+// just 1 byte over (round up). Most end users do not have the dual P4 Xeon systems with
+// two gigs of RDram and a Raid 0+1 of Western Digital 120meg Special Editions that all
+// worthy developers have (all six of us), so they will need any space and LOADING TIME
+// savings they will need; taking an extra 32k or more out of your end user's 64megs of
+// ram on Windows 98 is Not a Good Thing.
+//
+// Now, as a ADDED BONUS at NO EXTRA COST TO YOU! Under VC6, using the /merge:.text=.data
+// pragma will cause the output file to be un-disassembleable! (is that a word?) At least,
+// with the normal tools - WinDisam, DumpBin, and the like will not work. Try it - use the
+// header, compile release, and then use DUMPBIN /DISASM filename.exe - no code!
+// Thanks to Gëzim Pani <gpani@siu.edu> for discovering this gem - for a full writeup on
+// this issue and the ramifactions of it, visit www.nopcode.com for the Aggressive Optimize
+// article.
+
+#ifndef _AGGRESSIVEOPTIMIZE_H_
+#define _AGGRESSIVEOPTIMIZE_H_
+
+#pragma warning(disable:4711)
+
+#ifdef NDEBUG
+// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers)
+#pragma optimize("gsy",on)
+
+#if (_MSC_VER<1300)
+ #pragma comment(linker,"/RELEASE")
+#endif
+
+/*
+// Note that merging the .rdata section will result in LARGER exe's if you using
+// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project.
+#ifdef _MERGE_RDATA_
+#pragma comment(linker,"/merge:.rdata=.data")
+#endif // _MERGE_RDATA_
+
+#pragma comment(linker,"/merge:.text=.data")
+#if (_MSC_VER<1300)
+ // In VC7, this causes problems with the relocation and data tables, so best to not merge them
+ #pragma comment(linker,"/merge:.reloc=.data")
+#endif
+*/
+
+// Merging sections with different attributes causes a linker warning, so
+// turn off the warning. From Michael Geary. Undocumented, as usual!
+#if (_MSC_VER<1300)
+ // In VC7, you will need to put this in your project settings
+ #pragma comment(linker,"/ignore:4078")
+#endif
+
+// With Visual C++ 5, you already get the 512-byte alignment, so you will only need
+// it for VC6, and maybe later.
+#if _MSC_VER >= 1000
+
+// Option #1: use /filealign
+// Totally undocumented! And if you set it lower than 512 bytes, the program crashes.
+// Either leave at 0x200 or 0x1000
+//#pragma comment(linker,"/FILEALIGN:0x200")
+
+// Option #2: use /opt:nowin98
+// See KB:Q235956 or the READMEVC.htm in your VC directory for info on this one.
+// This is our currently preferred option, since it is fully documented and unlikely
+// to break in service packs and updates.
+#if (_MSC_VER<1300)
+ // In VC7, you will need to put this in your project settings
+ #pragma comment(linker,"/opt:nowin98")
+#else
+
+// Option #3: use /align:4096
+// A side effect of using the default align value is that it turns on the above switch.
+// Does nothing under Vc7 that /opt:nowin98 doesn't already give you
+// #pragma comment(linker,"/ALIGN:512")
+#endif
+
+#endif // _MSC_VER >= 1000
+
+#endif // NDEBUG
+
+#endif // _AGGRESSIVEOPTIMIZE_H_
diff --git a/yamn/filter/Simple/docs/simple-readme.txt b/yamn/filter/Simple/docs/simple-readme.txt new file mode 100644 index 0000000..34c0842 --- /dev/null +++ b/yamn/filter/Simple/docs/simple-readme.txt @@ -0,0 +1,51 @@ +==========================
+= Simple Filter for YAMN =
+==========================
+
+Q: What???
+A: YAMN filter to classify incoming email.
+
+Q: How?
+A: Regarding what the email is from and finding it in the blacklist email file.
+
+Q: Blacklist email file?
+A: Yes. It is created by yourself and located in Miranda directory with name 'simplefilterdeny.txt'
+
+Q: Created by myself?
+A: Just create the file and write there your blacklist mails in every line.
+
+Q: That's all?
+A: Yes and no. You can specify spamlevel for each mail.
+
+Q: Spamlevel?
+A: Yes.
+ 1=notify, display with another color in mailbrowser
+ 2=do not notify, display with another color in mailbrowser
+ 3=delete, display in mailbrowser about deleted mail
+ 4=delete, do not display (mail's quick death, hehe)
+
+Q: How to specify it?
+A: After email press <tab> and write number 1-4. Note this is optional. If not defined, level 2 is default.
+
+Q: Ok, that's easy.
+A: Yes, this is the example:
+<------ start of file ------>
+nigeria@spamserver.com 2
+cheapsoftware@junkmails.net 3
+learnenglish@commercial.org
+<------ end of file ------->
+
+Q: Wait while. Ok, but it does not work.
+A: Check if you have this plugin listed in Miranda/Options/Plugins/YAMN item as YAMN plugin.
+
+Q: No, it is not listed in YAMN plugins.
+A: Then check if the dll residents in Plugins/YAMN direcotry.
+
+Q: This directory does not exists.
+A: Create it and put the dll there. Restart Miranda.
+
+Q: Hmmm, ok. But it is not still listed.
+A: Your version of YAMN and filter does not match.
+
+Q: And?
+A: Try to look to http://www.majvan.host.sk/Projekty/YAMN for updates.
\ No newline at end of file diff --git a/yamn/filter/Simple/maindll.cpp b/yamn/filter/Simple/maindll.cpp new file mode 100644 index 0000000..7748835 --- /dev/null +++ b/yamn/filter/Simple/maindll.cpp @@ -0,0 +1,132 @@ +//---------------------------------------------------------------------------
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_langpack.h>
+#include <m_options.h>
+#include "../../m_filterplugin.h"
+#if !defined(_WIN64)
+ #include "aggressiveoptimize.h"
+#endif
+
+typedef INT_PTR(* MIRANDASERVICE)(WPARAM,LPARAM);
+
+DWORD WINAPI FilterMail(HACCOUNT Account,DWORD AccountVer,HYAMNMAIL Mail,DWORD MailVer);//Function marks mail as spam when it is spam...
+DWORD WINAPI UnLoadFilter(LPVOID);
+
+YAMN_FILTERIMPORTFCN FilterFunctions= //we set for YAMN which is our filter function
+{
+ FilterMail,
+ UnLoadFilter, //No unloading
+};
+
+YAMN_FILTERREGISTRATION FilterRegistration= //classical YAMN registration
+{
+ "Simple filter plugin for YAMN",
+ __DATE__,
+ "© porter+ majvan",
+ "Classifies mails using the blacklist emails stored in file",
+ "porterbox@hotmail.com",
+ "http://www.majvan.host.sk/Projekty/YAMN?fm=soft",
+};
+
+char *FilterPath=NULL;
+
+struct YAMNExportedFcn
+{
+ YAMN_SETFILTERPLUGINFCNIMPORTFCN SetFilterPluginFcnImportFcn;
+ MIRANDASERVICE RegisterFilterPlugin;
+} YAMNFcn,*pYAMNFcn; //exported functions from YAMN we will use
+
+HYAMNFILTERPLUGIN POPFilePlugin; //handle of this plugin for YAMN
+HINSTANCE hInst; //handle of this DLL for Windows
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
+{
+ hInst=hinstDLL;
+ return true;
+}
+
+extern "C" int __declspec(dllexport) LoadFilter(MIRANDASERVICE GetYAMNFcnPtr)
+{
+ FilterPath=new char[MAX_PATH];
+ char *delim;
+ pYAMNFcn=&YAMNFcn;
+
+ GetModuleFileName(GetModuleHandle(NULL),FilterPath,MAX_PATH);
+ if(NULL!=(delim=strrchr(FilterPath,'\\')))
+ *delim=0;
+ lstrcat(FilterPath,"\\simplefilterdeny.txt");
+
+ pYAMNFcn->RegisterFilterPlugin=(MIRANDASERVICE)GetYAMNFcnPtr((WPARAM)MS_YAMN_REGISTERFILTERPLUGIN,(LPARAM)0);
+ pYAMNFcn->SetFilterPluginFcnImportFcn=(YAMN_SETFILTERPLUGINFCNIMPORTFCN)GetYAMNFcnPtr((WPARAM)YAMN_SETFILTERPLUGINFCNIMPORTID,(LPARAM)0);
+//Register our filter plugin to YAMN
+ if(NULL==(POPFilePlugin=(HYAMNFILTERPLUGIN)pYAMNFcn->RegisterFilterPlugin((WPARAM)&FilterRegistration,(LPARAM)YAMN_FILTERREGISTRATIONVERSION)))
+ return 0;
+//And add our imported functions for YAMN
+ if(!pYAMNFcn->SetFilterPluginFcnImportFcn(POPFilePlugin,0xb0000000,&FilterFunctions,YAMN_FILTERIMPORTFCNVERSION))
+ return 0;
+ return 1; //Load luccess
+}
+
+DWORD WINAPI UnLoadFilter(LPVOID)
+{
+ if(FilterPath!=NULL)
+ delete[] FilterPath;
+ FilterPath=NULL;
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) UninstallFilter()
+{
+ if(FilterPath==NULL)
+ MessageBox(NULL,"Cannot delete blacklist file when Simple Filter is not loaded. Please do it manually.","Simple Filter uninstalling",MB_OK|MB_ICONWARNING);
+ else
+ DeleteFile(FilterPath);
+ return 0;
+}
+
+
+//And this is main filter function.
+DWORD WINAPI FilterMail(HACCOUNT Account,DWORD AccountVer,HYAMNMAIL Mail,DWORD MailVer)
+{
+ FILE *fp;
+ char EmailSpam[256];
+ unsigned char spamLevel;
+ struct CMimeItem *Browser;
+
+ if(MailVer!=YAMN_MAILVERSION) //we test if we work with the right YAMNMAIL
+ return 0;
+ if(Mail->MailData==NULL) //MailData should be available
+ return 0;
+ fp=fopen(FilterPath,"rt");
+ if(fp != NULL) {
+ if(!(Mail->Flags & YAMN_MSG_VIRTUAL))
+ for(Browser=Mail->MailData->TranslatedHeader;Browser!=NULL;Browser=Browser->Next) { //we browse all header stored in Mail->TranslatedHeader
+ if((!lstrcmp(Browser->name,"Return-Path")) || (!lstrcmp(Browser->name,"From"))) { //and if we find
+ fseek(fp, 0L, SEEK_SET);
+ while(!feof(fp)) {
+ if(fscanf(fp, "%255s", EmailSpam) != 0) {
+ if(!feof(fp))
+ if(fscanf(fp, "%d", &spamLevel)==0)
+ spamLevel=2;
+ if(spamLevel>4)
+ spamLevel=2;
+ if(strstr(Browser->value,EmailSpam)!=NULL) {
+ if((Mail->Flags & (YAMN_MSG_SPAMMASK==0)) && (spamLevel==0))
+ Mail->Flags&=~(YAMN_MSG_SOUND | YAMN_MSG_APP | YAMN_MSG_POPUP | YAMN_MSG_SYSTRAY | YAMN_MSG_BROWSER);
+ else if((Mail->Flags & YAMN_MSG_SPAMMASK) < spamLevel) //if some filter plugin set higher level of spam, we do nothing
+ Mail->Flags=(Mail->Flags & ~YAMN_MSG_SPAMMASK)+spamLevel; //else we set spam level 2 (clearing spam bits and then settting them to level 2
+ }
+ }
+ }
+ }
+ }
+ fclose(fp);
+ }
+ return 1;
+}
diff --git a/yamn/filter/Simple/simple.dsp b/yamn/filter/Simple/simple.dsp new file mode 100644 index 0000000..dc6d52e --- /dev/null +++ b/yamn/filter/Simple/simple.dsp @@ -0,0 +1,105 @@ +# Microsoft Developer Studio Project File - Name="simple" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=simple - Win32 Release
+!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
+!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
+!MESSAGE
+!MESSAGE NMAKE /f "simple.mak".
+!MESSAGE
+!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "simple.mak" CFG="simple - Win32 Release"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "simple - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "simple - Win32 Debug" (basierend auf "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)" == "simple - 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 Ignore_Export_Lib 1
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 1
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD CPP /nologo /G4 /Zp4 /MD /W3 /GX /Zi /O1 /Ob0 /I "../../../../include" /I "../../../../include/msapi" /I "../../../../include_API" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib /nologo /dll /machine:I386 /out:"../../../../bin/release/plugins/YAMN-filter/simple.dll" /filealign:512
+# ADD LINK32 kernel32.lib user32.lib /nologo /dll /pdb:"../../../../bin/Release/plugins/YAMN/simple.pdb" /debug /machine:I386 /out:"../../../../bin/Release/plugins/YAMN/simple.dll" /filealign:512
+
+!ELSEIF "$(CFG)" == "simple - 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 Ignore_Export_Lib 1
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# 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 /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../../../include" /I "../../../../include/msapi" /I "../../../../include_API" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x417 /d "_DEBUG"
+# ADD RSC /l 0x417 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib /nologo /dll /debug /machine:I386 /out:"../../../../bin/Debug/plugins/YAMN-filter/simple.dll"
+# ADD LINK32 kernel32.lib user32.lib /nologo /dll /pdb:"../../../../bin/Debug/plugins/YAMN/simple.pdb" /debug /machine:I386 /out:"../../../../bin/Debug/plugins/YAMN/simple.dll" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "simple - Win32 Release"
+# Name "simple - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\maindll.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/yamn/filter/Simple/simple.mak b/yamn/filter/Simple/simple.mak new file mode 100644 index 0000000..085dc22 --- /dev/null +++ b/yamn/filter/Simple/simple.mak @@ -0,0 +1,207 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on simple.dsp
+!IF "$(CFG)" == ""
+CFG=simple - Win32 Release
+!MESSAGE No configuration specified. Defaulting to simple - Win32 Release.
+!ENDIF
+
+!IF "$(CFG)" != "simple - Win32 Release" && "$(CFG)" != "simple - Win32 Debug"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!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 "simple.mak" CFG="simple - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "simple - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "simple - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+!IF "$(CFG)" == "simple - Win32 Release"
+
+OUTDIR=.\Release
+INTDIR=.\Release
+
+ALL : "..\..\..\..\bin\release\plugins\YAMN-filter\simple.dll"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\maindll.obj"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(OUTDIR)\simple.exp"
+ -@erase "..\..\..\..\bin\release\plugins\YAMN-filter\simple.dll"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G4 /Zp4 /MD /W3 /GX /O1 /Ob0 /I "../../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\simple.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=
+RSC=rc.exe
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\simple.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib user32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\simple.pdb" /machine:I386 /out:"../../../../bin/release/plugins/YAMN-filter/simple.dll" /implib:"$(OUTDIR)\simple.lib" /filealign:512
+LINK32_OBJS= \
+ "$(INTDIR)\maindll.obj"
+
+"..\..\..\..\bin\release\plugins\YAMN-filter\simple.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ELSEIF "$(CFG)" == "simple - Win32 Debug"
+
+OUTDIR=.\Debug
+INTDIR=.\Debug
+# Begin Custom Macros
+OutDir=.\Debug
+# End Custom Macros
+
+ALL : "..\..\..\..\bin\Debug\plugins\YAMN-filter\simple.dll" "$(OUTDIR)\simple.bsc"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\maindll.obj"
+ -@erase "$(INTDIR)\maindll.sbr"
+ -@erase "$(INTDIR)\vc60.idb"
+ -@erase "$(INTDIR)\vc60.pdb"
+ -@erase "$(OUTDIR)\simple.bsc"
+ -@erase "$(OUTDIR)\simple.exp"
+ -@erase "$(OUTDIR)\simple.pdb"
+ -@erase "..\..\..\..\bin\Debug\plugins\YAMN-filter\simple.dll"
+ -@erase "..\..\..\..\bin\Debug\plugins\YAMN-filter\simple.ilk"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /G4 /Zp4 /MDd /W3 /Gm /Gi /GX /ZI /Od /I "../../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\simple.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=
+RSC=rc.exe
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\simple.bsc"
+BSC32_SBRS= \
+ "$(INTDIR)\maindll.sbr"
+
+"$(OUTDIR)\simple.bsc" : "$(OUTDIR)" $(BSC32_SBRS)
+ $(BSC32) @<<
+ $(BSC32_FLAGS) $(BSC32_SBRS)
+<<
+
+LINK32=link.exe
+LINK32_FLAGS=kernel32.lib user32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\simple.pdb" /debug /machine:I386 /out:"../../../../bin/Debug/plugins/YAMN-filter/simple.dll" /implib:"$(OUTDIR)\simple.lib"
+LINK32_OBJS= \
+ "$(INTDIR)\maindll.obj"
+
+"..\..\..\..\bin\Debug\plugins\YAMN-filter\simple.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+!ENDIF
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("simple.dep")
+!INCLUDE "simple.dep"
+!ELSE
+!MESSAGE Warning: cannot find "simple.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "simple - Win32 Release" || "$(CFG)" == "simple - Win32 Debug"
+SOURCE=.\maindll.cpp
+
+!IF "$(CFG)" == "simple - Win32 Release"
+
+
+"$(INTDIR)\maindll.obj" : $(SOURCE) "$(INTDIR)"
+
+
+!ELSEIF "$(CFG)" == "simple - Win32 Debug"
+
+
+"$(INTDIR)\maindll.obj" "$(INTDIR)\maindll.sbr" : $(SOURCE) "$(INTDIR)"
+
+
+!ENDIF
+
+
+!ENDIF
+
diff --git a/yamn/filter/readme.txt b/yamn/filter/readme.txt new file mode 100644 index 0000000..a46db02 --- /dev/null +++ b/yamn/filter/readme.txt @@ -0,0 +1 @@ +This folder contains filter plugin sources for YAMN.
\ No newline at end of file diff --git a/yamn/filterplugin.cpp b/yamn/filterplugin.cpp new file mode 100644 index 0000000..cf7252d --- /dev/null +++ b/yamn/filterplugin.cpp @@ -0,0 +1,226 @@ +/*
+ * YAMN plugin export functions for filtering
+ *
+ * (c) majvan 2002-2004
+ */
+
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <newpluginapi.h>
+#include <m_database.h>
+#include "m_yamn.h"
+#include "m_filterplugin.h"
+#include "mails/m_mails.h"
+#include "debug.h"
+
+//- imported ---------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+//From main.cpp
+extern LPCRITICAL_SECTION PluginRegCS;
+extern YAMN_VARIABLES YAMNVar;
+//From synchro.cpp
+extern DWORD WINAPI WaitToWriteFcn(PSWMRG SObject,PSCOUNTER=NULL);
+extern void WINAPI WriteDoneFcn(PSWMRG SObject,PSCOUNTER=NULL);
+//From maild.cpp
+extern INT_PTR LoadMailDataSvc(WPARAM wParam,LPARAM lParam);
+extern INT_PTR UnloadMailDataSvc(WPARAM wParam,LPARAM);
+extern INT_PTR SaveMailDataSvc(WPARAM wParam,LPARAM lParam);
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+PYAMN_FILTERPLUGINQUEUE FirstFilterPlugin=NULL;
+
+INT_PTR RegisterFilterPluginSvc(WPARAM,LPARAM);
+
+//Removes plugin from queue and deletes its structures
+INT_PTR UnregisterFilterPlugin(HYAMNFILTERPLUGIN Plugin);
+
+INT_PTR UnregisterFilterPluginSvc(WPARAM wParam,LPARAM lParam);
+
+//Removes all filter plugins
+INT_PTR UnregisterFilterPlugins();
+
+INT_PTR FilterMailSvc(WPARAM,LPARAM);
+
+//Sets imported functions for an plugin and therefore it starts plugin to be registered and running
+// Plugin- plugin, which wants to set its functions
+// Importance- importance of plugin (see m_filterplugin.h)
+// YAMNFilterFcn- pointer to imported functions
+// YAMNfilterFcnVer- version of YAMN_FILTERIMPORTFCN, use YAMN_FILTERIMPORTFCNVERSION
+// returns nonzero if success
+int WINAPI SetFilterPluginFcnImportFcn(HYAMNFILTERPLUGIN Plugin,DWORD Importance,PYAMN_FILTERIMPORTFCN YAMNFilterFcn,DWORD YAMNFilterFcnVer);
+
+struct CExportedFunctions FilterPluginExportedFcn[]=
+{
+ {YAMN_SETFILTERPLUGINFCNIMPORTID,(void *)SetFilterPluginFcnImportFcn},
+};
+
+struct CExportedServices FilterPluginExportedSvc[]=
+{
+ {MS_YAMN_REGISTERFILTERPLUGIN,RegisterFilterPluginSvc},
+ {MS_YAMN_UNREGISTERFILTERPLUGIN,UnregisterFilterPluginSvc},
+};
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+INT_PTR RegisterFilterPluginSvc(WPARAM wParam,LPARAM lParam)
+{
+ PYAMN_FILTERREGISTRATION Registration=(PYAMN_FILTERREGISTRATION)wParam;
+ HYAMNFILTERPLUGIN Plugin;
+
+ if(lParam!=YAMN_FILTERREGISTRATIONVERSION)
+ return 0;
+ if((Registration->Name==NULL) || (Registration->Ver==NULL))
+ return NULL;
+ if(NULL==(Plugin=new YAMN_FILTERPLUGIN))
+ return NULL;
+
+ Plugin->PluginInfo=Registration;
+
+ Plugin->FilterFcn=NULL;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"::: YAMN- new filter registered: %0x (%s) :::\n",Plugin,Registration->Name);
+#endif
+ return (INT_PTR)Plugin;
+}
+
+INT_PTR UnregisterFilterPlugin(HYAMNFILTERPLUGIN Plugin)
+{
+ PYAMN_FILTERPLUGINQUEUE Parser,Found;
+
+ if(FirstFilterPlugin->Plugin==Plugin)
+ {
+ Found=FirstFilterPlugin;
+ FirstFilterPlugin=FirstFilterPlugin->Next;
+ }
+ else
+ {
+ for(Parser=FirstFilterPlugin;(Parser->Next!=NULL) && (Plugin!=Parser->Next->Plugin);Parser=Parser->Next);
+ if(Parser->Next!=NULL)
+ {
+ Found=Parser->Next;
+ Parser->Next=Parser->Next->Next;
+ }
+ else
+ Found=NULL;
+ }
+ if(Found!=NULL)
+ {
+ if(Plugin->FilterFcn->UnLoadFcn!=NULL)
+ Plugin->FilterFcn->UnLoadFcn((void *)0);
+
+ delete Found->Plugin;
+ delete Found;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"::: YAMN- filter %0x unregistered :::\n",Plugin);
+#endif
+ }
+ else
+ return 0;
+ return 1;
+}
+
+INT_PTR UnregisterFilterPluginSvc(WPARAM wParam,LPARAM lParam)
+{
+ HYAMNFILTERPLUGIN Plugin=(HYAMNFILTERPLUGIN)wParam;
+
+ EnterCriticalSection(PluginRegCS);
+ UnregisterFilterPlugin(Plugin);
+ LeaveCriticalSection(PluginRegCS);
+ return 1;
+}
+
+INT_PTR UnregisterFilterPlugins()
+{
+ EnterCriticalSection(PluginRegCS);
+//We remove protocols from the protocol list
+ while(FirstFilterPlugin!=NULL)
+ UnregisterFilterPlugin(FirstFilterPlugin->Plugin);
+ LeaveCriticalSection(PluginRegCS);
+ return 1;
+}
+
+int WINAPI SetFilterPluginFcnImportFcn(HYAMNFILTERPLUGIN Plugin,DWORD Importance,PYAMN_FILTERIMPORTFCN YAMNFilterFcn,DWORD YAMNFilterFcnVer)
+{
+ PYAMN_FILTERPLUGINQUEUE Parser,Previous;
+
+ if(YAMNFilterFcnVer!=YAMN_FILTERIMPORTFCNVERSION)
+ return 0;
+ if(YAMNFilterFcn==NULL)
+ return 0;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"::: YAMN- filter %0x import succeed :::\n",Plugin);
+#endif
+ Plugin->Importance=Importance;
+ Plugin->FilterFcn=YAMNFilterFcn;
+
+ EnterCriticalSection(PluginRegCS);
+//We add protocol to the protocol list
+ for(Previous=NULL,Parser=FirstFilterPlugin;Parser!=NULL && Parser->Next!=NULL && Parser->Plugin->Importance<=Importance;Previous=Parser,Parser=Parser->Next);
+ if(Previous==NULL) //insert to the beginnig of queue
+ {
+ FirstFilterPlugin=new YAMN_FILTERPLUGINQUEUE;
+ FirstFilterPlugin->Plugin=Plugin;
+ FirstFilterPlugin->Next=Parser;
+ }
+ else
+ {
+ Previous->Next=new YAMN_FILTERPLUGINQUEUE;
+ Previous=Previous->Next; //leave previous, go to actual plugin
+ Previous->Plugin=Plugin;
+ Previous->Next=Parser; //and in actual plugin set, that next plugin is the one we insert in front of
+ }
+
+ LeaveCriticalSection(PluginRegCS);
+ return 1;
+}
+
+INT_PTR FilterMailSvc(WPARAM wParam,LPARAM lParam)
+{
+ HACCOUNT Account=(HACCOUNT)wParam;
+ HYAMNMAIL Mail=(HYAMNMAIL)lParam;
+ PYAMN_FILTERPLUGINQUEUE ActualPlugin;
+
+ EnterCriticalSection(PluginRegCS);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"FilterMail:ActualAccountMsgsSO-write wait\n");
+#endif
+ WaitToWriteFcn(Account->MessagesAccessSO);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"FilterMail:ActualAccountMsgsSO-write enter\n");
+#endif
+ for(ActualPlugin=FirstFilterPlugin;ActualPlugin!=NULL;ActualPlugin=ActualPlugin->Next)
+ {
+ if(ActualPlugin->Plugin->FilterFcn->FilterMailFcnPtr!=NULL)
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tFiltering Mail, running plugin %0x to filter mail\n",ActualPlugin->Plugin);
+#endif
+ ActualPlugin->Plugin->FilterFcn->FilterMailFcnPtr(Account,YAMN_ACCOUNTVERSION,Mail,YAMN_MAILVERSION);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tFiltering Mail done\n");
+#endif
+ }
+ }
+ Mail->Flags|=YAMN_MSG_FILTERED;
+
+//Set mail flags according to spamlevel settings
+ if((Mail->Flags & YAMN_MSG_SPAMMASK) > YAMN_MSG_SPAML1)
+ Mail->Flags=Mail->Flags & ~(YAMN_MSG_BROWSER | YAMN_MSG_POPUP | YAMN_MSG_SYSTRAY | YAMN_MSG_SOUND | YAMN_MSG_APP | YAMN_MSG_NEVENT);
+ if(YAMN_MSG_SPAML(Mail->Flags,YAMN_MSG_SPAML3) || YAMN_MSG_SPAML(Mail->Flags,YAMN_MSG_SPAML4))
+ Mail->Flags=Mail->Flags | (YAMN_MSG_AUTODELETE | YAMN_MSG_DELETEOK); //set message to delete
+ if(YAMN_MSG_SPAML(Mail->Flags,YAMN_MSG_SPAML3))
+ Mail->Flags=Mail->Flags & ~(YAMN_MSG_MEMDELETE); //set message not to delete it immidiatelly from memory
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"FilterMail:ActualAccountMsgsSO-write done\n");
+#endif
+ WriteDoneFcn(Account->MessagesAccessSO);
+ LeaveCriticalSection(PluginRegCS);
+ return 1;
+}
diff --git a/yamn/icons/iconttbup.ico b/yamn/icons/iconttbup.ico Binary files differnew file mode 100644 index 0000000..ad18c56 --- /dev/null +++ b/yamn/icons/iconttbup.ico diff --git a/yamn/icons/icoyamn1.ico b/yamn/icons/icoyamn1.ico Binary files differnew file mode 100644 index 0000000..d3959b4 --- /dev/null +++ b/yamn/icons/icoyamn1.ico diff --git a/yamn/icons/icoyamn2.ico b/yamn/icons/icoyamn2.ico Binary files differnew file mode 100644 index 0000000..dfada56 --- /dev/null +++ b/yamn/icons/icoyamn2.ico diff --git a/yamn/icons/proto_YAMN.dsp b/yamn/icons/proto_YAMN.dsp new file mode 100644 index 0000000..93652ba --- /dev/null +++ b/yamn/icons/proto_YAMN.dsp @@ -0,0 +1,91 @@ +# Microsoft Developer Studio Project File - Name="proto_YAMN" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** NICHT BEARBEITEN **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=proto_YAMN - Win32 Release
+!MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
+!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
+!MESSAGE
+!MESSAGE NMAKE /f "proto_YAMN.mak".
+!MESSAGE
+!MESSAGE Sie können beim Ausführen von NMAKE eine Konfiguration angeben
+!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
+!MESSAGE
+!MESSAGE NMAKE /f "proto_YAMN.mak" CFG="proto_YAMN - Win32 Release"
+!MESSAGE
+!MESSAGE Für die Konfiguration stehen zur Auswahl:
+!MESSAGE
+!MESSAGE "proto_YAMN - Win32 Release" (basierend auf "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
+# 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 0
+# 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
+# ADD CPP /nologo
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib /out:"../../../bin/release/icons/proto_YAMN.dll" /filealign:512 /noentry
+# ADD LINK32 /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib /out:"../../../bin/Release/Icons/proto_YAMN.dll" /filealign:512 /noentry
+# Begin Target
+
+# Name "proto_YAMN - Win32 Release"
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=..\resources\iconeutral.ico
+# End Source File
+# Begin Source File
+
+SOURCE=..\resources\iconttbdown.ico
+# End Source File
+# Begin Source File
+
+SOURCE=iconttbup.ico
+# End Source File
+# Begin Source File
+
+SOURCE=..\resources\icooffline.ico
+# End Source File
+# Begin Source File
+
+SOURCE=icoyamn1.ico
+# End Source File
+# Begin Source File
+
+SOURCE=icoyamn2.ico
+# End Source File
+# Begin Source File
+
+SOURCE=..\resources\icoyamn3.ico
+# End Source File
+# Begin Source File
+
+SOURCE=proto_YAMN.rc
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/yamn/icons/proto_YAMN.mak b/yamn/icons/proto_YAMN.mak new file mode 100644 index 0000000..94c25d7 --- /dev/null +++ b/yamn/icons/proto_YAMN.mak @@ -0,0 +1,112 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on proto_YAMN.dsp
+!IF "$(CFG)" == ""
+CFG=proto_YAMN - Win32 Release
+!MESSAGE No configuration specified. Defaulting to proto_YAMN - Win32 Release.
+!ENDIF
+
+!IF "$(CFG)" != "proto_YAMN - Win32 Release"
+!MESSAGE Invalid configuration "$(CFG)" specified.
+!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 "proto_YAMN.mak" CFG="proto_YAMN - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "proto_YAMN - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+!ERROR An invalid configuration is specified.
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE
+NULL=nul
+!ENDIF
+
+OUTDIR=.\Release
+INTDIR=.\Release
+
+ALL : "..\..\..\bin\release\icons\proto_YAMN.dll"
+
+
+CLEAN :
+ -@erase "$(INTDIR)\proto_YAMN.res"
+ -@erase "$(OUTDIR)\proto_YAMN.exp"
+ -@erase "$(OUTDIR)\proto_YAMN.lib"
+ -@erase "..\..\..\bin\release\icons\proto_YAMN.dll"
+
+"$(OUTDIR)" :
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+CPP=cl.exe
+CPP_PROJ=/nologo /ML /Fo"$(INTDIR)\\"
+
+.c{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.obj::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.c{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cpp{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+.cxx{$(INTDIR)}.sbr::
+ $(CPP) @<<
+ $(CPP_PROJ) $<
+<<
+
+MTL=midl.exe
+MTL_PROJ=
+RSC=rc.exe
+RSC_PROJ=/l 0x417 /fo"$(INTDIR)\proto_YAMN.res" /d "NDEBUG"
+BSC32=bscmake.exe
+BSC32_FLAGS=/nologo /o"$(OUTDIR)\proto_YAMN.bsc"
+BSC32_SBRS= \
+
+LINK32=link.exe
+LINK32_FLAGS=/nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib /out:"../../../bin/release/icons/proto_YAMN.dll" /implib:"$(OUTDIR)\proto_YAMN.lib" /filealign:512 /noentry
+LINK32_OBJS= \
+ "$(INTDIR)\proto_YAMN.res"
+
+"..\..\..\bin\release\icons\proto_YAMN.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+<<
+
+
+!IF "$(NO_EXTERNAL_DEPS)" != "1"
+!IF EXISTS("proto_YAMN.dep")
+!INCLUDE "proto_YAMN.dep"
+!ELSE
+!MESSAGE Warning: cannot find "proto_YAMN.dep"
+!ENDIF
+!ENDIF
+
+
+!IF "$(CFG)" == "proto_YAMN - Win32 Release"
+SOURCE=proto_YAMN.rc
+
+"$(INTDIR)\proto_YAMN.res" : $(SOURCE) "$(INTDIR)"
+ $(RSC) $(RSC_PROJ) $(SOURCE)
+
+
+
+!ENDIF
+
diff --git a/yamn/icons/proto_YAMN.rc b/yamn/icons/proto_YAMN.rc new file mode 100644 index 0000000..e20bd50 --- /dev/null +++ b/yamn/icons/proto_YAMN.rc @@ -0,0 +1,19 @@ +#include "resource.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+
+IDI_ONLINE ICON DISCARDABLE "../resources/iconeutral.ico"
+IDI_ICOYAMN1 ICON DISCARDABLE "icoyamn1.ico"
+IDI_ICOYAMN2 ICON DISCARDABLE "icoyamn2.ico"
+IDI_ICOTTBUP ICON DISCARDABLE "iconttbup.ico"
+
+IDI_OFFLINE ICON DISCARDABLE "../resources/icooffline.ico"
+IDI_NA ICON DISCARDABLE "../resources/icoyamn3.ico"
+IDI_OCCUPIED ICON DISCARDABLE "../resources/iconttbdown.ico"
diff --git a/yamn/icons/resource.h b/yamn/icons/resource.h new file mode 100644 index 0000000..af36adf --- /dev/null +++ b/yamn/icons/resource.h @@ -0,0 +1,2 @@ +#include "../resources/resource.h"
+
diff --git a/yamn/include/IcoLib.h b/yamn/include/IcoLib.h new file mode 100644 index 0000000..a911ba5 --- /dev/null +++ b/yamn/include/IcoLib.h @@ -0,0 +1,26 @@ +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
+ char *pszDefaultFile; //default icon file to use
+ int iDefaultIndex;
+} SKINICONDESC;
+
+//
+// Add a icon into options UI
+// NB! pszName should be unique, e.g.: clistmw_apply, tabsrmm_history
+//
+// 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/yamn/include/m_icolib.h b/yamn/include/m_icolib.h new file mode 100644 index 0000000..a31abe2 --- /dev/null +++ b/yamn/include/m_icolib.h @@ -0,0 +1,75 @@ +// ---------------------------------------------------------------------------80
+// Icons Library Manager plugin for Miranda Instant Messenger
+// __________________________________________________________
+//
+// Copyright © 2005 Denis Stanishevskiy // StDenis
+// Copyright © 2006 Joe Kucera
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// -----------------------------------------------------------------------------
+
+#define SKINICONDESC_SIZE sizeof(SKINICONDESC)
+#define SKINICONDESC_SIZE_V1 0x18
+#define SKINICONDESC_SIZE_V2 0x1C
+#define SKINICONDESC_SIZE_V3 0x24
+
+typedef struct {
+ int cbSize;
+ union {
+ char *pszSection; // section name used to group icons
+ TCHAR *ptszSection;
+ wchar_t *pwszSection;
+ };
+ union {
+ char *pszDescription; // description for options dialog
+ TCHAR *ptszDescription;
+ wchar_t *pwszDescription;
+ };
+ char *pszName; // name to refer to icon when playing and in db
+ char *pszDefaultFile; // default icon file to use
+ int iDefaultIndex; // index of icon in default file
+ HICON hDefaultIcon; // handle to default icon
+ int cx,cy; // dimensions of icon
+ int flags;
+} SKINICONDESC;
+
+#define SIDF_UNICODE 0x100 // Section and Description are in UCS-2
+
+#if defined(_UNICODE)
+ #define SIDF_TCHAR SIDF_UNICODE
+#else
+ #define SIDF_TCHAR 0
+#endif
+
+//
+// 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 is managed by IcoLib
+//
+
+#define MS_SKIN2_GETICON "Skin2/Icons/GetIcon"
+
+//
+// Icons change notification
+//
+#define ME_SKIN2_ICONSCHANGED "Skin2/IconsChanged"
diff --git a/yamn/include/m_kbdnotify.h b/yamn/include/m_kbdnotify.h new file mode 100644 index 0000000..256c009 --- /dev/null +++ b/yamn/include/m_kbdnotify.h @@ -0,0 +1,64 @@ +/*
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#ifndef _KBDNOTIFY_
+#define _KBDNOTIFY_
+
+//Enables all notifications (for use by BossKey)
+//wParam=0
+//lParam=0
+//returns 0
+#define MS_KBDNOTIFY_ENABLE "KeyboardNotify/Enable"
+
+
+//Disables all notifications (for use by BossKey)
+//wParam=0
+//lParam=0
+//returns 0
+#define MS_KBDNOTIFY_DISABLE "KeyboardNotify/Disable"
+
+
+//Makes the flashing begin
+//wParam=(unsigned int)eventCount
+//lParam=(char *)szFlashingSequence or NULL if you want the plugin to use current settings
+//returns 0
+#define MS_KBDNOTIFY_STARTBLINK "KeyboardNotify/StartBlinking"
+
+
+//Receives the number of events that were opened (usuful for the 'until events opened' setting)
+//wParam=(unsigned int)eventCount
+//lParam=0
+//returns 0
+#define MS_KBDNOTIFY_EVENTSOPENED "KeyboardNotify/EventsWereOpened"
+
+
+//Informs if the flashing is active
+//wParam=0
+//lParam=0
+//returns 0 if the flashing is inactive or a pointer to the string representing the sequence being used
+#define MS_KBDNOTIFY_FLASHINGACTIVE "KeyboardNotify/IsFlashingActive"
+
+
+//Normalizes the flashing sequence informed
+//wParam=0
+//lParam=(char *)szFlashingSequence <- it is rewritten
+//returns a pointer to the string representing the sequence normalized (which is in fact lParam)
+#define MS_KBDNOTIFY_NORMALSEQUENCE "KeyboardNotify/NormalizeSequence"
+
+
+#endif
diff --git a/yamn/include/m_popup.h b/yamn/include/m_popup.h new file mode 100644 index 0000000..9e5f179 --- /dev/null +++ b/yamn/include/m_popup.h @@ -0,0 +1,318 @@ +/*
+===============================================================================
+ PopUp plugin
+Plugin Name: PopUp
+Plugin authors: Luca Santarelli aka hrk (hrk@users.sourceforge.net)
+ Victor Pavlychko aka zazoo (nullbie@gmail.com)
+===============================================================================
+The purpose of this plugin is to give developers a common "platform/interface"
+to show PopUps. It is born from the source code of NewStatusNotify, another
+plugin I've made.
+
+Remember that users *must* have this plugin enabled, or they won't get any
+popup. Write this in the requirements, do whatever you wish ;-)... but tell
+them!
+===============================================================================
+*/
+#ifndef M_POPUP_H
+#define M_POPUP_H
+
+/*
+NOTE! Since Popup 1.0.1.2 there is a main meun group called "PopUps" where I
+have put a "Enable/Disable" item. You can add your own "enable/disable" items
+by adding these lines before you call MS_CLIST_ADDMAINMENUITEM:
+mi.pszPopUpName = Translate("PopUps");
+mi.position = 0; //You don't need it and it's better if you put it to zero.
+*/
+
+//#define MAX_CONTACTNAME 32
+//#define MAX_SECONDLINE 40
+#define MAX_CONTACTNAME 2048
+#define MAX_SECONDLINE 2048
+
+#define POPUP_USE_SKINNED_BG 0xffffffff
+
+//This is the basic data you'll need to fill and pass to the service function.
+typedef struct {
+ HANDLE lchContact; //Handle to the contact, can be NULL (main contact).
+ HICON lchIcon; //Handle to a icon to be shown. Cannot be NULL.
+ char lpzContactName[MAX_CONTACTNAME]; //This is the contact name or the first line in the plugin. Cannot be NULL.
+ char lpzText[MAX_SECONDLINE]; //This is the second line text. Users can choose to hide it. Cannot be NULL.
+ COLORREF colorBack; //COLORREF to be used for the background. Can be NULL, default will be used.
+ COLORREF colorText; //COLORREF to be used for the text. Can be NULL, default will be used.
+ WNDPROC PluginWindowProc; //Read below. Can be NULL; default will be used.
+ void * PluginData; //Read below. Can be NULL.
+} POPUPDATA, * LPPOPUPDATA;
+
+typedef struct {
+ HANDLE lchContact;
+ HICON lchIcon;
+ char lpzContactName[MAX_CONTACTNAME];
+ char lpzText[MAX_SECONDLINE];
+ COLORREF colorBack; //Set background to POPUP_USE_SKINNED_BG to turn on skinning
+ COLORREF colorText;
+ WNDPROC PluginWindowProc;
+ void * PluginData;
+ int iSeconds; //Custom delay time in seconds. -1 means "forever", 0 means "default time".
+// char cZero[16];
+ LPCTSTR lpzClass; //PopUp class. Used with skinning. See PopUp/AddClass for details
+ COLORREF skinBack; //Background color for colorizable skins
+ char cZero[16 - sizeof(LPCTSTR) - sizeof(COLORREF)];
+ //some unused bytes which may come useful in the future.
+} POPUPDATAEX, *LPPOPUPDATAEX;
+
+/*
+When you call MS_POPUP_ADDPOPUP, my plugin will check if the given POPUPDATA structure is filled with acceptable values. If not, the data will be rejected and no popup will be shown.
+
+- lpzText should be given, because it's really bad if a user chooses to have the second line displayed
+and it's empty :-) Just write it and let the user choose if it will be displayed or not.
+
+- PluginWindowProc is a WNDPROC address you have to give me. Why? What? Where? Calm down 8)
+My plugin will take care of the creation of the popup, of the destruction of the popup, of the come into
+view and the hiding of the popup. Transparency, animations... all this stuff.
+My plugin will not (as example) open the MessageWindow when you left click on a popup.
+Why? Because I don't know if your popup desires to open the MessageWindow :))))
+This means that you need to make a WNDPROC which takes care of the WM_messages you need.
+For example, WM_COMMAND or WM_CONTEXTMENU or WM_LMOUSEUP or whatever.
+At the end of your WNDPROC remember to "return DefWindowProc(hwnd, msg, wParam, lParam);"
+When you process a message that needs a return value (an example could be WM_CTLCOLORSTATIC,
+but you don't need to catch it 'cause it's my plugin's job), simply return the nedeed value. :)
+The default WNDPROC does nothing.
+
+- PluginData is a pointer to a void, which means a pointer to anything. You can make your own structure
+to store the data you need (example: a status information, a date, your name, whatever) and give me a
+pointer to that struct.
+You will need to destroy that structure and free the memory when the PopUp is going to be destroyed. You'll know this when you receive a UM_FREEPLUGINDATA. The name tells it all: free your own plugin data.
+
+Appendix A: Messages my plugin will handle and your WNDPROC will never see.
+WM_CREATE, WM_DESTROY, WM_TIMER, WM_ERASEBKGND
+WM_CTLCOLOR* [whatever it may be: WM_CTLCOLORDLG, WM_CTLCOLORSTATIC...]
+WM_PAINT, WM_PRINT, WM_PRINTCLIENT
+
+Appendix B: "What do I need to do?!?".
+Here is an example in C.
+
+//Your plugin is in /plugins/myPlugin/ or in miranda32/something/
+#include "../../plugins/PopUp/m_popup.h"
+
+Define your own plugin data if you need it. In this example, we need it and we'll use NewStatusNotify as example: thsi plugin shows a popup when someone in your contact list changes his/hers status. We'll need to know his status, both current and old one.
+typedef struct {
+ WORD oldStatus;
+ WORD newStatus;
+} MY_PLUGIN_DATA;
+
+When we need to show the popup, we do:
+{
+ POPUPDATA ppd;
+ hContact = A_VALID_HANDLE_YOU_GOT_FROM_SOMEWHERE;
+ hIcon = A_VALID_HANDLE_YOU_GOT_SOMEWHERE;
+ char * lpzContactName = (char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)lhContact,0);
+ //99% of the times you'll just copy this line.
+ //1% of the times you may wish to change the contact's name. I don't know why you should, but you can.
+ char * lpzText;
+ //The text for the second line. You could even make something like: char lpzText[128]; lstrcpy(lpzText, "Hello world!"); It's your choice.
+ COLORREF colorBack = GetSysColor(COLOR_BTNFACE); //The colour of Miranda's option Pages (and many other windows...)
+ COLORREF colorText = RGB(255,255,255); //White.
+ MY_PLUGIN_DATA * mpd = (MY_PLUGIN_DATA*)malloc(sizeof(MY_PLUGIN_DATA));
+
+ ZeroMemory(ppd, sizeof(ppd)); //This is always a good thing to do.
+ ppd.lchContact = (HANDLE)hContact; //Be sure to use a GOOD handle, since this will not be checked.
+ ppd.lchIcon = hIcon;
+ lstrcpy(ppd.lpzContactName, lpzContactName);
+ lstrcpy(ppd.lpzText, lpzText);
+ ppd.colorBack = colorBack;
+ ppd.colorText = colorText;
+ ppd.PluginWindowProc = (WNDPROC)PopupDlgProc;
+
+ //Now the "additional" data.
+ mpd->oldStatus = ID_STATUS_OFFLINE;
+ mpd->newStatus = ID_STATUS_ONLINE;
+
+ //Now that the plugin data has been filled, we add it to the PopUpData.
+ ppd.PluginData = mpd;
+
+ //Now that every field has been filled, we want to see the popup.
+ CallService(MS_POPUP_ADDPOPUP, (WPARAM)&ppd, 0);
+}
+
+Obviously, you have previously declared some:
+static int CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ switch(message) {
+ case WM_COMMAND:
+ if ((HIWORD)wParam == STN_CLICKED) { //It was a click on the Popup.
+ PUDeletePopUp(hWnd);
+ return TRUE;
+ }
+ break;
+ case UM_FREEPLUGINDATA: {
+ MY_PLUGIN_DATA * mpd = NULL;
+ mpd = (MY_PLUGIN_DATA*)CallService(MS_POPUP_GETPLUGINDATA, (WPARAM)hWnd,(LPARAM)mpd);
+ if (mdp > 0) free(mpd);
+ return TRUE; //TRUE or FALSE is the same, it gets ignored.
+ }
+ default:
+ break;
+ }
+ return DefWindowProc(hWnd, message, wParam, lParam);
+}
+*/
+
+/*
+Creates, adds and shows a popup, given a (valid) POPUPDATA structure pointer.
+wParam = (WPARAM)(*POPUPDATA)PopUpDataAddress
+lParam = 0
+Returns: > 0 on success, 0 if creation went bad, -1 if the PopUpData contained unacceptable values.
+NOTE: it returns -1 if the PopUpData was not valid, if there were already too many popups, if the module was disabled.
+Otherwise, it can return anything else...
+*/
+#define MS_POPUP_ADDPOPUP "PopUp/AddPopUp"
+static int __inline PUAddPopUp(POPUPDATA* ppdp) {
+ return CallService(MS_POPUP_ADDPOPUP, (WPARAM)ppdp,0);
+}
+
+#define MS_POPUP_ADDPOPUPEX "PopUp/AddPopUpEx"
+static int __inline PUAddPopUpEx(POPUPDATAEX* ppdp) {
+ return CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)ppdp,0);
+}
+
+/*
+Returns the handle to the contact associated to the specified PopUpWindow.
+You will probably need to know this handle inside your WNDPROC. Exampole: you want to open the MessageWindow. :-)
+Call MS_POPUP_GETCONTACT on the hWnd you were given in the WNDPROC.
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = 0;
+Returns: the HANDLE of the contact. Can return NULL, meaning it's the main contact. -1 means failure.
+*/
+#define MS_POPUP_GETCONTACT "PopUp/GetContact"
+static HANDLE __inline PUGetContact(HWND hPopUpWindow) {
+ return (HANDLE)CallService(MS_POPUP_GETCONTACT, (WPARAM)hPopUpWindow,0);
+}
+
+/*
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = (LPARAM)(PLUGINDATA*)PluginDataAddress;
+Returns: the address of the PLUGINDATA structure. Can return NULL, meaning nothing was given. -1 means failure.
+IMPORTANT NOTE: it doesn't seem to work if you do:
+CallService(..., (LPARAM)aPointerToAStruct);
+and then use that struct.
+Do this, instead:
+aPointerToStruct = CallService(..., (LPARAM)aPointerToAStruct);
+and it will work. Just look at the example I've written above (PopUpDlgProc).
+*/
+#define MS_POPUP_GETPLUGINDATA "PopUp/GetPluginData"
+static void __inline * PUGetPluginData(HWND hPopUpWindow) {
+ long * uselessPointer = NULL;
+ return (void*)CallService(MS_POPUP_GETPLUGINDATA,(WPARAM)hPopUpWindow,(LPARAM)uselessPointer);
+}
+
+/*
+wParam = 0
+lParam = 0
+Returns: 0 if the user has chosen not to have the second line, 1 if he choose to have the second line.
+*/
+#define MS_POPUP_ISSECONDLINESHOWN "PopUp/IsSecondLineShown"
+static BOOL __inline PUIsSecondLineShown() {
+ return (BOOL)CallService(MS_POPUP_ISSECONDLINESHOWN,0,0);
+}
+
+/*
+Requests an action or an answer from PopUp module.
+wParam = (WPARAM)wpQuery
+returns 0 on success, -1 on error, 1 on stupid calls ;-)
+*/
+#define PUQS_ENABLEPOPUPS 1 //returns 0 if state was changed, 1 if state wasn't changed
+#define PUQS_DISABLEPOPUPS 2 // " "
+#define PUQS_GETSTATUS 3 //Returns 1 (TRUE) if popups are enabled, 0 (FALSE) if popups are disabled.
+
+#define MS_POPUP_QUERY "PopUp/Query"
+
+/*
+UM_FREEPLUGINDATA
+wParam = lParam = 0. Process this message if you have allocated your own memory. (i.e.: POPUPDATA.PluginData != NULL)
+*/
+#define UM_FREEPLUGINDATA (WM_USER + 0x0200)
+
+/*
+UM_DESTROYPOPUP
+wParam = lParam = 0. Send this message when you want to destroy the popup, or use the function below.
+*/
+#define UM_DESTROYPOPUP (WM_USER + 0x0201)
+static int __inline PUDeletePopUp(HWND hWndPopUp) {
+ return (int)SendMessage(hWndPopUp, UM_DESTROYPOPUP,0,0);
+}
+
+/*
+UM_INITPOPUP
+wParam = (WPARAM)(HWND)hPopUpWindow (but this is useless, since I'll directly send it to your hPopUpWindow
+lParam = 0.
+This message is sent to the PopUp when its creation has been finished, so POPUPDATA (and thus your PluginData) is reachable.
+Catch it if you needed to catch WM_CREATE or WM_INITDIALOG, which you'll never ever get in your entire popup-life.
+Return value: if you process this message, return 0. If you don't process it, return 0. Do whatever you like ;-)
+*/
+#define UM_INITPOPUP (WM_USER + 0x0202)
+
+/*
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = (LPARAM)(char*)lpzNewText
+returns: > 0 for success, -1 for failure, 0 if the failure is due to second line not being shown. (but you could call PUIsSecondLineShown() before changing the text...)
+Changes the text displayed in the second line of the popup.
+*/
+#define MS_POPUP_CHANGETEXT "PopUp/Changetext"
+static int __inline PUChangeText(HWND hWndPopUp, LPCTSTR lpzNewText) {
+ return (int)CallService(MS_POPUP_CHANGETEXT, (WPARAM)hWndPopUp, (LPARAM)lpzNewText);
+}
+
+/*
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = (LPARAM)(POPUPDATAEX*)newData
+Changes the entire popup
+*/
+#define MS_POPUP_CHANGE "PopUp/Change"
+static int __inline PUChange(HWND hWndPopUp, POPUPDATAEX *newData) {
+ return (int)CallService(MS_POPUP_CHANGE, (WPARAM)hWndPopUp, (LPARAM)newData);
+}
+
+/*
+This is mainly for developers.
+Shows a warning message in a PopUp. It's useful if you need a "MessageBox" like function, but you don't want a modal window (which will interfere with a DialogProcedure. MessageBox steals focus and control, this one not.
+wParam = (char*) lpzMessage
+lParam = 0;
+Returns: 0 if the popup was shown, -1 in case of failure.
+*/
+#define SM_WARNING 0x01 //Triangle icon.
+#define SM_NOTIFY 0x02 //Exclamation mark icon.
+#define MS_POPUP_SHOWMESSAGE "PopUp/ShowMessage"
+
+static int __inline PUShowMessage(char* lpzText, BYTE kind) {
+ return (int)CallService(MS_POPUP_SHOWMESSAGE, (WPARAM)lpzText,(LPARAM)kind);
+}
+
+/*
+Each skinned popup (e.g. with colorBack == POPUP_USE_SKINNED_BG) should have
+class set. Then you can choose separate skin for each class (for example, you
+can create separate class for your plugin and use it for all ypu popups. User
+would became able to choose skin for your popups independently from others)
+
+You have to register popup class before using it. To do so call "PopUp/AddClass"
+with lParam = (LPARAM)(const char *)popUpClassName.
+
+All class names are translated (via Translate()) before being added to list. You
+should use english names for them.
+
+There are three predefined classes and one for backward compatability.
+
+Note that you can add clases after popup wal loaded, e.g. you shoul intercept
+ME_SYSTEM_MODULESLOADED event
+*/
+#define MS_POPUP_ADDCLASS "PopUp/AddClass"
+#define POPUP_CLASS_DEFAULT "Default"
+#define POPUP_CLASS_WARNING "Warning"
+#define POPUP_CLASS_NOTIFY "Notify"
+#define POPUP_CLASS_OLDAPI "PopUp 1.0.1.x compatability" // for internal purposes
+
+static void __inline PUAddClass(const char *lpzClass){
+ CallService(MS_POPUP_ADDCLASS, 0, (LPARAM)lpzClass);
+}
+
+#endif
diff --git a/yamn/include/m_toptoolbar.h b/yamn/include/m_toptoolbar.h new file mode 100644 index 0000000..5b83100 --- /dev/null +++ b/yamn/include/m_toptoolbar.h @@ -0,0 +1,125 @@ +
+#ifndef M_TOPTOOLBAR_H
+#define M_TOPTOOLBAR_H
+
+//button flags
+#define TTBBF_DISABLED 1
+#define TTBBF_VISIBLE 2
+#define TTBBF_PUSHED 4
+#define TTBBF_SHOWTOOLTIP 8
+#define TTBBF_DRAWBORDER 16//draw border for bitmap,bitmap must be WxH 16x12
+#define TTBBF_ISSEPARATOR 32
+
+//for internal launch buttons
+#define TTBBF_ISLBUTTON 64
+
+typedef struct {
+ int cbSize;
+ HBITMAP hbBitmapUp;
+ HBITMAP hbBitmapDown;
+ char *pszServiceUp;
+ char *pszServiceDown;
+ DWORD dwFlags;
+ LPARAM lParamUp;
+ WPARAM wParamUp;
+ LPARAM lParamDown;
+ WPARAM wParamDown;
+ char *name;
+
+} TTBButton, * lpTTBButton;
+
+typedef struct {
+ int cbSize;
+ HBITMAP hbBitmapUp;
+ HBITMAP hbBitmapDown;
+ char *pszServiceUp;
+ char *pszServiceDown;
+ DWORD dwFlags;
+ LPARAM lParamUp;
+ WPARAM wParamUp;
+ LPARAM lParamDown;
+ WPARAM wParamDown;
+ char *name;
+ HICON hIconUp,hIconDn;
+ char *tooltipUp;
+ char *tooltipDn;
+
+} TTBButtonV2, * lpTTBButtonV2;
+
+//=== EVENTS ===
+/*
+toptoolbar/moduleloaded event
+wParam = lParam = 0
+Called when the toolbar services are available
+
+!!!Warning you may work with TTB services only in this event or later.
+
+*/
+#define ME_TTB_MODULELOADED "TopToolBar/ModuleLoaded"
+
+
+
+//=== SERVICES ===
+/*
+toptoolbar/addbutton service
+wparam = (TTBButton*)lpTTBButton
+lparam = 0
+returns: hTTBButton - handle of added button on success, -1 on failure.
+*/
+#define MS_TTB_ADDBUTTON "TopToolBar/AddButton"
+
+/*
+toptoolbar/removebutton service
+wparam = (HANDLE)hTTButton
+lparam = 0
+returns: 0 on success, -1 on failure.
+*/
+#define MS_TTB_REMOVEBUTTON "TopToolBar/RemoveButton"
+
+/*
+toptoolbar/setstate service
+wparam = (HANDLE)hTTButton
+lparam = (LPARAM) state
+returns: 0 on success, -1 on failure.
+*/
+#define TTBST_PUSHED 1
+#define TTBST_RELEASED 2
+
+#define MS_TTB_SETBUTTONSTATE "TopToolBar/SetState"
+
+/*
+toptoolbar/getstate service
+wparam = (HANDLE)hTTButton
+lparam = 0
+returns: state on success, -1 on failure.
+*/
+#define MS_TTB_GETBUTTONSTATE "TopToolBar/GetState"
+
+/*
+toptoolbar/getoptions service
+(HIWORD)wparam = (HANDLE)hTTButton
+(LOWORD)wparam = TTBO_FLAG
+lparam = 0,or lparam=lpTTBButton if flag=TTBO_ALLDATA
+returns: value on success, -1 on failure.
+*/
+#define TTBO_FLAGS 0 //get/set all flags
+#define TTBO_POS 1 //position
+#define TTBO_WIDTH 2 //not impemented
+#define TTBO_HEIGHT 3 //not impemented
+#define TTBO_TIPNAME 4 //tool tip name
+#define TTBO_ALLDATA 5 //change all data via lparam=lpTTBButton
+
+
+#define MS_TTB_GETBUTTONOPTIONS "TopToolBar/GetOptions"
+
+/*
+toptoolbar/setoptions service
+(HIWORD)wparam = (HANDLE)hTTButton
+(LOWORD)wparam = TTBO_FLAG
+lparam = value
+returns: 1 on success, -1 on failure.
+*/
+#define MS_TTB_SETBUTTONOPTIONS "TopToolBar/SetOptions"
+
+
+#endif
diff --git a/yamn/include/m_uninstaller.h b/yamn/include/m_uninstaller.h new file mode 100644 index 0000000..e26f55c --- /dev/null +++ b/yamn/include/m_uninstaller.h @@ -0,0 +1,700 @@ +/*
+
+ PluginUninstaller 1.1.2.1 for Miranda IM 0.3.3a and +
+ ------------------------------------------------------------------------
+ Developers - C/C++ Header File
+
+ Plugin Info: ----------------------------
+ | Version: 1.1.2.1
+ | Filename: uninstaller.dll
+ | Author: H. Herkenrath (hrathh@users.sourceforge.net)
+ | Description: Extends the plugin options and offers the possibility
+ | to directly remove plugins and delete all associated
+ | settings and files.
+
+ Contents: -------------------------------
+ | > General Info:
+ | - Uninstall Example/Template
+ | - Changing displayed icon
+ | - Changing displayed docs
+ | - Message boxes on uninstall
+ | - Service Accesibility
+ | - Including this file
+ |
+ | > Structs:
+ | - Uninstall Params (PLUGINUNINSTALLPARAMS)
+ |
+ | > Helpers:
+ | - Macro: Run service while uninstalling (PUICallService)
+ | - Function: Remove some files in directory (PUIRemoveFilesInDirectory)
+ |
+ | > Events:
+ | - Allow to uninstall a plugin (ME_PLUGINUNINSTALLER_OKTOUNINSTALL)
+ | - Plugin gets uninstalled (ME_PLUGINUNINSTALLER_UNINSTALL)
+ |
+ | > Services:
+ | - Remove database module (MS_PLUGINUNINSTALLER_REMOVEDBMODULE)
+ | - Remove a setting globally (MS_PLUGINUNINSTALLER_REMOVEDBSETTINGGLOBALLY)
+ | - Remove skinned sound (MS_PLUGINUNINSTALLER_REMOVESKINSOUND)
+ | - Uninstall a plugin (MS_PLUGINUNISTALLER_UNISTALLPLUGIN)
+ | - Getting handles (MS_PLUGINUNINSTALLER_GETHANDLE)
+ |
+
+
+ This file is only thought for plugin developers.
+ If you only want to use "PluginUninstaller" and don't want to develop a plugin
+ or something with it you don't need this file.
+
+ If there are any problems or bugs with or in this file or something else
+ please mail me. My e-mail address is: hrathh@users.sourceforge.net
+ For more documentation you can use this address, too. :-)
+
+ If you have any whishes on some plugin uninstalling for your
+ plugin you can mail me, too. :-)
+
+*/
+#ifndef M_UNINSTALLER_H
+#define M_UNINSTALLER_H
+
+#ifndef CallService
+ #pragma message("Mistake Alert!: "m_uninstaller.h" needs to be included after "newpluginapi.h"!\n The following errors are resulting of this mistake.\n")
+#endif
+
+
+// | General Info
+// -----------------------------
+
+// Uninstall Example/Template
+// ---------------------------
+// Making your plugin uninstallable is very easy.
+// Just add the following "Uninstall" function near the "Unload" function
+// in your plugin.
+// A template plugin is available in the source code package.
+
+// Old:
+// int __declspec(dllexport) Uninstall(BOOL bIsMirandaRunning, BOOL bDoDeleteSettings, char* pszPluginPath);
+
+// New:
+//int __declspec(dllexport) UninstallEx(PLUGINUNINSTALLPARAMS* ppup)
+//{
+ // Available Variables:
+ // -----------------------------
+ // ppup->bIsMirandaRunning:
+ // Contains if Miranda is running
+ // (Currently this is always TRUE).
+
+ // ppup->bDoDeleteSettings:
+ // Contains if the users selected
+ // that he wants all settings be deleted.
+
+ // ppup->pszPluginsPath:
+ // Contains the plugins directory name.
+
+
+ // Notes:
+ // -----------------------------
+
+ // Run before "Unload" function:
+ // -> IMPORTANT: Be careful not to write to the database or to files in "Unload" again!!!
+ // -> Perhaps create a global BOOL variable which is set to TRUE when your plugin gets uninstalled
+ // or check of a database setting "IsInstalled" in Unload() or sth. like that
+
+ // All Miranda is still loaded
+
+ // Here you can do:
+ // - Delete settings group in database
+ // - Delete registry items
+ // - Delete ini-files and other settings files
+ // - Delete other files
+
+ // Your plugin dll gets automatically deleted
+
+ // Services to remove are offered:
+ // MS_PLUGINUNINSTALLER_REMOVEDBMODULE
+ // MS_PLUGINUNINSTALLER_REMOVEDBSETTINGGLOBALLY
+ // MS_PLUGINUNINSTALLER_REMOVESKINSOUND
+
+
+ // Getting other useful paths:
+ // -----------------------------
+
+ // System directory:
+
+ //char szSysPath[MAX_PATH];
+ //GetSystemDirectory(szSysPath, MAX_PATH);
+
+
+ // Windows directory:
+
+ //char szWinPath[MAX_PATH];
+ //GetWindowsDirectory(szWinPath, MAX_PATH);
+
+
+ // Other directories:
+
+ // char szPath[MAX_PATH];
+ // SHGetSpecialFolderPath(NULL, szPath, CSIDL_* , FALSE);
+
+ // Some available dirs:
+ // CSIDL_APPDATA CSIDL_SENDTO CSIDL_FAVORITES
+ // CSIDL_STARTUP CSIDL_PROFILE CSIDL_DESKTOPDIRECTORY
+
+
+ // Delete Files
+ //const char* apszFiles[] = {"MyPlugin_Readme.txt", "MyPlugin_License.txt", "MyPlugin_Developer.txt", "MyPlugin_Translation.txt"};
+ //PUIRemoveFilesInPath(ppup->pszPluginsPath, apszFiles);
+
+ // Delete Settings
+ //if(ppup->bDoDeleteSettings == TRUE)
+ //{
+ //if (ppup->bIsMirandaRunning == TRUE) // Check if it is possible to access services
+ //{
+ // Remove plugin's module
+ //PUIRemoveDbModule("MyPlugin");
+
+ // Remove plugin's sounds
+ //PUIRemoveSkinSound("MySoundSetting1");
+ //PUIRemoveSkinSound("MySoundSetting2");
+ //}
+ //}
+
+ // Remember:
+ // Do not forget to remove your (eventually) created registry items here, too.
+
+
+ // The plugin's dll file gets deleted after returning.
+
+ // Remember:
+ // If your DLL file is additionally in use by another application (eg. Windows)
+ // you need to free the DLL *here* completely. Otherwise it can't be deleted.
+
+// return 0;
+//}
+
+
+
+// Changing displayed icon
+// ---------------------------
+// The icon that gets displayed on the options page is always the "first"
+// icon in your DLL file.
+// An icon in your DLL file is the first icon when it has the lowest recource ID.
+// If you would like to have an other icon shown in the options please change your
+// icon resource IDs so that the icon you would like to have has the lowest one.
+// For example if you use MS Visual C++, open "resource.h" and change the resource define
+// of your prefered icon to the lowest icon number.
+
+
+// Changing displayed docs
+// ---------------------------
+// The items "License" and "More Information" on the plugin details page
+// are created when the a license and/or a readme file for the plugin exists.
+// The files get detected automatically and need a special name
+// so that they get detected.
+// The text files need to be either placed in the "Plugins" directory or
+// in the "Docs" directory. Whereof the last one is the better one :-)
+//
+// For the license file the following file name formatings are possible:
+// PluginName-License.txt (I personally think that this is the best naming solution... :-) )
+// PluginName_License.txt,
+//
+// For the readme file the following ones are possible:
+// PluginName-Readme.txt (Again...I like this one :-D ),
+// PluginName_Readme.txt,
+
+// Message boxes on uninstall
+// ---------------------------
+// If you would like to ask the user for something to remove/uninstall
+// please hook the event ME_PLUGINUNINSTALLER_UNINSTALL and show your
+// message box there. Save the action the user chose in a
+// global BOOL variable and do the chosen action in "UninstallEx".
+// You can get the plugins options window handle with MS_PLUGINUNINSTALLER_GETHANDLE.
+
+
+// Service Accessibility
+// ---------------------------
+// Remember that you only can use these functions after the event ME_SYSTEM_MODULESLOADED
+// or later because "PluginUninstaller" needs to be loaded first.
+// Normally you only use them in your "UninstallEx" function.
+//
+// IMPORTANT!:
+// Please make sure that you always use the macro PUICallService
+// in the "UninstallEx" function instead of the CallService function.
+
+
+// Including this file
+// ---------------------------
+// To use some of the uninstalling functionality you have to include this file
+// into your project.
+//
+// IMPORTANT!:
+// Please make sure that you include the file "newpluginapi.h" before this one.
+// If this isn't the case there may some compile errors come up.
+
+ // -> Example:
+ // If your plugin is in the directory "Plugins/MyPlugin/" and
+ // this include file is in the directory "Plugins/PluginUninstaller"
+ // you can use the following:
+
+ //#include "../PluginUninstaller/m_uninstaller.h"
+
+ // If your plugin is in an directory that is different to that one just
+ // change the include path to the one you want.
+
+
+
+
+
+// | Structs
+// -----------------------------
+
+// ---------------------------------------------
+// -- Struct: Uninstall Params -----------------
+// ---------------------------------------------
+
+// Struct: PLUGINUNINSTALLPARAMS
+// (Gets passed to "UninstallEx" function)
+
+typedef int (*HELPERPROC)(const char*, WPARAM, LPARAM); // Used internally (for pHelperProcAddress)
+
+typedef struct {
+ BOOL bIsMirandaRunning; // Is TRUE when Miranda is loaded and services are available (Please use PUICallService instead of CallService)
+ BOOL bDoDeleteSettings; // Is TRUE when user wants to delete settings (If this is FALSE, please only delete your files)
+ char* pszPluginsPath; // Contains the plugin directory path
+ char* pszDocsPath; // Contains the document directory for plugins documentation (Added in version 1.1.1.0)
+ char* pszIconsPath; // Contains the icon directory for icon dlls (Added in version 1.1.2.0)
+ HELPERPROC pHelperProcAddress; // Used internally (Contains proc address for PUICallService)
+} PLUGINUNINSTALLPARAMS;
+
+
+
+
+
+// | Helper
+// -----------------------------
+
+
+// ---------------------------------------------
+// -- Macro: Run service while uninstalling ----
+// ---------------------------------------------
+
+// Macro: PUICallService
+
+#define PUICallService(service, wParam, lParam) (ppup->pHelperProcAddress) (service, wParam, lParam);
+
+// Description:
+// -------------
+// This service provides the possibility to call a Miranda
+// service in the "UninstallEx" function.
+// Important!: Use this macro always instead of "CallService",
+// because else a crash occurs when the plugin was decativated
+// and gets uninstalled
+
+// Parameters:
+// -------------
+// Same parameters as CallService of Miranda Core.
+
+// Return Values:
+// --------------
+// Return values are the same as the CallService function of Miranda Core.
+// Additionaly returns CALLSERVICE_NOTFOUND if Miranda is not loaded
+// which means the services are not accessable.
+
+
+ // Example:
+ // ----------------------------------
+
+ //if ( (bIsMirandaRunning == TRUE) && (bDoDeleteSettings == TRUE) )
+ //{
+ // Remove plugin's module
+ //PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBMODULE, (WPARAM)"MyPlugin", 0);
+ //}
+
+
+
+
+// ---------------------------------------------
+// -- Function: Remove some files in directory -
+// ---------------------------------------------
+
+// Function: PUIRemoveFilesInDirectory
+
+static BOOL __inline PUIRemoveFilesInDirectory(char* pszPath, const char* apszFiles[]);
+
+// Description:
+// -------------
+// This helper provides the possibility to easily
+// remove specified files in a specified directory.
+
+// Note: The last version of this helper (PUIRemoveFilesInPath)
+// did not work correctly.
+// Please do now always append a NULL slot to the end of your array.
+
+// Parameters:
+// -------------
+// char* pszPath = Path to the files in array
+// const LPCSTR apszFiles[] = NULL-terminated array of files to be deleted.
+
+// Return Values:
+// --------------
+// Returns TRUE if the files could be deleted.
+// FALSE if the files could not be deleted or did not exist.
+
+
+static BOOL __inline PUIRemoveFilesInDirectory(char* pszPath, const char* apszFiles[])
+{
+ char szFile[MAX_PATH];
+ BOOL bReturn = FALSE;
+ int iFile = 0;
+
+ while (apszFiles[iFile] != NULL)
+ {
+ strncpy(szFile, pszPath, sizeof(szFile));
+ strncat(szFile, apszFiles[iFile], sizeof(szFile)-strlen(szFile));
+
+ if ((BOOL)DeleteFile(szFile) == TRUE) bReturn = TRUE;
+ iFile++;
+ }
+
+ return bReturn;
+}
+
+ // Example:
+ // ----------------------------------
+
+ //const char* apszFiles[] = {"File1.txt", "File2.txt", "File3.txt", NULL};
+ //PUIRemoveFilesInDirectory(ppup->pszPluginsPath, apszFiles);
+
+
+
+
+// | Events
+// -----------------------------
+
+
+// ---------------------------------------------
+// -- Event: Allow to uninstall a plugin -------
+// ---------------------------------------------
+
+// Event: ME_PLUGINUNINSTALLER_OKTOUNINSTALL
+
+#define ME_PLUGINUNINSTALLER_OKTOUNINSTALL "PluginUninstaller/OkToUninstall"
+
+// Submitted Values:
+// -----------------
+// wParam = pszPluginName (String containing the translated plugin name)
+// lParam = pszPluginFile (String containing the plugin dll file name in lower case)
+
+// Return Values:
+// -----------------
+// Returning 1 on this event causes the "Remove Plugin" button to be disabled.
+
+
+
+// ---------------------------------------------
+// -- Event: Plugin gets uninstalled -----------
+// ---------------------------------------------
+
+// Event: ME_PLUGINUNINSTALLER_UNINSTALL
+
+#define ME_PLUGINUNINSTALLER_UNINSTALL "PluginUninstaller/Uninstall"
+
+// Submitted Values:
+// -----------------
+// wParam = pszPluginName (String containing the translated plugin name)
+// lParam = pszPluginFile (String containing the plugin dll file name in lower case)
+
+// Return Values:
+// -----------------
+// Returning 1 on this event causes the uninstall process to be canceled.
+
+// Notice:
+// Hook this event if you would like to ask the user for something to remove/uninstall
+// and show your message box on this event. Save the action the user chose in a
+// global BOOL variable and do the chosen action in "UninstallEx".
+// You can get the plugins options window handle with MS_PLUGINUNINSTALLER_GETHANDLE.
+
+// Other plugins can use this event to be noticed that another plugin isn't installed anylonger.
+
+
+
+
+// | Services
+// -----------------------------
+
+
+// ---------------------------------------------
+// -- Service: Remove database module ----------
+// ---------------------------------------------
+
+// Service: MS_PLUGINUNINSTALLER_REMOVEDBMODULE
+
+#define MS_PLUGINUNINSTALLER_REMOVEDBMODULE "PluginUninstaller/RemoveDbModule"
+
+// Description:
+// -------------
+// This service provides the possibility to delete all database modules
+// associated to your plugin.
+// The specified database module will be removed in all contacts
+// including the NULL contact.
+// Remember to call it always with PUICallService in "UninstallEx" function.
+
+// Parameters:
+// -------------
+// wParam = (char*)pszModule // Pointer to a string containd module name. Can't be NULL
+// lParam = (const char*)apszIgnoreSettings // NULL terminated array of strings. Can be 0 if no settings should be ignored.
+ // See example 3 for more details
+
+// Return Values:
+// --------------
+// Returns 0 on success.
+// Nonzero if the module was not present in database.
+
+
+#ifndef UNINSTALLER_NOHELPERS
+
+// Can only be used in "UninstallEx" function
+#define PUIRemoveDbModule(pszModule) PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBMODULE, (WPARAM)pszModule, 0);
+
+#endif
+
+
+ // Example 1:
+ // ----------------------------------
+
+ //PUIRemoveDbModule("MyPlugin");
+
+
+ // Example 2:
+ // ----------------------------------
+
+ //char szModule[] = "MyModule";
+ //PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBMODULE, (WPARAM)szModule, 0);
+
+
+ // Example 3:
+ // ----------------------------------
+
+ // This deletes all settings in the specified module exept
+ // the specified settings: "Setting1",..."Setting4"
+
+ // char szModule[] = "MyModule";
+ // const char* apszIgnoreSettings[] = {"Setting1", "Setting2", "Setting3", "Setting4", NULL};
+ // PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBMODULE, (WPARAM)szModule, (LPARAM)&apszIgnoreSettings);
+
+
+
+// ---------------------------------------------
+// -- Service: Remove a setting globally -------
+// ---------------------------------------------
+
+// Service: MS_PLUGINUNINSTALLER_REMOVEDBSETTINGGLOBALLY
+
+#define MS_PLUGINUNINSTALLER_REMOVEDBSETTINGGLOBALLY "PluginUninstaller/RemoveDbSettingGlobally"
+
+// Description:
+// -------------
+// This service provides the possibility to delete a specific
+// setting in database in all contacts including the NULL contact.
+// Remember to call it always with PUICallService in "UninstallEx" function.
+
+// Parameters:
+// -------------
+// wParam = (char*)pszModule
+// lParam = (char*)pszSetting
+
+// Return Values:
+// --------------
+// Returns 0 on success.
+// Nonzero if the setting was not present in database.
+
+
+#ifndef UNINSTALLER_NOHELPERS
+
+// Can only be used in "UninstallEx" function
+#define PUIRemoveDbSettingGlobally(pszModule, pszSetting) PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBSETTINGGLOBALLY, (WPARAM)pszModule, (LPARAM)pszSetting);
+
+
+#endif
+
+
+ // Example 1:
+ // ----------------------------------
+
+ //PUIRemoveDbSettingGlobally("MyPlugin", "MySetting");
+
+
+ // Example 2:
+ // ----------------------------------
+
+ //szModule[] = "MyPlugin";
+ //szSetting[] = "MySetting";
+ //PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBSETTINGGLOBALLY, (WPARAM)szModule, (LPARAM)szSetting);
+
+
+
+
+
+
+// ---------------------------------------------
+// -- Service: Remove skinned sound ------------
+// ---------------------------------------------
+
+// Service: MS_PLUGINUNINSTALLER_REMOVESKINSOUND
+
+#define MS_PLUGINUNINSTALLER_REMOVESKINSOUND "PluginUninstaller/RemoveSkinSound"
+
+// Description:
+// -------------
+// This service provides the possibility to delete all your sound settings
+// associated to your plugin.
+// The specified sound will be be removed.
+// Remember to call it always with PUICallService in "UninstallEx" function.
+
+// Parameters:
+// -------------
+// wParam = (char*)pszSoundSetting
+// lParam = 0
+
+// Return Values:
+// --------------
+// Returns 0 on success.
+// Nonzero if the sound was not present in database.
+
+
+#ifndef UNINSTALLER_NOHELPERS
+
+// Can only be used in "UninstallEx" function
+#define PUIRemoveSkinSound(pszSoundSetting) PUICallService(MS_PLUGINUNINSTALLER_REMOVESKINSOUND, (WPARAM)pszSoundSetting, 0);
+
+#endif
+
+
+ // Example 1:
+ // ----------------------------------
+
+ //PUIRemoveSkinSound("MySoundSetting");
+
+
+ // Example 2:
+ // ----------------------------------
+
+ //szSoundModule[] = "MySoundSetting";
+ //PUICallService(MS_PLUGINUNINSTALLER_REMOVEDBMODULE, (WPARAM)szSoundSetting, 0);
+
+
+
+
+
+// ---------------------------------------------
+// -- Service: Uninstall a plugin --------------
+// ---------------------------------------------
+
+// Service: MS_PLUGINUNINSTALLER_UNINSTALLPLUGIN
+
+#define MS_PLUGINUNINSTALLER_UNINSTALLPLUGIN "PluginUninstaller/UninstallPlugin"
+
+// Description:
+// -------------
+// This service marks a plugin to be uninstalled at next restart of Miranda IM.
+// It uses the default value for "Delete all settings".
+// You can use this service for example when you want that your sub-plugin gets
+// also removed when your main-plugin is uninstalled.
+// Note: This service is not needed for the normal uninstalling functionality.
+
+// Parameters:
+// -------------
+// wParam = (char*)pszPluginName // do not translate this!
+// lParam = (char*)pszPluginFile // without path, only file name!
+
+// Return Values:
+// --------------
+// Returns always 0.
+
+
+#ifndef UNINSTALLER_NOHELPERS
+
+int __inline PUIUninstallPlugin(char* pszPluginName, char* pszPluginFile)
+{
+ return CallService(MS_PLUGINUNINSTALLER_UNINSTALLPLUGIN, (WPARAM)pszPluginName, (LPARAM)pszPluginFile);
+}
+
+#endif
+
+
+ // Example 1:
+ // ----------------------------------
+
+ //PUIUninstallPlugin("PluginName", "plugin.dll");
+
+
+ // Example 2:
+ // ----------------------------------
+
+ // hInst => Handle of a specific (your?) plugin
+ // char szPluginName[] = "YourPluginName";
+
+ //char* pFileName;
+ //char szPath[MAX_PATH];
+
+ //GetModuleFileName(hInst, szPath, sizeof(szPath));
+ //pFileName = strrchr(szPath, '\\');
+ //pFileName = pFileName+1; // Pointer arithmetic
+
+ //CallService(MS_PLUGINUNINSTALLER_UNINSTALLPLUGIN, (WPARAM)szPluginName, (LPARAM)pFileName);
+
+
+
+
+// ---------------------------------------------
+// -- Service: Getting handles -----------------
+// ---------------------------------------------
+
+// Service: MS_PLUGINUNINSTALLER_GETHANDLE
+
+#define MS_PLUGINUNINSTALLER_GETHANDLE "PluginUninstaller/GetHandle"
+
+// Description:
+// -------------
+// This service gets a specified window/instance handle.
+
+// Note: This service must not be used in "UninstallEx" function.
+// It is mainly thought for being used in ME_PLUGINUNINSTALLER_UNINSTALL event
+// to give out a MessageBox or something like that.
+
+// Parameters:
+// -------------
+// wParam = UINT uHandleType;
+// lParam = 0
+
+// Possible values for wParam:
+#define PUIHT_HINST_PLUGIN_INSTANCE 0 // HINSTANCE of the PluginUninstaller plugin
+#define PUIHT_HWND_PLUGIN_OPTIONS 1 // HWND of the plugin options dialog (if it is loaded; else NULL)
+
+// Return Values:
+// --------------
+// Returns the specified handle value.
+// If no handle type is specified it returns NULL.
+// The handle doesn't need to be destroyed.
+
+
+#ifndef UNINSTALLER_NOHELPERS
+
+HANDLE __inline PUIGetHandle(UINT uHandleType)
+{
+ return (HANDLE)CallService(MS_PLUGINUNINSTALLER_GETHANDLE, uHandleType, 0);
+}
+
+#endif
+
+
+ // Example
+ // ----------------------------------
+
+ //HWND hwndDlg;
+ //hwndDlg = (HWND)PUIGetHandle(PUIHT_HWND_PLUGIN_OPTIONS);
+
+
+
+
+
+#endif // M_UNINSTALLER_H
diff --git a/yamn/include/m_updater.h b/yamn/include/m_updater.h new file mode 100644 index 0000000..e10bcb3 --- /dev/null +++ b/yamn/include/m_updater.h @@ -0,0 +1,156 @@ +#ifndef _M_UPDATER_H
+#define _M_UPDATER_H
+
+#include <stdio.h>
+#include "../../../include/newpluginapi.h" //CallService,UnHookEvent
+#include "../../../include/m_utils.h" //window broadcasting
+//#include <newpluginapi.h>
+//#include <m_utils.h>
+
+// NOTES:
+// - For langpack updates, include a string of the following format in the langpack text file:
+// ";FLID: <file listing name> <version>"
+// version must be four numbers seperated by '.', in the range 0-255 inclusive
+// - Updater will disable plugins that are downloaded but were not active prior to the update (this is so that, if an archive contains e.g. ansi and
+// unicode versions, the correct plugin will be the only one active after the new version is installed)...so if you add a support plugin, you may need
+// to install an ini file to make the plugin activate when miranda restarts after the update
+// - Updater will replace all dlls that have the same internal shortName as a downloaded update dll (this is so that msn1.dll and msn2.dll, for example,
+// will both be updated) - so if you have a unicode and a non-unicode version of a plugin in your archive, you should make the internal names different (which will break automatic
+// updates from the file listing if there is only one file listing entry for both versions, unless you use the 'MS_UPDATE_REGISTER' service below)
+// - Updater will install all files in the root of the archive into the plugins folder, except for langpack files that contain the FLID string which go into the root folder (same
+// folder as miranda32.exe)...all folders in the archive will also be copied to miranda's root folder, and their contents transferred into the new folders. The only exception is a
+// special folder called 'root_files' - if there is a folder by that name in the archive, it's contents will also be copied into miranda's root folder - this is intended to be used
+// to install additional dlls etc that a plugin may require)
+
+// if you set Update.szUpdateURL to the following value when registering, as well as setting your beta site and version data,
+// Updater will ignore szVersionURL and pbVersionPrefix, and attempt to find the file listing URL's from the backend XML data.
+// for this to work, the plugin name in pluginInfo.shortName must match the file listing exactly (except for case)
+#define UPDATER_AUTOREGISTER "UpdaterAUTOREGISTER"
+// Updater will also use the backend xml data if you provide URL's that reference the miranda file listing for updates (so you can use that method
+// if e.g. your plugin shortName does not match the file listing) - it will grab the file listing id from the end of these URLs
+
+typedef struct Update_tag {
+ int cbSize;
+ char *szComponentName; // component name as it will appear in the UI (will be translated before displaying)
+
+ char *szVersionURL; // URL where the current version can be found (NULL to disable)
+ BYTE *pbVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ // (note that this URL could point at a binary file - dunno why, but it could :)
+ int cpbVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szUpdateURL; // URL where dll/zip is located
+ // set to UPDATER_AUTOREGISTER if you want Updater to find the file listing URLs (ensure plugin shortName matches file listing!)
+
+ char *szBetaVersionURL; // URL where the beta version can be found (NULL to disable betas)
+ BYTE *pbBetaVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ int cpbBetaVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szBetaUpdateURL; // URL where dll/zip is located
+
+ BYTE *pbVersion; // bytes of current version, used for comparison with those in VersionURL
+ int cpbVersion; // number of bytes pointed to by pbVersion
+
+ char *szBetaChangelogURL; // url for displaying changelog for beta versions
+} Update;
+
+// register a comonent with Updater
+//
+// wparam = 0
+// lparam = (LPARAM)&Update
+#define MS_UPDATE_REGISTER "Update/Register"
+
+// utility functions to create a version string from a DWORD or from pluginInfo
+// point buf at a buffer at least 16 chars wide - but note the version string returned may be shorter
+//
+__inline static char *CreateVersionString(DWORD version, char *buf) {
+ mir_snprintf(buf, 16, "%d.%d.%d.%d", (version >> 24) & 0xFF, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);
+ return buf;
+}
+
+__inline static char *CreateVersionStringPlugin(PLUGININFO *pluginInfo, char *buf) {
+ return CreateVersionString(pluginInfo->version, buf);
+}
+
+__inline static char *CreateVersionStringPluginEx(PLUGININFOEX *pluginInfo, char *buf) {
+ return CreateVersionString(pluginInfo->version, buf);
+}
+
+
+// register the 'easy' way - use this method if you have no beta URL and the plugin is on the miranda file listing
+// NOTE: the plugin version string on the file listing must be the string version of the version in pluginInfo (i.e. 0.0.0.1,
+// four numbers between 0 and 255 inclusivem, so no letters, brackets, etc.)
+//
+// wParam = (int)fileID - this is the file ID from the file listing (i.e. the number at the end of the download link)
+// lParam = (PLUGININFO*)&pluginInfo
+#define MS_UPDATE_REGISTERFL "Update/RegisterFL"
+
+// this function can be used to 'unregister' components - useful for plugins that register non-plugin/langpack components and
+// may need to change those components on the fly
+// lParam = (char *)szComponentName
+#define MS_UPDATE_UNREGISTER "Update/Unregister"
+
+// this event is fired when the startup process is complete, but NOT if a restart is imminent
+// it is designed for status managment plugins to use as a trigger for beggining their own startup process
+// wParam = lParam = 0 (unused)
+// (added in version 0.1.6.0)
+#define ME_UPDATE_STARTUPDONE "Update/StartupDone"
+
+// this service can be used to enable/disable Updater's global status control
+// it can be called from the StartupDone event handler
+// wParam = (BOOL)enable
+// lParam = 0
+// (added in version 0.1.6.0)
+#define MS_UPDATE_ENABLESTATUSCONTROL "Update/EnableStatusControl"
+
+// An description of usage of the above service and event:
+// Say you are a status control plugin that normally sets protocol or global statuses in your ModulesLoaded event handler.
+// In order to make yourself 'Updater compatible', you would move the status control code from ModulesLoaded to another function,
+// say DoStartup. Then, in ModulesLoaded you would check for the existence of the MS_UPDATE_ENABLESTATUSCONTROL service.
+// If it does not exist, call DoStartup. If it does exist, hook the ME_UPDATE_STARTUPDONE event and call DoStartup from there. You may
+// also wish to call MS_UPDATE_ENABLESTATUSCONTROL with wParam == FALSE at this time, to disable Updater's own status control feature.
+
+// this service can be used to determine whether updates are possible for a component with the given name
+// wParam = 0
+// lParam = (char *)szComponentName
+// returns TRUE if updates are supported, FALSE otherwise
+#define MS_UPDATE_ISUPDATESUPPORTED "Update/IsUpdateSupported"
+
+#endif
+
+
+/////////////// Usage Example ///////////////
+
+#ifdef EXAMPLE_CODE
+
+// you need to #include "m_updater.h" and HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded) in your Load function...
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam) {
+
+ Update update = {0}; // for c you'd use memset or ZeroMemory...
+ char szVersion[16];
+
+ update.cbSize = sizeof(Update);
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionString(&pluginInfo, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+
+ // these are the three lines that matter - the archive, the page containing the version string, and the text (or data)
+ // before the version that we use to locate it on the page
+ // (note that if the update URL and the version URL point to standard file listing entries, the backend xml
+ // data will be used to check for updates rather than the actual web page - this is not true for beta urls)
+ update.szUpdateURL = "http://scottellis.com.au:81/test/updater.zip";
+ update.szVersionURL = "http://scottellis.com.au:81/test/updater_test.html";
+ update.pbVersionPrefix = (BYTE *)"Updater version ";
+
+ update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix);
+
+ // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+
+ // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing...
+ // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo);
+
+ return 0;
+}
+
+#endif
diff --git a/yamn/libs/unicows.lib b/yamn/libs/unicows.lib Binary files differnew file mode 100644 index 0000000..9ef8bbd --- /dev/null +++ b/yamn/libs/unicows.lib diff --git a/yamn/m_account.h b/yamn/m_account.h new file mode 100644 index 0000000..2baadd2 --- /dev/null +++ b/yamn/m_account.h @@ -0,0 +1,239 @@ +/*
+ * This file defines all needed parameters for one account.
+ * Other plugin can use this (so YAMN does not check it and another plugin can inform YAMN about new mail e.g.),
+ * this can be usefull for plugins like Yahoo or MSN (Hotmail notify)
+ *
+ * (c) majvan 2002-2004
+ */
+
+#ifndef __ACCOUNT_H
+#define __ACCOUNT_H
+
+#include <windows.h>
+#include <tchar.h>
+#include "m_synchro.h" //include synchronizing objects. If you want to write protocol plugin, which works with YAMN accounts, it must use YAMN synchronizing objects
+
+//
+//================================== OTHER DEFINITIONS ========================================
+//
+
+enum
+{
+// Error codes returned from functions (services) working with account book files
+ EACC_SYSTEM=1, //use GetLastError() to retrieve detailed information about error
+ EACC_ALLOC, //problem with memory allocation
+ EACC_FILECOMPATIBILITY, //file is corrupted
+ EACC_ENDOFFILE, //unexpected end of file occured
+ EACC_FILEVERSION, //file should be YAMN book format, but newer version that expected
+ EACC_FILESIZE, //file has wrong size
+};
+
+enum
+{
+// Status of account
+// used in messages WM_YAMN_CHANGESTATUS
+// used also in function GetStatus and SetStatus
+ ACC_IDLE=0, //account is IDLE (no work is performed with account)
+ ACC_FINDING, //DNS lookup for account
+ ACC_CONNECTING, //connecting in progress
+ ACC_LOGGING, //logging in progress
+ ACC_WORKING, //working
+ ACC_DISCONNECTING, //disconnecting from server
+};
+
+typedef struct CNotification
+{
+//#define YAMN_NOTIFICATIONVERSION is not implemented, use YAMN_ACCOUNTVERSION instead
+ CNotification(): PopUpB(0), PopUpT(0), PopUpTime(0), App(NULL), AppParam(NULL), Sound(NULL), TrayIcon1(NULL), TrayIcon2(NULL) {}
+
+#define YAMN_ACC_SND 0x00000001 //Plays sound (1)
+#define YAMN_ACC_MSG 0x00000002 //Shows dialog
+#define YAMN_ACC_ICO 0x00000004 //Shows system tray icon (1)
+#define YAMN_ACC_ICOB 0x00000008 //not used now, enables tray icon flashing (1)
+#define YAMN_ACC_APP 0x00000010 //Runs application (1)
+#define YAMN_ACC_POP 0x00000020 //Shows popup
+#define YAMN_ACC_POPC 0x00000040 //Use custom colors in popup
+#define YAMN_ACC_MSGP 0x00000080 //Persistant messgage. This means, when an situation occurs (e.g. new mail) and message is displayed, it is not destroyed when YAMN_ACC_MSG is not set
+#define YAMN_ACC_KBN 0x00000100 //Use Keyboard notify
+#define YAMN_ACC_CONT 0x00000200 //Use Contact notify
+#define YAMN_ACC_CONTNICK 0x00000400 //Use Contact Nick replacement
+#define YAMN_ACC_CONTNOEVENT 0x00000800 //Suppress event for this contact
+//(1) - usable only in newmail notification
+ DWORD Flags;
+
+ COLORREF PopUpB;
+ COLORREF PopUpT;
+ DWORD PopUpTime;
+ WCHAR *App;
+ WCHAR *AppParam;
+
+//These parameters are not stored in standard YAMN book file and therefore must be set by plugin
+ char *Sound;
+ HICON TrayIcon1;
+ HICON TrayIcon2;
+} YAMN_NOTIFICATION,*PYAMN_NOTIFICATION;
+
+typedef struct CServer
+{
+ CServer(): Name(NULL),Login(NULL),Passwd(NULL) {}
+
+ TCHAR *Name;
+ DWORD Port;
+
+ TCHAR *Login;
+
+// Password encryption definitions
+#define STARTCODEPSW 0x50
+#define ADDCODEPSW 0x0
+ TCHAR *Passwd;
+
+} *PSERVER;
+
+//
+//================================== ACCOUNT DEFINITION ==================================
+//
+
+typedef struct CAccount
+{
+#define YAMN_ACCOUNTFILEVERSION 2 //version of standard file format (YAMN book file format)
+#define YAMN_ACCOUNTVERSION 3
+//If changes are made in this structure, version is changed.
+//So then YAMN does not initialzie your structure, if version does not matches.
+
+ BOOL AbleToWork; //This is set to TRUE by default. When it is needed to stop working on this account, YAMN sets this to zero.
+
+ struct CYAMNProtoPlugin *Plugin; //free access, because this member should not be changed. The same as YAMN_PLUGIN structure
+
+ TCHAR *Name; //access only through AccountAccessSO
+
+// DWORD Abilities; //access only through AccountAccessSO
+
+ PSERVER Server; //access only through AccountAccessSO
+
+ WORD Interval; //access only through AccountAccessSO
+
+// YAMN account flags (set by user)
+#define YAMN_ACC_ENA 0x00000001 //Enables account. If account is disabled, no countdown is performed
+#define YAMN_ACC_POPN 0x00000002 //Shows one popup per one new mail or for N mails
+#define YAMN_ACC_APOP 0x00000004 //Use APOP authentication
+#define YAMN_ACC_SSL23 0x00000008 //Use SSLv2,3
+#define YAMN_ACC_NOTLS 0x00000010 //Don't try StartTLS (STLS) even available
+#define YAMN_ACC_BODY 0x00000020 //Always retrieve body of the message
+ DWORD Flags; //access only through AccountAccessSO
+
+// YAMN account flags (set by plugin)
+#define YAMN_ACC_BROWSE 0x00000001 //Can browse mails. On this account we can run mailbrowser window
+#define YAMN_ACC_POPUP 0x00000002 //Popups of new mail belonging to this account can be showed
+ DWORD AbilityFlags;
+
+// YAMN account status flags
+#define YAMN_ACC_ST0 0x00000001 //Check (countdown) when Offline
+#define YAMN_ACC_ST1 0x00000002 //Check (countdown) when Online
+#define YAMN_ACC_ST2 0x00000004 //Check (countdown) when Away
+#define YAMN_ACC_ST3 0x00000008 //Check (countdown) when N/A
+#define YAMN_ACC_ST4 0x00000010 //Check (countdown) when Occupied
+#define YAMN_ACC_ST5 0x00000020 //Check (countdown) when DND
+#define YAMN_ACC_ST6 0x00000040 //Check (countdown) when Free for chat
+#define YAMN_ACC_ST7 0x00000080 //Check (countdown) when Invisible
+#define YAMN_ACC_ST8 0x00000100 //Check (countdown) when On the phone
+#define YAMN_ACC_ST9 0x00000200 //Check (countdown) when Out to lunch
+#define YAMN_ACC_STARTA 0x00010000 //Check on start anyway
+#define YAMN_ACC_STARTS 0x00020000 //Check on start regarding to status setting
+#define YAMN_ACC_FORCE 0x00040000 //Check when "check new mail" item pressed (it is called forced checking)
+ DWORD StatusFlags; //access only through AccountAccessSO
+
+// Plugin flags. Use this DWORD if you want YAMN to store it to YAMN book file. You can set here any value
+ DWORD PluginFlags;
+
+ YAMN_NOTIFICATION NewMailN; //access only through AccountAccessSO
+ YAMN_NOTIFICATION NoNewMailN; //access only through AccountAccessSO
+ YAMN_NOTIFICATION BadConnectN; //access only through AccountAccessSO
+
+ SYSTEMTIME LastChecked; //last check, access only through AccountAccessSO
+ SYSTEMTIME LastSChecked; //last check (successfull), access only through AccountAccessSO
+ SYSTEMTIME LastSynchronised; //last synchronisation (successfull), access only through AccountAccessSO
+ SYSTEMTIME LastMail; //last check when new mail detected, access only through AccountAccessSO
+
+ char Status[255]; //access only through GetStatusFcn() and SetStatusFcn() functions
+
+ DWORD TimeLeft; //access only through AccountAccessSO
+
+ HANDLE Mails; //access only through MessagesAccessSO
+
+//Account members are mostly the same, but there can be protocol (POP3,IMAP...) special features.
+//To use them, only inherit this class and add your own features.
+//First idea was to add pointer to void, where plugin can store its own values.
+//But this solution is better in my opinion.
+
+//This is event with counter. Event is signaled when no threads are using account (and will not be using)
+//Very usefull for account delete operation
+ PSCOUNTER UsingThreads;
+
+//We have to achieve, that only one thread can write to account and more threads can read.
+//Writing to account means that we change account parameters
+//Reading from account meands we read account parameters
+//Use WaitToRead(), ReadDone(), WaitToWrite(), WriteDone() synchronization functions
+//For plugins, this is a pointer to void. It does not matter for plugin what is this variable for,
+//because plugin works only with synchronization routines. And why is this void * ? It is because
+//plugin does not need to include headers for SWMRG structures...
+ PSWMRG AccountAccessSO;
+
+//We have to achieve, that only one thread can write to account mails and more threads can read.
+//While some thread writes mails, other thread can write to account. This can be small problem, but it never appears in YAMN.
+//But you should think about this note if you want to add some features in the future
+//Writing to messages means any changes to message queue or message data
+//Reading from messages means reading message queue (browsing through all messages) or reading message data
+//Use MsgsWaitToRead(),MsgsReadDone(),MsgsWaitToWrite(),MsgsWriteDone() synchronization functions
+ PSWMRG MessagesAccessSO;
+
+//For clist contact notification
+ HANDLE hContact;
+ BOOL isCounting;
+
+ struct CAccount *Next;
+} *HACCOUNT;
+
+//
+//================================== FUNCTIONS DEFINITIONS ========================================
+//
+
+typedef void (WINAPI *YAMN_SETSTATUSFCN)(HACCOUNT,TCHAR *);
+typedef void (WINAPI *YAMN_GETSTATUSFCN)(HACCOUNT,TCHAR *);
+
+//
+//================================== QUICK FUNCTION CALL DEFINITIONS ========================================
+//
+
+//These are defininitions for YAMN exported functions. Your plugin can use them.
+//pYAMNFcn is global variable, it is pointer to your structure containing YAMN functions.
+//It is something similar like pluginLink variable in Miranda plugin. If you use
+//this name of variable, you have already defined these functions and you can use them.
+//It's similar to Miranda's CreateService function.
+
+//How to use YAMN functions:
+//Create a structure containing pointer to functions you want to use in your plugin
+//This structure can look something like this:
+//
+// struct
+// {
+// YAMN_SETSTATUSFCN SetStatusFcn;
+// YAMN_GETSTATUSFCN GetStatusFcn;
+// } *pYAMNFcn;
+//
+//then you have to fill this structure with pointers...
+//
+// pYAMNFcn->SetStatusFcn=(YAMN_SETSTATUSFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SETSTATUSID,(LPARAM)0);
+// pYAMNFcn->GetStatusFcn=(YAMN_GETSTATUSFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_GETSTATUSID,(LPARAM)0);
+//
+//and in your plugin just simply use e.g.:
+//
+// SetAccountStatus(ActualAccount,ACC_CONNECTING); //this command set account status to "connecting to server"
+//
+
+#define YAMN_SETSTATUSID "YAMN/SetStatus"
+#define YAMN_GETSTATUSID "YAMN/GetStatus"
+
+#define SetAccountStatus(x,y) pYAMNFcn->SetStatusFcn(x,y)
+#define GetAccountStatus(x,y) pYAMNFcn->GetStatusFcn(x,y)
+
+#endif
diff --git a/yamn/m_filterplugin.h b/yamn/m_filterplugin.h new file mode 100644 index 0000000..210cb0c --- /dev/null +++ b/yamn/m_filterplugin.h @@ -0,0 +1,139 @@ +#ifndef __M_FILTERPLUGIN_H
+#define __M_FILTERPLUGIN_H
+
+#include <windows.h>
+#include "mails/m_mails.h" //for mail definition
+
+//
+//================================== IMPORTED FUNCTIONS ==================================
+//
+
+#ifndef YAMN_STANDARDFCN
+typedef DWORD (WINAPI *YAMN_STANDARDFCN)(LPVOID);
+#endif
+typedef DWORD (WINAPI *YAMN_FILTERMAILFCN)(HACCOUNT,DWORD,HYAMNMAIL,DWORD);
+
+typedef struct CFilterImportFcn
+{
+//If changes are made in this structure, version is changed.
+//So then YAMN does not initialize your structure, if version does not match.
+#define YAMN_FILTERIMPORTFCNVERSION 2
+
+//Function is called to get info from mail and mark mail as spam or not...
+ YAMN_FILTERMAILFCN FilterMailFcnPtr;
+
+//Function is called when application exits. Plugin should unload
+ YAMN_STANDARDFCN UnLoadFcn;
+} YAMN_FILTERIMPORTFCN, *PYAMN_FILTERIMPORTFCN;
+
+//
+//================================== FILTER PLUGIN REGISTRATION STRUCTURES ==================================
+//
+
+typedef struct CFilterPluginRegistration
+{
+#define YAMN_FILTERREGISTRATIONVERSION 2
+//Name of plugin
+//this member CANNOT be NULL. Just write here description, i.e. "PopFile filter plugin for YAMN"
+ char *Name;
+
+//The version of plugin. CANNOT be NULL.
+ char *Ver;
+
+//Plugin copyright
+//Write here your copyright if you want (or NULL)
+ char *Copyright;
+
+//Plugin description. Can be NULL.
+ char *Description;
+
+//Your contact (email). Can be NULL.
+ char *Email;
+
+//The web page. Can be NULL.
+ char *WWW;
+} YAMN_FILTERREGISTRATION, *PYAMN_FILTERREGISTRATION;
+
+typedef struct CYAMNFilterPlugin
+{
+//Importance of plugin. Mails are filtered in the way, that filter with smallest importance number
+//filters and marks mails first and the filter using the highest number marks mails the last. It means,
+//that number with highest number is the most important, because it can set or clear flags as it wants,
+//if another plugin set some flag, plugin with higher number can clear it.
+ DWORD Importance;
+
+//All needed other info from plugin
+ PYAMN_FILTERREGISTRATION PluginInfo;
+
+//Imported functions
+ PYAMN_FILTERIMPORTFCN FilterFcn;
+} YAMN_FILTERPLUGIN, *PYAMN_FILTERPLUGIN, *HYAMNFILTERPLUGIN;
+
+typedef struct CFilterPluginQueue
+{
+ HYAMNFILTERPLUGIN Plugin;
+ struct CFilterPluginQueue *Next;
+} YAMN_FILTERPLUGINQUEUE,*PYAMN_FILTERPLUGINQUEUE;
+
+//
+//================================== YAMN SERVICES FOR PROTOCOL PLUGIN ==================================
+//
+
+//RegisterFilterPlugin Service
+//Registers filter plugin
+//WPARAM- pointer to YAMN_FILTERREGISTRATION structure. Plugin must not delete this structure from memory.
+//LPARAM- version of YAMN_FILTERREGISTRATION structure (use YAMN_PROTOREGISTRATIONVERSION definition)
+//returns handle to plugin (HYAMNFILTERPLUGIN), if registration failed (plugin not registered) returns NULL
+//You need next to call SetFilterPluginFcnImportFcn to have your plugin cooperated with YAMN.
+#define MS_YAMN_REGISTERFILTERPLUGIN "YAMN/Service/RegisterFilterPlugin"
+
+//UnregisterFilterPlugin Service
+//Unregisters filter plugin
+//WPARAM- (HYAMNFILTERPLUGIN) plugin handle
+//LPARAM- any value
+//returns nonzero if success
+#define MS_YAMN_UNREGISTERFILTERPLUGIN "YAMN/Service/UnregisterFilterPlugin"
+
+//
+//================================== FUNCTIONS DEFINITIONS ========================================
+//
+
+typedef INT_PTR (WINAPI *YAMN_SETFILTERPLUGINFCNIMPORTFCN)(HYAMNFILTERPLUGIN Plugin,DWORD Importance,PYAMN_FILTERIMPORTFCN YAMNFilterFcn,DWORD YAMNFilterFcnVer);
+
+//
+//================================== QUICK FUNCTION CALL DEFINITIONS ========================================
+//
+
+//These are defininitions for YAMN exported functions. Your plugin can use them.
+//pYAMNFcn is global variable, it is pointer to your structure containing YAMN functions.
+//It is something similar like pluginLink variable in Miranda plugin. If you use
+//this name of variable, you have already defined these functions and you can use them.
+//It's similar to Miranda's CreateService function.
+
+//How to use YAMN functions:
+//Create a structure containing pointer to functions you want to use in your plugin
+//This structure can look something like this:
+//
+// struct
+// {
+// YAMN_SETFILTERPLUGINFCNIMPORTFCN SetFilterPluginFcnImportFcn;
+// } *pYAMNFcn;
+//
+//then you have to fill this structure with pointers... If you use Miranda services, you will do it like this
+//
+// pYAMNFcn->SetFilterPluginFcnImportFcn=(YAMN_SETFILTERPLUGINFCNIMPORTFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SETFILTERPLUGINFCNIMPORTID,(LPARAM)0);
+//
+//If you do not use Miranda services, call service MS_YAMN_GETFCNPTR directly. The address to the MS_YAMN_GETFCNPTR is sent to you in LoadFilter function:
+//
+// pYAMNFcn->SetFilterPluginFcnImportFcn=(YAMN_SETFILTERPLUGINFCNIMPORTFCN)YAMN_GetFcnPtr((WPARAM)YAMN_SETFILTERPLUGINFCNIMPORTID,(LPARAM)0);
+//
+//and in your plugin just simply use e.g.:
+//
+// SetFilterPluginFcnImport(...);
+//
+
+#define YAMN_SETFILTERPLUGINFCNIMPORTID "YAMN/SetFilterPluginFcnImport"
+
+#define SetFilterPluginFcnImport(a,b,c,d) pYAMNFcn->SetFilterPluginFcnImportFcn(a,b,c,d)
+
+#endif
diff --git a/yamn/m_messages.h b/yamn/m_messages.h new file mode 100644 index 0000000..7fc0fbe --- /dev/null +++ b/yamn/m_messages.h @@ -0,0 +1,41 @@ +#ifndef __MESSAGES_H
+#define __MESSAGES_H
+
+//#include "list.h"
+
+// structure for chained list of handles (window handles, account handles, whatever)
+struct WndHandles
+{
+ HANDLE Handle;
+
+ struct WndHandles *Next;
+};
+
+#define WM_YAMN WM_APP+0x2800 //(0xA800 in fact)
+enum
+{
+ WM_YAMN_CHANGEHOTKEY=WM_YAMN,
+ WM_YAMN_CHANGETIME,
+
+//ChangeStatus message
+//WPARAM- (HACCOUNT) Account whose status is changed
+//LPARAM- new status of account
+ WM_YAMN_CHANGESTATUS,
+
+//StopAccount message
+//WPARAM- (HACCOUNT) Account, which should stop its work and finish immidiatelly
+ WM_YAMN_STOPACCOUNT,
+
+//Account content changed
+ WM_YAMN_CHANGECONTENT,
+
+ WM_YAMN_UPDATEMAILS,
+
+ WM_YAMN_NOTIFYICON,
+
+ WM_YAMN_CHANGESTATUSOPTION,
+
+ WM_YAMN_SHOWSELECTED,
+};
+
+#endif
diff --git a/yamn/m_protoplugin.h b/yamn/m_protoplugin.h new file mode 100644 index 0000000..4407dae --- /dev/null +++ b/yamn/m_protoplugin.h @@ -0,0 +1,389 @@ +#ifndef __M_PROTOPLUGIN_H
+#define __M_PROTOPLUGIN_H
+
+#include <windows.h>
+#include "m_account.h" //for account import functions
+#include "mails/m_mails.h" //for mail import functions
+
+//
+//================================== OTHER DEFINITIONS ========================================
+//
+
+//structure is used to give parameters to Check, Synchro or Timeout function
+struct CheckParam
+{
+//Your plugin should use this definition
+#define YAMN_CHECKVERSION 2
+//Version of this structure. Please verify your version in your plugin
+ DWORD Ver;
+//Event that new Check thread must set to signal calling thread that "I've copied all parameters from stack"
+//IMPORTANT!!!: Although version #defined in your plugin is not the same, your plugin MUST signal this event
+//in any way. YAMN is waiting for this event. If you do not signal it, YAMN is blocked.
+ HANDLE ThreadRunningEV;
+//ActualAccount- the only parameter used in Check function and should contain all needed information I think :)
+ HACCOUNT AccountParam;
+
+//I thought it, but this is needed, too
+#define YAMN_NORMALCHECK 0
+#define YAMN_FORCECHECK 1
+ DWORD Flags;
+
+//YAMN writes here some informations that are needed to pass to mail browser function (or bad connection)
+ void *BrowserParam;
+//Calling thread (protocol plugin) can write here its own parameters. Usefull when protocol calls its own check function. YAMN always sets this parameter to NULL
+ void *CustomParam;
+};
+
+//structure is used to give parameters to DeleteMails function
+struct DeleteParam
+{
+//Your plugin should use this definition
+#define YAMN_DELETEVERSION 1
+//Version of this structure. Please verify your version in your plugin
+ DWORD Ver;
+//Event that new Delete thread must set to signal calling thread that it copied all parameters from stack
+//IMPORTANT!!!: Although version #defined in your plugin is not the same, your plugin MUST signal this event
+//in any way. YAMN is waiting for this event. If you do not signal it, YAMN is blocked.
+ HANDLE ThreadRunningEV;
+//ActualAccount- which account to delete
+ HACCOUNT AccountParam;
+//YAMN writes here some informations that are needed to pass to mail browser function (or bad connection or no new mail)
+ void *BrowserParam;
+//Calling thread can write here its own parameter. Usefull when protocol calls its own delete function. YAMN always sets this parameter to NULL
+ void *CustomParam;
+};
+
+//
+//================================== IMPORTED FUNCTIONS ==================================
+//
+
+#ifndef YAMN_STANDARDFCN
+typedef DWORD (WINAPI *YAMN_STANDARDFCN)(LPVOID);
+#endif
+typedef struct CYAMNVariables *(WINAPI *YAMN_GETVARIABLESFCN)(DWORD);
+typedef HACCOUNT (WINAPI *YAMN_NEWACCOUNTFCN)(struct CYAMNProtoPlugin *,DWORD);
+typedef void (WINAPI *YAMN_STOPACCOUNTFCN)(HACCOUNT);
+typedef void (WINAPI *YAMN_DELETEACCOUNTFCN)(HACCOUNT);
+typedef DWORD (WINAPI *YAMN_WRITEPLUGINOPTS)(HANDLE File,HACCOUNT);
+typedef DWORD (WINAPI *YAMN_READPLUGINOPTS)(HACCOUNT,TCHAR **,TCHAR *);
+typedef DWORD (WINAPI *YAMN_CHECKFCN)(struct CheckParam *);
+typedef DWORD (WINAPI *YAMN_DELETEFCN)(struct DeleteParam *);
+typedef WCHAR* (WINAPI *YAMN_GETERRORSTRINGWFCN)(DWORD);
+typedef char* (WINAPI *YAMN_GETERRORSTRINGAFCN)(DWORD);
+typedef void (WINAPI *YAMN_DELETEERRORSTRINGFCN)(LPVOID);
+typedef DWORD (WINAPI *YAMN_WRITEACCOUNTSFCN)();
+
+typedef struct CAccountImportFcn
+{
+//If changes are made in this structure, version is changed.
+//So then YAMN does not initialize your structure, if version does not match.
+#define YAMN_PROTOIMPORTFCNVERSION 3
+
+//Note: not all of these functions are needed to be implemented in your protocol plugin. Those
+//functions, which are not implemented, you have to set to NULL.
+
+//Function is called to construct protocol defined account
+//This is VERY IMPORTANT for YAMN and plugin to cooperate:
+//Imagine following situation. YAMN wants to add new account (it is possible e.g.
+//when loading accounts from file), so it has to call protocol constructor.
+//It calls NewAccount function and plugin creates new account and returns
+//its handle (pointer in fact). That means new account is created with plugin features
+//(it is created inherited account, not base class).
+ YAMN_NEWACCOUNTFCN NewAccountFcnPtr;
+
+//Function is called to delete protocol defined variables to inherited CAccount structure
+ YAMN_DELETEACCOUNTFCN DeleteAccountFcnPtr;
+
+//Function is called when user requests not tu run account longer. (E.g. when closing Miranda)
+ YAMN_STOPACCOUNTFCN StopAccountFcnPtr;
+
+//Function is called when plugin should write its own info into book file
+ YAMN_WRITEPLUGINOPTS WritePluginOptsFcnPtr;
+
+//Function is called when plugin should read its own info from book file
+ YAMN_READPLUGINOPTS ReadPluginOptsFcnPtr;
+
+//Function is called to synchronise account (delete old mails and get the new ones)
+ YAMN_CHECKFCN SynchroFcnPtr;
+
+//Function is called when timer timed out- it can be the same as SynchroFcnPtr
+ YAMN_CHECKFCN TimeoutFcnPtr;
+
+//Function is called when forced checking- it can be the same as SynchroFcnPtr
+ YAMN_CHECKFCN ForceCheckFcnPtr;
+
+//Function is called when user wants to delete mails
+ YAMN_DELETEFCN DeleteMailsFcnPtr;
+
+//Function is called when YAMN wants to get error description. Note the parameter given in
+//this function is in fact the same as your CheckFcnPtr, DeleteMailsFcnPtr etc. returns to YAMN.
+//If you want, you may return pointer to some structure, which includes more information about
+//error than only one DWORD. And then, you can in your function create Unicode string containing
+//all your error code. YAMN copies this string into its own buffer. Your error code and pointer
+//can be deleted in DeleteErrorStringFcnPtr, which is called by YAMN
+ YAMN_GETERRORSTRINGWFCN GetErrorStringWFcnPtr;
+
+//This is the same as previous one, but plugin returns normal string (not Unicode). YAMN first
+//looks, if your plugin has implemented GetErrorStringWFcnPtr. If not, it looks for this function
+//So as you (of course) wait, you implemnt only one of these functions or no one of them.
+ YAMN_GETERRORSTRINGAFCN GetErrorStringAFcnPtr;
+
+//Deletes error string that was allocated in your GetErrorStringXFcnPtr. Parameter to this fcn is
+//Unicode or normal string. Therefore parameter is defined as LPVOID, but your plugin knows if it is
+//Unicode or not...
+//If NULL, YAMN does nothing with string
+ YAMN_DELETEERRORSTRINGFCN DeleteErrorStringFcnPtr;
+
+//Function is called to notify plugin, that it is quite good to store account status (and mails)
+ YAMN_WRITEACCOUNTSFCN WriteAccountsFcnPtr;
+
+//Function is called when user wants to view mails
+//not used now, in the future
+ YAMN_STANDARDFCN ViewMailsFcnPtr;
+
+//Function is called when application exits. Plugin should unload
+ YAMN_STANDARDFCN UnLoadFcn;
+} YAMN_PROTOIMPORTFCN, *PYAMN_PROTOIMPORTFCN;
+
+typedef HYAMNMAIL (WINAPI *YAMN_NEWMAILFCN)(HACCOUNT,DWORD);
+typedef void (WINAPI *YAMN_DELETEMAILFCN)(HYAMNMAIL);
+typedef DWORD (WINAPI *YAMN_WRITEMAILOPTS)(HANDLE File,HYAMNMAIL);
+typedef DWORD (WINAPI *YAMN_READMAILOPTS)(HYAMNMAIL,TCHAR **,TCHAR *);
+
+typedef struct CMailImportFcn
+{
+//If changes are made in this structure, version is changed.
+//So then YAMN does not initialize your structure, if version does not match.
+#define YAMN_MAILIMPORTFCNVERSION 1
+
+//Note: not all of these functions are needed to be implemented in your protocol plugin. Those
+//functions, which are not implemented, you have to set to NULL.
+
+//Function is called to construct protocol defined account
+//This is VERY IMPORTANT for YAMN and plugin to cooperate:
+//Imagine following situation. YAMN wants to add new account (it is possible e.g.
+//when loading accounts from file), so it has to call protocol constructor.
+//It calls NewAccount function and plugin creates new account and returns
+//its handle (pointer in fact). That means new account is created with plugin features
+//(it is created inherited account, not base class).
+ YAMN_NEWMAILFCN NewMailFcnPtr;
+
+//Function is called to delete protocol defined variables to inherited CAccount structure
+ YAMN_DELETEMAILFCN DeleteMailFcnPtr;
+
+//Function is called when plugin should write its own info into book file
+ YAMN_WRITEMAILOPTS WriteMailOptsFcnPtr;
+
+//Function is called when plugin should read its own info from book file
+ YAMN_READMAILOPTS ReadMailOptsFcnPtr;
+} YAMN_MAILIMPORTFCN, *PYAMN_MAILIMPORTFCN;
+
+//
+//================================== PROTOCOL PLUGIN REGISTRATION STRUCTURES ==================================
+//
+
+typedef struct CProtoPluginRegistration
+{
+#define YAMN_PROTOREGISTRATIONVERSION 1
+//Name of plugin
+//this member CANNOT be NULL. Just write here description, i.e. "Yahoo Mail 1.2"
+ char *Name;
+
+//The version of plugin. CANNOT be NULL.
+ char *Ver;
+
+//Plugin copyright
+//Write here your copyright if you want (or NULL)
+ char *Copyright;
+
+//Plugin description. Can be NULL.
+ char *Description;
+
+//Your contact (email). Can be NULL.
+ char *Email;
+
+//The web page. Can be NULL.
+ char *WWW;
+
+} YAMN_PROTOREGISTRATION, *PYAMN_PROTOREGISTRATION;
+
+typedef struct CYAMNProtoPlugin
+{
+//Pointer to first protocol plugin account
+ HACCOUNT FirstAccount;
+
+//We prevent browsing through accounts (chained list) from deleting or adding any account
+//If we want to delete or add, we must have "write" access to AccountBrowserSO
+//Note that accounts can be changed during AccountBrowser is in "read" mode, because we do not add or delete account.
+ PSWMRG AccountBrowserSO;
+
+//All needed other info from plugin
+ PYAMN_PROTOREGISTRATION PluginInfo;
+
+//Imported functions
+ PYAMN_PROTOIMPORTFCN Fcn;
+ PYAMN_MAILIMPORTFCN MailFcn;
+} YAMN_PROTOPLUGIN, *PYAMN_PROTOPLUGIN, *HYAMNPROTOPLUGIN;
+
+typedef struct CProtoPluginQueue
+{
+ HYAMNPROTOPLUGIN Plugin;
+ struct CProtoPluginQueue *Next;
+} YAMN_PROTOPLUGINQUEUE,*PYAMN_PROTOPLUGINQUEUE;
+
+//
+//================================== YAMN SERVICES FOR PROTOCOL PLUGIN ==================================
+//
+
+//RegisterProtoPlugin Service
+//Your plugin can call this service to "connect to YAMN"- it means, that you
+//give some parameters to YAMN and YAMN can then cooperate with your protocol plugins
+//WPARAM- pointer to YAMN_PROTOREGISTRATION structure. Plugin must not delete this structure from memory.
+//LPARAM- version of YAMN_PROTOREGISTRATION structure (use YAMN_PROTOREGISTRATIONVERSION definition)
+//returns handle to plugin (HYAMNPROTOPLUGIN), if registration failed (plugin not registered) returns NULL
+//Note, that your plugin should store returned plugin handle, because it will be usefull in next services.
+//You need next to call SetProtocolPluginFcnImportFcn to have your plugin cooperated with YAMN.
+#define MS_YAMN_REGISTERPROTOPLUGIN "YAMN/Service/RegisterProtocolPlugin"
+
+//UnregisterProtoPlugin Service
+//Removes plugin from YAMN and deltes its structures
+//WPARAM- (HYAMNPROTOPLUGIN) handle of protocol plugin
+//LPARAM- any value
+//returns nonzero if success
+#define MS_YAMN_UNREGISTERPROTOPLUGIN "YAMN/Service/UnregisterProtocolPlugin"
+
+//CreateAccount Service
+//Your plugin should call this to create new account for your plugin.
+//WPARAM- (HYAMNPLUGIN) Plugin handle
+//LPARAM- CAccount version (use YAMN_ACCOUNTVERSION definition)
+//returns pointer to (HACCOUNT) or pointer to your structure returned from imported NewAccountFcnPtr, if implemented
+#define MS_YAMN_CREATEPLUGINACCOUNT "YAMN/Service/CreateAccount"
+
+//DeletePluginAccount Service
+//Deletes plugin's account from memory. You probably won't use this service, because it deletes only account
+//without any synchronization. Use MS_YAMN_DELETEACCOUNT instead.
+//WPARAM- (HACCOUNT) to delete
+//LPARAM- any value
+//returns zero if failed, otherwise returns nonzero
+#define MS_YAMN_DELETEPLUGINACCOUNT "YAMN/Service/DeletePluginAccount"
+
+//FindAccountByName Service
+//Searches accounts queue for first account that belongs to plugin
+//WPARAM- (HYAMNPLUGIN) Plugin handle
+//LPARAM- (TCHAR *)string, name of account to find
+//returns found HACCOUNT handle or NULL if not found
+#define MS_YAMN_FINDACCOUNTBYNAME "YAMN/Service/FindAccountByName"
+
+//GetNextFreeAccount Service
+//Creates new account for plugin and adds it to plugin account queue.
+//Note!!! you have to use AccountBrowserSO in your plugin before and after calling this service, because it is not synchronized
+//So the normal way is like this:
+// WaitToWriteSO(MyPlugin->AccountBrowserSO);
+// CallService(MS_YAMN_GETNEXTFREEACCOUNT,MyPlugin,YAMN_ACCOUNTVERSION);
+// WriteDoneSO(MyPlugin->AccountBrowserSO);
+//
+//WPARAM- (HYAMNPLUGIN) Plugin handle
+//LPARAM- CAccount version (use YAMN_ACCOUNTVERSION definition)
+//returns new HACCOUNT handle or NULL if not found
+#define MS_YAMN_GETNEXTFREEACCOUNT "YAMN/Service/GetNextFreeAccount"
+
+//DeleteAccount Service
+//Deletes account from plugin account queue. It also deletes it, but in background (when needed).
+//This deleting is full synchronized and safe. It is recommended for plugins to use this service.
+//WPARAM- (HYAMNPLUGIN) Plugin handle
+//LPARAM- (HACCOUNT) Account to delete
+#define MS_YAMN_DELETEACCOUNT "YAMN/Service/DeleteAccount"
+
+//ReadAccountsA Service
+//Reads standard accounts to file. Standard account means standard YAMN book format.
+//WPARAM- (HYAMNPLUGIN) Plugin handle
+//LPARAM- (char *)filename string. Put here your own desired filename.
+//return value is one of the ones written in "account.h" file
+#define MS_YAMN_READACCOUNTSA "YAMN/Service/ReadAccountsA"
+
+//ReadAccountsW Service
+//Same as ReadAccountsA service, but difference is in WPARAM
+//WPARAM- (HYAMNPLUGIN) Plugin handle
+//LPARAM- (WCHAR *)filename string. Use MS_YAMN_GETFILENAMEW service to retrieve your filename, or
+// just put your own desired filename
+#define MS_YAMN_READACCOUNTSW "YAMN/Service/ReadAccountsW"
+
+//WriteAccountsA Service
+//Writes standard accounts to file. Standard account means standard YAMN book format. It does not
+//store special protocol features. It stores Account settings from CAccount struct and stores MIME mails
+//from CMimeMsgQueue. If your Mails pointer does not point to CMimeMsgQueue structure,
+//do not use this function. You are then forced to write your own function
+//WPARAM- (HYAMNPLUGIN) Plugin handle
+//LPARAM- (char *)filename string. Put here your own desired filename.
+//return value is one of the ones written in "account.h" file
+#define MS_YAMN_WRITEACCOUNTSA "YAMN/Service/WriteAccountsA"
+
+//WriteAccountsW Service
+//Writes standard accounts to file. Standard account means standard YAMN book format.
+//WPARAM- (HYAMNPLUGIN) Plugin handle
+//LPARAM- (WCHAR *)filename string. Use MS_YAMN_GETFILENAMEW service to retrieve your filename, or
+// just put your own desired filename
+//return value is one of the ones written in "account.h" file
+#define MS_YAMN_WRITEACCOUNTSW "YAMN/Service/WriteAccountsW"
+
+//GetFileNameA Service
+//Function makes original filename, when you add your protocol string
+//From "yahoo" makes "yamn-accounts.yahoo.xxxxx.book" filename
+//It is good to use this fcn to have similar filenames...
+//WPARAM- (char *) plugin string
+//LPARAM- any value
+//returns NULL when failed, otherwise returns (WCHAR *)string (!!! not char *) to filename!!!
+//You can use MS_YAMN_DELETEFILENAME service to release allocated filename from memory
+#define MS_YAMN_GETFILENAMEA "YAMN/Service/GetFileNameA"
+
+//GetFileNameW Service
+//Same as GetFileNameA service, but difference is in WPARAM
+//WPARAM- (WCHAR *) plugin string
+//LPARAM- any value
+#define MS_YAMN_GETFILENAMEW "YAMN/Service/GetFileNameW"
+
+//DeleteFileName Service
+//deletes unicode string from memory
+//WPARAM- (WCHAR *) pointer to unicode string
+//LPARAM- any value
+#define MS_YAMN_DELETEFILENAME "YAMN/Service/DeleteFileName"
+
+//
+//================================== FUNCTIONS DEFINITIONS ========================================
+//
+
+typedef int (WINAPI *YAMN_SETPROTOCOLPLUGINFCNIMPORTFCN)(HYAMNPROTOPLUGIN Plugin,PYAMN_PROTOIMPORTFCN YAMNFcn,DWORD YAMNFcnVer,PYAMN_MAILIMPORTFCN YAMNMailFcn,DWORD YAMNMailFcnVer);
+
+//
+//================================== QUICK FUNCTION CALL DEFINITIONS ========================================
+//
+
+//These are defininitions for YAMN exported functions. Your plugin can use them.
+//pYAMNFcn is global variable, it is pointer to your structure containing YAMN functions.
+//It is something similar like pluginLink variable in Miranda plugin. If you use
+//this name of variable, you have already defined these functions and you can use them.
+//It's similar to Miranda's CreateService function.
+
+//How to use YAMN functions:
+//Create a structure containing pointer to functions you want to use in your plugin
+//This structure can look something like this:
+//
+// struct
+// {
+// YAMN_SETPROTOCOLPLUGINFCNIMPORTFCN SetProtocolPluginFcnImportFcn;
+// } *pYAMNFcn;
+//
+//then you have to fill this structure with pointers...
+//
+// pYAMNFcn->SetProtocolPluginFcnImportFcn=(YAMN_SETPROTOCOLPLUGINFCNIMPORTFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SETPROTOCOLPLUGINFCNIMPORTID,(LPARAM)0);
+//
+//and in your plugin just simply use e.g.:
+//
+// SetProtocolPluginFcnImport(...);
+//
+
+#define YAMN_SETPROTOCOLPLUGINFCNIMPORTID "YAMN/SetProtocolPluginFcnImport"
+
+#define SetProtocolPluginFcnImport(a,b,c,d,e) pYAMNFcn->SetProtocolPluginFcnImportFcn(a,b,c,d,e)
+
+#endif
diff --git a/yamn/m_synchro.h b/yamn/m_synchro.h new file mode 100644 index 0000000..ff3e601 --- /dev/null +++ b/yamn/m_synchro.h @@ -0,0 +1,160 @@ +#ifndef __SYNCHRO_H
+#define __SYNCHRO_H
+
+#include <windows.h>
+
+//
+//================================== OTHER DEFINITIONS ========================================
+//
+
+#define WAIT_FINISH WAIT_OBJECT_0+1
+
+// This structure is used to get semaphore-like synchronization:
+// Includes incrementing, decrementing DWORD value and if DWORD is zero, sets event
+typedef struct SynchronisedCounter
+{
+// Stores number value
+ HANDLE Event;
+ DWORD Number;
+
+// These methods are deleted due to external plugins. Use SCGetNumber,SCInc and SCDec instead
+// DWORD GetNumber();
+// DWORD Inc();
+// DWORD Dec();
+
+// Yes, some code is defined here. But it is not so problematic, because it uses only Win32 API calls and Win32 structures,
+ SynchronisedCounter(): Number(0)
+ {
+ InitializeCriticalSection(&CounterCS);
+ Event=CreateEvent(NULL,FALSE,TRUE,NULL);
+ SetEvent(Event);
+ }
+
+ SynchronisedCounter(HANDLE InitializedEvent): Number(0)
+ {
+ InitializeCriticalSection(&CounterCS);
+ Event=InitializedEvent;
+ SetEvent(Event);
+ }
+
+ ~SynchronisedCounter()
+ {
+ DeleteCriticalSection(&CounterCS);
+ CloseHandle(Event);
+ }
+
+//private: //it is not private as other functions (not methods) use these members
+ CRITICAL_SECTION CounterCS;
+} SCOUNTER, *PSCOUNTER;
+
+// The single-writer/multiple-reader guard
+// compound synchronization object (SO)
+// Notices: Copyright (c) 1995-1997 Jeffrey Richter
+// Changes: majvan, only one process implementation,
+// hFinishEV event added- signals when we do not want to use this SO anymore
+typedef struct SingleWriterMultiReaderGuard
+{
+// This event guards access to the other objects
+// managed by this data structure and also indicates
+// whether any writer threads are writing.
+ HANDLE hEventNoWriter;
+
+// This manual-reset event is signaled when
+// no reader threads are reading.
+ HANDLE hEventNoReaders;
+
+// This value is used simply as a counter.
+// (the count is the number of reader threads)
+ HANDLE hSemNumReaders;
+
+// The request is for not to enter critical section
+// for writing or reading due to going to delete guard
+ HANDLE hFinishEV;
+} SWMRG, *PSWMRG;
+
+//
+//================================== FUNCTIONS DEFINITIONS ========================================
+//
+
+typedef DWORD (WINAPI *YAMN_WAITTOWRITEFCN)(PSWMRG,PSCOUNTER);
+typedef void (WINAPI *YAMN_WRITEDONEFCN)(PSWMRG,PSCOUNTER);
+typedef DWORD (WINAPI *YAMN_WAITTOREADFCN)(PSWMRG);
+typedef void (WINAPI *YAMN_READDONEFCN)(PSWMRG);
+typedef DWORD (WINAPI *YAMN_SCMANAGEFCN)(PSCOUNTER);
+
+//
+//================================== QUICK FUNCTION CALL DEFINITIONS ========================================
+//
+
+//These are defininitions for YAMN exported functions. Your plugin can use them.
+//pYAMNFcn is global variable, it is pointer to your structure containing YAMN functions.
+//It is something similar like pluginLink variable in Miranda plugin. If you use
+//this name of variable, you have already defined these functions and you can use them.
+//It's similar to Miranda's CreateService function.
+//These functions are used to synchronize accounts. YAMN could create service for these
+//functions and you could call them then e.g. CallService(MS_YAMNWAITTOWRITE,WPARAM,LPARAM),
+//but I think this solution is better, because these functions are much used. It is more
+//"normal" if you call function for example like:
+//WaitToWrite(ActualAccount) than CallService(MS_YAMNWAITTOWRITE,ActualAccount,NULL))
+
+//How to use YAMN functions:
+//Create a structure containing pointer to functions you want to use in your plugin
+//This structure can look something like this:
+//
+// struct
+// {
+// YAMN_WAITTOWRITEFCN WaitToWriteFcn;
+// YAMN_WRITEDONEFCN WriteDoneFcn;
+// } *pYAMNFcn;
+//
+//then you have to fill this structure with pointers...
+//you have to use YAMN service to get pointer, like this (I wrote here all functions you may need,
+//you can copy to your sources only those you need):
+//
+// pYAMNFcn->WaitToWriteFcn=(YAMN_WAITTOWRITEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_WAITTOWRITEID,(LPARAM)0);
+// pYAMNFcn->WriteDoneFcn=(YAMN_WRITEDONEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_WRITEDONEID,(LPARAM)0);
+// pYAMNFcn->WaitToReadFcn=(YAMN_WAITTOREADFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_WAITTOREADID,(LPARAM)0);
+// pYAMNFcn->ReadDoneFcn=(YAMN_READDONEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_READDONEID,(LPARAM)0);
+// pYAMNFcn->SCGetNumberFcn=(YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SCGETNUMBERID,(LPARAM)0);
+// pYAMNFcn->SCIncFcn=(YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SCINCID,(LPARAM)0);
+// pYAMNFcn->SCDecFcn=(YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SCDECID,(LPARAM)0);
+//
+//and in your plugin just simply use e.g.:
+//
+// MsgsWriteDone(ActualAccount); //this command leaves write access to account mails
+//
+
+#define YAMN_WAITTOWRITEID "YAMN/WaitToWrite"
+#define YAMN_WRITEDONEID "YAMN/WriteDone"
+#define YAMN_WAITTOREADID "YAMN/WaitToRead"
+#define YAMN_READDONEID "YAMN/ReadDone"
+#define YAMN_SCGETNUMBERID "YAMN/SCGetNumber"
+#define YAMN_SCINCID "YAMN/SCInc"
+#define YAMN_SCDECID "YAMN/SCDec"
+
+#define WaitToWrite(x) pYAMNFcn->WaitToWriteFcn(x->AccountAccessSO,0)
+#define WaitToWriteEx(x,y) pYAMNFcn->WaitToWriteFcn(x->AccountAccessSO,y)
+#define WriteDone(x) pYAMNFcn->WriteDoneFcn(x->AccountAccessSO,0)
+#define WaitToRead(x) pYAMNFcn->WaitToReadFcn(x->AccountAccessSO)
+#define WaitToReadEx(x,y) pYAMNFcn->WaitToReadFcn(x->AccountAccessSO,y)
+#define ReadDone(x) pYAMNFcn->ReadDoneFcn(x->AccountAccessSO)
+
+#define MsgsWaitToWrite(x) pYAMNFcn->WaitToWriteFcn(x->MessagesAccessSO,0)
+#define MsgsWaitToWriteEx(x,y) pYAMNFcn->WaitToWriteFcn(x->MessagesAccessSO,y)
+#define MsgsWriteDone(x) pYAMNFcn->WriteDoneFcn(x->MessagesAccessSO,0)
+#define MsgsWaitToRead(x) pYAMNFcn->WaitToReadFcn(x->MessagesAccessSO)
+#define MsgsWaitToReadEx(x) pYAMNFcn->WaitToReadFcn(x->MessagesAccessSO,y)
+#define MsgsReadDone(x) pYAMNFcn->ReadDoneFcn(x->MessagesAccessSO)
+
+#define WaitToWriteSO(x) pYAMNFcn->WaitToWriteFcn(x,0)
+#define WaitToWriteSOEx(x,y) pYAMNFcn->WaitToWriteFcn(x,y)
+#define WriteDoneSO(x) pYAMNFcn->WriteDoneFcn(x,0)
+#define WaitToReadSO(x) pYAMNFcn->WaitToReadFcn(x)
+#define WaitToReadSOEx(x,y) pYAMNFcn->WaitToReadFcn(x,y)
+#define ReadDoneSO(x) pYAMNFcn->ReadDoneFcn(x)
+
+#define SCGetNumber(x) pYAMNFcn->SCGetNumberFcn(x)
+#define SCInc(x) pYAMNFcn->SCIncFcn(x)
+#define SCDec(x) pYAMNFcn->SCDecFcn(x)
+
+#endif
diff --git a/yamn/m_yamn.h b/yamn/m_yamn.h new file mode 100644 index 0000000..035c71f --- /dev/null +++ b/yamn/m_yamn.h @@ -0,0 +1,154 @@ +#ifndef __M_YAMN_H
+#define __M_YAMN_H
+
+#include <windows.h>
+
+//
+//================================== VARIABLES STRUCT ========================================
+//
+
+#ifndef MIRANDASERVICE
+typedef INT_PTR (*MIRANDASERVICE)(WPARAM,LPARAM);
+#endif
+
+typedef struct CYAMNVariables
+{
+#define YAMN_VARIABLESVERSION 3
+ HINSTANCE hInst;
+ HANDLE MessageWnds;
+ HANDLE NewMailAccountWnd;
+ int Shutdown;
+} YAMN_VARIABLES, *PYAMN_VARIABLES;
+
+//
+//================================== EXPORTED FUNCTIONS STRUCT ===============================
+//
+
+struct CExportedFunctions
+{
+ char* ID;
+ void *Ptr;
+};
+
+struct CExportedServices
+{
+ char* ID;
+ INT_PTR (* Ptr)(WPARAM,LPARAM);
+};
+
+//
+//================================== YAMN EVENTS ==================================
+//
+
+//UninstallPlugin Event
+//Sent when user wants to uninstall YAMN and all its plugins
+#define ME_YAMN_UNINSTALLPLUGINS "YAMN/MirandaEvents/UninstallPlugins"
+
+//NewMail Event
+//Notifies you about new mail
+//no arguments now (Developers, send mail, which params would you like to have, but note there's problem that
+//params are 32b numbers. When it is pointer to some data, these data should persist while every plugin read them and
+//after that they can be removed from memory. So it is problem)
+#define ME_YAMN_NEWMAIL "YAMN/MirandaEvents/NewMail"
+
+//
+//================================== YAMN SERVICES ==================================
+//
+
+//GetFcnPtr Service
+//Your plugin can co-operate with YAMN in 2 ways: with Miranda services and with YAMN exported functions
+//Some commands are written in services, some are functions. The advantage of function calling instead of
+//service calling is, that your code is more clear and it is faster than service calling (smaller, FASTER,
+//easier- it is slogan of Miranda, isn't it ?). Miranda service has only 2 parameters, that can be
+//disadvantage too.
+//In every way, it is discutable which functions should be exported or if they should be implemented as
+//services. And if YAMN should export some functions etc. Functions not used very often are now implemented
+//as Miranda services.
+//
+//This service gets pointer to YAMN function. Then you can use function directly. In m_?????.h files you have
+//definitions of some functions, with definitions of structure variable, so you can use functions very
+//clearly, just look to header file.
+//WPARAM- function ID. It is string representating function you need to get pointer (e.g. YAMN_WRITEWAITID)
+//LPARAM- not used now, but set it to 0
+//returns pointer to YAMN function or NULL when functions does not exist
+#define MS_YAMN_GETFCNPTR "YAMN/Service/GetFcn"
+
+//GetVariables Service
+//Ask YAMN for pointer to CYAMNVariables structure.
+//WPARAM- YAMN_VARIABLESVERSION
+//LPARAM- any value
+//returns pointer to YAMN_VARIABLES or NULL when version of structure does not match
+#define MS_YAMN_GETVARIABLES "YAMN/Service/GetVar"
+
+//ForceCheck Service
+//Check mail on accounts
+//WPARAM- not used
+//LPARAM- not used
+#define MS_YAMN_FORCECHECK "YAMN/Service/ForceCheck"
+
+//AccountCheck Service
+//Check mail on individual account
+//WPARAM- HACCOUNT
+//LPARAM- BOOL: Show Popup on no new mail
+#define MS_YAMN_ACCOUNTCHECK "YAMN/Service/AccountCheck"
+
+//Contact List Context Menu Click
+//wParam=(WPARAM)hContact
+//lParam=0
+//
+//Event is fired when there is a double click on a CList contact,
+//it is upto the caller to check for the protocol & status
+//of the HCONTACT, it's not done for you anymore since it didn't make
+//sense to store all this information in memory, etc.
+#define MS_YAMN_CLISTCONTEXT "YAMN/Service/ClistContactContextMenu"
+
+//Contact List Context Menu Click for application
+//wParam=(WPARAM)hContact
+//lParam=0
+//
+//Event is fired when there is a double click on a CList contact,
+//it is upto the caller to check for the protocol & status
+//of the HCONTACT, it's not done for you anymore since it didn't make
+//sense to store all this information in memory, etc.
+#define MS_YAMN_CLISTCONTEXTAPP "YAMN/Service/ClistContactContextMenuApp"
+
+//Contact List Double Click
+//wParam=(WPARAM)hContact
+//lParam=0
+//
+//Event is fired when there is a double click on a CList contact,
+//it is upto the caller to check for the protocol & status
+//of the HCONTACT, it's not done for you anymore since it didn't make
+//sense to store all this information in memory, etc.
+#define MS_YAMN_CLISTDBLCLICK "YAMN/Service/ClistContactDoubleclicked"
+
+//FilterMail Service
+//Ask YAMN to process mail filtering. YAMN calls filter plugins to mark mail as spam etc... Warning! Leave all
+//read or write access to mail as this function waits for write-access to mail!
+//WPARAM- (HACCOUNT) account to which mail belongs
+//LPARAM- (HYAMNMAIL) mail to filter
+#define MS_YAMN_FILTERMAIL "YAMN/Service/FilterMail"
+
+//MailBrowser Service
+//runs mail browser window (or tray icon only or popups only)
+//WPARAM- pointer to YAMN_MAILBROWSERPARAM structure, data to mailbrowser. You do not need to fill ThreadRunningEV event member.
+//LPARAM- YAMN_MAILBROWSERPARAM structure version param. Use YAMN_MAILBROWSERVERSION definition.
+//returns zero if failed, nonzero if succeed
+#define MS_YAMN_MAILBROWSER "YAMN/Service/RunMailBrowser"
+
+//NoNewMail Service
+//runs no new mail procedure (shows popups e.g.)
+//WPARAM- pointer to YAMN_NONEWMAILPARAM structure, data to no new mail procedure. You do not need to fill ThreadRunningEV event member.
+//LPARAM- YAMN_NONEWMAILPARAM structure version param. Use YAMN_NONEWMAILVERSION definition.
+//returns zero if failed, nonzero if succeed
+#define MS_YAMN_NONEWMAILPROC "YAMN/Service/NoNewMailProc"
+
+//BadConnection Service
+//runs bad connection window
+//WPARAM- pointer to YAMN_BADCONNECTIONPARAM structure, data to mailbrowser. You do not need to fill ThreadRunningEV event member.
+//LPARAM- YAMN_BADCONNECTIONPARAM structure version param. Use YAMN_BADCONNECTIONVERSION definition.
+//returns zero if failed, nonzero if succeed
+#define MS_YAMN_BADCONNECTION "YAMN/Service/BadConnection"
+
+#define MUUID_YAMN_FORCECHECK { 0x7d15e716, 0x6045, 0x40e3, { 0xa2, 0xb5, 0x5f, 0xb, 0xa4, 0x2b, 0xc7, 0x77 } }
+#endif
diff --git a/yamn/mails/decode.cpp b/yamn/mails/decode.cpp new file mode 100644 index 0000000..15c23e9 --- /dev/null +++ b/yamn/mails/decode.cpp @@ -0,0 +1,558 @@ +/*
+ * This code implements decoding encoded MIME header in style
+ * =?iso-8859-2?Q? "User using email in central Europe characters such as =E9" ?=
+ *
+ * (c) majvan 2002-2004
+ */
+#include "../yamn.h"
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+struct _tcptable CodePageNamesAll[]=
+{
+ {_T("ANSI"),_T(""),TRUE,CP_ACP},
+ {_T("WINDOWS-1"),_T("250"),0,1250},
+ {_T("WINDOWS-1"),_T("251"),0,1251},
+ {_T("WINDOWS-1"),_T("252"),0,1252},
+ {_T("WINDOWS-1"),_T("253"),0,1253},
+ {_T("WINDOWS-1"),_T("254"),0,1254},
+ {_T("WINDOWS-1"),_T("255"),0,1255},
+ {_T("WINDOWS-1"),_T("256"),0,1256},
+ {_T("WINDOWS-1"),_T("257"),0,1257},
+ {_T("WINDOWS-1"),_T("258"),0,1258},
+ {_T("CP1"),_T("250"),0,1250},
+ {_T("CP1"),_T("251"),0,1251},
+ {_T("CP1"),_T("252"),0,1252},
+ {_T("CP1"),_T("253"),0,1253},
+ {_T("CP1"),_T("254"),0,1254},
+ {_T("CP1"),_T("255"),0,1255},
+ {_T("CP1"),_T("256"),0,1256},
+ {_T("CP1"),_T("257"),0,1257},
+ {_T("CP1"),_T("258"),0,1258},
+ {_T("ANSI-1"),_T("250"),0,1250},
+ {_T("ANSI-1"),_T("251"),0,1251},
+ {_T("ANSI-1"),_T("252"),0,1252},
+ {_T("ANSI-1"),_T("253"),0,1253},
+ {_T("ANSI-1"),_T("254"),0,1254},
+ {_T("ANSI-1"),_T("255"),0,1255},
+ {_T("ANSI-1"),_T("256"),0,1256},
+ {_T("ANSI-1"),_T("257"),0,1257},
+ {_T("ANSI-1"),_T("258"),0,1258},
+ {_T("KOI8"),_T("-R"),0,20866},
+ {_T("KOI8"),_T(""),0,20866},
+ {_T("KOI8"),_T("-U"),0,21866},
+ {_T("KOI8"),_T("-RU"),0,21866},
+ {_T("US-"),_T("ASCII"),0,20127},
+ {_T("CP"),_T("367"),0,20127},
+ {_T("ASCII"),_T(""),0,20127},
+ {_T("ASCII"),_T("7"),0,20127},
+ {_T("ISO-8859"),_T("-1"),0,28591},
+ {_T("ISO-8859"),_T("-2"),0,28592},
+ {_T("ISO-8859"),_T("-3"),0,28593},
+ {_T("ISO-8859"),_T("-4"),0,28594},
+ {_T("ISO-8859"),_T("-5"),0,28595},
+ {_T("ISO-8859"),_T("-6"),0,28596},
+ {_T("ISO-8859"),_T("-7"),0,28597},
+ {_T("ISO-8859"),_T("-8"),0,28598},
+ {_T("ISO-8859"),_T("-9"),0,28599},
+ {_T("ISO-8859"),_T("-15"),0,28605},
+ {_T("ISO_8859"),_T("-1"),0,28591},
+ {_T("ISO_8859"),_T("-2"),0,28592},
+ {_T("ISO_8859"),_T("-3"),0,28593},
+ {_T("ISO_8859"),_T("-4"),0,28594},
+ {_T("ISO_8859"),_T("-5"),0,28595},
+ {_T("ISO_8859"),_T("-6"),0,28596},
+ {_T("ISO_8859"),_T("-7"),0,28597},
+ {_T("ISO_8859"),_T("-8"),0,28598},
+ {_T("ISO_8859"),_T("-9"),0,28599},
+ {_T("ISO_8859"),_T("-15"),0,28605},
+ {_T("ISO-"),_T("10646-USC2"),0,1200},
+ {_T("ISO-2022"),_T("/2-JP"),0,50220},
+ {_T("ISO-2022"),_T("-JP"),0,50221},
+ {_T("ISO-2022"),_T("/JIS-JP"),0,50222},
+ {_T("ISO-2022"),_T("-KR"),0,50225},
+ {_T("ISO-2022"),_T("-CH(SP)"),0,50227},
+ {_T("ISO-2022"),_T("-CH(TR)"),0,50229},
+ {_T("UTF-"),_T("7"),0,65000},
+ {_T("UTF-"),_T("8"),0,65001},
+ {_T("ARAB-"),_T("TRANSPARENT"),0,710},
+ {_T("ASMO-"),_T("TRANSPARENT"),0,720},
+ {_T("ASMO-"),_T("449"),0,709},
+ {_T("ASMO-"),_T("708"),0,708},
+ {_T("BIG5"),_T(""),0,950},
+ {_T("EUC-"),_T("CH(SP)"),0,51936},
+ {_T("EUC-"),_T("CH(TR)"),0,51950},
+ {_T("EUC-"),_T("JP"),0,51932},
+ {_T("EUC-"),_T("KR"),0,51949},
+ {_T("GB-"),_T("2312"),0,20936},
+ {_T("GB"),_T("2312"),0,20936},
+ {_T("HZGB-"),_T("2312"),0,52936},
+ {_T("IBM-"),_T("037"),0,37},
+ {_T("IBM-"),_T("290"),0,290},
+ {_T("IBM-"),_T("437"),0,437},
+ {_T("IBM-"),_T("500"),0,500},
+ {_T("IBM-"),_T("775"),0,775},
+ {_T("IBM-"),_T("850"),0,850},
+ {_T("IBM-"),_T("852"),0,852},
+ {_T("IBM-"),_T("855"),0,855},
+ {_T("IBM-"),_T("857"),0,857},
+ {_T("IBM-"),_T("860"),0,860},
+ {_T("IBM-"),_T("861"),0,861},
+ {_T("IBM-"),_T("862"),0,862},
+ {_T("IBM-"),_T("863"),0,863},
+ {_T("IBM-"),_T("864"),0,864},
+ {_T("IBM-"),_T("865"),0,865},
+ {_T("IBM-"),_T("866"),0,866},
+ {_T("IBM-"),_T("869"),0,869},
+ {_T("IBM-"),_T("870"),0,870},
+ {_T("IBM-"),_T("875"),0,875},
+ {_T("IBM-"),_T("1026"),0,1026},
+ {_T("IBM-"),_T("273"),0,20273},
+ {_T("IBM-"),_T("277"),0,20277},
+ {_T("IBM-"),_T("278"),0,20278},
+ {_T("IBM-"),_T("280"),0,20280},
+ {_T("IBM-"),_T("284"),0,20284},
+ {_T("IBM-"),_T("285"),0,20285},
+ {_T("IBM-"),_T("290"),0,20290},
+ {_T("IBM-"),_T("297"),0,20297},
+ {_T("IBM-"),_T("420"),0,20420},
+ {_T("IBM-"),_T("423"),0,20423},
+ {_T("IBM-"),_T("871"),0,20871},
+ {_T("IBM-"),_T("880"),0,20880},
+ {_T("IBM-"),_T("905"),0,20905},
+ {_T("IBM-"),_T("THAI"),0,20838},
+ {_T("ISCII-"),_T("DEVANAGARI"),0,57002},
+ {_T("ISCII-"),_T("BENGALI"),0,57003},
+ {_T("ISCII-"),_T("TAMIL"),0,57004},
+ {_T("ISCII-"),_T("TELUGU"),0,57005},
+ {_T("ISCII-"),_T("ASSAMESE"),0,57006},
+ {_T("ISCII-"),_T("ORIYA"),0,57007},
+ {_T("ISCII-"),_T("KANNADA"),0,57008},
+ {_T("ISCII-"),_T("MALAYALAM"),0,57009},
+ {_T("ISCII-"),_T("GUJARATI"),0,57010},
+ {_T("ISCII-"),_T("PUNJABI"),0,57011},
+ {_T("KOR-"),_T("JOHAB"),0,1361},
+ {_T("KSC-"),_T("5601"),0,1361},
+ {_T("MAC-"),_T("ROMAN"),0,10000},
+ {_T("MAC-"),_T("JP"),0,10001},
+ {_T("MAC-"),_T("CH(SP)(BIG5)"),0,10002},
+ {_T("MAC-"),_T("KR"),0,10003},
+ {_T("MAC-"),_T("AR"),0,10004},
+ {_T("MAC-"),_T("HW"),0,10005},
+ {_T("MAC-"),_T("GR"),0,10006},
+ {_T("MAC-"),_T("CY"),0,10007},
+ {_T("MAC-"),_T("CH(SP)(GB2312)"),0,10008},
+ {_T("MAC-"),_T("ROMANIA"),0,10010},
+ {_T("MAC-"),_T("UA"),0,10017},
+ {_T("MAC-"),_T("TH"),0,10021},
+ {_T("MAC-"),_T("LAT2"),0,10029},
+ {_T("MAC-"),_T("ICE"),0,10079},
+ {_T("MAC-"),_T("TR"),0,10081},
+ {_T("MAC-"),_T("CR"),0,10082},
+};
+
+int CPLENALL = (sizeof(CodePageNamesAll)/sizeof(CodePageNamesAll[0]));
+struct _tcptable *CodePageNamesSupp;
+int CPLENSUPP = 1;
+
+//Gets codepage ID from string representing charset such as "iso-8859-1"
+// input- the string
+// size- max length of input string
+int GetCharsetFromString(char *input,size_t size);
+
+//HexValue to DecValue ('a' to 10)
+// HexValue- hexa value ('a')
+// DecValue- poiner where to store dec value
+// returns 0 if not success
+int FromHexa(char HexValue,char *DecValue);
+
+//Decodes a char from Base64
+// Base64Value- input char in Base64
+// DecValue- pointer where to store the result
+// returns 0 if not success
+int FromBase64(char Base64Value,char *DecValue);
+
+//Decodes string in quoted printable
+// Src- input string
+// Dst- where to store output string
+// DstLen- how max long should be output string
+// isQ- if is "Q-encoding" modification. should be TRUE in headers
+// always returns 1
+int DecodeQuotedPrintable(char *Src,char *Dst,int DstLen, BOOL isQ);
+
+//Decodes string in base64
+// Src- input string
+// Dst- where to store output string
+// DstLen- how max long should be output string
+// returns 0 if string was not properly decoded
+int DecodeBase64(char *Src,char *Dst,int DstLen);
+
+//Converts string to unicode from string with specified codepage
+// stream- input string
+// cp- codepage of input string
+// out- pointer to new allocated memory that contains unicode string
+int ConvertStringToUnicode(char *stream,unsigned int cp,WCHAR **out);
+
+//Converts string from MIME header to unicode
+// stream- input string
+// cp- codepage of input string
+// storeto- pointer to memory that contains unicode string
+// mode- MIME_PLAIN or MIME_MAIL (MIME_MAIL deletes '"' from start and end of string)
+void ConvertCodedStringToUnicode(char *stream,WCHAR **storeto,DWORD cp,int mode);
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+int GetCharsetFromString(char *input,size_t size)
+//"ISO-8859-1" to ID from table
+{
+ char *pin=input;
+ char *pout,*parser;
+
+ if((size<1) || (parser=pout=new char[size+1])==NULL)
+ return -1;
+ while((*pin!=0) && (pin-input< (INT_PTR)size))
+ {
+ if ((*pin>='a') && (*pin<='z'))
+ *parser++=*(pin++)-('a'-'A'); // make it capital
+ //else if(*pin=='\"') // this is already done in ExtractFromContentType
+ // *pin++; //skip the quotes if any
+ else
+ *parser++=*pin++;
+ }
+
+ *parser=(char)0;
+
+#ifdef DEBUG_DECODECODEPAGE
+ DebugLog(DecodeFile,"<CodePage>%s</CodePage>",pout);
+#endif
+ for(int i=0;i<CPLENALL;i++){
+ size_t len = strlen(CodePageNamesAll[i].NameBase);
+ if(0==strncmp(pout,CodePageNamesAll[i].NameBase,len)){
+ if (0==strcmp(pout+len,CodePageNamesAll[i].NameSub)){
+ delete[] pout;
+ return CodePageNamesAll[i].CP;
+ }
+ }
+ }
+ delete[] pout;
+ return -1; //not found
+}
+
+int FromHexa(char HexValue,char *DecValue)
+{
+ if(HexValue>='0' && HexValue<='9')
+ {
+ *DecValue=HexValue-'0';
+ return 1;
+ }
+ if(HexValue>='A' && HexValue<='F')
+ {
+ *DecValue=HexValue-'A'+10;
+ return 1;
+ }
+ if(HexValue>='a' && HexValue<='f')
+ {
+ *DecValue=HexValue-'a'+10;
+ return 1;
+ }
+ return 0;
+}
+
+int FromBase64(char Base64Value,char *DecValue)
+{
+ if(Base64Value>='A' && Base64Value<='Z')
+ {
+ *DecValue=Base64Value-'A';
+ return 1;
+ }
+ if(Base64Value>='a' && Base64Value<='z')
+ {
+ *DecValue=Base64Value-'a'+26;
+ return 1;
+ }
+ if(Base64Value>='0' && Base64Value<='9')
+ {
+ *DecValue=Base64Value-'0'+52;
+ return 1;
+ }
+ if(Base64Value=='+')
+ {
+ *DecValue=Base64Value-'+'+62;
+ return 1;
+ }
+ if(Base64Value=='/')
+ {
+ *DecValue=Base64Value-'/'+63;
+ return 1;
+ }
+ if(Base64Value=='=')
+ {
+ *DecValue=0;
+ return 1;
+ }
+ return 0;
+}
+
+int DecodeQuotedPrintable(char *Src,char *Dst,int DstLen, BOOL isQ)
+{
+#ifdef DEBUG_DECODEQUOTED
+ char *DstTemp=Dst;
+ DebugLog(DecodeFile,"<Decode Quoted><Input>%s</Input>",Src);
+#endif
+ for(int Counter=0;((char)*Src!=0) && DstLen && (Counter++<DstLen);Src++,Dst++)
+ if(*Src=='=')
+ {
+ if (!isQ){
+ if (Src[1]==0x0D){
+ Src++; Src++;
+ if (Src[0]==0x0A) Src++;
+ goto CopyCharQuotedPrintable;
+ }
+ if (Src[1]==0x0A){
+ Src++; Src++;
+ goto CopyCharQuotedPrintable;
+ }
+ }
+ char First,Second;
+ if(!FromHexa(*(++Src),&First))
+ {
+ *Dst++='=';Src--;
+ continue;
+ }
+ if(!FromHexa(*(++Src),&Second))
+ {
+ *Dst++='=';Src--;Src--;
+ continue;
+ }
+ *Dst=(char)(First)<<4;
+ *Dst+=Second;
+ }
+ else if(isQ && *Src=='_')
+ *Dst=' ';
+ else
+CopyCharQuotedPrintable: // Yeah. Bad programming stile.
+ *Dst=*Src;
+ *Dst=(char)0;
+#ifdef DEBUG_DECODEQUOTED
+ DebugLog(DecodeFile,"<Output>%s</Output></Decode Quoted>",DstTemp);
+#endif
+ return 1;
+}
+
+int DecodeBase64(char *Src,char *Dst,int DstLen)
+{
+ int Result=0;
+ char Locator=0,MiniResult[4];
+ char *End=Dst+DstLen;
+
+ MiniResult[0]=MiniResult[1]=MiniResult[2]=MiniResult[3]=0;
+
+#ifdef DEBUG_DECODEBASE64
+ char *DstTemp=Dst;
+ DebugLog(DecodeFile,"<Decode Base64><Input>\n%s\n</Input>\n",Src);
+#endif
+ while(*Src!=0 && DstLen && Dst!=End)
+ {
+ if ((*Src==0x0D)||(*Src==0x0A)) {
+ Src++;
+ continue;
+ }
+ if((!(Result=FromBase64(*Src,MiniResult+Locator)) && (*Src==0)) || Locator++==3) //end_of_str || end_of_4_bytes
+ {
+ Locator=0; //next write to the first byte
+ *Dst++=(char)((MiniResult[0]<<2) | (MiniResult[1]>>4));
+ if(Dst==End) goto end; //DstLen exceeded?
+ *Dst++=(char)((MiniResult[1]<<4) | (MiniResult[2]>>2));
+ if(Dst==End) goto end; //someones don't like goto, but not me
+ *Dst++=(char)((MiniResult[2]<<6) | MiniResult[3]);
+ if(!Result && (*Src==0)) goto end; //end of string?
+ MiniResult[0]=MiniResult[1]=MiniResult[2]=MiniResult[3]=0; //zero 4byte buffer for next loop
+ }
+ if(!Result) return 0; //unrecognised character occured
+ Src++;
+ }
+end:
+ *Dst=0;
+#ifdef DEBUG_DECODEBASE64
+ DebugLog(DecodeFile,"<Output>\n%s\n</Output></Decode Base64>",DstTemp);
+#endif
+ return 1;
+}
+
+
+
+int ConvertStringToUnicode(char *stream,unsigned int cp,WCHAR **out)
+{
+ CPINFO CPInfo;
+ WCHAR *temp,*src=*out,*dest;
+ size_t outlen;
+ int streamlen,Index;
+
+ //codepages, which require to have set 0 in dwFlags parameter when calling MultiByteToWideChar
+ DWORD CodePagesZeroFlags[]={50220,50221,50222,50225,50227,50229,52936,54936,57002,57003,57004,57005,57006,57007,57008,57009,57010,57011,65000,65001};
+
+ if((cp!=CP_ACP) && (cp!=CP_OEMCP) && (cp!=CP_MACCP) && (cp!=CP_THREAD_ACP) && (cp!=CP_SYMBOL) && (cp!=CP_UTF7) && (cp!=CP_UTF8) && !GetCPInfo(cp,&CPInfo))
+ cp=CP_ACP;
+#ifdef DEBUG_DECODECODEPAGE
+ DebugLog(DecodeFile,"<CodePage #>%d</CodePage #>",cp);
+#endif
+
+ for(Index=0;Index<sizeof(CodePagesZeroFlags)/sizeof(CodePagesZeroFlags[0]);Index++)
+ if(CodePagesZeroFlags[Index]==cp)
+ {
+ Index=-1;
+ break;
+ }
+ if(Index==-1)
+ streamlen=MultiByteToWideChar(cp,0,stream,-1,NULL,0);
+ else
+ streamlen=MultiByteToWideChar(cp,MB_USEGLYPHCHARS,stream,-1,NULL,0);
+
+ if(*out!=NULL)
+ outlen=wcslen(*out);
+ else
+ outlen=0;
+ temp=new WCHAR[streamlen+outlen+1];
+
+ if(*out!=NULL)
+ {
+ for(dest=temp;*src!=(WCHAR)0;src++,dest++) //copy old string from *out to temp
+ *dest=*src;
+// *dest++=L' '; //add space?
+ delete[] *out;
+ }
+ else
+ dest=temp;
+ *out=temp;
+
+ if(Index==-1)
+ {
+ if(!MultiByteToWideChar(cp,0,stream,-1,dest,streamlen))
+ return 0;
+ }
+ else
+ {
+ if(!MultiByteToWideChar(cp,MB_USEGLYPHCHARS,stream,-1,dest,streamlen))
+ return 0;
+ }
+ return 1;
+}
+
+void ConvertCodedStringToUnicode(char *stream,WCHAR **storeto,DWORD cp,int mode)
+{
+ char *start=stream,*finder,*finderend;
+ char Encoding=0;
+ char *DecodedResult=NULL;
+
+ if(stream==NULL)
+ return;
+
+ while(WS(start)) start++;
+ WCHAR *tempstore=0;
+ if(!ConvertStringToUnicode(stream,cp,&tempstore))return;
+
+ size_t tempstoreLength = wcslen(tempstore);
+
+ size_t outind = 0;
+ while(*start!=0){
+ if(CODES(start)){
+ finder=start+2;finderend=finder;
+ while(!CODED(finderend) && !EOS(finderend)) finderend++;
+ start = finderend;
+ if(CODED(finderend))
+ {
+ Encoding=*(finderend+1);
+ switch(Encoding)
+ {
+ case 'b':
+ case 'B':
+ case 'q':
+ case 'Q':
+ break;
+ default:
+ goto NotEncoded;
+ }
+ if(-1==(cp=(DWORD)GetCharsetFromString(finder,finderend-finder)))
+ cp=CP_ACP;
+ if(Encoding!=0)
+ {
+ int size,codeend;
+ char *pcodeend;
+
+ finder=finderend+2;
+ if(CODED(finder))
+ finder++;
+ while(WS(finder)) finder++;
+ finderend=finder;
+ while(!CODEE(finderend) && !EOS(finderend)) finderend++;
+ if(codeend=CODEE(finderend))
+ pcodeend=finderend;
+ while(WS(finderend-1)) finderend--;
+ if((mode==MIME_MAIL) && (((*finder=='"') && (*(finderend-1)=='"'))))
+ {
+ finder++;
+ finderend--;
+ }
+ //*finderend=(char)0;
+ char * oneWordEncoded = new char[finderend-finder+1];
+ strncpy(oneWordEncoded,finder,finderend-finder);
+ oneWordEncoded[finderend-finder]=0;
+ switch(Encoding)
+ {
+ case 'b':
+ case 'B':
+ size=(finderend-finder)*3/4+3+1+1;
+ break;
+ case 'q':
+ case 'Q':
+ size=finderend-finder+1+1;
+ break;
+ }
+ if(DecodedResult!=NULL)
+ delete[] DecodedResult;
+ DecodedResult=new char[size+1];
+ switch(Encoding)
+ {
+ case 'q':
+ case 'Q':
+ DecodeQuotedPrintable(oneWordEncoded,DecodedResult,size, TRUE);
+ break;
+ case 'b':
+ case 'B':
+ DecodeBase64(oneWordEncoded,DecodedResult,size);
+ break;
+ }
+ delete[] oneWordEncoded;
+ if(codeend)
+ finderend=pcodeend+2;
+ if(WS(finderend)) //if string continues and there's some whitespace, add space to string that is to be converted
+ {
+ size_t len=strlen(DecodedResult);
+ DecodedResult[len]=' ';
+ DecodedResult[len+1]=0;
+ finderend++;
+ }
+ WCHAR *oneWord=0;
+ if(ConvertStringToUnicode(DecodedResult,cp,&oneWord)){
+ size_t len = wcslen(oneWord);
+ memcpy(&tempstore[outind],oneWord,len*sizeof(WCHAR));
+ outind += len;
+ }
+ delete oneWord;
+ oneWord = 0;
+ delete[] DecodedResult; DecodedResult = 0;
+ start = finderend;
+ } else if (!EOS(start)) start++;
+ } else if (!EOS(start)) start++;
+ }else{
+NotEncoded:
+ tempstore[outind] = tempstore[start-stream];
+ outind++;
+ if (outind > tempstoreLength) break;
+ start++;
+ }
+ }
+ tempstore[outind] = 0;
+ *storeto = tempstore;
+}
diff --git a/yamn/mails/m_decode.h b/yamn/mails/m_decode.h new file mode 100644 index 0000000..e6d2b52 --- /dev/null +++ b/yamn/mails/m_decode.h @@ -0,0 +1,25 @@ +#ifndef __DECODE_H
+#define __DECODE_H
+
+#include "../debug.h"
+
+#define DOTLINE(s) ((((s)[-2]=='\r') || ((s)[-2]=='\n')) && ((s)[-1]=='.') && (((s)[0]=='\r') || ((s)[0]=='\n') || ((s)[0]=='\0'))) // be careful, it's different to ESR's pop3.c ;-)
+#define ENDLINE(s) (((s)[0]=='\r') || ((s)[0]=='\n')) //endline
+#define WS(s) (((s)[0]==' ') || ((s)[0]=='\t')) //whitespace
+#define ENDLINEWS(s) ((((s)[0]=='\r') || ((s)[0]=='\n')) && (((((s)[1]=='\r') || ((s)[1]=='\n')) && (((s)[2]==' ') || ((s)[2]=='\t'))) || (((s)[1]==' ') || ((s)[1]=='\t')))) //endline+whitespace: enters(CR or LF and their combinations) followed by space or tab
+#define EOS(s) ((s)[0]==0) //end of string (stream)
+
+#define CODES(s) ((s[0]=='=') && (s[1]=='?')) //start of coded string
+#define CODEE(s) ((s[0]=='?') && (s[1]=='=')) //end of coded string
+#define CODED(s) (s[0]=='?') //code delimiter
+
+#define MIME_PLAIN 1
+#define MIME_MAIL 2
+
+struct cptable
+{
+ char *name;
+ unsigned int ID;
+};
+
+#endif
diff --git a/yamn/mails/m_mails.h b/yamn/mails/m_mails.h new file mode 100644 index 0000000..e1826a1 --- /dev/null +++ b/yamn/mails/m_mails.h @@ -0,0 +1,285 @@ +#ifndef __MAILS_H
+#define __MAILS_H
+
+#include <windows.h>
+#include <tchar.h>
+#include "../m_account.h"
+
+//
+//================================== OTHER DEFINITIONS ========================================
+//
+
+typedef struct CShortNames
+{
+ char *Value;
+ char *ValueNick;
+ struct CShortNames *Next;
+} YAMN_MIMESHORTNAMES,*PYAMN_MIMESHORTNAMES;
+
+typedef struct CNames
+{
+ WCHAR *Value;
+ WCHAR *ValueNick;
+ struct CNames *Next;
+} YAMN_MIMENAMES,*PYAMN_MIMENAMES;
+
+struct CShortHeader
+//this header is used in to get non-unicode data from mime header
+{
+ char *From;
+ char *FromNick;
+ char *ReturnPath;
+ char *ReturnPathNick;
+ char *Subject;
+ PYAMN_MIMESHORTNAMES To;
+ PYAMN_MIMESHORTNAMES Cc;
+ PYAMN_MIMESHORTNAMES Bcc;
+ char *Date;
+ char Priority;
+ char *Body;
+
+ int CP;
+
+ CShortHeader() {}
+ ~CShortHeader() {}
+};
+
+struct CHeader
+//this header is used in miranda to store final results of mime reading in Unicode
+{
+ WCHAR *From;
+ WCHAR *FromNick;
+ WCHAR *ReturnPath;
+ WCHAR *ReturnPathNick;
+ WCHAR *Subject;
+ PYAMN_MIMENAMES To;
+ PYAMN_MIMENAMES Cc;
+ PYAMN_MIMENAMES Bcc;
+ WCHAR *Date;
+ TCHAR Priority;
+ WCHAR *Body;
+
+ CHeader() {}
+ ~CHeader() {}
+};
+
+struct CMimeItem
+{
+ char *name;
+ char *value;
+ struct CMimeItem *Next;
+ CMimeItem(): name(NULL), value(NULL), Next(NULL){}
+};
+
+typedef struct CMailData //this is plugin-independent
+{
+#define YAMN_MAILDATAVERSION 3
+
+ DWORD Size;
+ int CP;
+
+ struct CMimeItem *TranslatedHeader; //MIME items
+ struct CMimeItem *Additional; //MIME items not read from server (custom, for filter plugins etc.)
+ char *Body; //Message body
+
+ CMailData(): CP(-1), Size(0), TranslatedHeader(NULL), Body(NULL){}
+} MAILDATA,*PMAILDATA;
+
+typedef struct CMimeMsgQueue
+{
+#define YAMN_MAILVERSION 3
+ char *ID; //The ID of mail. This ID identifies every mail in the account, so plugin should set it
+
+ DWORD Number;
+
+#define YAMN_MSG_ANY 0xffffffff //any mail
+
+//The difference between new and unseen: when new mail is found in account, it becomes unseen and new. But in the next check, if the same mail is found, it is not new.
+//However, when user was not near computer, he does not know about this mail- it is unseen. After user accepts, that he saw new mails, it becomes seen.
+#define YAMN_MSG_NEW 0x80000000 //this mail is new
+#define YAMN_MSG_UNSEEN 0x40000000 //this mail is mailbrowser unseen
+#define YAMN_MSG_DISPLAY 0x20000000 //this mail can be displayed in mailbrowser
+#define YAMN_MSG_POPUP 0x10000000 //this mail can be displayed in popup and can invoke a popup
+#define YAMN_MSG_SYSTRAY 0x08000000 //this mail can invoke systray icon
+#define YAMN_MSG_BROWSER 0x04000000 //this mail can run mailbrowser
+#define YAMN_MSG_DISPLAYC 0x02000000 //this mail is inserted to browser mail counter system (the "Account - xx new mails, yy total" phrase)
+#define YAMN_MSG_POPUPC 0x01000000 //this mail is inserted to popup counter system (the "Account - xx new mails, yy total" phrase)
+
+#define YAMN_MSG_SOUND 0x00800000 //this mail can "play sound"
+#define YAMN_MSG_APP 0x00400000 //this mail can "launch application"
+#define YAMN_MSG_NEVENT 0x00100000 //this mail can launch Miranda "new mail" event
+
+#define YAMN_MSG_VIRTUAL 0x00080000 //this mail is not real- does not exists
+
+#define YAMN_MSG_FILTERED 0x00040000 //this mail has been filtered
+
+#define YAMN_MSG_DELETETRASH 0x00020000 //this mail should be moved to the trash bin rather than really deleting from mailbox (this is only switch doing nothing, perhaps usefull for filter plugins)
+#define YAMN_MSG_DELETED 0x00010000 //this mail is already deleted from server (also must be set virtual flag) (when doing synchronizations between 2 queues, YAMN then does not touch this mail)
+#define YAMN_MSG_MEMDELETE 0x00008000 //this mail will be deleted immidiatelly from memory (and disk) when deleted from server (some opposite of YAMN_MSG_DELETED)
+#define YAMN_MSG_USERDELETE 0x00004000 //this mail is about to delete from server (user deletes manually)
+#define YAMN_MSG_AUTODELETE 0x00002000 //this mail is about to delete from server (plugin marks it for deleting)
+#define YAMN_MSG_DELETEOK 0x00001000 //this mail is confirmed to delete (this flag must be set to delete this mail)
+
+#define YAMN_MSG_BODYREQUESTED 0x00000800 //user requested (part of) the body. In POP3 it should be (TOP <nr> <lines>)
+#define YAMN_MSG_BODYRECEIVED 0x00000200 //(part of) the body.received;
+#define YAMN_MSG_STAYUNSEEN 0x00000400 //this mail stays unseen while user does not really see it
+
+#define YAMN_MSG_DELETE (YAMN_MSG_USERDELETE | YAMN_MSG_AUTODELETE)
+
+#define YAMN_MSG_NORMALNEW (YAMN_MSG_NEW | YAMN_MSG_UNSEEN | YAMN_MSG_BROWSER | YAMN_MSG_DISPLAY | YAMN_MSG_DISPLAYC | YAMN_MSG_POPUP | YAMN_MSG_POPUPC | YAMN_MSG_SYSTRAY | YAMN_MSG_SOUND | YAMN_MSG_APP | YAMN_MSG_NEVENT | YAMN_MSG_MEMDELETE | YAMN_MSG_STAYUNSEEN)
+
+#define YAMN_MSG_FLAGSSET(maildata,flag) ((maildata & flag)==flag)
+
+#define YAMN_MSG_SPAML1 1 //spam level 1: notify, show in another color in mail browser
+#define YAMN_MSG_SPAML2 2 //spam level 2: do not notify, show in another color in mail browser
+#define YAMN_MSG_SPAML3 3 //spam level 3: delete, show in another color in mail browser that it was deleted, you do not need to set YAMN_MSG_AUTODELETE
+#define YAMN_MSG_SPAML4 4 //spam level 4: delete, do not show, you do not need to set YAMN_MSG_AUTODELETE
+#define YAMN_MSG_SPAMMASK 0x0000000F
+
+#define YAMN_MSG_SPAML(maildata,level) ((maildata & YAMN_MSG_SPAMMASK)==level)
+ DWORD Flags;
+//Plugins can read mail data, but it can be NULL!!! So plugin should use Load and Save services to load or save data and Unload to release data from memory
+ PMAILDATA MailData;
+//Here YAMN stores its own informations about this mail. Not usefull for plugins...
+// void *YAMNData;
+ HWND MsgWindow;
+//plugins can store here its own data
+ void *PluginData;
+
+ CMimeMsgQueue(): ID(NULL), Number(0), Flags(0), MailData(NULL), MsgWindow(NULL), PluginData(NULL), Next(NULL){}
+ ~CMimeMsgQueue(){}
+
+ struct CMimeMsgQueue *Next;
+} YAMNMAIL,*HYAMNMAIL;
+
+#define LoadedMailData(x) (x->MailData!=NULL)
+
+//
+//================================== YAMN MAIL SERVICES ==================================
+//
+
+//CreateAccountMail Service
+//Your plugin should call this to create new mail for your plugin.
+//WPARAM- (HACCOUNT) Account handle
+//LPARAM- CMailData version (use YAMN_MAILVERSION definition)
+//returns pointer to (HYAMNMAIL) or pointer to your structure returned from imported NewMailFcnPtr, if implemented
+#define MS_YAMN_CREATEACCOUNTMAIL "YAMN/Service/CreateMail"
+#define CreateAccountMail(x) (HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL,(WPARAM)x,(LPARAM)YAMN_MAILVERSION)
+
+//DeleteAccountMail Service
+//Deletes plugin's mail from memory. You probably won't use this service, because it deletes only account
+//without any synchronization. Use MS_YAMN_DELETEACCOUNT instead. Note that deleting mail is something like "this mail is
+//not more in the account".
+//WPARAM- (HYAMNPROTOPLUGIN) handle of plugin, which is going to delete mail
+//LPARAM- (HYAMNMAIL) mail going to delete
+//returns zero if failed, otherwise returns nonzero
+#define MS_YAMN_DELETEACCOUNTMAIL "YAMN/Service/DeletePluginMail"
+#define DeleteAccountMail(x,y) CallService(MS_YAMN_DELETEACCOUNTMAIL,(WPARAM)x,(LPARAM)y)
+
+//LoadMailData Service
+//This service loads mail from standard YAMN storage (now it is 1 file, from which mails are loaded once at startup, but
+//in the future it can be Miranda profile file or separate file (1 file per 1 mail). It depends on YAMN implementation...
+//Use this function if you want to read or write to MailData member of mail structure. Please use synchronization obejcts
+//before calling this service (so you must have read or write access to mails)
+//WPARAM- (HYAMNMAIL) mail where to load data
+//LPARAM- (DWORD) version of MAILDATA structure (use YAMN_MAILDATAVERSION definition)
+//returns pointer to new allocated MailData structure (the same value as MailData member)
+#define MS_YAMN_LOADMAILDATA "YAMN/Service/LoadMailData"
+#define LoadMailData(x) (PMAILDATA)CallService(MS_YAMN_LOADMAILDATA,(WPARAM)x,(LPARAM)YAMN_MAILDATAVERSION)
+
+//UnloadMailData Service
+//This service frees mail data from memory. It does not care if data were saved or not. So you should save mail before you
+//release data from memory.
+//WPARAM- (HYAMNMAIL) mail whose data are about to free
+//LPARAM- nothing yet
+//returns nonzero if success
+#define MS_YAMN_UNLOADMAILDATA "YAMN/Service/UnloadMailData"
+#define UnloadMailData(x) CallService(MS_YAMN_UNLOADMAILDATA,(WPARAM)x,(LPARAM)0)
+
+//SaveMailData Service
+//This service saves mail to standard YAMN storage (when using now 1 book file, it does nothing, because save is done when
+//using MS_YAMN_WRITEACCOUNT service. In the future, mail can be saved to Miranda profile or to separate file...)
+//WPARAM- (HYAMNMAIL) mail to save
+//LPARAM- (DWORD) version of MAILDATA structure (use YAMN_MAILDATAVERSION definition)
+//returns ZERO! if succes
+#define MS_YAMN_SAVEMAILDATA "YAMN/Service/SaveMailData"
+#define SaveMailData(x) CallService(MS_YAMN_SAVEMAILDATA,(WPARAM)x,(LPARAM)YAMN_MAILDATAVERSION)
+
+//
+//================================== FUNCTIONS DEFINITIONS ========================================
+//
+
+//typedef void (WINAPI *YAMN_SENDMESSAGEFCN)(UINT,WPARAM,LPARAM);
+typedef void (WINAPI *YAMN_SYNCHROMIMEMSGSFCN)(HACCOUNT,HYAMNMAIL *,HYAMNMAIL *,HYAMNMAIL *,HYAMNMAIL *);
+typedef void (WINAPI *YAMN_TRANSLATEHEADERFCN)(char *,int,struct CMimeItem **);
+typedef void (WINAPI *YAMN_APPENDQUEUEFCN)(HYAMNMAIL,HYAMNMAIL);
+typedef void (WINAPI *YAMN_DELETEMIMEQUEUEFCN)(HACCOUNT,HYAMNMAIL);
+typedef void (WINAPI *YAMN_DELETEMIMEMESSAGEFCN)(HYAMNMAIL *,HYAMNMAIL,int);
+typedef HYAMNMAIL (WINAPI *YAMN_FINDMIMEMESSAGEFCN)(HYAMNMAIL,char *);
+typedef HYAMNMAIL (WINAPI *YAMN_CREATENEWDELETEQUEUEFCN)(HYAMNMAIL);
+typedef void (WINAPI *YAMN_SETREMOVEQUEUEFLAGSFCN)(HYAMNMAIL,DWORD,DWORD,DWORD,int);
+
+//
+//================================== QUICK FUNCTION CALL DEFINITIONS ========================================
+//
+
+//These are defininitions for YAMN exported functions. Your plugin can use them.
+//pYAMNFcn is global variable, it is pointer to your structure containing YAMN functions.
+//It is something similar like pluginLink variable in Miranda plugin. If you use
+//this name of variable, you have already defined these functions and you can use them.
+//It's similar to Miranda's CreateService function.
+
+//How to use YAMN functions:
+//Create a structure containing pointer to functions you want to use in your plugin
+//This structure can look something like this:
+//
+// struct
+// {
+// YAMN_SYNCHROMIMEMSGSFCN SynchroMessagesFcn;
+// YAMN_APPENDQUEUEFCN AppendQueueFcn;
+// } *pYAMNMailFcn;
+//
+//then you have to fill this structure with pointers...
+//you have to use YAMN service to get pointer, like this (I wrote here all functions you may need,
+//you can copy to your sources only those you need):
+//
+// pYAMNMailFcn->SynchroMessagesFcn=(YAMN_SYNCHROMIMEMSGSFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SYNCHROMIMEMSGSID,(LPARAM)0);
+// pYAMNMailFcn->TranslateHeaderFcn=(YAMN_TRANSLATEHEADERFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_TRANSLATEHEADERID,(LPARAM)0);
+// pYAMNMailFcn->AppendQueueFcn=(YAMN_APPENDQUEUEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_APPENDQUEUEID,(LPARAM)0);
+// pYAMNMailFcn->DeleteMessagesToEndFcn=(YAMN_DELETEMIMEQUEUEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_DELETEMIMEQUEUEID,(LPARAM)0);
+// pYAMNMailFcn->DeleteMessageFromQueueFcn=(YAMN_DELETEMIMEMESSAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_DELETEMIMEMESSAGEID,(LPARAM)0);
+// pYAMNMailFcn->FindMessageByIDFcn=(YAMN_FINDMIMEMESSAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_FINDMIMEMESSAGEID,(LPARAM)0);
+// pYAMNMailFcn->CreateNewDeleteQueueFcn=(YAMN_CREATENEWDELETEQUEUEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_CREATENEWDELETEQUEUEID,(LPARAM)0);
+// pYAMNMailFcn->SetRemoveQueueFlagsFcn=(YAMN_SETREMOVEQUEUEFLAGSFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SETREMOVEQUEUEFLAGSID,(LPARAM)0);
+//
+//
+//and in your plugin just simply use e.g.:
+//
+// DeleteMIMEQueue(MyAccount,OldMessages); //this command deletes all messages in the mail queue OldMessages
+//
+
+#define YAMN_SYNCHROMIMEMSGSID "YAMN/SynchroMessages"
+#define YAMN_TRANSLATEHEADERID "YAMN/TranslateHeader"
+#define YAMN_APPENDQUEUEID "YAMN/AppendQueue"
+#define YAMN_DELETEMIMEQUEUEID "YAMN/DeleteMIMEQueue"
+#define YAMN_DELETEMIMEMESSAGEID "YAMN/DeleteMIMEMessage"
+#define YAMN_FINDMIMEMESSAGEID "YAMN/FindMIMEMessageByID"
+#define YAMN_CREATENEWDELETEQUEUEID "YAMN/CreateNewDeleteQueue"
+#define YAMN_SETREMOVEQUEUEFLAGSID "YAMN/SetRemoveQueueFlags"
+
+#define YAMN_FLAG_REMOVE 0
+#define YAMN_FLAG_SET 1
+
+
+#define SynchroMessages(a,b,c,d,e) pYAMNMailFcn->SynchroMessagesFcn(a,b,c,d,e)
+#define TranslateHeader(a,b,c) pYAMNMailFcn->TranslateHeaderFcn(a,b,c)
+#define AppendQueue(x,y) pYAMNMailFcn->AppendQueueFcn(x,y)
+#define DeleteMIMEQueue(x,y) pYAMNMailFcn->DeleteMessagesToEndFcn(x,y)
+#define DeleteMIMEMessage(x,y) pYAMNMailFcn->DeleteMessageFromQueueFcn(x,y,0)
+#define DeleteMIMEMessageEx(x,y,z) pYAMNMailFcn->DeleteMessageFromQueueFcn(x,y,z)
+#define FindMIMEMessageByID(x,y) pYAMNMailFcn->FindMessageByIDFcn(x,y)
+#define CreateNewDeleteQueue(x) pYAMNMailFcn->CreateNewDeleteQueueFcn(x)
+#define SetQueueFlags(a,b,c,d) pYAMNMailFcn->SetRemoveQueueFlagsFcn(a,b,c,d,1)
+#define RemoveQueueFlags(a,b,c,d) pYAMNMailFcn->SetRemoveQueueFlagsFcn(a,b,c,d,0)
+
+#endif
diff --git a/yamn/mails/mails.cpp b/yamn/mails/mails.cpp new file mode 100644 index 0000000..b99a9fd --- /dev/null +++ b/yamn/mails/mails.cpp @@ -0,0 +1,499 @@ +/*
+ * This code implements retrieving info from MIME header
+ *
+ * (c) majvan 2002-2004
+ */
+
+#pragma warning( disable : 4290 )
+#include "../yamn.h"
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+// SMALL INTRO
+// Mails are queued in a queue (chained list). Pointer to first mail is pointed from Account structure
+// member called Mails.
+// Mail queue is ended with NULL- pointered mail (NULL handle)
+
+//Creates new mail for plugin (calling plugin's constructor, when plugin imported to YAMN)
+INT_PTR CreateAccountMailSvc(WPARAM wParam,LPARAM lParam);
+
+//Deletes mail for plugin (calling plugin's destructor, when plugin imported to YAMN)
+INT_PTR DeleteAccountMailSvc(WPARAM wParam,LPARAM lParam);
+
+//Loads mail data from standard storage to memory
+INT_PTR LoadMailDataSvc(WPARAM wParam,LPARAM lParam);
+
+//Deletes mail data from memory
+INT_PTR UnloadMailDataSvc(WPARAM wParam,LPARAM);
+
+//Saves mail data from memory to standard storage
+INT_PTR SaveMailDataSvc(WPARAM wParam,LPARAM lParam);
+
+//Appends second MIME mail queue to the first one
+//Only finds the end of first queue and its Next memember repoints to second one
+void WINAPI AppendQueueFcn(HYAMNMAIL first,HYAMNMAIL second);
+
+//Synchronizes two accounts
+//Function finds, if there were some mails deleted from mailbox and deletes (depends on RemovedOld param) them from OldQueue
+//Next finds, if there are new mails. Mails that are still on mailbox are deleted (depends on RemovedNew param) from NewQueue
+//After this, OldQueue is pointer to mails that are on mailbox, but not new mails
+//and NewQueue contains new mails in account
+//New accounts can be then appended to account mails queue, but they have set the New flag
+//
+//Two mails equals if they have the same ID
+//
+// hPlugin- handle of plugin going to delete mails
+// OldQueue- queue of mails that we found on mailbox last time, after function finishes queue contains all mails except new ones
+// RemovedOld- queue of mails where to store removed mails from OldQueue, if NULL deletes mails from OldQueue
+// NewQueue- queue of mails that we found on mailbox (all mails), after function finishes queue contains only new mails
+// RemovedNew- queue of mails where to store removed mails from NewQueue, if NULL deletes mails from NewQueue
+//So function works like:
+//1. delete (or move to RemovedOld queue if RemovedOld is not NULL) all mails from OldQueue not found in NewQueue
+//2. delete (or move to RemovedNew queue if RemovedNew is not NULL) all mails from NewQueue found in OldQueue
+void WINAPI SynchroMessagesFcn(HACCOUNT Account,HYAMNMAIL *OldQueue,HYAMNMAIL *RemovedOld,HYAMNMAIL *NewQueue,HYAMNMAIL *RemovedNew);
+
+//Deletes messages from mail From to the end
+// Account- account who owns mails
+// From- first mail in queue, which is going to delete
+void WINAPI DeleteMessagesToEndFcn(HACCOUNT Account,HYAMNMAIL From);
+
+//Removes message from queue, does not delete from memory
+// From- queue pointer
+// Which- mail to delete
+// mode- nonzero if you want to decrement numbers in messages that are bigger than the one in Which mail, 0 if not
+void WINAPI DeleteMessageFromQueueFcn(HYAMNMAIL *From,HYAMNMAIL Which,int mode);
+
+//Finds message in queue that has the same ID number
+// From- message queue
+// ID- pointer to ID
+// returns pointer to found message, NULL if not found
+HYAMNMAIL WINAPI FindMessageByIDFcn(HYAMNMAIL From,char *ID);
+
+//Translate header from text to queue of CMimeItem structures
+//This means that new queue will contain all info about headers
+// stream- pointer to text containing header (can be ended with zero)
+// len- length of stream
+// head- function fills this pointer to first header item in queue
+void WINAPI TranslateHeaderFcn(char *stream,int len,struct CMimeItem **head);
+
+//Creates new mail queue, copying only these mails, that have set flag for deleting
+// From- message queue, whose mail with given flag are duplicated
+// returns new mail queue (or NULL when no mail with flag is in From queue)
+//Function does not copy the whole mails, it copies only ID string. And ID is copied as string, so
+//you can use this fcn only if you have your ID as pointer to char string ended with zero character
+HYAMNMAIL WINAPI CreateNewDeleteQueueFcn(HYAMNMAIL From);
+
+//Sets/removes flags from specific mails
+// From- pointer to first message
+// FlagsSet- mail must have set these flags...
+// FlagsNotSet- ...and must not have set these flags...
+// FlagsToSetRemove- ...to set/remove these flags (see mode)
+// mode- nonzero to set, else remove
+void WINAPI SetRemoveFlagsInQueueFcn(HYAMNMAIL From,DWORD FlagsSet,DWORD FlagsNotSet,DWORD FlagsToSetRemove,int mode);
+
+struct CExportedFunctions MailExportedFcn[]=
+{
+ {YAMN_SYNCHROMIMEMSGSID,(void *)SynchroMessagesFcn},
+ {YAMN_TRANSLATEHEADERID,(void *)TranslateHeaderFcn},
+ {YAMN_APPENDQUEUEID,(void *)AppendQueueFcn},
+ {YAMN_DELETEMIMEQUEUEID,(void *)DeleteMessagesToEndFcn},
+ {YAMN_DELETEMIMEMESSAGEID,(void *)DeleteMessageFromQueueFcn},
+ {YAMN_FINDMIMEMESSAGEID,(void *)FindMessageByIDFcn},
+ {YAMN_CREATENEWDELETEQUEUEID,(void *)CreateNewDeleteQueueFcn},
+ {YAMN_SETREMOVEQUEUEFLAGSID,(void *)SetRemoveFlagsInQueueFcn},
+};
+
+struct CExportedServices MailExportedSvc[]=
+{
+ {MS_YAMN_CREATEACCOUNTMAIL,CreateAccountMailSvc},
+ {MS_YAMN_DELETEACCOUNTMAIL,DeleteAccountMailSvc},
+ {MS_YAMN_LOADMAILDATA,LoadMailDataSvc},
+ {MS_YAMN_UNLOADMAILDATA,UnloadMailDataSvc},
+ {MS_YAMN_SAVEMAILDATA,SaveMailDataSvc},
+};
+
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+INT_PTR CreateAccountMailSvc(WPARAM wParam,LPARAM lParam)
+{
+ HACCOUNT Account=(HACCOUNT)wParam;
+ DWORD MailVersion=(DWORD)lParam;
+ HYAMNMAIL NewMail;
+
+//test if we are going to initialize members of suitable structure (structures of plugin and YAMN must match)
+ if(MailVersion!=YAMN_MAILVERSION)
+ return NULL;
+
+ if(Account->Plugin!=NULL)
+ {
+ if(Account->Plugin->MailFcn->NewMailFcnPtr!=NULL)
+ {
+//Let plugin create its own structure, which can be derived from CAccount structure
+ if(NULL==(NewMail=Account->Plugin->MailFcn->NewMailFcnPtr(Account,YAMN_MAILVERSION)))
+ return NULL;
+ }
+ else
+ {
+//We suggest plugin uses standard CAccount structure, so we create it
+ if(NULL==(NewMail=new YAMNMAIL))
+//If not created successfully
+ return NULL;
+ NewMail->MailData=NULL;
+ }
+//Init every members of structure, used by YAMN
+ return (INT_PTR)NewMail;
+ }
+ return NULL;
+}
+
+INT_PTR DeleteAccountMailSvc(WPARAM wParam,LPARAM lParam)
+{
+ HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
+ HYAMNMAIL OldMail=(HYAMNMAIL)lParam;
+ struct CMimeItem *TH;
+
+ if(Plugin->MailFcn!=NULL){
+ if(Plugin->MailFcn->DeleteMailFcnPtr!=NULL) {
+ //Let plugin delete its own CMimeMsgQueue derived structure
+ Plugin->MailFcn->DeleteMailFcnPtr(OldMail);
+ return 1;
+ }
+ }
+ if(OldMail->MailData!=NULL) {
+ if(OldMail->MailData->Body!=NULL)
+ delete[] OldMail->MailData->Body;
+ if((TH=OldMail->MailData->TranslatedHeader)!=NULL)
+ for(;OldMail->MailData->TranslatedHeader!=NULL;) {
+ TH=TH->Next;
+ if(OldMail->MailData->TranslatedHeader->name!=NULL)
+ delete[] OldMail->MailData->TranslatedHeader->name;
+ if(OldMail->MailData->TranslatedHeader->value!=NULL)
+ delete[] OldMail->MailData->TranslatedHeader->value;
+ delete OldMail->MailData->TranslatedHeader;
+ OldMail->MailData->TranslatedHeader=TH;
+ }
+ delete OldMail->MailData;
+ }
+ if(OldMail->ID!=NULL)
+ delete[] OldMail->ID;
+
+ delete OldMail; //consider mail as standard HYAMNMAIL, not initialized before and use its own destructor
+ return 1;
+}
+
+
+void WINAPI AppendQueueFcn(HYAMNMAIL first,HYAMNMAIL second)
+{
+ HYAMNMAIL Finder=first;
+ while(Finder->Next!=NULL) Finder=Finder->Next;
+ Finder->Next=second;
+}
+
+INT_PTR LoadMailDataSvc(WPARAM wParam,LPARAM lParam)
+{
+ HYAMNMAIL Mail=(HYAMNMAIL)wParam;
+ DWORD MailVersion=(DWORD)lParam;
+
+ if(MailVersion!=YAMN_MAILDATAVERSION)
+ return NULL;
+
+//now we have all data to memory persisting, so no loading is needed
+ return (INT_PTR)Mail->MailData;
+}
+
+INT_PTR UnloadMailDataSvc(WPARAM wParam,LPARAM)
+{
+ HYAMNMAIL Mail=(HYAMNMAIL)wParam;
+
+//now we should delete structure from memory, but it will be made in future YAMN version
+ return 1;
+}
+
+INT_PTR SaveMailDataSvc(WPARAM wParam,LPARAM lParam)
+{
+ HYAMNMAIL Mail=(HYAMNMAIL)wParam;
+ DWORD MailVersion=(DWORD)lParam;
+
+ if(MailVersion!=YAMN_MAILDATAVERSION)
+ return (INT_PTR)-1;
+
+//now we have all data to memory persisting, so no saving is needed
+ return (INT_PTR)0;
+}
+
+void WINAPI SynchroMessagesFcn(HACCOUNT Account,HYAMNMAIL *OldQueue,HYAMNMAIL *RemovedOld,HYAMNMAIL *NewQueue,HYAMNMAIL *RemovedNew)
+//deletes messages from new queue, if they are old
+//it also deletes messages from old queue, if they are not in mailbox anymore
+//"YAMN_MSG_DELETED" messages in old queue remain in old queue (are never removed, although they are not in new queue)
+//"YAMN_MSG_DELETED" messages in new queue remain in new queue (are never removed, although they can be in old queue)
+{
+ HYAMNMAIL Finder,FinderPrev;
+ HYAMNMAIL Parser,ParserPrev;
+ HYAMNMAIL RemovedOldParser =NULL;
+ HYAMNMAIL RemovedNewParser =NULL;
+ if(RemovedOld!=NULL) *RemovedOld=NULL;
+ if(RemovedNew!=NULL) *RemovedNew=NULL;
+
+ for(FinderPrev=NULL,Finder=*OldQueue;Finder!=NULL;)
+ {
+ if(Finder->Flags & YAMN_MSG_DELETED) //if old queue contains deleted mail
+ {
+ FinderPrev=Finder;
+ Finder=Finder->Next; //get next message in old queue for testing
+ continue;
+ }
+ for(ParserPrev=NULL,Parser=*NewQueue;Parser!=NULL;ParserPrev=Parser,Parser=Parser->Next)
+ {
+ if(Parser->Flags & YAMN_MSG_DELETED)
+ continue;
+
+ if(Parser->ID==NULL) //simply ignore the message, that has not filled its ID
+ continue;
+
+ if(0==strcmp(Parser->ID,Finder->ID)) //search for equal message in new queue
+ break;
+ }
+ if(Parser!=NULL) //found equal message in new queue
+ {
+ if(Parser==*NewQueue)
+ *NewQueue=(*NewQueue)->Next;
+ else
+ ParserPrev->Next=Parser->Next;
+ Finder->Number=Parser->Number; //rewrite the number of current message in old queue
+
+ if(RemovedNew==NULL) //delete from new queue
+ DeleteAccountMailSvc((WPARAM)Account->Plugin,(LPARAM)Parser);
+ else //or move to RemovedNew
+ {
+ if(RemovedNewParser==NULL) //if it is first mail removed from NewQueue
+ *RemovedNew=Parser; //set RemovedNew queue to point to first message in removed queue
+ else
+ RemovedNewParser->Next=Parser; //else don't forget to show to next message in RemovedNew queue
+ RemovedNewParser=Parser; //follow RemovedNew queue
+ RemovedNewParser->Next=NULL;
+ }
+ FinderPrev=Finder;
+ Finder=Finder->Next; //get next message in old queue for testing
+ }
+ else //a message was already deleted from mailbox
+ {
+ if(Finder==*OldQueue) //if we are at the first item in OldQueue
+ {
+ *OldQueue=(*OldQueue)->Next; //set OldQueue to next item
+ if(RemovedOld==NULL) //delete from old queue
+ DeleteAccountMailSvc((WPARAM)Account->Plugin,(LPARAM)Finder);
+ else //or move to RemovedOld
+ {
+ if(RemovedOldParser==NULL) //if it is first mail removed from OldQueue
+ *RemovedOld=Finder; //set RemovedOld queue to point to first message in removed queue
+ else
+ RemovedOldParser->Next=Finder; //else don't forget to show to next message in RemovedNew queue
+ RemovedOldParser=Finder; //follow RemovedOld queue
+ RemovedOldParser->Next=NULL;
+ }
+ Finder=*OldQueue;
+ }
+ else
+ {
+ FinderPrev->Next=Finder->Next;
+ if(RemovedOld==NULL) //delete from old queue
+ DeleteAccountMailSvc((WPARAM)Account->Plugin,(LPARAM)Finder);
+ else //or move to RemovedOld
+ {
+ if(RemovedOldParser==NULL) //if it is first mail removed from OldQueue
+ *RemovedOld=Finder; //set RemovedOld queue to point to first message in removed queue
+ else
+ RemovedOldParser->Next=Finder; //else don't forget to show to next message in RemovedNew queue
+ RemovedOldParser=Finder; //follow RemovedOld queue
+ RemovedOldParser->Next=NULL;
+ }
+ Finder=FinderPrev->Next;
+ }
+ }
+ }
+}
+
+void WINAPI DeleteMessagesToEndFcn(HACCOUNT Account,HYAMNMAIL From)
+{
+ HYAMNMAIL Temp;
+ while(From!=NULL)
+ {
+ Temp=From;
+ From=From->Next;
+ DeleteAccountMailSvc((WPARAM)Account->Plugin,(LPARAM)Temp);
+ }
+}
+
+void WINAPI DeleteMessageFromQueueFcn(HYAMNMAIL *From,HYAMNMAIL Which,int mode=0)
+{
+ DWORD Number=Which->Number;
+ HYAMNMAIL Parser;
+
+ if(*From==Which)
+ {
+ Parser=Which->Next;
+ *From=Parser;
+ }
+ else
+ {
+ for(Parser=*From;Which!=Parser->Next;Parser=Parser->Next)
+ if(mode && (Parser->Number>Number)) Parser->Number--;
+ if(mode && (Parser->Number>Number)) Parser->Number--;
+ Parser->Next=Parser->Next->Next;
+ Parser=Which->Next;
+ }
+ if(mode)
+ for(;Parser!=NULL;Parser=Parser->Next)
+ if(Parser->Number>Number) Parser->Number--;
+}
+
+void DeleteMessagesFromQueue(HYAMNMAIL *From,HYAMNMAIL Which,int mode=0)
+{
+ HYAMNMAIL Parser;
+
+ for(Parser=Which;Parser!=NULL;Parser=Parser->Next)
+ DeleteMessageFromQueueFcn(From,Parser,mode);
+}
+
+HYAMNMAIL WINAPI FindMessageByIDFcn(HYAMNMAIL From,char *ID)
+{
+ HYAMNMAIL Browser;
+
+ for(Browser=From;Browser!=NULL;Browser=Browser->Next)
+ if(0==lstrcmp(Browser->ID,ID))
+ break;
+ return Browser;
+}
+
+void WINAPI TranslateHeaderFcn(char *stream,int len,struct CMimeItem **head)
+{
+ try
+ {
+ char *finder=stream;
+ char *prev1,*prev2,*prev3;
+ struct CMimeItem *Item=NULL;
+
+ while(finder<=(stream+len))
+ {
+ while(ENDLINEWS(finder)) finder++;
+
+ //at the start of line
+ if(DOTLINE(finder+1)) //at the end of stream
+ break;
+
+ prev1=finder;
+
+ while(*finder!=':' && !EOS(finder)) finder++;
+ if(!EOS(finder))
+ prev2=finder++;
+ else
+ break;
+
+ while(WS(finder) && !EOS(finder)) finder++;
+ if(!EOS(finder))
+ prev3=finder;
+ else
+ break;
+
+ do
+ {
+ if(ENDLINEWS(finder)) finder+=2; //after endline information continues
+ while(!ENDLINE(finder) && !EOS(finder)) finder++;
+ }while(ENDLINEWS(finder));
+
+ if(Item!=NULL)
+ {
+ if(NULL==(Item->Next=new struct CMimeItem))
+ break;
+ Item=Item->Next;
+ }
+ else
+ {
+ Item = new CMimeItem;
+ *head = Item;
+ }
+
+ Item->Next=NULL;
+ Item->name=new char [prev2-prev1+1];
+ lstrcpyn(Item->name,prev1,prev2-prev1+1);
+ Item->value=new char [finder-prev3+1];
+ lstrcpyn(Item->value,prev3,finder-prev3+1);
+
+ if(EOS(finder))
+ break;
+ finder++;
+ if(ENDLINE(finder)) {
+ finder++;
+ if(ENDLINE(finder)) {
+ // end of headers. message body begins
+ finder++;
+ if(ENDLINE(finder))finder++;
+ prev1 = finder;
+ while (!DOTLINE(finder+1))finder++;
+ if (ENDLINE(finder))finder--;
+ prev2 = finder;
+ if (prev2>prev1){ // yes, we have body
+ if(NULL==(Item->Next=new struct CMimeItem)) break; // Cant create new item?!
+ Item=Item->Next;
+ Item->Next=NULL;//just in case;
+ Item->name=new char[5]; strncpy(Item->name,"Body",5);
+ Item->value=new char [prev2-prev1];
+ lstrcpyn(Item->value,prev1,prev2-prev1-1);
+ }
+ break; // there is nothing else
+ }
+ }
+ }
+ }
+ catch(...)
+ {
+ MessageBox(NULL,"Translate header error","",0);
+ }
+}
+
+HYAMNMAIL WINAPI CreateNewDeleteQueueFcn(HYAMNMAIL From)
+{
+ HYAMNMAIL FirstMail,Browser;
+
+ for(FirstMail=NULL;From!=NULL;From=From->Next)
+ {
+ if((From->Flags & (YAMN_MSG_USERDELETE | YAMN_MSG_AUTODELETE)) && !(From->Flags & YAMN_MSG_DELETED))
+ {
+ if(FirstMail==NULL)
+ {
+ FirstMail=Browser=new YAMNMAIL;
+ if(FirstMail==NULL)
+ break;
+ }
+ else
+ {
+ Browser->Next=new YAMNMAIL;
+ Browser=Browser->Next;
+ }
+ Browser->ID=new char[strlen(From->ID)+1];
+ strcpy(Browser->ID,From->ID);
+ Browser->Number=From->Number;
+ Browser->Flags=From->Flags;
+ }
+ }
+ return FirstMail;
+}
+
+void WINAPI SetRemoveFlagsInQueueFcn(HYAMNMAIL From,DWORD FlagsSet,DWORD FlagsNotSet,DWORD FlagsToSetRemove,int mode)
+{
+ HYAMNMAIL msgq;
+
+ for(msgq=(HYAMNMAIL)From;msgq!=NULL;msgq=msgq->Next)
+ {
+ if((FlagsSet==(msgq->Flags & FlagsSet)) && (0==(msgq->Flags & FlagsNotSet)))
+ {
+ if(mode)
+ msgq->Flags=msgq->Flags | FlagsToSetRemove;
+ else
+ msgq->Flags=msgq->Flags & ~FlagsToSetRemove;
+ }
+ }
+}
diff --git a/yamn/mails/mime.cpp b/yamn/mails/mime.cpp new file mode 100644 index 0000000..f2364c9 --- /dev/null +++ b/yamn/mails/mime.cpp @@ -0,0 +1,732 @@ +/*
+ * This code implements retrieving info from MIME header
+ *
+ * (c) majvan 2002-2004
+ */
+
+#pragma warning( disable : 4290 )
+#include "../yamn.h"
+
+//- imported ---------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+extern SWMRG *AccountBrowserSO;
+extern struct WndHandles *MessageWnd;
+
+extern int GetCharsetFromString(char *input,size_t size);
+extern void SendMsgToRecepients(struct WndHandles *FirstWin,UINT msg,WPARAM wParam,LPARAM lParam);
+extern void ConvertCodedStringToUnicode(char *stream,WCHAR **storeto,DWORD cp,int mode);
+extern DWORD WINAPI MailBrowser(LPVOID Param);
+extern DWORD WINAPI NoNewMailProc(LPVOID Param);
+extern DWORD WINAPI BadConnection(LPVOID Param);
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+//Copies one string to another
+// srcstart- source string
+// srcend- address to the end of source string
+// dest- pointer that stores new allocated string that contains copy of source string
+// mode- MIME_PLAIN or MIME_MAIL (MIME_MAIL deletes '"' characters (or '<' and '>') if they are at start and end of source string
+void CopyToHeader(char *srcstart,char *srcend,char **dest,int mode);
+
+//Extracts email address (finds nick name and mail and then stores them to strings)
+// finder- source string
+// storeto- pointer that receives address of mail string
+// storetonick- pointer that receives address of nickname
+void ExtractAddressFromLine(char *finder,char **storeto,char **storetonick);
+
+//Extracts simple text from string
+// finder- source string
+// storeto- pointer that receives address of string
+void ExtractStringFromLine(char *finder,char **storeto);
+
+//Extracts some item from content-type string
+//Example: ContentType string: "TEXT/PLAIN; charset=US-ASCII", item:"charset=", returns: "US-ASCII"
+// ContetType- content-type string
+// value- string item
+// returns extracted string (or NULL when not found)
+char *ExtractFromContentType(char *ContentType,char *value);
+
+//Extracts info from header text into header members
+//Note that this function as well as struct CShortHeadwer can be always changed, because there are many items to extract
+//(e.g. the X-Priority and Importance and so on)
+// items- translated header (see TranslateHeaderFcn)
+// head- header to be filled with values extracted from items
+void ExtractShortHeader(struct CMimeItem *items,struct CShortHeader *head);
+
+//Extracts header to mail using ExtractShortHeader fcn.
+// items- translated header (see TranslateHeaderFcn)
+// CP- codepage used when no default found
+// head- header to be filled with values extracted from items, in unicode (wide char)
+void ExtractHeader(struct CMimeItem *items,int &CP,struct CHeader *head);
+
+//Deletes items in CShortHeader structure
+// head- structure whose items are deleted
+void DeleteShortHeaderContent(struct CShortHeader *head);
+
+//Deletes list of YAMN_MIMENAMES structures
+// Names- pointer to first item of list
+void DeleteNames(PYAMN_MIMENAMES Names);
+
+//Deletes list of YAMN_MIMESHORTNAMES structures
+// Names- pointer to first item of list
+void DeleteShortNames(PYAMN_MIMESHORTNAMES Names);
+
+//Makes a string lowercase
+// string- string to be lowercased
+void inline ToLower(char *string);
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+void CopyToHeader(char *srcstart,char *srcend,char **dest,int mode)
+{
+ char *dst;
+
+ if(dest==NULL)
+ return;
+ if(srcstart>=srcend)
+ return;
+
+ if((mode==MIME_MAIL) && (((*srcstart=='"') && (*(srcend-1)=='"')) || ((*srcstart=='<') && (*(srcend-1)=='>'))))
+ {
+ srcstart++;
+ srcend--;
+ }
+
+ if(srcstart>=srcend)
+ return;
+
+ if(NULL!=*dest)
+ delete[] *dest;
+ if(NULL==(*dest=new char[srcend-srcstart+1]))
+ return;
+
+ dst=*dest;
+
+ for(;srcstart<srcend;dst++,srcstart++)
+ {
+ if(ENDLINE(srcstart))
+ {
+ while(ENDLINE(srcstart) || WS(srcstart)) srcstart++;
+ *dst=' ';
+ srcstart--; //because at the end of "for loop" we increment srcstart
+ }
+ else
+ *dst=*srcstart;
+ }
+ *dst=0;
+}
+
+void ExtractAddressFromLine(char *finder,char **storeto,char **storetonick)
+{
+ if(finder==NULL)
+ {
+ *storeto=*storetonick=NULL;
+ return;
+ }
+ while(WS(finder)) finder++;
+ if((*finder)!='<')
+ {
+ char *finderend=finder+1;
+ do
+ {
+ if(ENDLINEWS(finderend)) //after endline information continues
+ finderend+=2;
+ while(!ENDLINE(finderend) && !EOS(finderend)) finderend++; //seek to the end of line or to the end of string
+ }while(ENDLINEWS(finderend));
+ finderend--;
+ while(WS(finderend) || ENDLINE(finderend)) finderend--; //find the end of text, no whitespace
+ if(*finderend!='>') //not '>' at the end of line
+ CopyToHeader(finder,finderend+1,storeto,MIME_MAIL);
+ else //at the end of line, there's '>'
+ {
+ char *finder2=finderend;
+ while((*finder2!='<') && (finder2>finder)) finder2--; //go to matching '<' or to the start
+ CopyToHeader(finder2,finderend+1,storeto,MIME_MAIL);
+ if(*finder2=='<') //if we found '<', the rest copy as from nick
+ {
+ finder2--;
+ while(WS(finder2) || ENDLINE(finder2)) finder2--; //parse whitespace
+ CopyToHeader(finder,finder2+1,storetonick,MIME_MAIL); //and store nickname
+ }
+ }
+ }
+ else
+ {
+ char *finderend=finder+1;
+ do
+ {
+ if(ENDLINEWS(finderend)) //after endline information continues
+ finderend+=2;
+ while(!ENDLINE(finderend) && (*finderend!='>') && !EOS(finderend)) finderend++; //seek to the matching < or to the end of line or to the end of string
+ }while(ENDLINEWS(finderend));
+ CopyToHeader(finder,finderend+1,storeto,MIME_MAIL); //go to first '>' or to the end and copy
+ finder=finderend+1;
+ while(WS(finder)) finder++; //parse whitespace
+ if(!ENDLINE(finder) && !EOS(finder)) //if there are chars yet, it's nick
+ {
+ finderend=finder+1;
+ while(!ENDLINE(finderend) && !EOS(finderend)) finderend++; //seek to the end of line or to the end of string
+ finderend--;
+ while(WS(finderend)) finderend--; //find the end of line, no whitespace
+ CopyToHeader(finder,finderend+1,storetonick,MIME_MAIL);
+ }
+ }
+}
+
+void ExtractStringFromLine(char *finder,char **storeto)
+{
+ if(finder==NULL)
+ {
+ *storeto=NULL;
+ return;
+ }
+ while(WS(finder)) finder++;
+ char *finderend=finder;
+
+ do
+ {
+ if(ENDLINEWS(finderend)) finderend++; //after endline information continues
+ while(!ENDLINE(finderend) && !EOS(finderend)) finderend++;
+ }while(ENDLINEWS(finderend));
+ finderend--;
+ while(WS(finderend)) finderend--; //find the end of line, no whitespace
+ CopyToHeader(finder,finderend+1,storeto,MIME_PLAIN);
+}
+
+char *ExtractFromContentType(char *ContentType,char *value)
+{
+ char *lowered = _strdup(ContentType);
+ ToLower(lowered);
+ char *finder=strstr(lowered,value);
+ if(finder==NULL){
+ free (lowered);
+ return NULL;
+ }
+ finder = finder-lowered+ContentType;
+ free (lowered);
+
+ char *temp,*copier;
+ char *CopiedString;
+
+ temp=finder-1;
+ while((temp>ContentType) && WS(temp)) temp--; //now we have to find, if the word "Charset=" is located after ';' like "; Charset="
+ if(*temp!=';' && !ENDLINE(temp) && temp!=ContentType)
+ return NULL;
+ finder=finder+strlen(value); //jump over value string
+
+ while(WS(finder)) finder++; //jump over whitespaces
+ temp=finder;
+ while(*temp!=0 && *temp!=';') temp++; //jump to the end of setting (to the next ;)
+ temp--;
+ while(WS(temp)) temp--; //remove whitespaces from the end
+ if (*finder=='\"'){ //remove heading and tailing quotes
+ finder++;
+ if (*temp=='\"') temp--;
+ }
+ if(NULL==(CopiedString=new char[++temp-finder+1]))
+ return NULL;
+ for(copier=CopiedString;finder!=temp;*copier++=*finder++); //copy string
+ *copier=0; //and end it with zero character
+
+ return CopiedString;
+}
+
+void ExtractShortHeader(struct CMimeItem *items,struct CShortHeader *head)
+{
+ for(;items!=NULL;items=items->Next)
+ {
+ //at the start of line
+ //MessageBox(NULL,items->value,items->name,0);
+ if(0==_strnicmp(items->name,"From",4))
+ {
+ if(items->value==NULL)
+ continue;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting from>");
+ #endif
+ ExtractAddressFromLine(items->value,&head->From,&head->FromNick);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting>\n");
+ #endif
+ }
+ else if(0==_strnicmp(items->name,"Return-Path",11))
+ {
+ if(items->value==NULL)
+ continue;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting return-path>");
+ #endif
+ ExtractAddressFromLine(items->value,&head->ReturnPath,&head->ReturnPathNick);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting>\n");
+ #endif
+ }
+ else if(0==_strnicmp(items->name,"Subject",7))
+ {
+ if(items->value==NULL)
+ continue;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting subject>");
+ #endif
+ ExtractStringFromLine(items->value,&head->Subject);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting>\n");
+ #endif
+ }
+ else if(0==_strnicmp(items->name,"Body",4))
+ {
+ if(items->value==NULL)
+ continue;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting body>");
+ #endif
+ ExtractStringFromLine(items->value,&head->Body);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting>\n");
+ #endif
+ }
+ else if(0==_strnicmp(items->name,"Date",4))
+ {
+ if(items->value==NULL)
+ continue;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting date>");
+ #endif
+ ExtractStringFromLine(items->value,&head->Date);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting>\n");
+ #endif
+ }
+ else if(0==_strnicmp(items->name,"Content-Type",12))
+ {
+ if(items->value==NULL)
+ continue;
+
+ char *ContentType=NULL,*CharSetStr;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting Content-Type>");
+ #endif
+ ExtractStringFromLine(items->value,&ContentType);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting>\n");
+ #endif
+ ToLower(ContentType);
+ if(NULL!=(CharSetStr=ExtractFromContentType(ContentType,"charset=")))
+ {
+ head->CP=GetCharsetFromString(CharSetStr,strlen(CharSetStr));
+ delete[] CharSetStr;
+ }
+ delete[] ContentType;
+ }
+ else if(0==_strnicmp(items->name,"Importance",10))
+ {
+ if(items->value==NULL)
+ continue;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting importance>");
+ #endif
+ if(head->Priority!=-1)
+ {
+ if(0==strncmp(items->value,"low",3))
+ head->Priority=5;
+ else if(0==strncmp(items->value,"normal",6))
+ head->Priority=3;
+ else if(0==strncmp(items->value,"high",4))
+ head->Priority=1;
+ }
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting>\n");
+ #endif
+ }
+ else if(0==_strnicmp(items->name,"X-Priority",10))
+ {
+ if(items->value==NULL)
+ continue;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<X-Priority>");
+ #endif
+ if((*items->value>='1') && (*items->value<='5'))
+ head->Priority=*items->value-'0';
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting>\n");
+ #endif
+ }
+
+ }
+}
+
+void ExtractHeader(struct CMimeItem *items,int &CP,struct CHeader *head)
+{
+ struct CShortHeader ShortHeader;
+
+ ZeroMemory(&ShortHeader,sizeof(struct CShortHeader));
+ ShortHeader.Priority=ShortHeader.CP=-1;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting header>\n");
+ #endif
+ ExtractShortHeader(items,&ShortHeader);
+
+ head->Priority=ShortHeader.Priority==-1 ? 3 : ShortHeader.Priority;
+ CP=ShortHeader.CP==-1 ? CP : ShortHeader.CP;
+ #ifdef DEBUG_DECODE
+ if(NULL!=ShortHeader.From)
+ DebugLog(DecodeFile,"<Decoded from>%s</Decoded)\n",ShortHeader.From);
+ if(NULL!=ShortHeader.FromNick)
+ DebugLog(DecodeFile,"<Decoded from-nick>%s</Decoded)\n",ShortHeader.FromNick);
+ if(NULL!=ShortHeader.ReturnPath)
+ DebugLog(DecodeFile,"<Decoded return-path>%s</Decoded)\n",ShortHeader.ReturnPath);
+ if(NULL!=ShortHeader.ReturnPathNick)
+ DebugLog(DecodeFile,"<Decoded return-path nick>%s</Decoded)\n",ShortHeader.ReturnPathNick);
+ if(NULL!=ShortHeader.Subject)
+ DebugLog(DecodeFile,"<Decoded subject>%s</Decoded)\n",ShortHeader.Subject);
+ if(NULL!=ShortHeader.Date)
+ DebugLog(DecodeFile,"<Decoded date>%s</Decoded)\n",ShortHeader.Date);
+ DebugLog(DecodeFile,"</Extracting header>\n");
+ DebugLog(DecodeFile,"<Convert>\n");
+ #endif
+
+ ConvertCodedStringToUnicode(ShortHeader.From,&head->From,CP,MIME_PLAIN);
+
+ #ifdef DEBUG_DECODE
+ if(NULL!=head->From)
+ DebugLogW(DecodeFile,L"<Converted from>%s</Converted>\n",head->From);
+ #endif
+ ConvertCodedStringToUnicode(ShortHeader.FromNick,&head->FromNick,CP,MIME_MAIL);
+ #ifdef DEBUG_DECODE
+ if(NULL!=head->FromNick)
+ DebugLogW(DecodeFile,L"<Converted from-nick>%s</Converted>\n",head->FromNick);
+ #endif
+ ConvertCodedStringToUnicode(ShortHeader.ReturnPath,&head->ReturnPath,CP,MIME_PLAIN);
+ #ifdef DEBUG_DECODE
+ if(NULL!=head->ReturnPath)
+ DebugLogW(DecodeFile,L"<Converted return-path>%s</Converted>\n",head->ReturnPath);
+ #endif
+ ConvertCodedStringToUnicode(ShortHeader.ReturnPathNick,&head->ReturnPathNick,CP,MIME_MAIL);
+ #ifdef DEBUG_DECODE
+ if(NULL!=head->ReturnPathNick)
+ DebugLogW(DecodeFile,L"<Converted return-path nick>%s</Converted>\n",head->ReturnPathNick);
+ #endif
+ ConvertCodedStringToUnicode(ShortHeader.Subject,&head->Subject,CP,MIME_PLAIN);
+ #ifdef DEBUG_DECODE
+ if(NULL!=head->Subject)
+ DebugLogW(DecodeFile,L"<Converted subject>%s</Converted>\n",head->Subject);
+ #endif
+ ConvertCodedStringToUnicode(ShortHeader.Date,&head->Date,CP,MIME_PLAIN);
+ #ifdef DEBUG_DECODE
+ if(NULL!=head->Date)
+ DebugLogW(DecodeFile,L"<Converted date>%s</Converted>\n",head->Date);
+ #endif
+
+ ConvertCodedStringToUnicode(ShortHeader.Body,&head->Body,CP,MIME_PLAIN);
+ #ifdef DEBUG_DECODE
+ if(NULL!=head->Body)
+ DebugLogW(DecodeFile,L"<Converted Body>%s</Converted>\n",head->Body);
+ #endif
+
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Convert>\n");
+ #endif
+
+ DeleteShortHeaderContent(&ShortHeader);
+
+// head->From=L"Frommmm";
+// head->Subject=L"Subject";
+ return;
+}
+
+void DeleteShortHeaderContent(struct CShortHeader *head)
+{
+ if(head->From!=NULL) delete[] head->From;
+ if(head->FromNick!=NULL) delete[] head->FromNick;
+ if(head->ReturnPath!=NULL) delete[] head->ReturnPath;
+ if(head->ReturnPathNick!=NULL) delete[] head->ReturnPathNick;
+ if(head->Subject!=NULL) delete[] head->Subject;
+ if(head->Date!=NULL) delete[] head->Date;
+ if(head->To!=NULL) DeleteShortNames(head->To);
+ if(head->Cc!=NULL) DeleteShortNames(head->Cc);
+ if(head->Bcc!=NULL) DeleteShortNames(head->Bcc);
+ if(head->Body!=NULL) delete[] head->Body;
+}
+
+void DeleteHeaderContent(struct CHeader *head)
+{
+ if(head->From!=NULL) delete[] head->From;
+ if(head->FromNick!=NULL) delete[] head->FromNick;
+ if(head->ReturnPath!=NULL) delete[] head->ReturnPath;
+ if(head->ReturnPathNick!=NULL) delete[] head->ReturnPathNick;
+ if(head->Subject!=NULL) delete[] head->Subject;
+ if(head->Date!=NULL) delete[] head->Date;
+ if(head->Body!=NULL) delete[] head->Body;
+ if(head->To!=NULL) DeleteNames(head->To);
+ if(head->Cc!=NULL) DeleteNames(head->Cc);
+ if(head->Bcc!=NULL) DeleteNames(head->Bcc);
+}
+
+void DeleteNames(PYAMN_MIMENAMES Names)
+{
+ PYAMN_MIMENAMES Parser=Names,Old;
+ for(;Parser!=NULL;Parser=Parser->Next)
+ {
+ if(Parser->Value!=NULL)
+ delete[] Parser->Value;
+ if(Parser->ValueNick!=NULL)
+ delete[] Parser->ValueNick;
+ Old=Parser;
+ Parser=Parser->Next;
+ delete Old;
+ }
+}
+
+void DeleteShortNames(PYAMN_MIMESHORTNAMES Names)
+{
+ PYAMN_MIMESHORTNAMES Parser=Names,Old;
+ for(;Parser!=NULL;Parser=Parser->Next)
+ {
+ if(Parser->Value!=NULL)
+ delete[] Parser->Value;
+ if(Parser->ValueNick!=NULL)
+ delete[] Parser->ValueNick;
+ Old=Parser;
+ Parser=Parser->Next;
+ delete Old;
+ }
+}
+
+
+void inline ToLower(char *string)
+{
+ for(;*string!=0;string++)
+ if(*string>='A' && *string<='Z') *string=*string-'A'+'a';
+}
+
+#define TE_UNKNOWN
+#define TE_QUOTEDPRINTABLE 1
+#define TE_BASE64 2
+struct APartDataType
+{
+ char *Src;//Input
+ char *ContType;
+ int CodePage;
+ char *TransEnc;
+ BYTE TransEncType; //TE_something
+ char *body;
+ int bodyLen;
+ WCHAR *wBody;
+};
+
+
+void ParseAPart(APartDataType *data)
+{
+ size_t len = strlen(data->Src);
+ try
+ {
+ char *finder=data->Src;
+ char *prev1,*prev2,*prev3;
+
+ while(finder<=(data->Src+len))
+ {
+ while(ENDLINEWS(finder)) finder++;
+
+ //at the start of line
+ if (finder>data->Src){
+ if (*(finder-2)=='\r' || *(finder-2)=='\n')
+ *(finder-2)=0;
+ if (*(finder-1)=='\r' || *(finder-1)=='\n')
+ *(finder-1)=0;
+ }
+ prev1=finder;
+
+ while(*finder!=':' && !EOS(finder) && !ENDLINE(finder)) finder++;
+ if (ENDLINE(finder)||EOS(finder)){
+ // no ":" in the line? here the body begins;
+ data->body = prev1;
+ break;
+ }
+ prev2=finder++;
+
+ while(WS(finder) && !EOS(finder)) finder++;
+ if(!EOS(finder))
+ prev3=finder;
+ else
+ break;
+
+ do
+ {
+ if(ENDLINEWS(finder)) finder+=2; //after endline information continues
+ while(!ENDLINE(finder) && !EOS(finder)) finder++;
+ }while(ENDLINEWS(finder));
+
+ if (!_strnicmp(prev1,"Content-type",prev2-prev1)){
+ data->ContType = prev3;
+ } else if (!_strnicmp(prev1,"Content-Transfer-Encoding",prev2-prev1)){
+ data->TransEnc = prev3;
+ }
+
+ if(EOS(finder))
+ break;
+ finder++;
+ if(ENDLINE(finder)) {
+ finder++;
+ if(ENDLINE(finder)) {
+ // end of headers. message body begins
+ if (finder>data->Src){
+ if (*(finder-2)=='\r' || *(finder-2)=='\n')
+ *(finder-2)=0;
+ if (*(finder-1)=='\r' || *(finder-1)=='\n')
+ *(finder-1)=0;
+ }
+ finder++;
+ if(ENDLINE(finder))finder++;
+ prev1 = finder;
+ while (!EOS(finder+1))finder++;
+ if (ENDLINE(finder))finder--;
+ prev2 = finder;
+ if (prev2>prev1){ // yes, we have body
+ data->body = prev1;
+ }
+ break; // there is nothing else
+ }
+ }
+ }
+ }
+ catch(...)
+ {
+ MessageBox(NULL,_T("Translate header error"),_T(""),0);
+ }
+ if (data->body) data->bodyLen = (int)strlen(data->body);
+}
+
+//from decode.cpp
+int DecodeQuotedPrintable(char *Src,char *Dst,int DstLen, BOOL isQ);
+int DecodeBase64(char *Src,char *Dst,int DstLen);
+int ConvertStringToUnicode(char *stream,unsigned int cp,WCHAR **out);
+
+WCHAR *ParseMultipartBody(char *src, char *bond)
+{
+ char *srcback = _strdup(src);
+ size_t sizebond = strlen(bond);
+ int numparts = 1;
+ int i;
+ char *courbond = srcback;
+ WCHAR *dest;
+ for (;(courbond=strstr(courbond,bond));numparts++,courbond+=sizebond);
+ APartDataType *partData = new APartDataType[numparts];
+ memset(partData, 0, sizeof(APartDataType)*numparts);
+ partData[0].Src = courbond = srcback;
+ for (i=1;(courbond=strstr(courbond,bond));i++,courbond+=sizebond){
+ *(courbond-2) = 0;
+ partData[i].Src = courbond+sizebond;
+ while (ENDLINE(partData[i].Src)) partData[i].Src++;
+ }
+ size_t resultSize=0;
+ for (i=0;i<numparts;i++){
+ ParseAPart(&partData[i]);
+ if (partData[i].body){
+ if (partData[i].TransEnc){
+ if (!_stricmp(partData[i].TransEnc,"base64")) partData[i].TransEncType=TE_BASE64;
+ else if (!_stricmp(partData[i].TransEnc,"quoted-printable"))partData[i].TransEncType=TE_QUOTEDPRINTABLE;
+ }
+ if (partData[i].ContType){
+ char *CharSetStr;
+ if(NULL!=(CharSetStr=ExtractFromContentType(partData[i].ContType,"charset=")))
+ {
+ partData[i].CodePage=GetCharsetFromString(CharSetStr,strlen(CharSetStr));
+ delete[] CharSetStr;
+ }
+ }
+ if (partData[i].ContType && !_strnicmp(partData[i].ContType,"text",4)) {
+ char *localBody=0;
+ switch (partData[i].TransEncType){
+ case TE_BASE64:
+ {
+ int size =partData[i].bodyLen*3/4+5;
+ localBody = new char[size+1];
+ DecodeBase64(partData[i].body,localBody,size);
+ }break;
+ case TE_QUOTEDPRINTABLE:
+ {
+ int size = partData[i].bodyLen+2;
+ localBody = new char[size+1];
+ DecodeQuotedPrintable(partData[i].body,localBody,size,FALSE);
+ }break;
+ }
+ ConvertStringToUnicode(localBody?localBody:partData[i].body,partData[i].CodePage,&partData[i].wBody);
+ if (localBody) delete[] localBody;
+ } else if(partData[i].ContType && !_strnicmp(partData[i].ContType,"multipart/",10)){
+ //Multipart in mulitipart recursive? should be SPAM. Ah well
+ char *bondary=NULL;
+ if(NULL!=(bondary=ExtractFromContentType(partData[i].ContType,"boundary=")))
+ {
+ partData[i].wBody = ParseMultipartBody(partData[i].body,bondary);
+ delete[] bondary;
+ } else goto FailBackRaw; //multipart with no boundary? badly formatted messages.
+ } else {
+FailBackRaw:
+ ConvertStringToUnicode(partData[i].body,partData[i].CodePage,&partData[i].wBody);
+ }
+ resultSize += wcslen(partData[i].wBody);
+ }// if (partData[i].body)
+ resultSize += 100+4+3; //cr+nl+100+ 3*bullet
+ }
+ dest = new WCHAR[resultSize+1];
+ size_t destpos = 0;
+ for (i=0;i<numparts;i++){
+ if (i){ // part before first boudary should not have headers
+ char infoline[104]; size_t linesize = 0;
+ _snprintf(infoline,100,"%s %d",Translate("Part"),i);
+ linesize = strlen(infoline);
+ if (partData[i].TransEnc){
+ _snprintf(infoline+linesize,100-linesize,"; %s",partData[i].TransEnc);
+ linesize = strlen(infoline);
+ }
+ if (partData[i].ContType){
+ char *CharSetStr=strchr(partData[i].ContType,';');
+ if (CharSetStr){
+ CharSetStr[0]=0;
+ _snprintf(infoline+linesize,100-linesize,"; %s",partData[i].ContType);
+ linesize = strlen(infoline);
+ partData[i].ContType=CharSetStr+1;
+ if(NULL!=(CharSetStr=ExtractFromContentType(partData[i].ContType,"charset=")))
+ {
+ _snprintf(infoline+linesize,100-linesize,"; %s",CharSetStr);
+ linesize = strlen(infoline);
+ delete[] CharSetStr;
+ }
+ if(NULL!=(CharSetStr=ExtractFromContentType(partData[i].ContType,"name=")))
+ {
+ _snprintf(infoline+linesize,100-linesize,"; \"%s\"",CharSetStr);
+ linesize = strlen(infoline);
+ delete[] CharSetStr;
+ }
+ } else {
+ _snprintf(infoline+linesize,100-linesize,"; %s",partData[i].ContType);
+ linesize = strlen(infoline);
+ }
+ }
+ sprintf(infoline+linesize,".\r\n");
+ {WCHAR *temp=0;
+ dest[destpos] = dest[destpos+1] = dest[destpos+2] = 0x2022; // bullet;
+ destpos+=3;
+ ConvertStringToUnicode(infoline,CP_ACP,&temp);
+ size_t wsize = wcslen(temp);
+ wcscpy(&dest[destpos],temp);
+ destpos += wsize;
+ delete[] temp;
+ }
+ } // if (i)
+ if (partData[i].wBody){
+ size_t wsize = wcslen(partData[i].wBody);
+ wcscpy(&dest[destpos],partData[i].wBody);
+ destpos += wsize;
+ delete[] partData[i].wBody;
+ }
+ }
+
+ free (srcback);
+ delete[] partData;
+ dest[resultSize] = 0;//just in case
+ return dest;
+}
diff --git a/yamn/mails/test/header.txt b/yamn/mails/test/header.txt new file mode 100644 index 0000000..55a4d86 --- /dev/null +++ b/yamn/mails/test/header.txt @@ -0,0 +1,28 @@ +Return-Path: <foromundial-return-1047-decode.com.ar-pablo=decode.com.ar@decode.com.ar>
+Delivered-To: pablo@decode.com.ar
+Received: (qmail 5438 invoked by uid 618); 5 Sep 2003 19:49:16 -0000
+Mailing-List: contact foromundial-help@decode.com.ar; run by ezmlm
+Precedence: bulk
+X-No-Archive: yes
+List-Post: <mailto:foromundial@decode.com.ar>
+List-Help: <mailto:foromundial-help@decode.com.ar>
+List-Unsubscribe: <mailto:foromundial-unsubscribe@decode.com.ar>
+List-Subscribe: <mailto:foromundial-subscribe@decode.com.ar>
+X-Seq: 1047
+Delivered-To: mailing list foromundial@decode.com.ar
+Received: (qmail 5432 invoked by uid 618); 5 Sep 2003 19:49:15 -0000
+X-Spam-Status: No, hits=3.9 required=7.5
+Message-Id: <4.2.1.20030905163128.00a998a0@mail.labsem.cetuc.puc-rio.br>
+X-Sender: sandra@mail.labsem.cetuc.puc-rio.br
+X-Mailer: QUALCOMM Windows Eudora Pro Version 4.2.1
+Date: Fri, 05 Sep 2003 16:48:12 -0300
+To: foromundial@decode.com.ar
+From: "Sandra M. Landi" <sandra@labsem.cetuc.puc-rio.br>
+Mime-Version: 1.0
+Content-Type: multipart/alternative;
+ boundary="=====================_4293080==_.ALT"
+X-Antirelay: Good relay from local net2 139.82.127.0/26
+Subject: [foromundial-1047] frases para un viernes
+
+
+.
diff --git a/yamn/mails/test/header2.txt b/yamn/mails/test/header2.txt new file mode 100644 index 0000000..3ba81a2 --- /dev/null +++ b/yamn/mails/test/header2.txt @@ -0,0 +1,97 @@ +Return-Path: <miranda@megami.sprintserve.net>
+Received: [from megami.sprintserve.net (megami.sprintserve.net [207.142.136.160])
+ by mail2.ba.psg.sk with ESMTP id i4FHNUY6018585
+ for <om3tn@psg.sk>; Sat, 15 May 2004 19:23:31 +0200]
+X-Envelope-To: <om3tn@psg.sk>
+Received: from miranda by megami.sprintserve.net with local (Exim 4.34)
+ id 1BP2sS-0006W6-MS
+ for om3tn@psg.sk; Sat, 15 May 2004 13:23:12 -0400
+To: Undisclosed-recipients:;
+Subject: UpozornØn¡ na odpovØÔ v t‚matu - YAMN problem
+Reply-to: forum@miranda-im.org
+From: forum@miranda-im.org:
+Message-ID: <e003226b4a46a7ca6b490345f21b91af@forums.miranda-im.org>
+MIME-Version: 1.0
+Content-type: text/plain; charset=Windows-1250
+Content-transfer-encoding: 8bit
+Date: Sat, 15 May 2004 13:23:12 -0400
+X-Priority: 3
+X-MSMail-Priority: Normal
+X-Mailer: PHP
+X-MimeOLE: Produced By phpBB2
+X-MailScanner-Information: Please contact the ISP for more information
+X-MailScanner: Found to be clean
+X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
+X-AntiAbuse: Primary Hostname - megami.sprintserve.net
+X-AntiAbuse: Original Domain - psg.sk
+X-AntiAbuse: Originator/Caller UID/GID - [32110 32110] / [47 12]
+X-AntiAbuse: Sender Address Domain - megami.sprintserve.net
+X-Source:
+X-Source-Args:
+X-Source-Dir:
+.
+
+Subject: UpozornØn¡ na odpovØÔ v t‚matu - YAMN problem
+
+Return-Path: <miranda@megami.sprintserve.net>
+Received: [from megami.sprintserve.net (megami.sprintserve.net [207.142.136.160])
+ by mail2.ba.psg.sk with ESMTP id i4FHX2Y6020695
+ for <om3tn@psg.sk>; Sat, 15 May 2004 19:33:03 +0200]
+X-Envelope-To: <om3tn@psg.sk>
+Received: from miranda by megami.sprintserve.net with local (Exim 4.34)
+ id 1BP31h-0001cs-Ai
+ for om3tn@psg.sk; Sat, 15 May 2004 13:32:45 -0400
+To: Undisclosed-recipients:;
+Subject: UpozornØn¡ na odpovØÔ v t‚matu - YAMN problem
+Reply-to: forum@miranda-im.org
+From: forum@miranda-im.org
+Message-ID: <0873b36d0931479c4ebe23ba71ff4810@forums.miranda-im.org>
+MIME-Version: 1.0
+Content-type: text/plain; charset=Windows-1250
+Content-transfer-encoding: 8bit
+Date: Sat, 15 May 2004 13:32:45 -0400
+X-Priority: 3
+X-MSMail-Priority: Normal
+X-Mailer: PHP
+X-MimeOLE: Produced By phpBB2
+X-MailScanner-Information: Please contact the ISP for more information
+X-MailScanner: Found to be clean
+X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
+X-AntiAbuse: Primary Hostname - megami.sprintserve.net
+X-AntiAbuse: Original Domain - psg.sk
+X-AntiAbuse: Originator/Caller UID/GID - [32110 32110] / [47 12]
+X-AntiAbuse: Sender Address Domain - megami.sprintserve.net
+X-Source:
+X-Source-Args:
+X-Source-Dir:
+
+.
+
+Received: by hplm (mbox om3tn)
+ (with POP3 daemon cucipop (v1.31 1998/05/13) Tue May 27 18:42:20 2003)
+X-From_: HMF@hotbox.ru Tue May 20 18:11:44 2003
+Return-Path: <HMF@hotbox.ru>
+Received: from ns1.slovanet.net (ns1.slovanet.net [195.28.64.119])
+ by hplm.psg.sk (8.12.9/8.12.7) with SMTP id h4KGBfxJ003732
+ for <om3tn@psg.sk>; Tue, 20 May 2003 18:11:44 +0200
+X-Envelope-To: <om3tn@psg.sk>
+Received: (qmail 6339 invoked from network); 20 May 2003 18:11:45 +0200
+Received: from unknown (HELO ??+???) (61.33.134.106)
+ by ns1.slovanet.net with SMTP; 20 May 2003 18:11:45 +0200
+Received: by london.com (Postfix, from userid 302)
+ id WTS; Tue, 20 May 2003 20:13:19
+Received: from Œù+⌥ (Œù+⌥ [61.33.134.106])
+ by mill.co.uk (Postfix) with ESMTP id 613
+ for <om3tn@psg.sk>; Tue, 20 May 2003 20:13:19
+Subject: Òàìîæåííàî÷èñòêà. ÔèíëäèÌîñêâà. Îò 0,8 çà êã, âêëþ÷àâñå ! 20:13:19
+From: <HMF@hotbox.ru>
+To: OM3TN <om3tn@psg.sk>
+Reply-To: <>
+X-Mailer: AOL 7.0 for Windows UK sub 52
+X-Priority: 1
+X-MSMail-Priority: High
+Mime-Version: 1.0
+Content-Type: text/html; charset="Windows-1251"
+Content-Transfer-Encoding: 7bit
+Date: Tue, 20 May 2003 20:13:21
+Message-Id: <DED-173-MCL662@mail-relay2.slovanet.net>
\ No newline at end of file diff --git a/yamn/mails/test/readme.txt b/yamn/mails/test/readme.txt new file mode 100644 index 0000000..35a30b2 --- /dev/null +++ b/yamn/mails/test/readme.txt @@ -0,0 +1,4 @@ +This is project for testing mime encoding/decoding. It
+is very usefull for developers, when some problems with
+non-standard headers occured. You can use it to step through
+MIME decoding functions.
diff --git a/yamn/mails/test/test.cpp b/yamn/mails/test/test.cpp new file mode 100644 index 0000000..f8dcd14 --- /dev/null +++ b/yamn/mails/test/test.cpp @@ -0,0 +1,42 @@ +/*
+ * This file is for testing purposes. Save in header.txt your problem header and you can
+ * browse through functions to get result
+ *
+ * (c) majvan 2002-2004
+ */
+
+#include <stdio.h>
+#include "../m_mails.h"
+
+extern void WINAPI TranslateHeaderFcn(char *stream,int len,struct CMimeItem **head);
+extern void ExtractHeader(struct CMimeItem *items,int CP,struct CHeader *head);
+
+void main()
+{
+ char Buffer[8192]; //we do not suppose longer header
+ FILE *fp;
+ YAMNMAIL *Mail;
+ PMAILDATA *MailData;
+ CMimeItem *head;
+
+ struct CHeader ExtractedHeader;
+
+ if(NULL==(fp=fopen("header2.txt","r")))
+ return;
+ fread(Buffer,sizeof(Buffer),1,fp);
+ if(ferror(fp))
+ {
+ fclose(fp);
+ return;
+ }
+ fclose(fp);
+ Mail = new YAMNMAIL;
+ MailData = new PMAILDATA;
+ head = new CMimeItem;
+ Mail->MailData = *MailData;
+ Mail->MailData->TranslatedHeader = head;
+
+ TranslateHeaderFcn(Buffer,strlen(Buffer), &Mail->MailData->TranslatedHeader);
+ ExtractHeader(Mail->MailData->TranslatedHeader,CP_ACP,&ExtractedHeader);
+ return;
+}
\ No newline at end of file diff --git a/yamn/mails/test/test.dsp b/yamn/mails/test/test.dsp new file mode 100644 index 0000000..6d01b36 --- /dev/null +++ b/yamn/mails/test/test.dsp @@ -0,0 +1,112 @@ +# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=test - 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 "test.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 "test.mak" CFG="test - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "test - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "test - 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 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x405 /d "NDEBUG"
+# ADD RSC /l 0x405 /d "NDEBUG"
+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 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 /subsystem:console /machine:I386
+# ADD 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 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 /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "test - 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 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x405 /d "_DEBUG"
+# ADD RSC /l 0x405 /d "_DEBUG"
+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 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 /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD 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 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 /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "test - Win32 Release"
+# Name "test - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\decode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\mails.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\mime.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\test.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/yamn/mails/test/test.dsw b/yamn/mails/test/test.dsw new file mode 100644 index 0000000..e25096d --- /dev/null +++ b/yamn/mails/test/test.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "test"=.\test.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/yamn/main.cpp b/yamn/main.cpp new file mode 100644 index 0000000..9abb1a9 --- /dev/null +++ b/yamn/main.cpp @@ -0,0 +1,846 @@ +/*
+ * YAMN plugin main file
+ * Miranda homepage: http://miranda-icq.sourceforge.net/
+ * YAMN homepage: http://www.majvan.host.sk/Projekty/YAMN
+ *
+ * initializes all variables for further work
+ *
+ * (c) majvan 2002-2004
+ */
+
+
+#include "main.h"
+#include "yamn.h"
+#include "resources/resource.h"
+#include <io.h>
+//- imported ---------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+//CRITICAL_SECTION MWCS;
+//CRITICAL_SECTION ASCS;
+//CRITICAL_SECTION PRCS;
+
+extern LPCRITICAL_SECTION PluginRegCS;
+extern HANDLE ExitEV;
+extern HANDLE WriteToFileEV;
+
+extern int PosX,PosY,SizeX,SizeY;
+extern int HeadPosX,HeadPosY,HeadSizeX,HeadSizeY,HeadSplitPos;
+
+//From account.cpp
+extern LPCRITICAL_SECTION AccountStatusCS;
+extern LPCRITICAL_SECTION FileWritingCS;
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+WCHAR *ProfileName = NULL; //e.g. "majvan"
+WCHAR *UserDirectory = NULL; //e.g. "F:\WINNT\Profiles\UserXYZ"
+char *ProtoName = YAMN_DBMODULE;
+//char *AltProtoName;
+char *szMirandaDir = NULL;
+char *szProfileDir = NULL;
+
+INT_PTR YAMN_STATUS;
+
+BOOL UninstallPlugins;
+
+HANDLE hAccountFolder;
+
+HINSTANCE *hDllPlugins;
+static int iDllPlugins=0;
+
+PLUGINLINK *pluginLink;
+YAMN_VARIABLES YAMNVar;
+
+static const MUUID interfaces[] = {MUUID_YAMN_FORCECHECK, MIID_LAST};
+
+PLUGININFOEX pluginInfo={
+ sizeof(PLUGININFOEX),
+ YAMN_SHORTNAME,
+ YAMN_VERSION,
+ "Mail notifier and browser for Miranda IM. Included POP3 protocol.",
+ "y_b tweety (majvan)",
+ "francois.mean@skynet.be",
+ "© (2002-2004 majvan) 2005-2007 tweety y_b Miranda community",
+ "http://www.miranda-im.org/download/details.php?action=viewfile&id=3411", //"http://www.majvan.host.sk/Projekty/YAMN?fm=soft",
+ UNICODE_AWARE,
+ 0, //doesn't replace anything built-in
+ { 0xb047a7e5, 0x27a, 0x4cfc, { 0x8b, 0x18, 0xed, 0xa8, 0x34, 0x5d, 0x27, 0x90 } } // {B047A7E5-027A-4cfc-8B18-EDA8345D2790}
+
+};
+
+SKINSOUNDDESC NewMailSound={
+ sizeof(SKINSOUNDDESC),
+ YAMN_NEWMAILSOUND, //name to refer to sound when playing and in db
+ YAMN_NEWMAILSNDDESC, //description for options dialog
+ "", //default sound file to use, without path
+};
+
+SKINSOUNDDESC ConnectFailureSound={
+ sizeof(SKINSOUNDDESC),
+ YAMN_CONNECTFAILSOUND, //name to refer to sound when playing and in db
+ YAMN_CONNECTFAILSNDDESC,//description for options dialog
+ "", //default sound file to use, without path
+};
+
+HANDLE hNewMailHook;
+//HANDLE hUninstallPluginsHook;
+
+HANDLE NoWriterEV;
+
+HANDLE hTTButton; //TopToolBar button
+
+DWORD HotKeyThreadID;
+
+UINT SecTimer;
+
+BOOL bIcolibEmbededInCore = FALSE;
+
+HICON hYamnIcons[ICONSNUMBER];
+char *iconDescs[ICONSNUMBER]={ICONSDESCS};
+char *iconNames[ICONSNUMBER]={ICONSNAMES};
+ int iconIndexes[ICONSNUMBER]={ICONSINDS};
+
+HANDLE hMenuItemMain = 0;
+HANDLE hMenuItemCont = 0;
+HANDLE hMenuItemContApp = 0;
+
+BOOL (WINAPI *MyEnableThemeDialogTexture)(HANDLE, DWORD) = 0;
+HMODULE hUxTheme = 0;
+
+// function pointers, use typedefs for casting to shut up the compiler when using GetProcAddress()
+
+typedef BOOL (WINAPI *PITA)();
+typedef HANDLE (WINAPI *POTD)(HWND, LPCWSTR);
+typedef UINT (WINAPI *PDTB)(HANDLE, HDC, int, int, RECT *, RECT *);
+typedef UINT (WINAPI *PCTD)(HANDLE);
+typedef UINT (WINAPI *PDTT)(HANDLE, HDC, int, int, LPCWSTR, int, DWORD, DWORD, RECT *);
+
+PITA pfnIsThemeActive = 0;
+POTD pfnOpenThemeData = 0;
+PDTB pfnDrawThemeBackground = 0;
+PCTD pfnCloseThemeData = 0;
+PDTT pfnDrawThemeText = 0;
+
+#define FIXED_TAB_SIZE 100 // default value for fixed width tabs
+
+/*
+ * visual styles support (XP+)
+ * returns 0 on failure
+ */
+
+int InitVSApi()
+{
+ if((hUxTheme = LoadLibraryA("uxtheme.dll")) == 0)
+ return 0;
+
+ pfnIsThemeActive = (PITA)GetProcAddress(hUxTheme, "IsThemeActive");
+ pfnOpenThemeData = (POTD)GetProcAddress(hUxTheme, "OpenThemeData");
+ pfnDrawThemeBackground = (PDTB)GetProcAddress(hUxTheme, "DrawThemeBackground");
+ pfnCloseThemeData = (PCTD)GetProcAddress(hUxTheme, "CloseThemeData");
+ pfnDrawThemeText = (PDTT)GetProcAddress(hUxTheme, "DrawThemeText");
+
+ MyEnableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture");
+ if(pfnIsThemeActive != 0 && pfnOpenThemeData != 0 && pfnDrawThemeBackground != 0 && pfnCloseThemeData != 0 && pfnDrawThemeText != 0) {
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * unload uxtheme.dll
+ */
+
+int FreeVSApi()
+{
+ if(hUxTheme != 0)
+ FreeLibrary(hUxTheme);
+ return 0;
+}
+
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+static void GetProfileDirectory(char *szPath,int cbPath)
+//This is copied from Miranda's sources. In 0.2.1.0 it is needed, in newer vesions of Miranda use MS_DB_GETPROFILEPATH service
+{
+ szProfileDir=new char[MAX_PATH];
+ if (ServiceExists(MS_DB_GETPROFILEPATH)){
+ if (!CallService(MS_DB_GETPROFILEPATH,(WPARAM)cbPath,(LPARAM)szPath)) {
+ lstrcpy(szProfileDir,szPath);
+ return; //success
+ }
+ }
+ char szMirandaIni[MAX_PATH],szExpandedProfileDir[MAX_PATH];
+ DWORD dwAttributes;
+
+ lstrcpy(szMirandaIni,szMirandaDir);
+ lstrcat(szMirandaIni,"\\mirandaboot.ini");
+ GetPrivateProfileString("Database","ProfileDir",".",szProfileDir,sizeof(szProfileDir),szMirandaIni);
+ ExpandEnvironmentStrings(szProfileDir,szExpandedProfileDir,sizeof(szExpandedProfileDir));
+ _chdir(szMirandaDir);
+ if(!_fullpath(szPath,szExpandedProfileDir,cbPath))
+ lstrcpyn(szPath,szMirandaDir,cbPath);
+ if(szPath[lstrlen(szPath)-1]=='\\') szPath[lstrlen(szPath)-1]='\0';
+ if((dwAttributes=GetFileAttributes(szPath))!=0xffffffff&&dwAttributes&FILE_ATTRIBUTE_DIRECTORY) return;
+ CreateDirectory(szPath,NULL);
+}
+
+void SetDefaultProtocolIcons()
+{
+ char szFileName[MAX_PATH+1];
+ char oldname[] = YAMN_DBMODULE"4007_"; // the deprecated one
+ char dllname[] = "plugins\\"YAMN_DBMODULE".dll,-xxxxx";
+
+ // determine whether external icon file exists
+ lstrcpy(szFileName, szMirandaDir);
+ lstrcat(szFileName, "\\icons\\proto_"YAMN_DBMODULE".dll");
+ BOOL isDllPresent = (_access(szFileName, 0) == 0);
+
+ WORD statuses[4] = {ID_STATUS_OFFLINE,ID_STATUS_ONLINE,ID_STATUS_NA,ID_STATUS_OCCUPIED};
+ BYTE indices[4] = {7, 0, 3, 4};
+ //From skinicons.c skinIconStatusToIdStatus[]
+ BYTE protoStatusInd[4] = {0,1,4,5};
+
+ for (int i=0;i<4;i++){
+ oldname[sizeof(oldname)-2]=protoStatusInd[i]+'1'; // "Out for lunch will not work here"
+ if (isDllPresent){ // use the icons in proto_YAMN.dll and delete any user settings
+ DBDeleteContactSetting(NULL, "Icons", oldname);
+ } else {
+ DBVARIANT dbv;
+ if(!DBGetContactSetting(NULL,"SkinIcons",iconNames[indices[i]],&dbv))
+ {// user won't be able to set status icons different from those in YAMN section
+ DBWriteContactSettingString(NULL, "Icons", oldname, (char *)dbv.pszVal);
+ DBFreeVariant(&dbv);
+ } else {
+ _snprintf(&dllname[sizeof(dllname)-6],5,"%d",iconIndexes[indices[i]]);
+ DBWriteContactSettingString(NULL, "Icons", oldname, dllname);
+ }
+ }
+ }
+}
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+#ifndef WIN2IN1
+ OSVERSIONINFO OSversion;
+
+ OSversion.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
+
+ GetVersionEx(&OSversion);
+ switch(OSversion.dwPlatformId)
+ {
+ case VER_PLATFORM_WIN32s:
+ case VER_PLATFORM_WIN32_WINDOWS:
+#ifndef WIN9X
+ MessageBoxA(NULL,"This YAMN cannot run on Windows 95, 98 or Me. Why? Read FAQ. You should download Win9x version.","YAMN error",MB_OK | MB_ICONSTOP);
+ return FALSE;
+#else
+ break;
+#endif
+ case VER_PLATFORM_WIN32_NT:
+#ifdef WIN9X
+ MessageBoxA(NULL,"This YAMN is intended for Windows 95, 98 or Me. You should use native WinNT version.","YAMN error",MB_OK | MB_ICONSTOP);
+ return FALSE;
+#else
+ break;
+#endif
+ }
+#endif // WIN2IN1
+ YAMNVar.hInst=hinstDLL;
+ if(fdwReason==DLL_PROCESS_ATTACH)
+ {
+ if(NULL==(UserDirectory=new WCHAR[MAX_PATH]))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ if (mirandaVersion >= PLUGIN_MAKE_VERSION(0, 7, 0, 3))
+ bIcolibEmbededInCore = TRUE;
+ pluginInfo.cbSize = sizeof(PLUGININFO);//Miranda pre-0.7.0.17 does not load the plugin if cbSize does not match.
+ return (PLUGININFO *) &pluginInfo;
+}
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ if (mirandaVersion >= PLUGIN_MAKE_VERSION(0, 7, 0, 3))
+ bIcolibEmbededInCore = TRUE;
+ pluginInfo.cbSize = sizeof(PLUGININFOEX);//Make sure cbSize is correct;
+ return &pluginInfo;
+}
+
+extern "C" __declspec(dllexport) const MUUID * MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+#ifdef YAMN_DEBUG
+static char unknownCP[1500]={0};
+#endif
+// The callback function
+BOOL CALLBACK EnumSystemCodePagesProc(LPTSTR cpStr)
+{
+ //Convert code page string to number
+ UINT cp = _ttoi(cpStr);
+ if (!IsValidCodePage(cp))
+ return TRUE;
+
+ //Get Code Page name
+ CPINFOEX info;
+ if(GetCPInfoEx(cp,0,&info)){
+ #ifdef YAMN_DEBUG
+ BOOLEAN found = FALSE;
+ #endif
+ for (int i=1;i<CPLENALL;i++) if (CodePageNamesAll[i].CP==cp) {
+ CodePageNamesAll[i].isValid = TRUE;
+ CPLENSUPP++;
+ #ifdef YAMN_DEBUG
+ found = TRUE;
+ #endif
+ break;
+ }
+ #ifdef YAMN_DEBUG
+ if (!found) {
+ strcat(unknownCP,info.CodePageName);
+ strcat(unknownCP,"\n");
+ }
+ #endif
+ }
+ return TRUE;
+}
+
+int SystemModulesLoaded(WPARAM,LPARAM){
+ if(ServiceExists(MS_SKIN2_ADDICON))
+ {
+ //MessageBox(NULL,"Icolib present","test",0);
+ SKINICONDESC sid = {0};
+ HICON temp;
+ sid.cbSize = SKINICONDESC_SIZE;
+ sid.pszSection = "YAMN";
+ sid.pszDefaultFile = NULL;
+ for (int i=0; i<ICONSNUMBER; i++){
+ sid.iDefaultIndex = -iconIndexes[i];
+ sid.pszName = iconNames[i];
+ sid.pszDescription = Translate(iconDescs[i]);
+ sid.hDefaultIcon = hYamnIcons[i];
+ CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid);
+ if (temp = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) iconNames[i]))hYamnIcons[i]=temp;
+ }
+ }
+
+ CLISTMENUITEM mi;
+
+ //Insert "Check mail (YAMN)" item to Miranda's menu
+ ZeroMemory(&mi,sizeof(mi));
+ mi.cbSize = sizeof(mi);
+ mi.position = 0xb0000000;
+ mi.flags = 0;
+ mi.hIcon = hYamnIcons[5];
+ mi.pszName = Translate("Check &mail (All Account)");
+ mi.pszPopupName = NULL;//ProtoName;
+ mi.pszService = MS_YAMN_FORCECHECK;
+ if(DBGetContactSettingByte(NULL, YAMN_DBMODULE, YAMN_SHOWMAINMENU, 0))
+ hMenuItemMain = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+
+ mi.pszName = Translate("Check &mail (This Account)");
+ mi.pszContactOwner = ProtoName;
+ mi.pszService = MS_YAMN_CLISTCONTEXT;
+ hMenuItemCont = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi);
+
+ mi.hIcon = hYamnIcons[4];
+ mi.pszName = Translate("Launch application");
+ mi.pszContactOwner = ProtoName;
+ mi.pszService = MS_YAMN_CLISTCONTEXTAPP;
+ hMenuItemContApp = (HANDLE) CallService(MS_CLIST_ADDCONTACTMENUITEM,0,(LPARAM)&mi);
+
+ //Use for the Updater plugin
+ if(ServiceExists(MS_UPDATE_REGISTER))
+ {
+ Update update = {0};
+ char szVersion[16];
+ char szUrl[250];
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionStringPlugin((PLUGININFO *)&pluginInfo, szVersion);
+ update.cpbVersion = (int)strlen((char *)update.pbVersion);
+ /*#ifdef YAMN_9x
+ update.szUpdateURL = "http://addons.miranda-im.org/feed.php?dlfile=2166";
+ update.szVersionURL = "http://addons.miranda-im.org/details.php?action=viewfile&id=2166";
+ update.pbVersionPrefix = (BYTE *)"<span class=\"fileNameHeader\">YAMN tweety win9x ";
+ #else
+ update.szUpdateURL = "http://addons.miranda-im.org/feed.php?dlfile=2165";
+ update.szVersionURL = "http://addons.miranda-im.org/details.php?action=viewfile&id=2165";
+ update.pbVersionPrefix = (BYTE *)"<span class=\"fileNameHeader\">YAMN tweety ";
+ #endif*/
+ update.szUpdateURL = "http://addons.miranda-im.org/feed.php?dlfile=3411";
+ update.szVersionURL = "http://addons.miranda-im.org/details.php?action=viewfile&id=3411";
+ update.pbVersionPrefix = (BYTE *)"<span class=\"fileNameHeader\">YAMN 2in1 ";
+ wsprintf(szUrl,"http://www.miranda-fr.net/tweety/yamn/%s.zip",YAMN_FILENAME);
+ update.szBetaUpdateURL = szUrl;
+ update.szBetaVersionURL = "http://www.miranda-fr.net/tweety/yamn/yamn_beta.html";
+ update.pbBetaVersionPrefix = (BYTE *)"YAMN version ";
+ update.cpbVersionPrefix = (int)strlen((char *)update.pbVersionPrefix);
+ update.cpbBetaVersionPrefix = (int)strlen((char *)update.pbBetaVersionPrefix);
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+
+ }
+ if (ServiceExists(MS_FOLDERS_GET_PATH)){
+ //char AccountFolder[MAX_PATH];
+ //CallService(MS_DB_GETPROFILEPATH, (WPARAM) MAX_PATH, (LPARAM)AccountFolder);
+ //sprintf(AccountFolder,"%s\\%s",AccountFolder,ProtoName);
+ hAccountFolder = FoldersRegisterCustomPathW(ProtoName,YAMN_DBMODULE" Account Folder",UserDirectory);
+
+ FoldersGetCustomPathW(hAccountFolder, UserDirectory, MAX_PATH, UserDirectory);
+ //MultiByteToWideChar(CP_ACP,MB_USEGLYPHCHARS,AccountFolder,-1,UserDirectory,strlen(AccountFolder)+1);
+ }
+
+ RegisterPOP3Plugin(0,0);
+
+ return 0;
+}
+
+//int IcoLibIconsChanged(WPARAM wParam, LPARAM lParam); // implemented in services.cpp
+extern HCURSOR hCurSplitNS, hCurSplitWE;
+extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+ UINT mod,vk;
+ char pn[MAX_PATH+1];
+ char *fc;
+ int i,k;
+
+ pluginLink=link;
+
+ YAMN_STATUS = ID_STATUS_OFFLINE;
+
+ // we get the Miranda Root Path
+ szMirandaDir=new char[MAX_PATH];
+ if (ServiceExists(MS_UTILS_PATHTOABSOLUTE)){
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)".",(LPARAM)szMirandaDir);
+ }
+ else {
+ char *str2;
+ GetModuleFileName(GetModuleHandle(NULL),szMirandaDir,MAX_PATH);
+ str2=strrchr(szMirandaDir,'\\');
+ if(str2!=NULL) *str2=0;
+ }
+
+ // we get the user path where our yamn-account.book.ini is stored from mirandaboot.ini file
+ char szProfileDir[MAX_PATH+1];
+ GetProfileDirectory(szProfileDir,sizeof(szProfileDir));
+ MultiByteToWideChar(CP_ACP,MB_USEGLYPHCHARS,szProfileDir,-1,UserDirectory,(int)strlen(szProfileDir)+1);
+
+
+ // Enumerate all the code pages available for the System Locale
+ EnumSystemCodePages(EnumSystemCodePagesProc, CP_INSTALLED);
+ CodePageNamesSupp = new _tcptable[CPLENSUPP];
+ for (i=0,k=0;i<CPLENALL;i++) {
+ if (CodePageNamesAll[i].isValid){
+ CodePageNamesSupp[k]=CodePageNamesAll[i];
+ k++;
+ }
+ }
+ #ifdef YAMN_DEBUG
+//unknownCP 0x6005a734
+//20127 (US-ASCII)
+//20261 (T.61)
+//28605 (ISO 8859-15 Latin 9)
+//737 (OEM - Greek 437G)
+//874 (ANSI/OEM - Thai)
+//932 (ANSI/OEM - Japanese Shift-JIS)
+//936 (ANSI/OEM - Simplified Chinese GBK)
+//949 (ANSI/OEM - Korean)
+ MessageBox( NULL,unknownCP, TEXT("Unkown Code Page"), MB_OK);
+ #endif
+
+ HIMAGELIST CSImages = ImageList_Create(16, 16, ILC_COLOR8|ILC_MASK, 0, 3);
+ {// workarround of 4bit forced images
+ HBITMAP hScrBM = (HBITMAP)LoadImage(YAMNVar.hInst,MAKEINTRESOURCE(IDB_ICONS), IMAGE_BITMAP, 0, 0,LR_SHARED);
+ ImageList_AddMasked(CSImages, hScrBM, RGB( 255, 0, 255 ));
+ DeleteObject(hScrBM);
+ }
+ for (i=0,k=0; i<ICONSNUMBER; i++){
+ switch (i){
+ case 0: case 3: case 4: case 7: hYamnIcons[i] = LoadIcon(YAMNVar.hInst,MAKEINTRESOURCE(iconIndexes[i])); break;
+ case 6: hYamnIcons[i] = hYamnIcons[4]; break;
+ default: hYamnIcons[i] = ImageList_ExtractIcon(NULL, CSImages, k); k++;
+ }
+ }
+
+ //Registering YAMN as protocol
+ PROTOCOLDESCRIPTOR pd;
+
+ memset(&pd,0,sizeof(pd));
+ pd.cbSize=sizeof(pd);
+ pd.szName=ProtoName;
+ pd.type=PROTOTYPE_PROTOCOL;
+
+ CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd);
+
+ if(NULL==(ProfileName=new WCHAR[MAX_PATH]))
+ return 1;
+
+ CallService(MS_DB_GETPROFILENAME,(WPARAM)sizeof(pn),(LPARAM)&(*pn)); //not to pass entire array to fcn
+ if(NULL!=(fc=strrchr(pn,(int)'.')))
+ *fc=0;
+ MultiByteToWideChar(CP_ACP,MB_USEGLYPHCHARS,pn,-1,ProfileName,(int)strlen(pn)+1);
+
+ if(NULL==(AccountStatusCS=new CRITICAL_SECTION))
+ return 1;
+ if(NULL==(FileWritingCS=new CRITICAL_SECTION))
+ return 1;
+ if(NULL==(PluginRegCS=new CRITICAL_SECTION))
+ return 1;
+
+ InitializeCriticalSection(AccountStatusCS);
+ InitializeCriticalSection(FileWritingCS);
+ InitializeCriticalSection(PluginRegCS);
+
+ if(NULL==(NoWriterEV=CreateEvent(NULL,TRUE,TRUE,NULL)))
+ return 1;
+ if(NULL==(WriteToFileEV=CreateEvent(NULL,FALSE,FALSE,NULL)))
+ return 1;
+ if(NULL==(ExitEV=CreateEvent(NULL,TRUE,FALSE,NULL)))
+ return 1;
+// AccountWriterSO=new SCOUNTER(NoWriterEV);
+
+ NewMailSound.pszDescription=Translate(YAMN_NEWMAILSNDDESC);
+ ConnectFailureSound.pszDescription=Translate(YAMN_CONNECTFAILSNDDESC);
+
+ PosX=DBGetContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBPOSX,0);
+ PosY=DBGetContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBPOSY,0);
+ SizeX=DBGetContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBSIZEX,800);
+ SizeY=DBGetContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBSIZEY,200);
+
+ HeadPosX=DBGetContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGPOSX,0);
+ HeadPosY=DBGetContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGPOSY,0);
+ HeadSizeX=DBGetContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGSIZEX,690);
+ HeadSizeY=DBGetContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGSIZEY,300);
+ HeadSplitPos=DBGetContactSettingWord(NULL,YAMN_DBMODULE,YAMN_DBMSGPOSSPLIT,250);
+
+ optDateTime=DBGetContactSettingByte(NULL,YAMN_DBMODULE,YAMN_DBTIMEOPTIONS,optDateTime);
+
+//Create new window queues for broadcast messages
+ YAMNVar.MessageWnds=(HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST,0,0);
+ YAMNVar.NewMailAccountWnd=(HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST,0,0);
+ YAMNVar.Shutdown=FALSE;
+
+ hCurSplitNS = LoadCursor(NULL, IDC_SIZENS);
+ hCurSplitWE = LoadCursor(NULL, IDC_SIZEWE);
+
+#ifdef YAMN_DEBUG
+ InitDebug();
+#endif
+
+
+ CreateServiceFunctions();
+
+ CallService(MS_SKIN_ADDNEWSOUND,0,(LPARAM)&NewMailSound);
+ CallService(MS_SKIN_ADDNEWSOUND,0,(LPARAM)&ConnectFailureSound);
+
+ /*
+ // this does nothing - these event are never fired
+ hNewMailHook=CreateHookableEvent(ME_YAMN_NEWMAIL);
+ hUninstallPluginsHook=CreateHookableEvent(ME_YAMN_UNINSTALLPLUGINS);
+ */
+
+ HookEvents();
+
+ if (!bIcolibEmbededInCore)
+ SetDefaultProtocolIcons();
+
+ LoadPlugins();
+
+ InitVSApi();
+
+ WordToModAndVk(DBGetContactSettingWord(NULL,YAMN_DBMODULE,YAMN_HKCHECKMAIL,YAMN_DEFAULTHK),&mod,&vk);
+
+//Create thread for hotkey
+ WORD HotKey = MAKEWORD((BYTE)vk,(BYTE)mod);
+ CloseHandle(CreateThread(NULL,0,YAMNHotKeyThread,(LPVOID)HotKey,0,&HotKeyThreadID));
+//Create thread that will be executed every second
+ if(!(SecTimer=SetTimer(NULL,0,1000,(TIMERPROC)TimerProc)))
+ return 1;
+
+
+#ifdef YAMN_VER_BETA
+ #ifdef YAMN_VER_BETA_CRASHONLY
+ MessageBox(NULL,"This YAMN beta version is intended for testing. After crash, you should send report to author. Please read included readme when available. Thank you.","YAMN beta",MB_OK);
+ #else
+ MessageBox(NULL,"This YAMN beta version is intended for testing. You should inform author if it works or when it does not work. Please read included readme when available. Thank you.","YAMN beta",MB_OK);
+ #endif
+#endif
+#ifdef YAMN_DEBUG
+ MessageBox(NULL,"This YAMN creates extended debug logfiles. It is not intended for general use.","YAMN beta",MB_OK);
+#endif
+
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) UninstallEx(PLUGINUNINSTALLPARAMS* ppup)
+{
+ const char* DocFiles[]={"YAMN-License.txt","YAMN-Readme.txt","YAMN-Readme.developers.txt",NULL};
+
+ typedef int (* UNINSTALLFILTERFCN)();
+ UNINSTALLFILTERFCN UninstallFilter;
+
+ PUIRemoveSkinSound(YAMN_NEWMAILSOUND);
+ PUIRemoveSkinSound(YAMN_CONNECTFAILSOUND);
+
+ if(UninstallPlugins)
+ {
+ for(int i=0;i<iDllPlugins;i++)
+ {
+ if(NULL!=(UninstallFilter=(UNINSTALLFILTERFCN)GetProcAddress(hDllPlugins[i],"UninstallFilter")))
+ UninstallFilter();
+
+ FreeLibrary(hDllPlugins[i]);
+ hDllPlugins[i]=NULL; //for safety
+ }
+ iDllPlugins = 0;
+ if(hDllPlugins){
+ free((void *)hDllPlugins);
+ hDllPlugins = NULL;
+ }
+
+// NotifyEventHooks(ME_YAMN_UNINSTALLPLUGINS,0,0);
+ }
+ UninstallPOP3(ppup);
+
+ MessageBoxA(NULL,"You have to delete manually YAMN plugins located in \"Plugins/YAMN\" folder.","YAMN uninstalling",MB_OK|MB_ICONINFORMATION);
+ PUIRemoveFilesInDirectory(ppup->pszDocsPath,DocFiles);
+ if(ppup->bDoDeleteSettings)
+ PUIRemoveDbModule("YAMN");
+ return 0;
+}
+
+int Shutdown(WPARAM,LPARAM)
+{
+ DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGPOSX,HeadPosX);
+ DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGPOSY,HeadPosY);
+ DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGSIZEX,HeadSizeX);
+ DBWriteContactSettingDword(NULL,YAMN_DBMODULE,YAMN_DBMSGSIZEY,HeadSizeY);
+ DBWriteContactSettingWord(NULL,YAMN_DBMODULE,YAMN_DBMSGPOSSPLIT,HeadSplitPos);
+ YAMNVar.Shutdown=TRUE;
+// CallService(MS_TTB_REMOVEBUTTON,(WPARAM)hTTButton,0); //this often leads to deadlock in Miranda (bug in Miranda)
+ KillTimer(NULL,SecTimer);
+
+ UnregisterProtoPlugins();
+ UnregisterFilterPlugins();
+ return 0;
+}
+
+//We undo all things from Load()
+extern "C" int __declspec(dllexport) Unload(void)
+{
+#ifdef YAMN_DEBUG
+ UnInitDebug();
+#endif
+ DestroyCursor(hCurSplitNS);
+ DestroyCursor(hCurSplitWE);
+
+ CloseHandle(NoWriterEV);
+ CloseHandle(WriteToFileEV);
+ CloseHandle(ExitEV);
+
+ FreeVSApi();
+
+ DeleteCriticalSection(AccountStatusCS);
+ delete AccountStatusCS;
+ DeleteCriticalSection(FileWritingCS);
+ delete FileWritingCS;
+ DeleteCriticalSection(PluginRegCS);
+
+ delete PluginRegCS;
+ UnhookEvents();
+ DestroyServiceFunctions();
+
+ UnloadPlugins();
+
+ delete [] CodePageNamesSupp;
+ delete [] szMirandaDir;
+ delete [] UserDirectory;
+ delete [] szProfileDir;
+ delete [] ProfileName;
+ return 0;
+}
+
+void LoadPlugins()
+{
+ HANDLE hFind;
+ WIN32_FIND_DATA fd;
+ char szSearchPath[MAX_PATH];
+ char szPluginPath[MAX_PATH];
+ lstrcpy(szSearchPath,szMirandaDir);
+ lstrcat(szSearchPath,"\\Plugins\\YAMN\\*.dll");
+ typedef INT_PTR (*LOADFILTERFCN)(MIRANDASERVICE GetYAMNFcn);
+
+ hDllPlugins=NULL;
+
+ if(INVALID_HANDLE_VALUE!=(hFind=FindFirstFile(szSearchPath,&fd)))
+ {
+ do
+ { //rewritten from Miranda sources... Needed because Win32 API has a bug in FindFirstFile, search is done for *.dlllllll... too
+ char *dot=strrchr(fd.cFileName,'.');
+ if(dot)
+ { // we have a dot
+ int len=(int)strlen(fd.cFileName); // find the length of the string
+ char* end=fd.cFileName+len; // get a pointer to the NULL
+ int safe=(end-dot)-1; // figure out how many chars after the dot are "safe", not including NULL
+
+ if((safe!=3) || (lstrcmpi(dot+1,"dll")!=0)) //not bound, however the "dll" string should mean only 3 chars are compared
+ continue;
+ }
+ else
+ continue;
+
+ HINSTANCE hDll;
+ LOADFILTERFCN LoadFilter;
+
+ lstrcpy(szPluginPath,szMirandaDir);
+ lstrcat(szPluginPath,"\\Plugins\\YAMN\\");
+ lstrcat(szPluginPath,fd.cFileName);
+ if((hDll=LoadLibrary(szPluginPath))==NULL) continue;
+ LoadFilter=(LOADFILTERFCN)GetProcAddress(hDll,"LoadFilter");
+ if(NULL==LoadFilter)
+ {
+ FreeLibrary(hDll);
+ hDll=NULL;
+ continue;
+ }
+ if(!(*LoadFilter)(GetFcnPtrSvc))
+ {
+ FreeLibrary(hDll);
+ hDll=NULL;
+ }
+
+ if(hDll!=NULL)
+ {
+ hDllPlugins=(HINSTANCE *)realloc((void *)hDllPlugins,(iDllPlugins+1)*sizeof(HINSTANCE));
+ hDllPlugins[iDllPlugins++]=hDll;
+ }
+ } while(FindNextFile(hFind,&fd));
+ FindClose(hFind);
+ }
+}
+
+void UnloadPlugins()
+{
+ for(int i=iDllPlugins-1;i>=0;i--) {
+ if(FreeLibrary(hDllPlugins[i])){
+ hDllPlugins[i]=NULL; //for safety
+ iDllPlugins --;
+ }
+ }
+ if(hDllPlugins){
+ free((void *)hDllPlugins);
+ hDllPlugins = NULL;
+ }
+}
+
+void GetIconSize(HICON hIcon, int* sizeX, int* sizeY)
+{
+ ICONINFO ii;
+ BITMAP bm;
+ GetIconInfo(hIcon, &ii);
+ GetObject(ii.hbmColor, sizeof(bm), &bm);
+ if (sizeX != NULL) *sizeX = bm.bmWidth;
+ if (sizeY != NULL) *sizeY = bm.bmHeight;
+ DeleteObject(ii.hbmMask);
+ DeleteObject(ii.hbmColor);
+}
+
+HBITMAP LoadBmpFromIcon(HICON hIcon)
+{
+ HBITMAP hBmp, hoBmp;
+ HDC hdc, hdcMem;
+ HBRUSH hBkgBrush;
+
+ int IconSizeX = 16;
+ int IconSizeY = 16;
+
+ //GetIconSize(hIcon, &IconSizeX, &IconSizeY);
+
+ //DebugLog(SynchroFile,"Icon size %i %i\n",IconSizeX,IconSizeY);
+
+ if ((IconSizeX == 0) || (IconSizeY == 0))
+ {
+ IconSizeX = 16;
+ IconSizeY = 16;
+ }
+
+ RECT rc;
+ BITMAPINFOHEADER bih = {0};
+ int widthBytes;
+
+ hBkgBrush = CreateSolidBrush(GetSysColor(COLOR_3DFACE));
+ bih.biSize = sizeof(bih);
+ bih.biBitCount = 24;
+ bih.biPlanes = 1;
+ bih.biCompression = BI_RGB;
+ bih.biHeight = IconSizeY;
+ bih.biWidth = IconSizeX;
+ widthBytes = ((bih.biWidth*bih.biBitCount + 31) >> 5) * 4;
+ rc.top = rc.left = 0;
+ rc.right = bih.biWidth;
+ rc.bottom = bih.biHeight;
+ hdc = GetDC(NULL);
+ hBmp = CreateCompatibleBitmap(hdc, bih.biWidth, bih.biHeight);
+ hdcMem = CreateCompatibleDC(hdc);
+ hoBmp = (HBITMAP)SelectObject(hdcMem, hBmp);
+ FillRect(hdcMem, &rc, hBkgBrush);
+ DrawIconEx(hdcMem, 0, 0, hIcon, bih.biWidth, bih.biHeight, 0, NULL, DI_NORMAL);
+ SelectObject(hdcMem, hoBmp);
+
+ return hBmp;
+}
+
+int AddTopToolbarIcon(WPARAM,LPARAM)
+{
+ TTBButton Button=
+ {
+ sizeof(TTBButton),
+ NULL,
+ NULL,
+ NULL,
+ MS_YAMN_FORCECHECK,
+ TTBBF_VISIBLE | TTBBF_SHOWTOOLTIP, // | TTBBF_DRAWBORDER,
+ 0,0,0,0,
+ NULL
+ };
+
+ if(!DBGetContactSettingByte(NULL,YAMN_DBMODULE,YAMN_TTBFCHECK,1))
+ return 1;
+
+ Button.name=Translate("Check mail");
+
+ Button.hbBitmapUp = LoadBmpFromIcon(hYamnIcons[5]);
+ Button.hbBitmapDown = LoadBmpFromIcon(hYamnIcons[6]); //LoadBitmap(YAMNVar.hInst,MAKEINTRESOURCE(IDB_BMTTB));
+
+ if((HANDLE)-1==(hTTButton=(HANDLE)CallService(MS_TTB_ADDBUTTON,(WPARAM)&Button,(LPARAM)0)))
+ return 1;
+ CallService(MS_TTB_SETBUTTONOPTIONS,MAKEWPARAM((WORD)TTBO_TIPNAME,(WORD)hTTButton),(LPARAM)Translate("Check mail"));
+ return 0;
+}
+
+int UninstallQuestionSvc(WPARAM wParam,LPARAM)
+{
+// if(strcmp((char *)wParam,Translate("Yet Another Mail Notifier")))
+// return 0;
+ switch(MessageBoxA(NULL,Translate("Do you also want to remove native YAMN plugins settings?"),Translate("YAMN uninstalling"),MB_YESNOCANCEL|MB_ICONQUESTION))
+ {
+ case IDYES:
+ UninstallPlugins=TRUE;
+ break;
+ case IDNO:
+ UninstallPlugins=FALSE;
+ break;
+ case IDCANCEL:
+ return 1;
+ }
+ return 0;
+}
diff --git a/yamn/main.h b/yamn/main.h new file mode 100644 index 0000000..21923ae --- /dev/null +++ b/yamn/main.h @@ -0,0 +1,66 @@ +#ifndef __MAIN_H
+#define __MAIN_H
+
+#ifdef __GNUC__
+ #define __try
+ #define __except(x) if (0) /* don't execute handler */
+ #define __finally
+ #define _try __try
+ #define _except __except
+ #define _finally __finally
+#endif
+//For updater
+//#define YAMN_9x
+#ifndef WIN2IN1
+#ifdef YAMN_9x
+ #define YAMN_SHORTNAME "YAMN tweety win9x"
+ #define YAMN_FILENAME "yamn_9x"
+#else
+ #define YAMN_SHORTNAME "YAMN tweety"
+ #define YAMN_FILENAME "yamn"
+#endif
+#else
+ #define YAMN_SHORTNAME "YAMN tweety 2in1"
+ #define YAMN_FILENAME "yamn"
+#endif //WIN2IN1
+
+#include "version.h"
+#define YAMN_NEWMAILSNDDESC "YAMN: new mail message"
+#define YAMN_CONNECTFAILSNDDESC "YAMN: connect failed"
+#define YAMN_CONNECTFAILSOUND "YAMN/Sound/ConnectFail"
+#define YAMN_NEWMAILSOUND "YAMN/Sound/NewMail"
+
+#define YAMN_DBMODULE "YAMN"
+#define YAMN_DBPOSX "MailBrowserWinX"
+#define YAMN_DBPOSY "MailBrowserWinY"
+#define YAMN_DBSIZEX "MailBrowserWinW"
+#define YAMN_DBSIZEY "MailBrowserWinH"
+#define YAMN_DBMSGPOSX "MailMessageWinX"
+#define YAMN_DBMSGPOSY "MailMessageWinY"
+#define YAMN_DBMSGSIZEX "MailMessageWinW"
+#define YAMN_DBMSGSIZEY "MailMessageWinH"
+#define YAMN_DBMSGPOSSPLIT "MailMessageSplitY"
+#define YAMN_HKCHECKMAIL "HKCheckMail"
+#define YAMN_TTBFCHECK "ForceCheckTTB"
+#define YAMN_SHOWMAINMENU "ShowMainMenu"
+#define YAMN_CLOSEDELETE "CloseOnDelete"
+#define YAMN_SHOWASPROTO "ShowAsProtcol"
+#define YAMN_DBTIMEOPTIONS "MailBrowserTimeOpts"
+
+#define YAMN_DEFAULTHK MAKEWORD(VK_F12,MOD_CONTROL)
+
+#define SHOWDATELONG 0x01
+#define SHOWDATENOTODAY 0x02
+#define SHOWDATENOSECONDS 0x04
+
+extern unsigned char optDateTime;
+
+void UnloadPlugins();
+
+// Loading Icon and checking for icolib
+void LoadIcons();
+extern int iconIndexes[];
+
+
+#endif
+
diff --git a/yamn/mingw/base.dev b/yamn/mingw/base.dev new file mode 100644 index 0000000..42e2fab --- /dev/null +++ b/yamn/mingw/base.dev @@ -0,0 +1,69 @@ +[Project]
+FileName=base.dev
+Name=base
+Ver=1
+IsCpp=1
+Type=3
+Compiler=-D__GNUWIN32__ -mcpu=i486 -D_M_IX86=400 -W -fno-inline -DWIN32 -DNDEBUG -D_WINDOWS_@@_
+CppCompiler=-D__GNUWIN32__ -mcpu=i486 -D_M_IX86=400 -W -fno-inline -DWIN32 -DNDEBUG -D_WINDOWS_@@_
+Includes=../../../include
+Linker=-lkernel32 -luser32_@@_
+Libs=
+UnitCount=2
+Folders="Header Files","Resource Files","Source Files"
+ObjFiles=
+PrivateResource=
+ResourceIncludes=
+MakeIncludes=
+Icon=
+ExeOutput=binfilter
+ObjectOutput=objbase
+OverrideOutput=0
+OverrideOutputName=base.dll
+HostApplication=
+CommandLine=
+UseCustomMakefile=1
+CustomMakefile=base.win
+IncludeVersionInfo=0
+SupportXPThemes=0
+CompilerSet=0
+CompilerSettings=0010000001001000000100
+
+[Unit1]
+FileName=..\filter\base\maindll.cpp
+Folder="Source Files"
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit2]
+FileName=..\filter\base\debug.cpp
+Folder="Source Files"
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[VersionInfo]
+Major=0
+Minor=1
+Release=1
+Build=1
+LanguageID=1033
+CharsetID=1252
+CompanyName=
+FileVersion=0.1
+FileDescription=Developed using the Dev-C++ IDE
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=base.dll
+ProductName=base
+ProductVersion=0.1
+AutoIncBuildNr=0
+
diff --git a/yamn/mingw/base.win b/yamn/mingw/base.win new file mode 100644 index 0000000..3af9e7a --- /dev/null +++ b/yamn/mingw/base.win @@ -0,0 +1,38 @@ +# Project: base
+# Makefile created by Dev-C++ 4.9.9.2
+
+CPP = g++.exe
+CC = gcc.exe
+WINDRES = windres.exe
+RES =
+OBJ = objbase/maindll.o objbase/debug.o $(RES)
+LINKOBJ = objbase/maindll.o objbase/debug.o $(RES)
+LIBS = -lkernel32 -luser32 -s
+INCS = -I"../../../include"
+CXXINCS = -I"../../../include"
+BIN = binfilter/base.dll
+CXXFLAGS = $(CXXINCS) -D__GNUWIN32__ -W -fno-inline -DWIN32 -DNDEBUG -D_WINDOWS -w -fweb -frename-registers -Os
+CFLAGS = $(INCS) -D__GNUWIN32__ -W -fno-inline -DWIN32 -DNDEBUG -D_WINDOWS -w -fweb -frename-registers -Os
+RM = rm -f
+
+.PHONY: all all-before all-after clean clean-custom
+
+all: all-before binfilter/base.dll all-after
+
+
+clean: clean-custom
+ ${RM} $(OBJ) $(BIN)
+
+DLLWRAP=dllwrap.exe
+DEFFILE=objbase/libbase.def
+STATICLIB=objbase/libbase.a
+
+$(BIN): $(LINKOBJ)
+# $(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
+ $(CPP) $(LINKOBJ) $(LIBS) -o $(BIN) -mdll
+
+objbase/maindll.o: ../filter/base/maindll.cpp
+ $(CPP) -c ../filter/base/maindll.cpp -o objbase/maindll.o $(CXXFLAGS)
+
+objbase/debug.o: ../filter/base/debug.cpp
+ $(CPP) -c ../filter/base/debug.cpp -o objbase/debug.o $(CXXFLAGS)
diff --git a/yamn/mingw/simple.dev b/yamn/mingw/simple.dev new file mode 100644 index 0000000..617324b --- /dev/null +++ b/yamn/mingw/simple.dev @@ -0,0 +1,59 @@ +[Project]
+FileName=simple.dev
+Name=simple
+Ver=1
+IsCpp=1
+Type=3
+Compiler=-D__GNUWIN32__ -mcpu=i486 -D_M_IX86=400 -W -fno-inline -DWIN32 -DNDEBUG -D_WINDOWS_@@_
+CppCompiler=-D__GNUWIN32__ -mcpu=i486 -D_M_IX86=400 -W -fno-inline -DWIN32 -DNDEBUG -D_WINDOWS_@@_
+Includes=../../../include
+Linker=-lkernel32 -luser32_@@_
+Libs=
+UnitCount=1
+Folders="Header Files","Resource Files","Source Files"
+ObjFiles=
+PrivateResource=
+ResourceIncludes=
+MakeIncludes=
+Icon=
+ExeOutput=binfilter
+ObjectOutput=objsimple
+OverrideOutput=0
+OverrideOutputName=simple.dll
+HostApplication=
+CommandLine=
+UseCustomMakefile=1
+CustomMakefile=simple.win
+IncludeVersionInfo=0
+SupportXPThemes=0
+CompilerSet=0
+CompilerSettings=0010000001001000000100
+
+[Unit1]
+FileName=..\filter\Simple\maindll.cpp
+Folder="Source Files"
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[VersionInfo]
+Major=0
+Minor=1
+Release=1
+Build=1
+LanguageID=1033
+CharsetID=1252
+CompanyName=
+FileVersion=0.1
+FileDescription=Developed using the Dev-C++ IDE
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=simple.dll
+ProductName=simple
+ProductVersion=0.1
+AutoIncBuildNr=0
+
diff --git a/yamn/mingw/simple.win b/yamn/mingw/simple.win new file mode 100644 index 0000000..fc9e3c6 --- /dev/null +++ b/yamn/mingw/simple.win @@ -0,0 +1,35 @@ +# Project: simple
+# Makefile created by Dev-C++ 4.9.9.2
+
+CPP = g++.exe
+CC = gcc.exe
+WINDRES = windres.exe
+RES =
+OBJ = objsimple/maindll.o $(RES)
+LINKOBJ = objsimple/maindll.o $(RES)
+LIBS = -lkernel32 -luser32 -s
+INCS = -I"../../../include"
+CXXINCS = -I"../../../include"
+BIN = binfilter/simple.dll
+CXXFLAGS = $(CXXINCS) -D__GNUWIN32__ -W -fno-inline -DWIN32 -DNDEBUG -D_WINDOWS -w -fweb -frename-registers -Os
+CFLAGS = $(INCS) -D__GNUWIN32__ -W -fno-inline -DWIN32 -DNDEBUG -D_WINDOWS -w -fweb -frename-registers -Os
+RM = rm -f
+
+.PHONY: all all-before all-after clean clean-custom
+
+all: all-before binfilter/simple.dll all-after
+
+
+clean: clean-custom
+ ${RM} $(OBJ) $(BIN)
+
+DLLWRAP=dllwrap.exe
+DEFFILE=objsimple/libsimple.def
+STATICLIB=objsimple/libsimple.a
+
+$(BIN): $(LINKOBJ)
+# $(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
+ $(CPP) $(LINKOBJ) $(LIBS) -o $(BIN) -mdll
+
+objsimple/maindll.o: ../filter/Simple/maindll.cpp
+ $(CPP) -c ../filter/Simple/maindll.cpp -o objsimple/maindll.o $(CXXFLAGS)
diff --git a/yamn/mingw/yamn-2in1.dev b/yamn/mingw/yamn-2in1.dev new file mode 100644 index 0000000..615e63f --- /dev/null +++ b/yamn/mingw/yamn-2in1.dev @@ -0,0 +1,469 @@ +[Project]
+FileName=yamn-2in1.dev
+Name=YAMN
+Ver=1
+IsCpp=1
+Type=3
+Compiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -DWIN2IN1
+CppCompiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -DWIN2IN1
+Includes=../../../include
+Linker=-lunicows -lkernel32 -luser32 -lshell32 -lmsvcrt -lcomctl32 -lcomdlg32 -lgdi32 -lwsock32 --image-base "0x60010000"
+Libs=../libs
+UnitCount=36
+Folders=Documentation,"Resource Files",YAMN,YAMN/Header,YAMN/include,"YAMN/Mail browser, dialogs",YAMN/Mails,"YAMN/POP3 plugin"
+ObjFiles=
+PrivateResource=YAMN_private.rc
+ResourceIncludes=../resources
+MakeIncludes=
+Icon=
+ExeOutput=bin2in1
+ObjectOutput=objs2in1
+OverrideOutput=1
+OverrideOutputName=YAMN.dll
+HostApplication=
+CommandLine=
+UseCustomMakefile=1
+CustomMakefile=yamn-2in1.win
+IncludeVersionInfo=0
+SupportXPThemes=0
+CompilerSet=0
+CompilerSettings=0010000001001000000100
+
+[Unit1]
+FileName=..\browser\badconnect.cpp
+Folder=YAMN/Mail browser, dialogs
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit2]
+FileName=..\browser\mailbrowser.cpp
+Folder=YAMN/Mail browser, dialogs
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit3]
+FileName=..\mails\decode.cpp
+Folder=YAMN/Mails
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit4]
+FileName=..\mails\mails.cpp
+Folder=YAMN/Mails
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit5]
+FileName=..\mails\mime.cpp
+Folder=YAMN/Mails
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit6]
+FileName=..\proto\md5.c
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=0
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit7]
+FileName=..\proto\netlib.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit8]
+FileName=..\proto\pop3\pop3.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit9]
+FileName=..\proto\pop3\pop3comm.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit10]
+FileName=..\proto\pop3\pop3opt.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit11]
+FileName=..\proto\ssl.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit12]
+FileName=..\debug.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit13]
+FileName=..\main.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit14]
+FileName=..\proto\pop3\pop3.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit15]
+FileName=..\proto\pop3\pop3comm.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit16]
+FileName=..\proto\pop3\pop3opt.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit17]
+FileName=..\yamn.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit18]
+FileName=..\include\m_kbdnotify.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit19]
+FileName=..\include\m_popup.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit20]
+FileName=..\include\m_toptoolbar.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit21]
+FileName=..\include\m_uninstaller.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit22]
+FileName=..\include\m_updater.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit23]
+FileName=..\account.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit24]
+FileName=..\ChangeLog.txt
+Folder=Documentation
+Compile=0
+CompileCpp=1
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit25]
+FileName=..\debug.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit26]
+FileName=..\filterplugin.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit27]
+FileName=..\main.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit28]
+FileName=..\protoplugin.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit29]
+FileName=..\services.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit30]
+FileName=..\synchro.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit31]
+FileName=..\yamn.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit32]
+FileName=..\resources\ttbfcheck.bmp
+Folder=Resource Files
+Compile=0
+CompileCpp=1
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit33]
+FileName=..\resources\YAMN.rc
+Folder=Resource Files
+Compile=1
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit34]
+FileName=..\docs\language.pop3.txt
+Folder=Documentation
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit35]
+FileName=..\docs\language.txt
+Folder=Documentation
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit36]
+FileName=..\m_messages.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit37]
+FileName=..\resources\icoyamn2.ico
+Folder=Resource Files
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit38]
+FileName=..\resources\icoyamn3.ico
+Folder=Resource Files
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit39]
+FileName=..\resources\ttbfcheck.bmp
+Folder=Resource Files
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit40]
+FileName=..\resources\YAMN.rc
+Folder=Resource Files
+Compile=1
+CompileCpp=1
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit41]
+FileName=..\docs\language.pop3.txt
+Folder=Documentation
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit42]
+FileName=..\docs\language.txt
+Folder=Documentation
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[VersionInfo]
+Major=0
+Minor=1
+Release=1
+Build=1
+LanguageID=1033
+CharsetID=1252
+CompanyName=
+FileVersion=0.1
+FileDescription=Developed using the Dev-C++ IDE
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=YAMN.exe
+ProductName=YAMN
+ProductVersion=0.1
+AutoIncBuildNr=0
+
diff --git a/yamn/mingw/yamn-2in1.win b/yamn/mingw/yamn-2in1.win new file mode 100644 index 0000000..5b90f86 --- /dev/null +++ b/yamn/mingw/yamn-2in1.win @@ -0,0 +1,92 @@ +# Project: YAMN
+# Makefile created by Dev-C++ 4.9.9.2
+
+CPP = g++.exe
+CC = gcc.exe
+WINDRES = windres.exe
+RES = objs2in1/YAMN.res
+OBJ = objs2in1/badconnect.o objs2in1/mailbrowser.o objs2in1/decode.o objs2in1/mails.o objs2in1/mime.o objs2in1/md5.o objs2in1/netlib.o objs2in1/pop3.o objs2in1/pop3comm.o objs2in1/pop3opt.o objs2in1/ssl.o objs2in1/account.o objs2in1/debug.o objs2in1/filterplugin.o objs2in1/main.o objs2in1/protoplugin.o objs2in1/services.o objs2in1/synchro.o objs2in1/yamn.o $(RES)
+LINKOBJ = objs2in1/badconnect.o objs2in1/mailbrowser.o objs2in1/decode.o objs2in1/mails.o objs2in1/mime.o objs2in1/md5.o objs2in1/netlib.o objs2in1/pop3.o objs2in1/pop3comm.o objs2in1/pop3opt.o objs2in1/ssl.o objs2in1/account.o objs2in1/debug.o objs2in1/filterplugin.o objs2in1/main.o objs2in1/protoplugin.o objs2in1/services.o objs2in1/synchro.o objs2in1/yamn.o $(RES)
+LIBS = -L"../libs" -lunicows -lkernel32 -luser32 -lshell32 -lmsvcrt -lcomctl32 -lcomdlg32 -lgdi32 -lwsock32 -s
+INCS = -I"../../../include"
+CXXINCS = -I"../../../include"
+BIN = bin2in1/yamn.dll
+CXXFLAGS = $(CXXINCS) -D__GNUWIN32__ -W -fno-inline -DWIN32 -DNDEBUG -D_WINDOWS -DWIN2IN1 -w -fweb -frename-registers -Os
+CFLAGS = $(INCS) -D__GNUWIN32__ -W -fno-inline -DWIN32 -DNDEBUG -D_WINDOWS -DWIN2IN1 -w -fweb -frename-registers -Os
+RM = rm -f
+
+.PHONY: all all-before all-after clean clean-custom
+
+all: all-before bin2in1/yamn.dll all-after
+
+
+clean: clean-custom
+ ${RM} $(OBJ) $(BIN)
+
+DLLWRAP=dllwrap.exe
+DEFFILE=bin2in1/libYAMN.def
+STATICLIB=bin2in1/libYAMN.a
+
+$(BIN): $(LINKOBJ)
+# $(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
+ $(CPP) $(LINKOBJ) $(LIBS) -o $(BIN) -mdll
+
+objs2in1/badconnect.o: ../browser/badconnect.cpp
+ $(CPP) -c ../browser/badconnect.cpp -o objs2in1/badconnect.o $(CXXFLAGS)
+
+objs2in1/mailbrowser.o: ../browser/mailbrowser.cpp
+ $(CPP) -c ../browser/mailbrowser.cpp -o objs2in1/mailbrowser.o $(CXXFLAGS)
+
+objs2in1/decode.o: ../mails/decode.cpp
+ $(CPP) -c ../mails/decode.cpp -o objs2in1/decode.o $(CXXFLAGS)
+
+objs2in1/mails.o: ../mails/mails.cpp
+ $(CPP) -c ../mails/mails.cpp -o objs2in1/mails.o $(CXXFLAGS)
+
+objs2in1/mime.o: ../mails/mime.cpp
+ $(CPP) -c ../mails/mime.cpp -o objs2in1/mime.o $(CXXFLAGS)
+
+objs2in1/md5.o: ../proto/md5.c
+ $(CC) -c ../proto/md5.c -o objs2in1/md5.o $(CFLAGS)
+
+objs2in1/netlib.o: ../proto/netlib.cpp
+ $(CPP) -c ../proto/netlib.cpp -o objs2in1/netlib.o $(CXXFLAGS)
+
+objs2in1/pop3.o: ../proto/pop3/pop3.cpp
+ $(CPP) -c ../proto/pop3/pop3.cpp -o objs2in1/pop3.o $(CXXFLAGS)
+
+objs2in1/pop3comm.o: ../proto/pop3/pop3comm.cpp
+ $(CPP) -c ../proto/pop3/pop3comm.cpp -o objs2in1/pop3comm.o $(CXXFLAGS)
+
+objs2in1/pop3opt.o: ../proto/pop3/pop3opt.cpp
+ $(CPP) -c ../proto/pop3/pop3opt.cpp -o objs2in1/pop3opt.o $(CXXFLAGS)
+
+objs2in1/ssl.o: ../proto/ssl.cpp
+ $(CPP) -c ../proto/ssl.cpp -o objs2in1/ssl.o $(CXXFLAGS)
+
+objs2in1/account.o: ../account.cpp
+ $(CPP) -c ../account.cpp -o objs2in1/account.o $(CXXFLAGS)
+
+objs2in1/debug.o: ../debug.cpp
+ $(CPP) -c ../debug.cpp -o objs2in1/debug.o $(CXXFLAGS)
+
+objs2in1/filterplugin.o: ../filterplugin.cpp
+ $(CPP) -c ../filterplugin.cpp -o objs2in1/filterplugin.o $(CXXFLAGS)
+
+objs2in1/main.o: ../main.cpp
+ $(CPP) -c ../main.cpp -o objs2in1/main.o $(CXXFLAGS)
+
+objs2in1/protoplugin.o: ../protoplugin.cpp
+ $(CPP) -c ../protoplugin.cpp -o objs2in1/protoplugin.o $(CXXFLAGS)
+
+objs2in1/services.o: ../services.cpp
+ $(CPP) -c ../services.cpp -o objs2in1/services.o $(CXXFLAGS)
+
+objs2in1/synchro.o: ../synchro.cpp
+ $(CPP) -c ../synchro.cpp -o objs2in1/synchro.o $(CXXFLAGS)
+
+objs2in1/yamn.o: ../yamn.cpp
+ $(CPP) -c ../yamn.cpp -o objs2in1/yamn.o $(CXXFLAGS)
+
+objs2in1/YAMN.res: ../resources/YAMN.rc
+ $(WINDRES) -i ../resources/YAMN.rc --input-format=rc -o objs2in1/YAMN.res -O coff --include-dir ../resources
diff --git a/yamn/mingw/yamn-w9x.dev b/yamn/mingw/yamn-w9x.dev new file mode 100644 index 0000000..b652000 --- /dev/null +++ b/yamn/mingw/yamn-w9x.dev @@ -0,0 +1,469 @@ +[Project]
+FileName=yamn-w9x.dev
+Name=YAMN
+Ver=1
+IsCpp=1
+Type=3
+Compiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -DWIN9X
+CppCompiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -DWIN9X
+Includes=../../../include
+Linker=-lunicows -lkernel32 -luser32 -lshell32 -lmsvcrt -lcomctl32 -lcomdlg32 -lgdi32 -lwsock32 --image-base "0x60010000"
+Libs=../libs
+UnitCount=36
+Folders=Documentation,"Resource Files",YAMN,YAMN/Header,YAMN/include,"YAMN/Mail browser, dialogs",YAMN/Mails,"YAMN/POP3 plugin"
+ObjFiles=
+PrivateResource=YAMN_private.rc
+ResourceIncludes=../resources
+MakeIncludes=
+Icon=
+ExeOutput=bin9x
+ObjectOutput=objs9x
+OverrideOutput=1
+OverrideOutputName=YAMN.dll
+HostApplication=
+CommandLine=
+UseCustomMakefile=1
+CustomMakefile=yamn-w9x.win
+IncludeVersionInfo=0
+SupportXPThemes=0
+CompilerSet=0
+CompilerSettings=0010000001001000000100
+
+[Unit1]
+FileName=..\browser\badconnect.cpp
+Folder=YAMN/Mail browser, dialogs
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit2]
+FileName=..\browser\mailbrowser.cpp
+Folder=YAMN/Mail browser, dialogs
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit3]
+FileName=..\mails\decode.cpp
+Folder=YAMN/Mails
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit4]
+FileName=..\mails\mails.cpp
+Folder=YAMN/Mails
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit5]
+FileName=..\mails\mime.cpp
+Folder=YAMN/Mails
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit6]
+FileName=..\proto\md5.c
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=0
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit7]
+FileName=..\proto\netlib.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit8]
+FileName=..\proto\pop3\pop3.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit9]
+FileName=..\proto\pop3\pop3comm.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit10]
+FileName=..\proto\pop3\pop3opt.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit11]
+FileName=..\proto\ssl.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit12]
+FileName=..\debug.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit13]
+FileName=..\main.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit14]
+FileName=..\proto\pop3\pop3.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit15]
+FileName=..\proto\pop3\pop3comm.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit16]
+FileName=..\proto\pop3\pop3opt.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit17]
+FileName=..\yamn.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit18]
+FileName=..\include\m_kbdnotify.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit19]
+FileName=..\include\m_popup.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit20]
+FileName=..\include\m_toptoolbar.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit21]
+FileName=..\include\m_uninstaller.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit22]
+FileName=..\include\m_updater.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit23]
+FileName=..\account.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit24]
+FileName=..\ChangeLog.txt
+Folder=Documentation
+Compile=0
+CompileCpp=1
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit25]
+FileName=..\debug.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit26]
+FileName=..\filterplugin.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit27]
+FileName=..\main.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit28]
+FileName=..\protoplugin.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit29]
+FileName=..\services.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit30]
+FileName=..\synchro.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit31]
+FileName=..\yamn.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit32]
+FileName=..\resources\ttbfcheck.bmp
+Folder=Resource Files
+Compile=0
+CompileCpp=1
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit33]
+FileName=..\resources\YAMN.rc
+Folder=Resource Files
+Compile=1
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit34]
+FileName=..\docs\language.pop3.txt
+Folder=Documentation
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit35]
+FileName=..\docs\language.txt
+Folder=Documentation
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit36]
+FileName=..\m_messages.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit37]
+FileName=..\resources\icoyamn2.ico
+Folder=Resource Files
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit38]
+FileName=..\resources\icoyamn3.ico
+Folder=Resource Files
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit39]
+FileName=..\resources\ttbfcheck.bmp
+Folder=Resource Files
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit40]
+FileName=..\resources\YAMN.rc
+Folder=Resource Files
+Compile=1
+CompileCpp=1
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit41]
+FileName=..\docs\language.pop3.txt
+Folder=Documentation
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit42]
+FileName=..\docs\language.txt
+Folder=Documentation
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[VersionInfo]
+Major=0
+Minor=1
+Release=1
+Build=1
+LanguageID=1033
+CharsetID=1252
+CompanyName=
+FileVersion=0.1
+FileDescription=Developed using the Dev-C++ IDE
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=YAMN.exe
+ProductName=YAMN
+ProductVersion=0.1
+AutoIncBuildNr=0
+
diff --git a/yamn/mingw/yamn-w9x.win b/yamn/mingw/yamn-w9x.win new file mode 100644 index 0000000..0e741d5 --- /dev/null +++ b/yamn/mingw/yamn-w9x.win @@ -0,0 +1,92 @@ +# Project: YAMN
+# Makefile created by Dev-C++ 4.9.9.2
+
+CPP = g++.exe
+CC = gcc.exe
+WINDRES = windres.exe
+RES = objs9x/YAMN.res
+OBJ = objs9x/badconnect.o objs9x/mailbrowser.o objs9x/decode.o objs9x/mails.o objs9x/mime.o objs9x/md5.o objs9x/netlib.o objs9x/pop3.o objs9x/pop3comm.o objs9x/pop3opt.o objs9x/ssl.o objs9x/account.o objs9x/debug.o objs9x/filterplugin.o objs9x/main.o objs9x/protoplugin.o objs9x/services.o objs9x/synchro.o objs9x/yamn.o $(RES)
+LINKOBJ = objs9x/badconnect.o objs9x/mailbrowser.o objs9x/decode.o objs9x/mails.o objs9x/mime.o objs9x/md5.o objs9x/netlib.o objs9x/pop3.o objs9x/pop3comm.o objs9x/pop3opt.o objs9x/ssl.o objs9x/account.o objs9x/debug.o objs9x/filterplugin.o objs9x/main.o objs9x/protoplugin.o objs9x/services.o objs9x/synchro.o objs9x/yamn.o $(RES)
+LIBS = -L"../libs" -lunicows -lkernel32 -luser32 -lshell32 -lmsvcrt -lcomctl32 -lcomdlg32 -lgdi32 -lwsock32 -s
+INCS = -I"../../../include"
+CXXINCS = -I"../../../include"
+BIN = bin9x/yamn.dll
+CXXFLAGS = $(CXXINCS) -D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -DWIN9X -w -fweb -frename-registers -Os
+CFLAGS = $(INCS) -D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -DWIN9X -w -fweb -frename-registers -Os
+RM = rm -f
+
+.PHONY: all all-before all-after clean clean-custom
+
+all: all-before bin9x/yamn.dll all-after
+
+
+clean: clean-custom
+ ${RM} $(OBJ) $(BIN)
+
+DLLWRAP=dllwrap.exe
+DEFFILE=bin9x/libYAMN.def
+STATICLIB=bin9x/libYAMN.a
+
+$(BIN): $(LINKOBJ)
+# $(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
+ $(CPP) $(LINKOBJ) $(LIBS) -o $(BIN) -mdll
+
+objs9x/badconnect.o: ../browser/badconnect.cpp
+ $(CPP) -c ../browser/badconnect.cpp -o objs9x/badconnect.o $(CXXFLAGS)
+
+objs9x/mailbrowser.o: ../browser/mailbrowser.cpp
+ $(CPP) -c ../browser/mailbrowser.cpp -o objs9x/mailbrowser.o $(CXXFLAGS)
+
+objs9x/decode.o: ../mails/decode.cpp
+ $(CPP) -c ../mails/decode.cpp -o objs9x/decode.o $(CXXFLAGS)
+
+objs9x/mails.o: ../mails/mails.cpp
+ $(CPP) -c ../mails/mails.cpp -o objs9x/mails.o $(CXXFLAGS)
+
+objs9x/mime.o: ../mails/mime.cpp
+ $(CPP) -c ../mails/mime.cpp -o objs9x/mime.o $(CXXFLAGS)
+
+objs9x/md5.o: ../proto/md5.c
+ $(CC) -c ../proto/md5.c -o objs9x/md5.o $(CFLAGS)
+
+objs9x/netlib.o: ../proto/netlib.cpp
+ $(CPP) -c ../proto/netlib.cpp -o objs9x/netlib.o $(CXXFLAGS)
+
+objs9x/pop3.o: ../proto/pop3/pop3.cpp
+ $(CPP) -c ../proto/pop3/pop3.cpp -o objs9x/pop3.o $(CXXFLAGS)
+
+objs9x/pop3comm.o: ../proto/pop3/pop3comm.cpp
+ $(CPP) -c ../proto/pop3/pop3comm.cpp -o objs9x/pop3comm.o $(CXXFLAGS)
+
+objs9x/pop3opt.o: ../proto/pop3/pop3opt.cpp
+ $(CPP) -c ../proto/pop3/pop3opt.cpp -o objs9x/pop3opt.o $(CXXFLAGS)
+
+objs9x/ssl.o: ../proto/ssl.cpp
+ $(CPP) -c ../proto/ssl.cpp -o objs9x/ssl.o $(CXXFLAGS)
+
+objs9x/account.o: ../account.cpp
+ $(CPP) -c ../account.cpp -o objs9x/account.o $(CXXFLAGS)
+
+objs9x/debug.o: ../debug.cpp
+ $(CPP) -c ../debug.cpp -o objs9x/debug.o $(CXXFLAGS)
+
+objs9x/filterplugin.o: ../filterplugin.cpp
+ $(CPP) -c ../filterplugin.cpp -o objs9x/filterplugin.o $(CXXFLAGS)
+
+objs9x/main.o: ../main.cpp
+ $(CPP) -c ../main.cpp -o objs9x/main.o $(CXXFLAGS)
+
+objs9x/protoplugin.o: ../protoplugin.cpp
+ $(CPP) -c ../protoplugin.cpp -o objs9x/protoplugin.o $(CXXFLAGS)
+
+objs9x/services.o: ../services.cpp
+ $(CPP) -c ../services.cpp -o objs9x/services.o $(CXXFLAGS)
+
+objs9x/synchro.o: ../synchro.cpp
+ $(CPP) -c ../synchro.cpp -o objs9x/synchro.o $(CXXFLAGS)
+
+objs9x/yamn.o: ../yamn.cpp
+ $(CPP) -c ../yamn.cpp -o objs9x/yamn.o $(CXXFLAGS)
+
+objs9x/YAMN.res: ../resources/YAMN.rc
+ $(WINDRES) -i ../resources/YAMN.rc --input-format=rc -o objs9x/YAMN.res -O coff --include-dir ../resources
diff --git a/yamn/mingw/yamn.dev b/yamn/mingw/yamn.dev new file mode 100644 index 0000000..d726894 --- /dev/null +++ b/yamn/mingw/yamn.dev @@ -0,0 +1,469 @@ +[Project]
+FileName=yamn.dev
+Name=YAMN
+Ver=1
+IsCpp=1
+Type=3
+Compiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS
+CppCompiler=-D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS
+Includes=../../../include
+Linker=-lkernel32 -luser32 -lshell32 -lmsvcrt -lcomctl32 -lcomdlg32 -lgdi32 -lwsock32 --image-base "0x60010000"
+Libs=
+UnitCount=36
+Folders=Documentation,"Resource Files",YAMN,YAMN/Header,YAMN/include,"YAMN/Mail browser, dialogs",YAMN/Mails,"YAMN/POP3 plugin"
+ObjFiles=
+PrivateResource=YAMN_private.rc
+ResourceIncludes=../resources
+MakeIncludes=
+Icon=
+ExeOutput=bin
+ObjectOutput=objs
+OverrideOutput=0
+OverrideOutputName=YAMN.dll
+HostApplication=
+CommandLine=
+UseCustomMakefile=1
+CustomMakefile=yamn.win
+IncludeVersionInfo=0
+SupportXPThemes=0
+CompilerSet=0
+CompilerSettings=0000000001001000000100
+
+[Unit1]
+FileName=..\browser\badconnect.cpp
+Folder=YAMN/Mail browser, dialogs
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit2]
+FileName=..\browser\mailbrowser.cpp
+Folder=YAMN/Mail browser, dialogs
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit3]
+FileName=..\mails\decode.cpp
+Folder=YAMN/Mails
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit4]
+FileName=..\mails\mails.cpp
+Folder=YAMN/Mails
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit5]
+FileName=..\mails\mime.cpp
+Folder=YAMN/Mails
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit6]
+FileName=..\proto\md5.c
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=0
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit7]
+FileName=..\proto\netlib.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit8]
+FileName=..\proto\pop3\pop3.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit9]
+FileName=..\proto\pop3\pop3comm.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit10]
+FileName=..\proto\pop3\pop3opt.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit11]
+FileName=..\proto\ssl.cpp
+Folder=YAMN/POP3 plugin
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit12]
+FileName=..\debug.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit13]
+FileName=..\main.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit14]
+FileName=..\proto\pop3\pop3.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit15]
+FileName=..\proto\pop3\pop3comm.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit16]
+FileName=..\proto\pop3\pop3opt.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit17]
+FileName=..\yamn.h
+Folder=YAMN/Header
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit18]
+FileName=..\include\m_kbdnotify.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit19]
+FileName=..\include\m_popup.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit20]
+FileName=..\include\m_toptoolbar.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit21]
+FileName=..\include\m_uninstaller.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit22]
+FileName=..\include\m_updater.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit23]
+FileName=..\account.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit24]
+FileName=..\ChangeLog.txt
+Folder=Documentation
+Compile=0
+CompileCpp=1
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit25]
+FileName=..\debug.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit26]
+FileName=..\filterplugin.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit27]
+FileName=..\main.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit28]
+FileName=..\protoplugin.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit29]
+FileName=..\services.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit30]
+FileName=..\synchro.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit31]
+FileName=..\yamn.cpp
+Folder=YAMN
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit32]
+FileName=..\resources\ttbfcheck.bmp
+Folder=Resource Files
+Compile=0
+CompileCpp=1
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit33]
+FileName=..\resources\YAMN.rc
+Folder=Resource Files
+Compile=1
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit34]
+FileName=..\docs\language.pop3.txt
+Folder=Documentation
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit35]
+FileName=..\docs\language.txt
+Folder=Documentation
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit36]
+FileName=..\m_messages.h
+Folder=YAMN/include
+Compile=1
+CompileCpp=1
+Link=1
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit37]
+FileName=..\resources\icoyamn2.ico
+Folder=Resource Files
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit38]
+FileName=..\resources\icoyamn3.ico
+Folder=Resource Files
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit39]
+FileName=..\resources\ttbfcheck.bmp
+Folder=Resource Files
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit40]
+FileName=..\resources\YAMN.rc
+Folder=Resource Files
+Compile=1
+CompileCpp=1
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit41]
+FileName=..\docs\language.pop3.txt
+Folder=Documentation
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[Unit42]
+FileName=..\docs\language.txt
+Folder=Documentation
+Compile=0
+CompileCpp=0
+Link=0
+Priority=1000
+OverrideBuildCmd=0
+BuildCmd=
+
+[VersionInfo]
+Major=0
+Minor=1
+Release=1
+Build=1
+LanguageID=1033
+CharsetID=1252
+CompanyName=
+FileVersion=0.1
+FileDescription=Developed using the Dev-C++ IDE
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=YAMN.exe
+ProductName=YAMN
+ProductVersion=0.1
+AutoIncBuildNr=0
+
diff --git a/yamn/mingw/yamn.win b/yamn/mingw/yamn.win new file mode 100644 index 0000000..d396e45 --- /dev/null +++ b/yamn/mingw/yamn.win @@ -0,0 +1,92 @@ +# Project: YAMN
+# Makefile created by Dev-C++ 4.9.9.2
+
+CPP = g++.exe
+CC = gcc.exe
+WINDRES = windres.exe
+RES = objs/YAMN.res
+OBJ = objs/badconnect.o objs/mailbrowser.o objs/decode.o objs/mails.o objs/mime.o objs/md5.o objs/netlib.o objs/pop3.o objs/pop3comm.o objs/pop3opt.o objs/ssl.o objs/account.o objs/debug.o objs/filterplugin.o objs/main.o objs/protoplugin.o objs/services.o objs/synchro.o objs/yamn.o $(RES)
+LINKOBJ = objs/badconnect.o objs/mailbrowser.o objs/decode.o objs/mails.o objs/mime.o objs/md5.o objs/netlib.o objs/pop3.o objs/pop3comm.o objs/pop3opt.o objs/ssl.o objs/account.o objs/debug.o objs/filterplugin.o objs/main.o objs/protoplugin.o objs/services.o objs/synchro.o objs/yamn.o $(RES)
+LIBS = -lkernel32 -luser32 -lshell32 -lmsvcrt -lcomctl32 -lcomdlg32 -lgdi32 -lwsock32 -s
+INCS = -I"../../../include"
+CXXINCS = -I"../../../include"
+BIN = bin/yamn.dll
+CXXFLAGS = $(CXXINCS) -D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -w -fweb -frename-registers -Os
+CFLAGS = $(INCS) -D__GNUWIN32__ -W -DWIN32 -DNDEBUG -D_WINDOWS -w -fweb -frename-registers -Os
+RM = rm -f
+
+.PHONY: all all-before all-after clean clean-custom
+
+all: all-before bin/yamn.dll all-after
+
+
+clean: clean-custom
+ ${RM} $(OBJ) $(BIN)
+
+DLLWRAP=dllwrap.exe
+DEFFILE=bin/libyamn.def
+STATICLIB=bin/libyamn.a
+
+$(BIN): $(LINKOBJ)
+# $(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(LINKOBJ) $(LIBS) -o $(BIN)
+ $(CPP) $(LINKOBJ) $(LIBS) -o $(BIN) -mdll
+
+objs/badconnect.o: ../browser/badconnect.cpp
+ $(CPP) -c ../browser/badconnect.cpp -o objs/badconnect.o $(CXXFLAGS)
+
+objs/mailbrowser.o: ../browser/mailbrowser.cpp
+ $(CPP) -c ../browser/mailbrowser.cpp -o objs/mailbrowser.o $(CXXFLAGS)
+
+objs/decode.o: ../mails/decode.cpp
+ $(CPP) -c ../mails/decode.cpp -o objs/decode.o $(CXXFLAGS)
+
+objs/mails.o: ../mails/mails.cpp
+ $(CPP) -c ../mails/mails.cpp -o objs/mails.o $(CXXFLAGS)
+
+objs/mime.o: ../mails/mime.cpp
+ $(CPP) -c ../mails/mime.cpp -o objs/mime.o $(CXXFLAGS)
+
+objs/md5.o: ../proto/md5.c
+ $(CC) -c ../proto/md5.c -o objs/md5.o $(CFLAGS)
+
+objs/netlib.o: ../proto/netlib.cpp
+ $(CPP) -c ../proto/netlib.cpp -o objs/netlib.o $(CXXFLAGS)
+
+objs/pop3.o: ../proto/pop3/pop3.cpp
+ $(CPP) -c ../proto/pop3/pop3.cpp -o objs/pop3.o $(CXXFLAGS)
+
+objs/pop3comm.o: ../proto/pop3/pop3comm.cpp
+ $(CPP) -c ../proto/pop3/pop3comm.cpp -o objs/pop3comm.o $(CXXFLAGS)
+
+objs/pop3opt.o: ../proto/pop3/pop3opt.cpp
+ $(CPP) -c ../proto/pop3/pop3opt.cpp -o objs/pop3opt.o $(CXXFLAGS)
+
+objs/ssl.o: ../proto/ssl.cpp
+ $(CPP) -c ../proto/ssl.cpp -o objs/ssl.o $(CXXFLAGS)
+
+objs/account.o: ../account.cpp
+ $(CPP) -c ../account.cpp -o objs/account.o $(CXXFLAGS)
+
+objs/debug.o: ../debug.cpp
+ $(CPP) -c ../debug.cpp -o objs/debug.o $(CXXFLAGS)
+
+objs/filterplugin.o: ../filterplugin.cpp
+ $(CPP) -c ../filterplugin.cpp -o objs/filterplugin.o $(CXXFLAGS)
+
+objs/main.o: ../main.cpp
+ $(CPP) -c ../main.cpp -o objs/main.o $(CXXFLAGS)
+
+objs/protoplugin.o: ../protoplugin.cpp
+ $(CPP) -c ../protoplugin.cpp -o objs/protoplugin.o $(CXXFLAGS)
+
+objs/services.o: ../services.cpp
+ $(CPP) -c ../services.cpp -o objs/services.o $(CXXFLAGS)
+
+objs/synchro.o: ../synchro.cpp
+ $(CPP) -c ../synchro.cpp -o objs/synchro.o $(CXXFLAGS)
+
+objs/yamn.o: ../yamn.cpp
+ $(CPP) -c ../yamn.cpp -o objs/yamn.o $(CXXFLAGS)
+
+objs/YAMN.res: ../resources/YAMN.rc
+ $(WINDRES) -i ../resources/YAMN.rc --input-format=rc -o objs/YAMN.res -O coff --include-dir ../resources
diff --git a/yamn/proto/md5.c b/yamn/proto/md5.c new file mode 100644 index 0000000..25546d2 --- /dev/null +++ b/yamn/proto/md5.c @@ -0,0 +1,260 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */
+//#include <string.h> /* for memcpy() */ +#if defined(_WIN64) + typedef unsigned __int64 size_t; +#else + typedef unsigned int size_t; + #include "../filter/simple/AggressiveOptimize.h" +#endif +void * __cdecl memcpy(void *, const void *, size_t);
+void * __cdecl memset(void *, int, size_t);
+#include "md5.h" + +#ifndef HIGHFIRST +#define byteReverse(buf, len) /* Nothing */ +#else +void byteReverse(unsigned char *buf, unsigned longs); + +#ifndef ASM_MD5 +/* + * Note: this code is harmless on little-endian machines. + */ +void byteReverse(unsigned char *buf, unsigned longs) +{ + uint32 t; + do { + t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(uint32 *) buf = t; + buf += 4; + } while (--longs); +} +#endif +#endif + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +void MD5Init(struct MD5Context *ctx) +{ + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bits[0] = 0; + ctx->bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) +{ + uint32 t; + + /* Update bitcount */ + + t = ctx->bits[0]; + if ((ctx->bits[0] = t + ((uint32) len << 3)) < t) + ctx->bits[1]++; /* Carry from low to high */ + ctx->bits[1] += len >> 29; + + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ + + /* Handle any leading odd-sized chunks */ + + if (t) { + unsigned char *p = (unsigned char *) ctx->in + t; + + t = 64 - t; + if (len < t) { + memcpy(p, buf, len); + return; + } + memcpy(p, buf, t); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += t; + len -= t; + } + /* Process data in 64-byte chunks */ + + while (len >= 64) { + memcpy(ctx->in, buf, 64); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void MD5Final(unsigned char digest[16], struct MD5Context *ctx) +{ + unsigned count; + unsigned char *p; + + /* Compute number of bytes mod 64 */ + count = (ctx->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + p = ctx->in + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = 64 - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset(p, 0, count); + byteReverse(ctx->in, 16); + MD5Transform(ctx->buf, (uint32 *) ctx->in); + + /* Now fill the next block with 56 bytes */ + memset(ctx->in, 0, 56); + } else { + /* Pad block to 56 bytes */ + memset(p, 0, count - 8); + } + byteReverse(ctx->in, 14); + + /* Append length in bits and transform */ + ((uint32 *) ctx->in)[14] = ctx->bits[0]; + ((uint32 *) ctx->in)[15] = ctx->bits[1]; + + MD5Transform(ctx->buf, (uint32 *) ctx->in); + byteReverse((unsigned char *) ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ +} + +#ifndef ASM_MD5 + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +void MD5Transform(uint32 buf[4], uint32 const in[16]) +{ + register uint32 a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +#endif diff --git a/yamn/proto/md5.h b/yamn/proto/md5.h new file mode 100644 index 0000000..e264f68 --- /dev/null +++ b/yamn/proto/md5.h @@ -0,0 +1,27 @@ +#ifndef MD5_H +#define MD5_H + +#ifdef __alpha +typedef unsigned int uint32; +#else +typedef unsigned long uint32; +#endif + +struct MD5Context { + uint32 buf[4]; + uint32 bits[2]; + unsigned char in[64]; +}; + +void MD5Init(struct MD5Context *context); +void MD5Update(struct MD5Context *context, unsigned char const *buf, + unsigned len); +void MD5Final(unsigned char digest[16], struct MD5Context *context); +void MD5Transform(uint32 buf[4], uint32 const in[16]); + +/* + * This is needed to make RSAREF happy on some MS-DOS compilers. + */ +typedef struct MD5Context MD5_CTX; + +#endif /* !MD5_H */ diff --git a/yamn/proto/netclient.h b/yamn/proto/netclient.h new file mode 100644 index 0000000..2414dbd --- /dev/null +++ b/yamn/proto/netclient.h @@ -0,0 +1,22 @@ +#ifndef __CLIENT_H
+#define __CLIENT_H
+
+class CNetClient
+{
+public:
+ CNetClient(): Stopped(FALSE) {}
+ virtual void Connect(const char* servername,const int port)=0;
+ virtual void Send(const char *query)=0;
+ virtual char* Recv(char *buf=NULL,int buflen=65536)=0;
+ virtual void Disconnect()=0;
+ virtual BOOL Connected()=0;
+ virtual void SSLify()=0;
+
+ BOOL Stopped;
+ int Rcv;
+ DWORD NetworkError;
+ DWORD SystemError;
+ BOOL ifTLSed;
+};
+
+#endif
diff --git a/yamn/proto/netlib.cpp b/yamn/proto/netlib.cpp new file mode 100644 index 0000000..f6f497b --- /dev/null +++ b/yamn/proto/netlib.cpp @@ -0,0 +1,278 @@ +/*
+ * This code implements communication based on Miranda netlib library
+ *
+ * (c) majvan 2002-2004
+ */
+
+#if !defined(_WIN64)
+ #include "../filter/simple/AggressiveOptimize.h"
+#endif
+#include <windows.h>
+#include <stdio.h>
+#include <newpluginapi.h> //CallService,UnHookEvent
+#include <m_netlib.h> //socket thorugh proxy functions
+#include <m_langpack.h> //langpack for "connection" and other words
+#include "../debug.h"
+#include "netlib.h"
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+BOOL SSLLoaded=FALSE;
+HANDLE hNetlibUser=NULL;
+
+extern PVOID TLSCtx;
+extern PVOID SSLCtx;
+
+void __stdcall SSL_DebugLog(const char *fmt, ...)
+{
+ char str[ 4096 ];
+ va_list vararg;
+
+ va_start( vararg, fmt );
+ int tBytes = _vsnprintf( str, sizeof(str)-1, fmt, vararg );
+ if ( tBytes == 0 )
+ return;
+
+ if ( tBytes > 0 )
+ str[ tBytes ] = 0;
+ else
+ str[ sizeof(str)-1 ] = 0;
+
+ CallService(MS_NETLIB_LOG, (WPARAM)hNetlibUser, (LPARAM)str);
+ va_end( vararg );
+}
+
+HANDLE RegisterNLClient(const char *name)
+{
+ static NETLIBUSER nlu={0};
+ char desc[128];
+
+ sprintf(desc, TranslateT("%s connection"),name);
+
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<Register PROXY support>");
+#endif
+ nlu.cbSize = sizeof(nlu);
+ nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS;
+ nlu.szDescriptiveName=desc;
+ nlu.szSettingsModule=(char *)name;
+ hNetlibUser=(HANDLE)CallService(MS_NETLIB_REGISTERUSER,0,(LPARAM)&nlu);
+
+#ifdef DEBUG_COMM
+ if(NULL==hNetlibUser)
+ DebugLog(CommFile,"<error></Register PROXY support>\n");
+ else
+ DebugLog(CommFile,"</Register PROXY support>\n");
+#endif
+ return hNetlibUser;
+}
+
+//Move connection to SSL
+void CNLClient::SSLify() throw(DWORD){
+#ifdef DEBUG_COMM
+ SSL_DebugLog("Staring SSL...");
+#endif
+ int socket = CallService(MS_NETLIB_GETSOCKET, (WPARAM)hConnection, 0);
+ if (socket != INVALID_SOCKET)
+ {
+#ifdef DEBUG_COMM
+ SSL_DebugLog("Staring netlib core SSL");
+#endif
+ if (CallService(MS_NETLIB_STARTSSL, (WPARAM)hConnection, 0))
+ {
+#ifdef DEBUG_COMM
+ SSL_DebugLog("Netlib core SSL started");
+#endif
+ isTLSed = true;
+ SSLLoaded = TRUE;
+ return;
+ }
+ }
+
+ //ssl could not be created
+ throw NetworkError = (DWORD)ESSL_CREATESSL;
+}
+
+//Connects to the server through the sock
+//if not success, exception is throwed
+void CNLClient::Connect(const char* servername,const int port) throw(DWORD)
+{
+ NETLIBOPENCONNECTION nloc;
+
+ NetworkError=SystemError=0;
+ isTLSed = false;
+
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<connect>\n");
+#endif
+ try
+ {
+ nloc.cbSize=sizeof(NETLIBOPENCONNECTION);
+ nloc.szHost=servername;
+ nloc.wPort=port;
+ nloc.flags=0;
+ if(NULL==(hConnection=(HANDLE)CallService(MS_NETLIB_OPENCONNECTION,(WPARAM)hNetlibUser,(LPARAM)&nloc)))
+ {
+ SystemError=WSAGetLastError();
+ throw NetworkError=(DWORD)ENL_CONNECT;
+ }
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</connect>\n");
+#endif
+ return;
+ }
+ catch(...)
+ {
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<error></connect>\n");
+#endif
+ throw;
+ }
+}
+
+//Performs a simple query
+// query- command to send
+int CNLClient::LocalNetlib_Send(HANDLE hConn,const char *buf,int len,int flags) {
+ if (isTLSed)
+ {
+#ifdef DEBUG_COMM
+ SSL_DebugLog("SSL send: %s", buf);
+#endif
+ }
+
+ NETLIBBUFFER nlb={(char*)buf,len,flags};
+ return CallService(MS_NETLIB_SEND,(WPARAM)hConn,(LPARAM)&nlb);
+}
+
+void CNLClient::Send(const char *query) throw(DWORD)
+{
+ unsigned int Sent;
+
+ if(NULL==query)
+ return;
+ if(hConnection==NULL)
+ return;
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<send>%s",query);
+#endif
+ try
+ {
+ if((SOCKET_ERROR==(Sent=LocalNetlib_Send(hConnection,query,(int)strlen(query),MSG_DUMPASTEXT))) || Sent!=(unsigned int)strlen(query))
+ {
+ SystemError=WSAGetLastError();
+ throw NetworkError=(DWORD)ENL_SEND;
+ }
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</send>\n");
+#endif
+ }
+ catch(...)
+ {
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<error></send>\n");
+#endif
+ throw;
+ }
+}
+
+//Reads data from socket
+// buf- buffer where to store max. buflen of received characters
+// if buf is NULL, creates buffer of buflen size
+// buf is NULL by default
+//You need free() returned buffer, which can be allocated in this function
+//if not success, exception is throwed
+
+int CNLClient::LocalNetlib_Recv(HANDLE hConn,char *buf,int len,int flags) {
+ NETLIBBUFFER nlb={buf,len,flags};
+ int iReturn = CallService(MS_NETLIB_RECV,(WPARAM)hConn,(LPARAM)&nlb);
+ if (isTLSed)
+ {
+#ifdef DEBUG_COMM
+ SSL_DebugLog("SSL recv: %s", buf);
+#endif
+ }
+
+ return iReturn;
+}
+
+char* CNLClient::Recv(char *buf,int buflen) throw(DWORD)
+{
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<reading>");
+#endif
+ try
+ {
+ if(buf==NULL)
+ buf=(char *)malloc(sizeof(char)*(buflen+1));
+ if(buf==NULL)
+ throw NetworkError=(DWORD)ENL_RECVALLOC;
+
+ if (!isTLSed)
+ {
+ NETLIBSELECT nls;
+ memset(&nls, 0, sizeof(NETLIBSELECT));
+ nls.cbSize = sizeof(NETLIBSELECT);
+ nls.dwTimeout = 60000;
+ nls.hReadConns[0] = hConnection;
+ switch (CallService(MS_NETLIB_SELECT, 0, (LPARAM) &nls))
+ {
+ case SOCKET_ERROR:
+ free(buf);
+ SystemError=WSAGetLastError();
+ throw NetworkError = (DWORD) ENL_RECV;
+ case 0: // time out!
+ free(buf);
+ throw NetworkError = (DWORD) ENL_TIMEOUT;
+ }
+ }
+
+ ZeroMemory(buf,buflen);
+ if(SOCKET_ERROR==(Rcv=LocalNetlib_Recv(hConnection,buf,buflen,MSG_DUMPASTEXT)))
+ {
+ free(buf);
+ SystemError=WSAGetLastError();
+ throw NetworkError=(DWORD)ENL_RECV;
+ }
+ if(!Rcv)
+ {
+ free(buf);
+ SystemError=WSAGetLastError();
+ throw NetworkError=(DWORD)ENL_RECV;
+ }
+#ifdef DEBUG_COMM
+ *(buf+Rcv)=0; //end the buffer to write it to file
+ DebugLog(CommFile,"%s",buf);
+ DebugLog(CommFile,"</reading>\n");
+#endif
+ return(buf);
+ }
+ catch(...)
+ {
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<error></reading>\n");
+#endif
+ throw;
+ }
+}
+
+//Closes netlib connection
+void CNLClient::Disconnect()
+{
+ Netlib_CloseHandle(hConnection);
+ hConnection=(HANDLE)NULL;
+}
+
+//Uninitializes netlib library
+void UnregisterNLClient()
+{
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<Unregister PROXY support>");
+#endif
+
+ Netlib_CloseHandle(hNetlibUser);
+ hNetlibUser=(HANDLE)NULL;
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</Unregister PROXY support>\n");
+#endif
+}
diff --git a/yamn/proto/netlib.h b/yamn/proto/netlib.h new file mode 100644 index 0000000..90ad361 --- /dev/null +++ b/yamn/proto/netlib.h @@ -0,0 +1,55 @@ +#ifndef __NETLIB_H
+#define __NETLIB_H
+
+#include "netclient.h"
+
+#pragma warning( disable : 4290 )
+
+class CNLClient: public CNetClient
+{
+public:
+ CNLClient(): hConnection(NULL) {}
+ void Connect(const char* servername,const int port) throw(DWORD);
+ void Send(const char *query) throw(DWORD);
+ char* Recv(char *buf=NULL,int buflen=65536) throw(DWORD);
+ void Disconnect();
+ void SSLify()throw(DWORD);
+
+ inline BOOL Connected() {return hConnection!=NULL;}
+
+protected:
+ HANDLE hConnection;
+ BOOL isTLSed;
+ int LocalNetlib_Send(HANDLE hConn,const char *buf,int len,int flags);
+ int LocalNetlib_Recv(HANDLE hConn,char *buf,int len,int flags);
+};
+
+void SSL_DebugLog(const char *fmt, ...);
+
+enum
+{
+ ENL_WINSOCKINIT=1, //error initializing socket //only wsock
+ ENL_GETHOSTBYNAME, //DNS error //only wsock
+ ENL_CREATESOCKET, //error creating socket //only wsock
+ ENL_CONNECT, //cannot connect to server
+ ENL_SEND, //cannot send data
+ ENL_RECV, //cannot receive data
+ ENL_RECVALLOC, //cannot allocate memory for received data
+ ENL_TIMEOUT, //timed out during recv
+};
+
+enum
+{
+ ESSL_NOTLOADED=1, //OpenSSL is not loaded
+ ESSL_WINSOCKINIT, //WinSock 2.0 init failed
+ ESSL_GETHOSTBYNAME, //DNS error
+ ESSL_CREATESOCKET, //error creating socket
+ ESSL_SOCKETCONNECT, //error connecting with socket
+ ESSL_CREATESSL, //error creating SSL session structure
+ ESSL_SETSOCKET, //error connect socket with SSL session for bidirect I/O space
+ ESSL_CONNECT, //cannot connect to server
+ ESSL_SEND, //cannot send data
+ ESSL_RECV, //cannot receive data
+ ESSL_RECVALLOC, //cannot allocate memory for received data
+};
+#endif
diff --git a/yamn/proto/pop3/pop3.cpp b/yamn/proto/pop3/pop3.cpp new file mode 100644 index 0000000..59b8244 --- /dev/null +++ b/yamn/proto/pop3/pop3.cpp @@ -0,0 +1,374 @@ +/* + * This code implements basics of POP3 protocol + * + * (c) majvan 2002-2004 + */ +/* This was made from the libspopc project + * copyright c 2002 Benoit Rouits <brouits@free.fr> + * released under the terms of GNU LGPL + * (GNU Lesser General Public Licence). + * libspopc offers simple API for a pop3 client (MTA). + * See RFC 1725 for pop3 specifications. + * more information on http://brouits.free.fr/libspopc/ + */ +/* + * This file is not original and is changed by majvan <om3tn@psg.sk> + * for mail checker purpose. Please see original web page to + * obtain the original. I rewrote it in C++, but good ideas were, + * I think, unchanged. + * + * Note that this file was not designed to work under Unix. It's + * needed to add Unix-specific features. I was interested only in + * Windows for my project. majvan + * + */ +
+#pragma warning( disable : 4290 ) + +#if !defined(_WIN64) + #include "../../filter/simple/AggressiveOptimize.h" +#endif +#include <windows.h> +#include <stdio.h> +#include "pop3.h"
+
+extern "C" { +#include "../md5.h" +} +
+extern void __stdcall SSL_DebugLog( const char *fmt, ... ); + +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- + +//Connects to the server through the netlib +//if not success, exception is throwed +//returns welcome string returned by server +//sets AckFlag +char *CPop3Client::Connect(const char* servername,const int port,BOOL UseSSL, BOOL NoTLS) +{
+ char *temp = 0; + if(Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + if(NetClient!=NULL) + delete NetClient; + SSL=UseSSL; + NetClient=new CNLClient; + +#ifdef DEBUG_DECODE + DebugLog(DecodeFile,"Connect:servername: %s port:%d\n",servername,port); +#endif + POP3Error=EPOP3_CONNECT; + NetClient->Connect(servername,port); + POP3Error=0; + + if (SSL) + { + try { NetClient->SSLify(); } + catch (...) + { + NetClient->Disconnect(); + return NULL; + } + } + + temp = RecvRest(NetClient->Recv(),POP3_SEARCHACK);
+ extern BOOL SSLLoaded;
+ if (!NoTLS & !(SSL)){ + if(NetClient->Stopped) //check if we can work with this POP3 client session
+ throw POP3Error=(DWORD)EPOP3_STOPPED;
+ NetClient->Send("STLS\r\n");
+ free(temp);
+ temp=RecvRest(NetClient->Recv(),POP3_SEARCHACK);
+ if(AckFlag==POP3_FOK){ // Ok, we are going to tls
+ try {
+ NetClient->SSLify();
+ } catch (...) {
+ NetClient->Disconnect();
+ return NULL;
+ }
+// temp = RecvRest(NetClient->Recv(),POP3_SEARCHACK);
+ }
+ }
+// SSL_DebugLog("Received: %s",temp);
+ return temp; +}
+ +//Receives data to the end of packet +// prev- previous data read (appends to this string next received data) +// mode- mode of packet. +// Packet can end with ack state (+OK or -ERR): set mode to POP3_SEARCHACK +// If packet ends with '.' (end of string), set mode to POP3_SEARCHDOT +// size- received data are stored to memory, but if length of data is more than allocated memory, function allocates +// new memory. New allocated memory has allocated size more bytes +// This value can be selectable: if you think it is better to reallocate by 1kB size, select size to 1024, +// default is 128. You do not need to use this parameter +char* CPop3Client::RecvRest(char* prev,int mode,int size) +{ + int SizeRead=0; + int SizeLeft=size-NetClient->Rcv; + int RcvAll=NetClient->Rcv; + char *LastString,*PrevString=prev; + + AckFlag=0; + + while(((mode==POP3_SEARCHDOT) && !SearchFromEnd(PrevString+RcvAll-1,RcvAll-3,POP3_SEARCHDOT) && !SearchFromStart(PrevString,2,POP3_SEARCHERR)) || //we are looking for dot or -err phrase + ((mode==POP3_SEARCHACK) && (!SearchFromStart(PrevString,RcvAll-3,mode) || !((RcvAll>3) && SearchFromEnd(PrevString+RcvAll-1,1,POP3_SEARCHNL))))) //we are looking for +ok or -err phrase ended with newline + { //if not found + if(NetClient->Stopped) //check if we can work with this POP3 client session + { + if(PrevString!=NULL) + free(PrevString); + throw POP3Error=(DWORD)EPOP3_STOPPED; + } + if(SizeLeft==0) //if block is full + { + SizeRead+=size; + SizeLeft=size; + LastString=NetClient->Recv(NULL,SizeLeft); + PrevString=(char *)realloc(PrevString,sizeof(char)*(SizeRead+size)); + if(PrevString==NULL) + throw POP3Error=(DWORD)EPOP3_RESTALLOC; + memcpy(PrevString+SizeRead,LastString,size); + free(LastString); + } + else + NetClient->Recv(PrevString+RcvAll,SizeLeft); //to Rcv stores received bytes + SizeLeft=SizeLeft-NetClient->Rcv; + RcvAll+=NetClient->Rcv; +// printf("[Read: %s]\n",PrevString); + } + NetClient->Rcv=RcvAll; //at the end, store the number of all bytes, no the number of last received bytes + return PrevString; +} + +// CPop3Client::SearchFromEnd +// returns 1 if substring DOTLINE or ENDLINE found from end in bs bytes +// if you need to add condition for mode, insert it into switch statement +BOOL CPop3Client::SearchFromEnd(char *end,int bs,int mode) +{ + while(bs>=0) + { + switch(mode) + { + case POP3_SEARCHDOT: + if(DOTLINE(end)) + return 1; + break; + case POP3_SEARCHNL: + if(ENDLINE(end)) + return 1; + break; + } + end--; + bs--; + } + return 0; +} + +//Finds for a occurence of some pattern in string +// returns 1 if substring OKLINE, ERRLINE or any of them found from start in bs bytes +//call only this function to retrieve ack status (+OK or -ERR), because it sets flag AckFlag +//if you need to add condition for mode, insert it into switch statement +BOOL CPop3Client::SearchFromStart(char *start,int bs,int mode) +{ + while(bs>=0) + { + switch(mode) + { + case POP3_SEARCHOK: + if(OKLINE(start)) + { + AckFlag=POP3_FOK; + return 1; + } + break; + case POP3_SEARCHERR: + if(ERRLINE(start)) + { + AckFlag=POP3_FERR; + return 1; + } + break; + case POP3_SEARCHACK: + if(ACKLINE(start)) + { + OKLINE(start) ? AckFlag=POP3_FOK : AckFlag=POP3_FERR; + return 1; + } + break; + } + start++; + bs--; + } + return 0; +} + +//Performs "USER" pop query and returns server response +//sets AckFlag +char* CPop3Client::User(char* name) +{ + if(NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[128]; + char *Result; + + sprintf(query,"USER %s\r\n",name); + NetClient->Send(query); + Result=RecvRest(NetClient->Recv(),POP3_SEARCHACK); + if(AckFlag==POP3_FERR) + throw POP3Error=(DWORD)EPOP3_BADUSER; + POP3Error=0; + return Result; +} + +//Performs "PASS" pop query and returns server response +//sets AckFlag +char* CPop3Client::Pass(char* pw) +{ + if(NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[128]; + char *Result; + + sprintf(query,"PASS %s\r\n",pw); + NetClient->Send(query); + Result=RecvRest(NetClient->Recv(),POP3_SEARCHACK); + if(AckFlag==POP3_FERR) + throw POP3Error=(DWORD)EPOP3_BADPASS; + return Result; +} + +//Performs "APOP" pop query and returns server response +//sets AckFlag +char* CPop3Client::APOP(char* name, char* pw, char* timestamp) +{ + if(NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[512]; + char *Result; + unsigned char digest[16]; + char hexdigest[40]; + + if(timestamp==NULL) + throw POP3Error=(DWORD)EPOP3_APOP; + MD5Context ctx; + MD5Init(&ctx); + MD5Update(&ctx,(const unsigned char *)timestamp,(unsigned int)strlen(timestamp)); + MD5Update(&ctx,(const unsigned char *)pw,(unsigned int)strlen(pw)); + MD5Final(digest,&ctx); + hexdigest[0]='\0'; + for(int i=0; i<16; i++) { + char tmp[4]; + sprintf(tmp, "%02x", digest[i]); + strcat(hexdigest, tmp); + } + sprintf(query,"APOP %s %s\r\n",name, hexdigest); + NetClient->Send(query); + Result=RecvRest(NetClient->Recv(),POP3_SEARCHACK); + if(AckFlag==POP3_FERR) + throw POP3Error=(DWORD)EPOP3_BADUSER; + return Result; +} + +//Performs "QUIT" pop query and returns server response +//sets AckFlag +char* CPop3Client::Quit() +{ + char query[]="QUIT\r\n"; + + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHACK); +} + +//Performs "STAT" pop query and returns server response +//sets AckFlag +char* CPop3Client::Stat() +{ + if(NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[]="STAT\r\n"; + + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHACK); +} + +//Performs "LIST" pop query and returns server response +//sets AckFlag +char* CPop3Client::List() +{ + if(NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[]="LIST\r\n"; + + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHDOT); +} + +//Performs "TOP" pop query and returns server response +//sets AckFlag +char* CPop3Client::Top(int nr, int lines) +{ + if(NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[128]; + + sprintf(query,"TOP %d %d\r\n",nr,lines); + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHDOT); +} + +//Performs "UIDL" pop query and returns server response +//sets AckFlag +char* CPop3Client::Uidl(int nr) +{ + if(NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[128]; + + if(nr) + { + sprintf(query,"UIDL %d\r\n",nr); + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHACK); + } + sprintf(query,"UIDL\r\n"); + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHDOT); +} + +//Performs "DELE" pop query and returns server response +//sets AckFlag +char* CPop3Client::Dele(int nr) +{ + if(NetClient->Stopped) //check if we can work with this POP3 client session + throw POP3Error=(DWORD)EPOP3_STOPPED; + + char query[128]; + + sprintf(query,"DELE %d\r\n",nr); + NetClient->Send(query); + return RecvRest(NetClient->Recv(),POP3_SEARCHACK); +} +//Performs "RETR" pop query and returns server response
+//sets AckFlag +char* CPop3Client::Retr(int nr)
+{
+ if(NetClient->Stopped) //check if we can work with this POP3 client session
+ throw POP3Error=(DWORD)EPOP3_STOPPED;
+
+ char query[128];
+
+ sprintf(query,"RETR %d\r\n",nr);
+ NetClient->Send(query);
+ RecvRest(NetClient->Recv(),POP3_SEARCHACK);
+ return NetClient->Recv();
+}
\ No newline at end of file diff --git a/yamn/proto/pop3/pop3.h b/yamn/proto/pop3/pop3.h new file mode 100644 index 0000000..faa6bd6 --- /dev/null +++ b/yamn/proto/pop3/pop3.h @@ -0,0 +1,66 @@ +#ifndef __POP3_H
+#define __POP3_H
+
+#include "../../debug.h"
+#include "../netlib.h" //NetLib client
+
+#define DOTLINE(s) ((((s)[-2]=='\r') || ((s)[-2]=='\n')) && ((s)[-1]=='.') && (((s)[0]=='\r') || ((s)[0]=='\n') || ((s)[0]=='\0'))) // be careful, it's different to ESR's pop3.c ;-)
+#define ENDLINE(s) (((s)[0]=='\r') || ((s)[0]=='\n')) //endline
+#define OKLINE(s) (((s)[0]=='+') && (((s)[1]=='o') || ((s)[1]=='O')) && (((s)[2]=='k') || ((s)[2]=='K'))) // +OK
+#define ERRLINE(s) (((s)[0]=='-') && (((s)[1]=='e') || ((s)[1]=='E')) && (((s)[2]=='r') || ((s)[2]=='R')) && (((s)[3]=='r') || ((s)[3]=='R'))) // -ERR
+#define ACKLINE(s) (OKLINE(s) || ERRLINE(s))
+
+#define POP3_SEARCHDOT 1
+#define POP3_SEARCHACK 2
+#define POP3_SEARCHOK 3
+#define POP3_SEARCHERR 4
+#define POP3_SEARCHNL 5
+
+#define POP3_FOK 1
+#define POP3_FERR 2
+
+class CPop3Client
+{
+public:
+ CPop3Client(): NetClient(NULL), Stopped(FALSE) {}
+ ~CPop3Client() {if(NetClient!=NULL) delete NetClient;}
+
+ char* Connect(const char* servername,const int port=110,BOOL UseSSL=FALSE, BOOL NoTLS=FALSE);
+ char* RecvRest(char* prev,int mode,int size=65536);
+ char* User(char* name);
+ char* Pass(char* pw);
+ char* APOP(char* name, char* pw, char* timestamp);
+ char* Quit();
+ char* Stat();
+ char* List();
+ char* Top(int nr, int lines=0);
+ char* Uidl(int nr=0);
+ char* Dele(int nr);
+ char* Retr(int nr);
+
+ unsigned char AckFlag;
+ BOOL SSL;
+ BOOL Stopped;
+
+ DWORD POP3Error;
+ class CNetClient *NetClient; //here the network layout is defined (TCP or SSL+TCP etc.)
+private:
+ BOOL SearchFromEnd(char *end,int bs,int mode);
+ BOOL SearchFromStart(char *end,int bs,int mode);
+};
+
+enum
+{
+ EPOP3_QUEUEALLOC=1, //memory allocation
+ EPOP3_STOPPED, //stop account
+ EPOP3_CONNECT, //cannot connect to server
+ EPOP3_RESTALLOC, //cannot allocate memory for received data
+ EPOP3_BADUSER, //cannot login because USER command failed
+ EPOP3_BADPASS, //cannot login because PASS command failed
+ EPOP3_APOP, //server does not send timestamp for APOP auth
+ EPOP3_STAT,
+ EPOP3_LIST,
+ EPOP3_UIDL,
+};
+
+#endif
diff --git a/yamn/proto/pop3/pop3comm.cpp b/yamn/proto/pop3/pop3comm.cpp new file mode 100644 index 0000000..d80ab20 --- /dev/null +++ b/yamn/proto/pop3/pop3comm.cpp @@ -0,0 +1,1636 @@ +/*
+ * This code implements POP3 server checking for new mail and so on.
+ * There's function SynchroPOP3 in this file- for checking and synchronising POP3 account
+ * and DeleteMailsPOP3- for deleting mails from POP3 server
+ *
+ * Note this file acts as main file for internal plugin.
+ *
+ * (c) majvan 2002-2004
+ * 18/08
+*/
+
+
+#pragma warning( disable : 4290 )
+#include "../../main.h"
+#include "../../yamn.h"
+#include "pop3.h"
+#include "pop3comm.h" //all we need for POP3 account (POP3 account= YAMN account + some more POP3 specified members)
+#include <m_netlib.h> //socket thorugh proxy functions
+
+#define ERRORSTR_MAXLEN 1024 //in wide-chars
+
+//- imported ---------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+//From main.cpp
+void SetDefaultProtocolIcons();
+//From pop3opt.cpp
+extern int POP3OptInit(WPARAM wParam,LPARAM lParam);
+//From netlib.cpp
+extern HANDLE RegisterNLClient(const char *name);
+//this is imported because of one bug, should not be imported normally (this POP3 is plugin of YAMN)
+extern INT_PTR FilterMailSvc(WPARAM,LPARAM);
+
+extern char *ProtoName;
+extern INT_PTR YAMN_STATUS;
+extern PLUGININFO pluginInfo;
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+HANDLE hNetLib = NULL;
+PSCOUNTER CPOP3Account::AccountWriterSO = NULL;
+
+//Creates new CPOP3Account structure
+HACCOUNT WINAPI CreatePOP3Account(HYAMNPROTOPLUGIN Plugin,DWORD CAccountVersion);
+
+//Deletes CPOP3Account structure
+void WINAPI DeletePOP3Account(HACCOUNT Which);
+
+//Sets stop flag to account
+void WINAPI StopPOP3Account(HACCOUNT Which);
+
+//Function registers standard functions for YAMN
+int RegisterPOP3Plugin(WPARAM,LPARAM);
+
+//This should be normally exporeted fcn UninstallEx from plugin DLL, but YAMN has already exported one, so this is the same called from YAMN UninstallEx
+//This is used by PluginUninstall
+int UninstallPOP3(PLUGINUNINSTALLPARAMS* ppup);
+
+//Unloads all variables created on heap (delete[])
+DWORD WINAPI UnLoadPOP3(void *);
+
+//Function writes POP3 accounts using YAMN exported functions
+DWORD WINAPI WritePOP3Accounts();
+
+//Function stores plugin's data for account to file
+DWORD WINAPI WritePOP3Options(HANDLE,HACCOUNT);
+
+//Function reads plugin's data for account from file
+DWORD WINAPI ReadPOP3Options(HACCOUNT,TCHAR **,TCHAR *);
+
+//Creates new mail for an account
+HYAMNMAIL WINAPI CreatePOP3Mail(HACCOUNT Account,DWORD CMimeMailVersion);
+
+//Function does all needed work when connection failed or any error occured
+//Creates structure containing error code, closes internet session, runs "bad connect" function
+static void PostErrorProc(HPOP3ACCOUNT ActualAccount,void *ParamToBadConnect,DWORD POP3PluginParam,BOOL UseSSL);
+
+//Checks POP3 account and stores all info to account. It deletes old mails=> synchro
+// WhichTemp- pointer to strucure containing needed information
+DWORD WINAPI SynchroPOP3(struct CheckParam *WhichTemp);
+
+//Deletes mails from POP3 server
+// WhichTemp- structure containing needed information (queued messages to delete)
+//Function deletes from memory queue in WhichTemp structure
+DWORD WINAPI DeleteMailsPOP3(struct DeleteParam *WhichTemp);
+
+//Function makes readable message about error. It sends it back to YAMN, so YAMN then
+//can show it to the message window
+WCHAR* WINAPI GetErrorString(DWORD Code);
+
+//Function deletes string allocated in GetErrorString
+void WINAPI DeleteErrorString(LPVOID String);
+
+//Extracts info from result of POP3's STAT command
+// stream- source string
+// len- length of source string
+// mboxsize- adreess to integer, that receives size of mailbox
+// mails- adreess to integer, that receives number of mails
+void ExtractStat(char *stream,int len,int *mboxsize,int *mails);
+
+//Extracts mail ID on mailbox
+// stream- source string
+// len- length of source string
+// queue- address of first message, where first ID will be stored
+void ExtractUIDL(char *stream,int len,HYAMNMAIL queue);
+
+//Extracts mail size on mailbox
+// stream- source string
+// len- length of source string
+// queue- address of first message, where size of message #1 will be stored
+void ExtractList(char *stream,int len,HYAMNMAIL queue);
+
+void ExtractMail(char *stream,int len,HYAMNMAIL queue);
+
+struct YAMNExportedFcns *pYAMNFcn = NULL;
+struct MailExportedFcns *pYAMNMailFcn = NULL;
+
+YAMN_PROTOIMPORTFCN POP3ProtocolFunctions =
+{
+ CreatePOP3Account,
+ DeletePOP3Account,
+ StopPOP3Account,
+ WritePOP3Options,
+ ReadPOP3Options,
+ SynchroPOP3,
+ SynchroPOP3,
+ SynchroPOP3,
+ DeleteMailsPOP3,
+ GetErrorString,
+ NULL,
+ DeleteErrorString,
+ WritePOP3Accounts,
+ NULL,
+ UnLoadPOP3,
+};
+
+YAMN_MAILIMPORTFCN POP3MailFunctions =
+{
+ CreatePOP3Mail,
+ NULL,
+ NULL,
+ NULL,
+};
+
+PYAMN_VARIABLES pYAMNVar = NULL;
+HYAMNPROTOPLUGIN POP3Plugin = NULL;
+
+YAMN_PROTOREGISTRATION POP3ProtocolRegistration =
+{
+ "POP3 protocol (internal)",
+ YAMN_VERSION_C,
+ "© 2002-2004 majvan | 2005-2007 tweety, yb",
+ "Mail notifier and browser for Miranda IM. Included POP3 protocol.",
+ "francois.mean@skynet.be",
+ "http://forums.miranda-im.org/showthread.php?t=3035",
+};
+
+WCHAR *FileName = NULL;
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+CPOP3Account::CPOP3Account()
+{
+//NOTE! This constructor constructs CAccount structure. If your plugin is not internal,
+//you will need these constructors. All you need is in Account.cpp. Just copy to your source code
+//constructor and destructor of CAccount.
+ UseInternetFree=CreateEvent(NULL,FALSE,TRUE,NULL);
+ InternetQueries=new SCOUNTER;
+ AbilityFlags=YAMN_ACC_BROWSE | YAMN_ACC_POPUP;
+
+ SetAccountStatus((HACCOUNT)this,TranslateT("Disconnected"));
+}
+
+CPOP3Account::~CPOP3Account()
+{
+ CloseHandle(UseInternetFree);
+ if(InternetQueries!=NULL)
+ delete InternetQueries;
+}
+
+HACCOUNT WINAPI CreatePOP3Account(HYAMNPROTOPLUGIN Plugin,DWORD CAccountVersion)
+{
+//First, we should check whether CAccountVersion matches.
+//But this is internal plugin, so YAMN's CAccount structure and our CAccount structure are
+//the same, so we do not need to test version. Otherwise, if CAccount version does not match
+//in your plugin, you should return NULL, like this:
+// if(CAccountVersion!=YAMN_ACCOUNTVERSION) return NULL;
+
+//Now it is needed to construct our POP3 account and return its handle
+ return (HACCOUNT)new struct CPOP3Account();
+}
+
+void WINAPI DeletePOP3Account(HACCOUNT Which)
+{
+ delete (HPOP3ACCOUNT)Which;
+}
+
+void WINAPI StopPOP3Account(HACCOUNT Which)
+{
+ ((HPOP3ACCOUNT)Which)->Client.Stopped=TRUE;
+ if(((HPOP3ACCOUNT)Which)->Client.NetClient!=NULL) //we should inform also network client. Usefull only when network client implements this feature
+ ((HPOP3ACCOUNT)Which)->Client.NetClient->Stopped=TRUE;
+}
+
+//This function is like main function for POP3 internal protocol
+int RegisterPOP3Plugin(WPARAM,LPARAM)
+{
+
+ //Get YAMN variables we can use
+ if(NULL==(pYAMNVar=(PYAMN_VARIABLES)CallService(MS_YAMN_GETVARIABLES,(WPARAM)YAMN_VARIABLESVERSION,(LPARAM)0)))
+ return 0;
+
+ //We have to get pointers to YAMN exported functions: allocate structure and fill it
+ if(NULL==(pYAMNFcn=new struct YAMNExportedFcns))
+ {UnLoadPOP3(0); return 0;}
+
+ //Register new pop3 user in netlib
+ if(NULL==(hNetLib=RegisterNLClient("YAMN-POP3")))
+ {UnLoadPOP3(0); return 0;}
+
+ pYAMNFcn->SetProtocolPluginFcnImportFcn=(YAMN_SETPROTOCOLPLUGINFCNIMPORTFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SETPROTOCOLPLUGINFCNIMPORTID,(LPARAM)0);
+ pYAMNFcn->WaitToWriteFcn=(YAMN_WAITTOWRITEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_WAITTOWRITEID,(LPARAM)0);
+ pYAMNFcn->WriteDoneFcn=(YAMN_WRITEDONEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_WRITEDONEID,(LPARAM)0);
+ pYAMNFcn->WaitToReadFcn=(YAMN_WAITTOREADFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_WAITTOREADID,(LPARAM)0);
+ pYAMNFcn->ReadDoneFcn=(YAMN_READDONEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_READDONEID,(LPARAM)0);
+ pYAMNFcn->SCGetNumberFcn=(YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SCGETNUMBERID,(LPARAM)0);
+ pYAMNFcn->SCIncFcn=(YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SCINCID,(LPARAM)0);
+ pYAMNFcn->SCDecFcn=(YAMN_SCMANAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SCDECID,(LPARAM)0);
+ pYAMNFcn->SetStatusFcn=(YAMN_SETSTATUSFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SETSTATUSID,(LPARAM)0);
+ pYAMNFcn->GetStatusFcn=(YAMN_GETSTATUSFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_GETSTATUSID,(LPARAM)0);
+
+ if(NULL==(pYAMNMailFcn=new struct MailExportedFcns))
+ {UnLoadPOP3(0); return 0;}
+
+ pYAMNMailFcn->SynchroMessagesFcn=(YAMN_SYNCHROMIMEMSGSFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_SYNCHROMIMEMSGSID,(LPARAM)0);
+ pYAMNMailFcn->TranslateHeaderFcn=(YAMN_TRANSLATEHEADERFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_TRANSLATEHEADERID,(LPARAM)0);
+ pYAMNMailFcn->AppendQueueFcn=(YAMN_APPENDQUEUEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_APPENDQUEUEID,(LPARAM)0);
+ pYAMNMailFcn->DeleteMessagesToEndFcn=(YAMN_DELETEMIMEQUEUEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_DELETEMIMEQUEUEID,(LPARAM)0);
+ pYAMNMailFcn->DeleteMessageFromQueueFcn=(YAMN_DELETEMIMEMESSAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_DELETEMIMEMESSAGEID,(LPARAM)0);
+ pYAMNMailFcn->FindMessageByIDFcn=(YAMN_FINDMIMEMESSAGEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_FINDMIMEMESSAGEID,(LPARAM)0);
+ pYAMNMailFcn->CreateNewDeleteQueueFcn=(YAMN_CREATENEWDELETEQUEUEFCN)CallService(MS_YAMN_GETFCNPTR,(WPARAM)YAMN_CREATENEWDELETEQUEUEID,(LPARAM)0);
+
+ //set static variable
+ if(CPOP3Account::AccountWriterSO==NULL) {
+ if(NULL==(CPOP3Account::AccountWriterSO=new SCOUNTER))
+ {UnLoadPOP3(0); return 0;}
+ }
+
+ //First, we register this plugin
+ //it is quite impossible this function returns zero (failure) as YAMN and internal plugin structre versions are the same
+ POP3ProtocolRegistration.Name = Translate("POP3 protocol (internal)");
+ POP3ProtocolRegistration.Description = Translate("Mail notifier and browser for Miranda IM. Included POP3 protocol.");
+ if(NULL==(POP3Plugin=(HYAMNPROTOPLUGIN)CallService(MS_YAMN_REGISTERPROTOPLUGIN,(WPARAM)&POP3ProtocolRegistration,(LPARAM)YAMN_PROTOREGISTRATIONVERSION)))
+ return 0;
+
+ //Next we set our imported functions for YAMN
+ if(!SetProtocolPluginFcnImport(POP3Plugin,&POP3ProtocolFunctions,YAMN_PROTOIMPORTFCNVERSION,&POP3MailFunctions,YAMN_MAILIMPORTFCNVERSION))
+ return 0;
+
+ //Then, we read all mails for accounts.
+ //You must first register account, before using this function as YAMN must use CreatePOP3Account function to add new accounts
+ //But if CreatePOP3Account is not implemented (equals to NULL), YAMN creates account as YAMN's standard HACCOUNT
+ if(FileName) CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName,(LPARAM)0); //shoud not happen (only for secure)
+ FileName=(WCHAR *)CallService(MS_YAMN_GETFILENAMEA,(WPARAM)"pop3",(LPARAM)0);
+
+ switch(CallService(MS_YAMN_READACCOUNTSW,(WPARAM)POP3Plugin,(LPARAM)FileName))
+ {
+ case EACC_FILEVERSION:
+ MessageBoxA(NULL,Translate("Found new version of account book, not compatible with this version of YAMN."),Translate(_T("YAMN (internal POP3) read error")),MB_OK);
+ CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName,(LPARAM)0);
+ return 0;
+ case EACC_FILECOMPATIBILITY:
+ MessageBoxA(NULL,Translate("Error reading account file. Account file corrupted."),Translate("YAMN (internal POP3) read error"),MB_OK);
+ CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName,(LPARAM)0);
+ return 0;
+ case EACC_ALLOC:
+ MessageBoxA(NULL,Translate("Memory allocation error while data reading"),Translate("YAMN (internal POP3) read error"),MB_OK);
+ CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName,(LPARAM)0);
+ return 0;
+ case EACC_SYSTEM:
+ if(ERROR_FILE_NOT_FOUND!=GetLastError())
+ {
+ char temp[1024] = {0};
+ _snprintf(temp,1024,"%s\n%S",Translate("Reading file error. File already in use?"),FileName);
+ MessageBoxA(NULL,temp,Translate("YAMN (internal POP3) read error"),MB_OK);
+ CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName,(LPARAM)0);
+ return 0;
+ }
+ break;
+ }
+ //HookEvent(ME_OPT_INITIALISE,POP3OptInit);
+
+ HACCOUNT Finder;
+ HANDLE hContact;
+ DBVARIANT dbv;
+ char *szProto;
+
+ for(Finder=POP3Plugin->FirstAccount;Finder!=NULL;Finder=Finder->Next)
+ {
+ Finder->hContact = NULL;
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while(hContact)
+ {
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ if(szProto != NULL && strcmp(szProto, ProtoName)==0)
+ {
+ if(!DBGetContactSetting(hContact,ProtoName,"Id",&dbv))
+ {
+
+ if( strcmp((char*)dbv.pszVal, Finder->Name)==0)
+ {
+ Finder->hContact = hContact;
+ DBWriteContactSettingWord(Finder->hContact, ProtoName, "Status", ID_STATUS_ONLINE);
+ DBWriteContactSettingString(Finder->hContact, "CList", "StatusMsg", Translate("No new mail message"));
+ if((Finder->Flags & YAMN_ACC_ENA) && (Finder->NewMailN.Flags & YAMN_ACC_CONT))
+ {
+ DBDeleteContactSetting(Finder->hContact, "CList", "Hidden");
+ }
+ if(!(Finder->Flags & YAMN_ACC_ENA) || !(Finder->NewMailN.Flags & YAMN_ACC_CONT))
+ {
+ DBWriteContactSettingByte(Finder->hContact, "CList", "Hidden", 1);
+ }
+ }
+ DBFreeVariant(&dbv);
+ }
+
+ }
+ hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0);
+ }
+ if(Finder->hContact == NULL && (Finder->Flags & YAMN_ACC_ENA) && (Finder->NewMailN.Flags & YAMN_ACC_CONT))
+ {
+ //No account contact found, have to create one
+ Finder->hContact =(HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0);
+ CallService(MS_PROTO_ADDTOCONTACT,(WPARAM)Finder->hContact,(LPARAM)ProtoName);
+ DBWriteContactSettingString(Finder->hContact,ProtoName,"Id",Finder->Name);
+ DBWriteContactSettingString(Finder->hContact,ProtoName,"Nick",Finder->Name);
+ DBWriteContactSettingString(Finder->hContact,"Protocol","p",ProtoName);
+ DBWriteContactSettingWord(Finder->hContact, ProtoName, "Status", YAMN_STATUS);
+ }
+
+ /*//this doesn't work. the function doesn't know which contact to check
+ //if((Finder->Flags & YAMN_ACC_ENA) && (Finder->NewMailN.Flags & YAMN_ACC_CONT) && DBGetContactSettingByte(NULL, YAMN_DBMODULE, YAMN_SHOWMAINMENU, 0))
+ //{
+ // mi.cbSize = sizeof(mi);
+ // mi.position = 0xb0000000;
+ // mi.flags = CMIM_ICON;
+ // mi.hIcon = hYamnIcons[1];
+ // mi.pszName = Finder->Name;
+ // mi.pszPopupName = ProtoName;
+ // mi.pszService = MS_YAMN_CLISTCONTEXT;
+ // hMenuItemMain = (HANDLE) CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+ }*/
+
+ }
+
+ return 0;
+}
+
+int UninstallPOP3(PLUGINUNINSTALLPARAMS* ppup) //Usually UninstallEx, but need different name, because it is registered yet in main.cpp
+{
+ if(ppup->bDoDeleteSettings)
+ {
+ char FileNameA[MAX_PATH+1];
+
+ PUIRemoveDbModule("YAMN-POP3");
+
+ if(FileName==NULL)
+ MessageBox(NULL,"Cannot delete book file when YAMN is not loaded. Please do it manually.","YAMN-POP3 uninstalling",MB_OK|MB_ICONWARNING);
+ else
+ {
+ if(!WideCharToMultiByte(CP_ACP,0,FileName,-1,FileNameA,MAX_PATH+1,NULL,NULL))
+ MessageBox(NULL,"Cannot delete book file. Please do it manually.","YAMN-POP3 uninstalling",MB_OK|MB_ICONWARNING);
+ else
+ DeleteFile(FileNameA);
+ }
+ }
+ return 0;
+}
+
+DWORD WINAPI UnLoadPOP3(void *)
+{
+ //pYAMNVar is only a pointr, no need delete or free
+ if(hNetLib) {
+ Netlib_CloseHandle(hNetLib); hNetLib = NULL;}
+ if(CPOP3Account::AccountWriterSO) {
+ delete CPOP3Account::AccountWriterSO; CPOP3Account::AccountWriterSO = NULL;}
+ if(pYAMNMailFcn) {
+ delete pYAMNMailFcn; pYAMNMailFcn = NULL;}
+ if(pYAMNFcn) {
+ delete pYAMNFcn; pYAMNFcn = NULL;}
+ if(FileName) {
+ CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName,(LPARAM)0); FileName = NULL;}
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"UnLoadPOP3:done\n");
+ #endif
+ return 1;
+}
+
+DWORD WINAPI WritePOP3Accounts()
+{
+// WCHAR *FileName=(WCHAR *)CallService(MS_YAMN_GETFILENAMEA,(WPARAM)"pop3",(LPARAM)0);
+ DWORD ReturnValue=CallService(MS_YAMN_WRITEACCOUNTSW,(WPARAM)POP3Plugin,(LPARAM)FileName);
+
+ switch(ReturnValue)
+ {
+ case EACC_SYSTEM:
+ {
+ char temp[1024] = {0};
+ _snprintf(temp,1024,"%s\n%S",Translate("Error while copying data to disk occured. File in use?"),FileName);
+ MessageBox(NULL,temp,Translate("POP3 plugin- write file error"),MB_OK);
+ }
+ break;
+ case 0:
+ break;
+ }
+// CallService(MS_YAMN_DELETEFILENAME,(WPARAM)FileName,(LPARAM)0);
+ return ReturnValue;
+}
+
+DWORD WINAPI WritePOP3Options(HANDLE File,HACCOUNT Which)
+{
+ DWORD WrittenBytes;
+ DWORD Ver=POP3_FILEVERSION;
+
+ if((!WriteFile(File,(char *)&Ver,sizeof(DWORD),&WrittenBytes,NULL)) ||
+ (!WriteFile(File,(char *)&((HPOP3ACCOUNT)Which)->CP,sizeof(WORD),&WrittenBytes,NULL)))
+ return EACC_SYSTEM;
+ return 0;
+}
+
+DWORD WINAPI ReadPOP3Options(HACCOUNT Which,TCHAR **Parser,TCHAR *End)
+{
+ DWORD Ver;
+#ifdef DEBUG_FILEREAD
+ TCHAR Debug[256];
+#endif
+ Ver=*(DWORD *)(*Parser);
+ (*Parser)+=sizeof(DWORD)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+ if(Ver!=POP3_FILEVERSION)
+ return EACC_FILECOMPATIBILITY;
+
+ ((HPOP3ACCOUNT)Which)->CP=*(WORD *)(*Parser);
+ (*Parser)+=sizeof(WORD)/sizeof(TCHAR);
+ if(*Parser>=End)
+ return EACC_FILECOMPATIBILITY;
+#ifdef DEBUG_FILEREAD
+ _stprintf(Debug,_T("CodePage: %d, remaining %d chars"),((HPOP3ACCOUNT)Which)->CP,End-*Parser);
+ MessageBox(NULL,Debug,_T("debug"),MB_OK);
+#endif
+ return 0;
+}
+
+HYAMNMAIL WINAPI CreatePOP3Mail(HACCOUNT Account,DWORD MailDataVersion)
+{
+ HYAMNMAIL NewMail;
+//First, we should check whether MAILDATA matches.
+//But this is internal plugin, so YAMN's MAILDATA structure and our MAILDATA structure are
+//the same, so we do not need to test version. Otherwise, if MAILDATA version does not match
+//in your plugin, you should return NULL, like this:
+// if(MailDataVersion!=YAMN_MAILDATAVERSION) return NULL;
+
+//Now it is needed to construct our POP3 account and return its handle
+ if(NULL==(NewMail=new YAMNMAIL))
+ return NULL;
+
+ if(NULL==(NewMail->MailData=new MAILDATA))
+ {
+ delete NewMail;
+ return NULL;
+ }
+ NewMail->MailData->CP=((HPOP3ACCOUNT)Account)->CP;
+ return (HYAMNMAIL)NewMail;
+}
+
+static void SetContactStatus(HACCOUNT account, int status){
+ if ((account->hContact) && (account->NewMailN.Flags & YAMN_ACC_CONT)){
+ DBWriteContactSettingWord(account->hContact, ProtoName, "Status", status);
+ }
+}
+
+static void PostErrorProc(HPOP3ACCOUNT ActualAccount,void *ParamToBadConnection,DWORD POP3PluginParam,BOOL UseSSL)
+{
+ char *DataRX;
+
+//We create new structure, that we pass to bad connection dialog procedure. This procedure next calls YAMN imported fuction
+//from POP3 protocol to determine the description of error. We can describe error from our error code structure, because later,
+//when YAMN calls our function, it passes us our error code. This is pointer to structure for POP3 protocol in fact.
+ PPOP3_ERRORCODE ErrorCode;
+
+//We store status before we do Quit(), because quit can destroy our errorcode status
+ if(NULL!=(ErrorCode=new POP3_ERRORCODE))
+ {
+ ErrorCode->SSL=UseSSL;
+ ErrorCode->AppError=ActualAccount->SystemError;
+ ErrorCode->POP3Error=ActualAccount->Client.POP3Error;
+ ErrorCode->NetError=ActualAccount->Client.NetClient->NetworkError;
+ ErrorCode->SystemError=ActualAccount->Client.NetClient->SystemError;
+ }
+
+ if(POP3PluginParam==(DWORD)NULL) //if it was normal YAMN call (force check or so on)
+ {
+ try
+ {
+ DataRX=ActualAccount->Client.Quit();
+ if(DataRX!=NULL)
+ free(DataRX);
+ }
+ catch(...)
+ {
+ }
+//We always close connection if error occured
+ try
+ {
+ ActualAccount->Client.NetClient->Disconnect();
+ }
+ catch(...)
+ {
+ }
+
+ SetAccountStatus(ActualAccount,Translate("Disconnected"));
+
+//If we cannot allocate memory, do nothing
+ if(ErrorCode==NULL)
+ {
+ SetEvent(ActualAccount->UseInternetFree);
+ return;
+ }
+ }
+ else //else it was called from POP3 plugin, probably error when deleting old mail (POP3 synchro calls POP3 delete)
+ if(ErrorCode==NULL)
+ return;
+
+ if((ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG) || (ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO) || (ActualAccount->BadConnectN.Flags & YAMN_ACC_POP))
+ {
+ YAMN_BADCONNECTIONPARAM cp={(HANDLE)0,ActualAccount,(UINT_PTR)ErrorCode,ParamToBadConnection};
+
+ CallService(MS_YAMN_BADCONNECTION,(WPARAM)&cp,(LPARAM)YAMN_BADCONNECTIONVERSION);
+ }
+ if(POP3PluginParam==(DWORD)NULL) //if it was normal YAMN call
+ SetEvent(ActualAccount->UseInternetFree);
+}
+
+//Checks POP3 account and synchronizes it
+DWORD WINAPI SynchroPOP3(struct CheckParam * WhichTemp)
+{
+ HPOP3ACCOUNT ActualAccount;
+ CPop3Client *MyClient;
+ HYAMNMAIL NewMails=NULL,MsgQueuePtr=NULL;
+ char* DataRX=NULL,*Temp;
+ int mboxsize,msgs,i;
+ SYSTEMTIME now;
+ LPVOID YAMNParam;
+ DWORD CheckFlags;
+ BOOL UsingInternet=FALSE;
+ struct {
+ char *ServerName;
+ DWORD ServerPort;
+ char *ServerLogin;
+ char *ServerPasswd;
+ DWORD Flags;
+ DWORD NFlags;
+ DWORD NNFlags;
+ } ActualCopied;
+
+ //First, we should compare our version of CheckParam structure, but here it is not needed, because YAMN and internal plugin
+ //have the same version. But your plugin should do that in this way:
+ // if(((struct CheckParam *)WhichTemp)->Ver!=YAMN_CHECKVERSION)
+ // {
+ // SetEvent(((struct CheckParam *)WhichTemp)->ThreadRunningEV); //don't forget to unblock YAMN
+ // return (DWORD)-1; //ok, but we should return value.
+ // //When our plugin returns e.g. 0xFFFFFFFF (=-1, this is only our plugin value, YAMN does nothing with return value,
+ // //but only tests if it is nonzero. If yes, it calls GetErrorStringFcn. We know problem occured in YAMN incompatibility
+ // //and then we can in our GetErrorStringFcn e.g. return string "Uncompatible version of YAMN".
+ // }
+
+ ActualAccount=(HPOP3ACCOUNT)WhichTemp->AccountParam; //copy address of structure from calling thread to stack of this thread
+ YAMNParam=WhichTemp->BrowserParam;
+ CheckFlags=WhichTemp->Flags;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:Incrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+ #endif
+ SCInc(ActualAccount->UsingThreads);
+ //Unblock YAMN, signal that we have copied all parameters from YAMN thread stack
+ if(INVALID_HANDLE_VALUE!=WhichTemp->ThreadRunningEV)
+ SetEvent(WhichTemp->ThreadRunningEV);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=WaitToRead(ActualAccount))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountSO-read wait failed\n");
+ #endif
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+ #endif
+ SCDec(ActualAccount->UsingThreads);
+ return 0;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountSO-read enter\n");
+ #endif
+ MyClient=&ActualAccount->Client;
+ //Now, copy all needed information about account to local variables, so ActualAccount is not blocked in read mode during all connection process, which can last for several minutes.
+ ActualCopied.ServerName=_strdup(ActualAccount->Server->Name);
+ ActualCopied.ServerPort=ActualAccount->Server->Port;
+ ActualCopied.Flags=ActualAccount->Flags;
+ ActualCopied.ServerLogin=_strdup(ActualAccount->Server->Login);
+ ActualCopied.ServerPasswd=_strdup(ActualAccount->Server->Passwd);
+ ActualCopied.NFlags=ActualAccount->NewMailN.Flags;
+ ActualCopied.NNFlags=ActualAccount->NoNewMailN.Flags;
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountSO-read done\n");
+ #endif
+ ReadDone(ActualAccount);
+
+ SCInc(ActualAccount->InternetQueries); //increment counter, that there is one more thread waiting for connection
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:InternetFreeEV-wait\n");
+ #endif
+ WaitForSingleObject(ActualAccount->UseInternetFree,INFINITE); //wait until we can use connection
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:InternetFreeEV-enter\n");
+ #endif
+ SCDec(ActualAccount->InternetQueries);
+
+ //OK, we enter the "use internet" section. But after we start communication, we can test if we did not enter the "use internet" section only for the reason,
+ //that previous thread release the internet section because this account has stop signal (we stop account and there are 2 threads: one communicating,
+ //the second one waiting for network access- the first one ends because we want to stop account, this one is released, but should be stopped as well).
+ if(!ActualAccount->AbleToWork)
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:stop signal-InternetFreeEV-done\n");
+ #endif
+ SetEvent(ActualAccount->UseInternetFree);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:stop signal-Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+ #endif
+ SCDec(ActualAccount->UsingThreads);
+ return 0;
+ }
+ UsingInternet=TRUE;
+
+ GetLocalTime(&now);
+ ActualAccount->SystemError=0; //now we can use internet for this socket. First, clear errorcode.
+ try
+ {
+ SetContactStatus(ActualAccount,ID_STATUS_OCCUPIED);
+ #ifdef DEBUG_COMM
+ DebugLog(CommFile,"<--------Communication-------->\n");
+ #endif
+ // if we are already connected, we have open session (another thread left us open session), so we don't need to login
+ // note that connected state without logging cannot occur, because if we close session, we always close socket too (we must close socket is the right word :) )
+ if((MyClient->NetClient==NULL) || !MyClient->NetClient->Connected())
+ {
+ SetAccountStatus(ActualAccount,Translate("Connecting to server"));
+
+ DataRX=MyClient->Connect(ActualCopied.ServerName,ActualCopied.ServerPort,ActualCopied.Flags & YAMN_ACC_SSL23,ActualCopied.Flags & YAMN_ACC_NOTLS);
+ char *timestamp=NULL;
+
+ if(DataRX!=NULL)
+ {
+ if(ActualCopied.Flags & YAMN_ACC_APOP)
+ {
+ char *lpos=strchr(DataRX,'<');
+ char *rpos=strchr(DataRX,'>');
+ if(lpos && rpos && rpos>lpos) {
+ int sz=(int)(rpos-lpos+2);
+ timestamp=new char[sz];
+ memcpy(timestamp, lpos, sz-1);
+ timestamp[sz-1]='\0';
+ }
+ }
+ free(DataRX);
+ DataRX=NULL;
+ }
+
+ SetAccountStatus(ActualAccount,Translate("Entering POP3 account"));
+
+ if(ActualCopied.Flags & YAMN_ACC_APOP)
+ {
+ DataRX=MyClient->APOP(ActualCopied.ServerLogin,ActualCopied.ServerPasswd,timestamp);
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ delete[] timestamp;
+ } else {
+ DataRX=MyClient->User(ActualCopied.ServerLogin);
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ DataRX=MyClient->Pass(ActualCopied.ServerPasswd);
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ }
+ }
+ SetAccountStatus(ActualAccount,Translate("Searching for new mail message"));
+
+ DataRX=MyClient->Stat();
+
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<--------Account checking-------->\n");
+ DebugLog(DecodeFile,"<Extracting stat>\n");
+ #endif
+ ExtractStat(DataRX,MyClient->NetClient->Rcv,&mboxsize,&msgs);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<MailBoxSize>%d</MailBoxSize>\n",mboxsize);
+ DebugLog(DecodeFile,"<Msgs>%d</Msgs>\n",msgs);
+ DebugLog(DecodeFile,"</Extracting stat>\n");
+ #endif
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ for(i=0;i<msgs;i++)
+ {
+ if(!i)
+ MsgQueuePtr=NewMails=(HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL,(WPARAM)ActualAccount,(LPARAM)YAMN_MAILVERSION);
+ else
+ {
+ MsgQueuePtr->Next=(HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL,(WPARAM)ActualAccount,(LPARAM)YAMN_MAILVERSION);
+ MsgQueuePtr=MsgQueuePtr->Next;
+ }
+ if(MsgQueuePtr==NULL)
+ {
+ ActualAccount->SystemError=EPOP3_QUEUEALLOC;
+ throw (DWORD)ActualAccount->SystemError;
+ }
+ }
+
+ if(msgs)
+ {
+ DataRX=MyClient->List();
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting list>\n");
+ #endif
+ ExtractList(DataRX,MyClient->NetClient->Rcv,NewMails);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting list>\n");
+ #endif
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting UIDL>\n");
+ #endif
+ DataRX=MyClient->Uidl();
+ ExtractUIDL(DataRX,MyClient->NetClient->Rcv,NewMails);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting UIDL>\n");
+ #endif
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=MsgsWaitToWrite(ActualAccount))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write wait failed\n");
+ #endif
+ throw (DWORD)(ActualAccount->SystemError=EACC_STOPPED);
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write enter\n");
+ #endif
+ ActualAccount->LastChecked=now;
+ for(MsgQueuePtr=(HYAMNMAIL)ActualAccount->Mails;MsgQueuePtr!=NULL;MsgQueuePtr=MsgQueuePtr->Next){
+ if (MsgQueuePtr->Flags&YAMN_MSG_BODYREQUESTED){
+ HYAMNMAIL NewMsgsPtr=NULL;
+ for(NewMsgsPtr=(HYAMNMAIL)NewMails;NewMsgsPtr!=NULL;NewMsgsPtr=NewMsgsPtr->Next){
+ if (!strcmp(MsgQueuePtr->ID,NewMsgsPtr->ID)){
+ char accstatus[512];
+ sprintf(accstatus,Translate("Reading body %s"),NewMsgsPtr->ID);
+ SetAccountStatus(ActualAccount,accstatus);
+ DataRX=MyClient->Top(MsgQueuePtr->Number,100);
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Reading body>\n");
+ DebugLog(DecodeFile,"<Header>%s</Header>\n",DataRX);
+ #endif
+ if(DataRX!=NULL)
+ {
+ Temp=DataRX;
+ while((Temp<DataRX+MyClient->NetClient->Rcv) && (WS(Temp) || ENDLINE(Temp))) Temp++;
+
+ if(OKLINE(DataRX))
+ for(Temp=DataRX;(Temp<DataRX+MyClient->NetClient->Rcv) && (!ENDLINE(Temp));Temp++);
+ while((Temp<DataRX+MyClient->NetClient->Rcv) && ENDLINE(Temp)) Temp++;
+ }
+ else
+ continue;
+ //delete all the headers of the old mail MsgQueuePtr->MailData->TranslatedHeader
+ struct CMimeItem *TH = MsgQueuePtr->MailData->TranslatedHeader;
+ if (TH) for(;MsgQueuePtr->MailData->TranslatedHeader!=NULL;)
+ {
+ TH=TH->Next;
+ if(MsgQueuePtr->MailData->TranslatedHeader->name!=NULL)
+ delete[] MsgQueuePtr->MailData->TranslatedHeader->name;
+ if(MsgQueuePtr->MailData->TranslatedHeader->value!=NULL)
+ delete[] MsgQueuePtr->MailData->TranslatedHeader->value;
+ delete MsgQueuePtr->MailData->TranslatedHeader;
+ MsgQueuePtr->MailData->TranslatedHeader=TH;
+ }
+
+ TranslateHeader(Temp,MyClient->NetClient->Rcv-(Temp-DataRX),&MsgQueuePtr->MailData->TranslatedHeader);
+
+
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Reading body>\n");
+ #endif
+ MsgQueuePtr->Flags|=YAMN_MSG_BODYRECEIVED;
+
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ break;
+ }
+ }
+ }
+ }
+
+ SynchroMessages(ActualAccount,(HYAMNMAIL *)&ActualAccount->Mails,NULL,(HYAMNMAIL *)&NewMails,NULL); //we get only new mails on server!
+// NewMails=NULL;
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write done\n");
+ #endif
+ MsgsWriteDone(ActualAccount);
+ for(MsgQueuePtr=(HYAMNMAIL)ActualAccount->Mails;MsgQueuePtr!=NULL;MsgQueuePtr=MsgQueuePtr->Next){
+ if ((MsgQueuePtr->Flags&YAMN_MSG_BODYREQUESTED) && (MsgQueuePtr->Flags&YAMN_MSG_BODYRECEIVED)){
+ MsgQueuePtr->Flags&=~YAMN_MSG_BODYREQUESTED;
+ if (MsgQueuePtr->MsgWindow){
+ SendMessage(MsgQueuePtr->MsgWindow,WM_YAMN_CHANGECONTENT,0,0);
+ }
+ }
+ }
+
+ for(msgs=0,MsgQueuePtr=NewMails;MsgQueuePtr!=NULL;MsgQueuePtr=MsgQueuePtr->Next,msgs++); //get number of new mails
+
+ try
+ {
+ char accstatus[512];
+
+ for(i=0,MsgQueuePtr=NewMails;MsgQueuePtr!=NULL;i++)
+ {
+ BOOL autoretr = (ActualAccount->Flags & YAMN_ACC_BODY)!=0;
+ DataRX=MyClient->Top(MsgQueuePtr->Number,autoretr?100:0);
+ sprintf(accstatus,Translate("Reading new mail messages (%d%% done)"),100*i/msgs);
+ SetAccountStatus(ActualAccount,accstatus);
+
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<New mail>\n");
+ DebugLog(DecodeFile,"<Header>%s</Header>\n",DataRX);
+ #endif
+ if(DataRX!=NULL)
+ {
+ Temp=DataRX;
+ while((Temp<DataRX+MyClient->NetClient->Rcv) && (WS(Temp) || ENDLINE(Temp))) Temp++;
+
+ if(OKLINE(DataRX))
+ for(Temp=DataRX;(Temp<DataRX+MyClient->NetClient->Rcv) && (!ENDLINE(Temp));Temp++);
+ while((Temp<DataRX+MyClient->NetClient->Rcv) && ENDLINE(Temp)) Temp++;
+ }
+ else
+ continue;
+
+ TranslateHeader(Temp,MyClient->NetClient->Rcv-(Temp-DataRX),&MsgQueuePtr->MailData->TranslatedHeader);
+
+
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</New mail>\n");
+ #endif
+ MsgQueuePtr->Flags|=YAMN_MSG_NORMALNEW;
+ if (autoretr) MsgQueuePtr->Flags|=YAMN_MSG_BODYRECEIVED;
+
+ //We are going to filter mail. Warning!- we must not be in read access neither write access to mails when calling this service
+ //This is done, because the "NewMails" queue is not synchronised. It is because it is new queue. Only this thread uses new queue yet, it is not
+ //connected to account mail queue.
+ // CallService(MS_YAMN_FILTERMAIL,(WPARAM)ActualAccount,(LPARAM)MsgQueuePtr);
+ FilterMailSvc((WPARAM)ActualAccount,(LPARAM)MsgQueuePtr);
+
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+
+ //MsgQueuePtr->MailData->Body=MyClient->Retr(MsgQueuePtr->Number);
+
+ MsgQueuePtr=MsgQueuePtr->Next;
+
+ }
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</--------Account checking-------->\n");
+ #endif
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=MsgsWaitToWrite(ActualAccount))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write wait failed\n");
+ #endif
+ throw (DWORD)ActualAccount->SystemError==EACC_STOPPED;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write enter\n");
+ #endif
+ if(ActualAccount->Mails==NULL)
+ ActualAccount->Mails=NewMails;
+ else
+ {
+ ActualAccount->LastMail=ActualAccount->LastChecked;
+ AppendQueue((HYAMNMAIL)ActualAccount->Mails,NewMails);
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write done\n");
+ #endif
+ MsgsWriteDone(ActualAccount);
+
+ // we are going to delete mails having SPAM flag level3 and 4 (see m_mails.h) set
+ {
+ struct DeleteParam ParamToDeleteMails={YAMN_DELETEVERSION,INVALID_HANDLE_VALUE,ActualAccount,YAMNParam,(void *)POP3_DELETEFROMCHECK};
+
+ // Delete mails from server. Here we should not be in write access for account's mails
+ DeleteMailsPOP3(&ParamToDeleteMails);
+ }
+
+ // if there is no waiting thread for internet connection close it
+ // else leave connection open
+ if(0==SCGetNumber(ActualAccount->InternetQueries))
+ {
+ DataRX=MyClient->Quit();
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ MyClient->NetClient->Disconnect();
+
+ SetAccountStatus(ActualAccount,Translate("Disconnected"));
+ }
+
+ UsingInternet=FALSE;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:InternetFreeEV-done\n");
+ #endif
+ SetEvent(ActualAccount->UseInternetFree);
+
+ ActualAccount->LastSChecked=ActualAccount->LastChecked;
+ ActualAccount->LastSynchronised=ActualAccount->LastChecked;
+ }
+ catch(...)
+ {
+ throw; //go to the main exception handling
+ }
+
+ {
+ YAMN_MAILBROWSERPARAM Param={(HANDLE)0,ActualAccount,ActualCopied.NFlags,ActualCopied.NNFlags,YAMNParam};
+
+ if(CheckFlags & YAMN_FORCECHECK)
+ Param.nnflags|=YAMN_ACC_POP; //if force check, show popup anyway and if mailbrowser was opened, do not close
+ Param.nnflags|= YAMN_ACC_MSGP; //do not close browser if already open
+ CallService(MS_YAMN_MAILBROWSER,(WPARAM)&Param,(LPARAM)YAMN_MAILBROWSERVERSION);
+ }
+ SetContactStatus(ActualAccount,ActualAccount->isCounting?ID_STATUS_ONLINE:ID_STATUS_OFFLINE);
+ }
+ #ifdef DEBUG_COMM
+ catch(DWORD ErrorCode)
+ #else
+ catch(DWORD)
+ #endif
+ {
+ if(ActualAccount->Client.POP3Error==EPOP3_STOPPED)
+ ActualAccount->SystemError=EACC_STOPPED;
+ #ifdef DEBUG_COMM
+ DebugLog(CommFile,"ERROR: %x\n",ErrorCode);
+ #endif
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write wait\n");
+ #endif
+ if(WAIT_OBJECT_0==MsgsWaitToWrite(ActualAccount))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write enter\n");
+ #endif
+ ActualAccount->LastChecked=now;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write done\n");
+ #endif
+ MsgsWriteDone(ActualAccount);
+ }
+ #ifdef DEBUG_SYNCHRO
+ else
+ DebugLog(SynchroFile,"CheckPOP3:ActualAccountMsgsSO-write wait failed\n");
+ #endif
+
+ DeleteMIMEQueue(ActualAccount,NewMails);
+
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ switch(ActualAccount->SystemError)
+ {
+ case EACC_QUEUEALLOC:
+ case EACC_STOPPED:
+ ActualAccount->Client.NetClient->Disconnect();
+ break;
+ default:
+ PostErrorProc(ActualAccount,YAMNParam,(DWORD)NULL,MyClient->SSL); //it closes internet connection too
+ }
+
+ if(UsingInternet) //if our thread still uses internet
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:InternetFreeEV-done\n");
+ #endif
+ SetEvent(ActualAccount->UseInternetFree);
+ }
+ SetContactStatus(ActualAccount,ID_STATUS_NA);
+ }
+ free(ActualCopied.ServerName);
+ free(ActualCopied.ServerLogin);
+ free(ActualCopied.ServerPasswd);
+ #ifdef DEBUG_COMM
+ DebugLog(CommFile,"</--------Communication-------->\n");
+ #endif
+// WriteAccounts();
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+ #endif
+ SCDec(ActualAccount->UsingThreads);
+ return 0;
+}
+
+DWORD WINAPI DeleteMailsPOP3(struct DeleteParam *WhichTemp)
+{
+ HPOP3ACCOUNT ActualAccount;
+ LPVOID YAMNParam;
+ UINT_PTR POP3PluginParam;
+ CPop3Client *MyClient;
+ HYAMNMAIL DeleteMails,NewMails=NULL,MsgQueuePtr;
+ char* DataRX=NULL;
+ int mboxsize,msgs,i;
+ BOOL UsingInternet=FALSE;
+ struct {
+ char *ServerName;
+ DWORD ServerPort;
+ char *ServerLogin;
+ char *ServerPasswd;
+ DWORD Flags;
+ DWORD NFlags;
+ DWORD NNFlags;
+ } ActualCopied;
+
+ //First, we should compare our version of DeleteParam structure, but here it is not needed, because YAMN and internal plugin
+ //have the same version. But your plugin should do that in this way:
+ // if(((struct DeleteParam *)WhichTemp)->Ver!=YAMN_DELETEVERSION)
+ // {
+ // SetEvent(((struct DeleteParam *)WhichTemp)->ThreadRunningEV); //don't forget to unblock YAMN
+ // return (DWORD)-1; //ok, but we should return value.
+ // //When our plugin returns e.g. 0xFFFFFFFF (this is only our plugin value, YAMN does nothing with return value,
+ // //but only tests if it is nonzero. If yes, it calls GetErrorStringFcn), we know problem occured in YAMN incompatibility
+ // //and then we can in our GetErrorStringFcn e.g. return string "Uncompatible version of YAMN".
+ // }
+
+ ActualAccount=(HPOP3ACCOUNT)((struct DeleteParam *)WhichTemp)->AccountParam; //copy address of structure from calling thread to stack of this thread
+ YAMNParam=((struct DeleteParam *)WhichTemp)->BrowserParam;
+ POP3PluginParam=(UINT_PTR)((struct DeleteParam *)WhichTemp)->CustomParam;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:Incrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+#endif
+ SCInc(ActualAccount->UsingThreads);
+ if(INVALID_HANDLE_VALUE!=WhichTemp->ThreadRunningEV)
+ SetEvent(WhichTemp->ThreadRunningEV);
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountSO-read wait\n");
+#endif
+ if(WAIT_OBJECT_0!=WaitToRead(ActualAccount))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountSO-read wait failed\n");
+#endif
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+#endif
+ SCDec(ActualAccount->UsingThreads);
+ return 0;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountSO-read enter\n");
+#endif
+ if(NULL==(DeleteMails=(HYAMNMAIL)CreateNewDeleteQueue((HYAMNMAIL)ActualAccount->Mails))) //if there's no mail for deleting, return
+ {
+ if(POP3_DELETEFROMCHECK!=POP3PluginParam) //We do not wait for free internet when calling from SynchroPOP3. It is because UseInternetFree is blocked
+ {
+ YAMN_MAILBROWSERPARAM Param={(HANDLE)0,ActualAccount,YAMN_ACC_MSGP,YAMN_ACC_MSGP,YAMNParam}; //Just update the window
+
+ CallService(MS_YAMN_MAILBROWSER,(WPARAM)&Param,(LPARAM)YAMN_MAILBROWSERVERSION);
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountSO-read done\n");
+#endif
+ ReadDone(ActualAccount);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+#endif
+ SCDec(ActualAccount->UsingThreads);
+
+ return NO_MAIL_FOR_DELETE;
+ }
+ MyClient=&(ActualAccount->Client);
+
+//Now, copy all needed information about account to local variables, so ActualAccount is not blocked in read mode during all connection process, which can last for several minutes.
+ ActualCopied.ServerName=_strdup(ActualAccount->Server->Name);
+ ActualCopied.ServerPort=ActualAccount->Server->Port;
+ ActualCopied.Flags=ActualAccount->Flags;
+ ActualCopied.ServerLogin=_strdup(ActualAccount->Server->Login);
+ ActualCopied.ServerPasswd=_strdup(ActualAccount->Server->Passwd);
+ ActualCopied.NFlags=ActualAccount->NewMailN.Flags;
+ ActualCopied.NNFlags=ActualAccount->NoNewMailN.Flags;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountSO-read done\n");
+#endif
+ ReadDone(ActualAccount);
+
+ SCInc(ActualAccount->InternetQueries); //This is POP3-internal SCOUNTER, we set another thread wait for this account to be connected to inet
+ if(POP3_DELETEFROMCHECK!=POP3PluginParam) //We do not wait for free internet when calling from SynchroPOP3. It is because UseInternetFree is blocked
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:InternetFreeEV-wait\n");
+#endif
+ WaitForSingleObject(ActualAccount->UseInternetFree,INFINITE);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:InternetFreeEV-enter\n");
+#endif
+ }
+ SCDec(ActualAccount->InternetQueries);
+ UsingInternet=TRUE;
+
+ try
+ {
+ SetContactStatus(ActualAccount,ID_STATUS_OCCUPIED);
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<--------Communication-------->\n");
+#endif
+ if((MyClient->NetClient==NULL) || !MyClient->NetClient->Connected())
+ {
+ SetAccountStatus(ActualAccount,Translate("Connecting to server"));
+
+ DataRX=MyClient->Connect(ActualCopied.ServerName,ActualCopied.ServerPort,ActualCopied.Flags & YAMN_ACC_SSL23,ActualCopied.Flags & YAMN_ACC_NOTLS);
+
+ char *timestamp=NULL;
+ if(DataRX!=NULL) {
+ if(ActualAccount->Flags & YAMN_ACC_APOP) {
+ char *lpos=strchr(DataRX,'<');
+ char *rpos=strchr(DataRX,'>');
+ if(lpos && rpos && rpos>lpos) {
+ int sz=(int)(rpos-lpos+2);
+ timestamp=new char[sz];
+ memcpy(timestamp, lpos, sz-1);
+ timestamp[sz-1]='\0';
+ }
+ }
+ free(DataRX);
+ DataRX=NULL;
+ }
+ SetAccountStatus(ActualAccount,Translate("Entering POP3 account"));
+
+ if(ActualAccount->Flags & YAMN_ACC_APOP)
+ {
+ DataRX=MyClient->APOP(ActualCopied.ServerLogin,ActualCopied.ServerPasswd,timestamp);
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ delete[] timestamp;
+ } else {
+ DataRX=MyClient->User(ActualCopied.ServerLogin);
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ DataRX=MyClient->Pass(ActualCopied.ServerPasswd);
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ }
+ }
+
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<--------Deleting requested mails-------->\n");
+#endif
+ if(POP3_DELETEFROMCHECK!=POP3PluginParam) //We do not need to get mails on server as we have already it from check function
+ {
+ SetAccountStatus(ActualAccount,Translate("Deleting requested mails"));
+
+ DataRX=MyClient->Stat();
+
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting stat>\n");
+#endif
+ ExtractStat(DataRX,MyClient->NetClient->Rcv,&mboxsize,&msgs);
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<MailBoxSize>%d</MailBoxSize>\n",mboxsize);
+ DebugLog(DecodeFile,"<Msgs>%d</Msgs>\n",msgs);
+ DebugLog(DecodeFile,"</Extracting stat>\n");
+#endif
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ for(i=0;i<msgs;i++)
+ {
+ if(!i)
+ MsgQueuePtr=NewMails=(HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL,(WPARAM)ActualAccount,(LPARAM)YAMN_MAILVERSION);
+ else
+ {
+ MsgQueuePtr->Next=(HYAMNMAIL)CallService(MS_YAMN_CREATEACCOUNTMAIL,(WPARAM)ActualAccount,(LPARAM)YAMN_MAILVERSION);
+ MsgQueuePtr=MsgQueuePtr->Next;
+ }
+ if(MsgQueuePtr==NULL)
+ {
+ ActualAccount->SystemError=EPOP3_QUEUEALLOC;
+ throw (DWORD)ActualAccount->SystemError;
+ }
+ }
+
+ if(msgs)
+ {
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Extracting UIDL>\n");
+#endif
+ DataRX=MyClient->Uidl();
+ ExtractUIDL(DataRX,MyClient->NetClient->Rcv,NewMails);
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</Extracting UIDL>\n");
+#endif
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+// we get "new mails" on server (NewMails will contain all mails on server not found in DeleteMails)
+// but also in DeleteMails we get only those, which are still on server with their responsable numbers
+ SynchroMessages(ActualAccount,(HYAMNMAIL *)&DeleteMails,NULL,(HYAMNMAIL *)&NewMails,NULL);
+ }
+ }
+ else
+ SetAccountStatus(ActualAccount,Translate("Deleting spam"));
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountMsgsSO-write wait\n");
+#endif
+ if(WAIT_OBJECT_0!=MsgsWaitToWrite(ActualAccount))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountMsgsSO-write wait failed\n");
+#endif
+ throw (DWORD)EACC_STOPPED;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountMsgsSO-write enter\n");
+#endif
+ if(msgs || POP3_DELETEFROMCHECK==POP3PluginParam)
+ {
+ try
+ {
+ HYAMNMAIL Temp;
+
+ for(i=0,MsgQueuePtr=DeleteMails;MsgQueuePtr!=NULL;i++)
+ {
+ if(!(MsgQueuePtr->Flags & YAMN_MSG_VIRTUAL)) //of course we can only delete real mails, not virtual
+ {
+ DataRX=MyClient->Dele(MsgQueuePtr->Number);
+ Temp=MsgQueuePtr->Next;
+ if(POP3_FOK==MyClient->AckFlag) //if server answers that mail was deleted
+ {
+ DeleteMIMEMessage((HYAMNMAIL *)&DeleteMails,MsgQueuePtr);
+ HYAMNMAIL DeletedMail=FindMIMEMessageByID((HYAMNMAIL)ActualAccount->Mails,MsgQueuePtr->ID);
+ if((MsgQueuePtr->Flags & YAMN_MSG_MEMDELETE)) //if mail should be deleted from memory (or disk)
+ {
+ DeleteMIMEMessage((HYAMNMAIL *)&ActualAccount->Mails,DeletedMail); //remove from queue
+ CallService(MS_YAMN_DELETEACCOUNTMAIL,(WPARAM)POP3Plugin,(LPARAM)DeletedMail);
+ }
+ else //else mark it only as "deleted mail"
+ {
+ DeletedMail->Flags |= (YAMN_MSG_VIRTUAL | YAMN_MSG_DELETED);
+ DeletedMail->Flags &= ~(YAMN_MSG_NEW | YAMN_MSG_USERDELETE | YAMN_MSG_AUTODELETE); //clear "new mail"
+ }
+ delete MsgQueuePtr->MailData;
+ delete[] MsgQueuePtr->ID;
+ delete MsgQueuePtr;
+ }
+ MsgQueuePtr=Temp;
+
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ }
+ else
+ MsgQueuePtr=MsgQueuePtr->Next;
+ }
+ }
+ catch(...) //if any exception in the code where we have write-access to account occured, don't forget to leave write-access
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountMsgsSO-write done\n");
+#endif
+ MsgsWriteDone(ActualAccount);
+ throw; //and go to the main exception handling
+ }
+
+ if(NewMails!=NULL)
+// in ActualAccount->Mails we have all mails stored before calling this function
+// in NewMails we have all mails not found in DeleteMails (in other words: we performed new ID checking and we
+// stored all mails found on server, then we deleted the ones we wanted to delete in this function
+// and NewMails queue now contains actual state of mails on server). But we will not use NewMails as actual state, because NewMails does not contain header data (subject, from...)
+// We perform deleting from ActualAccount->Mails: we remove from original queue (ActualAccount->Mails) all deleted mails
+ SynchroMessages(ActualAccount,(HYAMNMAIL *)&ActualAccount->Mails,NULL,(HYAMNMAIL *)&NewMails,NULL);
+// Now ActualAccount->Mails contains all mails when calling this function except the ones, we wanted to delete (these are in DeleteMails)
+// And in NewMails we have new mails (if any)
+ else if(POP3_DELETEFROMCHECK!=POP3PluginParam)
+ {
+ DeleteMIMEQueue(ActualAccount,(HYAMNMAIL)ActualAccount->Mails);
+ ActualAccount->Mails=NULL;
+ }
+ }
+ else
+ {
+ DeleteMIMEQueue(ActualAccount,(HYAMNMAIL)ActualAccount->Mails);
+ ActualAccount->Mails=NULL;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:ActualAccountMsgsSO-write done\n");
+#endif
+ MsgsWriteDone(ActualAccount);
+#ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"</--------Deleting requested mails-------->\n");
+#endif
+
+// TODO: now, we have in NewMails new mails. If NewMails is not NULL, we found some new mails, so Checking for new mail should be performed
+// now, we do not call CheckPOP3
+
+// if there is no waiting thread for internet connection close it
+// else leave connection open
+// if this functin was called from SynchroPOP3, then do not try to disconnect
+ if(POP3_DELETEFROMCHECK!=POP3PluginParam)
+ {
+ YAMN_MAILBROWSERPARAM Param={(HANDLE)0,ActualAccount,ActualCopied.NFlags,YAMN_ACC_MSGP,YAMNParam};
+
+ CallService(MS_YAMN_MAILBROWSER,(WPARAM)&Param,(LPARAM)YAMN_MAILBROWSERVERSION);
+
+ if(0==SCGetNumber(ActualAccount->InternetQueries))
+ {
+ DataRX=MyClient->Quit();
+ if(DataRX!=NULL)
+ free(DataRX);
+ DataRX=NULL;
+ MyClient->NetClient->Disconnect();
+
+ SetAccountStatus(ActualAccount,Translate("Disconnected"));
+ }
+
+ UsingInternet=FALSE;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:InternetFreeEV-done\n");
+#endif
+ SetEvent(ActualAccount->UseInternetFree);
+ }
+ SetContactStatus(ActualAccount,ActualAccount->isCounting?ID_STATUS_ONLINE:ID_STATUS_OFFLINE);
+ }
+#ifdef DEBUG_COMM
+ catch(DWORD ErrorCode)
+#else
+ catch(DWORD)
+#endif
+ {
+ if(ActualAccount->Client.POP3Error==EPOP3_STOPPED)
+ ActualAccount->SystemError=EACC_STOPPED;
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"ERROR %x\n",ErrorCode);
+#endif
+ if(DataRX!=NULL)
+ free(DataRX);
+ switch(ActualAccount->SystemError)
+ {
+ case EACC_QUEUEALLOC:
+ case EACC_STOPPED:
+ ActualAccount->Client.NetClient->Disconnect();
+ break;
+ default:
+ PostErrorProc(ActualAccount,YAMNParam,POP3PluginParam,MyClient->SSL); //it closes internet connection too
+ }
+
+ if(UsingInternet && (POP3_DELETEFROMCHECK!=POP3PluginParam)) //if our thread still uses internet and it is needed to release internet
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"CheckPOP3:InternetFreeEV-done\n");
+#endif
+ SetEvent(ActualAccount->UseInternetFree);
+ }
+ }
+
+ free(ActualCopied.ServerName);
+ free(ActualCopied.ServerLogin);
+ free(ActualCopied.ServerPasswd);
+
+ DeleteMIMEQueue(ActualAccount,NewMails);
+ DeleteMIMEQueue(ActualAccount,DeleteMails);
+
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</--------Communication-------->\n");
+#endif
+// WriteAccounts();
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"DeleteMailsPOP3:Decrementing \"using threads\" %x (account %x)\n",ActualAccount->UsingThreads,ActualAccount);
+#endif
+ SCDec(ActualAccount->UsingThreads);
+ return 0;
+}
+
+void ExtractStat(char *stream,int len,int *mboxsize,int *mails)
+{
+ char *finder=stream;
+ while(WS(finder) || ENDLINE(finder)) finder++;
+ if(ACKLINE(finder))
+ {
+ while(!WS(finder)) finder++;
+ while(WS(finder)) finder++;
+ }
+ if(1!=sscanf(finder,"%d",mails))
+ throw (DWORD)EPOP3_STAT;
+ while(!WS(finder)) finder++;
+ while(WS(finder)) finder++;
+ if(1!=sscanf(finder,"%d",mboxsize))
+ throw (DWORD)EPOP3_STAT;
+}
+void ExtractMail(char *stream,int len,HYAMNMAIL queue)
+{
+ char *finder=stream;
+ char *finderend;
+ int msgnr,i;
+ HYAMNMAIL queueptr=queue;
+
+ while(WS(finder) || ENDLINE(finder)) finder++;
+ while(!ACKLINE(finder)) finder++;
+ while(!ENDLINE(finder)) finder++; //now we at the end of first ack line
+ while(finder<=(stream+len))
+ {
+ while(ENDLINE(finder)) finder++; //go to the new line
+ if(DOTLINE(finder+1)) //at the end of stream
+ break;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Message>\n");
+ #endif
+ while(WS(finder)) finder++; //jump whitespace
+ if(1!=sscanf(finder,"%d",&msgnr))
+ throw (DWORD)EPOP3_UIDL;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Nr>%d</Nr>\n",msgnr);
+ #endif
+// for(i=1,queueptr=queue;(queueptr->Next!=NULL) && (i<msgnr);queueptr=queueptr->Next,i++);
+// if(i!=msgnr)
+// throw (DWORD)EPOP3_UIDL;
+ while(!WS(finder)) finder++; //jump characters
+ while(WS(finder)) finder++; //jump whitespace
+ finderend=finder+1;
+ while(!WS(finderend) && !ENDLINE(finderend)) finderend++;
+ queueptr->ID=new char[finderend-finder+1];
+ for(i=0;finder!=finderend;finder++,i++)
+ queueptr->MailData->Body[i]=*finder;
+ queueptr->MailData->Body[i]=0; //ends string
+ queueptr->Number=msgnr;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<ID>%s</ID>\n",queueptr->MailData->Body);
+ DebugLog(DecodeFile,"</Message>\n");
+ #endif
+ queueptr=queueptr->Next;
+ while(!ENDLINE(finder)) finder++;
+ }
+}
+
+void ExtractUIDL(char *stream,int len,HYAMNMAIL queue)
+{
+ char *finder=stream;
+ char *finderend;
+ int msgnr,i;
+ HYAMNMAIL queueptr=queue;
+
+ while(WS(finder) || ENDLINE(finder)) finder++;
+ while(!ACKLINE(finder)) finder++;
+ while(!ENDLINE(finder)) finder++; //now we at the end of first ack line
+ while(finder<=(stream+len))
+ {
+ while(ENDLINE(finder)) finder++; //go to the new line
+ if(DOTLINE(finder+1)) //at the end of stream
+ break;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Message>\n");
+ #endif
+ while(WS(finder)) finder++; //jump whitespace
+ if(1!=sscanf(finder,"%d",&msgnr))
+ throw (DWORD)EPOP3_UIDL;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Nr>%d</Nr>\n",msgnr);
+ #endif
+// for(i=1,queueptr=queue;(queueptr->Next!=NULL) && (i<msgnr);queueptr=queueptr->Next,i++);
+// if(i!=msgnr)
+// throw (DWORD)EPOP3_UIDL;
+ while(!WS(finder)) finder++; //jump characters
+ while(WS(finder)) finder++; //jump whitespace
+ finderend=finder+1;
+ while(!WS(finderend) && !ENDLINE(finderend)) finderend++;
+ queueptr->ID=new char[finderend-finder+1];
+ for(i=0;finder!=finderend;finder++,i++)
+ queueptr->ID[i]=*finder;
+ queueptr->ID[i]=0; //ends string
+ queueptr->Number=msgnr;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<ID>%s</ID>\n",queueptr->ID);
+ DebugLog(DecodeFile,"</Message>\n");
+ #endif
+ queueptr=queueptr->Next;
+ while(!ENDLINE(finder)) finder++;
+ }
+}
+
+void ExtractList(char *stream,int len,HYAMNMAIL queue)
+{
+ char *finder=stream;
+ char *finderend;
+ int msgnr,i;
+ HYAMNMAIL queueptr;
+
+ while(WS(finder) || ENDLINE(finder)) finder++;
+ while(!ACKLINE(finder)) finder++;
+ while(!ENDLINE(finder)) finder++; //now we at the end of first ack line
+ while(finder<=(stream+len))
+ {
+ while(ENDLINE(finder)) finder++; //go to the new line
+ if(DOTLINE(finder+1)) //at the end of stream
+ break;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Message>\n",NULL,0);
+ #endif
+ while(WS(finder)) finder++; //jump whitespace
+ if(1!=sscanf(finder,"%d",&msgnr)) //message nr.
+ throw (DWORD)EPOP3_LIST;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Nr>%d</Nr>\n",msgnr);
+ #endif
+
+ for(i=1,queueptr=queue;(queueptr->Next!=NULL) && (i<msgnr);queueptr=queueptr->Next,i++);
+ if(i!=msgnr)
+ throw (DWORD)EPOP3_LIST;
+ while(!WS(finder)) finder++; //jump characters
+ while(WS(finder)) finder++; //jump whitespace
+ finderend=finder+1;
+ if(1!=sscanf(finder,"%d",&queueptr->MailData->Size))
+ throw (DWORD)EPOP3_LIST;
+ #ifdef DEBUG_DECODE
+ DebugLog(DecodeFile,"<Nr>%d</Nr>\n",queueptr->MailData->Size);
+ #endif
+ while(!ENDLINE(finder)) finder++;
+ }
+}
+
+WCHAR* WINAPI GetErrorString(DWORD Code)
+{
+ static char *POP3Errors[]=
+ {
+ "Memory allocation error.", //memory allocation
+ "Account is about to be stopped.", //stop account
+ "Cannot connect to POP3 server.",
+ "Cannot allocate memory for received data.",
+ "Cannot login to POP3 server.",
+ "Bad user or password.",
+ "Server does not support APOP authorization.",
+ "Error while executing POP3 command.",
+ "Error while executing POP3 command.",
+ "Error while executing POP3 command.",
+ };
+
+ static char *NetlibErrors[]=
+ {
+ "Cannot connect to server with NetLib.",
+ "Cannot send data.",
+ "Cannot receive data.",
+ "Cannot allocate memory for received data.",
+ };
+
+ static char *SSLErrors[]=
+ {
+ "OpenSSL not loaded.",
+ "Windows socket 2.0 init failed.",
+ "DNS lookup error.",
+ "Error while creating base socket.",
+ "Error connecting to server with socket.",
+ "Error while creating SSL structure.",
+ "Error connecting socket with SSL.",
+ "Server rejected connection with SSL.",
+ "Cannot write SSL data.",
+ "Cannot read SSL data.",
+ "Cannot allocate memory for received data.",
+ };
+
+ char *ErrorStringA=new char[ERRORSTR_MAXLEN];
+ WCHAR *ErrorStringW=new WCHAR[ERRORSTR_MAXLEN];
+ POP3_ERRORCODE *ErrorCode=(POP3_ERRORCODE *)(UINT_PTR)Code;
+
+ sprintf(ErrorStringA,Translate("Error %d-%d-%d-%d:"),ErrorCode->AppError,ErrorCode->POP3Error,ErrorCode->NetError,ErrorCode->SystemError);
+ if(ErrorCode->POP3Error)
+ sprintf(ErrorStringA,"%s\n%s",ErrorStringA,Translate(POP3Errors[ErrorCode->POP3Error-1]));
+ if(ErrorCode->NetError)
+ if(ErrorCode->SSL)
+ sprintf(ErrorStringA,"%s\n%s",ErrorStringA,Translate(SSLErrors[ErrorCode->NetError-1]));
+ else
+ sprintf(ErrorStringA,"%s\n%s",ErrorStringA,Translate(NetlibErrors[ErrorCode->NetError-4]));
+
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"%s\n",ErrorStringA);
+#endif
+ MultiByteToWideChar(CP_ACP,MB_USEGLYPHCHARS,ErrorStringA,-1,ErrorStringW,(int)strlen(ErrorStringA)+1);
+ delete[] ErrorStringA; //we delete ErrorStringA, used to get error string, because Translate() doesn't works in unicode
+ delete ErrorCode; //now we can delete ErrorCode, that will not be used anymore
+ return ErrorStringW;
+}
+
+void WINAPI DeleteErrorString(LPVOID String)
+{
+ delete (char *)String;
+}
diff --git a/yamn/proto/pop3/pop3comm.h b/yamn/proto/pop3/pop3comm.h new file mode 100644 index 0000000..0d30e5d --- /dev/null +++ b/yamn/proto/pop3/pop3comm.h @@ -0,0 +1,97 @@ +#ifndef __POP3COMM_H
+#define __POP3COMM_H
+
+#include <windows.h>
+#include "pop3.h"
+
+#include "../../m_protoplugin.h"
+//We can use synchro.h because this is internal plugin. If you use external plugin,
+//and you want to use SO for your plugin, you can use YAMN's SO.
+//All you need is to include synchro.h and use YAMN's exported synchronization functions.
+#include "../../m_synchro.h"
+
+//For mail exported functions defintions
+#include "../../mails/m_mails.h"
+
+#include "../../debug.h"
+
+#define POP3_FILEVERSION 1 //Version of aditional information stored in book file
+
+typedef struct CPOP3Account: public CAccount
+{
+// We can use SCOUNTER structure, because this is internal plugin.
+// This SO is used to determine if any POP3 account is in "write access" mode
+ static PSCOUNTER AccountWriterSO;
+
+// It is usefull to have client structure in account. With this structure we have access to account's socket.
+// This is related to InternetQueries and UseInternetFree
+// This member should be synchronized with UseInternetFree
+ class CPop3Client Client;
+
+// This member is usefull for MIME headers. It is default codepage, if no other codepage found
+ WORD CP; //access only through AccountAccessSO
+
+// In this memeber last error code is stored
+ DWORD SystemError; //access through UseInternetFree
+
+// We use only counter from this object and it is # of threads waiting to work on internet.
+// We use event UseInternet to access critical sections.
+// It is usefull in 2 ways: we have mutual exclusion that only one thread works with account on internet.
+// Thread, which has done its work with account on internet can close socket, but it is not needed, when any other
+// thread wants to work (e.g. we have deleted mails, but when deleting, another thread wants to check new mail, so
+// we delete all needed mails and check if there's thread that wants to work. If yes, we do not need to quit session,
+// we leave socket open, and leave internet. Another thread then start checking and does not connect, does not send
+// user and password... because socket is open- it continues)
+ PSCOUNTER InternetQueries;
+ HANDLE UseInternetFree;
+
+ CPOP3Account();
+ ~CPOP3Account();
+
+} POP3ACCOUNT,*HPOP3ACCOUNT;
+
+typedef struct POP3LayeredError
+{
+ BOOL SSL;
+ DWORD AppError;
+ DWORD POP3Error;
+ DWORD NetError;
+ DWORD SystemError;
+} POP3_ERRORCODE,*PPOP3_ERRORCODE;
+
+struct YAMNExportedFcns
+{
+ YAMN_SETPROTOCOLPLUGINFCNIMPORTFCN SetProtocolPluginFcnImportFcn;
+ YAMN_WAITTOWRITEFCN WaitToWriteFcn;
+ YAMN_WRITEDONEFCN WriteDoneFcn;
+ YAMN_WAITTOREADFCN WaitToReadFcn;
+ YAMN_READDONEFCN ReadDoneFcn;
+ YAMN_SCMANAGEFCN SCGetNumberFcn;
+ YAMN_SCMANAGEFCN SCIncFcn;
+ YAMN_SCMANAGEFCN SCDecFcn;
+ YAMN_SETSTATUSFCN SetStatusFcn;
+ YAMN_GETSTATUSFCN GetStatusFcn;
+};
+
+struct MailExportedFcns
+{
+ YAMN_SYNCHROMIMEMSGSFCN SynchroMessagesFcn;
+ YAMN_TRANSLATEHEADERFCN TranslateHeaderFcn;
+ YAMN_APPENDQUEUEFCN AppendQueueFcn;
+ YAMN_DELETEMIMEQUEUEFCN DeleteMessagesToEndFcn;
+ YAMN_DELETEMIMEMESSAGEFCN DeleteMessageFromQueueFcn;
+ YAMN_FINDMIMEMESSAGEFCN FindMessageByIDFcn;
+ YAMN_CREATENEWDELETEQUEUEFCN CreateNewDeleteQueueFcn;
+};
+
+enum
+{
+ EACC_QUEUEALLOC=1, //memory allocation
+ EACC_STOPPED, //stop account
+};
+
+#define NO_MAIL_FOR_DELETE 1
+
+#define POP3_DELETEFROMCHECK 1
+
+#endif
diff --git a/yamn/proto/pop3/pop3opt.cpp b/yamn/proto/pop3/pop3opt.cpp new file mode 100644 index 0000000..004d2aa --- /dev/null +++ b/yamn/proto/pop3/pop3opt.cpp @@ -0,0 +1,1671 @@ +/*
+ * This code implements POP3 options window handling
+ *
+ * (c) majvan 2002-2003
+*/
+
+/*
+#include <tchar.h>
+#include <stdio.h>
+#include <windows.h>
+#include <winuser.h>
+#include <commctrl.h>
+#include "../../../../../SDK/headers_c/newpluginapi.h"
+//#include "../../../../random/utils/m_utils.h" //for window broadcasting
+#include "../../../../../SDK/headers_c/m_langpack.h"
+#include "../../../../../SDK/headers_c/m_options.h"
+#include "../../../../../SDK/headers_c/m_utils.h"
+#include "../../SDK/import/m_popup.h"
+#include "../../m_protoplugin.h"
+#include "../../m_synchro.h"
+#include "../../m_messages.h"
+#include "../../resources/resource.h"
+#include "../../m_yamn.h"
+#include "../../debug.h"
+*/
+#include "../../yamn.h"
+#include "../../main.h"
+#include "pop3comm.h"
+#include "pop3opt.h"
+#include "uxtheme.h"
+
+//- imported ---------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+extern PLUGINLINK *pluginLink;
+extern PYAMN_VARIABLES pYAMNVar;
+extern HYAMNPROTOPLUGIN POP3Plugin;
+extern struct YAMNExportedFcns *pYAMNFcn;
+extern YAMN_VARIABLES YAMNVar;
+
+extern HICON hYamnIcons[];
+
+extern DWORD WINAPI WritePOP3Accounts();
+extern DWORD HotKeyThreadID;
+extern LPCRITICAL_SECTION PluginRegCS;
+//From filterplugin.cpp
+extern PYAMN_FILTERPLUGINQUEUE FirstFilterPlugin;
+//From protoplugin.cpp
+extern PYAMN_PROTOPLUGINQUEUE FirstProtoPlugin;
+//for XP themes
+extern BOOL (WINAPI *MyEnableThemeDialogTexture)(HANDLE, DWORD);
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+
+BOOL Check0,Check1,Check2,Check3,Check4,Check5,Check6,Check7,Check8,Check9;
+TCHAR DlgInput[MAX_PATH];
+
+//Fuction took from Miranda
+void WordToModAndVk(WORD w,UINT *mod,UINT *vk);
+
+//Initializes YAMN general options for Miranda
+int YAMNOptInitSvc(WPARAM wParam,LPARAM lParam);
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+void WordToModAndVk(WORD w,UINT *mod,UINT *vk)
+{
+ *mod=0;
+ if(HIBYTE(w)&HOTKEYF_CONTROL) *mod|=MOD_CONTROL;
+ if(HIBYTE(w)&HOTKEYF_SHIFT) *mod|=MOD_SHIFT;
+ if(HIBYTE(w)&HOTKEYF_ALT) *mod|=MOD_ALT;
+ if(HIBYTE(w)&HOTKEYF_EXT) *mod|=MOD_WIN;
+ *vk=LOBYTE(w);
+}
+
+
+INT_PTR CALLBACK DlgProcYAMNOpt(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hDlg);
+ CheckDlgButton(hDlg,IDC_CHECKTTB,DBGetContactSettingByte(NULL,YAMN_DBMODULE,YAMN_TTBFCHECK,1) ? BST_CHECKED : BST_UNCHECKED);
+ SendDlgItemMessage(hDlg,IDC_HKFORCE,HKM_SETHOTKEY,DBGetContactSettingWord(NULL,YAMN_DBMODULE,YAMN_HKCHECKMAIL,YAMN_DEFAULTHK),0);
+ CheckDlgButton(hDlg,IDC_LONGDATE,(optDateTime&SHOWDATELONG) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_SMARTDATE,(optDateTime&SHOWDATENOTODAY) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_NOSECONDS,(optDateTime&SHOWDATENOSECONDS) ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_MAINMENU,DBGetContactSettingByte(NULL, YAMN_DBMODULE, YAMN_SHOWMAINMENU, 0));
+ CheckDlgButton(hDlg,IDC_YAMNASPROTO,DBGetContactSettingByte(NULL, YAMN_DBMODULE, YAMN_SHOWASPROTO, 0));
+ CheckDlgButton(hDlg,IDC_CLOSEONDELETE,DBGetContactSettingByte(NULL, YAMN_DBMODULE, YAMN_CLOSEDELETE, 0));
+
+ break;
+ case WM_COMMAND:
+ {
+ WORD wNotifyCode = HIWORD(wParam);
+ switch(LOWORD(wParam))
+ {
+ case IDC_YAMNASPROTO:
+ case IDC_MAINMENU:
+ case IDC_CHECKTTB:
+ case IDC_HKFORCE:
+ case IDC_CLOSEONDELETE:
+ case IDC_LONGDATE:
+ case IDC_SMARTDATE:
+ case IDC_NOSECONDS:
+ SendMessage(GetParent(hDlg),PSM_CHANGED,0,0);
+ break;
+
+ }
+ break;
+ }
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ switch(((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ WORD ForceHotKey =(WORD)SendDlgItemMessage(hDlg,IDC_HKFORCE,HKM_GETHOTKEY,0,0);
+ BYTE TTBFCheck =(BYTE)IsDlgButtonChecked(hDlg,IDC_CHECKTTB);
+ BYTE MainMenu = (BYTE)IsDlgButtonChecked(hDlg,IDC_MAINMENU);
+ BYTE CloseDelete = (BYTE)IsDlgButtonChecked(hDlg,IDC_CLOSEONDELETE);
+ BYTE ShowAsProto = (BYTE)IsDlgButtonChecked(hDlg,IDC_YAMNASPROTO);
+ UINT mod,vk;
+
+ DBWriteContactSettingByte(NULL,YAMN_DBMODULE,YAMN_SHOWASPROTO,ShowAsProto);
+ DBWriteContactSettingWord(NULL,YAMN_DBMODULE,YAMN_HKCHECKMAIL,ForceHotKey);
+ DBWriteContactSettingByte(NULL,YAMN_DBMODULE,YAMN_TTBFCHECK,TTBFCheck);
+ DBWriteContactSettingByte(NULL,YAMN_DBMODULE,YAMN_SHOWMAINMENU,MainMenu);
+ DBWriteContactSettingByte(NULL,YAMN_DBMODULE,YAMN_CLOSEDELETE,CloseDelete);
+ WordToModAndVk(ForceHotKey,&mod,&vk);
+ PostThreadMessage(HotKeyThreadID,WM_YAMN_CHANGEHOTKEY,(WPARAM)mod,(LPARAM)vk);
+
+ optDateTime = 0;
+ if (IsDlgButtonChecked(hDlg,IDC_LONGDATE))optDateTime |= SHOWDATELONG;
+ if (IsDlgButtonChecked(hDlg,IDC_SMARTDATE))optDateTime |= SHOWDATENOTODAY;
+ if (IsDlgButtonChecked(hDlg,IDC_NOSECONDS))optDateTime |= SHOWDATENOSECONDS;
+ DBWriteContactSettingByte(NULL,YAMN_DBMODULE,YAMN_DBTIMEOPTIONS,optDateTime);
+ }
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+INT_PTR CALLBACK DlgProcPluginOpt(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hDlg);
+ break;
+ case WM_COMMAND:
+ {
+ WORD wNotifyCode = HIWORD(wParam);
+ switch(LOWORD(wParam))
+ {
+ case IDC_COMBOPLUGINS:
+ if(wNotifyCode==CBN_SELCHANGE)
+ {
+ HWND hCombo=GetDlgItem(hDlg,IDC_COMBOPLUGINS);
+ PYAMN_PROTOPLUGINQUEUE PParser;
+ PYAMN_FILTERPLUGINQUEUE FParser;
+ int index,id;
+
+ if(CB_ERR==(index=SendMessage(hCombo,CB_GETCURSEL,0,0)))
+ break;
+ id=SendMessage(hCombo,CB_GETITEMDATA,(WPARAM)index,(LPARAM)0);
+ EnterCriticalSection(PluginRegCS);
+ for(PParser=FirstProtoPlugin;PParser!=NULL;PParser=PParser->Next)
+ if(id==(INT_PTR)PParser->Plugin)
+ {
+ SetDlgItemText(hDlg,IDC_STVER,PParser->Plugin->PluginInfo->Ver);
+ SetDlgItemText(hDlg,IDC_STDESC,PParser->Plugin->PluginInfo->Description == NULL ? "" : PParser->Plugin->PluginInfo->Description);
+ SetDlgItemText(hDlg,IDC_STCOPY,PParser->Plugin->PluginInfo->Copyright == NULL ? "" : PParser->Plugin->PluginInfo->Copyright);
+ SetDlgItemText(hDlg,IDC_STMAIL,PParser->Plugin->PluginInfo->Email == NULL ? "" : PParser->Plugin->PluginInfo->Email);
+ SetDlgItemText(hDlg,IDC_STWWW,PParser->Plugin->PluginInfo->WWW == NULL ? "" : PParser->Plugin->PluginInfo->WWW);
+ break;
+ }
+ for(FParser=FirstFilterPlugin;FParser!=NULL;FParser=FParser->Next)
+ if(id==(INT_PTR)FParser->Plugin)
+ {
+ SetDlgItemText(hDlg,IDC_STVER,FParser->Plugin->PluginInfo->Ver);
+ SetDlgItemText(hDlg,IDC_STDESC,FParser->Plugin->PluginInfo->Description == NULL ? "" : FParser->Plugin->PluginInfo->Description);
+ SetDlgItemText(hDlg,IDC_STCOPY,FParser->Plugin->PluginInfo->Copyright == NULL ? "" : FParser->Plugin->PluginInfo->Copyright);
+ SetDlgItemText(hDlg,IDC_STMAIL,FParser->Plugin->PluginInfo->Email == NULL ? "" : FParser->Plugin->PluginInfo->Email);
+ SetDlgItemText(hDlg,IDC_STWWW,FParser->Plugin->PluginInfo->WWW == NULL ? "" : FParser->Plugin->PluginInfo->WWW);
+ break;
+ }
+ LeaveCriticalSection(PluginRegCS);
+ }
+ break;
+ case IDC_STWWW:
+ {
+ char str[1024];
+
+ GetDlgItemText(hDlg,IDC_STWWW,str,sizeof(str));
+ CallService(MS_UTILS_OPENURL,1,(LPARAM)str);
+ break;
+ }
+
+ }
+ break;
+ }
+ case WM_SHOWWINDOW:
+ if(TRUE==(BOOL)wParam)
+ {
+ PYAMN_PROTOPLUGINQUEUE PParser;
+ PYAMN_FILTERPLUGINQUEUE FParser;
+ int index;
+
+ EnterCriticalSection(PluginRegCS);
+ for(PParser=FirstProtoPlugin;PParser!=NULL;PParser=PParser->Next)
+ {
+ index=SendDlgItemMessage(hDlg,IDC_COMBOPLUGINS,CB_ADDSTRING,0,(LPARAM)PParser->Plugin->PluginInfo->Name);
+ index=SendDlgItemMessage(hDlg,IDC_COMBOPLUGINS,CB_SETITEMDATA,(WPARAM)index,(LPARAM)PParser->Plugin);
+ }
+ for(FParser=FirstFilterPlugin;FParser!=NULL;FParser=FParser->Next)
+ {
+ index=SendDlgItemMessage(hDlg,IDC_COMBOPLUGINS,CB_ADDSTRING,0,(LPARAM)FParser->Plugin->PluginInfo->Name);
+ index=SendDlgItemMessage(hDlg,IDC_COMBOPLUGINS,CB_SETITEMDATA,(WPARAM)index,(LPARAM)FParser->Plugin);
+ }
+
+ LeaveCriticalSection(PluginRegCS);
+ SendDlgItemMessage(hDlg,IDC_COMBOPLUGINS,CB_SETCURSEL,(WPARAM)0,(LPARAM)0);
+ SendMessage(hDlg,WM_COMMAND,MAKELONG(IDC_COMBOPLUGINS,CBN_SELCHANGE),(LPARAM)NULL);
+ break;
+ }
+ else //delete all items in combobox
+ {
+ int cbn=SendDlgItemMessage(hDlg,IDC_COMBOPLUGINS,CB_GETCOUNT,(WPARAM)0,(LPARAM)0);
+
+ for(int i=0;i<cbn;i++)
+ SendDlgItemMessage(hDlg,IDC_COMBOPLUGINS,CB_DELETESTRING,(WPARAM)0,(LPARAM)0);
+ break;
+ }
+ case WM_NOTIFY:
+ break;
+ }
+
+ return FALSE;
+}
+
+
+int YAMNOptInitSvc(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp={0};
+
+ odp.cbSize=sizeof(odp);
+ odp.position=0x00000000;
+ odp.hInstance=YAMNVar.hInst;
+ odp.pszGroup=LPGEN("Plugins");
+ odp.pszTitle=LPGEN("YAMN");
+ odp.flags=ODPF_BOLDGROUPS;
+//insert YAMN options dialog
+ //odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPTIONS);
+ //odp.pfnDlgProc=(DLGPROC)DlgOptionsProc;
+ //CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ odp.pszTab = LPGEN("Accounts");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_POP3ACCOUNTOPT);
+ odp.pfnDlgProc = DlgProcPOP3AccOpt;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) &odp);
+
+ odp.pszTab = LPGEN("General");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_YAMNOPT);
+ odp.pfnDlgProc = DlgProcYAMNOpt;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) &odp);
+
+ odp.pszTab = LPGEN("Plugins");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_PLUGINOPT);
+ odp.pfnDlgProc = DlgProcPluginOpt;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) &odp);
+
+ if( ServiceExists(MS_POPUP_ADDPOPUPEX) )
+ {
+ odp.pszGroup=Translate("PopUps");
+ odp.pszTab=LPGEN("YAMN");
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_POP3ACCOUNTPOPUP);
+ odp.pfnDlgProc = DlgProcPOP3AccPopup;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM) &odp);
+ }
+ return 0;
+}
+
+
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+BOOL DlgEnableAccountStatus(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST0),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST1),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST2),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST3),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST4),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST5),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST6),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST7),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST8),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST9),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST9),(BOOL)wParam);
+ return TRUE;
+}
+BOOL DlgEnableAccountPopup(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKPOP),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITPOPS),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCOL),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPB),(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPT),(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_RADIOPOPN),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_RADIOPOP1),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKNPOP),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITNPOPS),(IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKNCOL),(IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPNB),(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPNT),(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFPOP),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITFPOPS),(IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFCOL),(IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPFB),(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPFT),(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKAPOP),(BOOL)wParam);
+ return TRUE;
+}
+
+BOOL DlgEnableAccount(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECK),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITSERVER),wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITNAME),wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITPORT),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITLOGIN),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITPASS),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITINTERVAL),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKSND),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKMSG),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKICO),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKAPP),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKKBN),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNAPP),(IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITAPP),(IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITAPPPARAM),(IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKNMSGP),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFSND),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFMSG),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFICO),(BOOL)wParam);
+ /*EnableWindow(GetDlgItem(hDlg,IDC_CHECKST0),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST1),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST2),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST3),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST4),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST5),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST6),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST7),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST8),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST9),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKST9),(BOOL)wParam);*/
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKSTART),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFORCE),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_COMBOCP),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_STTIMELEFT),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNRESET),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEFAULT),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNSTATUS),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKSSL),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKNOTLS),(IsDlgButtonChecked(hDlg,IDC_CHECKSSL)==BST_UNCHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_AUTOBODY),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCONTACT),(BOOL)wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCONTACTNICK),(IsDlgButtonChecked(hDlg,IDC_CHECKCONTACT)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCONTACTNOEVENT),(IsDlgButtonChecked(hDlg,IDC_CHECKCONTACT)==BST_CHECKED) && wParam);
+ return TRUE;
+}
+BOOL DlgShowAccountStatus(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ HPOP3ACCOUNT ActualAccount=(HPOP3ACCOUNT)lParam;
+
+ if((DWORD)wParam==M_SHOWACTUAL)
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read wait\n");
+ #endif
+ WaitToRead(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read enter\n");
+ #endif
+ CheckDlgButton(hDlg,IDC_CHECKST0,ActualAccount->StatusFlags & YAMN_ACC_ST0 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST1,ActualAccount->StatusFlags & YAMN_ACC_ST1 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST2,ActualAccount->StatusFlags & YAMN_ACC_ST2 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST3,ActualAccount->StatusFlags & YAMN_ACC_ST3 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST4,ActualAccount->StatusFlags & YAMN_ACC_ST4 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST5,ActualAccount->StatusFlags & YAMN_ACC_ST5 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST6,ActualAccount->StatusFlags & YAMN_ACC_ST6 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST7,ActualAccount->StatusFlags & YAMN_ACC_ST7 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST8,ActualAccount->StatusFlags & YAMN_ACC_ST8 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST9,ActualAccount->StatusFlags & YAMN_ACC_ST9 ? BST_CHECKED : BST_UNCHECKED);
+ ReadDone(ActualAccount);
+ }
+ else
+ {
+ CheckDlgButton(hDlg,IDC_CHECKST0,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST1,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST2,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST3,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST4,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST5,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST6,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST7,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST8,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST9,BST_CHECKED);
+ }
+ return TRUE;
+}
+BOOL DlgShowAccountPopup(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ HPOP3ACCOUNT ActualAccount=(HPOP3ACCOUNT)lParam;
+
+ if((DWORD)wParam==M_SHOWACTUAL)
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read wait\n");
+ #endif
+ WaitToRead(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read enter\n");
+ #endif
+ SetDlgItemInt(hDlg,IDC_EDITPOPS,ActualAccount->NewMailN.PopUpTime,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITNPOPS,ActualAccount->NoNewMailN.PopUpTime,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITFPOPS,ActualAccount->BadConnectN.PopUpTime,FALSE);
+
+
+ CheckDlgButton(hDlg,IDC_CHECKPOP,ActualAccount->NewMailN.Flags & YAMN_ACC_POP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCOL,ActualAccount->NewMailN.Flags & YAMN_ACC_POPC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNPOP,ActualAccount->NoNewMailN.Flags & YAMN_ACC_POP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNCOL,ActualAccount->NoNewMailN.Flags & YAMN_ACC_POPC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFPOP,ActualAccount->BadConnectN.Flags & YAMN_ACC_POP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFCOL,ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOPN,ActualAccount->Flags & YAMN_ACC_POPN ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOP1,ActualAccount->Flags & YAMN_ACC_POPN ? BST_UNCHECKED : BST_CHECKED);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read done\n");
+ #endif
+ ReadDone(ActualAccount);
+ }
+ else //default
+ {
+
+ SetDlgItemInt(hDlg,IDC_EDITPOPS,0,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITNPOPS,0,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITFPOPS,0,FALSE);
+ CheckDlgButton(hDlg,IDC_CHECKPOP,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCOL,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNPOP,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNCOL,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFPOP,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFCOL,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOPN,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOP1,BST_CHECKED);
+ }
+ return TRUE;
+}
+BOOL DlgShowAccount(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ HPOP3ACCOUNT ActualAccount=(HPOP3ACCOUNT)lParam;
+ int i;
+
+ if((DWORD)wParam==M_SHOWACTUAL)
+ {
+ TCHAR accstatus[256];
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read wait\n");
+ #endif
+ WaitToRead(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read enter\n");
+ #endif
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITSERVER,(LPARAM)ActualAccount->Server->Name);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITNAME,(LPARAM)ActualAccount->Name);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITLOGIN,(LPARAM)ActualAccount->Server->Login);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITPASS,(LPARAM)ActualAccount->Server->Passwd);
+ DlgSetItemTextW(hDlg,(WPARAM)IDC_EDITAPP,(LPARAM)ActualAccount->NewMailN.App);
+ DlgSetItemTextW(hDlg,(WPARAM)IDC_EDITAPPPARAM,(LPARAM)ActualAccount->NewMailN.AppParam);
+ SetDlgItemInt(hDlg,IDC_EDITPORT,ActualAccount->Server->Port,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITINTERVAL,ActualAccount->Interval/60,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITPOPS,ActualAccount->NewMailN.PopUpTime,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITNPOPS,ActualAccount->NoNewMailN.PopUpTime,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITFPOPS,ActualAccount->BadConnectN.PopUpTime,FALSE);
+ for(i=0;i<=CPLENSUPP;i++)
+ if((i<CPLENSUPP) && (CodePageNamesSupp[i].CP==ActualAccount->CP))
+ {
+ SendMessage(GetDlgItem(hDlg,IDC_COMBOCP),CB_SETCURSEL,(WPARAM)i,(LPARAM)0);
+ break;
+ }
+ if(i==CPLENSUPP)
+ SendMessage(GetDlgItem(hDlg,IDC_COMBOCP),CB_SETCURSEL,(WPARAM)CPDEFINDEX,(LPARAM)0);
+
+ CheckDlgButton(hDlg,IDC_CHECK,ActualAccount->Flags & YAMN_ACC_ENA ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKSND,ActualAccount->NewMailN.Flags & YAMN_ACC_SND ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKMSG,ActualAccount->NewMailN.Flags & YAMN_ACC_MSG ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKICO,ActualAccount->NewMailN.Flags & YAMN_ACC_ICO ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKPOP,ActualAccount->NewMailN.Flags & YAMN_ACC_POP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCOL,ActualAccount->NewMailN.Flags & YAMN_ACC_POPC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKAPP,ActualAccount->NewMailN.Flags & YAMN_ACC_APP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKKBN,ActualAccount->NewMailN.Flags & YAMN_ACC_KBN ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNPOP,ActualAccount->NoNewMailN.Flags & YAMN_ACC_POP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNCOL,ActualAccount->NoNewMailN.Flags & YAMN_ACC_POPC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNMSGP,ActualAccount->NoNewMailN.Flags & YAMN_ACC_MSGP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFSND,ActualAccount->BadConnectN.Flags & YAMN_ACC_SND ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFMSG,ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFICO,ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFPOP,ActualAccount->BadConnectN.Flags & YAMN_ACC_POP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFCOL,ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOPN,ActualAccount->Flags & YAMN_ACC_POPN ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOP1,ActualAccount->Flags & YAMN_ACC_POPN ? BST_UNCHECKED : BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKSSL,ActualAccount->Flags & YAMN_ACC_SSL23 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNOTLS,ActualAccount->Flags & YAMN_ACC_NOTLS ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKAPOP,ActualAccount->Flags & YAMN_ACC_APOP ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_AUTOBODY,ActualAccount->Flags & YAMN_ACC_BODY ? BST_CHECKED : BST_UNCHECKED);
+ /*CheckDlgButton(hDlg,IDC_CHECKST0,ActualAccount->StatusFlags & YAMN_ACC_ST0 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST1,ActualAccount->StatusFlags & YAMN_ACC_ST1 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST2,ActualAccount->StatusFlags & YAMN_ACC_ST2 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST3,ActualAccount->StatusFlags & YAMN_ACC_ST3 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST4,ActualAccount->StatusFlags & YAMN_ACC_ST4 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST5,ActualAccount->StatusFlags & YAMN_ACC_ST5 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST6,ActualAccount->StatusFlags & YAMN_ACC_ST6 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST7,ActualAccount->StatusFlags & YAMN_ACC_ST7 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST8,ActualAccount->StatusFlags & YAMN_ACC_ST8 ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST9,ActualAccount->StatusFlags & YAMN_ACC_ST9 ? BST_CHECKED : BST_UNCHECKED);*/
+ Check0=ActualAccount->StatusFlags & YAMN_ACC_ST0;
+ Check1=ActualAccount->StatusFlags & YAMN_ACC_ST1;
+ Check2=ActualAccount->StatusFlags & YAMN_ACC_ST2;
+ Check3=ActualAccount->StatusFlags & YAMN_ACC_ST3;
+ Check4=ActualAccount->StatusFlags & YAMN_ACC_ST4;
+ Check5=ActualAccount->StatusFlags & YAMN_ACC_ST5;
+ Check6=ActualAccount->StatusFlags & YAMN_ACC_ST6;
+ Check7=ActualAccount->StatusFlags & YAMN_ACC_ST7;
+ Check8=ActualAccount->StatusFlags & YAMN_ACC_ST8;
+ Check9=ActualAccount->StatusFlags & YAMN_ACC_ST9;
+ CheckDlgButton(hDlg,IDC_CHECKSTART,ActualAccount->StatusFlags & YAMN_ACC_STARTS ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFORCE,ActualAccount->StatusFlags & YAMN_ACC_FORCE ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCONTACT,ActualAccount->NewMailN.Flags & YAMN_ACC_CONT ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCONTACTNICK,ActualAccount->NewMailN.Flags & YAMN_ACC_CONTNICK ? BST_CHECKED : BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCONTACTNOEVENT,ActualAccount->NewMailN.Flags & YAMN_ACC_CONTNOEVENT ? BST_CHECKED : BST_UNCHECKED);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNT:ActualAccountSO-read done\n");
+#endif
+ GetAccountStatus(ActualAccount,accstatus);
+ SetDlgItemText(hDlg,IDC_STSTATUS,accstatus);
+ ReadDone(ActualAccount);
+ }
+ else //default
+ {
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITSERVER,(LPARAM)NULL);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITNAME,(LPARAM)NULL);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITLOGIN,(LPARAM)NULL);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITPASS,(LPARAM)NULL);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITAPP,(LPARAM)NULL);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITAPPPARAM,(LPARAM)NULL);
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+ SetDlgItemInt(hDlg,IDC_EDITPORT,110,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITINTERVAL,10,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITPOPS,0,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITNPOPS,0,FALSE);
+ SetDlgItemInt(hDlg,IDC_EDITFPOPS,0,FALSE);
+ SendMessage(GetDlgItem(hDlg,IDC_COMBOCP),CB_SETCURSEL,(WPARAM)CPDEFINDEX,(LPARAM)0);
+ CheckDlgButton(hDlg,IDC_CHECK,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKSND,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKMSG,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKICO,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKPOP,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCOL,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKAPP,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKPOP,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKCOL,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFSND,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFMSG,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFICO,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFPOP,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFCOL,BST_CHECKED);
+ /*CheckDlgButton(hDlg,IDC_CHECKST0,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST1,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST2,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST3,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST4,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST5,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST6,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST7,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST8,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKST9,BST_CHECKED);*/
+ CheckDlgButton(hDlg,IDC_CHECKSTART,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKFORCE,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOPN,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_RADIOPOP1,BST_CHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKSSL,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKNOTLS,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_CHECKAPOP,BST_UNCHECKED);
+ CheckDlgButton(hDlg,IDC_AUTOBODY,BST_UNCHECKED);
+
+ SetDlgItemText(hDlg,IDC_STSTATUS,TranslateT("No account selected"));
+ }
+ return TRUE;
+}
+
+BOOL DlgShowAccountColors(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ HPOP3ACCOUNT ActualAccount=(HPOP3ACCOUNT)lParam;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNTCOLORS:ActualAccountSO-read wait\n");
+#endif
+ WaitToRead(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNTCOLORS:ActualAccountSO-read enter\n");
+#endif
+ if(ActualAccount->NewMailN.Flags & YAMN_ACC_POPC)
+ {
+ SendDlgItemMessage(hDlg,IDC_CPB,CPM_SETCOLOUR,0,(LPARAM)ActualAccount->NewMailN.PopUpB);
+ SendDlgItemMessage(hDlg,IDC_CPT,CPM_SETCOLOUR,0,(LPARAM)ActualAccount->NewMailN.PopUpT);
+ }
+ else
+ {
+ SendDlgItemMessage(hDlg,IDC_CPB,CPM_SETCOLOUR,0,(LPARAM)GetSysColor(COLOR_BTNFACE));
+ SendDlgItemMessage(hDlg,IDC_CPT,CPM_SETCOLOUR,0,(LPARAM)GetSysColor(COLOR_WINDOWTEXT));
+ }
+ if(ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC)
+ {
+ SendDlgItemMessage(hDlg,IDC_CPFB,CPM_SETCOLOUR,0,(LPARAM)ActualAccount->BadConnectN.PopUpB);
+ SendDlgItemMessage(hDlg,IDC_CPFT,CPM_SETCOLOUR,0,(LPARAM)ActualAccount->BadConnectN.PopUpT);
+ }
+ else
+ {
+ SendDlgItemMessage(hDlg,IDC_CPFB,CPM_SETCOLOUR,0,(LPARAM)GetSysColor(COLOR_BTNFACE));
+ SendDlgItemMessage(hDlg,IDC_CPFT,CPM_SETCOLOUR,0,(LPARAM)GetSysColor(COLOR_WINDOWTEXT));
+ }
+ if(ActualAccount->NoNewMailN.Flags & YAMN_ACC_POPC)
+ {
+ SendDlgItemMessage(hDlg,IDC_CPNB,CPM_SETCOLOUR,0,(LPARAM)ActualAccount->NoNewMailN.PopUpB);
+ SendDlgItemMessage(hDlg,IDC_CPNT,CPM_SETCOLOUR,0,(LPARAM)ActualAccount->NoNewMailN.PopUpT);
+ }
+ else
+ {
+ SendDlgItemMessage(hDlg,IDC_CPNB,CPM_SETCOLOUR,0,(LPARAM)GetSysColor(COLOR_BTNFACE));
+ SendDlgItemMessage(hDlg,IDC_CPNT,CPM_SETCOLOUR,0,(LPARAM)GetSysColor(COLOR_WINDOWTEXT));
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:SHOWACCOUNTCOLORS:ActualAccountSO-read done\n");
+#endif
+ ReadDone(ActualAccount); //we do not need to check if account is deleted. It is not deleted, because only thread that can delete account is this thread
+ return TRUE;
+}
+
+BOOL DlgSetItemText(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ if((TCHAR*)lParam==NULL)
+ SetDlgItemText(hDlg,(UINT)wParam,_T(""));
+ else
+ SetDlgItemText(hDlg,(UINT)wParam,(TCHAR *)lParam);
+ return TRUE;
+}
+
+BOOL DlgSetItemTextW(HWND hDlg,WPARAM wParam,LPARAM lParam)
+{
+ if((WCHAR*)lParam==NULL)
+ SetDlgItemTextW(hDlg,(UINT)wParam,(LPWSTR)L"");
+ else
+ SetDlgItemTextW(hDlg,(UINT)wParam,(LPWSTR)lParam);
+ return TRUE;
+}
+
+BOOL CALLBACK DlgProcPOP3AccStatusOpt(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ static HPOP3ACCOUNT ActualAccount;
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)DlgInput);
+ if(ActualAccount != NULL)
+ {
+ DlgShowAccountStatus(hDlg,(WPARAM)M_SHOWACTUAL,(LPARAM)ActualAccount);
+ DlgEnableAccountStatus(hDlg,(WPARAM)TRUE,(LPARAM)TRUE);
+ }
+ TranslateDialogDefault(hDlg);
+ SendMessage(GetParent(hDlg),PSM_UNCHANGED,(WPARAM)hDlg,0);
+ return TRUE;
+ break;
+ }
+ case WM_COMMAND:
+ {
+
+ WORD wNotifyCode = HIWORD(wParam);
+ switch(LOWORD(wParam))
+ {
+ case IDOK:
+ Check0=(IsDlgButtonChecked(hDlg,IDC_CHECKST0)==BST_CHECKED);
+ Check1=(IsDlgButtonChecked(hDlg,IDC_CHECKST1)==BST_CHECKED);
+ Check2=(IsDlgButtonChecked(hDlg,IDC_CHECKST2)==BST_CHECKED);
+ Check3=(IsDlgButtonChecked(hDlg,IDC_CHECKST3)==BST_CHECKED);
+ Check4=(IsDlgButtonChecked(hDlg,IDC_CHECKST4)==BST_CHECKED);
+ Check5=(IsDlgButtonChecked(hDlg,IDC_CHECKST5)==BST_CHECKED);
+ Check6=(IsDlgButtonChecked(hDlg,IDC_CHECKST6)==BST_CHECKED);
+ Check7=(IsDlgButtonChecked(hDlg,IDC_CHECKST7)==BST_CHECKED);
+ Check8=(IsDlgButtonChecked(hDlg,IDC_CHECKST8)==BST_CHECKED);
+ Check9=(IsDlgButtonChecked(hDlg,IDC_CHECKST9)==BST_CHECKED);
+ WindowList_BroadcastAsync(YAMNVar.MessageWnds,WM_YAMN_CHANGESTATUSOPTION,(WPARAM)0,(LPARAM)0);
+ EndDialog(hDlg,0);
+ DestroyWindow(hDlg);
+ break;
+
+ case IDCANCEL:
+ EndDialog(hDlg,0);
+ DestroyWindow(hDlg);
+ break;
+
+ default:
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+
+INT_PTR CALLBACK DlgProcPOP3AccOpt(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ BOOL Changed=FALSE;
+ static BOOL InList=FALSE;
+ static HPOP3ACCOUNT ActualAccount;
+ static UCHAR ActualStatus;
+// static struct CPOP3Options POP3Options;
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ int i;
+
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),FALSE);
+
+ DlgEnableAccount(hDlg,(WPARAM)FALSE,(LPARAM)FALSE);
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWDEFAULT,0);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:INITDIALOG:AccountBrowserSO-read wait\n");
+ #endif
+ WaitToReadSO(POP3Plugin->AccountBrowserSO);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:INITDIALOG:AccountBrowserSO-read enter\n");
+ #endif
+ //SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_ADDSTRING,0,(LPARAM)""); //this was in YAMN.rc initialisation but seems to be useless
+ if(POP3Plugin->FirstAccount!=NULL)
+ for(ActualAccount=(HPOP3ACCOUNT)POP3Plugin->FirstAccount;ActualAccount!=NULL;ActualAccount=(HPOP3ACCOUNT)ActualAccount->Next)
+ if(ActualAccount->Name!=NULL)
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_ADDSTRING,0,(LPARAM)ActualAccount->Name);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:INITDIALOG:AccountBrowserSO-read done\n");
+ #endif
+ ReadDoneSO(POP3Plugin->AccountBrowserSO);
+ SendDlgItemMessage(hDlg,IDC_COMBOCP,CB_ADDSTRING,0,(LPARAM)TranslateT("Default"));
+ for(i=1;i<CPLENSUPP;i++){
+ CPINFOEX info; GetCPInfoEx(CodePageNamesSupp[i].CP,0,&info);
+ size_t len = strlen(info.CodePageName+7);
+ info.CodePageName[len+6]=0;
+ SendDlgItemMessage(hDlg,IDC_COMBOCP,CB_ADDSTRING,0,(LPARAM)info.CodePageName+7);
+ }
+
+ SendMessage(GetDlgItem(hDlg,IDC_COMBOCP),CB_SETCURSEL,(WPARAM)CPDEFINDEX,(LPARAM)0);
+ ActualAccount=NULL;
+ TranslateDialogDefault(hDlg);
+ SendMessage(GetParent(hDlg),PSM_UNCHANGED,(WPARAM)hDlg,0);
+ return TRUE;
+ }
+
+ case WM_SHOWWINDOW:
+ if((BOOL)wParam==FALSE)
+ {
+ WindowList_Remove(pYAMNVar->MessageWnds,hDlg);
+ SendMessage(GetParent(hDlg),PSM_UNCHANGED,(WPARAM)hDlg,(LPARAM)0);
+ }
+ else
+ WindowList_Add(pYAMNVar->MessageWnds,hDlg,NULL);
+ return TRUE;
+ case WM_YAMN_CHANGESTATUS:
+ {
+ char accstatus[256];
+
+ if((HPOP3ACCOUNT)wParam!=ActualAccount)
+ break;
+ GetAccountStatus(ActualAccount,accstatus);
+ SetDlgItemTextA(hDlg,IDC_STSTATUS,accstatus);
+ return TRUE;
+ }
+
+ case WM_YAMN_CHANGESTATUSOPTION:
+ {
+ Changed=TRUE;
+ SendMessage(GetParent(hDlg),PSM_CHANGED,0,0);
+ return TRUE;
+ }
+
+ case WM_YAMN_CHANGETIME:
+ if((HPOP3ACCOUNT)wParam==ActualAccount)
+ {
+ TCHAR Text[256];
+ _stprintf(Text,Translate("Time left to next check [s]: %d"),(DWORD)lParam);
+ SetDlgItemText(hDlg,IDC_STTIMELEFT,Text);
+ }
+ return TRUE;
+ case WM_COMMAND:
+ {
+ WORD wNotifyCode = HIWORD(wParam);
+ switch(LOWORD(wParam))
+ {
+ LONG Result;
+ case IDC_COMBOACCOUNT:
+ switch(wNotifyCode)
+ {
+ case CBN_EDITCHANGE :
+ ActualAccount=NULL;
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+
+ if(GetDlgItemText(hDlg,IDC_COMBOACCOUNT,DlgInput,sizeof(DlgInput)/sizeof(TCHAR)))
+ DlgEnableAccount(hDlg,(WPARAM)TRUE,(LPARAM)FALSE);
+ else
+ DlgEnableAccount(hDlg,(WPARAM)FALSE,(LPARAM)FALSE);
+ break;
+ case CBN_KILLFOCUS:
+ GetDlgItemText(hDlg,IDC_COMBOACCOUNT,DlgInput,sizeof(DlgInput)/sizeof(TCHAR));
+ if(NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)DlgInput)))
+ {
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),FALSE);
+ if(lstrlen(DlgInput))
+ DlgEnableAccount(hDlg,(WPARAM)TRUE,(LPARAM)TRUE);
+ else
+ DlgEnableAccount(hDlg,(WPARAM)FALSE,(LPARAM)FALSE);
+ }
+ else
+ {
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWACTUAL,(LPARAM)ActualAccount);
+ DlgEnableAccount(hDlg,(WPARAM)TRUE,(LPARAM)TRUE);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),TRUE);
+ }
+ break;
+ case CBN_SELCHANGE:
+ if(CB_ERR!=(Result=SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_GETCURSEL,0,0)))
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_GETLBTEXT,(WPARAM)Result,(LPARAM)DlgInput);
+
+ if((Result==CB_ERR) || (NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)DlgInput))))
+ {
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),FALSE);
+ }
+ else
+ {
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWACTUAL,(LPARAM)ActualAccount);
+ DlgEnableAccount(hDlg,(WPARAM)TRUE,(LPARAM)FALSE);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),TRUE);
+ }
+ break;
+ }
+ break;
+ case IDC_COMBOCP:
+ {
+ int sel = SendDlgItemMessage(hDlg,IDC_COMBOCP,CB_GETCURSEL,0,0);
+ CPINFOEX info; GetCPInfoEx(CodePageNamesSupp[sel].CP,0,&info);
+ DlgSetItemText(hDlg,(WPARAM)IDC_STSTATUS,(LPARAM)info.CodePageName);
+ }
+ case IDC_CHECK:
+ case IDC_CHECKSND:
+ case IDC_CHECKMSG:
+ case IDC_CHECKICO:
+ case IDC_CHECKFSND:
+ case IDC_CHECKFMSG:
+ case IDC_CHECKFICO:
+ case IDC_CHECKST0:
+ case IDC_CHECKST1:
+ case IDC_CHECKST2:
+ case IDC_CHECKST3:
+ case IDC_CHECKST4:
+ case IDC_CHECKST5:
+ case IDC_CHECKST6:
+ case IDC_CHECKST7:
+ case IDC_CHECKST8:
+ case IDC_CHECKST9:
+ case IDC_CHECKSTART:
+ case IDC_CHECKFORCE:
+ case IDC_EDITAPPPARAM:
+ case IDC_CHECKAPOP:
+ case IDC_AUTOBODY:
+ case IDC_CHECKCONTACTNICK:
+ case IDC_CHECKCONTACTNOEVENT:
+ case IDC_CHECKNOTLS:
+ Changed=TRUE;
+ break;
+ case IDC_CHECKCONTACT:
+ Changed=IsDlgButtonChecked(hDlg,IDC_CHECKCONTACT)==BST_CHECKED;
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCONTACTNICK),Changed);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCONTACTNOEVENT),Changed);
+ Changed=TRUE;
+ break;
+ case IDC_CHECKSSL:
+ {
+ BOOL SSLC=(IsDlgButtonChecked(hDlg,IDC_CHECKSSL)==BST_CHECKED);
+ SetDlgItemInt(hDlg,IDC_EDITPORT,SSLC ? 995 : 110,FALSE);
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKNOTLS),SSLC?0:1);
+ }
+ Changed=TRUE;
+ break;
+ case IDC_CPB:
+ case IDC_CPT:
+ case IDC_CPFB:
+ case IDC_CPFT:
+ case IDC_CPNB:
+ case IDC_CPNT:
+ if(HIWORD(wParam)!=CPN_COLOURCHANGED)
+ break;
+ case IDC_CHECKKBN:
+ Changed=TRUE;
+ break;
+ case IDC_CHECKAPP:
+ Changed=TRUE;
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNAPP),IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITAPP),IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITAPPPARAM),IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED);
+ break;
+ case IDC_BTNSTATUS:
+ {
+ DialogBoxParamW(pYAMNVar->hInst,MAKEINTRESOURCEW(IDD_CHOOSESTATUSMODES),hDlg,(DLGPROC)DlgProcPOP3AccStatusOpt,(LPARAM)NULL);
+ break;
+ }
+
+ case IDC_BTNADD:
+ {
+ int index=0;
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWDEFAULT,0);
+ DlgEnableAccount(hDlg,(WPARAM)TRUE,(LPARAM)TRUE);
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),FALSE);
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITNAME,(LPARAM)TranslateT("New Account"));
+ index=SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_ADDSTRING,0,(LPARAM)TranslateT("New Account"));
+
+ if((index==CB_ERR) || (index==CB_ERRSPACE))
+ break;
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_SETCURSEL,(WPARAM)index,(LPARAM)TranslateT("New Account"));
+ break;
+ }
+
+ case IDC_BTNAPP:
+ {
+ OPENFILENAME OFNStruct;
+
+ memset(&OFNStruct,0,sizeof(OPENFILENAME));
+ OFNStruct.lStructSize=sizeof(OPENFILENAME);
+ OFNStruct.hwndOwner=hDlg;
+ OFNStruct.lpstrFilter=_T("Executables (*.exe;*.bat;*.cmd;*.com)\0*.exe;*.bat;*.cmd;*.com\0All Files (*.*)\0*.*\0");
+ OFNStruct.nFilterIndex=1;
+ OFNStruct.nMaxFile=MAX_PATH;
+ OFNStruct.lpstrFile=new TCHAR[MAX_PATH];
+ OFNStruct.lpstrFile[0]=(TCHAR)0;
+ OFNStruct.lpstrTitle=Translate("Select executable used for notification");
+ OFNStruct.Flags=OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;
+ if(!GetOpenFileName(&OFNStruct))
+ {
+ if(CommDlgExtendedError())
+ MessageBox(hDlg,_T("Dialog box error"),_T("Failed"),MB_OK);
+ }
+ else
+ DlgSetItemText(hDlg,(WPARAM)IDC_EDITAPP,(LPARAM)OFNStruct.lpstrFile);
+ delete[] OFNStruct.lpstrFile;
+ break;
+ }
+ case IDC_BTNDEFAULT:
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWDEFAULT,0);
+// DlgShowAccountColors(hDlg,0,(LPARAM)ActualAccount);
+ break;
+ case IDC_BTNDEL:
+ GetDlgItemText(hDlg,IDC_COMBOACCOUNT,DlgInput,sizeof(DlgInput)/sizeof(TCHAR));
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),FALSE);
+ if((CB_ERR==(Result=SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_GETCURSEL,0,0)))
+ || (NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)DlgInput))))
+ return TRUE;
+
+ if(IDOK!=MessageBox(hDlg,Translate("Do you really want to delete this account?"),Translate("Delete account confirmation"),MB_OKCANCEL | MB_ICONWARNING))
+ return TRUE;
+
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)Translate("Please wait while no account is in use."));
+
+ if(ActualAccount->hContact != NULL)
+ CallService(MS_DB_CONTACT_DELETE,(WPARAM)(HANDLE) ActualAccount->hContact, 0);
+
+ CallService(MS_YAMN_DELETEACCOUNT,(WPARAM)POP3Plugin,(LPARAM)ActualAccount);
+
+ //We can consider our account as deleted.
+
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_DELETESTRING,(WPARAM)Result,0);
+ DlgSetItemText(hDlg,(WPARAM)IDC_COMBOACCOUNT,(LPARAM)NULL);
+ DlgEnableAccount(hDlg,(WPARAM)FALSE,0);
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWDEFAULT,0);
+// Beep(100,50);
+ break;
+ case IDC_BTNRESET:
+ if(ActualAccount!=NULL)
+ ActualAccount->TimeLeft=ActualAccount->Interval;
+ return 1;
+ }
+ if(HIWORD(wParam)==EN_CHANGE)
+ Changed=TRUE;
+ break;
+ }
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ switch(((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ TCHAR Text[MAX_PATH];
+ WCHAR TextW[MAX_PATH];
+ BOOL Translated,NewAcc=FALSE,Check,CheckMsg,CheckSnd,CheckIco,CheckApp, CheckAPOP;
+ BOOL CheckNMsgP,CheckFMsg,CheckFSnd,CheckFIco;
+ BOOL CheckKBN, CheckContact,CheckContactNick,CheckContactNoEvent;
+ BOOL CheckSSL, CheckABody, CheckNoTLS;
+ //BOOL Check0,Check1,Check2,Check3,Check4,Check5,Check6,Check7,Check8,Check9,
+ BOOL CheckStart,CheckForce;
+ size_t Length,index;
+ UINT Port,Interval;
+
+ if(GetDlgItemText(hDlg,IDC_COMBOACCOUNT,Text,sizeof(Text)/sizeof(TCHAR)))
+ {
+ Check=(IsDlgButtonChecked(hDlg,IDC_CHECK)==BST_CHECKED);
+ CheckSSL=(IsDlgButtonChecked(hDlg,IDC_CHECKSSL)==BST_CHECKED);
+ CheckNoTLS=(IsDlgButtonChecked(hDlg,IDC_CHECKNOTLS)==BST_CHECKED);
+ CheckAPOP=(IsDlgButtonChecked(hDlg,IDC_CHECKAPOP)==BST_CHECKED);
+
+ CheckABody=(IsDlgButtonChecked(hDlg,IDC_AUTOBODY)==BST_CHECKED);
+ CheckMsg=(IsDlgButtonChecked(hDlg,IDC_CHECKMSG)==BST_CHECKED);
+ CheckSnd=(IsDlgButtonChecked(hDlg,IDC_CHECKSND)==BST_CHECKED);
+ CheckIco=(IsDlgButtonChecked(hDlg,IDC_CHECKICO)==BST_CHECKED);
+
+ CheckApp=(IsDlgButtonChecked(hDlg,IDC_CHECKAPP)==BST_CHECKED);
+ CheckKBN=(IsDlgButtonChecked(hDlg,IDC_CHECKKBN)==BST_CHECKED);
+ CheckContact=(IsDlgButtonChecked(hDlg,IDC_CHECKCONTACT)==BST_CHECKED);
+ CheckContactNick=(IsDlgButtonChecked(hDlg,IDC_CHECKCONTACTNICK)==BST_CHECKED);
+ CheckContactNoEvent=(IsDlgButtonChecked(hDlg,IDC_CHECKCONTACTNOEVENT)==BST_CHECKED);
+
+ CheckFSnd=(IsDlgButtonChecked(hDlg,IDC_CHECKFSND)==BST_CHECKED);
+ CheckFMsg=(IsDlgButtonChecked(hDlg,IDC_CHECKFMSG)==BST_CHECKED);
+ CheckFIco=(IsDlgButtonChecked(hDlg,IDC_CHECKFICO)==BST_CHECKED);
+
+ CheckNMsgP=(IsDlgButtonChecked(hDlg,IDC_CHECKNMSGP)==BST_CHECKED);
+
+ Port=GetDlgItemInt(hDlg,IDC_EDITPORT,&Translated,FALSE);
+ if(!Translated)
+ {
+ MessageBox(hDlg,Translate("This is not a valid number value"),Translate("Input error"),MB_OK);
+ SetFocus(GetDlgItem(hDlg,IDC_EDITPORT));
+ break;
+ }
+ Interval=GetDlgItemInt(hDlg,IDC_EDITINTERVAL,&Translated,FALSE);
+ if(!Translated)
+ {
+ MessageBox(hDlg,Translate("This is not a valid number value"),Translate("Input error"),MB_OK);
+ SetFocus(GetDlgItem(hDlg,IDC_EDITINTERVAL));
+ break;
+ }
+
+ GetDlgItemText(hDlg,IDC_EDITAPP,Text,sizeof(Text)/sizeof(TCHAR));
+ if(CheckApp && !(Length=_tcslen(Text)))
+ {
+ MessageBox(hDlg,TranslateT("Please select application to run"),TranslateT("Input error"),MB_OK);
+ break;
+ }
+
+ GetDlgItemText(hDlg,IDC_COMBOACCOUNT,Text,sizeof(Text)/sizeof(TCHAR));
+ if(!(Length=_tcslen(Text)))
+ GetDlgItemText(hDlg,IDC_EDITNAME,Text,sizeof(Text)/sizeof(TCHAR));
+ if(!(Length=_tcslen(Text)))
+ break;
+
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)TranslateT("Please wait while no account is in use."));
+
+ if(NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)Text)))
+ {
+ NewAcc=TRUE;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write wait\n");
+ #endif
+ WaitToWriteSO(POP3Plugin->AccountBrowserSO);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write enter\n");
+ #endif
+ if(NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_GETNEXTFREEACCOUNT,(WPARAM)POP3Plugin,(LPARAM)YAMN_ACCOUNTVERSION)))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write done\n");
+ #endif
+ WriteDoneSO(POP3Plugin->AccountBrowserSO);
+ MessageBox(hDlg,Translate("Cannot allocate memory space for new account"),Translate("Memory error"),MB_OK);
+ break;
+ }
+ }
+ else
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write wait\n");
+ #endif
+ //We have to get full access to AccountBrowser, so other iterating thrads cannot get new account until new account is right set
+ WaitToWriteSO(POP3Plugin->AccountBrowserSO);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write enter\n");
+ #endif
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:ActualAccountSO-write wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=WaitToWrite(ActualAccount))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:ActualAccountSO-write wait failed\n");
+ #endif
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:ActualBrowserSO-write done\n");
+ #endif
+ WriteDoneSO(POP3Plugin->AccountBrowserSO);
+
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:ActualAccountSO-write enter\n");
+ #endif
+
+// Beep(1000,100);Sleep(200);
+ GetDlgItemText(hDlg,IDC_EDITNAME,Text,sizeof(Text)/sizeof(TCHAR));
+ if(!(Length=_tcslen(Text)))
+ break;
+ if(NULL==ActualAccount->Name)
+ ActualAccount->Name=new TCHAR[Length+1];
+ _tcscpy(ActualAccount->Name,Text);
+
+
+
+// Beep(1000,100);Sleep(200);
+ GetDlgItemText(hDlg,IDC_EDITSERVER,Text,sizeof(Text)/sizeof(TCHAR));
+ if(NULL!=ActualAccount->Server->Name)
+ delete[] ActualAccount->Server->Name;
+ ActualAccount->Server->Name=new TCHAR[_tcslen(Text)+1];
+ _tcscpy(ActualAccount->Server->Name,Text);
+
+// Beep(1000,100);Sleep(200);
+ GetDlgItemText(hDlg,IDC_EDITLOGIN,Text,sizeof(Text)/sizeof(TCHAR));
+ if(NULL!=ActualAccount->Server->Login)
+ delete[] ActualAccount->Server->Login;
+ ActualAccount->Server->Login=new TCHAR[_tcslen(Text)+1];
+ _tcscpy(ActualAccount->Server->Login,Text);
+
+// Beep(1000,100);Sleep(200);
+ GetDlgItemText(hDlg,IDC_EDITPASS,Text,sizeof(Text)/sizeof(TCHAR));
+ if(NULL!=ActualAccount->Server->Passwd)
+ delete[] ActualAccount->Server->Passwd;
+ ActualAccount->Server->Passwd=new TCHAR[_tcslen(Text)+1];
+ _tcscpy(ActualAccount->Server->Passwd,Text);
+
+// Beep(1000,100);Sleep(200);
+ GetDlgItemTextW(hDlg,IDC_EDITAPP,TextW,sizeof(TextW)/sizeof(WCHAR));
+ if(NULL!=ActualAccount->NewMailN.App)
+ delete[] ActualAccount->NewMailN.App;
+ ActualAccount->NewMailN.App=new WCHAR[wcslen(TextW)+1];
+ wcscpy(ActualAccount->NewMailN.App,TextW);
+
+// Beep(1000,100);Sleep(200);
+ GetDlgItemTextW(hDlg,IDC_EDITAPPPARAM,TextW,sizeof(TextW)/sizeof(WCHAR));
+ if(NULL!=ActualAccount->NewMailN.AppParam)
+ delete[] ActualAccount->NewMailN.AppParam;
+ ActualAccount->NewMailN.AppParam=new WCHAR[wcslen(TextW)+1];
+ wcscpy(ActualAccount->NewMailN.AppParam,TextW);
+
+ ActualAccount->Server->Port=Port;
+ ActualAccount->Interval=Interval*60;
+
+// Beep(1000,100);Sleep(200);
+ if(CB_ERR==(index=SendDlgItemMessage(hDlg,IDC_COMBOCP,CB_GETCURSEL,0,0)))
+ index=CPDEFINDEX;
+ ActualAccount->CP=CodePageNamesSupp[index].CP;
+
+// Beep(1000,100);Sleep(200);
+ if(NewAcc)
+ ActualAccount->TimeLeft=Interval*60;
+
+ CheckStart=(IsDlgButtonChecked(hDlg,IDC_CHECKSTART)==BST_CHECKED);
+ CheckForce=(IsDlgButtonChecked(hDlg,IDC_CHECKFORCE)==BST_CHECKED);
+
+ ActualAccount->Flags=
+ (Check ? YAMN_ACC_ENA : 0) |
+ (CheckSSL ? YAMN_ACC_SSL23 : 0) |
+ (CheckNoTLS ? YAMN_ACC_NOTLS : 0) |
+ (CheckAPOP ? YAMN_ACC_APOP : 0) |
+ (CheckABody ? YAMN_ACC_BODY : 0) |
+ (ActualAccount->Flags & YAMN_ACC_POPN);
+
+ ActualAccount->StatusFlags=
+ (Check0 ? YAMN_ACC_ST0 : 0) |
+ (Check1 ? YAMN_ACC_ST1 : 0) |
+ (Check2 ? YAMN_ACC_ST2 : 0) |
+ (Check3 ? YAMN_ACC_ST3 : 0) |
+ (Check4 ? YAMN_ACC_ST4 : 0) |
+ (Check5 ? YAMN_ACC_ST5 : 0) |
+ (Check6 ? YAMN_ACC_ST6 : 0) |
+ (Check7 ? YAMN_ACC_ST7 : 0) |
+ (Check8 ? YAMN_ACC_ST8 : 0) |
+ (Check9 ? YAMN_ACC_ST9 : 0) |
+ (CheckStart ? YAMN_ACC_STARTS : 0) |
+ (CheckForce ? YAMN_ACC_FORCE : 0);
+
+ ActualAccount->NewMailN.Flags=
+ (CheckSnd ? YAMN_ACC_SND : 0) |
+ (CheckMsg ? YAMN_ACC_MSG : 0) |
+ (CheckIco ? YAMN_ACC_ICO : 0) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_POP) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_POPC) |
+ (CheckApp ? YAMN_ACC_APP : 0) |
+ (CheckKBN ? YAMN_ACC_KBN : 0) |
+ (CheckContact ? YAMN_ACC_CONT : 0) |
+ (CheckContactNick ? YAMN_ACC_CONTNICK : 0) |
+ (CheckContactNoEvent ? YAMN_ACC_CONTNOEVENT : 0) |
+ YAMN_ACC_MSGP; //this is default: when new mail arrives and window was displayed, leave it displayed.
+
+ ActualAccount->NoNewMailN.Flags=
+ (ActualAccount->NoNewMailN.Flags & YAMN_ACC_POP) |
+ (ActualAccount->NoNewMailN.Flags & YAMN_ACC_POPC) |
+ (CheckNMsgP ? YAMN_ACC_MSGP : 0);
+
+ ActualAccount->BadConnectN.Flags=
+ (CheckFSnd ? YAMN_ACC_SND : 0) |
+ (CheckFMsg ? YAMN_ACC_MSG : 0) |
+ (CheckFIco ? YAMN_ACC_ICO : 0) |
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_POP) |
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_POPC);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:ActualAccountSO-write done\n");
+ #endif
+ WriteDone(ActualAccount);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write done\n");
+ #endif
+ WriteDoneSO(POP3Plugin->AccountBrowserSO);
+
+ EnableWindow(GetDlgItem(hDlg,IDC_BTNDEL),TRUE);
+
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+
+
+ index = SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_GETCURSEL,(WPARAM)0,(LPARAM)0);
+
+
+ HPOP3ACCOUNT temp = ActualAccount;
+
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_RESETCONTENT,0,(LPARAM)0);
+ if(POP3Plugin->FirstAccount!=NULL)
+ for(ActualAccount=(HPOP3ACCOUNT)POP3Plugin->FirstAccount;ActualAccount!=NULL;ActualAccount=(HPOP3ACCOUNT)ActualAccount->Next)
+ if(ActualAccount->Name!=NULL)
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_ADDSTRING,0,(LPARAM)ActualAccount->Name);
+
+ ActualAccount = temp;
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_SETCURSEL,(WPARAM)index,(LPARAM)ActualAccount->Name);
+
+// if(0==WritePOP3Accounts())
+// Beep(500,100);
+ WritePOP3Accounts();
+ RefreshContact();
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ if(Changed)
+ SendMessage(GetParent(hDlg),PSM_CHANGED,0,0);
+ return FALSE;
+}
+
+INT_PTR CALLBACK DlgProcPOP3AccPopup(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ BOOL Changed=FALSE;
+ static BOOL InList=FALSE;
+ static HPOP3ACCOUNT ActualAccount;
+ static UCHAR ActualStatus;
+// static struct CPOP3Options POP3Options;
+
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ DlgEnableAccountPopup(hDlg,(WPARAM)FALSE,(LPARAM)FALSE);
+ DlgShowAccountPopup(hDlg,(WPARAM)M_SHOWDEFAULT,0);
+ //DlgShowAccountColors(hDlg,0,(LPARAM)ActualAccount);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:INITDIALOG:AccountBrowserSO-read wait\n");
+ #endif
+ WaitToReadSO(POP3Plugin->AccountBrowserSO);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:INITDIALOG:AccountBrowserSO-read enter\n");
+ #endif
+ if(POP3Plugin->FirstAccount!=NULL)
+ for(ActualAccount=(HPOP3ACCOUNT)POP3Plugin->FirstAccount;ActualAccount!=NULL;ActualAccount=(HPOP3ACCOUNT)ActualAccount->Next)
+ if(ActualAccount->Name!=NULL)
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_ADDSTRING,0,(LPARAM)ActualAccount->Name);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:INITDIALOG:AccountBrowserSO-read done\n");
+ #endif
+ ReadDoneSO(POP3Plugin->AccountBrowserSO);
+ ActualAccount=NULL;
+
+
+ TranslateDialogDefault(hDlg);
+ SendMessage(GetParent(hDlg),PSM_UNCHANGED,(WPARAM)hDlg,0);
+ return TRUE;
+ }
+
+ case WM_SHOWWINDOW:
+ if((BOOL)wParam==FALSE)
+ {
+ WindowList_Remove(pYAMNVar->MessageWnds,hDlg);
+ SendMessage(GetParent(hDlg),PSM_UNCHANGED,(WPARAM)hDlg,(LPARAM)0);
+ }
+ else
+ {
+ WindowList_Add(pYAMNVar->MessageWnds,hDlg,NULL);
+
+ int index = SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_GETCURSEL,(WPARAM)0,(LPARAM)0);
+ HPOP3ACCOUNT temp = ActualAccount;
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_RESETCONTENT,0,(LPARAM)0);
+
+ if(POP3Plugin->FirstAccount!=NULL)
+ for(ActualAccount=(HPOP3ACCOUNT)POP3Plugin->FirstAccount;ActualAccount!=NULL;ActualAccount=(HPOP3ACCOUNT)ActualAccount->Next)
+ if(ActualAccount->Name!=NULL)
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_ADDSTRING,0,(LPARAM)ActualAccount->Name);
+
+ ActualAccount = temp;
+
+ if(ActualAccount != NULL)
+ {
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_SETCURSEL,(WPARAM)index,(LPARAM)ActualAccount->Name);
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWACTUAL,(LPARAM)ActualAccount);
+ DlgShowAccountColors(hDlg,0,(LPARAM)ActualAccount);
+ DlgEnableAccountPopup(hDlg,(WPARAM)TRUE,(LPARAM)FALSE);
+ }
+ else
+ {
+ DlgShowAccountPopup(hDlg,(WPARAM)M_SHOWDEFAULT,0);
+ DlgEnableAccountPopup(hDlg,(WPARAM)FALSE,(LPARAM)FALSE);
+ }
+
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ {
+ WORD wNotifyCode = HIWORD(wParam);
+ switch(LOWORD(wParam))
+ {
+ LONG Result;
+ case IDC_COMBOACCOUNT:
+ switch(wNotifyCode)
+ {
+
+ case CBN_KILLFOCUS:
+ GetDlgItemText(hDlg,IDC_COMBOACCOUNT,DlgInput,sizeof(DlgInput)/sizeof(TCHAR));
+ if(NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)DlgInput)))
+ {
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+ if(lstrlen(DlgInput))
+ DlgEnableAccountPopup(hDlg,(WPARAM)TRUE,(LPARAM)TRUE);
+ else
+ DlgEnableAccountPopup(hDlg,(WPARAM)FALSE,(LPARAM)FALSE);
+ }
+ else
+ {
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWACTUAL,(LPARAM)ActualAccount);
+ DlgShowAccountColors(hDlg,0,(LPARAM)ActualAccount);
+ DlgEnableAccountPopup(hDlg,(WPARAM)TRUE,(LPARAM)TRUE);
+ }
+ break;
+ case CBN_SELCHANGE:
+ if(CB_ERR!=(Result=SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_GETCURSEL,0,0)))
+ SendDlgItemMessage(hDlg,IDC_COMBOACCOUNT,CB_GETLBTEXT,(WPARAM)Result,(LPARAM)DlgInput);
+ if((Result==CB_ERR) || (NULL==(ActualAccount=(HPOP3ACCOUNT)CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)DlgInput))))
+ {
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)NULL);
+ }
+ else
+ {
+ DlgShowAccount(hDlg,(WPARAM)M_SHOWACTUAL,(LPARAM)ActualAccount);
+ DlgShowAccountColors(hDlg,0,(LPARAM)ActualAccount);
+ DlgEnableAccountPopup(hDlg,(WPARAM)TRUE,(LPARAM)FALSE);
+ }
+ break;
+ }
+ break;
+ case IDC_COMBOCP:
+ {
+ int sel = SendDlgItemMessage(hDlg,IDC_COMBOCP,CB_GETCURSEL,0,0);
+ CPINFOEX info; GetCPInfoEx(CodePageNamesSupp[sel].CP,0,&info);
+ DlgSetItemText(hDlg,(WPARAM)IDC_STSTATUS,(LPARAM)info.CodePageName);
+ }
+ case IDC_RADIOPOPN:
+ case IDC_RADIOPOP1:
+ Changed=TRUE;
+ break;
+ case IDC_CPB:
+ case IDC_CPT:
+ case IDC_CPFB:
+ case IDC_CPFT:
+ case IDC_CPNB:
+ case IDC_CPNT:
+ if(HIWORD(wParam)!=CPN_COLOURCHANGED)
+ break;
+ case IDC_CHECKCOL:
+ case IDC_CHECKFCOL:
+ case IDC_CHECKNCOL:
+ EnableWindow(GetDlgItem(hDlg,IDC_CPB),(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPT),(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPNB),(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPNT),(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPFB),(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED) && wParam);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPFT),(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED) && (IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED) && wParam);
+ Changed=TRUE;
+ break;
+
+ case IDC_PREVIEW:
+ {
+ POPUPDATA Tester;
+ POPUPDATA TesterF;
+ POPUPDATA TesterN;
+ BOOL TesterC=(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED);
+ BOOL TesterFC=(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED);
+ BOOL TesterNC=(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED);
+
+ ZeroMemory(&Tester,sizeof(Tester));
+ ZeroMemory(&TesterF,sizeof(TesterF));
+ ZeroMemory(&TesterF,sizeof(TesterN));
+ Tester.lchContact=NULL;
+ TesterF.lchContact=NULL;
+ TesterN.lchContact=NULL;
+ Tester.lchIcon=hYamnIcons[2];
+ TesterF.lchIcon=hYamnIcons[3];
+ TesterN.lchIcon=hYamnIcons[1];
+
+ lstrcpy(Tester.lpzContactName,Translate("Account Test"));
+ lstrcpy(TesterF.lpzContactName,Translate("Account Test (failed)"));
+ lstrcpy(TesterN.lpzContactName,Translate("Account Test"));
+ lstrcpy(Tester.lpzText,Translate("You have N new mail messages"));
+ lstrcpy(TesterF.lpzText,Translate("Connection failed message"));
+ lstrcpy(TesterN.lpzText,Translate("No new mail message"));
+ if(TesterC)
+ {
+ Tester.colorBack=SendDlgItemMessage(hDlg,IDC_CPB,CPM_GETCOLOUR,0,0);
+ Tester.colorText=SendDlgItemMessage(hDlg,IDC_CPT,CPM_GETCOLOUR,0,0);
+ }
+ else
+ {
+ Tester.colorBack=GetSysColor(COLOR_BTNFACE);
+ Tester.colorText=GetSysColor(COLOR_WINDOWTEXT);
+ }
+ if(TesterFC)
+ {
+ TesterF.colorBack=SendDlgItemMessage(hDlg,IDC_CPFB,CPM_GETCOLOUR,0,0);
+ TesterF.colorText=SendDlgItemMessage(hDlg,IDC_CPFT,CPM_GETCOLOUR,0,0);
+ }
+ else
+ {
+ TesterF.colorBack=GetSysColor(COLOR_BTNFACE);
+ TesterF.colorText=GetSysColor(COLOR_WINDOWTEXT);
+ }
+ if(TesterNC)
+ {
+ TesterN.colorBack=SendDlgItemMessage(hDlg,IDC_CPNB,CPM_GETCOLOUR,0,0);
+ TesterN.colorText=SendDlgItemMessage(hDlg,IDC_CPNT,CPM_GETCOLOUR,0,0);
+ }
+ else
+ {
+ TesterN.colorBack=GetSysColor(COLOR_BTNFACE);
+ TesterN.colorText=GetSysColor(COLOR_WINDOWTEXT);
+ }
+ Tester.PluginWindowProc=(WNDPROC)NULL;
+ TesterF.PluginWindowProc=(WNDPROC)NULL;
+ TesterN.PluginWindowProc=(WNDPROC)NULL;
+ Tester.PluginData=NULL;
+ TesterF.PluginData=NULL;
+ TesterN.PluginData=NULL;
+
+ if(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED)
+ CallService(MS_POPUP_ADDPOPUP,(WPARAM)&Tester,0);
+ if(IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED)
+ CallService(MS_POPUP_ADDPOPUP,(WPARAM)&TesterF,0);
+ if(IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED)
+ CallService(MS_POPUP_ADDPOPUP,(WPARAM)&TesterN,0);
+ Changed=TRUE;
+ }
+ break;
+ case IDC_CHECKKBN:
+ Changed=TRUE;
+ break;
+ case IDC_CHECKPOP:
+ Changed=TRUE;
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKCOL),IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPB),(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED) && IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPT),(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED) && IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_RADIOPOPN),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED));
+ EnableWindow(GetDlgItem(hDlg,IDC_RADIOPOP1),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED));
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITPOPS),(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED));
+ break;
+ case IDC_CHECKFPOP:
+ Changed=TRUE;
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKFCOL),IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPFB),(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED) && IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPFT),(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED) && IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITFPOPS),(IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED));
+ break;
+ case IDC_CHECKNPOP:
+ Changed=TRUE;
+ EnableWindow(GetDlgItem(hDlg,IDC_CHECKNCOL),IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPNB),(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED) && IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_CPNT),(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED) && IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED);
+ EnableWindow(GetDlgItem(hDlg,IDC_EDITNPOPS),(IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED));
+ break;
+
+ }
+ if(HIWORD(wParam)==EN_CHANGE)
+ Changed=TRUE;
+ break;
+ }
+ case WM_NOTIFY:
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ switch(((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ TCHAR Text[MAX_PATH];
+ BOOL Translated,NewAcc=FALSE,CheckPopup,CheckPopupW;
+ BOOL CheckNPopup,CheckNPopupW,CheckFPopup,CheckFPopupW;
+ BOOL CheckPopN;
+ UINT Time,TimeN,TimeF;
+
+ if(GetDlgItemText(hDlg,IDC_COMBOACCOUNT,Text,sizeof(Text)/sizeof(TCHAR)))
+ {
+ CheckPopup=(IsDlgButtonChecked(hDlg,IDC_CHECKPOP)==BST_CHECKED);
+ CheckPopupW=(IsDlgButtonChecked(hDlg,IDC_CHECKCOL)==BST_CHECKED);
+
+ CheckFPopup=(IsDlgButtonChecked(hDlg,IDC_CHECKFPOP)==BST_CHECKED);
+ CheckFPopupW=(IsDlgButtonChecked(hDlg,IDC_CHECKFCOL)==BST_CHECKED);
+
+ CheckNPopup=(IsDlgButtonChecked(hDlg,IDC_CHECKNPOP)==BST_CHECKED);
+ CheckNPopupW=(IsDlgButtonChecked(hDlg,IDC_CHECKNCOL)==BST_CHECKED);
+
+ CheckPopN=(IsDlgButtonChecked(hDlg,IDC_RADIOPOPN)==BST_CHECKED);
+
+
+ Time=GetDlgItemInt(hDlg,IDC_EDITPOPS,&Translated,FALSE);
+ if(!Translated)
+ {
+ MessageBox(hDlg,Translate("This is not a valid number value"),Translate("Input error"),MB_OK);
+ SetFocus(GetDlgItem(hDlg,IDC_EDITPOPS));
+ break;
+ }
+ TimeN=GetDlgItemInt(hDlg,IDC_EDITNPOPS,&Translated,FALSE);
+ if(!Translated)
+ {
+ MessageBox(hDlg,Translate("This is not a valid number value"),Translate("Input error"),MB_OK);
+ SetFocus(GetDlgItem(hDlg,IDC_EDITNPOPS));
+ break;
+ }
+ TimeF=GetDlgItemInt(hDlg,IDC_EDITFPOPS,&Translated,FALSE);
+ if(!Translated)
+ {
+ MessageBox(hDlg,Translate("This is not a valid number value"),Translate("Input error"),MB_OK);
+ SetFocus(GetDlgItem(hDlg,IDC_EDITFPOPS));
+ break;
+ }
+
+
+ DlgSetItemText(hDlg,(WPARAM)IDC_STTIMELEFT,(LPARAM)Translate("Please wait while no account is in use."));
+
+ ActualAccount->Flags=
+ (ActualAccount->Flags & YAMN_ACC_ENA) |
+ (ActualAccount->Flags & YAMN_ACC_SSL23) |
+ (ActualAccount->Flags & YAMN_ACC_NOTLS) |
+ (ActualAccount->Flags & YAMN_ACC_APOP) |
+ (ActualAccount->Flags & YAMN_ACC_BODY) |
+ (CheckPopN ? YAMN_ACC_POPN : 0);
+
+ ActualAccount->NewMailN.Flags=
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_SND) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_MSG) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_ICO) |
+ (CheckPopup ? YAMN_ACC_POP : 0) |
+ (CheckPopupW ? YAMN_ACC_POPC : 0) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_APP) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_KBN) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_CONT) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_CONTNICK) |
+ (ActualAccount->NewMailN.Flags & YAMN_ACC_CONTNOEVENT) |
+ YAMN_ACC_MSGP;
+
+ ActualAccount->NoNewMailN.Flags=
+ (CheckNPopup ? YAMN_ACC_POP : 0) |
+ (CheckNPopupW ? YAMN_ACC_POPC : 0) |
+ (ActualAccount->NoNewMailN.Flags & YAMN_ACC_MSGP);
+
+ ActualAccount->BadConnectN.Flags=
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_SND) |
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_MSG) |
+ (ActualAccount->BadConnectN.Flags & YAMN_ACC_ICO) |
+ (CheckFPopup ? YAMN_ACC_POP : 0) |
+ (CheckFPopupW ? YAMN_ACC_POPC : 0);
+
+ ActualAccount->NewMailN.PopUpB=SendDlgItemMessage(hDlg,IDC_CPB,CPM_GETCOLOUR,0,0);
+ ActualAccount->NewMailN.PopUpT=SendDlgItemMessage(hDlg,IDC_CPT,CPM_GETCOLOUR,0,0);
+ ActualAccount->NewMailN.PopUpTime=Time;
+
+ ActualAccount->NoNewMailN.PopUpB=SendDlgItemMessage(hDlg,IDC_CPNB,CPM_GETCOLOUR,0,0);
+ ActualAccount->NoNewMailN.PopUpT=SendDlgItemMessage(hDlg,IDC_CPNT,CPM_GETCOLOUR,0,0);
+ ActualAccount->NoNewMailN.PopUpTime=TimeN;
+
+ ActualAccount->BadConnectN.PopUpB=SendDlgItemMessage(hDlg,IDC_CPFB,CPM_GETCOLOUR,0,0);
+ ActualAccount->BadConnectN.PopUpT=SendDlgItemMessage(hDlg,IDC_CPFT,CPM_GETCOLOUR,0,0);
+ ActualAccount->BadConnectN.PopUpTime=TimeF;
+
+
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:ActualAccountSO-write done\n");
+ #endif
+ WriteDone(ActualAccount);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Options:APPLY:AccountBrowserSO-write done\n");
+ #endif
+ WriteDoneSO(POP3Plugin->AccountBrowserSO);
+
+// if(0==WritePOP3Accounts())
+// Beep(500,100);
+ WritePOP3Accounts();
+ RefreshContact();
+ return TRUE;
+ }
+ }
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ if(Changed)
+ SendMessage(GetParent(hDlg),PSM_CHANGED,0,0);
+ return FALSE;
+}
+
diff --git a/yamn/proto/pop3/pop3opt.h b/yamn/proto/pop3/pop3opt.h new file mode 100644 index 0000000..291ff03 --- /dev/null +++ b/yamn/proto/pop3/pop3opt.h @@ -0,0 +1,38 @@ +#ifndef __OPTIONS_H
+#define __OPTIONS_H
+
+#define M_SHOWACTUAL 0
+#define M_SHOWDEFAULT 1
+
+
+//Enables account in options
+BOOL DlgEnableAccount(HWND hDlg,WPARAM wParam,LPARAM lParam);
+
+//Sets dialog controls to match current account
+BOOL DlgShowAccount(HWND hDlg,WPARAM wParam,LPARAM lParam);
+
+//Sets colors to match colors of actual account
+BOOL DlgShowAccountColors(HWND hDlg,WPARAM wParam,LPARAM lParam);
+
+//Sets dialog item text
+BOOL DlgSetItemText(HWND hDlg,WPARAM wParam,LPARAM lParam);
+
+//Sets dialog item text in Unicode
+BOOL DlgSetItemTextW(HWND hDlg,WPARAM wParam,LPARAM lParam);
+
+//Options dialog procedure
+INT_PTR CALLBACK DlgProcPOP3AccOpt(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//Options dialog procedure
+BOOL CALLBACK DlgProcPOP3AccStatusOpt(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//Options dialog procedure
+INT_PTR CALLBACK DlgProcYAMNOpt(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//Options dialog procedure
+INT_PTR CALLBACK DlgProcPOP3AccPopup(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+//Initializes POP3 options for Miranda
+int POP3OptInit(WPARAM wParam,LPARAM lParam);
+
+#endif
diff --git a/yamn/proto/ssl.cpp b/yamn/proto/ssl.cpp new file mode 100644 index 0000000..2865e91 --- /dev/null +++ b/yamn/proto/ssl.cpp @@ -0,0 +1,344 @@ +/*
+ * This code implements communication based on OpenSSL library
+ *
+ * (c) majvan 2002,2004
+ */
+
+#include "../filter/simple/AggressiveOptimize.h"
+#include <windows.h>
+#include <stdio.h>
+#include <newpluginapi.h> //CallService,UnHookEvent
+#include <m_netlib.h> //socket thorugh proxy functions
+#include <m_langpack.h> //langpack for "connection" and other words
+#include "../debug.h"
+#ifdef SSLTHRUNETLIB
+ #include "netlib.h" //yes, we want to use netlib connection
+#endif
+#include "ssl.h"
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+PFN_SSL_int_void SSL_library_init; // int SSL_library_init()
+PFN_SSL_pvoid_void SSLv23_client_method; // SSL_METHOD *SSLv23_client_method()
+PFN_SSL_pvoid_void TLSv1_client_method; // SSL_METHOD *TLSv1_client_method()
+PFN_SSL_pvoid_pvoid SSL_CTX_new; // SSL_CTX *SSL_CTX_new(SSL_METHOD *method)
+PFN_SSL_void_pvoid SSL_CTX_free; // void SSL_CTX_free(SSL_CTX *ctx);
+PFN_SSL_pvoid_pvoid SSL_new; // SSL *SSL_new(SSL_CTX *ctx)
+PFN_SSL_void_pvoid SSL_free; // void SSL_free(SSL *ssl);
+PFN_SSL_int_pvoid_int SSL_set_fd; // int SSL_set_fd(SSL *ssl, int fd);
+PFN_SSL_int_pvoid SSL_connect; // int SSL_connect(SSL *ssl);
+PFN_SSL_int_pvoid_pvoid_int SSL_read; // int SSL_read(SSL *ssl, void *buffer, int bufsize)
+PFN_SSL_int_pvoid_pvoid_int SSL_write; // int SSL_write(SSL *ssl, void *buffer, int bufsize)
+PFN_SSL_int_pvoid_int SSL_get_error; // int SSL_write(SSL *ssl, int ret)
+
+BOOL SSLLoaded=FALSE;
+HINSTANCE hSSLLibrary=(HINSTANCE)NULL;
+PVOID SSLCtx=NULL;
+PVOID TLSCtx=NULL;
+
+//PVOID CSSLClient::SSLCtx=NULL;
+//BOOL CSSLClient::SSLLoaded=FALSE;
+//HINSTANCE CSSLClient::hSSLLibrary=(HINSTANCE)NULL;
+extern HANDLE hNetlibUser;
+
+void __stdcall SSL_DebugLog( const char *fmt, ... )
+{
+ char str[ 4096 ];
+ va_list vararg;
+
+ va_start( vararg, fmt );
+ int tBytes = _vsnprintf( str, sizeof(str)-1, fmt, vararg );
+ if ( tBytes == 0 )
+ return;
+
+ if ( tBytes > 0 )
+ str[ tBytes ] = 0;
+ else
+ str[ sizeof(str)-1 ] = 0;
+
+ CallService( MS_NETLIB_LOG, ( WPARAM )hNetlibUser, ( LPARAM )str );
+ va_end( vararg );
+}
+
+#define SSLstr "SSL support"
+#define SSLconnstr "SSL connection"
+
+int RegisterSSL()
+{
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<Register SSL support>");
+#endif
+ SSL_DebugLog("%s %sing...",SSLstr,"register");
+ if(NULL==(hSSLLibrary=LoadLibrary("ssleay32.dll")))
+ if(NULL==(hSSLLibrary=LoadLibrary("libssl32.dll"))) //try to load library using the old OpenSSL filename
+ {
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<error, status:library not found></Register SSL support>\n");
+#endif
+ SSL_DebugLog("%s failed.",SSLstr);
+ return 0;
+ }
+
+ if(NULL!=(SSL_library_init=(PFN_SSL_int_void)GetProcAddress(hSSLLibrary,"SSL_library_init")))
+ if(NULL!=(SSLv23_client_method=(PFN_SSL_pvoid_void)GetProcAddress(hSSLLibrary,"SSLv23_client_method")))
+ if(NULL!=(SSL_CTX_new=(PFN_SSL_pvoid_pvoid)GetProcAddress(hSSLLibrary,"SSL_CTX_new")))
+ if(NULL!=(SSL_CTX_free=(PFN_SSL_void_pvoid)GetProcAddress(hSSLLibrary,"SSL_CTX_free")))
+ if(NULL!=(SSL_new=(PFN_SSL_pvoid_pvoid)GetProcAddress(hSSLLibrary,"SSL_new")))
+ if(NULL!=(SSL_free=(PFN_SSL_void_pvoid)GetProcAddress(hSSLLibrary,"SSL_free")))
+ if(NULL!=(SSL_set_fd=(PFN_SSL_int_pvoid_int)GetProcAddress(hSSLLibrary,"SSL_set_fd")))
+ if(NULL!=(SSL_connect=(PFN_SSL_int_pvoid)GetProcAddress(hSSLLibrary,"SSL_connect")))
+ if(NULL!=(SSL_read=(PFN_SSL_int_pvoid_pvoid_int)GetProcAddress(hSSLLibrary,"SSL_read")))
+ if(NULL!=(SSL_write=(PFN_SSL_int_pvoid_pvoid_int)GetProcAddress(hSSLLibrary,"SSL_write")))
+ if(NULL!=(SSL_get_error=(PFN_SSL_int_pvoid_int)GetProcAddress(hSSLLibrary,"SSL_get_error")))
+ {
+ TLSv1_client_method=(PFN_SSL_pvoid_void)GetProcAddress(hSSLLibrary,"TLSv1_client_method");
+ if (TLSv1_client_method) {
+ TLSCtx=SSL_CTX_new(TLSv1_client_method()); //TLS1 only used
+ } else {
+ SSL_DebugLog("TLSv1 not available");
+ }
+ SSL_library_init();
+ SSLCtx=SSL_CTX_new(SSLv23_client_method()); //SSL2,3 & TLS1 used
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</Register SSL support>\n");
+#endif
+ SSLLoaded=TRUE;
+ SSL_DebugLog("%s %sed.",SSLstr,"register");
+ return 1;
+ }
+
+ FreeLibrary(hSSLLibrary);
+ hSSLLibrary=(HINSTANCE)NULL;
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<error, status:library not compatible></Register SSL support>\n");
+#endif
+ SSL_DebugLog("%s failed: %s not compatible",SSLstr,"ssleay32.dll");
+ return 0;
+}
+
+//Connects to the server through the sock
+//if not success, exception is throwed
+void CSSLClient::Connect(const char* servername,const int port) throw(DWORD)
+{
+ WSADATA wsaData;
+
+ NetworkError=SystemError=0;
+
+ if(!SSLLoaded)
+ throw NetworkError=ESSL_NOTLOADED;
+ try
+ {
+#ifdef SSLTHRUNETLIB
+ NETLIBOPENCONNECTION nloc;
+
+ nloc.cbSize=sizeof(NETLIBOPENCONNECTION);
+ nloc.szHost=servername;
+ nloc.wPort=port;
+ nloc.flags=0;
+ #ifdef DEBUG_COMM
+ DebugLog(CommFile,"<open connection>\n");
+ #endif
+ if(NULL==(hNLConn=(HANDLE)CallService(MS_NETLIB_OPENCONNECTION,(WPARAM)hNetlibUser,(LPARAM)&nloc)))
+ {
+ #ifdef DEBUG_COMM
+ DebugLog(CommFile,"<error></open connection>\n");
+ #endif
+ sock=INVALID_SOCKET;
+ }
+ else
+ {
+ #ifdef DEBUG_COMM
+ DebugLog(CommFile,"</open connection>\n");
+ #endif
+ sock=CallService(MS_NETLIB_GETSOCKET,(WPARAM)hNLConn,0);
+ }
+#endif
+
+ if(sock==INVALID_SOCKET)
+ {
+ if(0!=WSAStartup(MAKEWORD(2,0),&wsaData))
+ {
+ SystemError=WSAGetLastError();
+ throw NetworkError=(DWORD)ESSL_WINSOCKINIT;
+ }
+ ZeroMemory(&connection,sizeof(struct sockaddr_in));
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<gethostbyname>\n");
+#endif
+ if(NULL==(server=gethostbyname(servername)))
+ {
+ SystemError=WSAGetLastError();
+ throw NetworkError=(DWORD)ESSL_GETHOSTBYNAME;
+ }
+ memmove((char*)&(connection.sin_addr.s_addr),server->h_addr,server->h_length);
+ connection.sin_family=AF_INET;
+ connection.sin_port=htons((unsigned short int)port); /* integral size mismatch in argument - htons(port)*/
+ if(INVALID_SOCKET==(sock=socket(AF_INET,SOCK_STREAM,0)))
+ {
+ SystemError=WSAGetLastError();
+ throw NetworkError=(DWORD)ESSL_CREATESOCKET;
+ }
+ if(-1==connect(sock,(struct sockaddr*)&connection,sizeof(connection)))
+ {
+ SystemError=WSAGetLastError();
+ throw NetworkError=(DWORD)ESSL_SOCKETCONNECT;
+ }
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</gethostbyname>\n");
+#endif
+ }
+
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<connect SSL>\n");
+#endif
+ if(NULL==(hConnection=SSL_new(SSLCtx)))
+ throw NetworkError=(DWORD)ESSL_CREATESSL;
+ if(SSL_set_fd(hConnection,sock)<1)
+ throw NetworkError=(DWORD)ESSL_SETSOCKET;
+ if(SSL_connect(hConnection)<1)
+ throw NetworkError=(DWORD)ESSL_CONNECT;
+ ConEstablished=TRUE;
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</connect>\n");
+#endif
+ SSL_DebugLog("%s to %s:%d %s.",SSLconnstr,servername,port,"established");
+ return;
+ }
+ catch(...)
+ {
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<error></connect>\n");
+#endif
+ SSL_DebugLog("%s to %s:%d %s.",SSLconnstr,servername,port,"failed");
+ throw;
+ }
+}
+
+void CSSLClient::SSLify() throw(DWORD)
+{
+ SSL_DebugLog("Hmm... Trying to start TLS in SSL... This should be a bug.");
+}
+
+//Performs a simple query
+// query- command to send
+void CSSLClient::Send(const char *query) throw(DWORD)
+{
+ unsigned int Sent;
+
+ if(NULL==query)
+ return;
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<send SSL>%s",query);
+#endif
+ try
+ {
+ if(!ConEstablished)
+ throw NetworkError=(DWORD)ESSL_SEND;
+ SSL_DebugLog("SSL send %s",query);
+ Sent=SSL_write(hConnection,(PVOID)query,strlen(query));
+ if(Sent!=strlen(query))
+ {
+ SystemError=SSL_get_error(hConnection,Sent);
+ throw NetworkError=(DWORD)ESSL_SEND;
+ }
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</send>\n");
+#endif
+ }
+ catch(...)
+ {
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<error></send>\n");
+#endif
+ if (ConEstablished) SSL_DebugLog("SSL send %s","failed");
+ throw;
+ }
+}
+
+//Reads data from SSL socket
+// buf- buffer where to store max. buflen of received characters
+// if buf is NULL, creates buffer of buflen size
+// buf is NULL by default
+//You need free() returned buffer, which can be allocated in this function
+//if not success, exception is throwed
+char* CSSLClient::Recv(char *buf,int buflen) throw(DWORD)
+{
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<reading>");
+#endif
+ try
+ {
+ if(!ConEstablished)
+ throw NetworkError=(DWORD)ESSL_RECV;
+ if(buf==NULL)
+ buf=(char *)malloc(sizeof(char)*(buflen+1));
+ if(buf==NULL)
+ throw NetworkError=(DWORD)ESSL_RECVALLOC;
+ ZeroMemory(buf,buflen);
+ if (hConnection){
+ Rcv=SSL_read(hConnection,buf,buflen);
+ } else {
+ Rcv=0;
+ SSL_DebugLog("SSL connection is lost");
+ }
+ if(Rcv<1)
+ {
+ SystemError=SSL_get_error(hConnection,Rcv);
+ throw NetworkError=(DWORD)ESSL_RECV;
+ }
+#ifdef DEBUG_COMM
+ *(buf+Rcv)=0; //end the buffer to write it to file
+ DebugLog(CommFile,"%s",buf);
+ DebugLog(CommFile,"</reading>\n");
+#endif
+ SSL_DebugLog("SSL recv %s",buf);
+ return(buf);
+ }
+ catch(...)
+ {
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<error></reading>\n");
+#endif
+ if (ConEstablished) SSL_DebugLog("SSL recv %s","failed.");
+ throw;
+ }
+}
+
+//Closes SSL connection
+void CSSLClient::Disconnect()
+{
+#ifdef SSLTHRUNETLIB
+ if((HANDLE)NULL!=hNLConn)
+ Netlib_CloseHandle(hNLConn);
+ else
+#endif
+ if(INVALID_SOCKET!=sock)
+ closesocket(sock);
+
+ if(hConnection!=(HANDLE)NULL)
+ SSL_free(hConnection);
+ hConnection=(HANDLE)NULL;
+ sock=INVALID_SOCKET;
+ hNLConn=(HANDLE)NULL;
+ if (ConEstablished) SSL_DebugLog("%s %s.",SSLconnstr,"closed");
+ ConEstablished=FALSE;
+}
+
+void UnregisterSSL()
+{
+ if(SSLLoaded)
+ {
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"<Unregister SSL support>");
+#endif
+ SSL_CTX_free(SSLCtx);
+ if (TLSCtx) SSL_CTX_free(TLSCtx);
+ FreeLibrary(hSSLLibrary);
+ hSSLLibrary=(HINSTANCE)NULL;
+#ifdef DEBUG_COMM
+ DebugLog(CommFile,"</Unregister SSL support>\n");
+#endif
+ SSL_DebugLog("%s unregistered.",SSLstr);
+ }
+}
diff --git a/yamn/proto/ssl.h b/yamn/proto/ssl.h new file mode 100644 index 0000000..2a61551 --- /dev/null +++ b/yamn/proto/ssl.h @@ -0,0 +1,61 @@ +#ifndef __SSL_H
+#define __SSL_H
+
+#include "netclient.h"
+
+#pragma warning( disable : 4290 )
+#define SSLTHRUNETLIB //performs netlib connection before normal winsock connection
+
+
+typedef int (*PFN_SSL_int_void)(void);
+typedef PVOID (*PFN_SSL_pvoid_void)(void);
+typedef PVOID (*PFN_SSL_pvoid_pvoid)(PVOID);
+typedef void (*PFN_SSL_void_pvoid)(PVOID);
+typedef int (*PFN_SSL_int_pvoid_int)(PVOID, int);
+typedef int (*PFN_SSL_int_pvoid)(PVOID);
+typedef int (*PFN_SSL_int_pvoid_pvoid_int)(PVOID, PVOID, int);
+
+class CSSLClient: public CNetClient
+{
+public:
+ CSSLClient(): hConnection(NULL), sock(INVALID_SOCKET), ConEstablished(FALSE) {}
+ void Connect(const char* servername,const int port) throw(DWORD);
+ void Send(const char *query) throw(DWORD);
+ char* Recv(char *buf=NULL,int buflen=65536) throw(DWORD);
+ void Disconnect();
+ void SSLify()throw(DWORD);
+
+ inline BOOL Connected() {return ConEstablished;}
+
+ //static BOOL SSLLoaded;
+ //static HINSTANCE hSSLLibrary;
+ //static PVOID SSLCtx;
+protected:
+ HANDLE hConnection;
+#ifdef SSLTHRUNETLIB
+ HANDLE hNLConn;
+#endif
+
+ int sock;
+ struct hostent *server;
+ struct sockaddr_in connection;
+
+ BOOL ConEstablished;
+};
+
+enum
+{
+ ESSL_NOTLOADED=1, //OpenSSL is not loaded
+ ESSL_WINSOCKINIT, //WinSock 2.0 init failed
+ ESSL_GETHOSTBYNAME, //DNS error
+ ESSL_CREATESOCKET, //error creating socket
+ ESSL_SOCKETCONNECT, //error connecting with socket
+ ESSL_CREATESSL, //error creating SSL session structure
+ ESSL_SETSOCKET, //error connect socket with SSL session for bidirect I/O space
+ ESSL_CONNECT, //cannot connect to server
+ ESSL_SEND, //cannot send data
+ ESSL_RECV, //cannot receive data
+ ESSL_RECVALLOC, //cannot allocate memory for received data
+};
+
+#endif
diff --git a/yamn/protoplugin.cpp b/yamn/protoplugin.cpp new file mode 100644 index 0000000..e89b879 --- /dev/null +++ b/yamn/protoplugin.cpp @@ -0,0 +1,258 @@ +/*
+ * YAMN plugin export functions for protocols
+ *
+ * (c) majvan 2002-2004
+ */
+
+#if !defined(_WIN64)
+ #include "filter/simple/AggressiveOptimize.h"
+#endif
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <newpluginapi.h>
+#include <m_database.h>
+#include "m_yamn.h"
+#include "m_protoplugin.h"
+#include "m_synchro.h"
+#include "debug.h"
+
+//- imported ---------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+extern WCHAR *UserDirectory; //e.g. "F:\WINNT\Profiles\UserXYZ"
+extern WCHAR *ProfileName; //e.g. "majvan"
+extern SWMRG *AccountBrowserSO;
+extern LPCRITICAL_SECTION PluginRegCS;
+extern YAMN_VARIABLES YAMNVar;
+//From synchro.cpp
+extern BOOL WINAPI SWMRGInitialize(PSWMRG,TCHAR *);
+extern void WINAPI SWMRGDelete(PSWMRG);
+extern DWORD WINAPI SWMRGWaitToWrite(PSWMRG pSWMRG,DWORD dwTimeout);
+extern void WINAPI SWMRGDoneWriting(PSWMRG pSWMRG);
+extern DWORD WINAPI SWMRGWaitToRead(PSWMRG pSWMRG, DWORD dwTimeout);
+extern void WINAPI SWMRGDoneReading(PSWMRG pSWMRG);
+//From account.cpp
+extern int StopAccounts(HYAMNPROTOPLUGIN Plugin);
+extern int DeleteAccounts(HYAMNPROTOPLUGIN Plugin);
+extern int WaitForAllAccounts(HYAMNPROTOPLUGIN Plugin,BOOL GetAccountBrowserAccess);
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+WCHAR FileName2[]=L"%s\\yamn-accounts.%s.%s.book"; //UserDirectory\\yamn-accounts.PluginName.UserProfileName.book
+PYAMN_PROTOPLUGINQUEUE FirstProtoPlugin=NULL;
+
+INT_PTR RegisterProtocolPluginSvc(WPARAM,LPARAM);
+
+//Removes plugin from queue and deletes registration structures
+INT_PTR UnregisterProtocolPlugin(HYAMNPROTOPLUGIN Plugin);
+
+INT_PTR UnregisterProtocolPluginSvc(WPARAM,LPARAM);
+
+//Removes plugins from queue and deletes registration structures
+INT_PTR UnregisterProtoPlugins();
+
+//Sets imported functions for an plugin and therefore it starts plugin to be registered and running
+// Plugin- plugin, which wants to set its functions
+// YAMNFcn- pointer to imported functions with accounts
+// YAMNFcnVer- version of YAMN_PROTOIMPORTFCN, use YAMN_PROTOIMPORTFCNVERSION
+// YAMNMailFcn- pointer to imported functions with mails
+// YAMNMailFcnVer- version of YAMN_MAILIMPORTFCN, use YAMN_MAILIMPORTFCNVERSION
+// returns nonzero if success
+int WINAPI SetProtocolPluginFcnImportFcn(HYAMNPROTOPLUGIN Plugin,PYAMN_PROTOIMPORTFCN YAMNFcn,DWORD YAMNFcnVer,PYAMN_MAILIMPORTFCN YAMNMailFcn,DWORD YAMNMailFcnVer);
+
+INT_PTR GetFileNameWSvc(WPARAM,LPARAM);
+INT_PTR GetFileNameASvc(WPARAM,LPARAM);
+INT_PTR DeleteFileNameSvc(WPARAM,LPARAM);
+
+struct CExportedFunctions ProtoPluginExportedFcn[]=
+{
+ {YAMN_SETPROTOCOLPLUGINFCNIMPORTID,(void *)SetProtocolPluginFcnImportFcn},
+};
+
+struct CExportedServices ProtoPluginExportedSvc[]=
+{
+ {MS_YAMN_REGISTERPROTOPLUGIN,RegisterProtocolPluginSvc},
+ {MS_YAMN_UNREGISTERPROTOPLUGIN,UnregisterProtocolPluginSvc},
+ {MS_YAMN_GETFILENAMEA,GetFileNameASvc},
+ {MS_YAMN_GETFILENAMEW,GetFileNameWSvc},
+ {MS_YAMN_DELETEFILENAME,DeleteFileNameSvc},
+};
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+INT_PTR RegisterProtocolPluginSvc(WPARAM wParam,LPARAM lParam)
+{
+ PYAMN_PROTOREGISTRATION Registration=(PYAMN_PROTOREGISTRATION)wParam;
+ HYAMNPROTOPLUGIN Plugin;
+
+ if(lParam!=YAMN_PROTOREGISTRATIONVERSION)
+ return 0;
+ if((Registration->Name==NULL) || (Registration->Ver==NULL))
+ return (INT_PTR)NULL;
+ if(NULL==(Plugin=new YAMN_PROTOPLUGIN))
+ return (INT_PTR)NULL;
+
+ Plugin->PluginInfo=Registration;
+
+ Plugin->FirstAccount=NULL;
+
+ Plugin->AccountBrowserSO=new SWMRG;
+ SWMRGInitialize(Plugin->AccountBrowserSO,NULL);
+
+ Plugin->Fcn=NULL;
+ Plugin->MailFcn=NULL;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"::: YAMN- new protocol registered: %0x (%s) :::\n",Plugin,Registration->Name);
+#endif
+ return (INT_PTR)Plugin;
+}
+
+int WINAPI SetProtocolPluginFcnImportFcn(HYAMNPROTOPLUGIN Plugin,PYAMN_PROTOIMPORTFCN YAMNFcn,DWORD YAMNFcnVer,PYAMN_MAILIMPORTFCN YAMNMailFcn,DWORD YAMNMailFcnVer)
+{
+ PYAMN_PROTOPLUGINQUEUE Parser;
+
+ if(YAMNFcnVer!=YAMN_PROTOIMPORTFCNVERSION)
+ return 0;
+ if(YAMNMailFcnVer!=YAMN_MAILIMPORTFCNVERSION)
+ return 0;
+ if(YAMNFcn==NULL)
+ return 0;
+ if(YAMNMailFcn==NULL)
+ return 0;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"::: YAMN- protocol %0x import succeed :::\n",Plugin);
+#endif
+ Plugin->Fcn=YAMNFcn;
+ Plugin->MailFcn=YAMNMailFcn;
+
+ EnterCriticalSection(PluginRegCS);
+//We add protocol to the protocol list
+ for(Parser=FirstProtoPlugin;Parser!=NULL && Parser->Next!=NULL;Parser=Parser->Next);
+ if(Parser==NULL)
+ {
+ FirstProtoPlugin=new YAMN_PROTOPLUGINQUEUE;
+ Parser=FirstProtoPlugin;
+ }
+ else
+ {
+ Parser->Next=new YAMN_PROTOPLUGINQUEUE;
+ Parser=Parser->Next;
+ }
+
+ Parser->Plugin=Plugin;
+ Parser->Next=NULL;
+
+ LeaveCriticalSection(PluginRegCS);
+ return 1;
+}
+
+INT_PTR UnregisterProtocolPlugin(HYAMNPROTOPLUGIN Plugin)
+{
+ PYAMN_PROTOPLUGINQUEUE Parser,Found;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Entering UnregisterProtocolPlugin\n");
+#endif
+ if(FirstProtoPlugin->Plugin==Plugin)
+ {
+ Found=FirstProtoPlugin;
+ FirstProtoPlugin=FirstProtoPlugin->Next;
+ }
+ else
+ {
+ for(Parser=FirstProtoPlugin;(Parser->Next!=NULL) && (Plugin!=Parser->Next->Plugin);Parser=Parser->Next);
+ if(Parser->Next!=NULL)
+ {
+ Found=Parser->Next;
+ Parser->Next=Parser->Next->Next;
+ }
+ else
+ Found=NULL;
+ }
+ if(Found!=NULL)
+ {
+ StopAccounts(Plugin);
+ DeleteAccounts(Plugin);
+ if(Plugin->Fcn->UnLoadFcn!=NULL)
+ Plugin->Fcn->UnLoadFcn((void *)0);
+
+ delete Found->Plugin->AccountBrowserSO;
+ delete Found->Plugin;
+ delete Found;
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"::: YAMN- protocol %0x unregistered :::\n",Plugin);
+#endif
+ }
+ else
+ return 0;
+ return 1;
+}
+
+INT_PTR UnregisterProtocolPluginSvc(WPARAM wParam,LPARAM lParam)
+{
+ HYAMNPROTOPLUGIN Plugin=(HYAMNPROTOPLUGIN)wParam;
+
+ EnterCriticalSection(PluginRegCS);
+ UnregisterProtocolPlugin(Plugin);
+ LeaveCriticalSection(PluginRegCS);
+ return 1;
+
+}
+
+INT_PTR UnregisterProtoPlugins()
+{
+ EnterCriticalSection(PluginRegCS);
+//We remove protocols from the protocol list
+ while(FirstProtoPlugin!=NULL)
+ UnregisterProtocolPlugin(FirstProtoPlugin->Plugin);
+ LeaveCriticalSection(PluginRegCS);
+ return 1;
+}
+
+INT_PTR GetFileNameWSvc(WPARAM wParam,LPARAM)
+{
+ WCHAR *FileName;
+
+ if(NULL==(FileName=new WCHAR[MAX_PATH]))
+ return NULL;
+ swprintf(FileName,FileName2,UserDirectory,(WCHAR *)wParam,ProfileName);
+// MessageBoxW(NULL,FileName,L"GetFileNameW",MB_OK);
+ return (INT_PTR)FileName;
+}
+
+INT_PTR GetFileNameASvc(WPARAM wParam,LPARAM)
+{
+ WCHAR *ConvertedInput;
+ WCHAR *FileName;
+
+ if(NULL==(FileName=new WCHAR[MAX_PATH]))
+ return NULL;
+ if(NULL==(ConvertedInput=new WCHAR[MAX_PATH]))
+ {
+ delete[] FileName;
+ return NULL;
+ }
+
+// Convert input string to unicode
+ MultiByteToWideChar(CP_ACP,MB_USEGLYPHCHARS,(char *)wParam,-1,ConvertedInput,(int)strlen((char *)wParam)+1);
+
+ swprintf(FileName,FileName2,UserDirectory,ConvertedInput,ProfileName);
+// MessageBoxW(NULL,FileName,L"GetFileNameA",MB_OK);
+ delete[] ConvertedInput;
+
+ return (INT_PTR)FileName;
+}
+
+INT_PTR DeleteFileNameSvc(WPARAM wParam,LPARAM)
+{
+ if((WCHAR *)wParam!=NULL)
+ delete[] (WCHAR *)wParam;
+
+ return 0;
+}
diff --git a/yamn/resources/YAMN.rc b/yamn/resources/YAMN.rc new file mode 100644 index 0000000..9269bf8 --- /dev/null +++ b/yamn/resources/YAMN.rc @@ -0,0 +1,383 @@ +// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+#endif //_WIN32
+
+#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
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DLGVIEWMESSAGES, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 455
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 105
+ END
+
+ IDD_DLGBADCONNECT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 43
+ END
+
+ IDD_PLUGINOPT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 312
+ VERTGUIDE, 13
+ VERTGUIDE, 85
+ VERTGUIDE, 160
+ VERTGUIDE, 307
+ TOPMARGIN, 4
+ HORZGUIDE, 5
+ HORZGUIDE, 20
+ HORZGUIDE, 147
+ HORZGUIDE, 157
+ HORZGUIDE, 173
+ HORZGUIDE, 184
+ HORZGUIDE, 207
+ HORZGUIDE, 217
+ END
+
+ IDD_POP3ACCOUNTOPT, DIALOG
+ BEGIN
+ VERTGUIDE, 155
+ VERTGUIDE, 236
+ END
+
+ IDD_CHOOSESTATUSMODES, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 219
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 147
+ END
+
+ IDD_YAMNOPT, DIALOG
+ BEGIN
+ VERTGUIDE, 8
+ END
+
+ IDD_POP3ACCOUNTPOPUP, DIALOG
+ BEGIN
+ VERTGUIDE, 155
+ VERTGUIDE, 236
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DLGVIEWMESSAGES DIALOG 50, 200, 460, 110
+STYLE DS_SETFONT | DS_3DLOOK | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+FONT 8, "MS Shell Dlg"
+BEGIN
+ CONTROL "List4",IDC_LISTMAILS,"SysListView32",LVS_REPORT | LVS_EDITLABELS | WS_BORDER | WS_TABSTOP,5,5,450,70
+ DEFPUSHBUTTON "",IDC_BTNOK,395,90,60,15
+ PUSHBUTTON "",IDC_BTNAPP,263,90,114,15
+ PUSHBUTTON "",IDC_BTNDEL,5,90,114,15
+ LTEXT "",IDC_STSTATUS,5,75,450,10
+ PUSHBUTTON "",IDC_BTNCHECKALL,150,91,92,14
+END
+
+IDD_DLGSHOWMESSAGE DIALOGEX 50, 200, 460, 132
+STYLE DS_SETFONT | DS_3DLOOK | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "List5",IDC_LISTHEADERS,"SysListView32",LVS_REPORT | LVS_EDITLABELS | WS_BORDER | WS_TABSTOP,5,5,450,70
+ CONTROL "",IDC_SPLITTER,"Static",SS_ENHMETAFILE | WS_TABSTOP,0,80,187,2,WS_EX_STATICEDGE
+ EDITTEXT IDC_EDITBODY,3,84,454,45,ES_MULTILINE | ES_READONLY | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
+END
+
+IDD_DLGBADCONNECT DIALOG 0, 0, 186, 76
+STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "OK",IDC_BTNOK,69,55,50,14
+ LTEXT "",IDC_STATICMSG,7,7,172,37
+END
+
+IDD_PLUGINOPT DIALOGEX 0, 0, 310, 231
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_BORDER
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX "Installed plugins",IDC_STATIC,7,5,300,142
+ COMBOBOX IDC_COMBOPLUGINS,13,14,287,58,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Version:",IDC_STATIC,13,30,72,11
+ EDITTEXT IDC_STVER,85,30,215,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | WS_GROUP
+ LTEXT "Description:",IDC_STATIC,13,41,72,23
+ EDITTEXT IDC_STDESC,85,41,215,23,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | WS_GROUP
+ LTEXT "Copyright:",IDC_STATIC,13,64,72,10
+ EDITTEXT IDC_STCOPY,85,63,215,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | WS_GROUP
+ LTEXT "Contact:",IDC_STATIC,13,77,72,11
+ EDITTEXT IDC_STMAIL,85,76,214,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | WS_GROUP
+ LTEXT "WWW:",IDC_STATIC,13,101,72,11
+ CONTROL "",IDC_STWWW,"Hyperlink",WS_TABSTOP,85,101,215,11
+END
+
+IDD_POP3ACCOUNTOPT DIALOGEX 0, 0, 310, 230
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ COMBOBOX IDC_COMBOACCOUNT,4,6,106,65,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Check this account",IDC_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,167,32,118,10,WS_EX_TRANSPARENT
+ LTEXT "Check interval [min]:",IDC_STINTERVAL,168,56,94,8
+ EDITTEXT IDC_EDITINTERVAL,259,53,20,12,ES_AUTOHSCROLL | ES_NUMBER,WS_EX_TRANSPARENT
+ GROUPBOX "Notifications",IDC_GBNEWMAIL,4,143,304,87
+ CONTROL "Sound",IDC_CHECKSND,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,12,162,60,10
+ CONTROL "Message",IDC_CHECKMSG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,174,135,10
+ CONTROL "Tray Icon",IDC_CHECKICO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,85,163,65,10
+ CONTROL "Keyboard Flash",IDC_CHECKKBN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,186,132,9
+ CONTROL "Execute Application",IDC_CHECKAPP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,198,135,8
+ PUSHBUTTON "...",IDC_BTNAPP,19,209,16,12
+ EDITTEXT IDC_EDITAPP,41,209,65,12,ES_AUTOHSCROLL
+ EDITTEXT IDC_EDITAPPPARAM,111,209,40,12,ES_AUTOHSCROLL
+ CONTROL "Use contact notification for this account",IDC_CHECKCONTACT,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,166,107,138,10,WS_EX_TRANSPARENT
+ CONTROL "Replace nick name",IDC_CHECKCONTACTNICK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,117,117,10,WS_EX_TRANSPARENT
+ CONTROL "Disable Events",IDC_CHECKCONTACTNOEVENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,128,115,10,WS_EX_TRANSPARENT
+ LTEXT "",IDC_STSTATUS,218,9,88,8
+ LTEXT "Server:",IDC_STSERVER,10,50,44,8
+ EDITTEXT IDC_EDITSERVER,56,48,92,12,ES_AUTOHSCROLL | WS_GROUP
+ LTEXT "User Name:",IDC_STLOGIN,10,82,44,8
+ EDITTEXT IDC_EDITLOGIN,57,80,92,12,ES_AUTOHSCROLL | WS_GROUP
+ LTEXT "Password:",IDC_STPASS,10,96,44,8
+ EDITTEXT IDC_EDITPASS,57,94,92,12,ES_PASSWORD | ES_AUTOHSCROLL | WS_GROUP
+ LTEXT "Codepage:",IDC_STCP,10,111,44,8
+ COMBOBOX IDC_COMBOCP,57,108,92,130,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Port:",IDC_STPORT,10,65,44,8,SS_CENTERIMAGE
+ EDITTEXT IDC_EDITPORT,57,64,27,12,ES_AUTOHSCROLL | ES_NUMBER | WS_GROUP
+ CONTROL "SSL",IDC_CHECKSSL,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,87,66,27,10
+ CONTROL "Disable STLS",IDC_CHECKNOTLS,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,83,125,69,10
+ CONTROL "Startup check",IDC_CHECKSTART,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,167,43,78,10
+ CONTROL "Auto retrieve body",IDC_AUTOBODY,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,166,86,137,10
+ CONTROL "Check from menu",IDC_CHECKFORCE,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,166,97,137,8
+ PUSHBUTTON "Only check when ...",IDC_BTNSTATUS,195,69,81,13
+ CONTROL "Sound notification if failed",IDC_CHECKFSND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,166,163,135,10
+ CONTROL "Message notification if failed",IDC_CHECKFMSG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,166,174,135,10
+ CONTROL "Tray icon notification if failed",IDC_CHECKFICO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,166,186,135,10
+ PUSHBUTTON "Reset counter",IDC_BTNRESET,161,200,75,13
+ PUSHBUTTON "-",IDC_BTNDEL,140,6,15,13
+ PUSHBUTTON "Default",IDC_BTNDEFAULT,9,124,54,13
+ LTEXT "",IDC_STTIMELEFT,163,216,141,8
+ LTEXT "Status:",IDC_STATIC,175,9,34,9
+ PUSHBUTTON "+",IDC_BTNADD,118,6,15,13
+ GROUPBOX "Account",IDC_STATIC,4,22,151,120
+ CONTROL "APOP",IDC_CHECKAPOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,119,66,34,10
+ LTEXT "Name:",IDC_STATIC,10,34,44,10
+ EDITTEXT IDC_EDITNAME,56,32,92,12,ES_AUTOHSCROLL
+ GROUPBOX "Options",IDC_STATIC,161,22,147,120
+ GROUPBOX "New Mail",IDC_STATIC,7,153,149,73
+ GROUPBOX "Errors",IDC_STATIC,161,153,143,44
+END
+
+IDD_CHOOSESTATUSMODES DIALOG 0, 0, 226, 154
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Check while ..."
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,112,133,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,169,133,50,14
+ GROUPBOX "Choose modes",IDC_STATUSGROUP,7,7,212,119
+ CONTROL "Offline",IDC_CHECKST0,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,15,19,70,9
+ CONTROL "Online",IDC_CHECKST1,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,15,39,70,9
+ CONTROL "Away",IDC_CHECKST2,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,15,62,70,9
+ CONTROL "N/A",IDC_CHECKST3,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,15,83,70,9
+ CONTROL "Occupied",IDC_CHECKST4,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,15,104,70,9
+ CONTROL "DND",IDC_CHECKST5,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,134,19,70,9
+ CONTROL "Free for chat",IDC_CHECKST6,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,134,39,70,9
+ CONTROL "Invisible",IDC_CHECKST7,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,134,62,70,9
+ CONTROL "On the phone",IDC_CHECKST8,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,134,83,70,9
+ CONTROL "Out to lunch",IDC_CHECKST9,"Button",BS_AUTOCHECKBOX | BS_NOTIFY | WS_TABSTOP,134,104,70,9
+END
+
+IDD_YAMNOPT DIALOGEX 0, 0, 310, 216
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_BORDER
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ CONTROL "HotKey1",IDC_HKFORCE,"msctls_hotkey32",WS_BORDER | WS_TABSTOP,169,15,110,12
+ LTEXT "Hotkey for mail check:",IDC_STATIC,7,16,153,10
+ CONTROL "TopToolBar button ""Check mail""",IDC_CHECKTTB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,28,160,11
+ GROUPBOX "YAMN General Options",IDC_STATIC,3,2,303,80
+ CONTROL "Enable YAMN Main Menu (Require Restart)",IDC_MAINMENU,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,46,270,9
+ GROUPBOX "MailBrowser Options",IDC_STATIC,3,91,151,61
+ CONTROL "Enable Close on Delete Button",IDC_CLOSEONDELETE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,103,143,11
+ CONTROL "Show long localised date",IDC_LONGDATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,100,144,10
+ CONTROL "Don't show today's date",IDC_SMARTDATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,112,144,10
+ GROUPBOX "Date/Time Representation",IDC_STATIC,166,91,141,61
+ CONTROL "Don't show seconds",IDC_NOSECONDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170,124,135,8
+ CONTROL "Show YAMN as a Protocol (Require Restart)",IDC_YAMNASPROTO,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,63,270,9
+END
+
+IDD_POP3ACCOUNTPOPUP DIALOGEX 0, 0, 315, 230
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ COMBOBOX IDC_COMBOACCOUNT,4,4,140,65,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Mail Notifications",IDC_GBNEWMAIL,5,23,300,76
+ CONTROL "Popup",IDC_CHECKPOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,32,108,10
+ CONTROL "Single popup",IDC_RADIOPOP1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,23,43,95,10
+ CONTROL "Multi popup",IDC_RADIOPOPN,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,23,55,95,10
+ CONTROL "Use custom colour",IDC_CHECKCOL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,83,107,10
+ CONTROL "",IDC_CPB,"ColourPicker",WS_TABSTOP,145,66,29,12
+ CONTROL "",IDC_CPT,"ColourPicker",WS_TABSTOP,145,83,29,12
+ EDITTEXT IDC_EDITPOPS,23,65,20,12,ES_AUTOHSCROLL
+ GROUPBOX "No new mail notifications",IDC_GBNONEWMAIL,5,152,300,62
+ CONTROL "Popup if no mail",IDC_CHECKNPOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,161,94,10
+ CONTROL "Persistant message",IDC_CHECKNMSGP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,188,110,10
+ CONTROL "Use custom colour",IDC_CHECKNCOL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,201,107,10
+ CONTROL "",IDC_CPNB,"ColourPicker",WS_TABSTOP,145,181,29,12
+ CONTROL "",IDC_CPNT,"ColourPicker",WS_TABSTOP,145,198,29,12
+ EDITTEXT IDC_EDITNPOPS,23,173,20,12,ES_AUTOHSCROLL
+ GROUPBOX "Connection failure notifications",IDC_GBBADCONNECT,5,101,300,49
+ CONTROL "Popup notification if failed",IDC_CHECKFPOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,110,118,10
+ CONTROL "Use custom colour",IDC_CHECKFCOL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,136,95,10
+ CONTROL "",IDC_CPFB,"ColourPicker",WS_TABSTOP,145,118,29,12
+ CONTROL "",IDC_CPFT,"ColourPicker",WS_TABSTOP,145,134,29,12
+ EDITTEXT IDC_EDITFPOPS,23,121,20,12,ES_AUTOHSCROLL
+ LTEXT "..s Popup duration",IDC_STATIC,45,67,70,8
+ LTEXT "..s Popup duration",IDC_STATIC,45,176,70,8
+ LTEXT "..s Popup duration",IDC_STATIC,45,122,70,8
+ PUSHBUTTON "Preview",IDC_PREVIEW,255,215,49,13
+ LTEXT "Background colour",IDC_STATIC,177,184,108,10
+ LTEXT "Text colour",IDC_STATIC,177,200,107,10
+ LTEXT "Background colour",IDC_STATIC,177,120,108,10
+ LTEXT "Text colour",IDC_STATIC,177,136,107,10
+ LTEXT "Background colour",IDC_STATIC,177,69,108,10
+ LTEXT "Text colour",IDC_STATIC,177,85,107,10
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ONLINE ICON "iconeutral.ico"
+IDI_OFFLINE ICON "icooffline.ico"
+IDI_NA ICON "icoyamn3.ico"
+IDI_OCCUPIED ICON "iconttbdown.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_ICONS BITMAP "yamn.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,1,2,5
+ PRODUCTVERSION 0,1,2,5
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "Comments", "Yet Another Mail Notifier"
+ VALUE "FileDescription", "Yet Another Mail Notifier"
+ VALUE "FileVersion", "0.1.2.5"
+ VALUE "InternalName", "YAMN"
+ VALUE "LegalCopyright", "Copyright © 2007"
+ VALUE "OriginalFilename", "YAMN.dll"
+ VALUE "ProductName", "YAMN tweety"
+ VALUE "ProductVersion", "0.1.2.5"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
+
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/yamn/resources/iconeutral.ico b/yamn/resources/iconeutral.ico Binary files differnew file mode 100644 index 0000000..9304f43 --- /dev/null +++ b/yamn/resources/iconeutral.ico diff --git a/yamn/resources/iconttbdown.ico b/yamn/resources/iconttbdown.ico Binary files differnew file mode 100644 index 0000000..206eba2 --- /dev/null +++ b/yamn/resources/iconttbdown.ico diff --git a/yamn/resources/icooffline.ico b/yamn/resources/icooffline.ico Binary files differnew file mode 100644 index 0000000..db5b2e1 --- /dev/null +++ b/yamn/resources/icooffline.ico diff --git a/yamn/resources/icoyamn3.ico b/yamn/resources/icoyamn3.ico Binary files differnew file mode 100644 index 0000000..ca11f0f --- /dev/null +++ b/yamn/resources/icoyamn3.ico diff --git a/yamn/resources/resource.h b/yamn/resources/resource.h new file mode 100644 index 0000000..bd9b48b --- /dev/null +++ b/yamn/resources/resource.h @@ -0,0 +1,130 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by YAMN.rc
+//
+#define IDI_ONLINE 104
+#define IDI_OFFLINE 105
+#define IDD_DLGVIEWMESSAGES 107
+#define IDD_DLGSHOWMESSAGE 108
+#define IDI_ICOYAMN2 112
+#define IDI_ICOYAMN1 113
+#define IDD_DLGBADCONNECT 115
+#define IDD_POP3ACCOUNTOPT 121
+#define IDD_YAMNOPT 126
+#define IDB_ICONS 127
+#define IDI_NA 131
+#define IDI_ICOTTBUP 138
+#define IDD_PLUGINOPT 141
+#define IDI_OCCUPIED 159
+#define IDD_CHOOSESTATUSMODES 310
+#define IDD_OPTIONS 311
+#define IDD_POP3ACCOUNTPOPUP 312
+#define IDC_EDITSERVER 1000
+#define IDC_EDITPORT 1001
+#define IDC_EDITLOGIN 1002
+#define IDC_EDITPASS 1003
+#define IDC_COMBOACCOUNT 1005
+#define IDC_BTNDEFAULT 1006
+#define IDC_EDITINTERVAL 1007
+#define IDC_CHECKSND 1008
+#define IDC_CHECKMSG 1009
+#define IDC_CHECKAPP 1010
+#define IDC_BTNAPP 1011
+#define IDC_CHECKICO 1012
+#define IDC_CHECK 1013
+#define IDC_BTNDEL 1014
+#define IDC_STSERVER 1015
+#define IDC_CHECKFSND 1016
+#define IDC_CHECKFMSG 1017
+#define IDC_CHECKFICO 1018
+#define IDC_CHECKST0 1019
+#define IDC_CHECKST1 1020
+#define IDC_CHECKST2 1021
+#define IDC_CHECKST3 1022
+#define IDC_CHECKST4 1023
+#define IDC_CHECKST5 1024
+#define IDC_CHECKST6 1025
+#define IDC_CHECKST7 1026
+#define IDC_EDITAPP 1027
+#define IDC_CHECKST8 1028
+#define IDC_CHECKST9 1029
+#define IDC_CHECKCONTACT 1030
+#define IDC_CHECKCONTACTNICK 1031
+#define IDC_CHECKCONTACTNOEVENT 1032
+#define IDC_STTIMELEFT 1033
+#define IDC_LISTMAILS 1038
+#define IDC_LISTHEADERS 1039
+#define IDC_EDITAPPPARAM 1044
+#define IDC_BTNOK 1047
+#define IDC_COMBOCP 1050
+#define IDC_STCP 1055
+#define IDC_STATICMSG 1055
+#define IDC_STPORT 1056
+#define IDC_STLOGIN 1057
+#define IDC_STPASS 1058
+#define IDC_STINTERVAL 1059
+#define IDC_AUTOBODY 1062
+#define IDC_BTNRESET 1063
+#define IDC_CHECKSTART 1064
+#define IDC_STWCHECK 1065
+#define IDC_CHECKFORCE 1066
+#define IDC_RADIOPOP1 1068
+#define IDC_RADIOPOPN 1069
+#define IDC_CPB 1070
+#define IDC_CPNB 1071
+#define IDC_CHECKCOL 1073
+#define IDC_CPT 1074
+#define IDC_CPFB 1075
+#define IDC_CPFT 1076
+#define IDC_CHECKFCOL 1077
+#define IDC_CHECKNCOL 1078
+#define IDC_CPNT 1079
+#define IDC_HKFORCE 1081
+#define IDC_CHECKPOP 1087
+#define IDC_CHECKNPOP 1088
+#define IDC_CHECKFPOP 1089
+#define IDC_EDITPOPS 1090
+#define IDC_EDITNPOPS 1091
+#define IDC_EDITFPOPS 1092
+#define IDC_GBNEWMAIL 1094
+#define IDC_GBNONEWMAIL 1095
+#define IDC_GBBADCONNECT 1096
+#define IDC_STSTATUS 1102
+#define IDC_COMBOPLUGINS 1104
+#define IDC_STWWW 1111
+#define IDC_STMAIL 1113
+#define IDC_STCOPY 1114
+#define IDC_STDESC 1115
+#define IDC_STVER 1116
+#define IDC_CHECKTTB 1117
+#define IDC_CHECKSSL 1117
+#define IDC_CHECKNMSGP 1118
+#define IDC_CHECKNOTLS 1120
+#define IDC_CHECKKBN 1121
+#define IDC_BTNSTATUS 1123
+#define IDC_OPTIONSTAB 1124
+#define IDC_BTNCHECKALL 1125
+#define IDC_MAINMENU 1126
+#define IDC_CLOSEONDELETE 1127
+#define IDC_LONGDATE 1128
+#define IDC_SMARTDATE 1129
+#define IDC_NOSECONDS 1130
+#define IDC_YAMNASPROTO 1131
+#define IDC_CHECKAPOP 1200
+#define IDC_STATUSGROUP 1338
+#define IDC_SPLITTER 1400
+#define IDC_EDITBODY 1401
+#define IDC_PREVIEW 1402
+#define IDC_BTNADD 1403
+#define IDC_EDITNAME 1404
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 143
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1407
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/yamn/resources/yamn.bmp b/yamn/resources/yamn.bmp Binary files differnew file mode 100644 index 0000000..91a9e34 --- /dev/null +++ b/yamn/resources/yamn.bmp diff --git a/yamn/services.cpp b/yamn/services.cpp new file mode 100644 index 0000000..e4b8b79 --- /dev/null +++ b/yamn/services.cpp @@ -0,0 +1,541 @@ +
+#include "main.h"
+#include "yamn.h"
+// External icon var for icolib support
+
+
+//MessageWndCS
+//We want to send messages to all windows in the queue
+//When we send messages, no other window can register itself to the queue for receiving messages
+extern LPCRITICAL_SECTION MessageWndCS;
+
+//Plugin registration CS
+//Used if we add (register) plugin to YAMN plugins and when we browse through registered plugins
+extern LPCRITICAL_SECTION PluginRegCS;
+
+//AccountWriterCS
+//We want to store number of writers of Accounts (number of Accounts used for writing)
+//If we want to read all accounts (for saving to file) immidiatelly, we have to wait until no account is changing (no thread writing to account)
+extern SCOUNTER *AccountWriterSO;
+
+//NoExitEV
+//Event that is signaled when there's a request to exit, so no new pop3 check should be performed
+extern HANDLE ExitEV;
+
+//WriteToFileEV
+//If this is signaled, write accounts to file is performed. Set this event if you want to actualize your accounts and messages
+extern HANDLE WriteToFileEV;
+
+//extern HICON hYamnIconsOrg[];
+extern HICON hYamnIcons[];
+extern char *iconDescs[];
+extern char *iconNames[];
+extern HIMAGELIST CSImages;
+
+extern void __stdcall SSL_DebugLog( const char *fmt, ... );
+
+extern char *ProtoName;
+extern INT_PTR YAMN_STATUS;
+
+extern PYAMN_VARIABLES pYAMNVar;
+extern HYAMNPROTOPLUGIN POP3Plugin;
+
+static INT_PTR Service_GetCaps(WPARAM wParam, LPARAM lParam)
+{
+ if(wParam==PFLAGNUM_4)
+ return PF4_NOCUSTOMAUTH;
+ if(wParam==PFLAG_UNIQUEIDTEXT)
+ return (INT_PTR) Translate("Nick");
+ if(wParam==PFLAG_MAXLENOFMESSAGE)
+ return 400;
+ if(wParam==PFLAG_UNIQUEIDSETTING)
+ return (INT_PTR) "Id";
+ if(wParam==PFLAGNUM_2)
+ return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND;
+ if(wParam==PFLAGNUM_5)
+ if(DBGetContactSettingByte(NULL, YAMN_DBMODULE, YAMN_SHOWASPROTO, 0))
+ return PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND;
+ else
+ return PF2_ONLINE | PF2_SHORTAWAY | PF2_LONGAWAY | PF2_LIGHTDND;
+ return 0;
+}
+
+static INT_PTR Service_GetStatus(WPARAM wParam, LPARAM lParam)
+{
+ return YAMN_STATUS;
+}
+
+static INT_PTR Service_SetStatus(WPARAM wParam,LPARAM lParam)
+{
+ INT_PTR newstatus = (wParam!=ID_STATUS_OFFLINE)?ID_STATUS_ONLINE:ID_STATUS_OFFLINE;
+ if (newstatus != YAMN_STATUS){
+ INT_PTR oldstatus = YAMN_STATUS;
+ YAMN_STATUS=newstatus;
+ ProtoBroadcastAck(ProtoName,NULL,ACKTYPE_STATUS,ACKRESULT_SUCCESS,(HANDLE)oldstatus,newstatus);
+ }
+ return 0;
+
+}
+
+static INT_PTR Service_GetName(WPARAM wParam, LPARAM lParam)
+{
+ lstrcpyn((char *) lParam, ProtoName, wParam);;
+ return 0;
+}
+
+static INT_PTR Service_LoadIcon(WPARAM wParam,LPARAM lParam)
+{
+ if ( LOWORD( wParam ) == PLI_PROTOCOL )
+ return (INT_PTR)CopyIcon(hYamnIcons[0]); // noone cares about other than PLI_PROTOCOL
+
+ return (INT_PTR)(HICON)NULL;
+
+}
+
+/*static*/ INT_PTR ClistContactDoubleclicked(WPARAM wParam, LPARAM lParam)
+{
+ ContactDoubleclicked(((CLISTEVENT*)lParam)->lParam, lParam);
+ return 0;
+}
+
+static int Service_ContactDoubleclicked(WPARAM wParam, LPARAM lParam)
+{
+ ContactDoubleclicked(wParam, lParam);
+ return 0;
+}
+
+static INT_PTR ContactApplication(WPARAM wParam, LPARAM lParam)
+{
+ DBVARIANT dbv;
+ char *szProto;
+ HACCOUNT ActualAccount;
+
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0);
+ if(szProto != NULL && strcmp(szProto, ProtoName)==0)
+ {
+ if(!DBGetContactSetting((HANDLE) wParam,ProtoName,"Id",&dbv))
+ {
+ ActualAccount=(HACCOUNT) CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)dbv.pszVal);
+ if(ActualAccount != NULL)
+ {
+ PROCESS_INFORMATION pi;
+ STARTUPINFOW si;
+
+ ZeroMemory(&si,sizeof(si));
+ si.cb=sizeof(si);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ContactApplication:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0==WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ContactApplication:ualAccountSO-read enter\n");
+ #endif
+ if(ActualAccount->NewMailN.App!=NULL)
+ {
+ WCHAR *Command;
+ if(ActualAccount->NewMailN.AppParam!=NULL)
+ Command=new WCHAR[wcslen(ActualAccount->NewMailN.App)+wcslen(ActualAccount->NewMailN.AppParam)+6];
+ else
+ Command=new WCHAR[wcslen(ActualAccount->NewMailN.App)+6];
+
+ if(Command!=NULL)
+ {
+ lstrcpyW(Command,L"\"");
+ lstrcatW(Command,ActualAccount->NewMailN.App);
+ lstrcatW(Command,L"\" ");
+ if(ActualAccount->NewMailN.AppParam!=NULL)
+ lstrcatW(Command,ActualAccount->NewMailN.AppParam);
+ CreateProcessW(NULL,Command,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
+ delete[] Command;
+ }
+ }
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ContactApplication:ActualAccountSO-read done\n");
+ #endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+ #ifdef DEBUG_SYNCHRO
+ else
+ DebugLog(SynchroFile,"ContactApplication:ActualAccountSO-read enter failed\n");
+ #endif
+ }
+ DBFreeVariant(&dbv);
+ }
+ }
+ return 0;
+}
+
+DWORD WINAPI SWMRGWaitToRead(PSWMRG pSWMRG, DWORD dwTimeout);
+static INT_PTR AccountMailCheck(WPARAM wParam, LPARAM lParam){
+ //This service will check/sincronize the account pointed by wParam
+ HACCOUNT ActualAccount = (HACCOUNT)wParam;
+ HANDLE ThreadRunningEV;
+ DWORD tid;
+ // copy/paste make mistakes
+ if(ActualAccount != NULL)
+ {
+ //we use event to signal, that running thread has all needed stack parameters copied
+ if(NULL==(ThreadRunningEV=CreateEvent(NULL,FALSE,FALSE,NULL)))
+ return 0;
+ //if we want to close miranda, we get event and do not run pop3 checking anymore
+ if(WAIT_OBJECT_0==WaitForSingleObject(ExitEV,0))
+ return 0;
+ EnterCriticalSection(PluginRegCS);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"AccountCheck:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=SWMRGWaitToRead(ActualAccount->AccountAccessSO,0))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read wait failed\n");
+ #endif
+ }
+ else
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read enter\n");
+ #endif
+ if((ActualAccount->Flags & YAMN_ACC_ENA) && ActualAccount->Plugin->Fcn->SynchroFcnPtr)
+ {
+ struct CheckParam ParamToPlugin={YAMN_CHECKVERSION,ThreadRunningEV,ActualAccount,lParam?YAMN_FORCECHECK:YAMN_NORMALCHECK,(void *)0,NULL};
+ HANDLE NewThread;
+
+ ActualAccount->TimeLeft=ActualAccount->Interval;
+ if(NewThread=CreateThread(NULL,0,(YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->SynchroFcnPtr,&ParamToPlugin,0,&tid))
+ {
+ WaitForSingleObject(ThreadRunningEV,INFINITE);
+ CloseHandle(NewThread);
+ }
+ else
+ {
+ //ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+
+ }
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+ LeaveCriticalSection(PluginRegCS);
+ CloseHandle(ThreadRunningEV);
+ }
+ return 0;
+}
+
+static INT_PTR ContactMailCheck(WPARAM wParam, LPARAM lParam)
+{
+
+ DBVARIANT dbv;
+ char *szProto;
+ HACCOUNT ActualAccount;
+ HANDLE ThreadRunningEV;
+ DWORD tid;
+
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0);
+ if(szProto != NULL && strcmp(szProto, ProtoName)==0)
+ {
+ if(!DBGetContactSetting((HANDLE) wParam,ProtoName,"Id",&dbv))
+ {
+ ActualAccount=(HACCOUNT) CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)dbv.pszVal);
+ if(ActualAccount != NULL)
+ {
+ //we use event to signal, that running thread has all needed stack parameters copied
+ if(NULL==(ThreadRunningEV=CreateEvent(NULL,FALSE,FALSE,NULL)))
+ return 0;
+ //if we want to close miranda, we get event and do not run pop3 checking anymore
+ if(WAIT_OBJECT_0==WaitForSingleObject(ExitEV,0))
+ return 0;
+ EnterCriticalSection(PluginRegCS);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read wait failed\n");
+ #endif
+ }
+ else
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read enter\n");
+ #endif
+ if((ActualAccount->Flags & YAMN_ACC_ENA) && (ActualAccount->StatusFlags & YAMN_ACC_FORCE)) //account cannot be forced to check
+ {
+ if(ActualAccount->Plugin->Fcn->ForceCheckFcnPtr==NULL)
+ {
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+ struct CheckParam ParamToPlugin={YAMN_CHECKVERSION,ThreadRunningEV,ActualAccount,YAMN_FORCECHECK,(void *)0,NULL};
+
+ if(NULL==CreateThread(NULL,0,(YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->ForceCheckFcnPtr,&ParamToPlugin,0,&tid))
+ {
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+ else
+ WaitForSingleObject(ThreadRunningEV,INFINITE);
+ }
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+ LeaveCriticalSection(PluginRegCS);
+ CloseHandle(ThreadRunningEV);
+ }
+ DBFreeVariant(&dbv);
+ }
+
+ }
+ return 0;
+}
+
+
+void MainMenuAccountClicked(WPARAM wParam, LPARAM lParam)
+{
+
+}
+
+/*static*/ void ContactDoubleclicked(WPARAM wParam, LPARAM lParam)
+{
+ DBVARIANT dbv;
+ char *szProto;
+ HACCOUNT ActualAccount;
+
+ szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0);
+ if(szProto != NULL && strcmp(szProto, ProtoName)==0)
+ {
+ if(!DBGetContactSetting((HANDLE) wParam,ProtoName,"Id",&dbv))
+ {
+ ActualAccount=(HACCOUNT) CallService(MS_YAMN_FINDACCOUNTBYNAME,(WPARAM)POP3Plugin,(LPARAM)dbv.pszVal);
+ if(ActualAccount != NULL)
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Service_ContactDoubleclicked:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0==WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Service_ContactDoubleclicked:ActualAccountSO-read enter\n");
+ #endif
+ YAMN_MAILBROWSERPARAM Param={(HANDLE)0,ActualAccount,ActualAccount->NewMailN.Flags,ActualAccount->NoNewMailN.Flags,0};
+
+ Param.nnflags=Param.nnflags | YAMN_ACC_MSG; //show mails in account even no new mail in account
+ Param.nnflags=Param.nnflags & ~YAMN_ACC_POP;
+
+ Param.nflags=Param.nflags | YAMN_ACC_MSG; //show mails in account even no new mail in account
+ Param.nflags=Param.nflags & ~YAMN_ACC_POP;
+
+ RunMailBrowserSvc((WPARAM)&Param,(LPARAM)YAMN_MAILBROWSERVERSION);
+
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"Service_ContactDoubleclicked:ActualAccountSO-read done\n");
+ #endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+ #ifdef DEBUG_SYNCHRO
+ else
+ DebugLog(SynchroFile,"Service_ContactDoubleclicked:ActualAccountSO-read enter failed\n");
+ #endif
+
+ }
+ DBFreeVariant(&dbv);
+ }
+
+ }
+}
+
+int IcoLibIconsChanged(WPARAM wParam, LPARAM lParam)
+{
+ HICON temp;
+ for (int i=0;i<ICONSNUMBER;i++){
+ if (temp = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) iconNames[i]))hYamnIcons[i]=temp;
+ }
+ { CLISTMENUITEM mi = {0};
+ extern HANDLE hMenuItemMain;
+ extern HANDLE hMenuItemCont;
+ extern HANDLE hMenuItemContApp;
+
+ mi.cbSize = sizeof(mi);
+ mi.flags = CMIM_ICON;
+
+ mi.hIcon = hYamnIcons[5];
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItemMain, (LPARAM)&mi);
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItemCont, (LPARAM)&mi);
+ mi.hIcon = hYamnIcons[4];
+ CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItemContApp, (LPARAM)&mi);
+ }
+ return 0;
+}
+
+int SystemModulesLoaded(WPARAM,LPARAM); //in main.cpp
+typedef struct { HANDLE hookHandle; const char *hookName; MIRANDAHOOK mirandaFunction;} HookDataType;
+static HookDataType hookData[]={
+ {0,ME_TTB_MODULELOADED,AddTopToolbarIcon},
+ {0,ME_SYSTEM_MODULESLOADED,SystemModulesLoaded}, //pop3 plugin must be included after all miranda modules are loaded
+ {0,ME_OPT_INITIALISE,YAMNOptInitSvc},
+ {0,ME_PLUGINUNINSTALLER_UNINSTALL,UninstallQuestionSvc},
+ {0,ME_SYSTEM_PRESHUTDOWN,Shutdown},
+ {0,ME_CLIST_DOUBLECLICKED, Service_ContactDoubleclicked},
+ {0,ME_SKIN2_ICONSCHANGED, IcoLibIconsChanged},
+ {0,0,0}//end marker
+};
+
+
+void HookEvents(void)
+{
+ //We set function which registers needed POP3 accounts. This is a part of internal POP3 plugin.
+ //Your plugin should do the same task in your Load fcn. Why we call it in MODULESLOADED? Because netlib
+ //user can be registered after all modules are loaded (see m_netlib.h in Miranda)
+ for (int i=0;hookData[i].hookName;i++){
+ hookData[i].hookHandle = HookEvent(hookData[i].hookName,hookData[i].mirandaFunction);
+ }
+}
+void UnhookEvents(void){
+ for (int i=0;i<(sizeof(hookData)/sizeof(hookData[0]));i++){
+ if (hookData[i].hookHandle) UnhookEvent(hookData[i].hookHandle);
+ }
+}
+
+typedef struct { HANDLE serviceHandle; const char *serviceName; MIRANDASERVICE serviceFunction;} ServiceDataType;
+static ServiceDataType serviceData[]={
+ {0,YAMN_DBMODULE PS_GETCAPS,Service_GetCaps},
+ {0,YAMN_DBMODULE PS_GETSTATUS,Service_GetStatus},
+ {0,YAMN_DBMODULE PS_SETSTATUS,Service_SetStatus},
+ {0,YAMN_DBMODULE PS_GETNAME,Service_GetName},
+ {0,YAMN_DBMODULE PS_LOADICON,Service_LoadIcon},
+
+ //Function with which protocol plugin can register
+ {0,MS_YAMN_GETFCNPTR,GetFcnPtrSvc},
+
+ //Function returns pointer to YAMN variables
+ {0,MS_YAMN_GETVARIABLES,GetVariablesSvc},
+
+ //Function with which protocol plugin can register
+ {0,MS_YAMN_REGISTERPROTOPLUGIN,RegisterProtocolPluginSvc},
+
+ //Function with which protocol plugin can unregister
+ {0,MS_YAMN_UNREGISTERPROTOPLUGIN,UnregisterProtocolPluginSvc},
+
+ //Function creates an account for plugin
+ {0,MS_YAMN_CREATEPLUGINACCOUNT,CreatePluginAccountSvc},
+
+ //Function deletes plugin account
+ {0,MS_YAMN_DELETEPLUGINACCOUNT,DeletePluginAccountSvc},
+
+ //Finds account for plugin by name
+ {0,MS_YAMN_FINDACCOUNTBYNAME,FindAccountByNameSvc},
+
+ //Creates next account for plugin
+ {0,MS_YAMN_GETNEXTFREEACCOUNT,GetNextFreeAccountSvc},
+
+ //Function removes account from YAMN queue. Does not delete it from memory
+ {0,MS_YAMN_DELETEACCOUNT,DeleteAccountSvc},
+
+ //Function finds accounts for specified plugin
+ {0,MS_YAMN_READACCOUNTSA,AddAccountsFromFileASvc},
+
+ //Function that reads all plugin mails from file
+ {0,MS_YAMN_READACCOUNTSW,AddAccountsFromFileWSvc},
+
+ //Function that stores all plugin mails to one file
+ {0,MS_YAMN_WRITEACCOUNTSA,WriteAccountsToFileASvc},
+
+ //Function that stores all plugin mails to one file
+ {0,MS_YAMN_WRITEACCOUNTSW,WriteAccountsToFileWSvc},
+
+ //Function that returns user's filename
+ {0,MS_YAMN_GETFILENAMEA,GetFileNameASvc},
+
+ //Function that returns user's filename (unicode input)
+ {0,MS_YAMN_GETFILENAMEW,GetFileNameWSvc},
+
+ //Releases unicode string from memory
+ {0,MS_YAMN_DELETEFILENAME,DeleteFileNameSvc},
+
+ //Checks mail
+ {0,MS_YAMN_FORCECHECK,ForceCheckSvc},
+
+ //Runs YAMN's mail browser
+ {0,MS_YAMN_MAILBROWSER,RunMailBrowserSvc},
+
+ //Runs YAMN's bad conenction window
+ {0,MS_YAMN_BADCONNECTION,RunBadConnectionSvc},
+
+ //Function creates new mail for plugin
+ {0,MS_YAMN_CREATEACCOUNTMAIL,CreateAccountMailSvc},
+
+ //Function deletes plugin account
+ {0,MS_YAMN_DELETEACCOUNTMAIL,DeleteAccountMailSvc},
+
+ //Function with which filter plugin can register
+ {0,MS_YAMN_REGISTERFILTERPLUGIN,RegisterFilterPluginSvc},
+
+ //Function with which filter plugin can unregister
+ {0,MS_YAMN_UNREGISTERFILTERPLUGIN,UnregisterFilterPluginSvc},
+
+ //Function filters mail
+ {0,MS_YAMN_FILTERMAIL,FilterMailSvc},
+
+ //Function contact list double click
+ {0,MS_YAMN_CLISTDBLCLICK,ClistContactDoubleclicked},
+
+ //Function to check individual account
+ {0,MS_YAMN_ACCOUNTCHECK,AccountMailCheck},
+
+ //Function contact list context menu click
+ {0,MS_YAMN_CLISTCONTEXT,ContactMailCheck},
+
+ //Function contact list context menu click
+ {0,MS_YAMN_CLISTCONTEXTAPP,ContactApplication},
+
+ {0,0,0}//end marker
+};
+
+void CreateServiceFunctions(void)
+{
+ for (int i=0;serviceData[i].serviceName;i++){
+ serviceData[i].serviceHandle = CreateServiceFunction(serviceData[i].serviceName,serviceData[i].serviceFunction);
+ }
+};
+
+void DestroyServiceFunctions(void)
+{
+ for (int i=0;serviceData[i].serviceName;i++){
+ if (serviceData[i].serviceHandle) DestroyServiceFunction(serviceData[i].serviceHandle);
+ }
+};
+
+//Function to put all enabled contact to the Online status
+void RefreshContact(void)
+{
+ HACCOUNT Finder;
+
+ for(Finder=POP3Plugin->FirstAccount;Finder!=NULL;Finder=Finder->Next)
+ {
+ if(Finder->hContact != NULL)
+ {
+ if((Finder->Flags & YAMN_ACC_ENA) && (Finder->NewMailN.Flags & YAMN_ACC_CONT))
+ {
+ DBDeleteContactSetting(Finder->hContact, "CList", "Hidden");
+ }
+ else
+ {
+ DBWriteContactSettingByte(Finder->hContact, "CList", "Hidden", 1);
+ }
+ }
+ else
+ {
+ if((Finder->Flags & YAMN_ACC_ENA) && (Finder->NewMailN.Flags & YAMN_ACC_CONT))
+ {
+ Finder->hContact =(HANDLE) CallService(MS_DB_CONTACT_ADD, 0, 0);
+ CallService(MS_PROTO_ADDTOCONTACT,(WPARAM)Finder->hContact,(LPARAM)ProtoName);
+ DBWriteContactSettingString(Finder->hContact,ProtoName,"Id",Finder->Name);
+ DBWriteContactSettingString(Finder->hContact,ProtoName,"Nick",Finder->Name);
+ DBWriteContactSettingString(Finder->hContact,"Protocol","p",ProtoName);
+ DBWriteContactSettingWord(Finder->hContact, ProtoName, "Status", ID_STATUS_ONLINE);
+ DBWriteContactSettingString(Finder->hContact, "CList", "StatusMsg", Translate("No new mail message"));
+ }
+
+ }
+ }
+
+}
diff --git a/yamn/synchro.cpp b/yamn/synchro.cpp new file mode 100644 index 0000000..e791d5f --- /dev/null +++ b/yamn/synchro.cpp @@ -0,0 +1,378 @@ +/*
+ * This code implements synchronization objects code between threads. If you want, you can include it to your
+ * code. This file is not dependent on any other external code (functions)
+ *
+ * (c) majvan 2002-2004
+ */
+#if !defined(_WIN64)
+ #include "filter/simple/AggressiveOptimize.h"
+#endif
+#include <windows.h>
+#include "debug.h"
+#include "m_yamn.h"
+#include "m_synchro.h"
+#ifdef DEBUG_SYNCHRO
+#include <tchar.h>
+#include <stdio.h>
+#endif
+
+// Initializes a SWMRG structure. This structure must be
+// initialized before any writer or reader threads attempt
+// to wait on it.
+// The structure must be allocated by the application and
+// the structure's address is passed as the first parameter.
+// The lpszName parameter is the name of the object. Pass
+// NULL if you do not want to share the object.
+BOOL WINAPI SWMRGInitialize(PSWMRG pSWMRG,TCHAR *Name);
+
+// Deletes the system resources associated with a SWMRG
+// structure. The structure must be deleted only when
+// no writer or reader threads in the calling process
+// will wait on it.
+void WINAPI SWMRGDelete(PSWMRG pSWMRG);
+
+// A writer thread calls this function to know when
+// it can successfully write to the shared data.
+// returns WAIT_FINISH when we are in write-access or WAIT_FAILED
+// when event about quick finishing is set (or when system returns fail when waiting for synchro object)
+DWORD WINAPI SWMRGWaitToWrite(PSWMRG pSWMRG,DWORD dwTimeout);
+
+// A writer thread calls this function to let other threads
+// know that it no longer needs to write to the shared data.
+void WINAPI SWMRGDoneWriting(PSWMRG pSWMRG);
+
+// A reader thread calls this function to know when
+// it can successfully read the shared data.
+// returns WAIT_FINISH when we are in read-access or WAIT_FAILED
+// when event about quick finishing is set (or when system returns fail when waiting for synchro object)
+DWORD WINAPI SWMRGWaitToRead(PSWMRG pSWMRG, DWORD dwTimeout);
+
+// A reader thread calls this function to let other threads
+// know when it no longer needs to read the shared data.
+void WINAPI SWMRGDoneReading(PSWMRG pSWMRG);
+
+// WaitToWriteFcn
+// is used to wait for write access with SWMRG SO, but it also increments counter if successfull
+// returns WAIT_FAILED or WAIT_FINISH
+// when WAIT_FAILED, we should not begin to access datas, we are not in write-access mode
+DWORD WINAPI WaitToWriteFcn(PSWMRG SObject,PSCOUNTER SCounter=NULL);
+
+// WriteDoneFcn
+// is used to release write access with SWMRG SO, but it also decrements counter if successfull
+void WINAPI WriteDoneFcn(PSWMRG SObject,PSCOUNTER SCounter=NULL);
+
+// WaitToReadFcn
+// is used to wait for read access with SWMRG SO, but it also increments counter if successfull
+// returns WAIT_FAILED or WAIT_FINISH
+// when WAIT_FAILED, we should not begin to access datas, we are not in read-access mode
+DWORD WINAPI WaitToReadFcn(PSWMRG SObject);
+
+// WriteDoneFcn
+// is used to release read access with SWMRG SO, but it also decrements counter if successfull
+void WINAPI ReadDoneFcn(PSWMRG SObject);
+
+// This functions is for export purposes
+// Plugin can call this function to manage SCOUNTER synchronization object
+
+// Gets number value stored in SCOUNTER SO
+// Note you must not read the number from memory directly, because
+// CPU can stop reading thread when it has read HI-Word, then another thread
+// can change the value and then OS starts the previous thread, that reads the
+// LO-WORD of DWORD. And the return value HI+LO-WORD is corrupted
+DWORD WINAPI SCGetNumberFcn(PSCOUNTER SCounter);
+
+// Increments SCOUNTER and unsets event
+// Returns Number after incrementing
+DWORD WINAPI SCIncFcn(PSCOUNTER SCounter);
+
+// Decrements SCOUNTER and sets event if zero
+// Returns Number after decrementing
+DWORD WINAPI SCDecFcn(PSCOUNTER SCounter);
+
+struct CExportedFunctions SynchroExportedFcn[]=
+{
+ {YAMN_WAITTOWRITEID,(void *)WaitToWriteFcn},
+ {YAMN_WRITEDONEID,(void *)WriteDoneFcn},
+ {YAMN_WAITTOREADID,(void *)WaitToReadFcn},
+ {YAMN_READDONEID,(void *)ReadDoneFcn},
+ {YAMN_SCGETNUMBERID,(void *)SCGetNumberFcn},
+ {YAMN_SCINCID,(void *)SCIncFcn},
+ {YAMN_SCDECID,(void *)SCDecFcn},
+};
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+void WINAPI SWMRGDelete(PSWMRG pSWMRG)
+{
+// Destroys any synchronization objects that were
+// successfully created.
+ if (NULL!=pSWMRG->hEventNoWriter)
+ CloseHandle(pSWMRG->hEventNoWriter);
+ if (NULL!=pSWMRG->hEventNoReaders)
+ CloseHandle(pSWMRG->hEventNoReaders);
+ if (NULL!=pSWMRG->hSemNumReaders)
+ CloseHandle(pSWMRG->hSemNumReaders);
+ if (NULL!=pSWMRG->hFinishEV)
+ CloseHandle(pSWMRG->hFinishEV);
+}
+
+BOOL WINAPI SWMRGInitialize(PSWMRG pSWMRG,TCHAR *Name)
+{
+ pSWMRG->hEventNoWriter=NULL;
+ pSWMRG->hEventNoReaders=NULL;
+ pSWMRG->hSemNumReaders=NULL;
+ pSWMRG->hFinishEV=NULL;
+
+// Creates the automatic-reset event that is signalled when
+// no writer threads are writing.
+// Initially no reader threads are reading.
+ if(Name!=NULL)
+ Name[0]=(TCHAR)'W';
+ pSWMRG->hEventNoWriter=CreateEvent(NULL,FALSE,TRUE,Name);
+
+// Creates the manual-reset event that is signalled when
+// no reader threads are reading.
+// Initially no reader threads are reading.
+ if(Name!=NULL)
+ Name[0]=(TCHAR)'R';
+ pSWMRG->hEventNoReaders=CreateEvent(NULL,TRUE,TRUE,Name);
+
+// Initializes the variable that indicates the number of
+// reader threads that are reading.
+// Initially no reader threads are reading.
+ if(Name!=NULL)
+ Name[0]=(TCHAR)'C';
+ pSWMRG->hSemNumReaders=CreateSemaphore(NULL,0,0x7FFFFFFF,Name);
+
+ if(Name!=NULL)
+ Name[0]=(TCHAR)'F';
+ pSWMRG->hFinishEV=CreateEvent(NULL,TRUE,FALSE,Name);
+
+// If a synchronization object could not be created,
+// destroys any created objects and return failure.
+ if((NULL==pSWMRG->hEventNoWriter) || (NULL==pSWMRG->hEventNoReaders) || (NULL==pSWMRG->hSemNumReaders) || (NULL==pSWMRG->hFinishEV))
+ {
+ SWMRGDelete(pSWMRG);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+DWORD WINAPI SWMRGWaitToWrite(PSWMRG pSWMRG,DWORD dwTimeout)
+{
+ DWORD dw;
+ HANDLE aHandles[2];
+
+// We can write if the following are true:
+// 1. No other threads are writing.
+// 2. No threads are reading.
+// But first we have to know if SWMRG structure is not about to delete
+ aHandles[0]=pSWMRG->hEventNoWriter;
+ aHandles[1]=pSWMRG->hEventNoReaders;
+ if(WAIT_OBJECT_0==(dw=WaitForSingleObject(pSWMRG->hFinishEV,0)))
+ return WAIT_FINISH;
+ if(WAIT_FAILED==dw)
+ return dw;
+ dw=WaitForMultipleObjects(2,aHandles,TRUE,dwTimeout);
+// if a request to delete became later, we should not catch it. Try once more to ask if account is not about to delete
+ if((dw!=WAIT_FAILED) && (WAIT_OBJECT_0==(WaitForSingleObject(pSWMRG->hFinishEV,0))))
+ {
+ SetEvent(pSWMRG->hEventNoWriter);
+ return WAIT_FINISH;
+ }
+
+// This thread can write to the shared data.
+// Automatic event for NoWriter sets hEventNoWriter to nonsignaled after WaitForMultipleObject
+
+// Because a writer thread is writing, the Event
+// should not be reset. This stops other
+// writers and readers.
+ return dw;
+}
+
+void WINAPI SWMRGDoneWriting(PSWMRG pSWMRG)
+// Presumably, a writer thread calling this function has
+// successfully called WaitToWrite. This means that we
+// do not have to wait on any synchronization objects
+// here because the writer already owns the Event.
+{
+// Allow other writer/reader threads to use
+// the SWMRG synchronization object.
+ SetEvent(pSWMRG->hEventNoWriter);
+}
+
+DWORD WINAPI SWMRGWaitToRead(PSWMRG pSWMRG, DWORD dwTimeout)
+{
+ DWORD dw;
+ LONG lPreviousCount;
+
+// We can read if no threads are writing.
+// And there's not request to delete structure
+ if(WAIT_OBJECT_0==(dw=WaitForSingleObject(pSWMRG->hFinishEV,0)))
+ return WAIT_FINISH;
+ if(WAIT_FAILED==dw)
+ return dw;
+ dw=WaitForSingleObject(pSWMRG->hEventNoWriter, dwTimeout);
+// if a request to delete became later, we should not catch it. Try once more to ask if account is not about to delete
+ if((dw!=WAIT_FAILED) && (WAIT_OBJECT_0==(WaitForSingleObject(pSWMRG->hFinishEV,0))))
+ {
+ SetEvent(pSWMRG->hEventNoWriter);
+ return WAIT_FINISH;
+ }
+
+ if(dw==WAIT_OBJECT_0)
+ {
+ // This thread can read from the shared data.
+ // Increment the number of reader threads.
+ // But there can't be more than one thread incrementing readers,
+ // so this is why we use semaphore.
+ ReleaseSemaphore(pSWMRG->hSemNumReaders,1,&lPreviousCount);
+ if(lPreviousCount==0)
+ // If this is the first reader thread,
+ // set event to reflect this. Other reader threads can read, no writer thread can write.
+ ResetEvent(pSWMRG->hEventNoReaders);
+
+ // Allow other writer/reader threads to use
+ // the SWMRG synchronization object. hEventNoWrite is still non-signaled
+ // (it looks like writer is processing thread, but it is not true)
+ SetEvent(pSWMRG->hEventNoWriter);
+ }
+
+ return(dw);
+}
+
+void WINAPI SWMRGDoneReading(PSWMRG pSWMRG)
+{
+ HANDLE aHandles[2];
+ LONG lNumReaders;
+
+// We can stop reading if the events are available,
+// but when we stop reading we must also decrement the
+// number of reader threads.
+ aHandles[0]=pSWMRG->hEventNoWriter;
+ aHandles[1]=pSWMRG->hSemNumReaders;
+ WaitForMultipleObjects(2,aHandles,TRUE,INFINITE);
+
+// Get the remaining number of readers by releasing the
+// semaphore and then restoring the count by immediately
+// performing a wait.
+ ReleaseSemaphore(pSWMRG->hSemNumReaders,1,&lNumReaders);
+ WaitForSingleObject(pSWMRG->hSemNumReaders,INFINITE);
+
+// If there are no remaining readers,
+// set the event to relect this.
+ if(lNumReaders==0)
+ // If there are no reader threads,
+ // set our event to reflect this.
+ SetEvent(pSWMRG->hEventNoReaders);
+
+// Allow other writer/reader threads to use
+// the SWMRG synchronization object.
+// (it looks like writer is processing thread, but it is not true)
+ SetEvent(pSWMRG->hEventNoWriter);
+}
+
+DWORD WINAPI WaitToWriteFcn(PSWMRG SObject,PSCOUNTER SCounter)
+{
+ DWORD EnterCode;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tSO WaitToWrite: %x\n",SObject);
+#endif
+ if(WAIT_OBJECT_0==(EnterCode=SWMRGWaitToWrite(SObject,INFINITE)))
+ if(SCounter!=NULL)
+ SCIncFcn(SCounter);
+ return EnterCode;
+}
+
+void WINAPI WriteDoneFcn(PSWMRG SObject,PSCOUNTER SCounter)
+{
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tSO WriteDone: %x\n",SObject);
+#endif
+ SWMRGDoneWriting(SObject);
+ if(SCounter!=NULL)
+ SCDecFcn(SCounter);
+}
+
+DWORD WINAPI WaitToReadFcn(PSWMRG SObject)
+{
+ DWORD EnterCode;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tSO WaitToRead: %x\n",SObject);
+#endif
+ EnterCode=SWMRGWaitToRead(SObject,INFINITE);
+ return EnterCode;
+}
+
+void WINAPI ReadDoneFcn(PSWMRG SObject)
+{
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tSO ReadDone: %x\n",SObject);
+#endif
+ SWMRGDoneReading(SObject);
+}
+
+DWORD WINAPI SCGetNumberFcn(PSCOUNTER SCounter)
+{
+ DWORD Temp;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tGetNumber-cs wait\n");
+#endif
+ EnterCriticalSection(&SCounter->CounterCS);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tGetNumber-cs enter\n");
+#endif
+ Temp=SCounter->Number;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tValue: %d\n",Temp);
+ DebugLog(SynchroFile,"\tGetNumber-cs done\n");
+#endif
+ LeaveCriticalSection(&SCounter->CounterCS);
+ return Temp;
+}
+
+DWORD WINAPI SCIncFcn(PSCOUNTER SCounter)
+{
+ DWORD Temp;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tIncrementValue-cs wait\n");
+#endif
+ EnterCriticalSection(&SCounter->CounterCS);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tIncrementValue-cs enter\n");
+#endif
+ Temp=++SCounter->Number;
+ ResetEvent(SCounter->Event);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tValue: %d\n",Temp);
+ DebugLog(SynchroFile,"\tIncrementValue-cs done\n");
+#endif
+ LeaveCriticalSection(&SCounter->CounterCS);
+ return Temp;
+}
+
+DWORD WINAPI SCDecFcn(PSCOUNTER SCounter)
+{
+ DWORD Temp;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tDecrementValue-cs wait\n");
+#endif
+ EnterCriticalSection(&SCounter->CounterCS);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tDecrementValue-cs enter\n");
+#endif
+ if(!(Temp=--SCounter->Number))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tDecrementValue-zero ev set\n");
+#endif
+ SetEvent(SCounter->Event);
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"\tValue: %d\n",Temp);
+ DebugLog(SynchroFile,"\tDecrementValue-cs done\n");
+#endif
+ LeaveCriticalSection(&SCounter->CounterCS);
+ return Temp;
+}
diff --git a/yamn/version.h b/yamn/version.h new file mode 100644 index 0000000..e658cfe --- /dev/null +++ b/yamn/version.h @@ -0,0 +1,3 @@ +#define YAMN_VERSION_H 0,1,2,5
+#define YAMN_VERSION PLUGIN_MAKE_VERSION( 0,1,2,5 )
+#define YAMN_VERSION_C "0.1.2.5"
diff --git a/yamn/yamn.cpp b/yamn/yamn.cpp new file mode 100644 index 0000000..467f3d6 --- /dev/null +++ b/yamn/yamn.cpp @@ -0,0 +1,478 @@ +/*
+ * This code implements miscellaneous usefull functions
+ *
+ * (c) majvan 2002-2004
+ */
+#include "m_yamn.h"
+#include "m_protoplugin.h"
+#include "m_messages.h"
+#include "m_synchro.h"
+#include "main.h"
+#include "yamn.h"
+#ifdef DEBUG_SYNCHRO
+ #include <stdio.h>
+#endif
+
+//- imported ---------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+extern PYAMN_PROTOPLUGINQUEUE FirstProtoPlugin;
+extern YAMN_VARIABLES YAMNVar;
+
+extern char *ProtoName;
+
+extern HANDLE hTTButton; //TopToolBar button
+
+extern DWORD WriteAccountsToFile();
+extern DWORD WINAPI SWMRGWaitToRead(PSWMRG,DWORD);
+extern void WINAPI SWMRGDoneReading(PSWMRG);
+extern DWORD WINAPI WaitToReadFcn(PSWMRG);
+extern void WINAPI ReadDoneFcn(PSWMRG);
+
+//From protoplugin.cpp
+extern struct CExportedFunctions ProtoPluginExportedFcn[1];
+extern struct CExportedServices ProtoPluginExportedSvc[5];
+//From filterplugin.cpp
+extern struct CExportedFunctions FilterPluginExportedFcn[1];
+extern struct CExportedServices FilterPluginExportedSvc[2];
+//From synchro.cpp
+extern struct CExportedFunctions SynchroExportedFcn[7];
+//From account.cpp
+extern struct CExportedFunctions AccountExportedFcn[2];
+extern struct CExportedServices AccountExportedSvc[9];
+//From mails.cpp (MIME)
+extern struct CExportedFunctions MailExportedFcn[8];
+extern struct CExportedServices MailExportedSvc[5];
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+//MessageWndCS
+//We want to send messages to all windows in the queue
+//When we send messages, no other window can register itself to the queue for receiving messages
+LPCRITICAL_SECTION MessageWndCS;
+
+//Plugin registration CS
+//Used if we add (register) plugin to YAMN plugins and when we browse through registered plugins
+LPCRITICAL_SECTION PluginRegCS;
+
+//AccountWriterCS
+//We want to store number of writers of Accounts (number of Accounts used for writing)
+//If we want to read all accounts (for saving to file) immidiatelly, we have to wait until no account is changing (no thread writing to account)
+SCOUNTER *AccountWriterSO;
+
+//NoExitEV
+//Event that is signaled when there's a request to exit, so no new pop3 check should be performed
+HANDLE ExitEV;
+
+//WriteToFileEV
+//If this is signaled, write accounts to file is performed. Set this event if you want to actualize your accounts and messages
+HANDLE WriteToFileEV;
+
+//Returns pointer to YAMN exported function
+INT_PTR GetFcnPtrSvc(WPARAM wParam,LPARAM lParam);
+
+//Returns pointer to YAMN variables
+INT_PTR GetVariablesSvc(WPARAM wParam,LPARAM);
+
+// Thread running only to catch hotkeys
+DWORD WINAPI YAMNHotKeyThread(LPVOID Param);
+
+// Function every seconds decrements account counter of seconds and checks if they are 0
+// If yes, creates a POP3 thread to check account
+void CALLBACK TimerProc(HWND,UINT,UINT,DWORD);
+
+// Function called to check all accounts immidialtelly
+// no params
+INT_PTR ForceCheckSvc(WPARAM,LPARAM);
+
+//thread is running all the time
+//waits for WriteToFileEV and then writes all accounts to file
+//DWORD WINAPI FileWritingThread(PVOID);
+
+// Function is called when Miranda notifies plugin that it is about to exit
+// Ensures succesfull end of POP3 checking, sets event that no next checking should be performed
+// If there's no writer to account (POP3 thread), saves the results to the file
+//not used now, perhaps in the future
+
+
+//int ExitProc(WPARAM wParam,LPARAM lParam);
+
+//--------------------------------------------------------------------------------------------------
+//--------------------------------------------------------------------------------------------------
+
+INT_PTR GetFcnPtrSvc(WPARAM wParam,LPARAM lParam)
+{
+ register int i;
+
+ for(i=0;i<sizeof(ProtoPluginExportedFcn)/sizeof(ProtoPluginExportedFcn[0]);i++)
+ if(0==lstrcmp((char *)wParam,ProtoPluginExportedFcn[i].ID))
+ return (INT_PTR)ProtoPluginExportedFcn[i].Ptr;
+ for(i=0;i<sizeof(ProtoPluginExportedSvc)/sizeof(ProtoPluginExportedSvc[0]);i++)
+ if(0==lstrcmp((char *)wParam,ProtoPluginExportedSvc[i].ID))
+ return (INT_PTR)ProtoPluginExportedSvc[i].Ptr;
+ for(i=0;i<sizeof(SynchroExportedFcn)/sizeof(SynchroExportedFcn[0]);i++)
+ if(0==lstrcmp((char *)wParam,SynchroExportedFcn[i].ID))
+ return (INT_PTR)SynchroExportedFcn[i].Ptr;
+ for(i=0;i<sizeof(AccountExportedFcn)/sizeof(AccountExportedFcn[0]);i++)
+ if(0==lstrcmp((char *)wParam,AccountExportedFcn[i].ID))
+ return (INT_PTR)AccountExportedFcn[i].Ptr;
+ for(i=0;i<sizeof(AccountExportedSvc)/sizeof(AccountExportedSvc[0]);i++)
+ if(0==lstrcmp((char *)wParam,AccountExportedSvc[i].ID))
+ return (INT_PTR)AccountExportedSvc[i].Ptr;
+ for(i=0;i<sizeof(MailExportedFcn)/sizeof(MailExportedFcn[0]);i++)
+ if(0==lstrcmp((char *)wParam,MailExportedFcn[i].ID))
+ return (INT_PTR)MailExportedFcn[i].Ptr;
+ for(i=0;i<sizeof(MailExportedSvc)/sizeof(MailExportedSvc[0]);i++)
+ if(0==lstrcmp((char *)wParam,MailExportedSvc[i].ID))
+ return (INT_PTR)MailExportedSvc[i].Ptr;
+ for(i=0;i<sizeof(FilterPluginExportedFcn)/sizeof(FilterPluginExportedFcn[0]);i++)
+ if(0==lstrcmp((char *)wParam,FilterPluginExportedFcn[i].ID))
+ return (INT_PTR)FilterPluginExportedFcn[i].Ptr;
+ for(i=0;i<sizeof(FilterPluginExportedSvc)/sizeof(FilterPluginExportedSvc[0]);i++)
+ if(0==lstrcmp((char *)wParam,FilterPluginExportedSvc[i].ID))
+ return (INT_PTR)FilterPluginExportedSvc[i].Ptr;
+ return (INT_PTR)NULL;
+}
+
+INT_PTR GetVariablesSvc(WPARAM wParam,LPARAM)
+{
+ return wParam==YAMN_VARIABLESVERSION ? (INT_PTR)&YAMNVar : (INT_PTR)NULL;
+}
+
+DWORD WINAPI YAMNHotKeyThread(LPVOID Param)
+{
+ MSG WinMessage;
+ WORD HotKey = LOWORD(Param);
+ int HotKeyID;
+
+// register hotkey for main YAMN thread first
+ if(!(HotKeyID=RegisterHotKey(NULL,(int)GlobalAddAtom(YAMN_HKCHECKMAIL),HIBYTE(HotKey),LOBYTE(HotKey))))
+ return 0;
+
+ while(1)
+ {
+ GetMessage(&WinMessage,NULL,WM_HOTKEY,WM_YAMN_CHANGEHOTKEY);
+
+// if we want to close miranda, we get event and do not run pop3 checking anymore
+ if(WAIT_OBJECT_0==WaitForSingleObject(ExitEV,0))
+ break;
+
+ switch(WinMessage.message)
+ {
+// user pressed hotkey
+ case WM_HOTKEY:
+ ForceCheckSvc((WPARAM)0,(LPARAM)0);
+ break;
+// hotkey changed
+ case WM_YAMN_CHANGEHOTKEY:
+ UnregisterHotKey(NULL,HotKeyID);
+ HotKeyID=RegisterHotKey(NULL,(int)GlobalAddAtom(YAMN_HKCHECKMAIL),WinMessage.wParam,WinMessage.lParam);
+ break;
+ }
+ }
+ return 1;
+}
+
+void CALLBACK TimerProc(HWND,UINT,UINT,DWORD)
+{
+ PYAMN_PROTOPLUGINQUEUE ActualPlugin;
+ HACCOUNT ActualAccount;
+ HANDLE ThreadRunningEV;
+ DWORD Status,tid;
+
+// we use event to signal, that running thread has all needed stack parameters copied
+ if(NULL==(ThreadRunningEV=CreateEvent(NULL,FALSE,FALSE,NULL)))
+ return;
+// if we want to close miranda, we get event and do not run checking anymore
+ if(WAIT_OBJECT_0==WaitForSingleObject(ExitEV,0))
+ return;
+// Get actual status of current user in Miranda
+ Status=CallService(MS_CLIST_GETSTATUSMODE,0,0);
+
+ EnterCriticalSection(PluginRegCS);
+ for(ActualPlugin=FirstProtoPlugin;ActualPlugin!=NULL;ActualPlugin=ActualPlugin->Next)
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"TimerProc:AccountBrowserSO-read wait\n");
+#endif
+ if(WAIT_OBJECT_0!=SWMRGWaitToRead(ActualPlugin->Plugin->AccountBrowserSO,0)) //we want to access accounts immiadtelly
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"TimerProc:AccountBrowserSO-read enter failed\n");
+#endif
+ LeaveCriticalSection(PluginRegCS);
+ return;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"TimerProc:AccountBrowserSO-read enter\n");
+#endif
+ for(ActualAccount=ActualPlugin->Plugin->FirstAccount;ActualAccount!=NULL;ActualAccount=ActualAccount->Next)
+ {
+ if(ActualAccount->Plugin==NULL || ActualAccount->Plugin->Fcn==NULL) //account not inited
+ continue;
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read wait\n");
+#endif
+ if(WAIT_OBJECT_0!=SWMRGWaitToRead(ActualAccount->AccountAccessSO,0))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read wait failed\n");
+#endif
+ continue;
+ }
+#ifdef DEBUG_SYNCHRO
+
+ switch(Status)
+ {
+ case ID_STATUS_OFFLINE:
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read enter status offline\n");
+ break;
+ case ID_STATUS_ONLINE:
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read enter status online\n");
+ break;
+ case ID_STATUS_AWAY:
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read enter status away\n");
+ break;
+ case ID_STATUS_DND:
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read enter status dnd\n");
+ break;
+ case ID_STATUS_NA:
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read enter status na\n");
+ break;
+ case ID_STATUS_OCCUPIED:
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read enter status occupied\n");
+ break;
+ case ID_STATUS_FREECHAT:
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read enter status freechat\n");
+ break;
+ case ID_STATUS_INVISIBLE:
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read enter status invisible\n");
+ break;
+ case ID_STATUS_ONTHEPHONE:
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read enter status onthephone\n");
+ break;
+ case ID_STATUS_OUTTOLUNCH:
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read enter status outtolunch\n");
+ break;
+ default:
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read enter status unknown\n");
+ break;
+ }
+#endif
+ BOOL isAccountCounting = 0;
+ if(
+ (ActualAccount->Flags & YAMN_ACC_ENA) &&
+ (((ActualAccount->StatusFlags & YAMN_ACC_ST0) && (Status<=ID_STATUS_OFFLINE)) ||
+ ((ActualAccount->StatusFlags & YAMN_ACC_ST1) && (Status==ID_STATUS_ONLINE)) ||
+ ((ActualAccount->StatusFlags & YAMN_ACC_ST2) && (Status==ID_STATUS_AWAY)) ||
+ ((ActualAccount->StatusFlags & YAMN_ACC_ST3) && (Status==ID_STATUS_DND)) ||
+ ((ActualAccount->StatusFlags & YAMN_ACC_ST4) && (Status==ID_STATUS_NA)) ||
+ ((ActualAccount->StatusFlags & YAMN_ACC_ST5) && (Status==ID_STATUS_OCCUPIED)) ||
+ ((ActualAccount->StatusFlags & YAMN_ACC_ST6) && (Status==ID_STATUS_FREECHAT)) ||
+ ((ActualAccount->StatusFlags & YAMN_ACC_ST7) && (Status==ID_STATUS_INVISIBLE)) ||
+ ((ActualAccount->StatusFlags & YAMN_ACC_ST8) && (Status==ID_STATUS_ONTHEPHONE)) ||
+ ((ActualAccount->StatusFlags & YAMN_ACC_ST9) && (Status==ID_STATUS_OUTTOLUNCH))))
+ {
+
+ if((!ActualAccount->Interval && !ActualAccount->TimeLeft) || ActualAccount->Plugin->Fcn->TimeoutFcnPtr==NULL)
+ {
+ goto ChangeIsCountingStatusLabel;
+ }
+ if(ActualAccount->TimeLeft){
+ ActualAccount->TimeLeft--;
+ isAccountCounting = TRUE;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"TimerProc:time left : %i\n",ActualAccount->TimeLeft);
+#endif
+ WindowList_BroadcastAsync(YAMNVar.MessageWnds,WM_YAMN_CHANGETIME,(WPARAM)ActualAccount,(LPARAM)ActualAccount->TimeLeft);
+ if(!ActualAccount->TimeLeft)
+ {
+ struct CheckParam ParamToPlugin={YAMN_CHECKVERSION,ThreadRunningEV,ActualAccount,YAMN_NORMALCHECK,(void *)0,NULL};
+ HANDLE NewThread;
+
+ ActualAccount->TimeLeft=ActualAccount->Interval;
+ if(NULL==(NewThread=CreateThread(NULL,0,(YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->TimeoutFcnPtr,&ParamToPlugin,0,&tid)))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read done\n");
+#endif
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ continue;
+ }
+ else
+ {
+ WaitForSingleObject(ThreadRunningEV,INFINITE);
+ CloseHandle(NewThread);
+ }
+ }
+
+ }
+ChangeIsCountingStatusLabel:
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"TimerProc:ActualAccountSO-read done\n");
+#endif
+ if (((ActualAccount->isCounting)!=0)!=isAccountCounting){
+ ActualAccount->isCounting=isAccountCounting;
+ WORD cStatus = DBGetContactSettingWord(ActualAccount->hContact,ProtoName,"Status",0);
+ switch (cStatus){
+ case ID_STATUS_ONLINE:
+ case ID_STATUS_OFFLINE:
+ DBWriteContactSettingWord(ActualAccount->hContact, ProtoName, "Status", isAccountCounting?ID_STATUS_ONLINE:ID_STATUS_OFFLINE);
+ default: break;
+ }
+ }
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"TimerProc:AccountBrowserSO-read done\n");
+#endif
+ SWMRGDoneReading(ActualPlugin->Plugin->AccountBrowserSO);
+ }
+ LeaveCriticalSection(PluginRegCS);
+ CloseHandle(ThreadRunningEV);
+ return;
+}
+
+INT_PTR ForceCheckSvc(WPARAM,LPARAM)
+{
+ PYAMN_PROTOPLUGINQUEUE ActualPlugin;
+ HACCOUNT ActualAccount;
+ HANDLE ThreadRunningEV;
+ DWORD tid;
+
+ //we use event to signal, that running thread has all needed stack parameters copied
+ if(NULL==(ThreadRunningEV=CreateEvent(NULL,FALSE,FALSE,NULL)))
+ return 0;
+ //if we want to close miranda, we get event and do not run pop3 checking anymore
+ if(WAIT_OBJECT_0==WaitForSingleObject(ExitEV,0))
+ return 0;
+ EnterCriticalSection(PluginRegCS);
+ for(ActualPlugin=FirstProtoPlugin;ActualPlugin!=NULL;ActualPlugin=ActualPlugin->Next)
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ForceCheck:AccountBrowserSO-read wait\n");
+ #endif
+ SWMRGWaitToRead(ActualPlugin->Plugin->AccountBrowserSO,INFINITE);
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ForceCheck:AccountBrowserSO-read enter\n");
+ #endif
+ for(ActualAccount=ActualPlugin->Plugin->FirstAccount;ActualAccount!=NULL;ActualAccount=ActualAccount->Next)
+ {
+ if(ActualAccount->Plugin->Fcn==NULL) //account not inited
+ continue;
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read wait\n");
+ #endif
+ if(WAIT_OBJECT_0!=WaitToReadFcn(ActualAccount->AccountAccessSO))
+ {
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read wait failed\n");
+ #endif
+ continue;
+ }
+ #ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ForceCheck:ActualAccountSO-read enter\n");
+ #endif
+ if((ActualAccount->Flags & YAMN_ACC_ENA) && (ActualAccount->StatusFlags & YAMN_ACC_FORCE)) //account cannot be forced to check
+ {
+ if(ActualAccount->Plugin->Fcn->ForceCheckFcnPtr==NULL)
+ {
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ continue;
+ }
+ struct CheckParam ParamToPlugin={YAMN_CHECKVERSION,ThreadRunningEV,ActualAccount,YAMN_FORCECHECK,(void *)0,NULL};
+
+ if(NULL==CreateThread(NULL,0,(YAMN_STANDARDFCN)ActualAccount->Plugin->Fcn->ForceCheckFcnPtr,&ParamToPlugin,0,&tid))
+ {
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ continue;
+ }
+ else
+ WaitForSingleObject(ThreadRunningEV,INFINITE);
+ }
+ ReadDoneFcn(ActualAccount->AccountAccessSO);
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ForceCheck:AccountBrowserSO-read done\n");
+#endif
+ SWMRGDoneReading(ActualPlugin->Plugin->AccountBrowserSO);
+ }
+ LeaveCriticalSection(PluginRegCS);
+ CloseHandle(ThreadRunningEV);
+ CallService(MS_TTB_SETBUTTONSTATE,(WPARAM)hTTButton,(LPARAM)TTBST_RELEASED);
+ return 1;
+}
+/*
+int ExitProc(WPARAM wParam,LPARAM lParam)
+{
+ THIS WILL BE IMPLEMENTED LATER
+// First, no thread must add or delete accounts. This is achieved by entering browsing through accounts
+// If any thread want to delete or add, it waits for write-access to browse accounts (so it waits infinite time)
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ExitProc:AccountBrowserSO-wait to obtain read access\n"));
+#endif
+ if(WAIT_TIMEOUT==SWMRGWaitToRead(AccountBrowserSO,0))
+ {
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ExitProc:AccountBrowserSO-read access obtain failed, I'll try later\n"));
+#endif
+ return 1;
+ }
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ExitProc:AccountBrowserSO-read access obtained\n"));
+#endif
+#ifdef DEBUG_SYNCHRO
+ TCHAR Debug[100];
+
+ _stprintf(Debug,_T("ExitProc:Writers: %d\n"),AccountWriterSO->GetNumber());
+ DEBUG_SYNCHRO2F(Debug);
+ DebugLog(SynchroFile,"ExitProc:NoWriterEV-test\n"));
+#endif
+// next, threads must not write to any account. This works like hFinishEV event in AccountAccessSO and MessagesAccessSO.
+// When hFinishEV is set, any beginning with reading and writing to account (messages) is failed.
+// This is similar, but the difference is, that we can finish the whole work (we can decide: if ExitEV is set, should we
+// end immidialtelly or should we continue (to end operation successfully)?
+// E.g. I decided that once we started checking account, we get all new mails and then we can end.
+// The second and more significant difference is, that ExitEV is signal to all accounts and messages, not only to one account.
+
+ SetEvent(ExitEV);
+ if(WAIT_TIMEOUT==WaitForSingleObject(AccountWriterSO->Event,0))
+ {
+// There exists a thread writing to account, so we ca try later to write accounts to file, if no thread is writting
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ExitProc:NoWriterEV-writer(s) exists, I'll try later\n"));
+#endif
+ SWMRGDoneReading(AccountBrowserSO);
+ return 1;
+ }
+
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"ExitProc:NoWriterEV-no writer, going to save!\n"));
+#endif
+// Save to file
+ WriteAccountsToFile();
+ SWMRGDoneReading(AccountBrowserSO);
+// Now, all is saved, we can safe exit from Miranda
+ return 0;
+}
+*/
+/*
+DWORD WINAPI FileWritingThread(PVOID)
+{
+ HACCOUNT ActualAccount=FirstAccount;
+
+ while(1)
+ {
+ WaitForSingleObject(WriteToFileEV,INFINITE);
+#ifdef DEBUG_SYNCHRO
+ DebugLog(SynchroFile,"FileWriting:WriteToFileEV-signaled\n"));
+#endif
+// now, write accounts and messages if it is possible. If it is not possible e.g. to read messages from one account,
+// function will wait until messages are not used and then writes messages
+ WriteAccountsToFile();
+ }
+ return 0;
+}
+*/
diff --git a/yamn/yamn.h b/yamn/yamn.h new file mode 100644 index 0000000..ee2fccb --- /dev/null +++ b/yamn/yamn.h @@ -0,0 +1,178 @@ +#ifndef __YAMN_H
+#define __YAMN_H
+#ifndef _WIN32_IE
+ #define _WIN32_IE 0x0400
+#endif
+#ifndef _WIN32_WINNT
+ #define _WIN32_WINNT 0x0501
+#endif
+
+#if !defined(_WIN64)
+ #include "filter/simple/AggressiveOptimize.h"
+#endif
+#include <wchar.h>
+#include <tchar.h>
+#include <windows.h>
+#include <stdio.h>
+#include <direct.h> //For _chdir()
+
+#define MIRANDA_VER 0x0600
+
+#include <commctrl.h> //For hotkeys
+#include "newpluginapi.h" //CallService,UnHookEvent
+#include "m_utils.h" //window broadcasting
+#include "m_system.h"
+#include "m_skin.h"
+#include "m_langpack.h"
+#include "m_clist.h"
+#include "m_clui.h"
+#include "m_options.h"
+#include "m_database.h" //database
+#include "m_contacts.h" //contact
+#include "m_protocols.h" //protocols
+#include "m_protomod.h" //protocols module
+#include "m_protosvc.h"
+#include "include/m_uninstaller.h" //PluginUninstaller structures
+#include "include/m_toptoolbar.h"
+#include "m_icolib.h"
+#include "include/m_kbdnotify.h"
+#include "m_popup.h"
+#include "include/m_updater.h"
+#include "m_account.h" //Account structure and all needed structures to cooperate with YAMN
+#include "m_messages.h" //Messages sent to YAMN windows
+#include "mails/m_mails.h" //use YAMN's mails
+#include "mails/m_decode.h" //use decoding macros (needed for header extracting)
+#include "browser/m_browser.h" //we want to run YAMN mailbrowser, no new mail notification and bad connect window
+#include "resources/resource.h"
+#include "m_protoplugin.h"
+#include "m_filterplugin.h"
+#include "m_yamn.h" //Main YAMN's variables
+#include "m_protoplugin.h" //Protocol registration and so on
+#include "m_synchro.h" //Synchronization
+#include "debug.h"
+#include <m_folders.h>
+
+
+//icons definitions
+#define ICONSNUMBER 8
+#define ICONSDESCS "Neutral","YAMN","New Mail","Connect Fail","Launch Application","TopToolBar UP","TopToolBar Down","Offline"
+#define ICONSNAMES "YAMN_Neutral",iconDescs[1],"YAMN_NewMail","YAMN_ConnectFail","YAMN_ApplExec","YAMN_TopToolBarUp","YAMN_TopToolBarDown","YAMN_Offline"
+#define ICONSINDS IDI_ONLINE,IDI_ICOYAMN1,IDI_ICOYAMN2,IDI_NA,IDI_OCCUPIED,IDI_ICOTTBUP,IDI_OCCUPIED,IDI_OFFLINE
+
+//From services.cpp
+void CreateServiceFunctions(void);
+void DestroyServiceFunctions(void);
+void HookEvents(void);
+void UnhookEvents(void);
+void RefreshContact(void);
+void ContactDoubleclicked(WPARAM wParam,LPARAM lParam);
+INT_PTR ClistContactDoubleclicked(WPARAM wParam, LPARAM lParam);
+
+//From debug.cpp
+#undef YAMN_DEBUG
+#ifdef YAMN_DEBUG
+void InitDebug();
+void UnInitDebug();
+#endif
+
+//From synchro.cpp
+//struct CExportedFunctions SynchroExported[];
+
+//From yamn.cpp
+INT_PTR GetFcnPtrSvc(WPARAM wParam,LPARAM lParam);
+INT_PTR GetVariablesSvc(WPARAM,LPARAM);
+//INT_PTR AddWndToYAMNWindowsSvc(WPARAM,LPARAM);
+//INT_PTR RemoveWndFromYAMNWindowsSvc(WPARAM,LPARAM);
+DWORD WINAPI YAMNHotKeyThread(LPVOID);
+void CALLBACK TimerProc(HWND,UINT,UINT,DWORD);
+INT_PTR ForceCheckSvc(WPARAM,LPARAM);
+// int ExitProc(WPARAM,LPARAM);
+
+//From account.cpp
+//struct CExportedFunctions AccountExported[];
+INT_PTR CreatePluginAccountSvc(WPARAM wParam,LPARAM lParam);
+INT_PTR DeletePluginAccountSvc(WPARAM wParam,LPARAM lParam);
+INT_PTR WriteAccountsToFileASvc(WPARAM wParam,LPARAM lParam);
+INT_PTR WriteAccountsToFileWSvc(WPARAM wParam,LPARAM lParam);
+INT_PTR AddAccountsFromFileASvc(WPARAM,LPARAM);
+INT_PTR AddAccountsFromFileWSvc(WPARAM,LPARAM);
+INT_PTR DeleteAccountSvc(WPARAM,LPARAM);
+INT_PTR FindAccountByNameSvc(WPARAM wParam,LPARAM lParam);
+INT_PTR GetNextFreeAccountSvc(WPARAM wParam,LPARAM lParam);
+
+//From protoplugin.cpp
+//struct CExportedFunctions ProtoPluginExported[];
+INT_PTR UnregisterProtoPlugins();
+INT_PTR RegisterProtocolPluginSvc(WPARAM,LPARAM);
+INT_PTR UnregisterProtocolPluginSvc(WPARAM,LPARAM);
+INT_PTR GetFileNameWSvc(WPARAM,LPARAM);
+INT_PTR GetFileNameASvc(WPARAM,LPARAM);
+INT_PTR DeleteFileNameSvc(WPARAM,LPARAM);
+
+//From filterplugin.cpp
+//struct CExportedFunctions FilterPluginExported[];
+INT_PTR UnregisterFilterPlugins();
+INT_PTR RegisterFilterPluginSvc(WPARAM,LPARAM);
+INT_PTR UnregisterFilterPluginSvc(WPARAM,LPARAM);
+INT_PTR FilterMailSvc(WPARAM,LPARAM);
+
+//From mails.cpp (MIME)
+//struct CExportedFunctions MailExported[];
+INT_PTR CreateAccountMailSvc(WPARAM wParam,LPARAM lParam);
+INT_PTR DeleteAccountMailSvc(WPARAM wParam,LPARAM lParam);
+INT_PTR LoadMailDataSvc(WPARAM wParam,LPARAM lParam);
+INT_PTR UnloadMailDataSvc(WPARAM wParam,LPARAM);
+INT_PTR SaveMailDataSvc(WPARAM wParam,LPARAM lParam);
+
+//From mime.cpp
+//void WINAPI ExtractHeaderFcn(char *,int,WORD,HYAMNMAIL); //already in MailExported
+struct _tcptable
+{
+ char *NameBase,*NameSub;
+ BOOLEAN isValid;
+ unsigned short int CP;
+};
+extern struct _tcptable CodePageNamesAll[]; // in mime/decode.cpp
+extern int CPLENALL;
+extern struct _tcptable *CodePageNamesSupp; // in mime/decode.cpp
+extern int CPLENSUPP;
+//#define CPDEFINDEX 63 //ISO-8859-1
+#define CPDEFINDEX 0 //ACP
+
+//From pop3comm.cpp
+int RegisterPOP3Plugin(WPARAM,LPARAM);
+int UninstallPOP3(PLUGINUNINSTALLPARAMS* ppup); //to uninstall POP3 plugin with YAMN
+
+//From mailbrowser.cpp
+INT_PTR RunMailBrowserSvc(WPARAM,LPARAM);
+
+//From badconnect.cpp
+INT_PTR RunBadConnectionSvc(WPARAM,LPARAM);
+
+//From YAMNopts.cpp
+void WordToModAndVk(WORD,UINT *,UINT *);
+int YAMNOptInitSvc(WPARAM,LPARAM);
+
+//From main.cpp
+int PostLoad(WPARAM,LPARAM); //Executed after all plugins loaded YAMN reads mails from file and notify every protocol it should set its functions
+int Shutdown(WPARAM,LPARAM); //Executed before Miranda is going to shutdown
+int AddTopToolbarIcon(WPARAM,LPARAM); //Executed when TopToolBar plugin loaded Adds bitmap to toolbar
+void LoadPlugins(); //Loads plugins located in MirandaDir/Plugins/YAMN/*.dll
+int UninstallQuestionSvc(WPARAM,LPARAM); //Ask information when user wants to uninstall plugin
+
+//From synchro.cpp
+extern DWORD WINAPI WaitToWriteFcn(PSWMRG SObject,PSCOUNTER SCounter=NULL);
+extern void WINAPI WriteDoneFcn(PSWMRG SObject,PSCOUNTER SCounter=NULL);
+extern DWORD WINAPI WaitToReadFcn(PSWMRG SObject);
+extern void WINAPI ReadDoneFcn(PSWMRG SObject);
+extern DWORD WINAPI SCIncFcn(PSCOUNTER SCounter);
+extern DWORD WINAPI SCDecFcn(PSCOUNTER SCounter);
+//From mails.cpp
+extern void WINAPI DeleteMessageFromQueueFcn(HYAMNMAIL *From,HYAMNMAIL Which,int mode);
+extern void WINAPI SetRemoveFlagsInQueueFcn(HYAMNMAIL From,DWORD FlagsSet,DWORD FlagsNotSet,DWORD FlagsToSet,int mode);
+//From mime.cpp
+void ExtractHeader(struct CMimeItem *items,int &CP,struct CHeader *head);
+void DeleteHeaderContent(struct CHeader *head);
+//From account.cpp
+void WINAPI GetStatusFcn(HACCOUNT Which,char *Value);
+#endif
|