summaryrefslogtreecommitdiff
path: root/plugins/!NotAdopted/WinPopup
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/!NotAdopted/WinPopup')
-rw-r--r--plugins/!NotAdopted/WinPopup/add_dialog.cpp74
-rw-r--r--plugins/!NotAdopted/WinPopup/add_dialog.h25
-rw-r--r--plugins/!NotAdopted/WinPopup/chat.cpp337
-rw-r--r--plugins/!NotAdopted/WinPopup/chat.h44
-rw-r--r--plugins/!NotAdopted/WinPopup/dllLoaderMinimal.h338
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/add.icobin0 -> 1406 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/away.icobin0 -> 2550 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/bad_name.icobin0 -> 1406 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/bad_names.icobin0 -> 1406 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/computer.icobin0 -> 1406 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/computer_error.icobin0 -> 1406 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/dnd.icobin0 -> 2550 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/explore.icobin0 -> 1406 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/freechat.icobin0 -> 2550 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/good_name.icobin0 -> 1406 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/good_names.icobin0 -> 1406 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/invisible.icobin0 -> 2550 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/lana.icobin0 -> 1406 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/na.icobin0 -> 2550 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/occupied.icobin0 -> 2550 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/offline.icobin0 -> 2550 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/online.icobin0 -> 2550 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/onthephone.icobin0 -> 2550 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/other_name.icobin0 -> 1406 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/other_names.icobin0 -> 1406 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/outtolunch.icobin0 -> 2550 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/overlay/away.icobin0 -> 1150 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/overlay/dnd.icobin0 -> 1150 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/overlay/freechat.icobin0 -> 1150 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/overlay/invisible.icobin0 -> 1150 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/overlay/na.icobin0 -> 1150 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/overlay/occupied.icobin0 -> 1150 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/overlay/onphone.icobin0 -> 1150 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/overlay/outtolunch.icobin0 -> 1150 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/icons/winpopup_proto.icobin0 -> 9062 bytes
-rw-r--r--plugins/!NotAdopted/WinPopup/m_uninstaller.h703
-rw-r--r--plugins/!NotAdopted/WinPopup/m_updater.h117
-rw-r--r--plugins/!NotAdopted/WinPopup/mailslot.cpp313
-rw-r--r--plugins/!NotAdopted/WinPopup/mailslot.h48
-rw-r--r--plugins/!NotAdopted/WinPopup/md5.h222
-rw-r--r--plugins/!NotAdopted/WinPopup/messagebox.cpp232
-rw-r--r--plugins/!NotAdopted/WinPopup/messagebox.h29
-rw-r--r--plugins/!NotAdopted/WinPopup/messenger.cpp469
-rw-r--r--plugins/!NotAdopted/WinPopup/messenger.h54
-rw-r--r--plugins/!NotAdopted/WinPopup/netbios.cpp1065
-rw-r--r--plugins/!NotAdopted/WinPopup/netbios.h134
-rw-r--r--plugins/!NotAdopted/WinPopup/netbios_name.cpp640
-rw-r--r--plugins/!NotAdopted/WinPopup/netbios_name.h157
-rw-r--r--plugins/!NotAdopted/WinPopup/network.cpp88
-rw-r--r--plugins/!NotAdopted/WinPopup/network.h31
-rw-r--r--plugins/!NotAdopted/WinPopup/options.cpp392
-rw-r--r--plugins/!NotAdopted/WinPopup/options.h24
-rw-r--r--plugins/!NotAdopted/WinPopup/processapi.cpp578
-rw-r--r--plugins/!NotAdopted/WinPopup/processapi.h264
-rw-r--r--plugins/!NotAdopted/WinPopup/resource.h66
-rw-r--r--plugins/!NotAdopted/WinPopup/scanner.cpp218
-rw-r--r--plugins/!NotAdopted/WinPopup/scanner.h49
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_avatars.h359
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_chat.h685
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_clist.h637
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_database.h1199
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_langpack.h114
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_netlib.h832
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_options.h138
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_plugins.h85
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_popup.h424
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_protocols.h487
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_protomod.h136
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_protosvc.h775
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_system.h631
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_userinfo.h76
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/m_utils.h573
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/newpluginapi.h291
-rw-r--r--plugins/!NotAdopted/WinPopup/sdk/statusmodes.h52
-rw-r--r--plugins/!NotAdopted/WinPopup/search.cpp330
-rw-r--r--plugins/!NotAdopted/WinPopup/search.h60
-rw-r--r--plugins/!NotAdopted/WinPopup/services.cpp1003
-rw-r--r--plugins/!NotAdopted/WinPopup/services.h36
-rw-r--r--plugins/!NotAdopted/WinPopup/smbconst.h108
-rw-r--r--plugins/!NotAdopted/WinPopup/stdafx.cpp22
-rw-r--r--plugins/!NotAdopted/WinPopup/stdafx.h136
-rw-r--r--plugins/!NotAdopted/WinPopup/user_info.cpp334
-rw-r--r--plugins/!NotAdopted/WinPopup/user_info.h24
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto.cpp1217
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto.def27
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto.h322
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto.rc251
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto_7.sln21
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto_7.vcproj406
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto_9.icproj37
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto_9.sln28
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto_9.vcproj773
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto_pack.cmd6
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto_readme.txt245
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto_todo.txt9
-rw-r--r--plugins/!NotAdopted/WinPopup/winpopup_proto_translation.txt43
96 files changed, 19643 insertions, 0 deletions
diff --git a/plugins/!NotAdopted/WinPopup/add_dialog.cpp b/plugins/!NotAdopted/WinPopup/add_dialog.cpp
new file mode 100644
index 0000000000..3312c73385
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/add_dialog.cpp
@@ -0,0 +1,74 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2010 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "winpopup_proto.h"
+#include "add_dialog.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+static INT_PTR CALLBACK DlgProcAddContact(HWND hwndDlg, UINT Msg,
+ WPARAM wParam, LPARAM /*lParam*/)
+{
+ switch ( Msg )
+ {
+ case WM_INITDIALOG:
+ TranslateDialogDefault( hwndDlg );
+ return TRUE;
+
+ case WM_COMMAND:
+ switch ( LOWORD( wParam ) )
+ {
+ case IDOK:
+ {
+ bool bGroup = IsDlgButtonChecked( hwndDlg, IDC_GROUP ) == BST_CHECKED;
+ CString sName;
+ GetDlgItemText( hwndDlg, IDC_NAME, sName.GetBuffer( 128 ), 127 );
+ sName.ReleaseBuffer();
+ sName.Trim();
+ if ( ! sName.IsEmpty() )
+ {
+ HCURSOR hCurrent = SetCursor( LoadCursor( NULL, IDC_WAIT ) );
+ HANDLE hContact = AddToListByName( sName, 0, NULL, true, bGroup );
+ SetCursor( hCurrent );
+ if ( hContact )
+ EndDialog( hwndDlg, IDOK );
+ }
+ }
+ return TRUE;
+
+ case IDCANCEL:
+ EndDialog( hwndDlg, IDCANCEL );
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+void AddDialog(HWND hParentWnd)
+{
+ DialogBox( pluginModule, MAKEINTRESOURCE( IDD_ADD ), hParentWnd, DlgProcAddContact );
+}
diff --git a/plugins/!NotAdopted/WinPopup/add_dialog.h b/plugins/!NotAdopted/WinPopup/add_dialog.h
new file mode 100644
index 0000000000..16f0245eb8
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/add_dialog.h
@@ -0,0 +1,25 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2009 Nikolay Raspopov
+
+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
+
+// /
+void AddDialog(HWND hParentWnd);
diff --git a/plugins/!NotAdopted/WinPopup/chat.cpp b/plugins/!NotAdopted/WinPopup/chat.cpp
new file mode 100644
index 0000000000..4572bb10ac
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/chat.cpp
@@ -0,0 +1,337 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2008-2010 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "winpopup_proto.h"
+#include "chat.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+#ifdef CHAT_ENABLED
+
+HANDLE plugin_CHAT_EVENT = NULL;
+
+static int __cdecl CHAT_EVENT(WPARAM /* wParam */, LPARAM lParam)
+{
+ GCHOOK* pgch = (GCHOOK*)lParam;
+ switch ( pgch->pDest->iType )
+ {
+ case GC_USER_MESSAGE:
+ {
+ //
+ ChatMessage( pgch->pDest->ptszID, pgch->ptszText );
+
+ //
+ DWORD dwLastError = 0;
+ SendMessage( pgch->pDest->ptszID, pgch->ptszText, dwLastError );
+ }
+ break;
+ }
+
+ return 0;
+}
+
+bool ChatRegister()
+{
+ GCREGISTER gcr =
+ {
+ sizeof( GCREGISTER ),
+ 0,
+ modname,
+ modname,
+ 0,
+ 0,
+ NULL
+ };
+ int result = CallServiceSync( MS_GC_REGISTER, 0, (LPARAM)&gcr );
+ if ( result != 0 )
+ return false;
+
+ _ASSERT (plugin_CHAT_EVENT == NULL);
+ plugin_CHAT_EVENT = HookEvent (ME_GC_EVENT, CHAT_EVENT);
+ _ASSERT (plugin_CHAT_EVENT != NULL);
+
+ return true;
+}
+
+void ChatUnregister()
+{
+ if (plugin_CHAT_EVENT)
+ {
+ UnhookEvent (plugin_CHAT_EVENT);
+ plugin_CHAT_EVENT = NULL;
+ }
+}
+
+bool ChatNewSession(LPCTSTR szSession)
+{
+ GCSESSION gcr =
+ {
+ sizeof( GCSESSION ),
+ GCW_CHATROOM,
+ modname,
+ (LPCSTR)szSession,
+ (LPCSTR)szSession,
+ NULL,
+ 0,
+ 0
+ };
+ return ( CallServiceSync( MS_GC_NEWSESSION, 0, (LPARAM)&gcr ) == 0 );
+}
+
+bool ChatAddGroup(LPCTSTR szSession, LPCTSTR szGroup)
+{
+ GCDEST gcdest =
+ {
+ modname,
+ (LPSTR)szSession,
+ GC_EVENT_ADDGROUP
+ };
+ GCEVENT gce =
+ {
+ sizeof( GCEVENT ),
+ &gcdest,
+ NULL,
+ NULL,
+ NULL,
+ (LPCSTR)szGroup,
+ NULL,
+ FALSE,
+ 0,
+ 0,
+ NULL
+ };
+ return ( CallServiceSync( MS_GC_EVENT, 0, (LPARAM)&gce ) == 0 );
+}
+
+bool ChatJoinMe(LPCTSTR szSession, LPCTSTR szGroup)
+{
+ CString sMe;
+
+ CString sMyNick = GetNick( NULL );
+ if ( ! sMyNick.IsEmpty() )
+ sMe = sMyNick;
+ else
+ sMe = pluginMachineName;
+
+ GCDEST gcdest =
+ {
+ modname,
+ (LPSTR)szSession,
+ GC_EVENT_JOIN
+ };
+ GCEVENT gce =
+ {
+ sizeof( GCEVENT ),
+ &gcdest,
+ NULL,
+ (LPCSTR)(LPCTSTR)sMe,
+ (LPCSTR)(LPCTSTR)sMe,
+ (LPCSTR)szGroup,
+ NULL,
+ TRUE,
+ 0,
+ 0,
+ NULL
+ };
+ return ( CallServiceSync( MS_GC_EVENT, 0, (LPARAM)&gce ) == 0 );
+}
+
+bool ChatJoinUser(LPCTSTR szSession, LPCTSTR szUser, LPCTSTR szGroup)
+{
+ GCDEST gcdest =
+ {
+ modname,
+ (LPSTR)szSession,
+ GC_EVENT_JOIN
+ };
+ GCEVENT gce =
+ {
+ sizeof( GCEVENT ),
+ &gcdest,
+ NULL,
+ (LPCSTR)szUser,
+ (LPCSTR)szUser,
+ (LPCSTR)szGroup,
+ NULL,
+ FALSE,
+ 0,
+ 0,
+ NULL
+ };
+ return ( CallServiceSync( MS_GC_EVENT, 0, (LPARAM)&gce ) == 0 );
+}
+
+bool ChatInitDone(LPCTSTR szSession)
+{
+ GCDEST gcdest =
+ {
+ modname,
+ (LPSTR)szSession,
+ GC_EVENT_CONTROL
+ };
+ GCEVENT gce =
+ {
+ sizeof( GCEVENT ),
+ &gcdest,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ FALSE,
+ 0,
+ 0,
+ NULL
+ };
+ return ( CallServiceSync( MS_GC_EVENT, SESSION_INITDONE, (LPARAM)&gce ) == 0 );
+}
+
+bool ChatOnline(LPCTSTR szSession)
+{
+ GCDEST gcdest =
+ {
+ modname,
+ (LPSTR)szSession,
+ GC_EVENT_CONTROL
+ };
+ GCEVENT gce =
+ {
+ sizeof( GCEVENT ),
+ &gcdest,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ FALSE,
+ 0,
+ 0,
+ NULL
+ };
+ return ( CallServiceSync( MS_GC_EVENT, SESSION_ONLINE, (LPARAM)&gce ) == 0 );
+}
+
+bool ChatOffline(LPCTSTR szSession)
+{
+ GCDEST gcdest =
+ {
+ modname,
+ (LPSTR)szSession,
+ GC_EVENT_CONTROL
+ };
+ GCEVENT gce =
+ {
+ sizeof( GCEVENT ),
+ &gcdest,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ FALSE,
+ 0,
+ 0,
+ NULL
+ };
+ return ( CallServiceSync( MS_GC_EVENT, SESSION_OFFLINE, (LPARAM)&gce ) == 0 );
+}
+
+bool ChatMessage(LPCTSTR szSession, LPCTSTR szFrom, LPCTSTR szMessage)
+{
+ GCDEST gcdest =
+ {
+ modname,
+ (LPSTR)szSession,
+ GC_EVENT_MESSAGE
+ };
+ GCEVENT gce =
+ {
+ sizeof( GCEVENT ),
+ &gcdest,
+ (LPCSTR)szMessage,
+ (LPCSTR)szFrom,
+ (LPCSTR)szFrom,
+ NULL,
+ NULL,
+ FALSE,
+ 0,
+ 0,
+ time()
+ };
+ return ( CallServiceSync( MS_GC_EVENT, 0, (LPARAM)&gce ) == 0 );
+}
+
+bool ChatMessage(LPCTSTR szSession, LPCTSTR szMessage)
+{
+ CString sMe;
+
+ CString sMyNick = GetNick( NULL );
+ if ( ! sMyNick.IsEmpty() )
+ sMe = sMyNick;
+ else
+ sMe = pluginMachineName;
+
+ GCDEST gcdest =
+ {
+ modname,
+ (LPSTR)szSession,
+ GC_EVENT_MESSAGE
+ };
+ GCEVENT gce =
+ {
+ sizeof( GCEVENT ),
+ &gcdest,
+ (LPCSTR)szMessage,
+ (LPCSTR)(LPCTSTR)sMe,
+ (LPCSTR)(LPCTSTR)sMe,
+ NULL,
+ NULL,
+ TRUE,
+ 0,
+ 0,
+ time()
+ };
+ return ( CallServiceSync( MS_GC_EVENT, 0, (LPARAM)&gce ) == 0 );
+}
+
+CString GetChatSession(HANDLE hContact)
+{
+ CString sContact;
+ DBVARIANT dbv = {};
+ if ( ! DBGetContactSettingTString( hContact, modname, "ChatRoomID", &dbv ) )
+ {
+ sContact = dbv.pszVal;
+ DBFreeVariant( &dbv );
+ }
+ return sContact;
+}
+
+bool IsChatRoom(HANDLE hContact)
+{
+ return ( DBGetContactSettingByte( hContact, modname, "ChatRoom", 0 ) != 0 );
+}
+
+#endif // CHAT_ENABLED
diff --git a/plugins/!NotAdopted/WinPopup/chat.h b/plugins/!NotAdopted/WinPopup/chat.h
new file mode 100644
index 0000000000..6351ea3042
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/chat.h
@@ -0,0 +1,44 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2008-2009 Nikolay Raspopov
+
+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 CHAT_ENABLED
+
+bool ChatRegister();
+void ChatUnregister();
+bool ChatNewSession(LPCTSTR szSession);
+bool ChatAddGroup(LPCTSTR szSession, LPCTSTR szGroup);
+bool ChatJoinMe(LPCTSTR szSession, LPCTSTR szGroup);
+bool ChatJoinUser(LPCTSTR szSession, LPCTSTR szUser, LPCTSTR szGroup);
+bool ChatInitDone(LPCTSTR szSession);
+bool ChatOnline(LPCTSTR szSession);
+bool ChatOffline(LPCTSTR szSession);
+bool ChatMessage(LPCTSTR szSession, LPCTSTR szFrom, LPCTSTR szMessage);
+bool ChatMessage(LPCTSTR szSession, LPCTSTR szMessage);
+
+// ( )
+CString GetChatSession(HANDLE hContact);
+
+// -
+bool IsChatRoom(HANDLE hContact);
+
+#endif // CHAT_ENABLED
diff --git a/plugins/!NotAdopted/WinPopup/dllLoaderMinimal.h b/plugins/!NotAdopted/WinPopup/dllLoaderMinimal.h
new file mode 100644
index 0000000000..218a5a114c
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/dllLoaderMinimal.h
@@ -0,0 +1,338 @@
+/*
+ * This software is the original work of DKLT.
+ * Copyright (c) 2002 DKLT. All rights reserved.
+ * email: dtung@eng.monash.edu.au
+ *
+ */
+/*
+ * Permission to make digital or hard copies of all or part of this work for personal
+ * or classroom use is granted without fee provided that copies are not distributed
+ * for profit or commercial advantage.
+ */
+
+#ifndef LOADDLL_H
+#define LOADDLL_H
+
+/// proof of concept code follows
+///////
+/////// class DllLoader and class DllFunctor<...>
+///////
+/////// Two classes are designed to provide the functionality to load a function,
+/////// using the "function name" as an identifier, from a Win32 .dll file.
+/////// Sample code are attached at the end of this file.
+///////
+/////// -04Oct2003 <Sat> 11.52pm
+/////// reworked article and sample code to be posted on codeproject.com
+/////// better defined behaviours with refined logics idealistic goals yet to be completed
+///////
+/////// -29Mar2003 <Sat> 1.47pm
+/////// Polishing code for public release. minimizing code size, removing redundent
+/////// comments, eliminating deprecated funcs.
+///////
+/////// -29Mar2003 <Sat> 12.47am
+/////// Revising the src tree. Using redundent code to achieve src level compatibility
+/////// (ie: same set of calls for both funcs attached with apps or reside in dlls)
+///////
+/////// -12Nov2002 <Mon> 1.35am
+/////// My first attempt to tidy the code for another public release.
+///////
+/////// -14Oct2002 <Mon> 1.40am
+/////// created and tested briefly inside \DKLT TestApp\
+///////
+///////
+///////
+
+//template <char* DllName>
+
+///
+/// No error message for you
+///
+#ifndef ERRORMSG
+#define DEBUGMSG(aMesg) ;
+#define ERRORMSG(aMesg) ;
+#endif
+
+///
+/// protos
+///
+class DllLoader;
+template <typename T> class DllFunctor;
+
+
+/*
+//++++++++++++++++++++++++++++++++++++++++++++++++++++
+// For Current release, you write code like these
+//++++++++++++++++++++++++++++++++++++++++++++++++++++
+ ///
+ /// u can load a dll function in two differnt ways
+ ///
+ DllLoader dll("testDll.dll", false);
+ DllFunctor<int(*)(int,int)> fAdd("Add");
+ fAdd.SetDll(dll);
+
+ int b;
+ b = fSub()(b,1); // with delay load, but not src level compatible
+
+ OR
+
+
+ DllLoader dll("testDll.dll");
+ FuncPtrType( int(*)(int,int) ) Add;
+ dll.LoadFunc(Add,"Add");
+ int a=90;
+ a = Add(a,1); // src level compatible, but no delay load
+
+
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++
+// For previous release, you write code like these
+//++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ //
+ // sample code for demonstrating class DllLoader {...}; and DllFunctor<...> {...};
+ //
+ FuncPtrType( int(*)(int) ) a; // define a new variable "a" of type "int(*)(int)"
+
+ DllLoader Dlldshow("dlls.dll"); // expect a dll name "dlls.dll"
+ Dllshow.LoadFunc( a, "test"); // load func named "test" from dll file
+ int i =a(10);
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++
+// For initial release, you write code like these
+//++++++++++++++++++++++++++++++++++++++++++++++++++++
+ This version enables a delay-load behaviour. Note the double ()() call on last line.
+
+ //
+ // sample code for demonstrating class DllLoader {...}; and DllFunctor<...> {...};
+ //
+
+ DllLoader Dlldshow("dlls.dll");
+ DllFunctor<void(*)(POINT*)> update("UpdatePoint");
+
+ Dlldshow.find(update);
+
+ update() (&pt);
+
+
+*/
+
+/*
+ A little comment here
+
+ My previous attempts to use operator()(...) and operator FuncPtrType () with MSVC
+ failed, where FuncPtrType is a function pointer typedef. That technique, enables
+ more control over a functor object. ie: can implement delay load among many exciting
+ features. That technique, however, works with g++ line of compilers.
+
+ This current implementation is design for use with MSVC line of compilers only.
+
+ It seems, from the MSVC compiler error message, that "operator FuncPtrType ()" is
+ never a candidate function, not to mention viability. I guess this is how they
+ design and implemented MSVC6. ".net" version doesnt "evaluate"
+ "operator FuncPtrType()" properly as well.
+
+ - DKLT March 2003
+*/
+
+
+//////
+//////++++++++++++++++++++++++++++++++++++++++++++++++++
+////// This marco is for performing the following task... GoodJob! creative man!!
+//////++++++++++++++++++++++++++++++++++++++++++++++++++
+////// normally, u define a function pointer variable this way
+//////
+////// int (*c) (int) = test; // c pointing to "int test(int) {...}"
+//////
+////// This marco enables u define a function pointer this way
+//////
+////// FuncPtrType( int(*)(int) ) c =test;
+//////
+//////
+////// took me a while to come up with this one.
+//////
+////// - DKLT 2003 March
+
+template <typename FuncTypeTTT>
+struct TypeOnlyStruct {
+typedef FuncTypeTTT FuncType;
+};
+
+#define FuncPtrType(funcType) \
+ TypeOnlyStruct<funcType>::FuncType
+
+//////
+////// potential problems
+////// - an instantiation for every differnt type on the template class
+////// thus bloated executable? need to fully test it out. not sure about
+////// behaviour at this stage.
+////// - DKLT March 2003
+
+
+//////
+////// class DllLoader {...}
+////// -init a dll file with LoadLibrary() so that its mapped into dll memory
+////// space. this class is designed to use with class DllFunctor<...>.
+//////
+//////
+/////////////////////////////////////////////////////////
+class DllLoader
+{
+/////////////////////////////////////////////////////////
+
+private:
+ TCHAR dllName[ MAX_PATH ];
+
+public:
+ HINSTANCE dll;
+
+ DllLoader (LPCTSTR n, bool loadNow = true) :
+ dll(0)
+ {
+ lstrcpy( dllName, n );
+ if (loadNow)
+ LoadLibrary();
+ }
+ ~DllLoader ()
+ {
+ FreeLibrary();
+ }
+
+ // test to see if dll is loaded already
+ operator bool () const
+ {
+ return (dll != 0);
+ }
+
+// FuncTypePtr(int(*)(int)) a;
+// Dllshow.LoadFunc( a, "test") ;
+// int i =a(10);
+
+ /// This is my latest implementation
+ ///----------------------------------------------------------
+ /// public:
+ /// template <typename FuncTTT>
+ /// DllLoader::LoadFunc(FuncTTT& c, string fNameStr)
+ ///----------------------------------------------------------
+ /// This function loads a function named "fNameStr" from a DllLoader object
+ /// and put the address of that function into c.
+ ///
+ /// - template type is derived(deduced) from 1st param.
+ ///
+ ///note: bloated executable is possible
+ template <typename FuncTTT>
+ //--------------------------
+ FuncTTT LoadFunc(FuncTTT& c, LPCSTR fNameStr) {
+ //--------------------------
+ FuncTTT fPtr;
+
+ // existing lib loaded?
+ if (!dll)
+ if (!this->LoadLibrary())
+ return (FuncTTT) NULL;
+
+ // load func from dll
+ fPtr =(FuncTTT)GetProcAddress (
+ dll, // handle to DLL module
+ fNameStr // name of function
+ );
+ if (!fPtr) {
+ /// return a pointer to a base generic function would be good. ie: ERROR prompt
+ return (FuncTTT) NULL;
+ }
+ c = fPtr;
+ return fPtr;
+ }
+
+public:
+ ///
+ /// decrement dll ref count via win32 ::FreeLibrary(...)
+ ///
+ //--------------------------
+ void FreeLibrary() {
+ //--------------------------
+ if (dll) {
+ ::FreeLibrary(dll);
+ dll=0;
+ }
+ }
+
+public:
+ ///
+ /// find the dll file and attempt to load it
+ ///
+ //------------------------
+ bool LoadLibrary (HINSTANCE hInstance = NULL) {
+ //------------------------
+
+ // existing lib loaded?
+ if (dll !=0 )
+ this->FreeLibrary();
+
+ // load from:
+ // 1. The directory from which the application loaded.
+ // 2. The current directory.
+ // 3. The Windows system directory.
+ // 4. The Windows directory.
+ // 5. The directories that are listed in the PATH environment variable.
+ dll = ::LoadLibrary( dllName );
+ if ( ! dll )
+ {
+ // 6. The module directory (if dll).
+ if ( hInstance )
+ {
+ TCHAR self[ MAX_PATH ];
+ GetModuleFileName( hInstance, self, MAX_PATH );
+ lstrcpy( lstrnrchr( self, _T('\\'), lstrlen( self )) + 1, dllName );
+ dll = ::LoadLibrary( self );
+ }
+ if ( ! dll )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ ////// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ ////// All class functions below are for backward compatibility....
+ ////// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ ////// U may delete all of them if u dont need them
+ //////
+ ///
+ /// find() is deprecated. Do not use it anymore.
+ /// locate the functor inside a dll. let a DllFunctor object to do the job
+ /// instead... double dispatch??
+ ///
+public:template <typename QQ>
+ bool find(DllFunctor<QQ>& functor) {
+ return functor.LoadFromDll(this);
+ }
+
+};
+
+///
+/// DllFunctor<> is templated on the function type
+///
+template <typename FuncPtrType>
+class DllFunctor {
+ FuncPtrType fp; // pointer to dll function
+ DllLoader* dll; // which dllLoader to load from
+ CString fname; // name of function as char array
+
+public:
+ DllFunctor(FuncPtrType f, DllLoader* d=0): fp(f), dll(d) {;}
+ DllFunctor(LPCTSTR n): fname(n),fp(0), dll(0) {;}
+ FuncPtrType operator()() {
+ if (!*dll) {
+ if (!dll->LoadLibrary())
+ return (FuncPtrType) NULL;
+ }
+ if (fp == 0) {
+ dll->LoadFunc (fp, fname.c_str());
+ }
+ return fp;
+ }
+ void SetDll(DllLoader& d) { dll=&d; }
+};
+
+#endif
diff --git a/plugins/!NotAdopted/WinPopup/icons/add.ico b/plugins/!NotAdopted/WinPopup/icons/add.ico
new file mode 100644
index 0000000000..2b407bd899
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/add.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/away.ico b/plugins/!NotAdopted/WinPopup/icons/away.ico
new file mode 100644
index 0000000000..fd4fc06d27
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/away.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/bad_name.ico b/plugins/!NotAdopted/WinPopup/icons/bad_name.ico
new file mode 100644
index 0000000000..d90e82cf30
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/bad_name.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/bad_names.ico b/plugins/!NotAdopted/WinPopup/icons/bad_names.ico
new file mode 100644
index 0000000000..939dcffcb1
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/bad_names.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/computer.ico b/plugins/!NotAdopted/WinPopup/icons/computer.ico
new file mode 100644
index 0000000000..70e0c09112
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/computer.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/computer_error.ico b/plugins/!NotAdopted/WinPopup/icons/computer_error.ico
new file mode 100644
index 0000000000..380ed3d9f1
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/computer_error.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/dnd.ico b/plugins/!NotAdopted/WinPopup/icons/dnd.ico
new file mode 100644
index 0000000000..3cc44e4a98
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/dnd.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/explore.ico b/plugins/!NotAdopted/WinPopup/icons/explore.ico
new file mode 100644
index 0000000000..0e26c97f10
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/explore.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/freechat.ico b/plugins/!NotAdopted/WinPopup/icons/freechat.ico
new file mode 100644
index 0000000000..730bbe436a
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/freechat.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/good_name.ico b/plugins/!NotAdopted/WinPopup/icons/good_name.ico
new file mode 100644
index 0000000000..86aaef9d46
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/good_name.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/good_names.ico b/plugins/!NotAdopted/WinPopup/icons/good_names.ico
new file mode 100644
index 0000000000..37fc97841f
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/good_names.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/invisible.ico b/plugins/!NotAdopted/WinPopup/icons/invisible.ico
new file mode 100644
index 0000000000..2c5378e70c
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/invisible.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/lana.ico b/plugins/!NotAdopted/WinPopup/icons/lana.ico
new file mode 100644
index 0000000000..d753509117
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/lana.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/na.ico b/plugins/!NotAdopted/WinPopup/icons/na.ico
new file mode 100644
index 0000000000..e9cffaf26f
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/na.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/occupied.ico b/plugins/!NotAdopted/WinPopup/icons/occupied.ico
new file mode 100644
index 0000000000..2abca3db31
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/occupied.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/offline.ico b/plugins/!NotAdopted/WinPopup/icons/offline.ico
new file mode 100644
index 0000000000..a94a20319a
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/offline.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/online.ico b/plugins/!NotAdopted/WinPopup/icons/online.ico
new file mode 100644
index 0000000000..8bd53fe6f7
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/online.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/onthephone.ico b/plugins/!NotAdopted/WinPopup/icons/onthephone.ico
new file mode 100644
index 0000000000..5f88fdbc48
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/onthephone.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/other_name.ico b/plugins/!NotAdopted/WinPopup/icons/other_name.ico
new file mode 100644
index 0000000000..b46b632318
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/other_name.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/other_names.ico b/plugins/!NotAdopted/WinPopup/icons/other_names.ico
new file mode 100644
index 0000000000..c5eb01ad5c
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/other_names.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/outtolunch.ico b/plugins/!NotAdopted/WinPopup/icons/outtolunch.ico
new file mode 100644
index 0000000000..9b144d1eea
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/outtolunch.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/overlay/away.ico b/plugins/!NotAdopted/WinPopup/icons/overlay/away.ico
new file mode 100644
index 0000000000..4c6928082d
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/overlay/away.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/overlay/dnd.ico b/plugins/!NotAdopted/WinPopup/icons/overlay/dnd.ico
new file mode 100644
index 0000000000..778689c234
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/overlay/dnd.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/overlay/freechat.ico b/plugins/!NotAdopted/WinPopup/icons/overlay/freechat.ico
new file mode 100644
index 0000000000..58a04c226e
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/overlay/freechat.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/overlay/invisible.ico b/plugins/!NotAdopted/WinPopup/icons/overlay/invisible.ico
new file mode 100644
index 0000000000..9775d6deea
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/overlay/invisible.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/overlay/na.ico b/plugins/!NotAdopted/WinPopup/icons/overlay/na.ico
new file mode 100644
index 0000000000..8ffa02a346
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/overlay/na.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/overlay/occupied.ico b/plugins/!NotAdopted/WinPopup/icons/overlay/occupied.ico
new file mode 100644
index 0000000000..290f2b4ef7
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/overlay/occupied.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/overlay/onphone.ico b/plugins/!NotAdopted/WinPopup/icons/overlay/onphone.ico
new file mode 100644
index 0000000000..9dda2ec2ae
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/overlay/onphone.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/overlay/outtolunch.ico b/plugins/!NotAdopted/WinPopup/icons/overlay/outtolunch.ico
new file mode 100644
index 0000000000..d357c23da1
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/overlay/outtolunch.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/icons/winpopup_proto.ico b/plugins/!NotAdopted/WinPopup/icons/winpopup_proto.ico
new file mode 100644
index 0000000000..6ee65927cf
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/icons/winpopup_proto.ico
Binary files differ
diff --git a/plugins/!NotAdopted/WinPopup/m_uninstaller.h b/plugins/!NotAdopted/WinPopup/m_uninstaller.h
new file mode 100644
index 0000000000..695330c4c5
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/m_uninstaller.h
@@ -0,0 +1,703 @@
+/*
+
+ 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;
+ unsigned iFile = 0;
+ unsigned cbPath = (unsigned)lstrlenA(pszPath);
+
+ for (; apszFiles[iFile] != NULL; ++iFile)
+ {
+ if(cbPath + lstrlenA(apszFiles[iFile]) < sizeof(szFile) / sizeof(szFile[0]))
+ {
+ lstrcpyA(szFile, pszPath);
+ lstrcatA(szFile, apszFiles[iFile]);
+
+ if (DeleteFileA(szFile)) bReturn = TRUE;
+ }
+ }
+
+ 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/plugins/!NotAdopted/WinPopup/m_updater.h b/plugins/!NotAdopted/WinPopup/m_updater.h
new file mode 100644
index 0000000000..c83b8a4600
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/m_updater.h
@@ -0,0 +1,117 @@
+#ifndef _M_UPDATER_H
+#define _M_UPDATER_H
+
+// 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"
+
+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
+ // (not that this URL could point at a binary file - dunno why, but it could :)
+ int cpbVersionPrefix; // number of bytes pionted 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 pionted 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 pionted to by pbVersion
+
+ char *szBetaChangelogURL; // url for displaying changelog for beta versions
+} Update;
+
+// register a comonent with the 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);
+}
+
+
+// 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 'short name' in pluginInfo must match the name of the plugin on the file listing, exactly (not including case)
+// AND the plugin version string on the file listing must be the string version of the version in pluginInfo (i.e. 0.0.0.1,
+// 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 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.
+
+#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);
+
+ 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/plugins/!NotAdopted/WinPopup/mailslot.cpp b/plugins/!NotAdopted/WinPopup/mailslot.cpp
new file mode 100644
index 0000000000..5774cfa2a9
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/mailslot.cpp
@@ -0,0 +1,313 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2010 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "winpopup_proto.h"
+#include "mailslot.h"
+#include "messagebox.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+#define MAX_MESSAGE_SIZE 424 // () /
+ //
+
+mailslot pluginMailslot; //
+
+/*const struct { //
+ LPCTSTR name;
+} blacklist [] = {
+ _T("winpopup"),
+ _T("vikpopup"),
+ _T("netter"),
+ _T("realpopup"),
+ NULL
+};*/
+
+////////////////////////////////////////////////////////////////////////
+// Class mailslot
+
+mailslot::mailslot () :
+ m_hMailslot (INVALID_HANDLE_VALUE),
+ m_MonitorTerm (NULL),
+ m_Monitor (NULL)
+{
+}
+
+mailslot::~mailslot ()
+{
+ Destroy ();
+}
+
+bool mailslot::Create (LPCTSTR Name)
+{
+ CLock oLock( m_cs );
+
+ m_sName = Name;
+
+ bool ret = true;
+ if ( ! IsValid() )
+ {
+ //
+ CString sAddr;
+ sAddr.Format( _T("\\\\.\\mailslot\\%s"), (LPCTSTR)m_sName );
+
+ m_hMailslot = CreateMailslot( sAddr, 0, 2000, NULL );
+ if ( ! IsValid() )
+ {
+ ret = false;
+ DWORD err = GetLastError ();
+ if (err == ERROR_ALREADY_EXISTS)
+ WarningBox (NULL, 0, _T("%s\r\n%s"), T_CREATE_ERROR,
+ TranslateT ("Please shutdown any other IM applications and/or Messenger service"));
+ else
+ WarningBox (NULL, err, T_CREATE_ERROR);
+ }
+ }
+ if (ret)
+ {
+ if (m_MonitorTerm)
+ ResetEvent (m_MonitorTerm);
+ else
+ m_MonitorTerm = CreateEvent (NULL, TRUE, FALSE, NULL);
+ m_Monitor = (HANDLE)mir_forkthread( MonitorThread, this );
+ }
+
+ return ret;
+}
+
+void mailslot::AskForDestroy()
+{
+ if (m_MonitorTerm)
+ SetEvent (m_MonitorTerm);
+}
+
+void mailslot::Destroy ()
+{
+ CLock oLock( m_cs );
+
+ //
+ AskForDestroy();
+
+ //
+ if ( IsValid() )
+ {
+ CloseHandle (m_hMailslot);
+ m_hMailslot = INVALID_HANDLE_VALUE;
+ }
+
+ //
+ if (m_Monitor)
+ {
+ if (WaitForSingleObject (m_Monitor, ALMOST_INFINITE) == WAIT_TIMEOUT)
+ {
+ LOG("Terminate mailslot monitor!");
+ TerminateThread (m_Monitor, 0);
+ }
+ m_Monitor = NULL;
+ }
+ if (m_MonitorTerm)
+ {
+ CloseHandle (m_MonitorTerm);
+ m_MonitorTerm = NULL;
+ }
+}
+
+bool mailslot::IsValid() const
+{
+ return ( m_hMailslot != INVALID_HANDLE_VALUE );
+}
+
+bool mailslot::SendMailslotMessage(HANDLE hContact, LPCTSTR msg, DWORD& err)
+{
+ //
+ CString sTo = GetNick( hContact );
+ if ( sTo.IsEmpty() )
+ {
+ err = ERROR_BAD_NETPATH;
+ return false;
+ }
+
+ //
+ CString sFrom = GetNick( NULL );
+ if ( sFrom.IsEmpty() )
+ {
+ err = ERROR_BAD_NETPATH;
+ return false;
+ }
+
+ //
+ // bool bGroup = IsGroup( hContact );
+
+ // : FROM<00>TO<00>MESSAGE<00>
+ COemString sOemMessage = msg;
+ COemString sOemTo = (LPCTSTR)sTo;
+ COemString sOemFrom = (LPCTSTR)sFrom;
+
+ //
+ int fixed_size = sOemFrom.GetLength() + 1 + sOemTo.GetLength() + 1 + 1;
+ if ( fixed_size >= MAX_MESSAGE_SIZE )
+ {
+ err = ERROR_BAD_LENGTH;
+ return false;
+ }
+
+ //
+ CString sAddr;
+ sAddr.Format( _T("\\\\%s\\mailslot\\%s"), sTo, (LPCTSTR)m_sName );
+ HANDLE hFile = CreateFile( sAddr, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ if ( hFile == INVALID_HANDLE_VALUE )
+ {
+ err = GetLastError();
+ return false;
+ }
+
+ int max_message_size = MAX_MESSAGE_SIZE - fixed_size;
+ char buf[ MAX_MESSAGE_SIZE ] = {};
+ lstrcpynA( buf, sOemFrom, sOemFrom.GetLength() + 1 );
+ lstrcpynA( buf + sOemFrom.GetLength() + 1, sOemTo, sOemTo.GetLength() + 1 );
+ do
+ {
+ int message_size = ( sOemMessage.GetLength() < max_message_size ) ?
+ sOemMessage.GetLength() : max_message_size;
+ lstrcpynA( buf + fixed_size - 1, sOemMessage, message_size + 1 );
+
+ //
+ DWORD written = 0;
+ if ( ! WriteFile( hFile, buf, (DWORD)fixed_size + message_size, &written, NULL ) ||
+ ( written < (DWORD)fixed_size ) )
+ {
+ err = GetLastError();
+ CloseHandle( hFile );
+ return false;
+ }
+ Sleep( 100 );
+
+ //
+ sOemMessage.CutFromStart( message_size );
+ }
+ while ( sOemMessage.GetLength() );
+
+ err = ERROR_SUCCESS;
+ CloseHandle( hFile );
+ return true;
+}
+
+bool mailslot::Receive(unsigned char* buf /* OEM */, DWORD size)
+{
+ // <FROM><00><TO><00><MESSAGE><00> ( <00> )
+ if (size)
+ {
+ char* from = (char*) buf;
+ char* to = lstrnchr (from, 0, (int)size);
+ if (to)
+ {
+ DWORD from_len = (DWORD)( to - from + 1 );
+ if ( from_len < size )
+ {
+ to++;
+ size -= from_len;
+ char* msg = lstrnchr (to, 0, (int)size);
+ if (msg)
+ {
+ DWORD to_len = (DWORD)( msg - to + 1 );
+ if (to_len < size)
+ {
+ msg++;
+ size -= to_len;
+ char* eof = lstrnchr (msg, 0, (int)size);
+ DWORD msg_len = eof ? (DWORD)( eof - msg + 1 ) : size;
+ if (msg_len == size)
+ {
+ CAnsiString sFrom (from);
+ CAnsiString sTo (to);
+ CAnsiString sMessage (msg);
+ ReceiveContactMessage(sFrom, sTo, sMessage, sMessage.GetLength ());
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+void mailslot::MonitorThread(void* param)
+{
+ if ( mailslot* pMailslot = (mailslot*)param )
+ {
+ pMailslot->Monitor();
+ pMailslot->m_Monitor = NULL;
+ }
+}
+
+void mailslot::Monitor ()
+{
+ // 500 , 50
+ while ( WaitForSingleObject( m_MonitorTerm, IsValid() ? 50u : 500u ) == WAIT_TIMEOUT )
+ {
+ //
+ LPSTR buf = NULL;
+ for ( DWORD buf_size = MAX_MESSAGE_SIZE; IsValid(); buf_size += 1024 )
+ {
+ if ( WaitForSingleObject( m_MonitorTerm, 0 ) != WAIT_TIMEOUT )
+ break;
+
+ if ( buf ) mir_free( buf );
+ buf = (LPSTR)mir_alloc( buf_size );
+
+ DWORD readed = 0;
+ DWORD err = ReadFile (m_hMailslot, buf, buf_size,
+ &readed, NULL) ? ERROR_SUCCESS : GetLastError ();
+ if (err == ERROR_ACCESS_DENIED || err == ERROR_SEM_TIMEOUT)
+ {
+ // -
+ break;
+ }
+ else if (err == ERROR_SUCCESS)
+ {
+ //
+ if (readed)
+ if (!Receive((LPBYTE)buf, readed))
+ LOG("Receive error (bad format?)");
+ break;
+ }
+ else if (err == ERROR_INSUFFICIENT_BUFFER)
+ {
+ //
+ continue;
+ }
+ else
+ {
+ //
+ // ERROR_HANDLE_EOF -
+ LOG("ReadFile form mailslot error: %d", err);
+ break;
+ }
+ }
+ if ( buf ) mir_free( buf );
+ }
+}
diff --git a/plugins/!NotAdopted/WinPopup/mailslot.h b/plugins/!NotAdopted/WinPopup/mailslot.h
new file mode 100644
index 0000000000..921127ae6e
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/mailslot.h
@@ -0,0 +1,48 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2010 Nikolay Raspopov
+
+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
+
+class mailslot
+{
+public:
+ mailslot();
+ ~mailslot();
+
+ bool Create(LPCTSTR Name);
+ void AskForDestroy(); //
+ void Destroy();
+ bool IsValid() const;
+ bool SendMailslotMessage(HANDLE hContact, LPCTSTR msg, DWORD& err);
+
+protected:
+ CString m_sName; //
+ HANDLE m_hMailslot; //
+ CComAutoCriticalSection m_cs; //
+ HANDLE m_MonitorTerm; // Monitor
+ HANDLE m_Monitor; // /
+
+ bool Receive(unsigned char* buf /* OEM */, DWORD size);
+ static void MonitorThread(void* param);
+ void Monitor();
+};
+
+extern mailslot pluginMailslot; //
diff --git a/plugins/!NotAdopted/WinPopup/md5.h b/plugins/!NotAdopted/WinPopup/md5.h
new file mode 100644
index 0000000000..dc5284ed35
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/md5.h
@@ -0,0 +1,222 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2006 Nikolay Raspopov
+
+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
+
+typedef unsigned long uint32;
+
+struct MD5Context {
+ uint32 buf[4];
+ uint32 bits[2];
+ unsigned char in[64];
+};
+
+// Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+// initialization constants.
+inline 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;
+}
+
+// The four core functions - F1 is optimized somewhat
+#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.
+inline void md5transform (uint32 buf[4], uint32 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;
+}
+
+// Update context to reflect the concatenation of another buffer full of bytes.
+inline void md5update (struct MD5Context *ctx, const unsigned char *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) {
+ CopyMemory (p, buf, len);
+ return;
+ }
+ CopyMemory (p, buf, t);
+ md5transform(ctx->buf, (uint32 *) ctx->in);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ CopyMemory (ctx->in, buf, 64);
+ md5transform(ctx->buf, (uint32 *) ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ CopyMemory (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)
+inline 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 */
+ ZeroMemory (p, count);
+ md5transform(ctx->buf, (uint32 *) ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ ZeroMemory (ctx->in, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ ZeroMemory (p, count - 8);
+ }
+
+ /* 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);
+ CopyMemory (digest, ctx->buf, 16);
+ ZeroMemory (ctx, sizeof(ctx)); /* In case it's sensitive */
+}
diff --git a/plugins/!NotAdopted/WinPopup/messagebox.cpp b/plugins/!NotAdopted/WinPopup/messagebox.cpp
new file mode 100644
index 0000000000..008110c269
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/messagebox.cpp
@@ -0,0 +1,232 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2011 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "winpopup_proto.h"
+#include "messagebox.h"
+#include "netbios.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+class messagebox
+{
+public:
+ messagebox () :
+ m_hwndOwner (NULL),
+ m_hwndMessageBox (NULL),
+ m_Timeout (0),
+ m_MonitorTerm (NULL)
+ {
+ }
+
+ int WINAPI DoModal (const LPMSGBOXPARAMS lpMsgBoxParams, DWORD dwTimeout)
+ {
+ int ret = 0;
+ m_hwndOwner = lpMsgBoxParams->hwndOwner;
+ m_Timeout = dwTimeout;
+ m_hwndMessageBox = NULL;
+ m_MonitorTerm = CreateEvent (NULL, TRUE, FALSE, NULL);
+ if (m_MonitorTerm) {
+ HANDLE hThread = (HANDLE)mir_forkthread( MsgBox, this );
+ if (hThread) {
+
+ ret = MessageBoxIndirect (lpMsgBoxParams);
+
+ //
+ SetEvent (m_MonitorTerm);
+ WaitForSingleObject (hThread, INFINITE);
+ }
+ CloseHandle (m_MonitorTerm);
+ }
+ return ret;
+ }
+
+protected:
+ static BOOL CALLBACK EnumWindowsProc (HWND hWnd, LPARAM lParam)
+ {
+ messagebox* self = reinterpret_cast <messagebox*> (lParam);
+
+ DWORD dwProcessId;
+ GetWindowThreadProcessId (hWnd, &dwProcessId);
+ const LONG req_style = WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU;
+ HWND hButton;
+ TCHAR ClassName[ 8 ];
+ if ( GetCurrentProcessId () != dwProcessId ||
+ ( GetWindowLongPtr(hWnd, GWL_STYLE) & req_style ) != req_style ||
+ GetParent( hWnd ) != NULL ||
+ GetWindow( hWnd, GW_OWNER ) != self->m_hwndOwner ||
+ ( hButton = GetWindow( hWnd, GW_CHILD ) ) == NULL ||
+ GetClassName( hButton, ClassName, _countof( ClassName ) ) == 0 ||
+ lstrcmpi( _T("button"), ClassName ) != 0 )
+ return TRUE;
+
+ self->m_hwndMessageBox = hWnd;
+
+ return FALSE;
+ }
+
+ static void MsgBox (LPVOID param)
+ {
+ messagebox* self = reinterpret_cast <messagebox*> (param);
+
+ // 10
+ DWORD i = 0;
+ while (WaitForSingleObject (self->m_MonitorTerm, 250) == WAIT_TIMEOUT &&
+ EnumWindows (messagebox::EnumWindowsProc, reinterpret_cast <LPARAM> (self)) &&
+ i++ < 10 * 4);
+ if (!self->m_hwndMessageBox)
+ //
+ return;
+
+ HWND hButton = GetWindow (self->m_hwndMessageBox, GW_CHILD);
+
+ //
+ while (self->m_Timeout-- &&
+ WaitForSingleObject (self->m_MonitorTerm, 1000) == WAIT_TIMEOUT &&
+ IsWindow (self->m_hwndMessageBox) && IsWindow (hButton)) {
+ CString buf, msg;
+ int buf_size = GetWindowTextLength (hButton);
+ if (buf_size) {
+ GetWindowText (hButton, buf.GetBuffer (buf_size + 1), buf_size + 1);
+ buf.ReleaseBuffer ();
+ }
+ int n = buf.ReverseFind (_T('='));
+ msg.Format (_T(" = %u"), self->m_Timeout);
+ SetWindowText (hButton, ((n < 1) ? buf : buf.Left (n - 1)) + msg);
+ }
+
+ //
+ if (IsWindow (self->m_hwndMessageBox) && IsWindow (hButton)) {
+ DWORD_PTR res;
+ SendMessageTimeout (self->m_hwndMessageBox, WM_COMMAND,
+ (WPARAM) GetDlgCtrlID (hButton),
+ (LPARAM) hButton, SMTO_ABORTIFHUNG | SMTO_NORMAL, 10000, &res);
+ }
+
+ return;
+ }
+
+ volatile HWND m_hwndOwner;
+ volatile HWND m_hwndMessageBox;
+ volatile DWORD m_Timeout;
+ HANDLE m_MonitorTerm;
+};
+
+static int WINAPI MessageBoxIndirectTimeout (const LPMSGBOXPARAMS lpMsgBoxParams, DWORD dwTimeout)
+{
+ messagebox mb;
+ return mb.DoModal (lpMsgBoxParams, dwTimeout);
+}
+
+LPCTSTR const szModules [] = {
+ _T("netapi32.dll"),
+ _T("netmsg.dll"),
+ _T("wininet.dll"),
+ _T("ntdll.dll"),
+ _T("ntdsbmsg.dll"),
+ NULL
+};
+
+void GetErrorMessage (DWORD dwLastError, CString &msg)
+{
+ CString buf;
+ if ( HRESULT_FACILITY( dwLastError ) == FACILITY_NETBIOS )
+ {
+ CString sMessage = (LPCTSTR)CA2T( GetNetbiosError( HRESULT_CODE ( dwLastError ) ) );
+ if ( ! sMessage.IsEmpty() )
+ msg.Format( _T("%s\r\nNetBIOS %s: %u"), sMessage, T_ERROR, HRESULT_CODE( dwLastError ) );
+ else
+ msg.Format( _T("NetBIOS %s: %u"), T_ERROR, HRESULT_CODE( dwLastError ) );
+ }
+ else
+ {
+ HMODULE hModule = NULL;
+ for (int i = 0; szModules [i]; i++)
+ {
+ hModule = LoadLibraryEx (szModules [i], NULL, LOAD_LIBRARY_AS_DATAFILE);
+ LPTSTR MessageBuffer = NULL;
+ if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_IGNORE_INSERTS |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ (hModule ? FORMAT_MESSAGE_FROM_HMODULE : 0u),
+ hModule, dwLastError, 0u, (LPTSTR) &MessageBuffer, 0u, NULL))
+ {
+ buf = MessageBuffer;
+ buf.Trim (_T(" \t\r\n"));
+ LocalFree (MessageBuffer);
+ if (hModule)
+ FreeLibrary (hModule);
+ break;
+ }
+ if (hModule)
+ FreeLibrary (hModule);
+ }
+ if ( ! buf.IsEmpty() )
+ msg.Format( _T("%s\r\n%s: %u"), (LPCTSTR)buf, T_ERROR, dwLastError );
+ else
+ msg.Format( _T("%s: %u"), T_ERROR, dwLastError );
+ }
+}
+
+static void PopupOrMessageBox (LPPOPUPDATAT ppdp)
+{
+ if (CALLSERVICE_NOTFOUND == PUAddPopUpT (ppdp))
+ {
+ MSGBOXPARAMS mbp = { 0 };
+ mbp.cbSize = sizeof (MSGBOXPARAMS);
+ mbp.lpszText = ppdp->lptzText;
+ mbp.lpszCaption = ppdp->lptzContactName;
+ mbp.dwStyle = MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL;
+ MessageBoxIndirectTimeout (&mbp, (DWORD)ppdp->iSeconds);
+ }
+}
+
+void WarningBox (HANDLE hContact /* = NULL */, DWORD dwLastError /* = 0 */, LPCTSTR format, ...)
+{
+ if (!pluginInstalled)
+ return;
+
+ POPUPDATAT pdp = { 0 };
+ pdp.lchContact = hContact;
+ pdp.lchIcon = (HICON) LoadImage( pluginModule, MAKEINTRESOURCE (IDI_WINPOPUP),
+ IMAGE_ICON, 16, 16, LR_SHARED );
+ lstrcpy (pdp.lptzContactName, modtitle_t);
+ va_list marker;
+ va_start (marker, format);
+ wvsprintf( pdp.lptzText, format, marker );
+ va_end (marker);
+ pdp.iSeconds = 10;
+
+ if (dwLastError) {
+ CString msg;
+ GetErrorMessage (dwLastError, msg);
+ int len = lstrlen (pdp.lptzText);
+ pdp.lptzText [len] = _T('\r');
+ pdp.lptzText [len + 1] = _T('\n');
+ lstrcpy (pdp.lptzText + len + 2, msg);
+ }
+
+ PopupOrMessageBox (&pdp);
+}
diff --git a/plugins/!NotAdopted/WinPopup/messagebox.h b/plugins/!NotAdopted/WinPopup/messagebox.h
new file mode 100644
index 0000000000..bde25887f4
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/messagebox.h
@@ -0,0 +1,29 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2006 Nikolay Raspopov
+
+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
+
+//
+// Popup Plugin,
+void WarningBox (HANDLE hContact /* = NULL */, DWORD dwLastError /* = 0 */, LPCTSTR format, ...);
+
+// WinAPI NetBIOS
+void GetErrorMessage (DWORD dwLastError, CString &msg);
diff --git a/plugins/!NotAdopted/WinPopup/messenger.cpp b/plugins/!NotAdopted/WinPopup/messenger.cpp
new file mode 100644
index 0000000000..b73bd4b23a
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/messenger.cpp
@@ -0,0 +1,469 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2010 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "winpopup_proto.h"
+#include "services.h"
+#include "messenger.h"
+#include "processapi.h"
+#include "messagebox.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+static bool IsMessengerRunning()
+{
+ bool found = false;
+ HANDLE h = CreateMailslot (_T("\\\\.\\mailslot\\") MESSENGER_MAIL, 0, 0, NULL);
+ if (h == INVALID_HANDLE_VALUE) {
+ if (GetLastError () == ERROR_ALREADY_EXISTS)
+ found = true;
+ else
+ LOG ("IsMessengerRunning() error 0x%08x", GetLastError ());
+ } else
+ CloseHandle (h);
+ return found;
+}
+
+messenger pluginMessenger; // / Messenger
+
+messenger::messenger () :
+ m_MonitorTerm (NULL),
+ m_Monitor (NULL),
+ m_ID (0),
+ m_bMSMessengerStopped (false)
+{
+}
+
+messenger::~messenger ()
+{
+ Destroy ();
+}
+
+bool messenger::Create(BOOL start)
+{
+ if ( pluginOS.dwPlatformId != VER_PLATFORM_WIN32_NT )
+ return false;
+
+ // , Messenger
+ bool messngr = IsMessengerRunning();
+ if ( start )
+ {
+ if ( ! messngr )
+ Start ();
+ }
+ else
+ {
+ if ( messngr )
+ Stop ();
+ }
+
+ m_ID = GetProcessId (_T("csrss.exe"));
+ LOG ( ( m_ID ? "Messenger host process CSRSS.EXE found : PID %u(%08x)" :
+ "Messenger host process CSRSS.EXE not found" ), m_ID, m_ID );
+
+ //
+ if (m_MonitorTerm)
+ ResetEvent (m_MonitorTerm);
+ else
+ m_MonitorTerm = CreateEvent (NULL, TRUE, FALSE, NULL);
+
+ if (!m_Monitor)
+ m_Monitor = (HANDLE)mir_forkthread( MonitorThread, this );
+
+ return (m_Monitor != NULL);
+}
+
+void messenger::AskForDestroy()
+{
+ if (m_MonitorTerm)
+ SetEvent (m_MonitorTerm);
+}
+
+void messenger::Destroy ()
+{
+ if (pluginOS.dwPlatformId != VER_PLATFORM_WIN32_NT)
+ return;
+
+ AskForDestroy();
+
+ if (m_Monitor)
+ {
+ if (WaitForSingleObject (m_Monitor, ALMOST_INFINITE) == WAIT_TIMEOUT)
+ {
+ LOG("Terminate Messenger monitor!");
+ TerminateThread (m_Monitor, 0);
+ }
+ m_Monitor = NULL;
+ }
+
+ if (m_MonitorTerm)
+ {
+ CloseHandle (m_MonitorTerm);
+ m_MonitorTerm = NULL;
+ }
+
+ // " ",
+ if (m_bMSMessengerStopped)
+ Start ();
+}
+
+messenger::operator bool () const
+{
+ return (m_Monitor != NULL);
+}
+
+BOOL CALLBACK messenger::EnumWindowsProc (HWND hWnd, LPARAM lParam)
+{
+ DWORD dwTargetId = reinterpret_cast <messenger*> (lParam)->m_ID;
+ DWORD dwProcessId = 0;
+ GetWindowThreadProcessId (hWnd, &dwProcessId);
+ if (dwTargetId && dwTargetId != dwProcessId)
+ return TRUE;
+
+ const LONG req_style = WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU;
+ const LONG req_style_ex = WS_EX_TOPMOST;
+ HWND hButton, hText;
+ TCHAR ClassName[ 8 ] = {};
+ if ((GetWindowLongPtr(hWnd, GWL_STYLE) & req_style) != req_style ||
+ (GetWindowLongPtr(hWnd, GWL_EXSTYLE) & req_style_ex) != req_style_ex ||
+ GetParent (hWnd) != NULL ||
+ GetWindow (hWnd, GW_OWNER) != NULL ||
+ // child 1 = Button, child 2 = STATIC, child 3 = NULL
+ (hButton = GetWindow (hWnd, GW_CHILD)) == NULL ||
+ GetClassName( hButton, ClassName, _countof( ClassName ) ) == 0 ||
+ lstrcmpi (_T("button"), ClassName) != 0 ||
+ (hText = GetNextWindow (hButton, GW_HWNDNEXT)) == NULL ||
+ GetClassName( hText, ClassName, _countof( ClassName ) ) == 0 ||
+ lstrcmpi( _T("static"), ClassName ) != 0 ||
+ GetNextWindow (hText, GW_HWNDNEXT) != NULL)
+ //
+ return TRUE;
+
+ CString buf;
+ int buf_size = GetWindowTextLength (hText);
+ if (buf_size) {
+ GetWindowText (hText, buf.GetBuffer (buf_size + 1), buf_size + 1);
+ buf.ReleaseBuffer ();
+ }
+
+ if (!buf.IsEmpty ()) {
+ CString tok, from, to, msg;
+ int curPos = 0;
+ for (int i = 0; (tok = buf.Tokenize( _T(" "), curPos)), !tok.IsEmpty (); i++) {
+ switch (i) {
+ case 2:
+ from = tok;
+ break;
+ case 4:
+ to = tok;
+ break;
+ }
+ }
+ int n = buf.Find ( _T("\n") );
+ msg = buf.Mid (n + 3);
+ if (!from.IsEmpty () && !to.IsEmpty () && !msg.IsEmpty ()) {
+ //
+ DWORD_PTR res = 0;
+ SendMessageTimeout (hWnd, WM_COMMAND, (WPARAM) GetDlgCtrlID (hButton),
+ (LPARAM) hButton, SMTO_ABORTIFHUNG | SMTO_NORMAL, 10000, &res);
+
+ //
+ ReceiveContactMessage(from, to, msg, msg.GetLength ());
+ }
+ }
+
+ return FALSE;
+}
+
+void messenger::Monitor ()
+{
+ while (WaitForSingleObject (m_MonitorTerm, 250) == WAIT_TIMEOUT)
+ {
+ EnumWindows (EnumWindowsProc, reinterpret_cast <LPARAM> (this));
+ }
+ m_Monitor = NULL;
+}
+
+void messenger::MonitorThread(LPVOID lpParameter)
+{
+ reinterpret_cast< messenger* >( lpParameter )->Monitor();
+}
+
+// " "
+bool messenger::Start ()
+{
+ if (pluginOS.dwPlatformId != VER_PLATFORM_WIN32_NT)
+ return false;
+
+ bool ret = m_bMSMessengerStopped = false;
+
+ //
+ SC_HANDLE manager = fnOpenSCManager (NULL, NULL,
+ STANDARD_RIGHTS_READ | SC_MANAGER_CONNECT);
+ if (manager) {
+ //
+ SC_HANDLE service = fnOpenService (manager, MESSENGER,
+ SERVICE_START | SERVICE_QUERY_STATUS);
+ if (service) {
+ for(;;)
+ {
+ //
+ SERVICE_STATUS ss = { 0 };
+ if (fnQueryServiceStatus (service, &ss)) {
+ if (ss.dwCurrentState == SERVICE_RUNNING) {
+ //
+ LOG ("Messenger service already running");
+ ret = true;
+ } else {
+ //
+ if (fnStartService (service, 0, NULL))
+ //
+ ret = WaitForService (T_START_ERROR, service, SERVICE_START_PENDING, SERVICE_RUNNING);
+ else {
+ DWORD err = GetLastError ();
+ if ( err == ERROR_SERVICE_DISABLED )
+ {
+ //
+ if ( Enable() )
+ //
+ continue;
+ } else
+ WarningBox (NULL, err, T_START_ERROR);
+ }
+ }
+ } else
+ WarningBox (NULL, GetLastError (), T_START_ERROR);
+ break;
+ }
+ fnCloseServiceHandle (service);
+ } else
+ WarningBox (NULL, GetLastError (), T_START_ERROR);
+ fnCloseServiceHandle (manager);
+ } else
+ WarningBox (NULL, GetLastError (), T_START_ERROR);
+ return ret;
+}
+
+// " "
+bool messenger::Stop ()
+{
+ if (pluginOS.dwPlatformId != VER_PLATFORM_WIN32_NT)
+ return false;
+
+ bool ret = m_bMSMessengerStopped = false;
+
+ //
+ SC_HANDLE manager = fnOpenSCManager (NULL, NULL,
+ STANDARD_RIGHTS_READ | SC_MANAGER_CONNECT);
+ if (manager)
+ {
+ //
+ SC_HANDLE service = fnOpenService (manager, MESSENGER,
+ SERVICE_STOP | SERVICE_QUERY_STATUS);
+ if (service)
+ {
+ //
+ SERVICE_STATUS ss = {};
+ if (fnQueryServiceStatus (service, &ss))
+ {
+ if (ss.dwCurrentState == SERVICE_STOPPED)
+ {
+ //
+ LOG ("Messenger service already stopped");
+ ret = true; // m_bMSMessengerStopped = false
+ }
+ else
+ {
+ //
+ ZeroMemory (&ss, sizeof (SERVICE_STATUS));
+ if (fnControlService (service, SERVICE_CONTROL_STOP, &ss))
+ {
+ //
+ ret = m_bMSMessengerStopped = WaitForService (
+ T_STOP_ERROR, service,
+ SERVICE_STOP_PENDING, SERVICE_STOPPED);
+ }
+ else
+ {
+ if (GetLastError () == ERROR_SERVICE_NOT_ACTIVE)
+ //
+ ret = true; // m_bMSMessengerStopped = false
+ else
+ WarningBox (NULL, GetLastError (), T_STOP_ERROR);
+ }
+ }
+ }
+ else
+ WarningBox (NULL, GetLastError (), T_STOP_ERROR);
+ fnCloseServiceHandle (service);
+ }
+ else
+ {
+ if (GetLastError () == ERROR_SERVICE_DOES_NOT_EXIST)
+ // -
+ ret = true; // m_bMSMessengerStopped = false
+ else
+ WarningBox (NULL, GetLastError (), T_STOP_ERROR);
+ }
+ fnCloseServiceHandle (manager);
+ }
+ else
+ WarningBox (NULL, GetLastError (), T_STOP_ERROR);
+
+ return ret;
+}
+
+// " "
+bool messenger::Enable ()
+{
+ bool ret = false;
+
+ //
+ SC_HANDLE manager = fnOpenSCManager (NULL, NULL,
+ STANDARD_RIGHTS_READ | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG |
+ SC_MANAGER_CONNECT | SC_MANAGER_LOCK);
+ if (manager)
+ {
+ //
+ SC_LOCK lock = fnLockServiceDatabase( manager );
+ if (lock)
+ {
+ //
+ SC_HANDLE service = fnOpenService ( manager, MESSENGER,
+ SERVICE_CHANGE_CONFIG );
+ if (service)
+ {
+ //
+ if ( fnChangeServiceConfig( service, SERVICE_NO_CHANGE,
+ SERVICE_AUTO_START, SERVICE_NO_CHANGE,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL ) )
+ ret = true;
+ else
+ WarningBox (NULL, GetLastError (), T_ENABLE_ERROR);
+
+ fnCloseServiceHandle (service);
+ }
+ else
+ WarningBox (NULL, GetLastError (), T_ENABLE_ERROR);
+
+ fnUnlockServiceDatabase( lock );
+ }
+ else
+ WarningBox (NULL, GetLastError (), T_ENABLE_ERROR);
+
+ fnCloseServiceHandle ( manager );
+ }
+ else
+ WarningBox (NULL, GetLastError (), T_ENABLE_ERROR);
+ return ret;
+}
+
+bool messenger::WaitForService (LPCTSTR reason, SC_HANDLE service, DWORD process, DWORD end)
+{
+ SERVICE_STATUS ss = { 0 };
+ if (fnQueryServiceStatus (service, &ss))
+ {
+ DWORD dwStartTickCount = GetTickCount();
+ DWORD dwOldCheckPoint = ss.dwCheckPoint;
+ while (ss.dwCurrentState == process) {
+ // Do not wait longer than the wait hint. A good interval is
+ // one tenth the wait hint, but no less than 1 second and no
+ // more than 10 seconds.
+ DWORD dwWaitTime = ss.dwWaitHint / 10;
+ if (dwWaitTime < 1000)
+ dwWaitTime = 1000;
+ else
+ if (dwWaitTime > 10000)
+ dwWaitTime = 10000;
+ Sleep (dwWaitTime);
+ // Check the status again.
+ if (!fnQueryServiceStatus (service, &ss))
+ {
+ WarningBox (NULL, GetLastError (), reason);
+ return false;
+ }
+ if (ss.dwCurrentState == end)
+ break;
+ if (ss.dwCheckPoint > dwOldCheckPoint)
+ {
+ // The service is making progress.
+ dwStartTickCount = GetTickCount();
+ dwOldCheckPoint = ss.dwCheckPoint;
+ } else
+ {
+ if (GetTickCount() - dwStartTickCount > ss.dwWaitHint)
+ {
+ WarningBox (NULL, 0, _T("%s\r\n%s"), TranslateT ("No progress"), reason);
+ return false;
+ }
+ }
+ }
+ if (ss.dwCurrentState == end)
+ return true;
+ WarningBox (NULL, 0, _T("%s\r\n%s"), TranslateT ("Unexpected service status change"), reason);
+ }
+ else
+ WarningBox (NULL, GetLastError (), reason);
+ return false;
+}
+
+bool messenger::SendMessengerMessage(HANDLE hContact, LPCTSTR msg, DWORD& err)
+{
+ if ( pluginOS.dwPlatformId != VER_PLATFORM_WIN32_NT || ! fnNetMessageBufferSend )
+ {
+ err = ERROR_NOT_SUPPORTED;
+ return false;
+ }
+
+ //
+ CString sTo = GetNick( hContact );
+ if ( sTo.IsEmpty() )
+ {
+ err = NERR_NameNotFound;
+ return false;
+ }
+
+ //
+ CString sFrom = GetNick( NULL );
+ if ( sFrom.IsEmpty() )
+ {
+ err = NERR_NameNotFound;
+ return false;
+ }
+
+ //
+ // bool bGroup = IsGroup( hContact );
+
+ LPWSTR wto = mir_t2u( sTo );
+ LPWSTR wfrom = mir_t2u( sFrom );
+ LPWSTR wmsg = mir_t2u( msg );
+ err = fnNetMessageBufferSend( NULL, wto, wfrom, (LPBYTE)wmsg,
+ lstrlen( msg ) * sizeof( WCHAR ) );
+ mir_free( wto );
+ mir_free( wfrom );
+ mir_free( wmsg );
+
+ return ( err == NERR_Success );
+}
diff --git a/plugins/!NotAdopted/WinPopup/messenger.h b/plugins/!NotAdopted/WinPopup/messenger.h
new file mode 100644
index 0000000000..582b4d554c
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/messenger.h
@@ -0,0 +1,54 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2010 Nikolay Raspopov
+
+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
+
+class messenger
+{
+public:
+ messenger ();
+ ~messenger ();
+
+ bool Create (BOOL start);
+ void AskForDestroy(); //
+ void Destroy ();
+ operator bool () const;
+
+ bool Start (); // " "
+ bool Stop (); // " "
+ bool Enable (); // " "
+
+ bool SendMessengerMessage(HANDLE hContact, LPCTSTR msg, DWORD& err);
+
+protected:
+ HANDLE m_MonitorTerm; //
+ HANDLE m_Monitor; //
+ DWORD m_ID; // ID CSRSS.EXE
+ bool m_bMSMessengerStopped; //
+ // MS Messenger Stop()
+
+ void Monitor ();
+ static BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam);
+ static void MonitorThread (LPVOID lpParameter);
+ static bool WaitForService (LPCTSTR reason, SC_HANDLE service, DWORD process, DWORD end);
+};
+
+extern messenger pluginMessenger; // / Messenger
diff --git a/plugins/!NotAdopted/WinPopup/netbios.cpp b/plugins/!NotAdopted/WinPopup/netbios.cpp
new file mode 100644
index 0000000000..21a0cfd3c4
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/netbios.cpp
@@ -0,0 +1,1065 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2011 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "winpopup_proto.h"
+#include "netbios.h"
+#include "smbconst.h"
+#include "messagebox.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+netbios pluginNetBIOS; // / NetBIOS
+
+// NetBIOS-
+#define NETBIOS_NAME_TRACE(bb,mm,nn) mir_snprintf((bb),(mm),"%s #%d %02x %c %s", \
+ (nn.GetANSIFullName()), (nn.name_num), (nn.name_flags), \
+ (((nn.name_flags & GROUP_NAME) == GROUP_NAME) ? 'G' : 'U'), \
+ (((nn.name_flags & (NAME_FLAGS_MASK & ~GROUP_NAME)) == REGISTERING) ? "REGISTERING" : \
+ (((nn.name_flags & (NAME_FLAGS_MASK & ~GROUP_NAME)) == REGISTERED) ? "REGISTERED" : \
+ (((nn.name_flags & (NAME_FLAGS_MASK & ~GROUP_NAME)) == DEREGISTERED) ? "DEREGISTERED" : \
+ (((nn.name_flags & (NAME_FLAGS_MASK & ~GROUP_NAME)) == DUPLICATE) ? "DUPLICATE" : \
+ (((nn.name_flags & (NAME_FLAGS_MASK & ~GROUP_NAME)) == DUPLICATE_DEREG) ? "DUPLICATE_DEREG" : \
+ "UNKNOWN"))))));
+
+// NetBIOS commands
+static const struct
+{
+ UCHAR code; // NetBIOS command code
+ LPCSTR name; // NetBIOS command description
+}
+NCBCommands[] =
+{
+ { NCBCALL, "CALL" },
+ { NCBLISTEN, "LISTEN" },
+ { NCBHANGUP, "HANG UP" },
+ { NCBSEND, "SEND" },
+ { NCBRECV, "RECEIVE" },
+ { NCBRECVANY, "RECEIVE ANY" },
+ { NCBCHAINSEND, "CHAIN SEND" },
+ { NCBDGSEND, "SEND DATAGRAM" },
+ { NCBDGRECV, "RECEIVE DATAGRAM" },
+ { NCBDGSENDBC, "SEND BROADCAST DATAGRAM" },
+ { NCBDGRECVBC, "RECEIVE BROADCAST DATAGRAM" },
+ { NCBADDNAME, "ADD NAME" },
+ { NCBDELNAME, "DELETE NAME" },
+ { NCBRESET, "RESET" },
+ { NCBASTAT, "ADAPTER STATUS" },
+ { NCBSSTAT, "SESSION STATUS" },
+ { NCBCANCEL, "CANCEL" },
+ { NCBADDGRNAME, "ADD GROUP NAME" },
+ { NCBENUM, "ENUMERATE LANA NUMBERS" },
+ { NCBUNLINK, "UNLINK" },
+ { NCBSENDNA, "SEND NO ACK" },
+ { NCBCHAINSENDNA, "CHAIN SEND NO ACK" },
+ { NCBLANSTALERT, "LAN STATUS ALERT" },
+ { NCBACTION, "ACTION" },
+ { NCBFINDNAME, "FIND NAME" },
+ { NCBTRACE, "TRACE" },
+ { 0, NULL }
+};
+
+// NetBIOS errors
+static const struct
+{
+ UCHAR error; // NetBIOS error code
+ LPCSTR message; // NetBIOS error message
+}
+NRCErrors [] =
+{
+ { NRC_GOODRET, "The operation succeeded." },
+ { NRC_BUFLEN, "An illegal buffer length was supplied." },
+ { NRC_ILLCMD, "An illegal command was supplied." },
+ { NRC_CMDTMO, "The command was timed out." },
+ { NRC_INCOMP, "The message was incomplete. The application is to issue another command." },
+ { NRC_BADDR, "The buffer address was illegal." },
+ { NRC_SNUMOUT, "The session number was out of range." },
+ { NRC_NORES, "No resource was available." },
+ { NRC_SCLOSED, "The session was closed." },
+ { NRC_CMDCAN, "The command was canceled." },
+ { NRC_DUPNAME, "A duplicate name existed in the local name table." },
+ { NRC_NAMTFUL, "The name table was full." },
+ { NRC_ACTSES, "The command finished; the name has active sessions and is no longer registered." },
+ { NRC_LOCTFUL, "The local session table was full." },
+ { NRC_REMTFUL, "The remote session table was full. The request to open a session was rejected." },
+ { NRC_ILLNN, "An illegal name number was specified." },
+ { NRC_NOCALL, "The system did not find the name that was called." },
+ { NRC_NOWILD, "Wildcards are not permitted in the ncb_name member." },
+ { NRC_INUSE, "The name was already in use on the remote adapter." },
+ { NRC_NAMERR, "The name was deleted." },
+ { NRC_SABORT, "The session ended abnormally." },
+ { NRC_NAMCONF, "A name conflict was detected." },
+ { NRC_IFBUSY, "The interface was busy." },
+ { NRC_TOOMANY, "Too many commands were outstanding; the application can retry the command later." },
+ { NRC_BRIDGE, "The ncb_lana_num member did not specify a valid network number." },
+ { NRC_CANOCCR, "The command finished while a cancel operation was occurring." },
+ { NRC_CANCEL, "The NCBCANCEL command was not valid; the command was not canceled." },
+ { NRC_DUPENV, "The name was defined by another local process." },
+ { NRC_ENVNOTDEF, "The environment was not defined." },
+ { NRC_OSRESNOTAV, "Operating system resources were exhausted. The application can retry the command later." },
+ { NRC_MAXAPPS, "The maximum number of applications was exceeded." },
+ { NRC_NOSAPS, "No service access points (SAPs) were available for NetBIOS." },
+ { NRC_NORESOURCES, "The requested resources were not available." },
+ { NRC_INVADDRESS, "The NCB address was not valid." },
+ { NRC_INVDDID, "The NCB DDID was invalid." },
+ { NRC_LOCKFAIL, "The attempt to lock the user area failed." },
+ { NRC_OPENERR, "An error occurred during an open operation being performed by the device driver." },
+ { NRC_SYSTEM, "A system error occurred." },
+ { NRC_PENDING, "An asynchronous operation is not yet finished." },
+ { 0, NULL }
+};
+
+LPCSTR GetNetbiosCommand(UCHAR command)
+{
+ command &= 0x7f; // strip ASYNCH bit
+ for ( int i = 0; NCBCommands[ i ].name; ++i )
+ if ( NCBCommands[ i ].code == command )
+ return NCBCommands[ i ].name;
+ return "UNKNOWN";
+}
+
+LPCSTR GetNetbiosError(UCHAR err)
+{
+ for ( int i = 0; NRCErrors [ i ].message; ++i )
+ if ( NRCErrors [ i ].error == err )
+ return NRCErrors [ i ].message;
+ return "Unknown error.";
+}
+
+UCHAR NetbiosEx(NCB* pNCB)
+{
+ UCHAR command = pNCB->ncb_command;
+ UCHAR ret = Netbios( pNCB );
+ //if ( ret != NRC_GOODRET )
+ if ( ret == pNCB->ncb_retcode )
+ {
+ LOG( "NetBIOS call 0x%02x \"%s\" result: 0x%02x \"%s\"",
+ command, GetNetbiosCommand( command ),
+ ret, GetNetbiosError( ret ) );
+ }
+ else
+ {
+ LOG( "NetBIOS call 0x%02x \"%s\" result: 0x%02x \"%s\", return: 0x%02x \"%s\"",
+ command, GetNetbiosCommand( command ),
+ ret, GetNetbiosError( ret ),
+ pNCB->ncb_retcode, GetNetbiosError( pNCB->ncb_retcode ) );
+ }
+ return ret;
+}
+
+// NCB
+// KB317437: "NetBIOS Listen May Return a Damaged NCB Structure"
+// The _NCB structure that is returned when a NetBIOS Listen call completes may have a changed server name offset.
+class CNCB
+{
+public:
+ CNCB() :
+ m_buf( VirtualAlloc( NULL, 4096, MEM_COMMIT, PAGE_READWRITE ) )
+ {
+ }
+
+ ~CNCB()
+ {
+ if ( m_buf )
+ {
+ VirtualFree( m_buf, 0, MEM_RELEASE );
+ }
+ }
+
+ inline operator bool() const
+ {
+ return ( m_buf != NULL );
+ }
+
+ inline operator NCB*() const
+ {
+ return (NCB*)m_buf;
+ }
+
+ inline NCB* operator->() const
+ {
+ return (NCB*)m_buf;
+ }
+
+protected:
+ void* m_buf;
+};
+
+////////////////////////////////////////////////////////////////////////
+// Class netbios
+
+netbios::netbios () :
+ m_initialized( false )
+{
+ ZeroMemory (&m_le, sizeof (m_le));
+}
+
+netbios::~netbios ()
+{
+ Destroy ();
+}
+
+bool netbios::Create (BOOL registration)
+{
+ CLock oLock( m_csData );
+
+ if ( ! m_initialized )
+ {
+ //
+ if ( EnumLanas( m_le ) == NRC_GOODRET )
+ {
+ //
+ for ( UCHAR i = 0; i < m_le.length; i++ )
+ {
+ ResetLana( m_le.lana [i] );
+ }
+
+ // ,
+ if ( registration )
+ {
+ Register ();
+ }
+ }
+
+ m_initialized = true;
+ }
+
+ return m_initialized;
+}
+
+void netbios::AskForDestroy()
+{
+ CLock oLock( m_csData );
+
+ //
+ for ( size_t i = 0; i < m_names.GetCount (); ++i )
+ m_names [i]->AskForDestroy();
+}
+
+void netbios::Destroy ()
+{
+ CLock oLock( m_csData );
+
+ if ( m_initialized )
+ {
+ Deregister();
+ m_initialized = false;
+ }
+}
+
+unsigned char* netbios::SetSMBHeaderCommand (unsigned char* szHeader, BYTE iCommandCode, size_t iBufferLen)
+{
+ ZeroMemory (szHeader, iBufferLen);
+ *(DWORD*)szHeader = SMB_MAGIC;
+ szHeader [4] = iCommandCode;
+ return (szHeader + SMB_HEADER_SIZE);
+}
+
+netbios::operator bool() const
+{
+ return m_initialized;
+}
+
+bool netbios::SendNetBIOSMessage(HANDLE hContact, LPCTSTR msg, DWORD& err)
+{
+ // Created by Ilja Razinkov (also known as IPv6), 2002, IPv6Intendo@yandex.ru
+ // Keep this comment if you redistribute this file
+
+ // NB-:
+ //1) D5. :
+ //- 00, A (1 ), 00 (3 )
+ //- A. 04, , 00, 04, , 00
+ // (2 ) 00,00,00 ( 5 ), D5
+ //
+ //2) D7. :
+ //- (2 ), 00, (A+B) (1 ), 00 ( 5 )
+ //- A. 01, B, 00 (3 )
+ //- B.
+ // ( 3 0-), D7
+ //
+ //3) 2
+ //
+ //4) D6. :
+ //- (2 ), 00, 00, 00 ( 5 )
+ // ( 3 0-), D6
+
+ //
+ CString sTo = GetNick( hContact );
+ if ( sTo.IsEmpty() )
+ {
+ err = (DWORD)MAKE_HRESULT( 0, FACILITY_NETBIOS, NRC_NOCALL );
+ return false;
+ }
+
+ //
+ CString sFrom = GetNick( NULL );
+ if ( sFrom.IsEmpty() )
+ {
+ err = (DWORD)MAKE_HRESULT( 0, FACILITY_NETBIOS, NRC_NOCALL );
+ return false;
+ }
+
+ bool bGroup = IsGroup( hContact );
+
+ //
+ CStringA sMessage( msg );
+ sMessage.AnsiToOem();
+ sMessage.Replace( "\r\n", "\x14" ); // <CR><LF> -> <14>
+ sMessage.Replace( "\r", "\x14" ); // <CR> -> <14>
+ sMessage.Replace( "\n", "\x14" ); // <LF> -> <14>
+ netbios_name nname_To( sTo, 3, bGroup );
+ netbios_name nname_From( sFrom, 3 );
+
+ //
+ UCHAR lana = 0;
+ if ( ! FindNameLana( nname_To, lana ) )
+ {
+ LOG ("SendNetBIOSMessage : Unknown name");
+ err = (DWORD)MAKE_HRESULT( 0, FACILITY_NETBIOS, NRC_NOCALL );
+ return false;
+ }
+
+ //
+ UCHAR lsn = 0;
+ err = Call (lana, nname_From, nname_To, lsn);
+ if (err != NRC_GOODRET)
+ {
+ LOG ("SendNetBIOSMessage : Cannot connect" );
+ err = (DWORD)MAKE_HRESULT( 0, FACILITY_NETBIOS, err );
+ return false;
+ }
+
+ UCHAR SMBBlock [168] = { 0 };
+ UCHAR* szSMBData = NULL;
+ UCHAR iFromLen = (UCHAR)nname_From.GetLength ();
+ UCHAR iToLen = (UCHAR)nname_To.GetLength ();
+ UCHAR iHiMsgCode = 0, iLoMsgCode = 0;
+
+ // 1.
+ LOG ( "SendNetBIOSMessage : Send start of multi-block message" );
+ szSMBData = SetSMBHeaderCommand (SMBBlock, SMBsendstrt, sizeof (SMBBlock));
+ UCHAR dwD5ALength = (UCHAR)( 1 + iFromLen + 2 + iToLen + 1 );
+ szSMBData[1] = dwD5ALength;
+ szSMBData[3] = 4;
+ szSMBData[4+iFromLen+1] = 4;
+ CopyMemory ( szSMBData + 4, nname_From.netbiosed.name, iFromLen );
+ CopyMemory ( szSMBData + 4 + iFromLen + 2, nname_To.netbiosed.name, iToLen );
+ UCHAR dwD5Length = (UCHAR)( 3 + dwD5ALength );
+ err = Send (lana, lsn, SMBBlock, (WORD) (SMB_HEADER_SIZE + dwD5Length));
+ if (err != NRC_GOODRET)
+ {
+ LOG ( "SendNetBIOSMessage : Can`t start session" );
+ Hangup (lana, lsn);
+ err = (DWORD)MAKE_HRESULT( 0, FACILITY_NETBIOS, err );
+ return false;
+ }
+
+ //
+ WORD length = sizeof (SMBBlock);
+ err = Recv (lana, lsn, SMBBlock, length);
+ if (err != NRC_GOODRET)
+ {
+ LOG ( "SendNetBIOSMessage : No reply (start session)" );
+ Hangup (lana, lsn);
+ err = (DWORD)MAKE_HRESULT( 0, FACILITY_NETBIOS, err );
+ return false;
+ }
+ iHiMsgCode=SMBBlock[SMB_HEADER_SIZE];
+ iLoMsgCode=SMBBlock[SMB_HEADER_SIZE+1];
+
+ // 2. ()
+ UCHAR dwD7BLength = 0;
+ for (int iSendedBytes = 0; iSendedBytes < sMessage.GetLength (); iSendedBytes += dwD7BLength)
+ {
+ dwD7BLength = sizeof (SMBBlock) - (5 + 3 + SMB_HEADER_SIZE);
+ szSMBData = SetSMBHeaderCommand (SMBBlock, SMBsendtxt, sizeof (SMBBlock));
+ if (iSendedBytes + dwD7BLength > sMessage.GetLength ())
+ dwD7BLength = (UCHAR)( sMessage.GetLength () - iSendedBytes );
+ szSMBData[0]=iHiMsgCode;
+ szSMBData[1]=iLoMsgCode;
+ szSMBData[3]=(UCHAR)( dwD7BLength + 3 );
+ szSMBData[5]=1;
+ szSMBData[6]=dwD7BLength;
+ CopyMemory (szSMBData + 5 + 3, (LPCSTR) sMessage + iSendedBytes, dwD7BLength);
+ LOG( "SendNetBIOSMessage : Send text (%u-%u bytes) of multi-block message" , iSendedBytes, iSendedBytes + dwD7BLength - 1);
+ err = Send (lana, lsn, SMBBlock, (WORD) (SMB_HEADER_SIZE + 5 + 3 + dwD7BLength));
+ if (err != NRC_GOODRET)
+ {
+ LOG ( "SendNetBIOSMessage : Can`t use session" );
+ Hangup (lana, lsn);
+ err = (DWORD)MAKE_HRESULT( 0, FACILITY_NETBIOS, err );
+ return false;
+ }
+ //
+ length = sizeof (SMBBlock);
+ err = Recv (lana, lsn, SMBBlock, length);
+ if (err != NRC_GOODRET)
+ {
+ LOG ( "SendNetBIOSMessage : No reply (use session)" );
+ Hangup (lana, lsn);
+ err = (DWORD)MAKE_HRESULT( 0, FACILITY_NETBIOS, err );
+ return false;
+ }
+ }
+
+ // 3.
+ LOG ( "SendNetBIOSMessage : Send and of multi-block message" );
+ szSMBData = SetSMBHeaderCommand (SMBBlock, SMBsendend, sizeof (SMBBlock));
+ DWORD dwD6Length=5;
+ szSMBData[0]=iHiMsgCode;
+ szSMBData[1]=iLoMsgCode;
+ err = Send (lana, lsn, SMBBlock, (WORD) (SMB_HEADER_SIZE + dwD6Length));
+ if (err != NRC_GOODRET)
+ {
+ LOG ( "SendNetBIOSMessage : Can`t close session" );
+ Hangup (lana, lsn);
+ err = (DWORD)MAKE_HRESULT( 0, FACILITY_NETBIOS, err );
+ return false;
+ }
+
+ //
+ length = sizeof (SMBBlock);
+ err = Recv (lana, lsn, SMBBlock, length);
+ if (err != NRC_GOODRET)
+ {
+ LOG ( "SendNetBIOSMessage : No reply (close session)" );
+ Hangup (lana, lsn);
+ err = (DWORD)MAKE_HRESULT( 0, FACILITY_NETBIOS, err );
+ return false;
+ }
+
+ //
+ Hangup (lana, lsn);
+ err = (DWORD)MAKE_HRESULT( 1, FACILITY_NETBIOS, NRC_GOODRET );
+ return true;
+}
+
+ip netbios::FindNameIP (LPCTSTR szName, UCHAR type)
+{
+ //
+ netbios_name nname( szName, type );
+ ip addr = INADDR_NONE;
+ FIND_NAME_BLOCK fn = { 0 };
+ for (UCHAR i = 0; i < m_le.length; i++) {
+ UINT uReturn = FindName (nname, m_le.lana [i], fn);
+ if (uReturn == NRC_GOODRET) {
+ LOG( "Found %s at %u boxes. LAN #%u IP: %u.%u.%u.%u", nname.GetANSIFullName(),
+ fn.fnb_header.node_count, m_le.lana [i],
+ fn.fnb_Names [0].source_addr[2],
+ fn.fnb_Names [0].source_addr[3],
+ fn.fnb_Names [0].source_addr[4],
+ fn.fnb_Names [0].source_addr[5]);
+ addr = ((ip)fn.fnb_Names [0].source_addr[5]) |
+ ((ip)fn.fnb_Names [0].source_addr[4] << 8) |
+ ((ip)fn.fnb_Names [0].source_addr[3] << 16) |
+ ((ip)fn.fnb_Names [0].source_addr[2] << 24);
+ break;
+ }
+ }
+ return addr;
+}
+
+void netbios::GetRegisteredNames (netbios_name_list& names)
+{
+ CLock oLock( m_csData );
+
+ for (size_t i = 0; i < m_names.GetCount (); ++i)
+ names.AddTail (*m_names [i]);
+}
+
+bool netbios::GetNames(netbios_name_list& names, LPCTSTR name, bool bGroup)
+{
+ //
+ ADAPTER_STATUS_BLOCK astat = { 0 };
+ netbios_name nname( name, 0, bGroup );
+ UINT uReturn = NRC_GOODRET;
+ for (UCHAR i = 0; i < m_le.length; i++)
+ {
+ uReturn = GetAdapterStatus (nname, m_le.lana [i], astat);
+ if (uReturn == NRC_GOODRET)
+ {
+ for (int j = 0; j < astat.asb_header.name_count; ++j)
+ {
+ names.AddTail (netbios_name (astat.asb_Names [j], m_le.lana [i]));
+ }
+ }
+ }
+ return (uReturn == NRC_GOODRET);
+}
+
+netbios_name* netbios::GetName (const netbios_name& nname)
+{
+ CLock oLock( m_csData );
+
+ netbios_name* ret = NULL;
+ for (size_t i = 0; i < m_names.GetCount (); ++i)
+ {
+ if ( nname == *(m_names [i]) )
+ {
+ //
+ ret = m_names [i];
+ break;
+ }
+ }
+
+ return ret;
+}
+
+bool netbios::FindNameLana(const netbios_name& nname, UCHAR& lana)
+{
+ //
+ ADAPTER_STATUS_BLOCK astat = {};
+ for (UCHAR i = 0; i < m_le.length; i++)
+ {
+ UINT uReturn = GetAdapterStatus (nname, m_le.lana [i], astat);
+ if ( uReturn == NRC_GOODRET )
+ {
+ for ( int j = 0; j < astat.asb_header.name_count; ++j )
+ {
+ if (nname == astat.asb_Names [j])
+ {
+ //
+ LOG ( "FindNameLana : Name \"%s\" found at #%d", nname.GetANSIFullName(), m_le.lana [i]);
+ lana = m_le.lana [i];
+ return true;
+ }
+ }
+ }
+ LOG( "FindNameLana : Name \"%s\" not found", nname.GetANSIFullName());
+ }
+
+ return false;
+}
+
+bool netbios::GetMAC (UCHAR lana, CString& mac)
+{
+ ADAPTER_STATUS_BLOCK astat = { 0 };
+ netbios_name nname;
+ UINT uReturn = GetAdapterStatus (nname, lana, astat);
+ if (uReturn == NRC_GOODRET) {
+ mac.Format (_T("%02x:%02x:%02x:%02x:%02x:%02x"),
+ astat.asb_header.adapter_address[0],
+ astat.asb_header.adapter_address[1],
+ astat.asb_header.adapter_address[2],
+ astat.asb_header.adapter_address[3],
+ astat.asb_header.adapter_address[4],
+ astat.asb_header.adapter_address[5]);
+ } else
+ mac.Empty ();
+ return true;
+}
+
+UCHAR netbios::FindName (const netbios_name& nname, UCHAR lana, FIND_NAME_BLOCK& fn)
+{
+ ZeroMemory (&fn, sizeof (FIND_NAME_BLOCK));
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ ncb->ncb_command = NCBFINDNAME;
+ ncb->ncb_lana_num = lana;
+ CopyMemory( ncb->ncb_callname, nname.netbiosed.name, NCBNAMSZ );
+ ncb->ncb_buffer = reinterpret_cast <BYTE*> (&fn);
+ ncb->ncb_length = sizeof (FIND_NAME_BLOCK);
+ NetbiosEx (ncb);
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::GetAdapterStatus (const netbios_name& nname, UCHAR lana, ADAPTER_STATUS_BLOCK& astat)
+{
+ ZeroMemory (&astat, sizeof (ADAPTER_STATUS_BLOCK));
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ ncb->ncb_command = NCBASTAT;
+ ncb->ncb_lana_num = lana;
+ CopyMemory( ncb->ncb_callname, nname.netbiosed.name, NCBNAMSZ );
+ ncb->ncb_buffer = reinterpret_cast <BYTE*> (&astat);
+ ncb->ncb_length = sizeof (ADAPTER_STATUS_BLOCK);
+ NetbiosEx (ncb);
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::EnumLanas (LANA_ENUM& le)
+{
+ //
+ ZeroMemory (&le, sizeof (LANA_ENUM));
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ ncb->ncb_command = NCBENUM;
+ ncb->ncb_buffer = (PUCHAR) &le;
+ ncb->ncb_length = sizeof (LANA_ENUM);
+ NetbiosEx (ncb);
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::ResetLana (UCHAR lana)
+{
+ //
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ ncb->ncb_command = NCBRESET;
+ ncb->ncb_lana_num = lana;
+ ncb->ncb_callname [0] = 20; // maximum sessions
+ ncb->ncb_callname [2] = 30; // maximum names
+ NetbiosEx (ncb);
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::Hangup (UCHAR lana, UCHAR lsn)
+{
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ ncb->ncb_command = NCBHANGUP;
+ ncb->ncb_lana_num = lana;
+ ncb->ncb_lsn = lsn;
+ NetbiosEx (ncb);
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::Send (UCHAR lana, UCHAR lsn, unsigned char* data, WORD length)
+{
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ ncb->ncb_lana_num = lana;
+ ncb->ncb_command = NCBSEND;
+ ncb->ncb_lsn = lsn;
+ ncb->ncb_length = length;
+ ncb->ncb_buffer = data;
+ ncb->ncb_rto = ncb->ncb_sto = (UCHAR) 10; // 10 * 500 ms = 5 s
+ NetbiosEx (ncb);
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::Recv (UCHAR lana, UCHAR lsn, unsigned char* data, WORD& length)
+{
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ ncb->ncb_command = NCBRECV;
+ ncb->ncb_lana_num = lana;
+ ncb->ncb_lsn = lsn;
+ ncb->ncb_length = length;
+ ncb->ncb_buffer = data;
+ ncb->ncb_rto = ncb->ncb_sto = (UCHAR) 10; // 10 * 500 ms = 5 s
+ NetbiosEx (ncb);
+ length = ncb->ncb_length;
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::Stat (const netbios_name& nname, SESSION_INFO_BLOCK* psibSession)
+{
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ ncb->ncb_command = NCBSSTAT;
+ ncb->ncb_lana_num = nname.GetLana();
+ ncb->ncb_buffer = (unsigned char*)psibSession;
+ ncb->ncb_length = sizeof (SESSION_INFO_BLOCK);
+ CopyMemory (ncb->ncb_name, nname.netbiosed.name, NCBNAMSZ);
+ NetbiosEx (ncb);
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::Listen (const netbios_name& nname, UCHAR& lsn)
+{
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ CopyMemory (ncb->ncb_name, nname.netbiosed.name, NCBNAMSZ);
+ CopyMemory (ncb->ncb_callname, SMB_ANY_NAME, NCBNAMSZ);
+ ncb->ncb_command = NCBLISTEN;
+ ncb->ncb_num = nname.netbiosed.name_num;
+ ncb->ncb_lana_num = nname.GetLana();
+ ncb->ncb_rto = ncb->ncb_sto = (UCHAR) 2; // 2 * 500 ms = 1 s
+ NetbiosEx (ncb);
+ lsn = ncb->ncb_lsn;
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::AddName (netbios_name& nname)
+{
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ ncb->ncb_command = (UCHAR)( nname.IsGroupName() ? NCBADDGRNAME : NCBADDNAME );
+ ncb->ncb_lana_num = nname.GetLana();
+ CopyMemory (ncb->ncb_name, nname.netbiosed.name, NCBNAMSZ);
+ NetbiosEx (ncb);
+ nname.netbiosed.name_num = ncb->ncb_num;
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::DeleteName (const netbios_name& nname)
+{
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ ncb->ncb_command = NCBDELNAME;
+ ncb->ncb_lana_num = nname.GetLana();
+ ncb->ncb_num = nname.netbiosed.name_num;
+ CopyMemory (ncb->ncb_name, nname.netbiosed.name, NCBNAMSZ);
+ NetbiosEx (ncb);
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::SendDatagram (const netbios_name& nname_from, const netbios_name& nname_to, unsigned char* data, WORD length)
+{
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ CopyMemory( ncb->ncb_name, nname_from.netbiosed.name, NCBNAMSZ );
+ CopyMemory( ncb->ncb_callname, nname_to.netbiosed.name, NCBNAMSZ );
+ ncb->ncb_command = NCBDGSEND;
+ ncb->ncb_num = nname_from.netbiosed.name_num;
+ ncb->ncb_lana_num = nname_from.GetLana();
+ ncb->ncb_buffer = data;
+ ncb->ncb_length = length;
+
+ CLock oLock( m_csNetBIOS );
+ Sleep( 100 );
+
+ NetbiosEx (ncb);
+
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::RecvDatagram (netbios_name& nname_from, const netbios_name& nname_to, unsigned char* data, WORD& length)
+{
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ CopyMemory (ncb->ncb_name, nname_to.netbiosed.name, NCBNAMSZ);
+ ncb->ncb_command = NCBDGRECV;
+ ncb->ncb_num = nname_to.netbiosed.name_num;
+ ncb->ncb_lana_num = nname_to.GetLana();
+ ncb->ncb_buffer = data;
+ ncb->ncb_length = length;
+ NetbiosEx (ncb);
+ nname_from = ncb->ncb_callname;
+ length = ncb->ncb_length;
+ return ncb->ncb_retcode;
+}
+
+UCHAR netbios::Call (UCHAR lana, const netbios_name& nname_from, const netbios_name& nname_to, UCHAR& lsn)
+{
+ CNCB ncb;
+ if ( ! ncb ) return NRC_SYSTEM;
+ CopyMemory( ncb->ncb_name, nname_from.netbiosed.name, NCBNAMSZ );
+ CopyMemory( ncb->ncb_callname, nname_to.netbiosed.name, NCBNAMSZ );
+ ncb->ncb_lana_num = lana;
+ ncb->ncb_rto = ncb->ncb_sto = 10; // 5
+ ncb->ncb_command = NCBCALL;
+ NetbiosEx (ncb);
+ lsn = ncb->ncb_lsn;
+ return ncb->ncb_retcode;
+}
+
+bool netbios::AskAway(const netbios_name& nname_to)
+{
+ bool ret = false;
+ if ( m_initialized )
+ {
+ //
+ const WORD packet_size = sizeof( WORD ) + 1;
+ if ( UCHAR* packet = (UCHAR*)mir_alloc( packet_size ) )
+ {
+ *(WORD*)packet = SM_MAGIC;
+ packet[ 2 ] = SM_GETAWAYMESSAGE;
+
+ for (UCHAR i = 0; i < m_le.length; i++)
+ {
+ if ( netbios_name* nname = GetName( netbios_name(
+ pluginMachineName, 0x03, false, m_le.lana [i] ) ) )
+ {
+ LOG( "Send \"Ask Away\" request to \"%s\"", nname_to.GetANSIFullName() );
+
+ if ( SendDatagram( *nname, nname_to, packet, packet_size ) == NRC_GOODRET )
+ {
+ ret = true;
+ }
+ }
+ }
+
+ mir_free( packet );
+ }
+ }
+ return ret;
+}
+
+bool netbios::SendAway(netbios_name& nname_from, const netbios_name& nname_to)
+{
+ bool ret = false;
+ if ( m_initialized )
+ {
+ CString sAwayT;
+ pluginStatusMessage.Lookup( pluginCurrentStatus, sAwayT );
+ CT2A sAwayA( sAwayT );
+ WORD len = (WORD)min( lstrlenA( sAwayA ), 250 );
+
+ //
+ WORD packet_size = (WORD)( 2 + 1 + 4 + len );
+ if ( UCHAR* packet = (UCHAR*)mir_alloc( packet_size ) )
+ {
+ *(WORD*)packet = SM_MAGIC;
+ packet [ 2 ] = SM_SENDAWAYMESSAGE;
+ *(__int32*)( packet + 2 + 1 ) = 0;
+ CopyMemory( packet + 2 + 1 + 4, sAwayA, len );
+
+ LOG( "Send \"Away\" answer from \"%s\" to \"%s\" : \"%s\"", nname_from.GetANSIFullName(), nname_to.GetANSIFullName(), (LPCSTR)sAwayA );
+
+ ret = ( SendDatagram( nname_from, nname_to, packet, packet_size ) == NRC_GOODRET );
+
+ mir_free( packet );
+ }
+ }
+ return ret;
+}
+
+bool netbios::AskStatus(const netbios_name& nname_to)
+{
+ bool ret = false;
+ if ( m_initialized )
+ {
+ //
+ const WORD packet_size = 2 + 1;
+ if ( UCHAR* packet = (UCHAR*)mir_alloc( packet_size ) )
+ {
+ *(WORD*)packet = SM_MAGIC;
+ packet[ 2 ] = SM_GETSTATUS;
+
+ for (UCHAR i = 0; i < m_le.length; i++)
+ {
+ if ( netbios_name* nname = GetName( netbios_name(
+ pluginMachineName, 0x03, false, m_le.lana [i] ) ) )
+ {
+ LOG( "Send \"Ask Status\" request to \"%s\"", nname_to.GetANSIFullName() );
+
+ if ( SendDatagram( *nname, nname_to, packet, packet_size ) == NRC_GOODRET )
+ {
+ ret = true;
+ }
+ }
+ }
+
+ mir_free( packet );
+ }
+ }
+ return ret;
+}
+
+bool netbios::SendStatus(netbios_name& nname_from, const netbios_name& nname_to)
+{
+ bool ret = false;
+ if ( m_initialized )
+ {
+ //
+ const WORD packet_size = 2 + 1 + 4;
+ if ( UCHAR* packet = (UCHAR*)mir_alloc( packet_size ) )
+ {
+ *(WORD*)packet = SM_MAGIC;
+ packet [ 2 ] = SM_SENDSTATUS;
+ *(__int32*)( packet + 2 + 1 ) = (__int32)pluginCurrentStatus;
+
+ LOG( "Send \"Status\" answer from \"%s\" to \"%s\" : \"%s\"", nname_from.GetANSIFullName(), nname_to.GetANSIFullName(), STATUS2TEXT(pluginCurrentStatus) );
+
+ ret = ( SendDatagram( nname_from, nname_to, packet, packet_size ) == NRC_GOODRET );
+
+ mir_free( packet );
+ }
+ }
+ return ret;
+}
+
+bool netbios::BroadcastStatus()
+{
+ bool ret = false;
+ if ( m_initialized )
+ {
+ for (UCHAR i = 0; i < m_le.length; i++)
+ {
+ netbios_name nname_to( MNS_STATUS, 0xab, true, m_le.lana [i] );
+ netbios_name* nname = GetName(
+ netbios_name ( pluginMachineName, 0x03, false, m_le.lana [i] ) );
+ if ( nname )
+ ret = SendStatus( *nname, nname_to ) || ret;
+ }
+ }
+ return ret;
+}
+
+bool netbios::AskAvatar(const netbios_name& nname_to)
+{
+ bool ret = false;
+ if ( m_initialized )
+ {
+ //
+ const WORD packet_size = 2 + 1;
+ if ( UCHAR* packet = (UCHAR*)mir_alloc( packet_size ) )
+ {
+ *(WORD*)packet = SM_MAGIC;
+ packet[ 2 ] = SM_GETAVATAR;
+
+ for (UCHAR i = 0; i < m_le.length; i++)
+ {
+ if ( netbios_name* nname = GetName( netbios_name(
+ pluginMachineName, 0x03, false, m_le.lana [i] ) ) )
+ {
+ LOG( "Send \"Ask Avatar\" request to \"%s\"", nname_to.GetANSIFullName() );
+
+ if ( SendDatagram( *nname, nname_to, packet, packet_size ) == NRC_GOODRET )
+ {
+ ret = true;
+ }
+ }
+ }
+
+ mir_free( packet );
+ }
+ }
+ return ret;
+}
+
+bool netbios::SendAvatar(netbios_name& nname_from, const netbios_name& nname_to)
+{
+ if ( ! m_initialized )
+ return false;
+
+ if ( ! ServiceExists( MS_AV_GETMYAVATAR ) )
+ //
+ return false;
+
+ //
+ AVATARCACHEENTRY* pAvatar = (AVATARCACHEENTRY*)CallService(
+ MS_AV_GETMYAVATAR, 0, (LPARAM)modname );
+ if ( ! pAvatar )
+ //
+ pAvatar = (AVATARCACHEENTRY*)CallService( MS_AV_GETMYAVATAR, 0, (LPARAM)"" );
+ if ( ! pAvatar || pAvatar->cbSize < sizeof( AVATARCACHEENTRY ) )
+ //
+ return false;
+
+ CString sFilename = (LPCTSTR)CA2T( pAvatar->szFilename );
+
+ CAtlFile oAvatarFile;
+ if ( FAILED( oAvatarFile.Create( sFilename, GENERIC_READ,
+ FILE_SHARE_READ, OPEN_EXISTING ) ) )
+ //
+ return false;
+
+ ULONGLONG avatar_size = 0;
+ if ( FAILED( oAvatarFile.GetSize( avatar_size ) ) ||
+ avatar_size < 16 || avatar_size > MAX_AVATAR_SIZE )
+ //
+ return false;
+
+ bool ret = false;
+
+ //
+ WORD packet_size = (WORD)( 2 + 1 + avatar_size );
+ if ( UCHAR* packet = (UCHAR*)mir_alloc( packet_size ) )
+ {
+ *(WORD*)packet = SM_MAGIC;
+ packet[ 2 ] = SM_SENDAVATAR;
+
+ //
+ if ( SUCCEEDED( oAvatarFile.Read( packet + 2 + 1, avatar_size ) ) )
+ {
+ LOG( "Send \"Avatar\" answer from \"%s\" to \"%s\"", nname_from.GetANSIFullName(), nname_to.GetANSIFullName() );
+
+ ret = ( SendDatagram( nname_from, nname_to, packet, packet_size ) == NRC_GOODRET );
+ }
+
+ mir_free( packet );
+ }
+
+ return ret;
+}
+
+bool netbios::Register ()
+{
+ CLock oLock( m_csData );
+
+ bool ret = false;
+
+ // ,
+ for (size_t i = 0; i < m_names.GetCount (); ++i)
+ delete m_names [i];
+ m_names.RemoveAll ();
+
+ //
+ for (UCHAR i = 0; i < m_le.length; i++)
+ {
+ // COMPUTER <01> U
+ netbios_name *pnn1 =
+ DBGetContactSettingByte (NULL, modname, "RegisterNick", TRUE) ?
+ new netbios_name ( pluginMachineName, 0x01, false, m_le.lana [i]) : NULL;
+ if (pnn1)
+ m_names.Add (pnn1);
+
+ // COMPUTER <03> U
+ netbios_name *pnn2 =
+ DBGetContactSettingByte (NULL, modname, "RegisterNick", TRUE) ?
+ new netbios_name ( pluginMachineName, 0x03, false, m_le.lana [i]) : NULL;
+ if (pnn2)
+ m_names.Add (pnn2);
+
+ // USER <03> U
+ netbios_name *pnn3 =
+ DBGetContactSettingByte (NULL, modname, "RegisterUser", TRUE) ?
+ new netbios_name ( pluginUserName, 0x03, false, m_le.lana [i]) : NULL;
+ if (pnn3) {
+ //
+ if (pnn2 && *pnn3 == *pnn2)
+ //
+ delete pnn3;
+ else
+ m_names.Add (pnn3);
+ }
+
+ // MNS_STATUS <AB> G
+ netbios_name *pnn4 =
+ DBGetContactSettingByte (NULL, modname, "RegisterStatus", TRUE) ?
+ new netbios_name (MNS_STATUS, 0xab, true, m_le.lana [i]) : NULL;
+ if ( pnn4 )
+ m_names.Add( pnn4 );
+ }
+
+ //
+ for ( size_t i = 0; i < m_names.GetCount (); ++i )
+ {
+ if ( m_names [i]->Register() )
+ {
+ ret = true;
+ }
+ }
+
+ return ret;
+}
+
+// NetBIOS-
+void netbios::Deregister ()
+{
+ CLock oLock( m_csData );
+
+ //
+ for (size_t i = 0; i < m_names.GetCount (); ++i)
+ m_names [i]->Destroy();
+
+ //
+ for (size_t i = 0; i < m_names.GetCount (); ++i)
+ delete m_names [i];
+ m_names.RemoveAll ();
+}
diff --git a/plugins/!NotAdopted/WinPopup/netbios.h b/plugins/!NotAdopted/WinPopup/netbios.h
new file mode 100644
index 0000000000..a56294cb14
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/netbios.h
@@ -0,0 +1,134 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2011 Nikolay Raspopov
+
+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 "netbios_name.h"
+
+const DWORD SMB_MAGIC = 0x424d53ff; // 0xff 'S' 'M' 'B'
+const WORD SM_MAGIC = 0x4d53; // 'S' 'M'
+
+// NetBIOS datagrams:
+// (obsolete)
+const UCHAR SM_CHANGESTATUS = 0x01;
+// Status request: 'S' 'M' 0x02
+const UCHAR SM_GETSTATUS = 0x02;
+// Status answer: 'S' 'M' 0x03 status(i32)
+const UCHAR SM_SENDSTATUS = 0x03;
+// Away message request: 'S' 'M' 0x04
+const UCHAR SM_GETAWAYMESSAGE = 0x04;
+// Away message answer: 'S' 'M' 0x05 0x00(i32) message(ASCII)
+const UCHAR SM_SENDAWAYMESSAGE = 0x05;
+// Avatar request: 'S' 'M' 0x06
+const UCHAR SM_GETAVATAR = 0x06;
+// Avatar answer: 'S' 'M' 0x07 avatar
+const UCHAR SM_SENDAVATAR = 0x07;
+
+const LPCTSTR MNS_STATUS = _T("MNS_STATUS");
+
+#define MAX_AVATAR_SIZE 65000 // ()
+
+#pragma pack (push, 1)
+
+typedef struct _FIND_NAME_BLOCK
+{
+ FIND_NAME_HEADER fnb_header;
+ FIND_NAME_BUFFER fnb_Names [256];
+} FIND_NAME_BLOCK, *PFIND_NAME_BLOCK;
+
+typedef struct _ADAPTER_STATUS_BLOCK
+{
+ ADAPTER_STATUS asb_header;
+ NAME_BUFFER asb_Names [NCBNAMSZ];
+} ADAPTER_STATUS_BLOCK, *PADAPTER_STATUS_BLOCK;
+
+#pragma pack (pop)
+
+class netbios
+{
+public:
+ netbios();
+ ~netbios();
+
+ bool Create (BOOL registration);
+ void AskForDestroy(); //
+ void Destroy ();
+ operator bool() const;
+
+ bool SendNetBIOSMessage (HANDLE hContact, LPCTSTR msg /* ANSI */, DWORD& err);
+ ip FindNameIP (LPCTSTR szName /* ANSI */, UCHAR type = 3);
+ void GetRegisteredNames (netbios_name_list& names);
+ bool GetNames (netbios_name_list& names, LPCTSTR name /* ANSI */, bool bGroup);
+
+ //
+ netbios_name* GetName (const netbios_name& nname);
+
+ //
+ bool FindNameLana (const netbios_name& nname, UCHAR& lana);
+
+ bool GetMAC (UCHAR lana, CString& mac);
+ UCHAR FindName (const netbios_name& nname, UCHAR lana, FIND_NAME_BLOCK& fn);
+ UCHAR GetAdapterStatus (const netbios_name& nname, UCHAR lana, ADAPTER_STATUS_BLOCK& astat);
+ UCHAR EnumLanas (LANA_ENUM& le);
+ UCHAR ResetLana (UCHAR lana);
+ UCHAR Hangup (UCHAR lana, UCHAR lsn);
+ UCHAR Send (UCHAR lana, UCHAR lsn, unsigned char* data, WORD length);
+ UCHAR Recv (UCHAR lana, UCHAR lsn, unsigned char* data, WORD& length);
+ UCHAR Stat (const netbios_name& nname, SESSION_INFO_BLOCK* psibSession);
+ UCHAR Listen (const netbios_name& nname, UCHAR& lsn);
+ UCHAR AddName (netbios_name& nname);
+ UCHAR DeleteName (const netbios_name& nname);
+ UCHAR SendDatagram (const netbios_name& nname_from, const netbios_name& nname_to, unsigned char* data, WORD length);
+ UCHAR RecvDatagram (netbios_name& nname_from, const netbios_name& nname_to, unsigned char* data, WORD& length);
+ UCHAR Call (UCHAR lana, const netbios_name& nname_from, const netbios_name& nname_to, UCHAR& lsn);
+ unsigned char* SetSMBHeaderCommand (unsigned char* szHeader, BYTE iCommandCode, size_t iBufferLen);
+
+ // -
+ bool AskAway(const netbios_name& nname_to);
+ // -
+ bool SendAway(netbios_name& nname_from, const netbios_name& nname_to);
+ //
+ bool AskStatus(const netbios_name& nname_to);
+ //
+ bool SendStatus(netbios_name& nname_from, const netbios_name& nname_to);
+ // ( COMPUTER<03> U MNS_STATUS<ab> G)
+ bool BroadcastStatus();
+ //
+ bool AskAvatar(const netbios_name& nname_to);
+ //
+ bool SendAvatar(netbios_name& nname_from, const netbios_name& nname_to);
+
+protected:
+ bool m_initialized; // NetBIOS
+ netbios_name_array m_names; // NetBIOS-
+ LANA_ENUM m_le; //
+ CComAutoCriticalSection m_csData; //
+ CComAutoCriticalSection m_csNetBIOS; // NetBIOS
+
+ bool Register (); // NetBIOS-
+ void Deregister (); // NetBIOS-
+};
+
+extern netbios pluginNetBIOS; // / NetBIOS
+
+LPCSTR GetNetbiosCommand(UCHAR command);
+LPCSTR GetNetbiosError(UCHAR err);
+UCHAR NetbiosEx(NCB* pNCB);
diff --git a/plugins/!NotAdopted/WinPopup/netbios_name.cpp b/plugins/!NotAdopted/WinPopup/netbios_name.cpp
new file mode 100644
index 0000000000..ce3ad86ce7
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/netbios_name.cpp
@@ -0,0 +1,640 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2011 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "winpopup_proto.h"
+#include "netbios.h"
+#include "smbconst.h"
+#include "messagebox.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// Class netbios_name
+
+netbios_name::netbios_name(LPCTSTR n, UCHAR type, bool group, UCHAR lana) :
+ m_managed (false),
+ m_registered (false),
+ m_duplicated (false),
+ m_error (false),
+ m_lana (lana),
+ m_listener (NULL),
+ m_dgreceiver (NULL),
+ m_term (NULL)
+{
+ // NetBIOS-
+ int len = NCBNAMSZ - 1;
+ CT2A nA( n );
+ LPCSTR src = (LPCSTR)nA;
+ LPSTR dst = (LPSTR)netbiosed.name;
+ for ( ; len && *src; --len, ++dst, ++src )
+ *dst = *src;
+ for ( ; len; --len )
+ *dst++ = ' ';
+ *dst = (CHAR)type;
+ CharUpperBuffA( (LPSTR)netbiosed.name, NCBNAMSZ - 1 );
+ CharToOemBuffA( (LPSTR)netbiosed.name, (LPSTR)netbiosed.name, NCBNAMSZ - 1 );
+ netbiosed.name_num = 0;
+ netbiosed.name_flags = (UCHAR)( group ? GROUP_NAME : UNIQUE_NAME );
+
+ original = GetANSIName();
+}
+
+netbios_name::netbios_name(const NAME_BUFFER& n, UCHAR lana) :
+ m_managed (false),
+ m_registered (false),
+ m_duplicated (false),
+ m_error (false),
+ m_lana (lana),
+ m_listener (NULL),
+ m_dgreceiver (NULL),
+ m_term (NULL)
+{
+ CopyMemory (&netbiosed, &n, sizeof (NAME_BUFFER));
+ original = GetANSIName();
+}
+
+netbios_name& netbios_name::operator=(const netbios_name& n)
+{
+ _ASSERTE (m_managed == false);
+ m_managed = n.m_managed;
+ _ASSERTE (m_registered == false);
+ m_registered = n.m_registered;
+ _ASSERTE (m_duplicated == false);
+ m_duplicated = n.m_duplicated;
+ _ASSERTE (m_error == false);
+ m_error = n.m_error;
+ m_lana = n.m_lana;
+ _ASSERTE( m_listener == NULL );
+ m_listener = NULL;
+ _ASSERTE( m_dgreceiver == NULL );
+ m_dgreceiver = NULL;
+ _ASSERTE( m_term == NULL );
+ m_term = NULL;
+ CopyMemory (&netbiosed, &n.netbiosed, sizeof( NAME_BUFFER ));
+ original = n.original;
+ return *this;
+}
+
+netbios_name& netbios_name::operator= (const UCHAR* n)
+{
+ _ASSERTE (m_managed == false);
+ m_managed = false;
+ _ASSERTE (m_registered == false);
+ m_registered = false;
+ _ASSERTE (m_duplicated == false);
+ m_duplicated = false;
+ _ASSERTE (m_error == false);
+ m_error = false;
+ m_lana = 0;
+ _ASSERTE( m_listener == NULL );
+ m_listener = NULL;
+ _ASSERTE( m_dgreceiver == NULL );
+ m_dgreceiver = NULL;
+ _ASSERTE( m_term == NULL );
+ m_term = NULL;
+ CopyMemory (netbiosed.name, n, NCBNAMSZ);
+ netbiosed.name_num = 0;
+ netbiosed.name_flags = UNIQUE_NAME;
+ original = GetANSIName();
+
+ return *this;
+}
+
+bool netbios_name::operator== (const NAME_BUFFER& n) const
+{
+ return ( netbiosed.name [NCBNAMSZ - 1] == n.name [NCBNAMSZ - 1] ) &&
+ ( ( netbiosed.name_flags & GROUP_NAME ) == ( n.name_flags & GROUP_NAME ) ) &&
+ ( memcmp( netbiosed.name, n.name, NCBNAMSZ - 1 ) == 0 );
+}
+
+bool netbios_name::operator!= (const NAME_BUFFER& n) const
+{
+ return ! operator==( n );
+}
+
+bool netbios_name::operator== (const netbios_name& n) const
+{
+ return ( m_lana == n.m_lana ) && operator==( n.netbiosed );
+}
+
+bool netbios_name::operator!= (const netbios_name& n) const
+{
+ return ( m_lana != n.m_lana ) || operator!=( n.netbiosed );
+}
+
+bool netbios_name::Register()
+{
+ m_managed = true;
+
+ UCHAR ret = AddName ();
+ LOG("Register NetBIOS name \"%s\" on lana %d num=%d : 0x%02x \"%s\"", GetANSIFullName(), m_lana, netbiosed.name_num, ret, GetNetbiosError( ret ) );
+ m_registered = (ret == NRC_GOODRET);
+ m_duplicated = (ret == NRC_DUPNAME);
+ if ( ret != NRC_GOODRET && ret != NRC_DUPNAME )
+ {
+ WarningBox (NULL, (DWORD)MAKE_HRESULT (0, FACILITY_NETBIOS, ret),
+ _T("%s: %s"), TranslateT ("Cannot register NetBIOS name"), (LPCTSTR)CA2T( GetANSIFullName() ) );
+ }
+
+ if (!m_term)
+ m_term = CreateEvent (NULL, TRUE, FALSE, NULL);
+ else
+ ResetEvent (m_term);
+
+ if ( m_term && !m_listener )
+ m_listener = (HANDLE)mir_forkthread( ListenerThread, this );
+
+ if ( m_term && !m_dgreceiver &&
+ // NOTE: Win9x -
+ // .. Netbios()
+ //
+ !m_duplicated )
+ {
+ m_dgreceiver = (HANDLE)mir_forkthread( DatagramReceiverThread, this );
+ }
+
+ return m_registered;
+}
+
+void netbios_name::AskForDestroy()
+{
+ if (m_term)
+ SetEvent (m_term);
+}
+
+void netbios_name::Destroy()
+{
+ // -
+ if ( m_term ) SetEvent( m_term );
+
+ // ( , )
+ UCHAR ret = DeleteName ();
+ LOG("Unregister NetBIOS name \"%s\" on lana %d num=%d : 0x%02x \"%s\"", GetANSIFullName(), m_lana, netbiosed.name_num, ret, GetNetbiosError( ret ) );
+ m_registered = !(ret == NRC_GOODRET);
+ if ( m_duplicated )
+ {
+ //
+ m_duplicated = false;
+
+ // NOTE: -
+ // uReturn = AddName ();
+ // LOG("Restore NetBIOS name \"%s\" on lana %d : 0x%02x", GetANSIFullName(), m_lana, uReturn);
+ }
+
+ // ,
+ if ( m_listener )
+ {
+ if ( m_term ) SetEvent( m_term );
+ if (WaitForSingleObject (m_listener, ALMOST_INFINITE) == WAIT_TIMEOUT)
+ {
+ LOG("Terminate NetBIOS listener!");
+ TerminateThread (m_listener, 0);
+ }
+ m_listener = NULL;
+ }
+
+ if ( m_dgreceiver )
+ {
+ if ( m_term ) SetEvent( m_term );
+ if (WaitForSingleObject (m_dgreceiver, ALMOST_INFINITE) == WAIT_TIMEOUT)
+ {
+ LOG("Terminate NetBIOS datagram receiver!");
+ TerminateThread (m_dgreceiver, 0);
+ }
+ m_dgreceiver = NULL;
+ }
+
+ if ( m_term )
+ {
+ CloseHandle (m_term);
+ m_term = NULL;
+ }
+}
+
+CStringA netbios_name::GetANSIName() const
+{
+ CStringA sName;
+ LPSTR szName = sName.GetBuffer( NCBNAMSZ );
+ CopyMemory( szName, (LPCSTR)netbiosed.name, NCBNAMSZ - 1 );
+ szName[ NCBNAMSZ - 1 ] = 0;
+ sName.ReleaseBuffer();
+ sName.Trim();
+ sName.OemToAnsi();
+ return sName;
+}
+
+CStringA netbios_name::GetANSIFullName() const
+{
+ CStringA sType;
+ sType.Format( " <%02X>", GetType() );
+ return original + sType;
+}
+
+UCHAR netbios_name::GetType () const
+{
+ return netbiosed.name [NCBNAMSZ - 1];
+}
+
+bool netbios_name::IsGroupName () const
+{
+ return ((netbiosed.name_flags & GROUP_NAME) == GROUP_NAME);
+}
+
+bool netbios_name::IsRegistered () const
+{
+ return m_registered;
+}
+
+bool netbios_name::IsDuplicated () const
+{
+ return m_duplicated;
+}
+
+bool netbios_name::IsError () const
+{
+ return m_error;
+}
+
+bool netbios_name::IsOwnName () const
+{
+ return m_managed;
+}
+
+UCHAR netbios_name::GetLana () const
+{
+ return m_lana;
+}
+
+bool netbios_name::GetRealSender (UCHAR lsn, CStringA& sRealFrom) const
+{
+ sRealFrom.Empty ();
+
+ SESSION_INFO_BLOCK sibSession = {};
+ UCHAR dwInfoRes = pluginNetBIOS.Stat( *this, &sibSession );
+ if ( dwInfoRes == NRC_GOODRET )
+ {
+ for ( int i = 0; i < sibSession.sib_header.num_sess; i++ )
+ {
+ if ( sibSession.sib_Names [i].lsn == lsn )
+ {
+ //
+ const char* n = (const char*)sibSession.sib_Names [i].remote_name;
+ BYTE j = NCBNAMSZ - 2;
+ for ( ; j && ( n [ j ] == ' ' ); --j );
+ sRealFrom.Append( n, j + 1 );
+ sRealFrom.OemToAnsi();
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+size_t netbios_name::GetLength() const
+{
+ return (size_t)original.GetLength();
+}
+
+UCHAR netbios_name::AddName()
+{
+ return pluginNetBIOS.AddName( *this );
+}
+
+UCHAR netbios_name::DeleteName()
+{
+ return pluginNetBIOS.DeleteName( *this );
+}
+
+typedef struct _ReceiverData
+{
+ netbios_name* self;
+ UCHAR lsn;
+} ReceiverData;
+
+void netbios_name::Listener()
+{
+ m_error = false;
+ while ( WaitForSingleObject( m_term, 50 ) == WAIT_TIMEOUT )
+ {
+ UCHAR lsn = 0;
+ UCHAR ret = pluginNetBIOS.Listen( *this, lsn );
+ if ( ret != NRC_GOODRET )
+ {
+ LOG( "Listener : Closing \"%s\"", GetANSIFullName() );
+ m_error = true;
+ break;
+ }
+
+ LOG( "Listener : Got packet for \"%s\"", GetANSIFullName() );
+ if ( ReceiverData* data = (ReceiverData*)mir_alloc( sizeof( ReceiverData ) ) )
+ {
+ data->self = this;
+ data->lsn = lsn;
+ mir_forkthread( ReceiverThread, data );
+ }
+ }
+}
+
+void netbios_name::ListenerThread(LPVOID param)
+{
+ if ( netbios_name* pName = (netbios_name*)param )
+ {
+ pName->Listener();
+ pName->m_listener = NULL;
+ }
+}
+
+void netbios_name::DatagramReceiver()
+{
+ UCHAR* SMBBlock = (UCHAR*)mir_alloc( 65536 );
+ if ( ! SMBBlock )
+ {
+ m_error = true;
+ return;
+ }
+
+ m_error = false;
+ while ( WaitForSingleObject ( m_term, 50 ) == WAIT_TIMEOUT )
+ {
+ ZeroMemory( SMBBlock, 65536 );
+
+ WORD iReadedBytes = 65535;
+ netbios_name nname_from;
+ UCHAR ret = pluginNetBIOS.RecvDatagram( nname_from, *this, SMBBlock, iReadedBytes );
+ if ( ret != NRC_GOODRET )
+ {
+ // -
+ m_error = true;
+ break;
+ }
+
+ nname_from.m_lana = m_lana;
+
+ LOG( "Got datagram from \"%s\" to \"%s\"", nname_from.GetANSIFullName(), GetANSIFullName() );
+
+ // ?
+ if ( IsItMe ( CA2T( nname_from.original ) ) )
+ {
+ LOG( "DatagramReceiver : Ignoring my datagram" );
+ continue;
+ }
+
+ //
+ if ( iReadedBytes > 2 && *(WORD*)SMBBlock == SM_MAGIC )
+ {
+ UCHAR iMsgType = SMBBlock[ 2 ];
+ switch ( iMsgType )
+ {
+ case SM_GETSTATUS:
+ //
+ LOG( "DatagramReceiver : It's status request" );
+ pluginNetBIOS.SendStatus( *this, nname_from );
+ break;
+
+ case SM_SENDSTATUS:
+ //
+ if ( iReadedBytes == 2 + 1 + 4 )
+ {
+ HANDLE hContact = GetContact( CA2T( nname_from.original ) );
+ if ( hContact )
+ {
+ LOG( "DatagramReceiver : It's status answer" );
+ SetContactStatus( hContact, *(__int32*)(SMBBlock + 2 + 1), false );
+ }
+ else
+ LOG( "DatagramReceiver : Unknown contact" );
+ }
+ else
+ LOG( "DatagramReceiver : Invalid format" );
+ break;
+
+ case SM_GETAWAYMESSAGE:
+ // -
+ LOG( "DatagramReceiver : It's away request" );
+ pluginNetBIOS.SendAway( *this, nname_from );
+ break;
+
+ case SM_SENDAWAYMESSAGE:
+ // -
+ if ( iReadedBytes >= 2 + 1 + 4 )
+ {
+ if ( HANDLE hContact = GetContact( CA2T( nname_from.original ) ) )
+ {
+ LPCSTR szAway = (LPCSTR)( SMBBlock + 2 + 1 + 4 );
+ SMBBlock[ iReadedBytes ] = 0; // ASCII -> ASCIIZ
+
+ LOG( "DatagramReceiver : It's away answer \"%s\"", szAway );
+ SetContactAway( hContact, szAway );
+ }
+ else
+ LOG( "DatagramReceiver : Unknown contact" );
+ }
+ else
+ LOG( "DatagramReceiver : Invalid format" );
+ break;
+
+ case SM_GETAVATAR:
+ //
+ LOG( "DatagramReceiver : It's avatar request." );
+ pluginNetBIOS.SendAvatar( *this, nname_from );
+ break;
+
+ case SM_SENDAVATAR:
+ //
+ if ( iReadedBytes >= 2 + 1 && iReadedBytes < MAX_AVATAR_SIZE + 3 )
+ {
+ if ( HANDLE hContact = GetContact( CA2T( nname_from.original ) ) )
+ {
+ LOG( "DatagramReceiver : It's avatar answer" );
+ SetContactAvatar( hContact, SMBBlock + 2 + 1, (DWORD)iReadedBytes - 3 );
+ }
+ else
+ LOG( "DatagramReceiver : Unknown contact" );
+ }
+ else
+ LOG( "DatagramReceiver : Invalid format or too big avatar" );
+ break;
+
+ default:
+ LOG( "DatagramReceiver : Unsupported message type 0x%02x", iMsgType );
+ }
+ }
+ else
+ LOG( "DatagramReceiver : Unsupported data 0x%04x", *(WORD*)SMBBlock );
+ }
+
+ mir_free( SMBBlock );
+}
+
+void netbios_name::DatagramReceiverThread(LPVOID param)
+{
+ if ( netbios_name* pName = (netbios_name*)param )
+ {
+ pName->DatagramReceiver();
+ pName->m_dgreceiver = NULL;
+ }
+}
+
+void netbios_name::Receiver(UCHAR lsn)
+{
+ // Created by Ilja Razinkov (also known as IPv6), 2002, IPv6Intendo@yandex.ru
+ // Keep this comment if you redistribute this file
+
+ UCHAR* SMBBlock = (UCHAR*)mir_alloc( 65536 );
+ if ( ! SMBBlock )
+ return;
+
+ CStringA sTo, sFrom, sMessage;
+ UCHAR nRes;
+ for (;;)
+ {
+ ZeroMemory( SMBBlock, 65536 );
+
+ //
+ WORD iReadedBytes = 65535;
+ nRes = pluginNetBIOS.Recv (m_lana, lsn, SMBBlock, iReadedBytes);
+ if (nRes != NRC_GOODRET)
+ {
+ LOG( "Receiver : Error while receiving data block" );
+ break;
+ }
+
+ // - -
+ if ( iReadedBytes < 4 || *(DWORD*)SMBBlock != SMB_MAGIC )
+ {
+ LOG( "Receiver : Unsupported data 0x%08x", *(DWORD*)SMBBlock );
+ break;
+ }
+
+ UCHAR iMsgType = SMBBlock [4];
+ if (iMsgType != SMBsends &&
+ iMsgType != SMBsendstrt &&
+ iMsgType != SMBsendend &&
+ iMsgType != SMBsendtxt)
+ {
+ LOG( "Receiver : Unsupported message type 0x%02x", iMsgType );
+ break;
+ }
+
+ //
+ UCHAR szReply [SMB_HEADER_SIZE + 5];
+ UCHAR* szReplyData =
+ pluginNetBIOS.SetSMBHeaderCommand (szReply, iMsgType, sizeof (szReply));
+ if (iMsgType == SMBsendstrt)
+ {
+ //
+ static UCHAR rnd = 1;
+ szReplyData [0] = 1; //
+ szReplyData [1] = rnd++; //
+ if ( rnd > 5 )
+ rnd = 1;
+ }
+ nRes = pluginNetBIOS.Send (m_lana, lsn, szReply,
+ (WORD)( (iMsgType == SMBsendstrt) ? (SMB_HEADER_SIZE + 5) : (SMB_HEADER_SIZE + 3) ) );
+ if ( nRes != NRC_GOODRET )
+ {
+ //
+ LOG( "Receiver : Error while sending ack" );
+ }
+
+ //
+ if (iMsgType == SMBsends)
+ {
+ LOG( "Receiver : Got single-block message" );
+ // , ...
+ sFrom = (const char*) SMBBlock + SMB_HEADER_SIZE + 4;
+ int iFromOffset = sFrom.GetLength ();
+ sTo = (const char*) SMBBlock + SMB_HEADER_SIZE + 4 + iFromOffset + 2;
+ int iToOffset = sTo.GetLength ();
+ sMessage = (const char*) SMBBlock + SMB_HEADER_SIZE + 4 + iFromOffset + 2 +
+ iToOffset + 4;
+ break;
+ }
+ else if (iMsgType == SMBsendstrt)
+ {
+ LOG( "Receiver : Got start of multi-block message" );
+ // , ,
+ sFrom = (const char*) SMBBlock + SMB_HEADER_SIZE + 4;
+ int iFromOffset = sFrom.GetLength ();
+ sTo = (const char*) SMBBlock + SMB_HEADER_SIZE + iFromOffset + 4 + 2;
+ }
+ else if (iMsgType == SMBsendtxt)
+ {
+ // , , ...
+ int iConcatSize = iReadedBytes - SMB_HEADER_SIZE - 8;
+ LOG( "Receiver : Got text (%d-%d bytes) of multi-block message", sMessage.GetLength(), sMessage.GetLength() + iConcatSize - 1 );
+ sMessage.Append ((const char*) (SMBBlock + SMB_HEADER_SIZE + 8), iConcatSize);
+ }
+ else if (iMsgType == SMBsendend)
+ {
+ LOG( "Receiver : Got end of multi-block message" );
+ // , , ,
+ break;
+ }
+ }
+
+ sMessage.Replace( "\x14", "\r\n" ); // <14> -> <CR><LF>
+
+ sTo.OemToAnsi();
+ sFrom.OemToAnsi();
+ sMessage.OemToAnsi();
+
+ //
+ CStringA sRealFrom;
+ if (GetRealSender (lsn, sRealFrom))
+ {
+ LOG( "Receiver : Message from \"%s\" (real \"%s\") to \"%s\"", (LPCSTR)sFrom, (LPCSTR)sRealFrom, (LPCSTR)sTo);
+ sFrom = sRealFrom;
+ }
+ else
+ {
+ LOG( "Receiver : Message from \"%s\" (real sender unknown) to \"%s\"", (LPCSTR)sFrom, (LPCSTR)sTo);
+ }
+
+ // ...
+ pluginNetBIOS.Hangup (m_lana, lsn);
+
+ // ( )
+ if ( ! sMessage.IsEmpty() )
+ {
+ ReceiveContactMessage( CA2T( sFrom ), CA2T( sTo ), CA2T( sMessage ), sMessage.GetLength ());
+ }
+ else
+ {
+ LOG( "Receiver : Ignoring empty message" );
+ }
+
+ mir_free( SMBBlock );
+}
+
+void netbios_name::ReceiverThread(LPVOID param)
+{
+ if ( ReceiverData* data = (ReceiverData*)param )
+ {
+ data->self->Receiver( data->lsn );
+ mir_free( data );
+ }
+}
diff --git a/plugins/!NotAdopted/WinPopup/netbios_name.h b/plugins/!NotAdopted/WinPopup/netbios_name.h
new file mode 100644
index 0000000000..2d35531b33
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/netbios_name.h
@@ -0,0 +1,157 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2011 Nikolay Raspopov
+
+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
+
+#define SMB_ANY_NAME _T("* ")
+#define FACILITY_NETBIOS (0x0f0f)
+#define SMB_HEADER_SIZE (32)
+
+#pragma pack (push, 1)
+
+typedef struct SESSION_INFO_BLOCK
+{
+ SESSION_HEADER sib_header;
+ SESSION_BUFFER sib_Names[ NCBNAMSZ ];
+} SESSION_INFO_BLOCK, *PSESSION_INFO_BLOCK;
+
+#pragma pack (pop)
+
+class netbios_name
+{
+public:
+ netbios_name(LPCTSTR n = SMB_ANY_NAME /* ANSI */, UCHAR type = 0, bool group = false, UCHAR lana = 0);
+ netbios_name(const NAME_BUFFER& n, UCHAR lana);
+ netbios_name& operator=(const netbios_name& n);
+ netbios_name& operator=(const UCHAR* n);
+ // ( , , )
+ bool operator==(const NAME_BUFFER& n) const;
+ // ( , , )
+ bool operator!=(const NAME_BUFFER& n) const;
+ // ( , , , )
+ bool operator==(const netbios_name& n) const;
+ // ( , , , )
+ bool operator!=(const netbios_name& n) const;
+ //
+ bool Register();
+ //
+ void AskForDestroy();
+ //
+ void Destroy();
+ // NetBIOS- OEM ANSI : NAME <TYPE>
+ CStringA GetANSIFullName() const;
+
+ CStringA original; // ( ANSI )
+ NAME_BUFFER netbiosed; // NetBIOS ( OEM ):
+ // typedef struct _NAME_BUFFER {
+ // UCHAR name[NCBNAMSZ];
+ // UCHAR name_num;
+ // UCHAR name_flags;
+ // } NAME_BUFFER, *PNAME_BUFFER;
+
+ // :
+
+ UCHAR GetType() const;
+ bool IsGroupName() const;
+ bool IsRegistered() const;
+ bool IsDuplicated() const;
+ bool IsError() const;
+ bool IsOwnName() const;
+ UCHAR GetLana() const;
+ size_t GetLength() const; // NetBIOS
+
+protected:
+ bool m_managed; //
+ bool m_registered; //
+ bool m_duplicated; //
+ bool m_error; //
+ UCHAR m_lana; //
+ HANDLE m_listener; // -
+ HANDLE m_dgreceiver; // -
+ HANDLE m_term; // -
+
+ // NetBIOS- OEM ANSI
+ CStringA GetANSIName() const;
+
+ bool GetRealSender(UCHAR lsn, CStringA& sRealFrom) const;
+ UCHAR AddName();
+ UCHAR DeleteName();
+
+ //
+ void Listener();
+ static void ListenerThread(LPVOID param);
+
+ //
+ void DatagramReceiver();
+ static void DatagramReceiverThread(LPVOID param);
+
+ // ( Listener)
+ void Receiver(UCHAR lsn);
+ static void ReceiverThread(LPVOID param);
+};
+
+typedef CAtlArray <netbios_name*> netbios_name_array;
+typedef CAtlList <netbios_name> netbios_name_list;
+
+/*
+Name Number(h) Type Usage
+--------------------------------------------------------------------------
+<computername> 00 U Workstation Service
+<computername> 01 U Messenger Service
+<\\--__MSBROWSE__> 01 G Master Browser
+<computername> 03 U Messenger Service
+<computername> 06 U RAS Server Service
+<computername> 1F U NetDDE Service
+<computername> 20 U File Server Service
+<computername> 21 U RAS Client Service
+<computername> 22 U Microsoft Exchange Interchange(MSMail
+Connector)
+<computername> 23 U Microsoft Exchange Store
+<computername> 24 U Microsoft Exchange Directory
+<computername> 30 U Modem Sharing Server Service
+<computername> 31 U Modem Sharing Client Service
+<computername> 43 U SMS Clients Remote Control
+<computername> 44 U SMS Administrators Remote Control
+Tool
+<computername> 45 U SMS Clients Remote Chat
+<computername> 46 U SMS Clients Remote Transfer
+<computername> 4C U DEC Pathworks TCPIP service on
+Windows NT
+<computername> 42 U mccaffee anti-virus
+<computername> 52 U DEC Pathworks TCPIP service on
+Windows NT
+<computername> 87 U Microsoft Exchange MTA
+<computername> 6A U Microsoft Exchange IMC
+<computername> BE U Network Monitor Agent
+<computername> BF U Network Monitor Application
+<username> 03 U Messenger Service
+<domain> 00 G Domain Name
+<domain> 1B U Domain Master Browser
+<domain> 1C G Domain Controllers
+<domain> 1D U Master Browser
+<domain> 1E G Browser Service Elections
+<INet~Services> 1C G IIS
+<IS~computer name> 00 U IIS
+<computername> [2B] U Lotus Notes Server Service
+IRISMULTICAST [2F] G Lotus Notes
+IRISNAMESERVER [33] G Lotus Notes
+Forte_$ND800ZA [20] U DCA IrmaLan Gateway Server Service
+*/
diff --git a/plugins/!NotAdopted/WinPopup/network.cpp b/plugins/!NotAdopted/WinPopup/network.cpp
new file mode 100644
index 0000000000..4f51318e08
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/network.cpp
@@ -0,0 +1,88 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2010 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "network.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+// , IPv4- xx.xx.xx.xx
+bool IsValidIP (LPCTSTR name)
+{
+ int dots = 0;
+ bool digit = false;
+ for ( ; *name; name++ )
+ {
+ if ( *name == _T('.') )
+ {
+ if ( ! digit )
+ //
+ return false;
+
+ dots++;
+ digit = false;
+ }
+ else if ( *name < _T('0') || *name > _T('9') )
+ {
+ //
+ return false;
+ }
+ else
+ {
+ digit = true;
+ }
+ }
+ return dots == 3 && digit;
+}
+
+// IP
+ip ResolveToIP (CString& name)
+{
+ // IP-
+ ip addr = IsValidIP (name) ? ::inet_addr ( CT2A( name ) ) : INADDR_NONE;
+ if (addr != INADDR_NONE) {
+ struct hostent *hp = ::gethostbyaddr ((const char*) &addr, sizeof (addr), AF_INET);
+ if (hp) {
+ //
+ name = hp->h_name;
+ int n = name.Find ('.');
+ if (n != -1)
+ name = name.Left (n);
+ }
+ }
+ // IP-
+ if (addr == INADDR_NONE) {
+ struct hostent *hp = ::gethostbyname ( CT2A( name ) );
+ if (hp) {
+ addr = ((struct in_addr*)hp->h_addr)->s_addr;
+ //
+ name = hp->h_name;
+ int n = name.Find ('.');
+ if (n != -1)
+ name = name.Left (n);
+ }
+ }
+ return ntohl (addr);
+}
diff --git a/plugins/!NotAdopted/WinPopup/network.h b/plugins/!NotAdopted/WinPopup/network.h
new file mode 100644
index 0000000000..541c764fbc
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/network.h
@@ -0,0 +1,31 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2009 Nikolay Raspopov
+
+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
+
+// IPv4
+typedef unsigned long ip;
+
+// , IP- xx.xx.xx.xx
+bool IsValidIP (LPCTSTR name);
+
+// IP
+ip ResolveToIP (CString& name);
diff --git a/plugins/!NotAdopted/WinPopup/options.cpp b/plugins/!NotAdopted/WinPopup/options.cpp
new file mode 100644
index 0000000000..bfc227402a
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/options.cpp
@@ -0,0 +1,392 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2011 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "winpopup_proto.h"
+#include "services.h"
+#include "options.h"
+#include "netbios.h"
+#include "add_dialog.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+#define WM_FILLTREE (WM_USER+75)
+
+static netbios_name_list nns;
+static HWND hTree = NULL;
+
+typedef struct _DlgDataOptions
+{
+ HMODULE hContact;
+ HIMAGELIST hTreeImages;
+ bool need_restart;
+} DlgDataOptions;
+
+static void FillTreeThread (LPVOID param)
+{
+ // NetBIOS (20 )
+ for ( int i = 0; i < 20 && ! pluginNetBIOS && IsWindow( hTree ); i++ )
+ Sleep( 1000 );
+
+ if ( IsWindow( hTree ) )
+ {
+ // ...
+ pluginNetBIOS.GetRegisteredNames( nns );
+ // ...
+ pluginNetBIOS.GetNames( nns, pluginMachineName, false );
+ // ...
+ PostMessage( reinterpret_cast <HWND>(param), WM_FILLTREE, 0, 0 );
+ }
+}
+
+static void Refresh (HWND hwndDlg, HWND hwndTree)
+{
+ bool bOnline = ( pluginCurrentStatus != ID_STATUS_OFFLINE );
+
+ nns.RemoveAll ();
+
+ // ...
+ TreeView_DeleteAllItems (hwndTree);
+ TVINSERTSTRUCT tvis = { TVI_ROOT, TVI_LAST };
+ tvis.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ tvis.item.iImage = tvis.item.iSelectedImage = bOnline ? 0 : 8;
+ tvis.item.pszText = bOnline ? TranslateT("Retrieving...") : TranslateT("Offline");
+ TreeView_InsertItem (hwndTree, &tvis);
+
+ if ( bOnline )
+ {
+ //
+ mir_forkthread( FillTreeThread, hwndDlg );
+ }
+}
+
+static INT_PTR CALLBACK DlgProcOptions (HWND hwndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ static bool bLastOnline = false;
+ DlgDataOptions* data = reinterpret_cast <DlgDataOptions*> (GetWindowLongPtr (hwndDlg, DWLP_USER));
+
+ switch ( Msg )
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault (hwndDlg);
+
+ data = (DlgDataOptions*)mir_alloc( sizeof( DlgDataOptions ) );
+ if ( ! data )
+ return FALSE;
+
+ SetWindowLongPtr (hwndDlg, DWLP_USER, reinterpret_cast <LONG> (data));
+ data->need_restart = false;
+ data->hTreeImages = ImageList_Create (16, 16, ILC_COLOR8 | ILC_MASK, 8, 0);
+
+ hTree = GetDlgItem (hwndDlg, IDC_TREE);
+
+ ImageList_AddIcon (data->hTreeImages, reinterpret_cast <HICON> (LoadImage ( // 0
+ pluginModule, MAKEINTRESOURCE (IDI_COMPUTER), IMAGE_ICON, 16, 16, LR_SHARED )));
+
+ ImageList_AddIcon (data->hTreeImages, reinterpret_cast <HICON> (LoadImage ( // 1
+ pluginModule, MAKEINTRESOURCE (IDI_LANA), IMAGE_ICON, 16, 16, LR_SHARED )));
+
+ HICON hIcon;
+ hIcon = reinterpret_cast <HICON> (LoadImage (
+ pluginModule, MAKEINTRESOURCE (IDI_GOOD_NAME), IMAGE_ICON, 16, 16, LR_SHARED ));
+ ImageList_AddIcon (data->hTreeImages, hIcon); // 2
+ SendDlgItemMessage (hwndDlg, IDC_LEGEND_1, STM_SETICON,
+ reinterpret_cast <WPARAM> (hIcon), 0);
+
+ hIcon = reinterpret_cast <HICON> (LoadImage (
+ pluginModule, MAKEINTRESOURCE (IDI_BAD_NAME), IMAGE_ICON, 16, 16, LR_SHARED ));
+ ImageList_AddIcon (data->hTreeImages, hIcon); // 3
+ SendDlgItemMessage (hwndDlg, IDC_LEGEND_2, STM_SETICON,
+ reinterpret_cast <WPARAM> (hIcon), 0);
+
+ hIcon = reinterpret_cast <HICON> (LoadImage (
+ pluginModule, MAKEINTRESOURCE (IDI_OTHER_NAME), IMAGE_ICON, 16, 16, LR_SHARED ));
+ ImageList_AddIcon (data->hTreeImages, hIcon); // 4
+ SendDlgItemMessage (hwndDlg, IDC_LEGEND_3, STM_SETICON,
+ reinterpret_cast <WPARAM> (hIcon), 0);
+
+ hIcon = reinterpret_cast <HICON> (LoadImage (
+ pluginModule, MAKEINTRESOURCE (IDI_GOOD_NAMES), IMAGE_ICON, 16, 16, LR_SHARED ));
+ ImageList_AddIcon (data->hTreeImages, hIcon); // 5
+ SendDlgItemMessage (hwndDlg, IDC_LEGEND_4, STM_SETICON,
+ reinterpret_cast <WPARAM> (hIcon), 0);
+
+ hIcon = reinterpret_cast <HICON> (LoadImage (
+ pluginModule, MAKEINTRESOURCE (IDI_BAD_NAMES), IMAGE_ICON, 16, 16, LR_SHARED ));
+ ImageList_AddIcon (data->hTreeImages, hIcon); // 6
+ SendDlgItemMessage (hwndDlg, IDC_LEGEND_5, STM_SETICON,
+ reinterpret_cast <WPARAM> (hIcon), 0);
+
+ hIcon = reinterpret_cast <HICON> (LoadImage (
+ pluginModule, MAKEINTRESOURCE (IDI_OTHER_NAMES), IMAGE_ICON, 16, 16, LR_SHARED ));
+ ImageList_AddIcon (data->hTreeImages, hIcon); // 7
+ SendDlgItemMessage (hwndDlg, IDC_LEGEND_6, STM_SETICON,
+ reinterpret_cast <WPARAM> (hIcon), 0);
+
+ hIcon = reinterpret_cast <HICON> (LoadImage (
+ pluginModule, MAKEINTRESOURCE (IDI_COMPUTER_ERROR), IMAGE_ICON, 16, 16, LR_SHARED ));
+ ImageList_AddIcon (data->hTreeImages, hIcon); // 8
+
+ TreeView_SetImageList (hTree, data->hTreeImages, TVSIL_NORMAL);
+
+ BOOL b = DBGetContactSettingByte (NULL, modname, "RegisterNick", TRUE);
+ CheckDlgButton (hwndDlg, IDC_CHECK_NICK, (UINT)( b ? BST_CHECKED : BST_UNCHECKED ));
+ EnableWindow (GetDlgItem (hwndDlg, IDC_NICK1), b);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_NICK2), b);
+
+ b = DBGetContactSettingByte (NULL, modname, "RegisterUser", TRUE);
+ CheckDlgButton (hwndDlg, IDC_CHECK_USER, (UINT)( b ? BST_CHECKED : BST_UNCHECKED ));
+ EnableWindow (GetDlgItem (hwndDlg, IDC_USER), b);
+
+ CheckDlgButton (hwndDlg, IDC_AUTOANSWER,
+ (UINT)( DBGetContactSettingByte (NULL, modname, "Auto-answer", FALSE) ?
+ BST_CHECKED : BST_UNCHECKED ) );
+ CheckDlgButton (hwndDlg, IDC_DUPS,
+ (UINT)( DBGetContactSettingByte (NULL, modname, "Filter-dups", TRUE) ?
+ BST_CHECKED : BST_UNCHECKED ) );
+ CheckDlgButton (hwndDlg, IDC_ALWAYSCHECK00FORONLINE,
+ (UINT)( IsLegacyOnline( NULL ) ? BST_CHECKED : BST_UNCHECKED ) );
+
+ BYTE method = (BYTE) DBGetContactSettingByte (NULL, modname, "SendMethod", 0);
+ CheckRadioButton (hwndDlg, IDC_USE_MAILSLOT, IDC_USE_NETSEND,
+ IDC_USE_MAILSLOT + method);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_USE_NETSEND), (fnNetMessageBufferSend != NULL));
+
+ CString sMyNick = GetNick( NULL );
+ if ( ! sMyNick.IsEmpty() )
+ {
+ netbios_name nname (sMyNick, 3);
+ SetDlgItemText (hwndDlg, IDC_NICK1, CA2T( nname.GetANSIFullName() ) );
+ }
+
+ if ( ! sMyNick.IsEmpty() )
+ {
+ netbios_name nname (sMyNick, 1);
+ SetDlgItemText (hwndDlg, IDC_NICK2, CA2T( nname.GetANSIFullName() ) );
+ }
+
+ DBVARIANT dbv = {};
+ if ( ! DBGetContactSettingTString( NULL, modname, "User", &dbv ) )
+ {
+ netbios_name nname (dbv.ptszVal, 3);
+ SetDlgItemText (hwndDlg, IDC_USER, CA2T( nname.GetANSIFullName() ) );
+ DBFreeVariant (&dbv);
+ }
+
+ bLastOnline = ! ( pluginCurrentStatus != ID_STATUS_OFFLINE );
+
+ SetTimer( hwndDlg, 55, 500, NULL );
+
+ return TRUE;
+ }
+
+ case WM_TIMER:
+ if ( bLastOnline != ( pluginCurrentStatus != ID_STATUS_OFFLINE ) )
+ {
+ bLastOnline = ( pluginCurrentStatus != ID_STATUS_OFFLINE );
+ Refresh( hwndDlg, hTree );
+ }
+ return TRUE;
+
+ case WM_DESTROY:
+ {
+ nns.RemoveAll();
+ SetWindowLongPtr( hwndDlg, DWLP_USER, NULL );
+ if ( data )
+ {
+ ImageList_Destroy( data->hTreeImages );
+ mir_free( data );
+ }
+ hTree = NULL;
+ break;
+ }
+
+ case WM_FILLTREE:
+ {
+ //
+ TreeView_DeleteAllItems (hTree);
+ TVINSERTSTRUCT tvis = { TVI_ROOT, TVI_LAST };
+ tvis.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
+ tvis.item.pszText = (LPTSTR)(LPCTSTR)pluginMachineName;
+ tvis.item.iImage = tvis.item.iSelectedImage = nns.GetCount() ? 0 : 8;
+ HTREEITEM hRoot = TreeView_InsertItem (hTree, &tvis);
+ if ( nns.GetCount() )
+ {
+ TVITEM item = { 0 };
+ for (POSITION pos = nns.GetHeadPosition (); pos;)
+ {
+ netbios_name nname (nns.GetNext (pos));
+ tvis.item.lParam = nname.GetLana();
+
+ //
+ item.hItem = TreeView_GetChild (hTree, hRoot);
+ while (item.hItem)
+ {
+ item.mask = TVIF_HANDLE | TVIF_PARAM;
+ if (TreeView_GetItem (hTree, &item) &&
+ item.lParam == nname.GetLana ())
+ //
+ break;
+ item.hItem = TreeView_GetNextSibling (hTree, item.hItem);
+ }
+ if (item.hItem)
+ //
+ tvis.hParent = item.hItem;
+ else
+ {
+ //
+ tvis.hParent = hRoot;
+ tvis.item.iImage = tvis.item.iSelectedImage = 1;
+ CString tmp;
+ tmp.Format ( _T("%s #%d"), TranslateT ("LAN adapter"), nname.GetLana ());
+ tvis.item.pszText = (LPTSTR) (LPCTSTR) tmp;
+ tvis.hParent = TreeView_InsertItem (hTree, &tvis);
+
+ pluginNetBIOS.GetMAC (nname.GetLana (), tmp);
+ tmp.Insert (0, _T("MAC: "));
+ tvis.item.pszText = (LPTSTR) (LPCTSTR) tmp;
+ TreeView_InsertItem (hTree, &tvis);
+ }
+
+ CA2T textT( nname.GetANSIFullName() );
+ tvis.item.pszText = (LPTSTR)(LPCTSTR)textT;
+ tvis.item.iImage = tvis.item.iSelectedImage =
+ (nname.IsOwnName () ? (nname.IsError () ? 1 : 0) : 2) +
+ (nname.IsGroupName () ? 5 : 2);
+
+ //
+ item.hItem = TreeView_GetChild (hTree, tvis.hParent);
+ while (item.hItem)
+ {
+ item.mask = TVIF_HANDLE | TVIF_TEXT;
+ item.cchTextMax = 64;
+ CString tmp;
+ item.pszText = tmp.GetBuffer (item.cchTextMax);
+ BOOL ret = TreeView_GetItem (hTree, &item);
+ tmp.ReleaseBuffer ();
+ if (ret && tmp == textT )
+ //
+ break;
+ item.hItem = TreeView_GetNextSibling (hTree, item.hItem);
+ }
+ if (!item.hItem)
+ //
+ TreeView_InsertItem (hTree, &tvis);
+ }
+ }
+ TreeView_Expand (hTree, hRoot, TVE_EXPAND);
+
+ nns.RemoveAll ();
+ return TRUE;
+ }
+
+ case WM_NOTIFY:
+ {
+ LPPSHNOTIFY lpHdr = reinterpret_cast <LPPSHNOTIFY> (lParam);
+ if (lpHdr->hdr.idFrom == 0) {
+ data->hContact = reinterpret_cast <HMODULE> (lpHdr->lParam);
+ switch (lpHdr->hdr.code) {
+ case PSN_KILLACTIVE:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
+ return TRUE;
+
+ case PSN_APPLY:
+ DBWriteContactSettingByte (NULL, modname, "RegisterNick",
+ (BYTE)( (IsDlgButtonChecked (hwndDlg, IDC_CHECK_NICK) == BST_CHECKED ? TRUE : FALSE ) ));
+ DBWriteContactSettingByte (NULL, modname, "RegisterUser",
+ (BYTE)( (IsDlgButtonChecked (hwndDlg, IDC_CHECK_USER) == BST_CHECKED ? TRUE : FALSE ) ));
+ DBWriteContactSettingByte (NULL, modname, "Auto-answer",
+ (BYTE)( (IsDlgButtonChecked (hwndDlg, IDC_AUTOANSWER) == BST_CHECKED ? TRUE : FALSE ) ));
+ DBWriteContactSettingByte (NULL, modname, "Filter-dups",
+ (BYTE)( (IsDlgButtonChecked (hwndDlg, IDC_DUPS) == BST_CHECKED ? TRUE : FALSE ) ));
+ DBWriteContactSettingByte (NULL, modname, "SendMethod",
+ (BYTE)( (((IsDlgButtonChecked (hwndDlg, IDC_USE_MAILSLOT) == BST_CHECKED) ? 0 :
+ ((IsDlgButtonChecked (hwndDlg, IDC_USE_NETBIOS) == BST_CHECKED) ? 1 :
+ ((IsDlgButtonChecked (hwndDlg, IDC_USE_NETSEND) == BST_CHECKED) ? 2 :
+ 0 ) )))));
+ SetLegacyOnline( NULL, ( IsDlgButtonChecked( hwndDlg,
+ IDC_ALWAYSCHECK00FORONLINE ) == BST_CHECKED ) );
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
+ if (data->need_restart) {
+ data->need_restart = false;
+ GotoOffline ();
+ Sleep (2000);
+ Refresh (hwndDlg, hTree);
+ }
+ return TRUE;
+ }
+ }
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam)) {
+ case IDC_CHECK_NICK:
+ case IDC_CHECK_USER:
+ EnableWindow (GetDlgItem (hwndDlg, IDC_NICK1),
+ IsDlgButtonChecked (hwndDlg, IDC_CHECK_NICK) == BST_CHECKED);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_NICK2),
+ IsDlgButtonChecked (hwndDlg, IDC_CHECK_NICK) == BST_CHECKED);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_USER),
+ IsDlgButtonChecked (hwndDlg, IDC_CHECK_USER) == BST_CHECKED);
+
+ case IDC_USE_MAILSLOT:
+ case IDC_USE_NETBIOS:
+ case IDC_USE_NETSEND:
+ data->need_restart = true;
+
+ case IDC_AUTOANSWER:
+ case IDC_ALWAYSCHECK00FORONLINE:
+ case IDC_DUPS:
+ PropSheet_Changed (GetParent (hwndDlg), hwndDlg);
+ break;
+
+ case IDC_ADD:
+ AddDialog( hwndDlg );
+ break;
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+int __cdecl OPT_INITIALISE (WPARAM wParam, LPARAM /* lParam */)
+{
+ OPTIONSDIALOGPAGE odp = {};
+ odp.cbSize = sizeof ( OPTIONSDIALOGPAGE );
+ odp.pszGroup = "Network";
+ odp.position = odp.pszGroup [0];
+ odp.hInstance = pluginModule;
+ odp.pszTemplate = MAKEINTRESOURCEA (IDD_OPTIONS);
+ odp.pszTitle = modtitle;
+ odp.pfnDlgProc = DlgProcOptions;
+ odp.flags = ODPF_BOLDGROUPS;
+ CallService (MS_OPT_ADDPAGE, wParam, (LPARAM) &odp);
+
+ return 0;
+}
diff --git a/plugins/!NotAdopted/WinPopup/options.h b/plugins/!NotAdopted/WinPopup/options.h
new file mode 100644
index 0000000000..8b7d8b8bec
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/options.h
@@ -0,0 +1,24 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2006 Nikolay Raspopov
+
+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
+
+int __cdecl OPT_INITIALISE (WPARAM wParam, LPARAM lParam);
diff --git a/plugins/!NotAdopted/WinPopup/processapi.cpp b/plugins/!NotAdopted/WinPopup/processapi.cpp
new file mode 100644
index 0000000000..d37578aed1
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/processapi.cpp
@@ -0,0 +1,578 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2010 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "processapi.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+DWORD GetProcessId (LPCTSTR name)
+{
+ DWORD id = 0;
+ int name_len = lstrlen (name);
+ CProcessApi papi;
+ if (papi.Init (true)) {
+ DWORD pl = papi.ProcessesGetList();
+ if (pl) {
+ CProcessApi::tProcessInfo pi = {0};
+ while (papi.ProcessesWalk (pl, &pi)) {
+ int len = lstrlen (pi.FileName);
+ if (len >= name_len &&
+ lstrcmpi (pi.FileName + (len - name_len), name) == 0) {
+ id = pi.pid;
+ break;
+ }
+ }
+ }
+ papi.ProcessesFreeList(pl);
+ }
+ return id;
+}
+
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2003 Elias Bachaalany <elias_bachaalany@yahoo.com>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ * -----------------------------------------------------------------------------
+ */
+
+#ifdef _UNICODE
+ #define Modifier "W"
+#else
+ #define Modifier "A"
+#endif
+
+// custom macro to allow me to load functions dynamically
+#define DynamicGetProcAddress(lib, prefix, mod_name, Mod) \
+ { \
+ PVOID p = GetProcAddress(lib, #mod_name Mod); \
+ if (!p) { \
+ FreeLibrary(lib); \
+ return (LastError = paeNoEntryPoint, false); \
+ } \
+ ##prefix##mod_name = (t_##prefix##mod_name)p; \
+ }
+
+//--------------------------------------------------------------------------------------------
+// The constructor only initializes some internal variables
+CProcessApi::CProcessApi() :
+ m_hPsApi (NULL),
+ m_hTlHlp (NULL),
+ m_hNtApi (NULL),
+ m_bPsApi (false),
+ m_bToolHelp (false),
+ m_bNtApi (false),
+ LastError (paeSuccess)
+{
+}
+
+//--------------------------------------------------------------------------------------------
+// This is the destructor. It frees any process helper api that has been used
+CProcessApi::~CProcessApi()
+{
+ if (m_hPsApi)
+ FreeLibrary(m_hPsApi);
+ if (m_hTlHlp)
+ FreeLibrary(m_hTlHlp);
+ if (m_hNtApi)
+ FreeLibrary(m_hNtApi);
+}
+
+//--------------------------------------------------------------------------------------------
+// Used to initialize the CProcessApi class
+bool CProcessApi::Init (bool bNtApiFirst)
+{
+ bool loaded = m_bPsApi || m_bToolHelp || m_bNtApi;
+
+ if (bNtApiFirst && !loaded) {
+ loaded = Load_NtApi();
+ }
+
+ if (!loaded) {
+ loaded = Load_PsApi();
+ }
+
+ if (!loaded) {
+ loaded = Load_TlHlp();
+ }
+
+ if (!bNtApiFirst && !loaded) {
+ loaded = Load_NtApi();
+ }
+
+ return (loaded ? (LastError = paeSuccess, true) : (LastError = paeNoApi, false));
+}
+
+//--------------------------------------------------------------------------------------------
+// This function returns a list id (list id) that can be used w/ Walking functions
+// in order to navigate through the process list
+// This function decides what to use from the helper apis
+DWORD CProcessApi::ModulesGetList(DWORD pid)
+{
+ tModulesData *md = new tModulesData;
+ if ( ! md )
+ return (LastError = paeNoMem, 0u);
+
+ // create the list
+ md->ml = new tModulesList;
+ if ( ! md->ml )
+ {
+ delete md;
+ return (LastError = paeNoMem, 0u);
+ }
+
+ // decide what to use
+ if (m_bPsApi)
+ LastError = ModulesPopulatePsApi(pid, md);
+ else if (m_bToolHelp)
+ LastError = ModulesPopulateToolHelp(pid, md);
+ else if (m_bNtApi)
+ LastError = ModulesPopulateNtApi(pid, md);
+
+ return (DWORD) md;
+}
+
+//--------------------------------------------------------------------------------------------
+// Populates the modules of a process using ToolHelp api
+DWORD CProcessApi::ModulesPopulateToolHelp(DWORD pid, tModulesData *md)
+{
+ MODULEENTRY32 me32 = {sizeof(MODULEENTRY32), 0};
+ tModuleInfo mi = {0};
+
+ // Take a snapshot of all modules in the specified process.
+ HANDLE hModuleSnap = tlhlp_CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
+
+ if (hModuleSnap == INVALID_HANDLE_VALUE)
+ return paeNoSnap;
+
+ // Start walking
+ BOOL bMore = tlhlp_Module32First(hModuleSnap, &me32);
+ do
+ {
+ lstrcpy (mi.FileName, me32.szExePath);
+ mi.ImageBase = me32.modBaseAddr;
+ mi.ImageSize = me32.modBaseSize;
+
+ // save item
+ md->ml->Add (mi);
+
+ // search next
+ bMore = tlhlp_Module32Next(hModuleSnap, &me32);
+ } while (bMore);
+
+ CloseHandle (hModuleSnap);
+ md->Pos = 0;
+ return paeSuccess;
+}
+
+//--------------------------------------------------------------------------------------------
+// Populates the modules of a process using PsApi api
+DWORD CProcessApi::ModulesPopulatePsApi(DWORD pid, tModulesData *md)
+{
+ DWORD nModules, nCount = 4096;
+ HANDLE hProcess;
+
+ // allocate memory for modules
+ HMODULE *modules = new HMODULE[nCount];
+
+ // open process for querying only
+ hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
+ if (!hProcess)
+ return paeNoSnap;
+
+ // now try to enum all modules
+ if (!psapi_EnumProcessModules(hProcess, modules, nCount * sizeof(DWORD), &nModules))
+ {
+ CloseHandle(hProcess);
+ return paeNoSnap;
+ }
+
+ // because nModules returned from EnumProcessModules() is in bytes, I divid by 4 to return n DWORDs
+ nModules /= 4;
+
+ tModuleInfo mi = {0};
+ MODULEINFO psapiMi = {0};
+
+ for (DWORD i=0; i < nModules; i++)
+ {
+ // get module name
+ psapi_GetModuleFileNameEx(hProcess, modules[i], mi.FileName, sizeof(mi.FileName));
+
+ // get module information
+ psapi_GetModuleInformation(hProcess, modules[i], &psapiMi, sizeof(MODULEINFO));
+
+ // get relevant data
+ mi.ImageBase = psapiMi.lpBaseOfDll;
+ mi.ImageSize = psapiMi.SizeOfImage;
+
+ // save item
+ md->ml->Add (mi);
+ }
+
+ md->Pos = 0;
+ CloseHandle(hProcess);
+ delete [] modules;
+
+ return paeSuccess;
+}
+
+//--------------------------------------------------------------------------------------------
+// It frees a modules list by its ID
+void CProcessApi::ModulesFreeList(DWORD_PTR lid)
+{
+ tModulesData *md = reinterpret_cast<tModulesData *>(lid);
+ delete md->ml;
+ delete md;
+}
+
+//--------------------------------------------------------------------------------------------
+// This function allows you to retrieve information about a certain module in a process
+// You can either use this function using the Pos parameter controlled by the ModulesCount()
+// Or you can keep calling it till it returns false
+bool CProcessApi::ModulesWalk(DWORD_PTR lid, tModuleInfo *mi, DWORD Pos)
+{
+ tModulesData *md = reinterpret_cast<tModulesData *>(lid);
+
+ // auto position ?
+ if (Pos == -1)
+ Pos = md->Pos;
+
+ // out of bounds?
+ if (Pos > md->ml->GetCount())
+ return (LastError = paeOutOfBounds, false);
+
+ // end reached ?
+ else if (Pos == md->ml->GetCount())
+ return (LastError = paeNoMore, false);
+
+ // copy information to user buffer
+ *mi = md->ml->GetAt (Pos);
+
+ // advance position to next item
+ md->Pos++;
+
+ return (LastError = paeSuccess, true);
+}
+
+
+//--------------------------------------------------------------------------------------------
+// This function allows you to retrieve information about a certain process in the list
+// You can either use this function using the Pos parameter controlled by the ProcessesCount()
+// Or you can keep calling it till it returns false
+bool CProcessApi::ProcessesWalk(DWORD_PTR lid, tProcessInfo *pi, DWORD Pos)
+{
+ tProcessesData *pd = reinterpret_cast<tProcessesData *>(lid);
+
+ // auto position ?
+ if (Pos == -1)
+ Pos = pd->Pos;
+
+ // out of bounds?
+ if (Pos > pd->pl->GetCount())
+ return (LastError = paeOutOfBounds, false);
+ // end reached ?
+ else if (Pos == pd->pl->GetCount())
+ return (LastError = paeNoMore, false);
+
+ // copy information to user buffer
+ *pi = pd->pl->GetAt (Pos);
+
+ // advance position to next item
+ pd->Pos++;
+ return (LastError = paeSuccess, true);
+}
+
+
+//--------------------------------------------------------------------------------------------
+// This function returns a list id (list id) that can be used w/ Walking functions
+// in order to navigate through the process list
+// This function decides what to use from the helper apis
+DWORD CProcessApi::ProcessesGetList()
+{
+ tProcessesData *pd = new tProcessesData;
+ if (!pd)
+ return (LastError = paeNoMem, 0u);
+
+ // create the list
+ pd->pl = new tProcessesList;
+ if (!pd->pl)
+ {
+ delete pd;
+ return (LastError = paeNoMem, 0u);
+ }
+
+ // decide what to use
+ if (m_bPsApi)
+ LastError = ProcessesPopulatePsApi(pd);
+ else if (m_bToolHelp)
+ LastError = ProcessesPopulateToolHelp(pd);
+ else if (m_bNtApi)
+ LastError = ProcessesPopulateNtApi(pd);
+
+ return (DWORD) pd;
+}
+
+//--------------------------------------------------------------------------------------------
+// It frees a process list by its ID
+void CProcessApi::ProcessesFreeList(DWORD_PTR lid)
+{
+ tProcessesData *pd = reinterpret_cast<tProcessesData *>(lid);
+ delete pd->pl;
+ delete pd;
+}
+
+//--------------------------------------------------------------------------------------------
+// Dynamically loads the PsApi functions
+bool CProcessApi::Load_PsApi()
+{
+ if (m_bPsApi)
+ return true;
+ if (!m_hPsApi)
+ m_hPsApi = LoadLibrary (_T("psapi.dll"));
+ if (!m_hPsApi)
+ return false;
+
+ DynamicGetProcAddress(m_hPsApi, psapi_, GetModuleFileNameEx, Modifier);
+ DynamicGetProcAddress(m_hPsApi, psapi_, EnumProcessModules, "");
+ DynamicGetProcAddress(m_hPsApi, psapi_, EnumProcesses, "");
+ DynamicGetProcAddress(m_hPsApi, psapi_, GetModuleInformation, "");
+
+ m_bPsApi = true;
+ return true;
+}
+
+
+//--------------------------------------------------------------------------------------------
+// Dynamically loads the ToolHelp functions
+bool CProcessApi::Load_TlHlp()
+{
+ if (m_bToolHelp)
+ return true;
+ if (!m_hTlHlp)
+ m_hTlHlp = LoadLibrary (_T("kernel32.dll"));
+ if (!m_hTlHlp)
+ return false;
+
+ DynamicGetProcAddress(m_hTlHlp, tlhlp_, CreateToolhelp32Snapshot, "");
+ DynamicGetProcAddress(m_hTlHlp, tlhlp_, Process32First, "");
+ DynamicGetProcAddress(m_hTlHlp, tlhlp_, Process32Next, "");
+ DynamicGetProcAddress(m_hTlHlp, tlhlp_, Module32First, "");
+ DynamicGetProcAddress(m_hTlHlp, tlhlp_, Module32Next, "");
+
+ m_bToolHelp = true;
+ return true;
+}
+
+bool CProcessApi::Load_NtApi()
+{
+ if (m_bNtApi)
+ return true;
+ if (!m_hNtApi)
+ m_hNtApi = LoadLibrary (_T("ntdll.dll"));
+ if (!m_hNtApi)
+ return false;
+
+ DynamicGetProcAddress(m_hNtApi, ntapi_, ZwQuerySystemInformation, "");
+
+ m_bNtApi = true;
+ return true;
+}
+
+//--------------------------------------------------------------------------------------------
+// Populates a tProcessesList with the help of ToolHelp API
+// Returns an error code paeXXXX
+DWORD CProcessApi::ProcessesPopulateToolHelp(tProcessesData *pd)
+{
+ // create a process snapshot
+ HANDLE hSnap = tlhlp_CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (hSnap == INVALID_HANDLE_VALUE)
+ return paeNoSnap;
+
+ BOOL bMore;
+ tProcessInfo pi = {0};
+
+ PROCESSENTRY32 pe32 = {sizeof(PROCESSENTRY32), 0};
+
+ // clear the list
+ pd->pl->RemoveAll ();
+
+ // initialize position
+ pd->Pos = 0;
+
+ bMore = tlhlp_Process32First(hSnap, &pe32);
+ while (bMore)
+ {
+ // convert from PROCESSENTRY32 to my unified tProcessInfo struct
+ pi.pid = pe32.th32ProcessID;
+ lstrcpy (pi.FileName, pe32.szExeFile);
+
+ pd->pl->Add(pi);
+ bMore = tlhlp_Process32Next(hSnap, &pe32);
+ }
+
+ CloseHandle(hSnap);
+ return paeSuccess;
+}
+
+
+//--------------------------------------------------------------------------------------------
+// Populates the list using PsApi functions
+DWORD CProcessApi::ProcessesPopulatePsApi(tProcessesData *pd)
+{
+ DWORD nProcess, // number of processes returned
+ nCount(4096); // maximum number of processes (defined by me)
+
+ // Dynamic array for storing returned processes IDs
+ DWORD *processes = new DWORD[nCount];
+
+ // enum all processes
+ if (!psapi_EnumProcesses(processes, nCount * sizeof(DWORD), &nProcess))
+ {
+ delete [] processes;
+ return paeNoSnap;
+ }
+
+ // convert fron bytes count to items count
+ nProcess /= 4;
+
+ // walk in process list
+ for (DWORD i = 0; i < nProcess; i++) {
+
+ if (processes[i] == 0)
+ // Idle
+ continue;
+
+ // open process for querying only
+ HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processes[i]);
+ if (!hProcess)
+ continue;
+
+ // get the process's image name by getting first module
+ DWORD nmod;
+ HMODULE mod1;
+
+ tProcessInfo pi = {0};
+ pi.pid = processes [i];
+ if (!psapi_EnumProcessModules (hProcess, &mod1, sizeof(mod1), &nmod))
+ lstrcpy (pi.FileName, _T("-"));
+ else
+ psapi_GetModuleFileNameEx (hProcess, mod1, pi.FileName, sizeof(pi.FileName));
+ pd->pl->Add (pi);
+
+ CloseHandle(hProcess);
+ }
+
+ // reposition list to 0
+ pd->Pos = 0;
+ delete [] processes;
+
+ return paeSuccess;
+}
+
+DWORD CProcessApi::ProcessesPopulateNtApi (tProcessesData *pd)
+{
+ ULONG cbBuffer = 0x10000;
+ char* pBuffer;
+ NTSTATUS Status;
+ do {
+ pBuffer = new char [cbBuffer];
+ if (pBuffer == NULL)
+ return paeNoMem;
+ Status = ntapi_ZwQuerySystemInformation (SystemProcessesAndThreadsInformation,
+ pBuffer, cbBuffer, NULL);
+ if (Status == STATUS_INFO_LENGTH_MISMATCH) {
+ delete [] pBuffer;
+ cbBuffer *= 2;
+ } else
+ if (!NT_SUCCESS(Status)) {
+ delete [] pBuffer;
+ return paeNoSnap;
+ }
+ } while (Status == STATUS_INFO_LENGTH_MISMATCH);
+
+ PSYSTEM_PROCESSES pProcesses = (PSYSTEM_PROCESSES) pBuffer;
+ for (;;) {
+ if (pProcesses->ProcessName.Buffer != NULL) {
+ tProcessInfo pi;
+ pi.pid = pProcesses->ProcessId;
+#ifdef UNICODE
+ lstrcpy (pi.FileName, pProcesses->ProcessName.Buffer);
+#else
+ WideCharToMultiByte (CP_ACP, 0, pProcesses->ProcessName.Buffer, -1,
+ pi.FileName, MAX_PATH, NULL, NULL);
+#endif
+ pd->pl->Add (pi);
+ } // else
+ // Idle
+
+ if (pProcesses->NextEntryDelta == 0)
+ break;
+
+ // find the address of the next process structure
+ pProcesses = (PSYSTEM_PROCESSES)(((LPBYTE)pProcesses) + pProcesses->NextEntryDelta);
+ }
+ pd->Pos = 0;
+ delete [] pBuffer;
+ return paeSuccess;
+}
+
+DWORD CProcessApi::ModulesPopulateNtApi(DWORD /* pid */, tModulesData* /* md */)
+{
+ return paeSuccess;
+}
+
+//--------------------------------------------------------------------------------------------
+// Returns the count in the processes list
+DWORD CProcessApi::ProcessesCount(DWORD_PTR lid) const
+{
+ return (DWORD)(reinterpret_cast<tProcessesData *>(lid))->pl->GetCount();
+}
+
+//--------------------------------------------------------------------------------------------
+// Returns the count in the modules list
+DWORD CProcessApi::ModulesCount(DWORD_PTR lid) const
+{
+ return (DWORD)(reinterpret_cast<tModulesData *>(lid))->ml->GetCount();
+}
diff --git a/plugins/!NotAdopted/WinPopup/processapi.h b/plugins/!NotAdopted/WinPopup/processapi.h
new file mode 100644
index 0000000000..b1875751ea
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/processapi.h
@@ -0,0 +1,264 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2006 Nikolay Raspopov
+
+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
+
+#pragma pack (push, 1)
+
+typedef LONG NTSTATUS;
+typedef LONG KPRIORITY;
+typedef LONG SYSTEM_INFORMATION_CLASS;
+
+#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
+#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
+#define SystemProcessesAndThreadsInformation 5
+
+typedef struct _CLIENT_ID {
+ DWORD UniqueProcess;
+ DWORD UniqueThread;
+} CLIENT_ID;
+
+typedef struct _UNICODE_STRING {
+ USHORT Length;
+ USHORT MaximumLength;
+ PWSTR Buffer;
+} UNICODE_STRING;
+
+typedef struct _VM_COUNTERS {
+ SIZE_T PeakVirtualSize;
+ SIZE_T VirtualSize;
+ ULONG PageFaultCount;
+ SIZE_T PeakWorkingSetSize;
+ SIZE_T WorkingSetSize;
+ SIZE_T QuotaPeakPagedPoolUsage;
+ SIZE_T QuotaPagedPoolUsage;
+ SIZE_T QuotaPeakNonPagedPoolUsage;
+ SIZE_T QuotaNonPagedPoolUsage;
+ SIZE_T PagefileUsage;
+ SIZE_T PeakPagefileUsage;
+} VM_COUNTERS;
+
+typedef struct _SYSTEM_THREADS {
+ LARGE_INTEGER KernelTime;
+ LARGE_INTEGER UserTime;
+ LARGE_INTEGER CreateTime;
+ ULONG WaitTime;
+ PVOID StartAddress;
+ CLIENT_ID ClientId;
+ KPRIORITY Priority;
+ KPRIORITY BasePriority;
+ ULONG ContextSwitchCount;
+ LONG State;
+ LONG WaitReason;
+} SYSTEM_THREADS, * PSYSTEM_THREADS;
+
+typedef struct _SYSTEM_PROCESSES {
+ ULONG NextEntryDelta;
+ ULONG ThreadCount;
+ ULONG Reserved1[6];
+ LARGE_INTEGER CreateTime;
+ LARGE_INTEGER UserTime;
+ LARGE_INTEGER KernelTime;
+ UNICODE_STRING ProcessName;
+ KPRIORITY BasePriority;
+ ULONG ProcessId;
+ ULONG InheritedFromProcessId;
+ ULONG HandleCount;
+ ULONG Reserved2[2];
+ VM_COUNTERS VmCounters;
+#if _WIN32_WINNT >= 0x500
+ IO_COUNTERS IoCounters;
+#endif
+ SYSTEM_THREADS Threads[1];
+} SYSTEM_PROCESSES, * PSYSTEM_PROCESSES;
+
+#pragma pack (pop)
+
+//--------------------------------------------------------------------------------------------
+// CProcessApi class - written by Elias Bachaalany.
+// Check the implementation file for more information
+//
+
+class CProcessApi
+{
+public:
+ typedef struct tProcessInfo
+ {
+ DWORD pid;
+ TCHAR FileName[MAX_PATH];
+ };
+
+ typedef struct tModuleInfo
+ {
+ LPVOID ImageBase;
+ DWORD ImageSize;
+ TCHAR FileName[MAX_PATH];
+ };
+
+private:
+ typedef CAtlArray <tProcessInfo> tProcessesList;
+ typedef CAtlArray <tModuleInfo> tModulesList;
+
+ typedef struct tProcessesData
+ {
+ DWORD Pos;
+ tProcessesList *pl;
+ };
+
+ typedef struct tModulesData
+ {
+ DWORD Pos;
+ tModulesList *ml;
+ };
+
+ // PSAPI.DLL functions prototype
+ typedef BOOL (WINAPI *t_psapi_EnumProcesses)(
+ DWORD *lpidProcess, // array of process identifiers
+ DWORD cb, // size of array
+ DWORD *cbNeeded // number of bytes returned
+ );
+
+ typedef BOOL (WINAPI *t_psapi_EnumProcessModules)(
+ HANDLE hProcess, // handle to process
+ HMODULE *lphModule, // array of module handles
+ DWORD cb, // size of array
+ LPDWORD lpcbNeeded // number of bytes required
+ );
+
+ typedef DWORD (WINAPI *t_psapi_GetModuleFileNameEx)(
+ HANDLE hProcess, // handle to process
+ HMODULE hModule, // handle to module
+ LPTSTR lpFilename, // path buffer
+ DWORD nSize // maximum characters to retrieve
+ );
+
+ typedef BOOL (WINAPI *t_psapi_GetModuleInformation)(
+ HANDLE hProcess,
+ HMODULE hModule,
+ LPMODULEINFO lpmodinfo,
+ DWORD cb
+ );
+
+ // functions instances
+ t_psapi_GetModuleFileNameEx psapi_GetModuleFileNameEx;
+ t_psapi_EnumProcessModules psapi_EnumProcessModules;
+ t_psapi_EnumProcesses psapi_EnumProcesses;
+ t_psapi_GetModuleInformation psapi_GetModuleInformation;
+
+ // TOOLHELP functions prototype
+ typedef HANDLE (WINAPI *t_tlhlp_CreateToolhelp32Snapshot)(
+ DWORD dwFlags,
+ DWORD th32ProcessID
+ );
+
+ typedef BOOL (WINAPI *t_tlhlp_Process32First)(
+ HANDLE hSnapshot,
+ LPPROCESSENTRY32 lppe
+ );
+
+ typedef BOOL (WINAPI *t_tlhlp_Process32Next)(
+ HANDLE hSnapshot,
+ LPPROCESSENTRY32 lppe
+ );
+
+ typedef BOOL (WINAPI *t_tlhlp_Module32First)(
+ HANDLE hSnapshot,
+ LPMODULEENTRY32 lpme
+ );
+
+ typedef BOOL (WINAPI *t_tlhlp_Module32Next)(
+ HANDLE hSnapshot,
+ LPMODULEENTRY32 lpme
+ );
+
+ // functions instances
+ t_tlhlp_CreateToolhelp32Snapshot tlhlp_CreateToolhelp32Snapshot;
+ t_tlhlp_Process32First tlhlp_Process32First;
+ t_tlhlp_Process32Next tlhlp_Process32Next;
+ t_tlhlp_Module32First tlhlp_Module32First;
+ t_tlhlp_Module32Next tlhlp_Module32Next;
+
+ // NTDLL.DLL functions prototype
+ typedef NTSTATUS (NTAPI *t_ntapi_ZwQuerySystemInformation)(
+ SYSTEM_INFORMATION_CLASS SystemInformationClass,
+ PVOID SystemInformation,
+ ULONG SystemInformationLength,
+ PULONG ReturnLength
+ );
+
+ // functions instances
+ t_ntapi_ZwQuerySystemInformation ntapi_ZwQuerySystemInformation;
+
+ // Private member variables
+ HMODULE m_hPsApi;
+ HMODULE m_hTlHlp;
+ HMODULE m_hNtApi;
+
+ bool m_bPsApi;
+ bool m_bToolHelp;
+ bool m_bNtApi;
+
+ bool Load_PsApi();
+ bool Load_TlHlp();
+ bool Load_NtApi();
+
+ DWORD ProcessesPopulatePsApi(tProcessesData *pd);
+ DWORD ProcessesPopulateToolHelp(tProcessesData *pd);
+ DWORD ProcessesPopulateNtApi(tProcessesData *pd);
+
+ DWORD ModulesPopulatePsApi(DWORD pid, tModulesData *md);
+ DWORD ModulesPopulateToolHelp(DWORD pid, tModulesData *md);
+ DWORD ModulesPopulateNtApi(DWORD pid, tModulesData *md);
+
+public:
+ // CProcessApi error enum
+ enum
+ {
+ paeSuccess = 0, // No error
+ paeNoApi, // No process API helper dll found
+ paeNoEntryPoint, // One needed entrypoint not found in helper dll
+ paeNoMem, // Not enough memory
+ paeNoSnap, // Could not get a snapshot
+ paeNoMore, // List contains no more items
+ paeOutOfBounds, // Tried to access list w/ an invalid index
+ paeYYY
+ };
+
+ DWORD LastError; // Holds the last error
+
+ CProcessApi();
+ ~CProcessApi();
+
+ bool Init (bool bNtApiFirst = false);
+
+ DWORD ProcessesGetList();
+ bool ProcessesWalk(DWORD_PTR lid, tProcessInfo *pi, DWORD Pos = -1);
+ DWORD ProcessesCount(DWORD_PTR lid) const;
+ void ProcessesFreeList(DWORD_PTR lid);
+
+ DWORD ModulesGetList(DWORD ProcessID);
+ bool ModulesWalk(DWORD_PTR lid, tModuleInfo *mi, DWORD Pos = -1);
+ DWORD ModulesCount(DWORD_PTR lid) const;
+ void ModulesFreeList(DWORD_PTR lid);
+};
+
+// PID
+DWORD GetProcessId (LPCTSTR name);
diff --git a/plugins/!NotAdopted/WinPopup/resource.h b/plugins/!NotAdopted/WinPopup/resource.h
new file mode 100644
index 0000000000..be40ff446c
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/resource.h
@@ -0,0 +1,66 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by winpopup_proto.rc
+//
+#define IDI_WINPOPUP 102
+#define IDI_ONLINE 104
+#define IDI_OFFLINE 105
+#define IDD_OPTIONS 106
+#define IDI_AWAY 128
+#define IDI_FREECHAT 129
+#define IDI_INVISIBLE 130
+#define IDI_NA 131
+#define IDI_DND 158
+#define IDI_OCCUPIED 159
+#define IDC_AUTOANSWER 1001
+#define IDI_ONTHEPHONE 1002
+#define IDC_NICK1 1002
+#define IDI_OUTTOLUNCH 1003
+#define IDC_USER 1003
+#define IDC_NICK2 1004
+#define IDC_ADD 1005
+#define IDC_NAME 1006
+#define IDC_DUPS 1006
+#define IDC_TREE 1007
+#define IDC_LEGEND_1 1008
+#define IDC_LEGEND_2 1009
+#define IDC_LEGEND_3 1010
+#define IDC_LEGEND_4 1011
+#define IDC_LEGEND_5 1012
+#define IDC_LEGEND_6 1013
+#define IDC_USE_MAILSLOT 1014
+#define IDC_USE_NETBIOS 1015
+#define IDC_USE_NETSEND 1016
+#define IDC_CHECK_USER 1017
+#define IDC_CHECK_NICK 1018
+#define IDC_ABOUT 1019
+#define IDC_ONLINE_CHECK 1020
+#define IDC_ALWAYSCHECK00FORONLINE 1021
+#define IDC_CHECK00FORONLINE 1022
+#define IDC_CHECK1 1023
+#define IDC_GROUP 1023
+#define IDD_ADD 2000
+#define IDI_LANA 2001
+#define IDI_COMPUTER 2002
+#define IDI_GOOD_NAME 2003
+#define IDI_BAD_NAME 2004
+#define IDI_OTHER_NAME 2005
+#define IDI_OTHER_NAMES 2006
+#define IDI_BAD_NAMES 2007
+#define IDI_GOOD_NAMES 2008
+#define IDD_USERINFO 2009
+#define IDI_EXPLORE 2011
+#define IDI_COMPUTER_ERROR 2013
+#define IDI_ADD_COMPUTER 2014
+#define IDD_CREATE 2015
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 2016
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1024
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/!NotAdopted/WinPopup/scanner.cpp b/plugins/!NotAdopted/WinPopup/scanner.cpp
new file mode 100644
index 0000000000..a6956ff51a
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/scanner.cpp
@@ -0,0 +1,218 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2011 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "winpopup_proto.h"
+#include "scanner.h"
+#include "netbios.h"
+#include "chat.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+contact_scanner pluginScanner;
+
+contact_scanner::contact_scanner () :
+ m_ScannerTerm (NULL),
+ m_Scanner (NULL)
+{
+}
+
+contact_scanner::~contact_scanner ()
+{
+ Destroy ();
+}
+
+bool contact_scanner::Create ()
+{
+ //
+ if (m_ScannerTerm)
+ ResetEvent (m_ScannerTerm);
+ else
+ m_ScannerTerm = CreateEvent (NULL, TRUE, FALSE, NULL);
+
+ if ( ! m_Scanner )
+ m_Scanner = (HANDLE)mir_forkthread( ScannerThread, this );
+
+ return ( m_Scanner != NULL );
+}
+
+void contact_scanner::AskForDestroy()
+{
+ if (m_ScannerTerm)
+ SetEvent (m_ScannerTerm);
+}
+
+void contact_scanner::Destroy ()
+{
+ AskForDestroy();
+
+ if (m_Scanner)
+ {
+ if (WaitForSingleObject (m_Scanner, ALMOST_INFINITE) == WAIT_TIMEOUT)
+ {
+ LOG("Terminate scanner!");
+ TerminateThread (m_Scanner, 0);
+ }
+ m_Scanner = NULL;
+ }
+
+ if (m_ScannerTerm) {
+ CloseHandle (m_ScannerTerm);
+ m_ScannerTerm = NULL;
+ }
+}
+
+contact_scanner::operator bool () const
+{
+ return ( m_Scanner != NULL );
+}
+
+// First, Next, ... Next, NULL, First, Next...
+HANDLE contact_scanner::GetNextScannableContact()
+{
+ static HANDLE hContact = NULL;
+ if (!hContact)
+ hContact = (HANDLE) CallService (MS_DB_CONTACT_FINDFIRST, 0, 0);
+
+ //
+ while( hContact )
+ {
+ //
+ if ( IsMyContact( hContact ) &&
+ !DBGetContactSettingByte (hContact, "CList", "NotOnList", 0) &&
+ !DBGetContactSettingByte (hContact, "CList", "Hidden", 0) )
+ {
+ //
+ // . ?
+ DWORD elapsed = GetElapsed (hContact, "LastSeen");
+ if ( elapsed >= MIN_PING_INTERVAL )
+ break;
+ }
+ hContact = (HANDLE) CallService (MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+ return hContact;
+}
+
+int contact_scanner::ScanContact(HANDLE hContact)
+{
+ if ( ! pluginInstalled )
+ return ID_STATUS_OFFLINE;
+
+#ifdef CHAT_ENABLED
+ if ( IsChatRoom( hContact ) )
+ {
+ CString sSession = GetChatSession( hContact );
+ if ( pluginChatEnabled && ! sSession.IsEmpty() )
+ {
+ CAtlList< CString > lst;
+ EnumWorkgroups( lst );
+ for ( POSITION pos = lst.GetHeadPosition(); pos; )
+ {
+ if ( lst.GetNext( pos ) == sSession )
+ return ID_STATUS_ONLINE;
+ }
+ }
+ return ID_STATUS_OFFLINE;
+ }
+ else
+#endif // CHAT_ENABLED
+ {
+ int status = ID_STATUS_OFFLINE;
+
+ // "Always Online"
+ if ( DBGetContactSettingByte( hContact, modname, "AlwaysOnline", FALSE ) )
+ status = ID_STATUS_ONLINE;
+
+ //
+ CString sNick = GetNick( hContact );
+ if ( ! sNick.IsEmpty() )
+ {
+ if ( IsGroup( hContact ) )
+ {
+ // ""
+ if ( sNick == _T("*") )
+ return ID_STATUS_ONLINE;
+
+ //
+ CAtlList< CString > lst;
+ EnumWorkgroups( lst );
+ for ( POSITION pos = lst.GetHeadPosition(); pos; )
+ {
+ if ( lst.GetNext( pos ).CompareNoCase( sNick ) == 0 )
+ return ID_STATUS_ONLINE;
+ }
+ }
+ else if ( IsLegacyOnline( NULL ) || IsLegacyOnline( hContact ) )
+ {
+ // NetBIOS- "Nick <00> U"
+ netbios_name nname( sNick, 0x00, false );
+ UCHAR foo;
+ if ( pluginNetBIOS.FindNameLana( nname, foo ) )
+ {
+ status = ID_STATUS_ONLINE;
+
+ // "Nick <00> U"
+ pluginNetBIOS.AskStatus( nname );
+ }
+ }
+ else
+ {
+ // NetBIOS- "Nick <03> U"
+ netbios_name nname( sNick, 0x03, false );
+ UCHAR foo;
+ if ( pluginNetBIOS.FindNameLana( nname, foo ) )
+ {
+ status = ID_STATUS_ONLINE;
+
+ // "Nick <03> U"
+ pluginNetBIOS.AskStatus( nname );
+ }
+ }
+ }
+ return status;
+ }
+}
+
+void contact_scanner::Scanner ()
+{
+ while (WaitForSingleObject (m_ScannerTerm, 1000) == WAIT_TIMEOUT)
+ {
+ //
+ if ( HANDLE hContact = GetNextScannableContact() )
+ {
+ //
+ SetContactStatus( hContact, ScanContact( hContact ), true );
+ }
+ }
+}
+
+void contact_scanner::ScannerThread (LPVOID lpParameter)
+{
+ if ( contact_scanner* pScanner = (contact_scanner*)lpParameter )
+ {
+ pScanner->Scanner();
+ pScanner->m_Scanner = NULL;
+ }
+}
diff --git a/plugins/!NotAdopted/WinPopup/scanner.h b/plugins/!NotAdopted/WinPopup/scanner.h
new file mode 100644
index 0000000000..f2a5c87402
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/scanner.h
@@ -0,0 +1,49 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2006 Nikolay Raspopov
+
+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
+
+class contact_scanner
+{
+public:
+ contact_scanner ();
+ ~contact_scanner ();
+
+ bool Create ();
+ void AskForDestroy(); //
+ void Destroy ();
+ operator bool () const;
+
+ // ( )
+ static int ScanContact(HANDLE hContact);
+
+protected:
+ HANDLE m_ScannerTerm; //
+ HANDLE m_Scanner; //
+
+ //
+ static HANDLE GetNextScannableContact ();
+ //
+ void Scanner ();
+ static void ScannerThread (LPVOID lpParameter);
+};
+
+extern contact_scanner pluginScanner;
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_avatars.h b/plugins/!NotAdopted/WinPopup/sdk/m_avatars.h
new file mode 100644
index 0000000000..9df013446f
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_avatars.h
@@ -0,0 +1,359 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2004 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+
+Avatar service
+
+- load and maintain a cache of contact avatars.
+- draw avatars to a given target device context
+- maintain per protocol fallback images
+
+The avatar service builds on top of Mirandas core bitmap loading service (MS_UTILS_LOADBITMAP).
+However, if imgdecoder.dll is installed in mirandas main or Plugins directory, it can be used
+to support PNG images. The avatar service loads 32bit PNG images and peforms alpha channel
+premultiplication so that these images can be rendered by using the Win32 AlphaBlend() API.
+
+The cache grows on demand only, that is, no avatars are PREloaded. An avatar is only loaded
+if a plugin requests this by using the MS_AV_GETAVATAR service. Since avatars may update
+asynchronously, the avatar iamge may not be ready when a plugin calls the service. In that
+case, an event (ME_AV_AVATARCHANGED) is fired when a contacts avatar changes. This event
+is also fired, when a contact avatar changes automatically.
+
+The service takes care about protocol capabilites (does not actively fetch avatars for
+protocols which do not report avatar capabilities via PF4_AVATARS or for protocols which
+have been disabled in the option dialog). It also does not actively fetch avatars for
+protocols which are in invisible status mode (may cause privacy issues and some protocols
+like MSN don't allow any outbound client communication when in invisible status mode)
+unless AF_FETCHALWAYS is set.
+
+- TODO
+- maintain recent avatars (store the last hashes to avoid re-fetching)
+- cache expiration, based on least recently used algorithm.
+
+(c) 2005 by Nightwish, silvercircle@gmail.com
+
+*/
+
+#ifndef _M_AVATARS_H
+#define _M_AVATARS_H
+
+#define AVS_BITMAP_VALID 1
+#define AVS_BITMAP_EXPIRED 2 // the bitmap has been expired from the cache. (unused, currently.
+#define AVS_HIDEONCLIST 4
+#define AVS_PREMULTIPLIED 8 // set in the dwFlags member of the struct avatarCacheEntry for 32 bit transparent
+ // images when loaded with imgdecoder. These images can be rendered transparently
+ // using the AlphaBlend() API with AC_SRC_ALPHA
+#define AVS_PROTOPIC 16 // picture is a protocol picture
+#define AVS_CUSTOMTRANSPBKG 32 // Bitmap was changed to set the background color transparent
+#define AVS_HASTRANSPARENCY 64 // Bitmap has at least one pixel transparent
+#define AVS_OWNAVATAR 128 // is own avatar entry
+#define AVS_NOTREADY 4096
+
+struct avatarCacheEntry {
+ DWORD cbSize; // set to sizeof(struct)
+ HANDLE hContact; // contacts handle, 0, if it is a protocol avatar
+ HBITMAP hbmPic; // bitmap handle of the picutre itself
+ DWORD dwFlags; // see above for flag values
+ LONG bmHeight, bmWidth; // bitmap dimensions
+ DWORD t_lastAccess; // last access time (currently unused, but plugins should still
+ // use it whenever they access the avatar. may be used in the future
+ // to implement cache expiration
+ LPVOID lpDIBSection; // unused field
+ char szFilename[MAX_PATH]; // filename of the avatar (absolute path)
+};
+
+typedef struct avatarCacheEntry AVATARCACHEENTRY;
+
+struct CacheNode {
+ struct CacheNode *pNextNode;
+ struct avatarCacheEntry ace;
+ //CRITICAL_SECTION cs;
+ BOOL loaded;
+ int mustLoad;
+ DWORD dwFlags;
+ int pa_format;
+};
+
+#define AVDRQ_FALLBACKPROTO 0x0001 // use the protocol picture as fallback (currently not used)
+#define AVDRQ_FAILIFNOTCACHED 0x0002 // don't create a cache entry if it doesn't already exist. (currently not working)
+#define AVDRQ_ROUNDEDCORNER 0x0004 // draw with rounded corners
+#define AVDRQ_DRAWBORDER 0x0008 // draw a border around the picture
+#define AVDRQ_PROTOPICT 0x0010 // draw a protocol picture (if available).
+#define AVDRQ_HIDEBORDERONTRANSPARENCY 0x0020 // hide border if bitmap has transparency
+#define AVDRQ_OWNPIC 0x0040 // draw own avatar (szProto is valid - use "" for global avatar)
+#define AVDRQ_RESPECTHIDDEN 0x0080 // don't draw images marked as hidden
+#define AVDRQ_DONTRESIZEIFSMALLER 0x0100 // don't resize images that are smaller then the draw area
+#define AVDRQ_FORCEFASTALPHA 0x0200 // force rendering with simple AlphaBlend (will use FI_Resample otherwise)
+#define AVDRQ_FORCEALPHA 0x0400 // force with simple AlphaBlend (may use StretchBlt otherwise)
+#define AVDRQ_AERO 0x0800 // draw on aero surface
+
+// request to draw a contacts picture. See MS_AV_DRAWAVATAR service description
+
+typedef struct _avatarDrawRequest {
+ DWORD cbSize; // set this to sizeof(AVATARDRAWREQUEST) - mandatory, service will return failure code if
+ // cbSize is wrong
+ HANDLE hContact; // the contact for which the avatar should be drawn. set it to 0 to draw a protocol picture
+ HDC hTargetDC; // target device context
+ RECT rcDraw; // target rectangle. The avatar will be centered within the rectangle and scaled to fit.
+ DWORD dwFlags; // flags (see above for valid bitflags)
+ DWORD dwReserved; // for future use
+ DWORD dwInternal; // don't use it
+ COLORREF clrBorder; // color for the border (used with AVDRQ_DRAWBORDER)
+ UCHAR radius; // radius (used with AVDRQ_ROUNDEDCORNER)
+ UCHAR alpha; // alpha value for semi-transparent avatars (valid values form 1 to 255, if it is set to 0
+ // the avatar won't be transparent.
+ char *szProto; // only used when AVDRQ_PROTOPICT or AVDRQ_OWNPIC is set
+} AVATARDRAWREQUEST;
+
+#define CACHE_BLOCKSIZE 20
+
+#define AVS_MODULE "AVS_Settings" // db settings module path
+#define PPICT_MODULE "AVS_ProtoPics" // protocol pictures are saved here
+
+// obtain the bitmap handle of the avatar for the given contact
+// wParam = (HANDLE)hContact
+// lParam = 0;
+// returns: pointer to a struct avatarCacheEntry *, NULL on failure
+// if it returns a failure, the avatar may be ready later and the caller may receive
+// a notification via ME_AV_AVATARCHANGED
+// DONT modify the contents of the returned data structure
+
+#define MS_AV_GETAVATARBITMAP "SV_Avatars/GetAvatar"
+
+// obtain a avatar cache entry for one of my own avatars
+// wParam = 0
+// lParam = (char *)szProto (protocol for which we need to obtain the own avatar information). Use "" to global
+// returns: pointer to a struct avatarCacheEntry *, NULL on failure
+// DONT modify the contents of the returned data structure
+
+#define MS_AV_GETMYAVATAR "SV_Avatars/GetMyAvatar"
+
+// protect the current contact picture from being overwritten by automatic
+// avatar updates. Actually, it only backups the contact picture filename
+// and will used the backuped version until the contact picture gets unlocked
+// again. So this service does not disable avatar updates, but it "fakes"
+// a locked contact picture to the users of the GetAvatar service.
+//
+// wParam = (HANDLE)hContact
+// lParam = 1 -> lock the avatar, lParam = 0 -> unlock
+
+#define MS_AV_PROTECTAVATAR "SV_Avatars/ProtectAvatar"
+
+// set (and optionally protect) a local contact picture for the given hContact
+//
+// wParam = (HANDLE)hContact
+// lParam = either a full picture filename or NULL. If lParam == NULL, the service
+// will open a file selection dialog.
+
+#define MS_AV_SETAVATAR "SV_Avatars/SetAvatar"
+
+// set a local picture for the given protocol
+//
+// wParam = (char *) protocol name or NULL for all protocols
+// lParam = either a full picture filename or NULL. If lParam == NULL, the service
+// will open a file selection dialog. If lParam == "" the avatar will be removed
+
+#define MS_AV_SETMYAVATAR "SV_Avatars/SetMyAvatar"
+
+// see if is possible to set the avatar for the expecified protocol
+//
+// wParam = (char *) protocol name
+// lParam = 0
+// return = 1 if can set, 0 if can't
+
+#define MS_AV_CANSETMYAVATAR "SV_Avatars/CanSetMyAvatar"
+
+// Call avatar option dialog for contact
+//
+// wParam = (HANDLE)hContact
+
+#define MS_AV_CONTACTOPTIONS "SV_Avatars/ContactOptions"
+
+// draw an avatar picture
+//
+// wParam = 0 (not used)
+// lParam = AVATARDRAWREQUEST *avdr
+// draw a contact picture to a destination device context. see description of
+// the AVATARDRAWREQUEST structure for more information on how to use this
+// service.
+// return value: 0 -> failure, avatar probably not available, or not ready. The drawing
+// service DOES schedule an avatar update so your plugin will be notified by the ME_AV_AVATARCHANGED
+// event when the requested avatar is ready for use.
+// 1 -> success. avatar was found and drawing should be ok.
+// -1 -> global avatar is incosistent
+
+#define MS_AV_DRAWAVATAR "SV_Avatars/Draw"
+
+// fired when a contacts avatar cached by avs changes
+// it includes changes made by the user
+// wParam = hContact
+// lParam = struct avatarCacheEntry *cacheEntry
+// the event CAN pass a NULL pointer in lParam which means that the avatar has changed,
+// but is no longer valid (happens, when a contact removes his avatar, for example).
+// DONT DESTROY the bitmap handle passed in the struct avatarCacheEntry *
+//
+// It is also possible that this event passes 0 as wParam (hContact), in which case,
+// a protocol picture (pseudo - avatar) has been changed.
+
+#define ME_AV_AVATARCHANGED "SV_Avatars/AvatarChanged"
+
+
+typedef struct _contactAvatarChangedNotification {
+ int cbSize; // sizeof()
+ HANDLE hContact; // this might have to be set by the caller too
+ int format; // PA_FORMAT_*
+ char filename[MAX_PATH]; // full path to filename which contains the avatar
+ char hash[128]; // avatar hash
+} CONTACTAVATARCHANGEDNOTIFICATION;
+
+// fired when the contacts avatar is changed by the contact
+// wParam = hContact
+// lParam = struct CONTACTAVATARCHANGENOTIFICATION *cacn
+// the event CAN pass a NULL pointer in lParam which means that the contact deleted its avatar
+
+#define ME_AV_CONTACTAVATARCHANGED "SV_Avatars/ContactAvatarChanged"
+
+// fired when one of our own avatars was changed
+// wParam = (char *)szProto (protocol for which a new avatar was set)
+// lParam = AVATARCACHEENTRY *ace (new cache entry, NULL if the new avatar is not valid)
+
+#define ME_AV_MYAVATARCHANGED "SV_Avatars/MyAvatarChanged"
+
+// Service to be called by protocols to report an avatar has changed. Some avatar changes
+// can be detected automatically, but some not (by now only Skype ones)
+// wParam = (char *)szProto (protocol for which a new avatar was set)
+// lParam = 0
+
+#define MS_AV_REPORTMYAVATARCHANGED "SV_Avatars/ReportMyAvatarChanged"
+
+
+
+// Bitmap services //////////////////////////////////////////////////////////////////////
+
+// Load an image
+// wParam = NULL
+// lParam = filename
+#define MS_AV_LOADBITMAP32 "SV_Avatars/LoadBitmap32"
+
+// Save an HBITMAP to an image
+// wParam = HBITMAP
+// lParam = full path of filename
+#define MS_AV_SAVEBITMAP "SV_Avatars/SaveBitmap"
+#define MS_AV_SAVEBITMAPW "SV_Avatars/SaveBitmapW"
+
+#if defined(UNICODE)
+ #define MS_AV_SAVEBITMAPT MS_AV_SAVEBITMAPW
+#else
+ #define MS_AV_SAVEBITMAPT MS_AV_SAVEBITMAP
+#endif
+
+// Returns != 0 if can save that type of image, = 0 if cant
+// wParam = 0
+// lParam = PA_FORMAT_* // image format
+#define MS_AV_CANSAVEBITMAP "SV_Avatars/CanSaveBitmap"
+
+// Returns a copy of the bitmap with the size especified or the original bitmap if nothing has to be changed
+// wParam = ResizeBitmap *
+// lParam = NULL
+#define MS_AV_RESIZEBITMAP "SV_Avatars/ResizeBitmap"
+
+/*
+ * flags for internal use ONLY
+ */
+
+#define MC_ISMASTERCONTACT 0x01
+#define MC_ISSUBCONTACT 0x02
+#define AVH_MUSTNOTIFY 0x04 // node->dwFlags (loader thread must notify avatar history about change/delete event)
+#define AVS_DELETENODEFOREVER 0x08
+
+
+
+// Protocol services //////////////////////////////////////////////////////////////////////
+
+/*
+wParam=0
+lParam=(const char *)Avatar file name or NULL to remove the avatar
+return=0 for sucess
+*/
+#define PS_SETMYAVATAR "/SetMyAvatar"
+
+/*
+wParam=(char *)Buffer to file name
+lParam=(int)Buffer size
+return=0 for sucess
+*/
+#define PS_GETMYAVATAR "/GetMyAvatar"
+
+
+#define PIP_NONE 0
+#define PIP_SQUARE 1
+
+// Avatar image max size
+// lParam = (POINT*) maxSize (use -1 for no max)
+// return 0 for success
+#define AF_MAXSIZE 1
+
+// Avatar image proportion
+// lParam = 0
+// return or of PIP_*
+#define AF_PROPORTION 2
+
+// Avatar format supported when setting avatars
+// lParam = PA_FORMAT_*
+// return = 1 (supported) or 0 (not supported)
+#define AF_FORMATSUPPORTED 3
+
+// Avatars are enabled for protocol?
+// lParam = 0
+// return = 1 (avatars ready) or 0 (disabled)
+#define AF_ENABLED 4
+
+// This protocol don't need delays for fetching contact avatars
+// lParam = 0
+// return = 1 (don't need) or 0 (need)
+#define AF_DONTNEEDDELAYS 5
+
+// Avatar file max size
+// return size in bytes (0 for no limit)
+#define AF_MAXFILESIZE 6
+
+// The amount of time avs should wait after a download avatar failed for a contact
+// lParam = 0
+// return = the time, in ms
+#define AF_DELAYAFTERFAIL 7
+
+// Fetching avatars is always possible and allowed
+// lParam = 0
+// return = 1 (always) or 0 (depending on our or contacts status mode)
+#define AF_FETCHALWAYS 8
+
+
+/*
+Query avatar caps for a protocol
+wParam = One of AF_*
+lParam = See descr of each AF_*
+return = See descr of each AF_*. Return 0 by default
+*/
+#define PS_GETAVATARCAPS "/GetAvatarCaps"
+
+
+
+#endif
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_chat.h b/plugins/!NotAdopted/WinPopup/sdk/m_chat.h
new file mode 100644
index 0000000000..e3cd416c6d
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_chat.h
@@ -0,0 +1,685 @@
+/*
+Chat module plugin for Miranda IM
+
+Copyright (C) 2003 Jörgen Persson
+
+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.
+*/
+
+
+
+/*
+ This plugin provides event driven chat rooms for protocols that wish to use it.
+ It is built for IRC, which I also develop and is naturally biased towards IRC,
+ but it should work very well with other protocols too. I will try to explain as
+ careful as possible in this document how to use chat.dll
+
+ -- General guidelines --
+
+ There is ONE rule a protocol MUST follow to use this:
+
+ 1. Do NOT touch hContacts that has a byte "ChatRoom" set to ANYTHING other than 0! (Could be 1, 2, 3, ...)
+ This is because chat.dll adds contacts to the clist using the protocol name
+ supplied by the protocol. But this will naturally not work well if the
+ protocol also tampers with the contacts. The value of the BYTE indicates which type of
+ window/contact it is (see the GCW_* flags below). There is two exceptions to this rule:
+
+ * You should continue to handle the right click menu items of these
+ contacts as usual, by hooking the menu prebuild hook etc. Chat.dll can not
+ handle this in an efficient manner!
+
+ * You should also handle when the user deletes the contact/room from the
+ contact list, as the protocol will then most likely have to send some message
+ to the server that the user has left the room.
+
+ NOTE. Chat keeps its own copies of strings passed.
+
+
+ * * Example of implementing this rule * *:
+ * * This is a code snippet that is common in protocols * *:
+
+
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact)
+ {
+ szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto != NULL && !lstrcmpi(szProto, PROTONAME))
+ {
+ ... do something with the hContact here;
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+
+
+
+ * * You should do this instead * *:
+
+
+
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
+ while (hContact)
+ {
+ szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0);
+ if (szProto != NULL && !lstrcmpi(szProto, PROTONAME))
+ {
+ if (DBGetContactSettingByte(hContact, PROTONAME, "ChatRoom", 0) == 0)
+ {
+ ... do something with the hContact here;
+ }
+ }
+ hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0);
+ }
+
+
+ There is not more to it than that! To recapitulate: do NOT touch contacts where the
+ BYTE "ChatRoom" is set to anything other than 0,
+
+
+
+
+
+
+ OK, enough of the precautions, HOW DO YOU USE CHAT? In short you need to do FOUR things:
+
+ 1. REGISTER your protocol with Chat
+ Only registered protocols can use Chat
+
+ 2. CREATE SESSIONS when your protocol are joining a group chat room. (One per room joined)
+ These sessions will be put on the contact-list and are managed totally by chat.
+ This is the reason you must obey to the "precautions" I mentioned above.
+ Do not tamper directly with Chat's hContacts. Use Services provided by Chat instead.
+
+ 3. SEND EVENTS to the sessions created in #3.
+ These events reflect users joining/leaving/speaking etc.
+
+ 4. DESTROY SESSIONS when the user leaves the room (ie the session is not needed anymore).
+
+ These four points are implemented in three services: MS_GC_REGISTER, MS_GC_NEWSESSION
+ and MS_GC_EVENT.
+*/
+
+
+//------------------------- SERVICES ------------------------
+/*
+ Step 1. -- REGISTER with Chat --
+
+ The first thing that a protocol need to do is register with Chat. This is best done
+ when ALL modules has loaded (ME_SYSTEM_MODULESLOADED). The registration is
+ needed to make sure that the protocol obey rule 1 mentioned above, but also to
+ set protocol specific preferences.
+
+ * Use MS_GC_REGISTER like this: CallService(MS_GC_REGISTER, 0, (LPARAM)(GCREGISTER *) &gcr;
+
+ * returns 0 on success or error code on failure.
+*/
+
+// Flags
+#define GC_BOLD 0x0001 //enable the 'bold' button
+#define GC_ITALICS 0x0002 //enable the 'italics' button
+#define GC_UNDERLINE 0x0004 //enable the 'underline' button
+#define GC_COLOR 0x0008 //enable the 'foreground color' button
+#define GC_BKGCOLOR 0x0010 //enable the 'background color' button
+#define GC_ACKMSG 0x0020 //the protocol must acknowlege messages sent
+#define GC_TYPNOTIF 0x0040 //NOT SUPPORTED YET! Enable typing notifications.
+#define GC_CHANMGR 0x0080 //enable the 'channel settings' button
+#define GC_SINGLEFORMAT 0x0100 //the protocol supports only 1 formatting per message
+#define GC_FONTSIZE 0x0200 //enable font size selection
+
+#define GC_UNICODE 0x01000 //NOT SUPPORTED YET! Enable unicode (if chat supports it),
+ //Pass UNICODE instead of ASCII. Note that
+ //registration will fail if the unicode version of chat is not installed
+#if defined( _UNICODE )
+ #define GC_TCHAR GC_UNICODE
+#else
+ #define GC_TCHAR 0
+#endif
+
+// Error messages
+#define GC_REGISTER_WRONGVER 1 //You appear to be using the wrong version of this API. Registration failed.
+#define GC_REGISTER_ERROR 2 //An internal error occurred. Registration failed.
+#define GC_REGISTER_NOUNICODE 3 //MS_GC_REGISTER returns this error if the Unicode version of chat
+ //is not installed and GC_UNICODE is set. Registration failed
+
+// GCREGISTER struct
+typedef struct {
+ int cbSize; //Set to sizeof(GCREGISTER);
+ DWORD dwFlags; //Use GC_* flags above to indicate features supported
+ const char* pszModule; //This MUST be the protocol name as registered with Miranda IM
+ union {
+ const char* pszModuleDispName; //This is the protocol's real name as it will be displayed to the user
+ const TCHAR* ptszModuleDispName; // used if GC_TCHAR flag is passed
+ };
+ int iMaxText; //Max message length the protocol supports. Will limit the typing area input. 0 = no limit
+ int nColors; //Number of colors in the colorchooser menu for the color buttons. Max = 100
+ COLORREF* pColors; //pointer to the first item in a static COLORREF array containing the colors
+ //that should be showed in the colorchooser menu.
+ //ie: COLORREF crCols[nColors];
+ // pColors = &crCols[0];
+}
+ GCREGISTER;
+
+#define MS_GC_REGISTER "GChat/Register"
+
+/*
+ Step 2. -- CREATE a new SESSION --
+
+ Create a new session (chat room) and set various settings related to it.
+ The chat room will not be shown to the user until the 'set up' phase is
+ completed and SESSION_INITDONE is sent. See the MS_GC_EVENT for that.
+
+ * Use MS_GC_NEWSESSION like this: CallService(MS_GC_NEWSESSION, 0, (LPARAM)(GCSESSION *) &gcr;
+
+ * returns 0 on success or error code on failure
+*/
+
+
+// Session type
+#define GCW_CHATROOM 1 // the session is a dedicated multi user chat room. ex "IRC channels".
+ // A hContact will be added for the session
+#define GCW_SERVER 2 // the session is used as a network console. ex "IRC server window"
+ // A hContact will be added for the session, but it will default to being hidden (on the CList)
+#define GCW_PRIVMESS 3 // NOT SUPPORTED YET! the session is a 1 to 1 session, but with additional
+ // support for adding more users etc. ex "MSN session".
+
+
+
+// Error messages
+#define GC_NEWSESSION_WRONGVER 1 //You appear to be using the wrong version of this API.
+#define GC_NEWSESSION_ERROR 2 //An internal error occurred.
+
+
+// GCREGISTER structure
+typedef struct {
+ int cbSize; //Set to sizeof(GCSESSION);
+ int iType; //Use one of the GCW_* flags above to set the type of session
+ const char *pszModule; //The name of the protocol owning the session (the same as pszModule when you register)
+ union {
+ const char* pszName; //The name of the session as it will be displayed to the user
+ const TCHAR* ptszName;
+ };
+ union {
+ const char* pszID; //The unique identifier for the session.
+ const TCHAR* ptszID;
+ };
+ union {
+ const char* pszStatusbarText; //Optional text to set in the statusbar of the chat room window, or NULL.
+ const TCHAR* ptszStatusbarText;
+ };
+ DWORD dwFlags;
+ DWORD dwItemData; //Set user defined data for this session. Retrieve it by using the GC_EVENT_GETITEMDATA event
+ } GCSESSION;
+#define MS_GC_NEWSESSION "GChat/NewChat"
+
+
+
+
+
+
+/*
+ Step 3 -- SEND an EVENT --
+
+ Events is what drives Chat! After having created the session in Step 2
+ it is time to make it work for real. Follow these guidelines:
+
+ 1. Start off by telling Chat what possible statuses a user can have (in the nicklist)
+ by sending GC_EVENT_ADDGROUP as many times as needed. Also supply an icon
+ to go with this status. Ex "Voice status" on IRC
+
+ 2.Then send "JOIN" events (GC_EVENT_JOIN) to populate the user list.
+ You will need to send one event per user that should be added. As long as
+ SESSION_INITDONE has not been sent these events will not show up in the log.
+
+ 3.When you are done with filling the user list it is a good time to end
+ the set up phase and make the window visible by calling GC_EVENT_CONTROL event
+ with wParam = SESSION_INITDONE.
+
+ 4.You will also want to send a GC_EVENT_CONTROL with wParam = SESSION_ONLINE to
+ make the statusbar and the CList item go to "online" status
+
+ You have now set up the session and made it active. A CList hContact has been added
+ to the contact list and a chat room window is associated to the session. Send EVENTS to
+ Chat users speaking, users joining and so on. See below for full
+ list of what events are possible.
+
+ IMPORTANT: For sending events you'll use the GCEVENT and GCDEST structures. A GCDEST
+ structure pointer is passed inside GCEVENT and it tells Chat what event type it is
+ and what session it is related to. The GCDEST structure and its members are ALWAYS
+ used (but the members can be NULL in some occasions). Depending on what type of event
+ you are sending, the members of GCEVENT have different usage. Each event and how to
+ use the members are discussed below. The "bAddToLog" and "time" members are always valid
+ and always mean the same. bAddToLog = TRUE means that the event is added to the disk log
+ (at least when this makes sense). This can be used by Jabber for instance, when
+ it needs to add channel history to the window, but without logging to disk.
+ The "time" member is the timestamp of the event.(Tip. use the function time(NULL)
+ to set the current time)
+
+ NOTE. It is possible to send formatted text (bold, italics, underlined, foreground color
+ and background color) to Chat by using the following identifiers in the text (pszText):
+
+ %cXX - set the foreground color ( XX is the zero based decimal index of the color registered in MS_GC_REGISTER.. Always use two digits )
+ %C - reset foreground color to default
+ %fXX - set the background color ( XX is the zero based decimal index of the color registered in MS_GC_REGISTER.. Always use two digits )
+ %F - reset the background color to default
+ %b - enable bold
+ %B - disable bold
+ %u - enable underlined
+ %U - disable underlined
+ %i - enable italics
+ %I - disable italics
+ %r - reset all to default
+ %% - escape the formatting. Translates to %
+
+ IMPORTANT. If you have specified GC_COLOR or GC_BKGCOLOR when you registered you can expect to
+ get these identifiers in the text you receive from Chat as well. Make sure % is ALWAYS
+ translated to %% in text you send to Chat to avoid accidental formatting.
+ NOTE. You will not get %cRRRGGGBBB back, instead you will get the index of the colour as
+ registered with GC_REGISTER. Eg %c3 (the fourth colour of your index)
+
+ * Use MS_GC_EVENT like this: CallService(MS_GC_EVENT, 0, (LPARAM)(GCEVENT *) &gce;
+
+ * returns 0 on success or error code on failure
+
+*/
+
+// * List of possible events to send to Chat. Unlisted members are not valid *
+// * for the event. Listed members are mandatory unless otherwise specified *
+
+
+// GC_EVENT_JOIN - "<pszNick> has joined" (A user is joining the session)
+// pszNick - Display name
+// pszUID - Unique identifier of the user
+// pszStatus - Which status does the user have. Should be a status previously
+// registered with GC_EVENT_ADDGROUP. Ex "Voice" in IRC
+// bIsMe - Set to TRUE if it is the Miranda user
+// Chat needs to know which user in the userlist that is "self"
+// It cannot highlight a message containing the "own" nick without this info
+// NOTE. if time == NULL, then the event will not be shown in the message log
+#define GC_EVENT_JOIN 0x0001
+
+// GC_EVENT_PART - "<pszNick> has left: <pszText>" (A user left the session)
+// pszNick - Display name
+// pszUID - Unique identifier
+// pszText - Optional part message, can be NULL
+#define GC_EVENT_PART 0x0002
+
+// GC_EVENT_QUIT - "<pszNick> disconnected: pszText" (A user disconnected from the network)
+// pszID(in GCDEST) - Should be NULL as a disconnect event is global.
+// pszNick - Display name
+// pszUID - Unique identifier
+// pszText - Optional disconnect message, can be NULL
+#define GC_EVENT_QUIT 0x0004
+
+// GC_EVENT_KICK - "<pszStatus> kicked <pszNick>: <pszText>" (A user is kicking another user from the room)
+// pszNick - Display name of the one being being kicked
+// pszUID - Unique identifier of the one being kicked
+// pszStatus - Name of user who is doing the kicking
+// pszText - Optional kick message, can be NULL
+#define GC_EVENT_KICK 0x0008
+
+// GC_EVENT_NICK - "<pszNick> is now known as <pszText>" (A user changed his name)
+// NOTE, see GC_EVENT_CHUID also
+// pszID(in GCDEST) - Should be NULL as a nick change event is global.
+// pszNick - Old display name
+// pszUID - Unique identifier
+// pszText - New display name of the user. Color codes are not valid
+#define GC_EVENT_NICK 0x0010
+
+// GC_EVENT_NOTICE - "Notice from <pszNick>: <pszText>" (An IRC type notice)
+// pszID(in GCDEST) - Should be NULL to send to the active window
+// pszNick - Display name
+// pszUID - Unique identifier
+// pszText - Notice text
+#define GC_EVENT_NOTICE 0x0020
+
+// GC_EVENT_MESSAGE - "<pszNick>: <pszText> (A user is speaking)
+// pszNick - Display name
+// pszUID - Unique identifier
+// bIsMe - Set to TRUE if it is the Miranda user
+// pszText - Message text.
+#define GC_EVENT_MESSAGE 0x0040
+
+// GC_EVENT_TOPIC - "Topic is <pszText> (Set by: <pszNick>" (The room topic was changed/set)
+// pszNick - Optional display name of who set the topic, can be NULL
+// pszUID - Optional unique identifier of who set the topic, can be NULL
+// pszText - Topic text
+#define GC_EVENT_TOPIC 0x0080
+
+// GC_EVENT_INFORMATION (Informational text) Ex a server response to a /WHO command in IRC
+// pszID(in GCDEST) - NULL to send to the active window
+// pszText - Information text
+#define GC_EVENT_INFORMATION 0x0100
+
+// GC_EVENT_ACTION - "<pszNick> <pszText>" (An IRC Style action event)
+// pszNick - Display name
+// pszUID - Unique identifier
+// bIsMe - Set to TRUE if it is the Miranda user
+// pszText - Message text.
+#define GC_EVENT_ACTION 0x0200
+
+// GC_EVENT_ADDSTATUS - "<pszText> enables '<pszStatus>' for <pszNick>" (A status change has occured for a user)
+// NOTE. Status changes are cumulative. The user will show in the nicklist with the highest status received.
+// Ex, IRC users can have "Op" and "Voice" statuses simultaneously but s/he will be displayed as "Op"
+// pszNick - Display name of the one who receives a new status
+// pszUID - Unique identifier of the one who receives a new status
+// pszText - The display name of the one who is setting the status. Color codes are not valid
+// pszStatus - The status. Should be a status previously
+// registered with GC_EVENT_ADDGROUP. Ex "Voice" in IRC
+#define GC_EVENT_ADDSTATUS 0x0400
+
+// GC_EVENT_REMOVESTATUS - "<pszText> disables '<pszStatus>' for <pszNick>" (A status change has occured for a user)
+// NOTE. Status changes are cumulative. The user will show in the nicklist with the highest status received.
+// Ex, IRC users can have "Op" and "Voice" statuses simultaneously but s/he will be displayed as "Op"
+// pszNick - Display name of the one who got a status mode disabled
+// pszUID - Unique identifier of the one who got a status mode disabled
+// pszText - The display name of the one disabling the status. Color codes are not valid
+// pszStatus - The status. Should be a status previously
+// registered with GC_EVENT_ADDGROUP. Ex "Voice" in IRC
+#define GC_EVENT_REMOVESTATUS 0x0800
+
+// GC_EVENT_CHUID - not shown in the log (Change the unique identifier of a contact)
+// pszID(in GCDEST) - Should be NULL as a unique id's are global.
+// pszUID - The current unique identifier
+// pszText - The new unique identifier. Color codes are not valid
+#define GC_EVENT_CHUID 0x1000
+
+// GC_EVENT_CHANGESESSIONAME - not shown in the log (Change the display name of a session)
+// pszText - The new name. Color codes are not valid
+#define GC_EVENT_CHANGESESSIONAME 0x1001
+
+// GC_EVENT_ADDGROUP - not shown in the log (Add a possible status mode to the nicklist, ex IRC uses "Op", "Voice", "Normal" etc )
+// NOTE. When adding several statuses, start with the highest status
+// pszStatus - The new group name
+// dwItemData - Optional HICON handle to a 10x10 icon. Set to NULL to use the built in icons.
+#define GC_EVENT_ADDGROUP 0x1002
+
+// GC_EVENT_SETITEMDATA & GC_EVENT_SETITEMDATA - not shown in the log (Get/Set the user defined data of a session)
+// dwItemData - The itemdata to set or get
+#define GC_EVENT_SETITEMDATA 0x1003
+#define GC_EVENT_GETITEMDATA 0x1004
+
+// GC_EVENT_SETSBTEXT - not shown in the log (Set the text of the statusbar for a chat room window)
+// pszText - Statusbar text. Color codes are not valid
+#define GC_EVENT_SETSBTEXT 0x1006
+
+// GC_EVENT_ACK - not shown in the log (Acknowledge a outgoing message, when GC_ACKMSG is set
+#define GC_EVENT_ACK 0x1007
+
+// GC_EVENT_SENDMESSAGE - not shown in the log ("Fake" a message from a chat room as if the user had typed it). Used by IRC to broadcast /AME and /AMSG messages
+// pszText - The text
+#define GC_EVENT_SENDMESSAGE 0x1008
+
+// GC_EVENT_SETSTATUSEX - not shown in the log (Space or tab delimited list of pszUID's to indicate as away).
+// Used by IRC to mark users as away in the nicklist. If UIDs can contain spaces, use tabs
+// pszText - Space or tab delimited list of pszUID's
+
+#define GC_SSE_ONLYLISTED 0x0001 // processes only listed contacts, resets all contacts otherwise
+#define GC_SSE_ONLINE 0x0002 // displays a contact online, otherwise away
+#define GC_SSE_TABDELIMITED 0x0004 // use tabs as delimiters
+
+#define GC_EVENT_SETSTATUSEX 0x1009
+
+// GC_EVENT_SETCONTACTSTATUS - sets status icon for contact
+// pszUID - Unique identifier of the one who receives a new status
+// dwItemData - (DWORD)ID_STATUS_* or zero to remove status icon
+#define GC_EVENT_SETCONTACTSTATUS 0x100A
+
+// GC_EVENT_CONTROL - not shown in the log (Control window associated to a session and the session itself)
+// NOTE 1: No members of GCEVENT are used, send one of the below flags in wParam instead,
+// Ex CallService(GC_EVENT_CONTROL, SESSION_INITDONE, (LPARAM)&gce);
+// NOTE 2: The first four control events are the only ones you should use most likely!
+// The ones below them are used by IRC to join channels hidden or maximized and show the server window from the system menu.
+// The SESSION_VISIBLE, SESSION_HIDDEN, SESSION_MAXIMIZE and SESSION_MINIMIZE events CAN replace SESSION_INITDONE but I urge you not to
+// do that as it will override any settings the user has made in the Chat options
+// NOTE 3: If pszID (of GCDEST) = NULL then this message will be broadcasted to all sessions, which can be usefule for terminating
+// all sessions when the protocol was disconnected
+#define SESSION_INITDONE 1 //send this when the session is fully set up (all users have ben added to the nicklist)
+#define SESSION_TERMINATE 7 //send to terminate a session and close the window associated with it
+#define SESSION_OFFLINE 8 //send to set the session as "online" (hContact is set to Online etc)
+#define SESSION_ONLINE 9 //send to set the session as "offline" (hContact is set to Offline etc)
+//------------
+#define WINDOW_VISIBLE 2 //make the room window visible
+#define WINDOW_HIDDEN 3 //close the room window. Session is not terminated.
+#define WINDOW_MAXIMIZE 4 //make the room window maximized
+#define WINDOW_MINIMIZE 5 //make the room window minimized
+#define WINDOW_CLEARLOG 6 //clear the log of the room window
+
+#define GC_EVENT_CONTROL 0x1005
+
+// Error messages
+#define GC_EVENT_WRONGVER 1 //You appear to be using the wrong version of this API.
+#define GC_EVENT_ERROR 2 //An internal error occurred.
+
+// The GCDEST structure. It is passed to Chat inside GCEVENT.
+typedef struct {
+ char* pszModule; //Name of the protocol (same as you registered with)
+ union {
+ char* pszID; //Unique identifier of the session, or NULL to broadcast to all sessions as specified above
+ TCHAR* ptszID;
+ };
+ int iType; //Use GC_EVENT_* as defined above. Only one event per service call.
+} GCDEST;
+
+
+// The GCEVENT structure
+typedef struct {
+ int cbSize; // Set to sizeof(GCEVENT);
+ GCDEST* pDest; // pointer to a GCDEST structure which specifies the session to receive the event
+ union {
+ const char *pszText; // usage depends on type of event, max 2048 characters
+ const TCHAR *ptszText;
+ };
+ union {
+ const char* pszNick; // usage depends on type of event
+ const TCHAR* ptszNick;
+ };
+ union {
+ const char* pszUID; // usage depends on type of event, Do NOT use spaces for unique user identifiers.
+ const TCHAR* ptszUID;
+ };
+ union {
+ const char* pszStatus; // usage depends on type of event
+ const TCHAR* ptszStatus;
+ };
+ union {
+ const char* pszUserInfo; // Additional user information that is displayed after the nickname.
+ const TCHAR* ptszUserInfo;
+ };
+ // IRC use it to display a hostmask for JOIN, PART (and more) events.
+ BOOL bIsMe; // Is this event from the Miranda user?
+ DWORD dwFlags; // event flags: GCEF_ADDTOLOG, GC_UNICODE
+
+ // FALSE any other time than when initializing the window (before sending SESSION_INITDONE)
+ DWORD_PTR dwItemData; // User specified data.
+ DWORD time; // Timestamp of the event
+}
+ GCEVENT;
+
+#define MS_GC_EVENT "GChat/NewEvent"
+
+#define GCEF_ADDTOLOG 0x0001
+
+// OK! That was about everything that you need to know about for operating Chat in a basic way.
+// There are however some more things you will need to know about. Some you may use and some you may not need,
+
+/*
+ -- GETTING info about a SESSION or session data --
+
+ Use this service to get information on different aspects of the sessions that are registered with Chat.
+
+ * Use MS_GC_GETINFO like this: CallService(MS_GC_GETSESSIONCOUNT, 0, (LPARAM)(char *) pszModule);
+
+ * returns -1 on failure and the sessioncount on success
+*/
+
+#define MS_GC_GETSESSIONCOUNT "GChat/GetCount"
+
+/*
+ -- GETTING info about a SESSION or session data --
+
+ Use this service to get information on different aspects of the sessions that are registered with Chat.
+
+ * Use MS_GC_GETINFO like this: CallService(MS_GC_GETINFO, 0, (LPARAM)(GC_INFO *) &gci;
+
+ * returns 0 on success or error code on failure
+*/
+
+// Flags
+#define BYINDEX 0x0001 // iItem is valid and should contain the index of the session to get
+#define BYID 0x0002 // pszID is valid and should contain the ID of the session to get. This is the default if no
+#define HCONTACT 0x0004 // hContact is valid
+#define DATA 0x0008 // wItemData is valid
+#define ID 0x0010 // pszID is valid.
+#define NAME 0x0020 // pszName is valid
+#define TYPE 0x0040 // iType is valid
+#define COUNT 0x0080 // iCount is valid
+#define USERS 0x0100 // pszUsers is valid
+
+
+// The GC_INFO structure
+typedef struct {
+ DWORD Flags; // use a combination of the above flags
+ int iItem; // session type (GCW_*)
+ int iType; // session type (GCW_*)
+ char* pszModule; // the module name as registered in MS_GC_REGISTER
+ TCHAR* pszID; // unique ID of the session
+ TCHAR* pszName; // display name of the session
+ DWORD_PTR dwItemData; // user specified data.
+ int iCount; // count of users in the nicklist
+ char* pszUsers; // space separated string containing the UID's of the users in the user list.
+ // NOTE. Use Mirandas mmi_free() on the returned string.
+ HANDLE hContact; // hContact for the session (can be NULL)
+}
+ GC_INFO;
+
+#define MS_GC_GETINFO "GChat/GetInfo"
+
+//------------------------- HOOKS ------------------------
+/*
+ -- user interaction --
+ Hook this to receive notifications about when user take actions in a chat room window.
+ Check for the below flags to find out what type of user interaction it is. See the
+ to find out which members of GCHOOK that are valid.
+
+ * wParam=0
+ * lParam=(LPARAM)(GCEVENT *)pgch
+
+ * Returning nonzero from your hook will stop other hooks from being called.
+*/
+#define GC_USER_MESSAGE 1 // user sent a message, with \n delimiting lines, pszText contains the text.
+#define GC_USER_CHANMGR 2 // user clicked the settings button in a chat room
+#define GC_USER_LOGMENU 3 // user has selected a message log menu item, dwData is valid. See ME_GC_BUILDMENU
+#define GC_USER_NICKLISTMENU 4 // user has selected a userlist menu item, valid members: dwData. See ME_GC_BUILDMENU
+#define GC_USER_TYPNOTIFY 5 // NOT IMPLEMENTED YET! user is typing
+#define GC_USER_PRIVMESS 6 // user requests to send a private message to a user. pszUID is valid
+#define GC_USER_LEAVE 8 // user requests to leave the session
+#define GC_USER_CLOSEWND 9 // user closed the window (this is usually not an indication that the protocol
+ // should take action, but MSN may want to terminate the session here)
+#define GC_SESSION_TERMINATE 7 // the session is about to be terminated, the "user defined data" is passed in dwData, which can be good free'ing any allocated memory.
+#define ME_GC_EVENT "GChat/OutgoingEvent"
+
+typedef struct {
+ GCDEST* pDest; // pointer to a GCDEST structure which specifies from which session the hook was triggered
+ union {
+ char* pszText; // usage depends on type of event
+ TCHAR* ptszText;
+ };
+ union {
+ char* pszUID; // unique identifier, usage depends on type of event
+ TCHAR* ptszUID;
+ };
+ DWORD_PTR dwData; // user defined data, usage depends on type of event
+}
+ GCHOOK;
+
+/*
+ -- Build the pop up menus --
+ The user wants to show a right click (popup) menu and your protocol should tell what
+ items should be added to the menu. You should create a static array of struct gc_item's.
+ When you get this notification you should set "nItems" to the number of gc_item's
+ you want to show on the user's popup menu and then set the "Item" member to point to that array.
+
+ * wParam=0
+ * lParam=(LPARAM)(GCMENUITEM *)gcmi
+
+ Returning nonzero from your hook will stop other hooks from being called.
+
+*/
+
+// type of item to add to the popup menu
+#define MENU_NEWPOPUP 1 // add submenu
+#define MENU_POPUPITEM 2 // add item to current submenu
+#define MENU_POPUPSEPARATOR 3 // add separator to current submenu
+#define MENU_SEPARATOR 4 // add separator to menu
+#define MENU_ITEM 5 // add item
+
+// Added in Miranda IM 0.8.0.6+
+#define MENU_POPUPCHECK 6 // add checked item to current submenu
+#define MENU_CHECK 7 // add checked item
+#define MENU_POPUPHMENU 8 // add custom submenu to current submenu, use dwID to specify HMENU
+#define MENU_HMENU 9 // add custom submenu, use dwID to specify HMENU
+
+// type of menu that is being requested
+#define MENU_ON_LOG 1 // pop up menu on the message log
+#define MENU_ON_NICKLIST 2 // pop up menu on the user list
+
+// contains info on a menuitem to be added
+struct gc_item {
+ TCHAR* pszDesc; // Textual description of the menu item to add
+ DWORD dwID; // when/if the user selects this menu item this
+ // value will be returned via the above hook, GC_USER_LOGMENU
+ // or GC_USER_NICKLISTMENU. Must not be 0 and must be unique.
+ int uType; // What kind of menu item is it? Use MENU_* flags above
+ BOOL bDisabled; // should the menu item be shown as disabled
+};
+
+typedef struct {
+ char * pszModule; // Contains the protocol name, do NOT change.
+ TCHAR* pszID; // The unique identifier of the session that triggered the hook, do NOT change.
+ TCHAR* pszUID; // Contains the unique identifier if Type = MENU_ON_NICKLIST. do NOT change.
+ int Type; // Type of menu. MENU_ON_* flags used. do NOT change.
+ int nItems; // Set this to the number of menu items you want to add
+ struct gc_item* Item; // pointer to the first in the array of gc_item's
+}
+ GCMENUITEMS;
+
+#define ME_GC_BUILDMENU "GChat/BuildMenu"
+
+/*
+ * Example of how to add 2 items to the popup menu for the userlist *
+
+ GCMENUITEMS *gcmi= (GCMENUITEMS*) lParam;
+ if (gcmi->Type == MENU_ON_NICKLIST)
+ {
+ static struct gc_item Item[] = {
+ {Translate("User &details"), 1, MENU_ITEM, FALSE},
+ {Translate("&Op"), 2, MENU_POPUPITEM, FALSE},
+ };
+
+ gcmi->nItems = sizeof(Item)/sizeof(Item[0]);
+ gcmi->Item = &Item[0];
+ gcmi->Item[gcmi->nItems-1].bDisabled = bFlag;
+
+ return 0;
+ }
+*/
+
+//////////////////////////////////////////////////////////////////////////
+// Get Chat ToolTip Text for buddy
+// wParam = (WPARAM)(TCHAR*) roomID parentdat->ptszID
+// lParam = (WPARAM)(TCHAR*) userID ui1->pszUID
+// result (int)(TCHAR*)mir_tstrdup("tooltip text")
+// returns pointer to text of tooltip and starts owns it
+#define MS_GC_PROTO_GETTOOLTIPTEXT "/GetChatToolTipText"
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_clist.h b/plugins/!NotAdopted/WinPopup/sdk/m_clist.h
new file mode 100644
index 0000000000..c0bbd3853a
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_clist.h
@@ -0,0 +1,637 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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_CLIST_H__
+#define M_CLIST_H__ 1
+
+#ifdef _MSC_VER
+ #pragma warning(disable:4201 4204)
+#endif
+
+#include "statusmodes.h"
+
+#if defined _STATIC
+ typedef struct _tagIntMenuItem* HGENMENU;
+#else
+ DECLARE_HANDLE(HGENMENU);
+#endif
+
+//sent when the user asks to change their status
+//wParam=new status, from statusmodes.h
+//lParam=protocol name, NULL if for all protocols (added in v0.3.1alpha)
+//also sent due to a ms_clist_setstatusmode call
+#define ME_CLIST_STATUSMODECHANGE "CList/StatusModeChange"
+
+//force a change of status mode
+//wParam=new status, from statusmodes.h
+#define MS_CLIST_SETSTATUSMODE "CList/SetStatusMode"
+
+//get the current status mode
+//wParam=lParam=0
+//returns the current status
+//This is the status *as set by the user*, not any protocol-specific status
+//All protocol modules will attempt to conform to this setting at all times
+#define MS_CLIST_GETSTATUSMODE "CList/GetStatusMode"
+
+//gets a textual description of the given status mode (v0.1.0.1+)
+//wParam=status mode, from statusmodes.h
+//lParam=flags, below
+//returns a static buffer of the description of the given status mode
+//returns NULL if the status mode was unknown
+#define GSMDF_PREFIXONLINE 1 //prefix "Online: " to all status modes that
+ //imply online, eg "Online: Away"
+#define GCMDF_UNICODE 2 //will return TCHAR* instead of char*
+#if defined( _UNICODE )
+ #define GCMDF_TCHAR GCMDF_UNICODE //will return TCHAR* instead of char*
+#else
+ #define GCMDF_TCHAR 0 //will return char*, as usual
+#endif
+#define GSMDF_UNTRANSLATED 4
+#define MS_CLIST_GETSTATUSMODEDESCRIPTION "CList/GetStatusModeDescription"
+
+//add a new item to the main menu
+//wParam=0
+//lParam=(LPARAM)(CLISTMENUITEM*)&mi
+//returns a handle to the new item, or NULL on failure
+//the service that is called when the item is clicked is called with
+//wParam=0, lParam=hwndContactList
+//dividers are inserted every 100000 positions
+//pszContactOwner is ignored for this service.
+//there is a #define PUTPOSITIONSINMENU in clistmenus.c which, when set, will
+//cause the position numbers to be placed in brackets after the menu items
+
+// WARNING: do not use Translate(TS) for p(t)szName or p(t)szPopupName as they
+// are translated by the core, which may lead to double translation.
+// Use LPGEN instead which are just dummy wrappers/markers for "lpgen.pl".
+typedef struct {
+ int cbSize; //size in bytes of this structure
+ union {
+ char* pszName; //[TRANSLATED-BY-CORE] text of the menu item
+ TCHAR* ptszName; //Unicode text of the menu item
+ };
+ DWORD flags; //set of CMIF_* flags
+ int position; //approx position on the menu. lower numbers go nearer the top
+ union {
+ HICON hIcon; //icon to put by the item. If this was not loaded from
+ //a resource, you can delete it straight after the call
+ HANDLE icolibItem; //set CMIF_ICONFROMICOLIB to pass this value
+ };
+ char* pszService; //name of service to call when the item gets selected
+ union {
+ char* pszPopupName; //[TRANSLATED-BY-CORE] name of the popup menu that this item is on. If this
+ TCHAR* ptszPopupName; //is NULL the item is on the root of the menu
+ HGENMENU hParentMenu; // valid if CMIF_ROOTHANDLE is set. NULL or (HGENMENU)-1 means the root menu
+ };
+
+ int popupPosition; //position of the popup menu on the root menu. Ignored
+ //if pszPopupName is NULL or the popup menu already
+ //existed
+ DWORD hotKey; //keyboard accelerator, same as lParam of WM_HOTKEY,0 for none
+ char *pszContactOwner; //contact menus only. The protocol module that owns
+ //the contacts to which this menu item applies. NULL if it
+ //applies to all contacts. If it applies to multiple but not all
+ //protocols, add multiple menu items or use ME_CLIST_PREBUILDCONTACTMENU
+} CLISTMENUITEM;
+
+#define HGENMENU_ROOT (( HGENMENU )-1)
+
+#define CMIF_GRAYED 1
+#define CMIF_CHECKED 2
+#define CMIF_HIDDEN 4 //only works on contact menus
+#define CMIF_NOTOFFLINE 8 //item won't appear for contacts that are offline
+#define CMIF_NOTONLINE 16 // " online
+#define CMIF_NOTONLIST 32 //item won't appear on standard contacts
+#define CMIF_NOTOFFLIST 64 //item won't appear on contacts that have the 'NotOnList' setting
+#define CMIF_ROOTHANDLE 384 //means that hParentMenu member is set
+
+#define CMIF_UNICODE 512 //will return TCHAR* instead of char*
+#if defined( _UNICODE )
+ #define CMIF_TCHAR CMIF_UNICODE //will return TCHAR* instead of char*
+#else
+ #define CMIF_TCHAR 0 //will return char*, as usual
+#endif
+
+#define CMIF_KEEPUNTRANSLATED 1024 // don't translate a menu item
+#define CMIF_ICONFROMICOLIB 2048 // use icolibName instead of hIcon
+#define CMIF_DEFAULT 4096 // this menu item is the default one
+
+// for compatibility. since 0.8.0 they both mean nothing
+#define CMIF_ROOTPOPUP 128 //root item for new popup(save return id for childs)
+#define CMIF_CHILDPOPUP 256 //child for rootpopup menu
+
+#define MS_CLIST_ADDMAINMENUITEM "CList/AddMainMenuItem"
+
+//add a new item to the user contact menus
+//identical to clist/addmainmenuitem except when item is selected the service
+//gets called with wParam=(WPARAM)(HANDLE)hContact
+//pszContactOwner is obeyed.
+//popup menus are not supported. pszPopupName and popupPosition are ignored.
+//If ctrl is held down when right clicking, the menu position numbers will be
+//displayed in brackets after the menu item text. This only works in debug
+//builds.
+#define MS_CLIST_ADDCONTACTMENUITEM "CList/AddContactMenuItem"
+#define MS_CLIST_ADDSTATUSMENUITEM "CList/AddStatusMenuItem"
+
+//modify an existing menu item v0.1.0.1+
+//wParam=(WPARAM)(HANDLE)hMenuItem
+//lParam=(LPARAM)(CLISTMENUITEM*)&clmi
+//returns 0 on success, nonzero on failure
+//hMenuItem will have been returned by clist/add*menuItem
+//clmi.flags should contain cmim_ constants below specifying which fields to
+//update. Fields without a mask flag cannot be changed and will be ignored
+#define CMIM_NAME 0x80000000
+#define CMIM_FLAGS 0x40000000
+#define CMIM_ICON 0x20000000
+#define CMIM_HOTKEY 0x10000000
+#define CMIM_ALL 0xF0000000
+#define MS_CLIST_MODIFYMENUITEM "CList/ModifyMenuItem"
+
+//the context menu for a contact is about to be built v0.1.0.1+
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=0
+//modules should use this to change menu items that are specific to the
+//contact that has them
+#define ME_CLIST_PREBUILDCONTACTMENU "CList/PreBuildContactMenu"
+
+//sets the service to call when a contact is double-clicked
+//wParam=0
+//lParam=(LPARAM)(CLISTDOUBLECLICKACTION*)&dca
+//contactType is one or more of the constants below
+//pszService is called with wParam=hContact, lParam=0
+//pszService will only be called if there is no outstanding event on the
+//selected contact
+//returns 0 on success, nonzero on failure
+//in case of conflicts, the first module to have registered will get the
+//double click, no others will. This service will return success even for
+//duplicates.
+/*
+ Note: During development of 0.3.0.0 (2003/02/15) this service was completely dropped
+ by default it always returns 1 to mark failure, see ME_CLIST_DOUBLECLICKED for
+ a better implementation as a hook.
+*/
+typedef struct {
+ int cbSize;
+ char *pszContactOwner; //name of protocol owning contact, or NULL for all
+ DWORD flags; //any of the CMIF_NOT... flags above
+ char *pszService; //service to call on double click
+} CLISTDOUBLECLICKACTION;
+#define MS_CLIST_SETDOUBLECLICKACTION "CList/SetDoubleClickAction"
+
+/*
+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 ME_CLIST_DOUBLECLICKED "CList/DoubleClicked"
+//gets the string that the contact list will use to represent a contact
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=flags
+//returns a pointer to the name, will always succeed, even if it needs to
+//return "(Unknown Contact)"
+//this pointer is to a statically allocated buffer which will be overwritten
+//on every call to this service. Callers should make sure that they copy the
+//information before they call this service again.
+#define GCDNF_NOMYHANDLE 1 //will never return the user's custom name
+#define GCDNF_UNICODE 2 //will return TCHAR* instead of char*
+#define GCDNF_NOCACHE 4 //will not use the cache
+
+#if defined( _UNICODE )
+ #define GCDNF_TCHAR GCDNF_UNICODE //will return TCHAR* instead of char*
+#else
+ #define GCDNF_TCHAR 0 //will return char*, as usual
+#endif
+
+ //even if it's the one that should be displayed. v0.1.2.0+
+ //v0.3.0.0+ if using GCDNF_NOMYHANDLE you must free your string
+#define MS_CLIST_GETCONTACTDISPLAYNAME "CList/GetContactDisplayName"
+
+// Invalidates the display name cache
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=not used
+#define MS_CLIST_INVALIDATEDISPLAYNAME "CList/InvalidateDiplayName"
+
+//adds an event to the contact list's queue
+//wParam=0
+//lParam=(LPARAM)(CLISTEVENT*)cle
+//The contact list will flash hIcon next to the contact hContact (use NULL for
+//a system message). szServiceName will be called when the user double clicks
+//the icon, at which point the event will be removed from the contact list's
+//queue automatically
+//pszService is called with wParam=(WPARAM)(HWND)hwndContactList,
+//lParam=(LPARAM)(CLISTEVENT*)cle. Its return value is ignored. cle is
+//invalidated when your service returns, so take copies of any important
+//information in it.
+//hDbEvent should be unique since it and hContact are the identifiers used by
+//clist/removeevent if, for example, your module implements a 'read next' that
+//bypasses the double-click.
+typedef struct {
+ int cbSize; //size in bytes of this structure
+ HANDLE hContact; //handle to the contact to put the icon by
+ HICON hIcon; //icon to flash
+ DWORD flags; //...of course
+ union
+ {
+ HANDLE hDbEvent; //caller defined but should be unique for hContact
+ char * lpszProtocol;
+ };
+ LPARAM lParam; //caller defined
+ char *pszService; //name of the service to call on activation
+ union {
+ char *pszTooltip; //short description of the event to display as a
+ TCHAR *ptszTooltip; //tooltip on the system tray
+ };
+} CLISTEVENT;
+#define CLEF_URGENT 1 //flashes the icon even if the user is occupied,
+ //and puts the event at the top of the queue
+#define CLEF_ONLYAFEW 2 //the icon will not flash for ever, only a few
+ //times. This is for eg online alert
+#define CLEF_UNICODE 4 //set pszTooltip as unicode
+
+#define CLEF_PROTOCOLGLOBAL 8 //set event globally for protocol, hContact has to be NULL,
+ //lpszProtocol the protocol ID name to be set
+
+#if defined( _UNICODE )
+ #define CLEF_TCHAR CLEF_UNICODE //will use TCHAR* instead of char*
+#else
+ #define CLEF_TCHAR 0 //will return char*, as usual
+#endif
+
+#define MS_CLIST_ADDEVENT "CList/AddEvent"
+
+//removes an event from the contact list's queue
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=(LPARAM)(HANDLE)hDbEvent
+//returns 0 if the event was successfully removed, or nonzero if the event
+//was not found
+#define MS_CLIST_REMOVEEVENT "Clist/RemoveEvent"
+
+//gets the details of an event in the queue v0.1.2.1+
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=iEvent
+//returns a CLISTEVENT* on success, NULL on failure
+//Returns the iEvent-th event from the queue for hContact, so iEvent=0 will
+//get the event that will be got when the user clicks on that contact.
+//Use hContact=INVALID_HANDLE_VALUE to search over all contacts, so iEvent=0
+//will get the event that will be got if the user clicks the systray icon.
+#define MS_CLIST_GETEVENT "CList/GetEvent"
+
+//process a WM_MEASUREITEM message for user context menus v0.1.1.0+
+//wParam, lParam, return value as for WM_MEASUREITEM
+//This is for displaying the icons by the menu items. If you don't call this
+//and clist/menudrawitem whne drawing a menu returned by one of the three menu
+//services below then it'll work but you won't get any icons
+#define MS_CLIST_MENUMEASUREITEM "CList/MenuMeasureItem"
+
+//process a WM_DRAWITEM message for user context menus v0.1.1.0+
+//wParam, lParam, return value as for WM_MEASUREITEM
+//See comments for clist/menumeasureitem
+#define MS_CLIST_MENUDRAWITEM "CList/MenuDrawItem"
+
+//builds the context menu for a specific contact v0.1.1.0+
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=0
+//returns a HMENU identifying the menu. This should be DestroyMenu()ed when
+//finished with.
+#define MS_CLIST_MENUBUILDCONTACT "CList/MenuBuildContact"
+
+//gets the image list with all the useful icons in it v0.1.1.0+
+//wParam=lParam=0
+//returns a HIMAGELIST
+//the members of this image list are opaque, and you should trust what you
+//are given
+#define MS_CLIST_GETICONSIMAGELIST "CList/GetIconsImageList"
+#define IMAGE_GROUPOPEN 11
+#define IMAGE_GROUPSHUT 12
+
+//get the icon that should be associated with a contact v0.1.2.0+
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=0
+//returns an index into the contact list imagelist. See clist/geticonsimagelist
+//If the contact is flashing an icon, this function will not return that
+//flashing icon. Use me_clist_contacticonchanged to get info about that.
+#define MS_CLIST_GETCONTACTICON "CList/GetContactIcon"
+
+//The icon of a contact in the contact list has changed v0.1.2.0+
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=iconId
+//iconId is an offset into the clist's imagelist. See clist/geticonsimagelist
+#define ME_CLIST_CONTACTICONCHANGED "CList/ContactIconChanged"
+
+/******************************* CLUI only *********************************/
+
+// Stuff below here is ideally for the use of a CList UI module only.
+
+//get a handle to the main Miranda menu v0.1.1.0+
+//wParam=lParam=0
+//returns a HMENU. This need not be freed since it's owned by clist
+#define MS_CLIST_MENUGETMAIN "CList/MenuGetMain"
+
+//get a handle to the Miranda status menu v0.1.1.0+
+//wParam=lParam=0
+//returns a HMENU. This need not be freed since it's owned by clist
+#define MS_CLIST_MENUGETSTATUS "CList/MenuGetStatus"
+
+
+
+
+//processes a menu selection from a menu v0.1.1.0+
+//wParam=MAKEWPARAM(LOWORD(wParam from WM_COMMAND),flags)
+//lParam=(LPARAM)(HANDLE)hContact
+//returns TRUE if it processed the command, FALSE otherwise
+//hContact is the currently selected contact. It it not used if this is a main
+//menu command. If this is NULL and the command is a contact menu one, the
+//command is ignored
+
+#define CLISTMENUIDMIN 0x4000 // reserved range for clist menu ids
+#define CLISTMENUIDMAX 0x7fff
+//////////////////////////////////////////////////////////////////////////
+// NOTE: v0.7.0.26+
+// Due to it is generic practice to handle menu command via WM_COMMAND
+// window message handle and practice to process it via calling service
+// in form: CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM) hContact))
+// to ensure that WM_COMMAND was realy from clist menu not from other menu
+// it is reserved range of menu ids from CLISTMENUIDMIN to CLISTMENUIDMAX
+// the menu items with ids outside from such range will not be processed by service.
+// Moreover if you process WM_COMMAND youself and your window contains self menu
+// please be sure that you will not call service for non-clist menu items.
+// The simplest way is to ensure that your menus are not use item ids from such range.
+// Otherwise, you HAVE TO distinguish WM_COMMAND from clist menus and from you internal menu and
+// DO NOT call MS_CLIST_MENUPROCESSCOMMAND for non clist menus.
+
+
+#define MPCF_CONTACTMENU 1 //test commands from a contact menu
+#define MPCF_MAINMENU 2 //test commands from the main menu
+#define MS_CLIST_MENUPROCESSCOMMAND "CList/MenuProcessCommand"
+
+//processes a menu hotkey v0.1.1.0+
+//wParam=virtual key code
+//lParam=MPCF_ flags
+//returns TRUE if it processed the command, FALSE otherwise
+//this should be called in WM_KEYDOWN
+#define MS_CLIST_MENUPROCESSHOTKEY "CList/MenuProcessHotkey"
+
+//process all the messages required for docking v0.1.1.0+
+//wParam=(WPARAM)(MSG*)&msg
+//lParam=(LPARAM)(LRESULT*)&lResult
+//returns TRUE if the message should not be processed further, FALSE otherwise
+//only msg.hwnd, msg.message, msg.wParam and msg.lParam are used
+//your wndproc should return lResult if and only if TRUE is returned
+#define MS_CLIST_DOCKINGPROCESSMESSAGE "CList/DockingProcessMessage"
+
+//determines whether the contact list is docked v0.1.1.0+
+//wParam=lParam=0
+//returns nonzero if the contact list is docked, of 0 if it is not
+#define MS_CLIST_DOCKINGISDOCKED "CList/DockingIsDocked"
+
+//process all the messages required for the tray icon v0.1.1.0+
+//wParam=(WPARAM)(MSG*)&msg
+//lParam=(LPARAM)(LRESULT*)&lResult
+//returns TRUE if the message should not be processed further, FALSE otherwise
+//only msg.hwnd, msg.message, msg.wParam and msg.lParam are used
+//your wndproc should return lResult if and only if TRUE is returned
+#define MS_CLIST_TRAYICONPROCESSMESSAGE "CList/TrayIconProcessMessage"
+
+//process all the messages required for hotkeys v0.1.1.0+
+//wParam=(WPARAM)(MSG*)&msg
+//lParam=(LPARAM)(LRESULT*)&lResult
+//returns TRUE if the message should not be processed further, FALSE otherwise
+//only msg.hwnd, msg.message, msg.wParam and msg.lParam are used
+//your wndproc should return lResult if and only if TRUE is returned
+#define MS_CLIST_HOTKEYSPROCESSMESSAGE "CList/HotkeysProcessMessage"
+
+//toggles the show/hide status of the contact list v0.1.1.0+
+//wParam=lParam=0
+//returns 0 on success, nonzero on failure
+#define MS_CLIST_SHOWHIDE "CList/ShowHide"
+
+//temporarily disable the autohide feature v0.1.2.1+
+//wParam=lParam=0
+//returns 0 on success, nonzero on failure
+//This service will restart the autohide timer, so if you need to keep the
+//window visible you'll have to be getting user input regularly and calling
+//this function each time
+#define MS_CLIST_PAUSEAUTOHIDE "CList/PauseAutoHide"
+
+//sent when the group get modified (created, renamed or deleted)
+//or contact is moving from group to group
+//wParam=hContact - NULL if operation on group
+//lParam=pointer to CLISTGROUPCHANGE
+typedef struct {
+ int cbSize; //size in bytes of this structure
+ TCHAR* pszOldName; //old group name
+ TCHAR* pszNewName; //new group name
+} CLISTGROUPCHANGE;
+
+#define ME_CLIST_GROUPCHANGE "CList/GroupChange"
+
+//creates a new group and calls CLUI to display it v0.1.1.0+
+//wParam=hParentGroup
+//lParam=groupName
+//returns a handle to the new group
+//hParentGroup is NULL to create the new group at the root, or can be the
+//handle of the group of which the new group should be a subgroup.
+//groupName is a TCHAR* pointing to the group name to create or NULL for
+//API to create unique name by itself
+#define MS_CLIST_GROUPCREATE "CList/GroupCreate"
+
+//deletes a group and calls CLUI to display the change v0.1.1.0+
+//wParam=(WPARAM)(HANDLE)hGroup
+//lParam=0
+//returns 0 on success, nonzero on failure
+#define MS_CLIST_GROUPDELETE "CList/GroupDelete"
+
+//change the expanded state flag for a group internally v0.1.1.0+
+//wParam=(WPARAM)(HANDLE)hGroup
+//lParam=newState
+//returns 0 on success, nonzero on failure
+//newState is nonzero if the group is expanded, 0 if it's collapsed
+//CLUI is not called when this change is made
+#define MS_CLIST_GROUPSETEXPANDED "CList/GroupSetExpanded"
+
+//changes the flags for a group v0.1.2.1+
+//wParam=(WPARAM)(HANDLE)hGroup
+//lParam=MAKELPARAM(flags,flagsMask)
+//returns 0 on success, nonzero on failure
+//Only the flags given in flagsMask are altered.
+//CLUI is called on changes to GROUPF_HIDEOFFLINE.
+#define MS_CLIST_GROUPSETFLAGS "CList/GroupSetFlags"
+
+//get the name of a group v0.1.1.0+
+//wParam=(WPARAM)(HANDLE)hGroup
+//lParam=(LPARAM)(int*)&isExpanded
+//returns a static buffer pointing to the name of the group
+//returns NULL if hGroup is invalid.
+//this buffer is only valid until the next call to this service
+//&isExpanded can be NULL if you don't want to know if the group is expanded
+//or not.
+#define MS_CLIST_GROUPGETNAME "CList/GroupGetName"
+
+//get the name of a group v0.1.2.1+
+//wParam=(WPARAM)(HANDLE)hGroup
+//lParam=(LPARAM)(DWORD*)&flags
+//returns a static buffer pointing to the name of the group
+//returns NULL if hGroup is invalid.
+//this buffer is only valid until the next call to this service
+//&flags can be NULL if you don't want any of that info.
+#define GROUPF_EXPANDED 0x04
+#define GROUPF_HIDEOFFLINE 0x08
+#define MS_CLIST_GROUPGETNAME2 "CList/GroupGetName2"
+
+//move a group to directly before another group v0.1.2.1+
+//wParam=(WPARAM)(HANDLE)hGroup
+//lParam=(LPARAM)(HANDLE)hBeforeGroup
+//returns the new handle of the group on success, NULL on failure
+//The order is represented by the order in which MS_CLUI_GROUPADDED is called,
+//however UIs are free to ignore this order and sort alphabetically if they
+//wish.
+#define MS_CLIST_GROUPMOVEBEFORE "CList/GroupMoveBefore"
+
+//rename a group internally v0.1.1.0+
+//wParam=(WPARAM)(HANDLE)hGroup
+//lParam=(LPARAM)(char*)szNewName
+//returns 0 on success, nonzero on failure
+//this will fail if the group name is a duplicate of an existing name
+//CLUI is not called when this change is made
+#define MS_CLIST_GROUPRENAME "CList/GroupRename"
+
+//build a menu of the group tree v0.1.2.1+
+//wParam=0
+//lParam=0
+//returns a HMENU on success, or NULL on failure
+//The return value must be DestroyMenu()ed when you're done with it.
+//NULL will be returned if the user doesn't have any groups
+//The dwItemData of every menu item is the handle to that group.
+//Menu item IDs are assigned starting at 100, in no particular order.
+#define MS_CLIST_GROUPBUILDMENU "CList/GroupBuildMenu"
+
+//changes the 'hide offline contacts' flag and call CLUI v0.1.1.0+
+//wParam=newValue
+//lParam=0
+//returns 0 on success, nonzero on failure
+//newValue is 0 to show all contacts, 1 to only show online contacts
+//or -1 to toggle the value
+#define MS_CLIST_SETHIDEOFFLINE "CList/SetHideOffline"
+
+//do the message processing associated with double clicking a contact v0.1.1.0+
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=0
+//returns 0 on success, nonzero on failure
+#define MS_CLIST_CONTACTDOUBLECLICKED "CList/ContactDoubleClicked"
+
+//do the processing for when some files are dropped on a contact v0.1.2.1+
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=(LPARAM)(char**)ppFiles
+//returns 0 on success, nonzero on failure
+//ppFiles is an array of fully qualified filenames, ending with a NULL.
+#define MS_CLIST_CONTACTFILESDROPPED "CList/ContactFilesDropped"
+
+//change the group a contact belongs to v0.1.1.0+
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=(LPARAM)(HANDLE)hGroup
+//returns 0 on success, nonzero on failure
+//use hGroup=NULL to put the contact in no group
+#define MS_CLIST_CONTACTCHANGEGROUP "CList/ContactChangeGroup"
+
+//determines the ordering of two contacts v0.1.1.0+
+//wParam=(WPARAM)(HANDLE)hContact1
+//lParam=(LPARAM)(HANDLE)hContact2
+//returns 0 if hContact1 is the same as hContact2
+//returns +1 if hContact2 should be displayed after hContact1
+//returns -1 if hContact1 should be displayed after hContact2
+#define MS_CLIST_CONTACTSCOMPARE "CList/ContactsCompare"
+
+/*
+ wParam=0 (not used)
+ lParam=(LPARAM) &MIRANDASYSTRAYNOTIFY
+
+ Affects: Show a message in a ballon tip against a protocol icon (if installed)
+ Returns: 0 on success, non zero on failure
+ Notes : This service will not be created on systems that haven't got the Windows
+ support for ballontips, also note that it's upto Windows if it shows your
+ message and it keeps check of delays (don't be stupid about showing messages)
+
+ Version: 0.3.1a
+*/
+#define NIIF_INFO 0x00000001
+#define NIIF_WARNING 0x00000002
+#define NIIF_ERROR 0x00000003
+#define NIIF_ICON_MASK 0x0000000F
+#define NIIF_NOSOUND 0x00000010
+#define NIIF_INTERN_UNICODE 0x00000100
+
+
+typedef struct {
+ int cbSize; // sizeof(MIRANDASYSTRAY)
+ char *szProto; // protocol to show under (may have no effect)
+ union {
+ char *szInfoTitle; // only 64chars of it will be used
+ TCHAR *tszInfoTitle; // used if NIIF_INTERN_UNICODE is specified
+ };
+ union {
+ char *szInfo; // only 256chars of it will be used
+ TCHAR *tszInfo; // used if NIIF_INTERN_UNICODE is specified
+ };
+ DWORD dwInfoFlags; // see NIIF_* stuff
+ UINT uTimeout; // how long to show the tip for
+} MIRANDASYSTRAYNOTIFY;
+#define MS_CLIST_SYSTRAY_NOTIFY "Miranda/Systray/Notify"
+
+#define SETTING_TOOLWINDOW_DEFAULT 1
+#define SETTING_SHOWMAINMENU_DEFAULT 1
+#define SETTING_SHOWCAPTION_DEFAULT 1
+#define SETTING_CLIENTDRAG_DEFAULT 1
+#define SETTING_ONTOP_DEFAULT 0
+#define SETTING_MIN2TRAY_DEFAULT 1
+#define SETTING_TRAY1CLICK_DEFAULT (IsWinVer7Plus()?1:0)
+#define SETTING_HIDEOFFLINE_DEFAULT 0
+#define SETTING_HIDEEMPTYGROUPS_DEFAULT 0
+#define SETTING_USEGROUPS_DEFAULT 1
+#define SETTING_SORTBYSTATUS_DEFAULT 0
+#define SETTING_SORTBYPROTO_DEFAULT 0
+#define SETTING_TRANSPARENT_DEFAULT 0
+#define SETTING_ALPHA_DEFAULT 200
+#define SETTING_AUTOALPHA_DEFAULT 150
+#define SETTING_CONFIRMDELETE_DEFAULT 1
+#define SETTING_AUTOHIDE_DEFAULT 0
+#define SETTING_HIDETIME_DEFAULT 30
+#define SETTING_CYCLETIME_DEFAULT 4
+#define SETTING_TRAYICON_DEFAULT SETTING_TRAYICON_SINGLE
+#define SETTING_ALWAYSSTATUS_DEFAULT 0
+#define SETTING_ALWAYSMULTI_DEFAULT 0
+
+#define SETTING_TRAYICON_SINGLE 0
+#define SETTING_TRAYICON_CYCLE 1
+#define SETTING_TRAYICON_MULTI 2
+
+#define SETTING_STATE_HIDDEN 0
+#define SETTING_STATE_MINIMIZED 1
+#define SETTING_STATE_NORMAL 2
+
+#define SETTING_BRINGTOFRONT_DEFAULT 0
+
+#endif // M_CLIST_H__
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_database.h b/plugins/!NotAdopted/WinPopup/sdk/m_database.h
new file mode 100644
index 0000000000..c1bf7dafd3
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_database.h
@@ -0,0 +1,1199 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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_DATABASE_H__
+#define M_DATABASE_H__ 1
+
+/******************* DATABASE MODULE ***************************/
+
+/* Notes (as I think of them):
+- The module is 100% thread-safe
+- The database is the main routing point for the vast majority of Miranda.
+ Events are sent from the protocol module to here, and the send/recv message
+ module (for example) hooks the db/event/added event. Events like 'contact
+ online status changed' do not come through here - icqlib will send that one.
+- contacts work much the same. the find/add users module calls db/contact/add
+ and db/contact/writesetting and the contact list will get db/contact/added
+ and db/contact/settingchanged events
+- The user is just a special contact. A hcontact of NULL in most functions
+ means the user. Functions in which it cannot be used will be stated
+- events attached to the user are things like system messages
+- also in this module are crypt/decrypt functions for stuff that should be
+ obfuscated on the disk, and some time functions for dealing with timestamps
+ in events.
+- the contactsettings system is designed for being read by many different
+ modules. eg lots of people will be interested in "ICQ"/"UIN", but the module
+ name passed to contact/writesetting should always be your own. The Mirabilis
+ ICQ database importer clearly has to be an exception to this rule, along with
+ a few other bits.
+- the current database format means that geteventcontact is exceptionally slow.
+ It should be avoidable in most cases so I'm not too concerned, but if people
+ really need to use it a lot, I'll sort it out.
+- handles do not need to be closed unless stated
+- the database is loaded as a memory mapped file. This has various
+ disadvantages but a massive advantage in speed for random access.
+- The database is optimised for reading. Write performance is fairly bad,
+ except for adding events which is the most common activity and pretty good.
+- I'll work on caching to improve this later
+- Deleted items are left as empty space and never reused. All new items are
+ put at the end. A count is kept of this slack space and at some point a
+ separate programme will need to be written to repack the database when the
+ slack gets too high. It's going to be a good few months of usage before this
+ can happen to anyone though, so no rush.
+*/
+
+/******************** GENERALLY USEFUL STUFF***********************/
+
+#include <tchar.h>
+
+#if !defined(M_SYSTEM_H__)
+ #include "m_system.h"
+#endif
+
+#if !defined(M_UTILS_H__)
+ #include "m_utils.h"
+#endif
+
+#ifdef _MSC_VER
+ #pragma warning(disable:4201 4204)
+#endif
+
+//DBVARIANT: used by db/contact/getsetting and db/contact/writesetting
+#define DBVT_DELETED 0 //this setting just got deleted, no other values are valid
+#define DBVT_BYTE 1 //bVal and cVal are valid
+#define DBVT_WORD 2 //wVal and sVal are valid
+#define DBVT_DWORD 4 //dVal and lVal are valid
+#define DBVT_ASCIIZ 255 //pszVal is valid
+#define DBVT_BLOB 254 //cpbVal and pbVal are valid
+#define DBVT_UTF8 253 //pszVal is valid
+#define DBVT_WCHAR 252 //pszVal is valid
+#if defined( _UNICODE )
+ #define DBVT_TCHAR DBVT_WCHAR
+#else
+ #define DBVT_TCHAR DBVT_ASCIIZ
+#endif
+#define DBVTF_VARIABLELENGTH 0x80
+#define DBVTF_DENYUNICODE 0x10000
+typedef struct {
+ BYTE type;
+ union {
+ BYTE bVal; char cVal;
+ WORD wVal; short sVal;
+ DWORD dVal; long lVal;
+ struct {
+ union {
+ char *pszVal;
+ TCHAR *ptszVal;
+ WCHAR *pwszVal;
+ };
+ WORD cchVal; //only used for db/contact/getsettingstatic
+ };
+ struct {
+ WORD cpbVal;
+ BYTE *pbVal;
+ };
+ };
+} DBVARIANT;
+
+/******************************************************************/
+/************************* SERVICES *******************************/
+/******************************************************************/
+
+/* DB/Contact/GetProfileName service
+Gets the name of the profile currently being used by the database module. This
+is the same as the filename of the database
+ wParam=(WPARAM)(UINT)cbName
+ lParam=(LPARAM)(char*)pszName
+pszName is a pointer to the buffer that receives the name of the profile
+cbName is the size in bytes of the pszName buffer
+Returns 0 on success or nonzero otherwise
+*/
+#define MS_DB_GETPROFILENAME "DB/GetProfileName"
+
+/* DB/Contact/GetProfilePath service
+Gets the path of the profile currently being used by the database module. This
+path does not include the last '\'.
+ wParam=(WPARAM)(UINT)cbName
+ lParam=(LPARAM)(char*)pszName
+pszName is a pointer to the buffer that receives the path of the profile
+cbName is the size in bytes of the pszName buffer
+Returns 0 on success or nonzero otherwise
+*/
+#define MS_DB_GETPROFILEPATH "DB/GetProfilePath"
+
+/************************* Contact ********************************/
+
+/* DB/Contact/GetSetting service
+Look up the value of a named setting for a specific contact in the database
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=(LPARAM)(DBCONTACTGETSETTING*)&dbcgs
+hContact should have been returned by find*contact or addcontact
+Caller is responsible for free()ing dbcgs.pValue->pszVal and pbVal if they are
+returned. This should be done with db/contact/freevariant if you have your own
+heap (like DLLs do).
+Note that DBCONTACTGETSETTING takes a pointer to a DBVARIANT, whereas
+DBCONTACTWRITESETTING contains a DBVARIANT.
+Returns 0 on success or nonzero if the setting name was not found or hContact
+was invalid
+Because this is such a common function there are some short helper function at
+the bottom of this header that use it.
+
+(Added during 0.3.3+ development!!)
+
+If a setting is queried under for contact and it is deleted it will
+not be returned as a successful attempt, prior to 0.3.3 a *deleted*
+setting would be successfully read (which was a bug because the pValue
+was often garbage and maybe not even NULL terminated)
+
+To test for existing but 'deleted' settings, the return value will
+be 2, and pValue->type==DBVT_DELETED, at this point pValue is undefined.
+*/
+typedef struct {
+ const char *szModule; // pointer to name of the module that wrote the
+ // setting to get
+ const char *szSetting; // pointer to name of the setting to get
+ DBVARIANT *pValue; // pointer to variant to receive the value
+} DBCONTACTGETSETTING;
+#define MS_DB_CONTACT_GETSETTING "DB/Contact/GetSetting"
+
+/* DB/Contact/GetSettingString service 0.4.3+
+Same as DB/Contact/GetSetting, but also gets the required string type inside
+the dbcgs->type parameter
+*/
+#define MS_DB_CONTACT_GETSETTING_STR "DB/Contact/GetSettingStr"
+
+/* DB/Contact/GetSettingStatic service
+Look up the value of a named setting for a specific contact in the database
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=(LPARAM)(DBCONTACTGETSETTING*)&dbcgs
+hContact should have been returned by find*contact or addcontact
+This service differs from db/contact/getsetting in that it won't malloc()
+memory for the return value if it needs to do so. This introduces some extra
+constraints:
+Upon calling dbcgs.pValue->type should be initialised to the expected type of
+the setting. If the setting is of an integral type it won't matter if it's
+wrong and the service will correct it before returning, however if the setting
+is a string or a blob the service needs to know where to put the data and will
+fail if type is set wrongly.
+If dbcgs.pValue->type is DBVT_ASCIIZ or DBVT_BLOB upon calling, the
+corresponding data field (pszVal or pbVal) must point to a buffer allocated by
+the caller and the length field (cchVal or cpbVal) must contain the size of
+that buffer in bytes.
+If the setting type is variable length (DBVT_ASCIIZ or DBVT_BLOB), on exit the
+length field (cchVal or cpbVal) will be filled with the full length of the
+setting's value (excluding the terminating nul if it's DBVT_ASCIIZ).
+This service exists as well as db/contact/getsetting because malloc()/free()
+can be too slow for frequently queried settings.
+Returns 0 on success or nonzero if the setting name was not found or hContact
+was invalid.
+*/
+#define MS_DB_CONTACT_GETSETTINGSTATIC "DB/Contact/GetSettingStatic"
+
+/* DB/Contact/FreeVariant service
+Free the memory in a DBVARIANT that is allocated by a call to
+db/contact/getsetting
+ wParam=0
+ lParam=(LPARAM)(DBVARIANT*)&dbv
+Returns 0 on success, nonzero otherwise
+This service is actually just a wrapper around a call to free() and a test to
+check that it is a string or a blob in the variant. It exists because DLLs have
+their own heap and cannot free the memory allocated in db/contact/getsetting.
+Thus it need not be called if you know the variant contains some form of int,
+and you will often see free() used instead in code written before I noticed
+this problem.
+Good style, of course, dictates that it should be present to match all calls to
+db/contact/getsetting, but that's not going to happen of course.
+There's a helper function for this at the bottom of this header too.
+*/
+#define MS_DB_CONTACT_FREEVARIANT "DB/Contact/FreeVariant"
+
+/* DB/Contact/WriteSetting service
+Change the value of, or create a new value with, a named setting for a specific
+contact in the database to the given value
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=(LPARAM)(DBCONTACTWRITESETTING*)&dbcws
+hContact should have been returned by find*contact or addcontact
+Returns 0 on success or nonzero if hContact was invalid
+Note that DBCONTACTGETSETTING takes a pointer to a DBVARIANT, whereas
+DBCONTACTWRITESETTING contains a DBVARIANT.
+Because this is such a common function there are some short helper function at
+the bottom of this header that use it.
+Triggers a db/contact/settingchanged event just before it returns.
+*/
+typedef struct {
+ const char *szModule; // pointer to name of the module that wrote the
+ // setting to get
+ const char *szSetting; // pointer to name of the setting to get
+ DBVARIANT value; // variant containing the value to set
+} DBCONTACTWRITESETTING;
+#define MS_DB_CONTACT_WRITESETTING "DB/Contact/WriteSetting"
+
+/* DB/Contact/DeleteSetting service
+Removes a named setting for a specific contact from the database
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=(LPARAM)(DBCONTACTGETSETTING*)&dbcgs
+hContact should have been returned by find*contact or addcontact
+pValue from dbcgs is not used.
+Returns 0 on success or nonzero if the setting was not present or hContact was
+invalid
+Triggers a db/contact/settingchanged event before it deletes the setting. The
+'new value' of the setting is set to type=0 and all the other fields are
+undefined.
+*/
+#define MS_DB_CONTACT_DELETESETTING "DB/Contact/DeleteSetting"
+
+/* db/contact/enumsettings v0.1.0.1+
+Lists all the settings a specific modules has stored in the database for a
+specific contact.
+wParam=(WPARAM)(HANDLE)hContact
+lParam=(LPARAM)(DBCONTACTENUMSETTINGS*)&dbces
+Returns the return value of the last call to pfnEnumProc, or -1 if there are
+no settings for that module/contact pair
+Writing to or deleting from the database while enumerating will have
+unpredictable results for the enumeration, but the write will succeed.
+Use db/modules/enum to get a complete list of module names
+szSetting is only guaranteed to be valid for the duration of the callback. If
+you want to keep it for longer you must allocation your own storage.
+*/
+typedef int (*DBSETTINGENUMPROC)(const char *szSetting,LPARAM lParam);
+typedef struct {
+ DBSETTINGENUMPROC pfnEnumProc;
+ LPARAM lParam; //passed direct to pfnEnumProc
+ const char *szModule; //name of the module to get settings for
+ DWORD ofsSettings; //filled by the function to contain the offset from
+ //the start of the database of the requested settings group.
+} DBCONTACTENUMSETTINGS;
+#define MS_DB_CONTACT_ENUMSETTINGS "DB/Contact/EnumSettings"
+
+/* DB/Contact/GetCount service
+Gets the number of contacts in the database, which does not count the user
+ wParam=lParam=0
+Returns the number of contacts. They can be retrieved using contact/findfirst
+and contact/findnext
+*/
+#define MS_DB_CONTACT_GETCOUNT "DB/Contact/GetCount"
+
+/* DB/Contact/FindFirst service
+Gets the handle of the first contact in the database. This handle can be used
+with loads of functions. It does not need to be closed.
+ wParam=lParam=0
+Returns a handle to the first contact in the db on success, or NULL if there
+are no contacts in the db.
+*/
+#define MS_DB_CONTACT_FINDFIRST "DB/Contact/FindFirst"
+
+/* DB/Contact/FindNext service
+Gets the handle of the next contact after hContact in the database. This handle
+can be used with loads of functions. It does not need to be closed.
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=0
+Returns a handle to the contact after hContact in the db on success or NULL if
+hContact was the last contact in the db or hContact was invalid.
+*/
+#define MS_DB_CONTACT_FINDNEXT "DB/Contact/FindNext"
+
+/* DB/Contact/Delete
+Deletes the contact hContact from the database and all events and settings
+associated with it.
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=0
+Returns 0 on success or nonzero if hContact was invalid
+Please don't try to delete the user contact (hContact=NULL)
+Triggers a db/contact/deleted event just *before* it removes anything
+Because all events are deleted, lots of people may end up with invalid event
+handles from this operation, which they should be prepared for.
+*/
+#define MS_DB_CONTACT_DELETE "DB/Contact/Delete"
+
+/* DB/Contact/Add
+Adds a new contact to the database. New contacts initially have no settings
+whatsoever, they must all be added with db/contacts/writesetting.
+ wParam=lParam=0
+Returns a handle to the newly created contact on success, or NULL otherwise.
+Triggers a db/contact/added event just before it returns.
+*/
+#define MS_DB_CONTACT_ADD "DB/Contact/Add"
+
+/* DB/Contact/Is
+Checks if a given value is a valid contact handle, note that due
+to the nature of multiple threading, a valid contact can still become
+invalid after a call to this service.
+ wParam=(WPARAM)hContact
+ lParam=0
+Returns 1 if the contact is a contact, or 0 if the contact is not valid.
+*/
+#define MS_DB_CONTACT_IS "DB/Contact/Is"
+
+/************************** Event *********************************/
+
+/* DB/EventType/Register service (0.7+)
+Registers the specified database event type, with module, id & description.
+When someone needs to retrieve an event's text, a service named Module/GetEventText<id>
+will be called. For example, for module named 'foo' and event id 2000 a service
+foo/GetEventText2000 should be defined to process this request. That handler should
+decode a blob and return the event text in the required format, its prototype is identical
+to a call of MS_DB_EVENT_GETTEXT (see below)
+ wParam=0
+ lParam=(LPARAM)(DBEVENTTYPEDESCR*)
+Always returns 0.
+*/
+
+#define DBEVENTTYPEDESCR_SIZE sizeof(DBEVENTTYPEDESCR)
+#define DBEVENTTYPEDESCR_SIZE_V1 0x10
+
+typedef struct
+{
+ int cbSize; // structure size in bytes
+ char* module; // event module name
+ int eventType; // event id, unique for this module
+ char* descr; // event type description (i.e. "File Transfer")
+ char* textService; // service name for MS_DB_EVENT_GETTEXT (0.8+, default Module+'/GetEventText'+EvtID)
+ char* iconService; // service name for MS_DB_EVENT_GETICON (0.8+, default Module+'/GetEventIcon'+EvtID)
+ HANDLE eventIcon; // icolib handle to eventicon (0.8+, default 'eventicon_'+Module+EvtID)
+ DWORD flags; // flags, combination of the DETF_*
+}
+ DBEVENTTYPEDESCR;
+
+// constants for default event behaviour
+#define DETF_HISTORY 1 // show event in history
+#define DETF_MSGWINDOW 2 // show event in message window
+#define DETF_NONOTIFY 4 // block event notify (e.g. Popups)
+
+
+#define MS_DB_EVENT_REGISTERTYPE "DB/EventType/Register"
+
+/* DB/EventType/Get service (0.7+)
+Retrieves the previously registered database event type, by module & id.
+ wParam=(WPARAM)(char*)szModule
+ lParam=(LPARAM)(int)eventType
+Returns DBEVENTTYPEDESCR* or NULL, if an event isn't found.
+*/
+
+#define MS_DB_EVENT_GETTYPE "DB/EventType/Get"
+
+/* DB/Event/GetCount service
+Gets the number of events in the chain belonging to a contact in the database.
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=0
+Returns the number of events in the chain owned by hContact or -1 if hContact
+is invalid. They can be retrieved using the event/find* services.
+*/
+#define MS_DB_EVENT_GETCOUNT "DB/Event/GetCount"
+
+/* DB/Event/Add
+Adds a new event to a contact's event list
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=(LPARAM)(DBEVENTINFO*)&dbe
+Returns a handle to the newly added event, or NULL on failure
+Triggers a db/event/added event just before it returns.
+Events are sorted chronologically as they are entered, so you cannot guarantee
+that the new hEvent is the last event in the chain, however if a new event is
+added that has a timestamp less than 90 seconds *before* the event that should
+be after it, it will be added afterwards, to allow for protocols that only
+store times to the nearest minute, and slight delays in transports.
+There are a few predefined eventTypes below for easier compatibility, but
+modules are free to define their own, beginning at 2000
+DBEVENTINFO.timestamp is in GMT, as returned by time(). There are services
+db/time/x below with useful stuff for dealing with it.
+*/
+#define DBEF_FIRST 1 //this is the first event in the chain;
+ //internal only: *do not* use this flag
+#define DBEF_SENT 2 //this event was sent by the user. If not set this
+ //event was received.
+#define DBEF_READ 4 //event has been read by the user. It does not need
+ //to be processed any more except for history.
+#define DBEF_RTL 8 //event contains the right-to-left aligned text
+#define DBEF_UTF 16 //event contains a text in utf-8
+
+typedef struct {
+ int cbSize; //size of the structure in bytes
+ char *szModule; //pointer to name of the module that 'owns' this
+ //event, ie the one that is in control of the data format
+ DWORD 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.
+ DWORD flags; //the omnipresent flags
+ WORD eventType; //module-defined event type field
+ DWORD cbBlob; //size of pBlob in bytes
+ PBYTE pBlob; //pointer to buffer containing module-defined event data
+} DBEVENTINFO;
+#define EVENTTYPE_MESSAGE 0
+#define EVENTTYPE_URL 1
+#define EVENTTYPE_CONTACTS 2 //v0.1.2.2+
+#define EVENTTYPE_ADDED 1000 //v0.1.1.0+: these used to be module-
+#define EVENTTYPE_AUTHREQUEST 1001 //specific codes, hence the module-
+#define EVENTTYPE_FILE 1002 //specific limit has been raised to 2000
+#define MS_DB_EVENT_ADD "DB/Event/Add"
+
+/* DB/Event/Delete
+Removes a single event from the database
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=(LPARAM)(HANDLE)hDbEvent
+hDbEvent should have been returned by db/event/add or db/event/find*event
+Returns 0 on success, or nonzero if hDbEvent was invalid
+Triggers a db/event/deleted event just *before* the event is deleted
+*/
+#define MS_DB_EVENT_DELETE "DB/Event/Delete"
+
+/* DB/Event/GetBlobSize
+Retrieves the space in bytes required to store the blob in hDbEvent
+ wParam=(WPARAM)(HANDLE)hDbEvent
+ lParam=0
+hDbEvent should have been returned by db/event/add or db/event/find*event
+Returns the space required in bytes, or -1 if hDbEvent is invalid
+*/
+#define MS_DB_EVENT_GETBLOBSIZE "DB/Event/GetBlobSize"
+
+/* DB/Event/Get
+Retrieves all the information stored in hDbEvent
+ wParam=(WPARAM)(HANDLE)hDbEvent
+ lParam=(LPARAM)(DBEVENTINFO*)&dbe
+hDbEvent should have been returned by db/event/add or db/event/find*event
+Returns 0 on success or nonzero if hDbEvent is invalid
+Don't forget to set dbe.cbSize, dbe.pBlob and dbe.cbBlob before calling this
+service
+The correct value dbe.cbBlob can be got using db/event/getblobsize
+If successful, all the fields of dbe are filled. dbe.cbBlob is set to the
+actual number of bytes retrieved and put in dbe.pBlob
+If dbe.cbBlob is too small, dbe.pBlob is filled up to the size of dbe.cbBlob
+and then dbe.cbBlob is set to the required size of data to go in dbe.pBlob
+On return, dbe.szModule is a pointer to the database module's own internal list
+of modules. Look but don't touch.
+*/
+#define MS_DB_EVENT_GET "DB/Event/Get"
+
+/* DB/Event/GetText (0.7.0+)
+Retrieves the event's text
+ wParam=(WPARAM)0 (unused)
+ lParam=(LPARAM)(DBEVENTGETTEXT*)egt - pointer to structure with parameters
+ egt->dbei should be the valid database event read via MS_DB_EVENT_GET
+ egt->datatype = DBVT_WCHAR or DBVT_ASCIIZ or DBVT_TCHAR. If a caller wants to
+suppress Unicode part of event in answer, add DBVTF_DENYUNICODE to this field.
+ egt->codepage is any valid codepage, CP_ACP by default.
+
+Function returns a pointer to a string in the required format.
+This string should be freed by a call of mir_free
+*/
+typedef struct {
+ DBEVENTINFO* dbei;
+ int datatype;
+ int codepage;
+} DBEVENTGETTEXT;
+
+#define MS_DB_EVENT_GETTEXT "DB/Event/GetText"
+
+__inline static char* DbGetEventTextA( DBEVENTINFO* dbei, int codepage )
+{ DBEVENTGETTEXT temp = { dbei, DBVT_ASCIIZ, codepage };
+ return (char*)CallService(MS_DB_EVENT_GETTEXT,0,(LPARAM)&temp);
+}
+
+__inline static WCHAR* DbGetEventTextW( DBEVENTINFO* dbei, int codepage )
+{ DBEVENTGETTEXT temp = { dbei, DBVT_WCHAR, codepage };
+ return (WCHAR*)CallService(MS_DB_EVENT_GETTEXT,0,(LPARAM)&temp);
+}
+
+__inline static TCHAR* DbGetEventTextT( DBEVENTINFO* dbei, int codepage )
+{ DBEVENTGETTEXT temp = { dbei, DBVT_TCHAR, codepage };
+ return (TCHAR*)CallService(MS_DB_EVENT_GETTEXT,0,(LPARAM)&temp);
+}
+
+/* DB/Event/GetIcon (0.7.0.1+)
+Retrieves the event's icon
+ wParam=(WPARAM)(int)flags - use LR_SHARED for shared HICON
+ lParam=(LPARAM)(DBEVENTINFO*)dbei
+dbei should be a valid database event read via MS_DB_EVENT_GET
+
+Function returns HICON (use DestroyIcon to release resources if not LR_SHARED)
+
+A plugin can register the standard event icon in IcoLib named
+'eventicon_'+Module+EvtID, like eventicon_ICQ2001. Otherwise, to declare an icon
+with the non-standard name, you can declare the special service, Module/GetEventIcon<id>,
+which will retrieve the custom icon handle (HICON). This service function has the
+same parameters MS_DB_EVENT_GETICON does.
+*/
+#define MS_DB_EVENT_GETICON "DB/Event/GetIcon"
+
+/* DB/Event/GetString (0.9.0+)
+Converts the event's string to TCHAR* depending on the event's format
+ wParam=(LPARAM)(DBEVENTINFO*)dbei
+ lParam=(WPARAM)(char*)str - string to be converted
+ returns TCHAR* - the converted string
+Caller must free the result using mir_free
+*/
+
+#define MS_DB_EVENT_GETSTRINGT "DB/Event/GetStringT"
+
+__inline static TCHAR* DbGetEventStringT( DBEVENTINFO* dbei, const char* str )
+{
+ return (TCHAR*)CallService( MS_DB_EVENT_GETSTRINGT, (WPARAM)dbei, (LPARAM)str );
+}
+
+/* DB/Event/MarkRead
+Changes the flags for an event to mark it as read.
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=(LPARAM)(HANDLE)hDbEvent
+hDbEvent should have been returned by db/event/add or db/event/find*event
+Returns the entire flag DWORD for the event after the change, or -1 if hDbEvent
+is invalid.
+This is the one database write operation that does not trigger an event.
+Modules should not save flags states for any length of time.
+*/
+#define MS_DB_EVENT_MARKREAD "DB/Event/MarkRead"
+
+/* DB/Event/GetContact
+Retrieves a handle to the contact that owns hDbEvent.
+ wParam=(WPARAM)(HANDLE)hDbEvent
+ lParam=0
+hDbEvent should have been returned by db/event/add or db/event/find*event
+NULL is a valid return value, meaning, as usual, the user.
+Returns (HANDLE)(-1) if hDbEvent is invalid, or the handle to the contact on
+success
+This service is exceptionally slow. Use only when you have no other choice at
+all.
+*/
+#define MS_DB_EVENT_GETCONTACT "DB/Event/GetContact"
+
+/* DB/Event/FindFirst
+Retrieves a handle to the first event in the chain for hContact
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=0
+Returns the handle, or NULL if hContact is invalid or has no events
+Events in a chain are sorted chronologically automatically
+*/
+#define MS_DB_EVENT_FINDFIRST "DB/Event/FindFirst"
+
+/* DB/Event/FindFirstUnread
+Retrieves a handle to the first unread event in the chain for hContact
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=0
+Returns the handle, or NULL if hContact is invalid or all its events have been
+read
+Events in a chain are sorted chronologically automatically, but this does not
+necessarily mean that all events after the first unread are unread too. They
+should be checked individually with event/findnext and event/get
+This service is designed for startup, reloading all the events that remained
+unread from last time
+*/
+#define MS_DB_EVENT_FINDFIRSTUNREAD "DB/Event/FindFirstUnread"
+
+/* DB/Event/FindLast
+Retrieves a handle to the last event in the chain for hContact
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=0
+Returns the handle, or NULL if hContact is invalid or has no events
+Events in a chain are sorted chronologically automatically
+*/
+#define MS_DB_EVENT_FINDLAST "DB/Event/FindLast"
+
+/* DB/Event/FindNext
+Retrieves a handle to the next event in a chain after hDbEvent
+ wParam=(WPARAM)(HANDLE)hDbEvent
+ lParam=0
+Returns the handle, or NULL if hDbEvent is invalid or is the last event
+Events in a chain are sorted chronologically automatically
+*/
+#define MS_DB_EVENT_FINDNEXT "DB/Event/FindNext"
+
+/* DB/Event/FindPrev
+Retrieves a handle to the previous event in a chain before hDbEvent
+ wParam=(WPARAM)(HANDLE)hDbEvent
+ lParam=0
+Returns the handle, or NULL if hDbEvent is invalid or is the first event
+Events in a chain are sorted chronologically automatically
+*/
+#define MS_DB_EVENT_FINDPREV "DB/Event/FindPrev"
+
+/************************** Encryption ****************************/
+
+/* DB/Crypt/EncodeString
+Scrambles pszString in-place using a strange encryption algorithm
+ wParam=(WPARAM)(int)cbString
+ lParam=(LPARAM)(char*)pszString
+cbString is the size of the buffer pointed to by pszString, *not* the length
+of pszString. This service may be changed at a later date such that it
+increases the length of pszString
+Returns 0 always
+*/
+#define MS_DB_CRYPT_ENCODESTRING "DB/Crypt/EncodeString"
+
+/* DB/Crypt/DecodeString
+Descrambles pszString in-place using the strange encryption algorithm
+ wParam=(WPARAM)(int)cbString
+ lParam=(LPARAM)(char*)pszString
+Reverses the operation done by crypt/encodestring
+cbString is the size of the buffer pointed to by pszString, *not* the length
+of pszString.
+Returns 0 always
+*/
+#define MS_DB_CRYPT_DECODESTRING "DB/Crypt/DecodeString"
+
+/**************************** Time ********************************/
+
+/* DB/Time/TimestampToLocal
+Converts a GMT timestamp into local time
+ wParam=(WPARAM)(DWORD)timestamp
+ lParam=0
+Returns the converted value
+Timestamps have zero at midnight 1/1/1970 GMT, this service converts such a
+value to be based at midnight 1/1/1970 local time.
+This service does not use a simple conversion based on the current offset
+between GMT and local. Rather, it figures out whether daylight savings time
+would have been in place at the time of the stamp and gives the local time as
+it would have been at the time and date the stamp contains.
+This service isn't nearly as useful as db/time/TimestampToString below and I
+recommend avoiding its use when possible so that you don't get your timezones
+mixed up (like I did. Living at GMT makes things easier for me, but has certain
+disadvantages :-) ).
+*/
+#define MS_DB_TIME_TIMESTAMPTOLOCAL "DB/Time/TimestampToLocal"
+
+/* DB/Time/TimestampToString
+Converts a GMT timestamp into a customisable local time string
+ wParam=(WPARAM)(DWORD)timestamp
+ lParam=(LPARAM)(DBTIMETOSTRING*)&tts
+Returns 0 always
+Uses db/time/timestamptolocal for the conversion so read that description to
+see what's going on.
+The string is formatted according to the current user's locale, language and
+preferences.
+szFormat can have the following special characters:
+ t Time without seconds, eg hh:mm
+ s Time with seconds, eg hh:mm:ss
+ m Time without minutes, eg hh
+ d Short date, eg dd/mm/yyyy
+ D Long date, eg d mmmm yyyy
+All other characters are copied across to szDest as-is
+*/
+typedef struct {
+ char *szFormat; // format string, as above
+ char *szDest; // place to put the output string
+ int cbDest; // maximum number of bytes to put in szDest
+} DBTIMETOSTRING;
+#define MS_DB_TIME_TIMESTAMPTOSTRING "DB/Time/TimestampToString"
+
+typedef struct {
+ TCHAR *szFormat; // format string, as above
+ TCHAR *szDest; // place to put the output string
+ int cbDest; // maximum number of bytes to put in szDest
+} DBTIMETOSTRINGT;
+#define MS_DB_TIME_TIMESTAMPTOSTRINGT "DB/Time/TimestampToStringT"
+
+/*************************** Random *******************************/
+
+/*
+Switches safety settings on or off
+wParam=(WPARAM)(BOOL)newSetting
+lParam=0
+returns 0 always
+newSetting is TRUE initially.
+Miranda's database is normally protected against corruption by agressively
+flushing data to the disk on writes. If you're doing a lot of writes (eg in
+an import plugin) it can sometimes be desirable to switch this feature off to
+speed up the process. If you do switch it off, you must remember that crashes
+are far more likely to be catastrophic, so switch it back on at the earliest
+possible opportunity.
+Note that if you're doing a lot of setting writes, the flush is already delayed
+so you need not use this service for that purpose.
+*/
+#define MS_DB_SETSAFETYMODE "DB/SetSafetyMode"
+
+/*************************** Modules ******************************/
+
+/* db/modules/enum v0.1.0.1+
+Enumerates the names of all modules that have stored or requested information
+from the database.
+wParam=lParam
+lParam=(WPARAM)(DBMODULEENUMPROC)dbmep
+Returns the value returned by the last call to dbmep
+This service is only really useful for debugging, in conjunction with
+db/contact/enumsettings
+lParam is passed directly to dbmep
+dbmep should return 0 to continue enumeration, or nonzero to stop.
+ofsModuleName is the offset of the module name from the start of the profile
+database, and is only useful for really heavyweight debugging
+Modules names will be enumerated in no particular order
+Writing to the database while module names are being enumerated will cause
+unpredictable results in the enumeration, but the write will work.
+szModuleName is only guaranteed to be valid for the duration of the callback.
+If you want to keep it for longer you must allocation your own storage.
+**BUG**: Prior to 0.1.2.0 dbmep was called as (lParam)(szMod,ofsMod,lParam).
+ This means that the lParam parameter to dbmep was useless, and explains the
+ slightly odd 'wParam=lParam' in the definition.
+*/
+typedef int (*DBMODULEENUMPROC)(const char *szModuleName,DWORD ofsModuleName,LPARAM lParam);
+#define MS_DB_MODULES_ENUM "DB/Modules/Enum"
+
+/* DB/Module/Delete 0.8.0+
+
+Removes all settings for the specified module.
+wParam=0 (unused)
+lParam=(LPARAM)(char*)szModuleName - the module name to be deleted
+*/
+
+#define MS_DB_MODULE_DELETE "DB/Module/Delete"
+
+/******************************************************************/
+/************************** EVENTS ********************************/
+/******************************************************************/
+
+/* DB/Event/Added event
+Called when a new event has been added to the event chain for a contact
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=(LPARAM)(HANDLE)hDbEvent
+hDbEvent is a valid handle to the event. hContact is a valid handle to the
+contact to which hDbEvent refers.
+Since events are sorted chronologically, you cannot guarantee that hDbEvent is
+at any particular position in the chain.
+*/
+#define ME_DB_EVENT_ADDED "DB/Event/Added"
+
+/* DB/Event/FilterAdd (NOTE: Added during 0.3.3+ development!)
+Called **before** a new event is made of a DBEVENTINFO structure, this
+hook is not SAFE unless you know what you're doing with it, the arguments
+are passed as-is (with errors, pointer problems, if any) from any arguments
+passed to MS_DB_EVENT_ADD.
+
+The point of this hook is to stop any unwanted database events, to stop
+an event being added, return 1, to allow the event to pass through return
+0.
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=(LPARAM)&DBEVENTINFO
+
+Any changed made to the said DBEVENTINFO are also passed along to the database,
+therefore it is possible to shape the data, however DO NOT DO THIS.
+*/
+#define ME_DB_EVENT_FILTER_ADD "DB/Event/FilterAdd"
+
+/* DB/Event/Deleted event
+Called when an event is about to be deleted from the event chain for a contact
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=(LPARAM)(HANDLE)hDbEvent
+hDbEvent is a valid handle to the event which is about to be deleted, but it
+won't be once your hook has returned.
+hContact is a valid handle to the contact to which hDbEvent refers, and will
+remain valid.
+Returning nonzero from your hook will not stop the deletion, but it will, as
+usual, stop other hooks from being called.
+*/
+#define ME_DB_EVENT_DELETED "DB/Event/Deleted"
+
+/* DB/Contact/Added event
+Called when a new contact has been added to the database
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=0
+hContact is a valid handle to the new contact.
+Contacts are initially created without any settings, so if you hook this event
+you will almost certainly also want to hook db/contact/settingchanged as well.
+*/
+#define ME_DB_CONTACT_ADDED "DB/Contact/Added"
+
+/* DB/Contact/Deleted event
+Called when an contact is about to be deleted
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=0
+hContact is a valid handle to the contact which is about to be deleted, but it
+won't be once your hook has returned.
+Returning nonzero from your hook will not stop the deletion, but it will, as
+usual, stop other hooks from being called.
+Deleting a contact invalidates all events in its chain.
+*/
+#define ME_DB_CONTACT_DELETED "DB/Contact/Deleted"
+
+/* DB/Contact/SettingChanged event
+Called when a contact has had one of its settings changed
+ wParam=(WPARAM)(HANDLE)hContact
+ lParam=(LPARAM)(DBCONTACTWRITESETTING*)&dbcws
+hContact is a valid handle to the contact that has changed.
+This event will be triggered many times rapidly when a whole bunch of values
+are set.
+Modules which hook this should be aware of this fact and quickly return if they
+are not interested in the value that has been changed.
+Careful not to get into infinite loops with this event.
+The structure dbcws is the same one as is passed to the original service, so
+don't change any of the members.
+*/
+#define ME_DB_CONTACT_SETTINGCHANGED "DB/Contact/SettingChanged"
+
+/* DB/Contact/SetSettingResident service (0.6+)
+Disables a setting saving to the database.
+ wParam=(WPARAM)(BOOL)bIsResident
+ lParam=(LPARAM)(char*)pszSettingName
+*/
+#define MS_DB_SETSETTINGRESIDENT "DB/SetSettingResident"
+
+/******************************************************************/
+/********************* SETTINGS HELPER FUNCTIONS ******************/
+/******************************************************************/
+
+#ifndef DB_NOHELPERFUNCTIONS
+
+#define db_byte_get(a,b,c,d) DBGetContactSettingByte(a,b,c,d)
+#define db_word_get(a,b,c,d) DBGetContactSettingWord(a,b,c,d)
+#define db_dword_get(a,b,c,d) DBGetContactSettingDword(a,b,c,d)
+#define db_get(a,b,c,d) DBGetContactSetting(a,b,c,d)
+
+#define db_byte_set(a,b,c,d) DBWriteContactSettingByte(a,b,c,d)
+#define db_word_set(a,b,c,d) DBWriteContactSettingWord(a,b,c,d)
+#define db_dword_set(a,b,c,d) DBWriteContactSettingDword(a,b,c,d)
+#define db_string_set(a,b,c,d) DBWriteContactSettingString(a,b,c,d)
+
+#define db_unset(a,b,c) DBDeleteContactSetting(a,b,c);
+
+#ifdef _DEBUG
+ #define DBGetContactSettingByte(a,b,c,d) DBGetContactSettingByte_Helper(a,b,c,d,__FILE__,__LINE__)
+ #define DBGetContactSettingWord(a,b,c,d) DBGetContactSettingWord_Helper(a,b,c,d,__FILE__,__LINE__)
+ #define DBGetContactSettingDword(a,b,c,d) DBGetContactSettingDword_Helper(a,b,c,d,__FILE__,__LINE__)
+ #define DBGetContactSetting(a,b,c,d) DBGetContactSetting_Helper(a,b,c,d,__FILE__,__LINE__)
+ #define DBGetContactSettingString(a,b,c,d) DBGetContactSettingString_Helper(a,b,c,d,__FILE__,__LINE__,DBVT_ASCIIZ)
+ #define DBGetContactSettingWString(a,b,c,d) DBGetContactSettingString_Helper(a,b,c,d,__FILE__,__LINE__,DBVT_WCHAR)
+ #define DBGetContactSettingUTF8String(a,b,c,d) DBGetContactSettingString_Helper(a,b,c,d,__FILE__,__LINE__,DBVT_UTF8)
+#else
+ #define DBGetContactSettingByte(a,b,c,d) DBGetContactSettingByte_Helper(a,b,c,d)
+ #define DBGetContactSettingWord(a,b,c,d) DBGetContactSettingWord_Helper(a,b,c,d)
+ #define DBGetContactSettingDword(a,b,c,d) DBGetContactSettingDword_Helper(a,b,c,d)
+ #define DBGetContactSetting(a,b,c,d) DBGetContactSetting_Helper(a,b,c,d)
+ #define DBGetContactSettingString(a,b,c,d) DBGetContactSettingString_Helper(a,b,c,d,DBVT_ASCIIZ)
+ #define DBGetContactSettingWString(a,b,c,d) DBGetContactSettingString_Helper(a,b,c,d,DBVT_WCHAR)
+ #define DBGetContactSettingUTF8String(a,b,c,d) DBGetContactSettingString_Helper(a,b,c,d,DBVT_UTF8)
+#endif
+
+#ifdef _UNICODE
+#define DBGetContactSettingTString DBGetContactSettingWString
+#else
+#define DBGetContactSettingTString DBGetContactSettingString
+#endif
+
+#define db_msg_dbg(s) MessageBoxA(0,(s),"",0);
+
+/* Deprecated & bizarre aliases */
+#define DBGetContactSettingStringUtf DBGetContactSettingUTF8String
+#define DBWriteContactSettingStringUtf DBWriteContactSettingUTF8String
+#ifdef _DEBUG
+ #define DBGetContactSettingW(a,b,c,d) DBGetContactSettingString_Helper(a,b,c,d,__FILE__,__LINE__,0)
+#else
+ #define DBGetContactSettingW(a,b,c,d) DBGetContactSettingString_Helper(a,b,c,d,0)
+#endif
+
+#ifdef _DEBUG
+#include <stdio.h>
+#endif
+
+__inline static int DBGetContactSettingByte_Helper(HANDLE hContact, const char *szModule, const char *szSetting, int errorValue
+#ifdef _DEBUG
+ ,const char *szFile, const int nLine
+#endif
+)
+{
+ DBVARIANT dbv;
+ DBCONTACTGETSETTING cgs;
+
+ cgs.szModule=szModule;
+ cgs.szSetting=szSetting;
+ cgs.pValue=&dbv;
+ if(CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)hContact,(LPARAM)&cgs))
+ return errorValue;
+#ifdef _DEBUG
+ if(dbv.type!=DBVT_BYTE) {
+ char buf[128];
+ _snprintf(buf,sizeof(buf),"%s:%d for %s/%s not a byte, return: %d",szFile,nLine,szModule,szSetting,dbv.type);
+ buf[sizeof(buf)-1]=0;
+ db_msg_dbg(buf);
+ }
+#endif
+ return dbv.bVal;
+}
+
+__inline static int DBGetContactSettingWord_Helper(HANDLE hContact,const char *szModule,const char *szSetting,int errorValue
+#ifdef _DEBUG
+ ,const char *szFile, const int nLine
+#endif
+)
+{
+ DBVARIANT dbv;
+ DBCONTACTGETSETTING cgs;
+
+ cgs.szModule=szModule;
+ cgs.szSetting=szSetting;
+ cgs.pValue=&dbv;
+ if(CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)hContact,(LPARAM)&cgs))
+ return errorValue;
+#ifdef _DEBUG
+ if(dbv.type!=DBVT_WORD) {
+ char buf[128];
+ _snprintf(buf,sizeof(buf),"%s:%d for %s/%s not a word, return: %d",szFile,nLine,szModule,szSetting,dbv.type);
+ buf[sizeof(buf)-1]=0;
+ db_msg_dbg(buf);
+ }
+#endif
+ return dbv.wVal;
+}
+
+__inline static DWORD DBGetContactSettingDword_Helper(HANDLE hContact,const char *szModule, const char *szSetting, DWORD errorValue
+#ifdef _DEBUG
+ ,const char *szFile, const int nLine
+#endif
+)
+{
+ DBVARIANT dbv;
+ DBCONTACTGETSETTING cgs;
+
+ cgs.szModule=szModule;
+ cgs.szSetting=szSetting;
+ cgs.pValue=&dbv;
+ if(CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)hContact,(LPARAM)&cgs))
+ return errorValue;
+#ifdef _DEBUG
+ if(dbv.type!=DBVT_DWORD) {
+ char buf[128];
+ _snprintf(buf,sizeof(buf),"%s:%d for %s/%s not a dword, return: %d",szFile,nLine,szModule,szSetting,dbv.type);
+ buf[sizeof(buf)-1]=0;
+ db_msg_dbg(buf);
+ }
+#endif
+ return dbv.dVal;
+}
+
+__inline static INT_PTR DBGetContactSetting_Helper(HANDLE hContact,const char *szModule,const char *szSetting,DBVARIANT *dbv
+#if defined(_DEBUG)
+ ,const char *szFile, const int nLine
+#endif
+)
+{
+ INT_PTR rc;
+ DBCONTACTGETSETTING cgs;
+ cgs.szModule=szModule;
+ cgs.szSetting=szSetting;
+ cgs.pValue=dbv;
+
+ rc=CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)hContact,(LPARAM)&cgs);
+#if defined(_DEBUG) && defined(DBCHECKSETTINGS)
+ if (rc != 0) {
+ char buf[128];
+ _snprintf(buf,sizeof(buf),"%s:%d failed to fetch %s/%s",szFile,nLine,szModule,szSetting);
+ db_msg_dbg(buf);
+ }
+#endif
+ return rc;
+}
+
+__inline static INT_PTR DBGetContactSettingString_Helper(HANDLE hContact,const char *szModule,const char *szSetting,DBVARIANT *dbv,
+#if defined(_DEBUG)
+ const char *szFile, const int nLine,
+#endif
+ const int nType)
+{
+ INT_PTR rc;
+ DBCONTACTGETSETTING cgs;
+ cgs.szModule=szModule;
+ cgs.szSetting=szSetting;
+ cgs.pValue=dbv;
+ dbv->type=(BYTE)nType;
+
+ rc=CallService(MS_DB_CONTACT_GETSETTING_STR,(WPARAM)hContact,(LPARAM)&cgs);
+#if defined(_DEBUG) && defined(DBCHECKSETTINGS)
+ if (rc != 0) {
+ char buf[128];
+ _snprintf(buf,sizeof(buf),"%s:%d failed to fetch %s/%s",szFile,nLine,szModule,szSetting);
+ db_msg_dbg(buf);
+ }
+#endif
+ return rc;
+}
+
+__inline static INT_PTR DBFreeVariant(DBVARIANT *dbv)
+{
+ return CallService(MS_DB_CONTACT_FREEVARIANT,0,(LPARAM)dbv);
+}
+
+__inline static char *DBGetString(HANDLE hContact,const char *szModule,const char *szSetting)
+{
+ char *str=NULL;
+ DBVARIANT dbv={0};
+ DBGetContactSettingString(hContact,szModule,szSetting,&dbv);
+ if(dbv.type==DBVT_ASCIIZ)
+ str=mir_strdup(dbv.pszVal);
+ DBFreeVariant(&dbv);
+ return str;
+}
+
+#define DBGetStringA DBGetString
+
+__inline static wchar_t *DBGetStringW(HANDLE hContact,const char *szModule,const char *szSetting)
+{
+ wchar_t *str=NULL;
+ DBVARIANT dbv={0};
+ DBGetContactSettingWString(hContact,szModule,szSetting,&dbv);
+ if(dbv.type==DBVT_WCHAR)
+ str=mir_wstrdup(dbv.pwszVal);
+ DBFreeVariant(&dbv);
+ return str;
+}
+
+#ifdef _UNICODE
+#define DBGetStringT DBGetStringW
+#else
+#define DBGetStringT DBGetString
+#endif
+
+__inline static INT_PTR DBDeleteContactSetting(HANDLE hContact,const char *szModule,const char *szSetting)
+{
+ DBCONTACTGETSETTING cgs;
+ cgs.szModule=szModule;
+ cgs.szSetting=szSetting;
+ return CallService(MS_DB_CONTACT_DELETESETTING,(WPARAM)hContact,(LPARAM)&cgs);
+}
+
+__inline static INT_PTR DBWriteContactSettingByte(HANDLE hContact,const char *szModule,const char *szSetting,BYTE val)
+{
+ DBCONTACTWRITESETTING cws;
+
+ cws.szModule=szModule;
+ cws.szSetting=szSetting;
+ cws.value.type=DBVT_BYTE;
+ cws.value.bVal=val;
+ return CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws);
+}
+
+__inline static INT_PTR DBWriteContactSettingWord(HANDLE hContact,const char *szModule,const char *szSetting,WORD val)
+{
+ DBCONTACTWRITESETTING cws;
+
+ cws.szModule=szModule;
+ cws.szSetting=szSetting;
+ cws.value.type=DBVT_WORD;
+ cws.value.wVal=val;
+ return CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws);
+}
+
+__inline static INT_PTR DBWriteContactSettingDword(HANDLE hContact,const char *szModule,const char *szSetting,DWORD val)
+{
+ DBCONTACTWRITESETTING cws;
+
+ cws.szModule=szModule;
+ cws.szSetting=szSetting;
+ cws.value.type=DBVT_DWORD;
+ cws.value.dVal=val;
+ return CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws);
+}
+
+__inline static INT_PTR DBWriteContactSettingString(HANDLE hContact,const char *szModule,const char *szSetting,const char *val)
+{
+ DBCONTACTWRITESETTING cws;
+
+ cws.szModule=szModule;
+ cws.szSetting=szSetting;
+ cws.value.type=DBVT_ASCIIZ;
+ cws.value.pszVal=(char*)val;
+ return CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws);
+}
+
+__inline static INT_PTR DBWriteContactSettingWString(HANDLE hContact,const char *szModule,const char *szSetting,const WCHAR *val)
+{
+ DBCONTACTWRITESETTING cws;
+
+ cws.szModule=szModule;
+ cws.szSetting=szSetting;
+ cws.value.type=DBVT_WCHAR;
+ cws.value.pwszVal=(WCHAR*)val;
+ return CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws);
+}
+
+#ifdef _UNICODE
+#define DBWriteContactSettingTString DBWriteContactSettingWString
+#else
+#define DBWriteContactSettingTString DBWriteContactSettingString
+#endif
+
+__inline static INT_PTR DBWriteContactSettingUTF8String(HANDLE hContact,const char *szModule,const char *szSetting,const char *val)
+{
+ DBCONTACTWRITESETTING cws;
+
+ cws.szModule=szModule;
+ cws.szSetting=szSetting;
+ cws.value.type=DBVT_UTF8;
+ cws.value.pszVal=(char*)val;
+ return CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws);
+}
+
+__inline static INT_PTR DBWriteContactSettingBlob(HANDLE hContact,const char *szModule,const char *szSetting,void *val,unsigned len)
+{
+ DBCONTACTWRITESETTING cws;
+
+ cws.szModule=szModule;
+ cws.szSetting=szSetting;
+ cws.value.type=DBVT_BLOB;
+ cws.value.cpbVal = (WORD)len;
+ cws.value.pbVal=(unsigned char*)val;
+ return CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws);
+}
+
+/* inlined range tolerate versions */
+
+__inline static BYTE DBGetContactSettingRangedByte(HANDLE hContact, const char *szModule, const char *szSetting, BYTE errorValue, BYTE minValue, BYTE maxValue) {
+ BYTE bVal = (BYTE)DBGetContactSettingByte(hContact, szModule, szSetting, errorValue);
+
+ if (bVal < minValue || bVal > maxValue) {
+#ifdef _DEBUG
+ char szBuf[MAX_PATH];
+ _snprintf(szBuf,sizeof(szBuf),"(%s:%s) not in range of %d..%d",szModule,szSetting,minValue,maxValue);
+ szBuf[sizeof(szBuf)-1]=0;
+ MessageBoxA(0,szBuf,"DBGetContactSettingRangedByte failed",MB_ICONERROR);
+#endif
+ return errorValue;
+ }
+ return bVal;
+}
+
+__inline static WORD DBGetContactSettingRangedWord(HANDLE hContact, const char *szModule, const char *szSetting, WORD errorValue, WORD minValue, WORD maxValue) {
+ WORD wVal = (WORD)DBGetContactSettingWord(hContact, szModule, szSetting, errorValue);
+
+ if (wVal < minValue || wVal > maxValue) {
+#ifdef _DEBUG
+ char szBuf[MAX_PATH];
+ _snprintf(szBuf,sizeof(szBuf),"(%s:%s) not in range of %d..%d",szModule,szSetting,minValue,maxValue);
+ szBuf[sizeof(szBuf)-1]=0;
+ MessageBoxA(0,szBuf,"DBGetContactSettingRangedWord failed",MB_ICONERROR);
+#endif
+ return errorValue;
+ }
+ return wVal;
+}
+
+__inline static DWORD DBGetContactSettingRangedDword(HANDLE hContact, const char *szModule, const char *szSetting, DWORD errorValue, DWORD minValue, DWORD maxValue) {
+ DWORD dVal = DBGetContactSettingDword(hContact, szModule, szSetting, errorValue);
+
+ if (dVal < minValue || dVal > maxValue) {
+#ifdef _DEBUG
+ char szBuf[MAX_PATH];
+ _snprintf(szBuf,sizeof(szBuf),"(%s:%s) not in range of %d..%d",szModule,szSetting,minValue,maxValue);
+ szBuf[sizeof(szBuf)-1]=0;
+ MessageBoxA(0,szBuf,"DBGetContactSettingRangedDword failed",MB_ICONERROR);
+#endif
+ return errorValue;
+ }
+ return dVal;
+}
+
+#endif
+
+#endif // M_DATABASE_H__
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_langpack.h b/plugins/!NotAdopted/WinPopup/sdk/m_langpack.h
new file mode 100644
index 0000000000..a903313cb8
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_langpack.h
@@ -0,0 +1,114 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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_LANGPACK_H__
+#define M_LANGPACK_H__
+
+#define LANG_UNICODE 0x1000
+
+//translates a single string into the user's local language v0.1.1.0+
+//wParam=0
+//lParam=(LPARAM)(const char*)szEnglish
+//returns a pointer to the localised string. If there is no known translation
+//it will return szEnglish. The return value does not need to be freed in any
+//way
+//Note that the Translate() macro as defined below will crash plugins that are
+//loaded into Miranda 0.1.0.1 and earlier. If anyone's actually using one of
+//these versions, I pity them.
+#define MS_LANGPACK_TRANSLATESTRING "LangPack/TranslateString"
+#define Translate(s) ((char*)CallService(MS_LANGPACK_TRANSLATESTRING,0,(LPARAM)(s)))
+#define TranslateW(s) ((WCHAR*)CallService(MS_LANGPACK_TRANSLATESTRING,LANG_UNICODE,(LPARAM)(s)))
+#ifdef _UNICODE
+ #define TranslateT(s) TranslateW(_T(s))
+ #define TranslateTS(s) TranslateW(s)
+#else
+ #define TranslateT(s) Translate(s)
+ #define TranslateTS(s) Translate(s)
+#endif
+
+// If you're storing some string for calling later-on Translate or using it
+// with an API call that does translation automatically marked with
+// [TRANSLATED-BY-CORE] please wrap it with one of LPGEN macros in order to
+// generate proper language pack.
+#define LPGEN(s) s
+#define LPGENW(s) L ## s
+#ifdef _UNICODE
+ #define LPGENT(s) _T(s)
+#else
+ #define LPGENT(s) s
+#endif
+//Those macros do NOTHING. They are just markers for lpgen.pl.
+
+//translates a dialog into the user's local language v0.1.1.0+
+//wParam=0
+//lParam=(LPARAM)(LANGPACKTRANSLATEDIALOG*)&lptd
+//returns 0 on success, nonzero on failure
+//This service only knows about the following controls:
+//Window titles, STATIC, EDIT, Hyperlink, BUTTON
+typedef struct {
+ int cbSize;
+ DWORD flags;
+ HWND hwndDlg;
+ const int *ignoreControls; //zero-terminated list of control IDs *not* to
+ //translate
+} LANGPACKTRANSLATEDIALOG;
+#define LPTDF_NOIGNOREEDIT 1 //translate all edit controls. By default
+ //non-read-only edit controls are not translated
+#define LPTDF_NOTITLE 2 //do not translate the title of the dialog
+
+#define MS_LANGPACK_TRANSLATEDIALOG "LangPack/TranslateDialog"
+__inline static INT_PTR TranslateDialogDefault(HWND hwndDlg)
+{
+ LANGPACKTRANSLATEDIALOG lptd;
+ lptd.cbSize=sizeof(lptd);
+ lptd.flags=0;
+ lptd.hwndDlg=hwndDlg;
+ lptd.ignoreControls=NULL;
+ return CallService(MS_LANGPACK_TRANSLATEDIALOG,0,(LPARAM)&lptd);
+}
+
+//translates a menu into the user's local language v0.1.1.0+
+//wParam=(WPARAM)(HMENU)hMenu
+//lParam=0
+//returns 0 on success, nonzero on failure
+#define MS_LANGPACK_TRANSLATEMENU "LangPack/TranslateMenu"
+
+//returns the codepage used in the language pack v0.4.3.0+
+//wParam=0
+//lParam=0
+//returns the codepage stated in the langpack, or CP_ACP if no langpack is present
+#define MS_LANGPACK_GETCODEPAGE "LangPack/GetCodePage"
+
+//returns the locale id associated with the language pack v0.4.3.0+
+//wParam=0
+//lParam=0
+//returns the Windows locale id stated in the langpack, or LOCALE_USER_DEFAULT if no langpack is present
+#define MS_LANGPACK_GETLOCALE "LangPack/GetLocale"
+
+//returns the strdup/wcsdup of lparam according to the langpack v0.4.3.0+
+//wParam=0
+//lParam=(LPARAM)(char*)source string
+//returns a string converted from char* to TCHAR* using the langpack codepage.
+//This string should be freed using mir_free() then
+#define MS_LANGPACK_PCHARTOTCHAR "LangPack/PcharToTchar"
+#endif // M_LANGPACK_H__
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_netlib.h b/plugins/!NotAdopted/WinPopup/sdk/m_netlib.h
new file mode 100644
index 0000000000..086ca25d02
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_netlib.h
@@ -0,0 +1,832 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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_NETLIB_H__
+#define M_NETLIB_H__ 1
+
+#include "m_utils.h"
+
+//this module was created in 0.1.2.2
+//All error codes are returned via GetLastError() (or WSAGetLastError():
+//they're the same).
+//This module is thread-safe where it is sensible for it to be so. This
+//basically means that you can call anything from any thread, but don't try
+//to predict what will happen if you try to recv() on the same connection from
+//two different threads at the same time.
+//Note that because the vast majority of the routines in this module return
+//a pointer, I have decided to diverge from the rest of Miranda and go with
+//the convention that functions return false on failure and nonzero on success.
+
+struct NETLIBHTTPREQUEST_tag;
+typedef struct NETLIBHTTPREQUEST_tag NETLIBHTTPREQUEST;
+struct NETLIBOPENCONNECTION_tag;
+typedef struct NETLIBOPENCONNECTION_tag NETLIBOPENCONNECTION;
+
+//Initialises the netlib for a set of connections
+//wParam=0
+//lParam=(LPARAM)(NETLIBUSER*)&nu
+//Returns a HANDLE to be used for future netlib calls, NULL on failure
+//NOTE: Netlib is loaded after any plugins, so you need to wait until
+// ME_SYSTEM_MODULESLOADED before calling this function
+//Netlib settings are stored under the module szSettingsModule
+//All netlib settings being with "NL".
+//The default settings for registered users that don't have any settings stored
+//in the database are the same as those displayed by the <All connections> page
+//of the netlib options page.
+//See notes below this function for the behaviour of HTTP gateways
+//Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY, ERROR_DUP_NAME
+typedef int (*NETLIBHTTPGATEWAYINITPROC)(HANDLE hConn,NETLIBOPENCONNECTION *nloc,NETLIBHTTPREQUEST *nlhr);
+typedef int (*NETLIBHTTPGATEWAYBEGINPROC)(HANDLE hConn,NETLIBOPENCONNECTION *nloc);
+typedef int (*NETLIBHTTPGATEWAYWRAPSENDPROC)(HANDLE hConn,PBYTE buf,int len,int flags,MIRANDASERVICE pfnNetlibSend);
+typedef PBYTE (*NETLIBHTTPGATEWAYUNWRAPRECVPROC)(NETLIBHTTPREQUEST *nlhr,PBYTE buf,int len,int *outBufLen,void *(*NetlibRealloc)(void*,size_t));
+typedef struct {
+ int cbSize;
+ char *szSettingsModule; //used for db settings and log
+ union {
+ char *szDescriptiveName; //used in options dialog, already translated
+ TCHAR *ptszDescriptiveName;
+ };
+ DWORD flags;
+ char *szHttpGatewayHello;
+ char *szHttpGatewayUserAgent; //can be NULL to send no user-agent, also used by HTTPS proxies
+ NETLIBHTTPGATEWAYINITPROC pfnHttpGatewayInit;
+ NETLIBHTTPGATEWAYBEGINPROC pfnHttpGatewayBegin; //can be NULL if no beginning required
+ NETLIBHTTPGATEWAYWRAPSENDPROC pfnHttpGatewayWrapSend; //can be NULL if no wrapping required
+ NETLIBHTTPGATEWAYUNWRAPRECVPROC pfnHttpGatewayUnwrapRecv; //can be NULL if no wrapping required
+ int minIncomingPorts; //only if NUF_INCOMING. Will be used for validation of user input.
+} NETLIBUSER;
+#define NUF_INCOMING 0x01 //binds incoming ports
+#define NUF_OUTGOING 0x02 //makes outgoing plain connections
+#define NUF_HTTPGATEWAY 0x04 //can use HTTP gateway for plain sockets. ???HttpGateway* are valid. Enables the HTTP proxy option in options.
+#define NUF_NOOPTIONS 0x08 //don't create an options page for this. szDescriptiveName is never used.
+#define NUF_HTTPCONNS 0x10 //at least some connections are made for HTTP communication. Enables the HTTP proxy option in options.
+#define NUF_NOHTTPSOPTION 0x20 //disable the HTTPS proxy option in options. Use this if all communication is HTTP.
+#define NUF_UNICODE 0x40 //if set ptszDescriptiveName points to Unicode, otherwise it points to ANSI string
+#define MS_NETLIB_REGISTERUSER "Netlib/RegisterUser"
+
+#if defined(_UNICODE)
+ #define NUF_TCHAR NUF_UNICODE
+#else
+ #define NUF_TCHAR 0
+#endif
+
+
+
+//Assign a Netlib user handle a set of dynamic HTTP headers to be used with all
+//
+//HTTP connections that enable the HTTP-use-sticky headers flag.
+//The headers persist until cleared with lParam=NULL.
+//
+//All memory should be allocated by the caller using malloc() from MS_SYSTEM_GET_MMI
+//Once it has passed to Netlib, Netlib is the owner of it, the caller should not refer to the memory
+//In any way after this point.
+//
+//wParam=(WPARAM)hNetLibUser
+//lParam=(LPARAM)(char*)szHeaders
+//
+//NOTE: The szHeaders parameter should be a NULL terminated string following the HTTP header syntax.
+//This string will be injected verbatim, thus the user should be aware of setting strings that are not
+//headers. This service is NOT THREAD SAFE, only a single thread is expected to set the headers and a single
+//thread reading the pointer internally, stopping race conditions and mutual exclusion don't happen.
+//
+//Version 0.3.2a+ (2003/10/27)
+//
+#define MS_NETLIB_SETSTICKYHEADERS "Netlib/SetStickyHeaders"
+
+/* Notes on HTTP gateway usage
+When a connection is initiated through an HTTP proxy using
+MS_NETLIB_OPENCONNECTION, netlib will GET nlu.szHttpGatewayHello and read
+the replied headers. Once this succeeds nlu.pfnHttpGatewayInit will be called
+with a valid handle to the connection, the NETLIBOPENCONNECTION structure that
+MS_NETLIB_OPENCONNECTION was called with, and the replied HTTP headers as its
+parameters. This function is responsible for recving and parsing the data then
+calling MS_NETLIB_SETHTTPPROXYINFO with the appropriate information.
+nlu.pfnHttpGatewayInit should return nonzero on success. If it returns zero
+then the entire connection attempt will return signalling failure. If your
+function needs to return an error code it can do so via SetLastError().
+If nlu.pfnHttpGatewayInit returns success without having called
+MS_NETLIB_SETHTTPPROXYINFO then the connection attempt will fail anyway.
+If you need more fine-tuned control over the GET/POST URLs than just appending
+sequence numbers you can call MS_NETLIB_SETHTTPPROXYINFO from within your
+wrap/unwrap functions (see below).
+
+Just prior to MS_NETLIB_OPENCONNECTION returning nlu.pfnHttpGatewayBegin is
+called with the handle to the connection and the NETLIBOPENCONNECTION structure
+as its parameters. This is for gateways that need special non-protocol
+initialisation. If you do send any packets in this function, you probably want
+to remember to use the MSG_NOHTTPGATEWAYWRAP flag. This function pointer can be
+NULL if this functionality isn't needed. This function must return nonzero on
+success. If it fails the connect attempt will return failure without changing
+LastError.
+
+Whenever MS_NETLIB_SEND is called on a connection through an HTTP proxy and
+the MSG_NOHTTPGATEWAYWRAP flags is not set and nlu.pfnHttpGatewayWrapSend is
+not NULL, nlu.pfnHttpGatewayWrapSend will be called *instead* of sending the
+data. It is this function's responsibility to wrap the sending data
+appropriately for transmission and call pfnNetlibSend to send it again.
+The flags parameter to nlu.pfnHttpGatewayWrapSend should be passed straight
+through to the pfnNetlibSend call. It has already been ORed with
+MSG_NOHTTPGATEWAYWRAP. nlu.pfnHttpGatewayWrapSend should return the a
+number of the same type as MS_NETLIB_SEND, ie the number of bytes sent or
+SOCKET_ERROR. The number of wrapping bytes should be subtracted so that the
+return value appears as if the proxy wasn't there.
+pfnNetlibSend() is identical to CallService(MS_NETLIB_SEND,...) but it's
+quicker to call using this pointer than to do the CallService() lookup again.
+
+Whenever an HTTP reply is received inside MS_NETLIB_RECV the headers and data
+are read into memory. If the headers indicate success then the data is passed
+to nlu.pfnHttpGatewayUnwrapRecv (if it's non-NULL) for processing. This
+function should remove (and do other processing if necessary) all HTTP proxy
+specific headers and return a pointer to the buffer whose size is returned in
+*outBufLen. If the buffer needs to be resized then NetlibRealloc() should be
+used for that purpose, *not* your own CRT's realloc(). NetlibRealloc() behaves
+identically to realloc() so it's possible to free the original buffer and
+create a new one if that's the most sensible way to write your parser.
+If errors are encountered you should SetLastError() and return NULL;
+MS_NETLIB_RECV will return SOCKET_ERROR. If the passed buffer unwraps to
+contain no actual data you should set *outBufLen to 0 but make sure you return
+some non-NULL buffer that can be freed.
+
+When you call MS_NETLIB_SEND or MS_NETLIB_RECV from any of these functions, you
+should use the MSG_DUMPPROXY flag so that the logging is neat.
+*/
+
+//Gets the user-configured settings for a netlib user
+//wParam=(WPARAM)(HANDLE)hUser
+//lParam=(LPARAM)(NETLIBUSERSETTINGS*)&nlus
+//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+//The pointers referred to in the returned struct will remain valid until
+//the hUser handle is closed, or until the user changes the settings in the
+//options page, so it's best not to rely on them for too long.
+//Errors: ERROR_INVALID_PARAMETER
+#define PROXYTYPE_SOCKS4 1
+#define PROXYTYPE_SOCKS5 2
+#define PROXYTYPE_HTTP 3
+#define PROXYTYPE_HTTPS 4
+#define PROXYTYPE_IE 5
+typedef struct {
+ int cbSize; // to be filled in before calling
+ int useProxy; // 1 or 0
+ int proxyType; // a PROXYTYPE_
+ char *szProxyServer; // can be NULL
+ int wProxyPort; // host byte order
+ int useProxyAuth; // 1 or 0. Always 0 for SOCKS4
+ char *szProxyAuthUser; // can be NULL, always used by SOCKS4
+ char *szProxyAuthPassword; // can be NULL
+ int useProxyAuthNtlm; // 1 or 0, only used by HTTP, HTTPS
+ int dnsThroughProxy; // 1 or 0
+ int specifyIncomingPorts; // 1 or 0
+ char *szIncomingPorts; // can be NULL. Of form "1024-1050,1060-1070,2000"
+ int specifyOutgoingPorts; // 0.3.3a+
+ char *szOutgoingPorts; // 0.3.3a+
+ int enableUPnP; // 0.6.1+ only for NUF_INCOMING
+ int validateSSL;
+} NETLIBUSERSETTINGS;
+#define MS_NETLIB_GETUSERSETTINGS "Netlib/GetUserSettings"
+
+//Changes the user-configurable settings for a netlib user
+//wParam=(WPARAM)(HANDLE)hUser
+//lParam=(LPARAM)(NETLIBUSERSETTINGS*)&nlus
+//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+//This function is only really useful for people that specify NUF_NOOPTIONS
+//and want to create their own options.
+//Even if a setting is not active (eg szProxyAuthPassword when useProxyAuth is
+//zero) that settings is still set for use in the options dialog.
+//Errors: ERROR_INVALID_PARAMETER
+#define MS_NETLIB_SETUSERSETTINGS "Netlib/SetUserSettings"
+
+//Closes a netlib handle
+//wParam=(WPARAM)(HANDLE)hNetlibHandle
+//lParam=0
+//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+//This function should be called on all handles returned by netlib functions
+//once you are done with them. If it's called on a socket-type handle, the
+//socket will be closed.
+//Errors: ERROR_INVALID_PARAMETER
+#define MS_NETLIB_CLOSEHANDLE "Netlib/CloseHandle"
+__inline static INT_PTR Netlib_CloseHandle(HANDLE h) {return CallService(MS_NETLIB_CLOSEHANDLE,(WPARAM)h,0);}
+
+//Open a port and wait for connections on it
+//wParam=(WPARAM)(HANDLE)hUser
+//lParam=(LPARAM)(NETLIBBIND*)&nlb
+//Returns a HANDLE on success, NULL on failure
+//hUser should have been returned by MS_NETLIB_REGISTERUSER
+//This function does the equivalent of socket(), bind(), getsockname(),
+//listen(), accept()
+//Internally this function creates a new thread which waits around in accept()
+//for new connections. When one is received it calls nlb.pfnNewConnection *from
+//this new thread* and then loops back to wait again.
+//Close the returned handle to end the thread and close the open port.
+//Errors: ERROR_INVALID_PARAMETER, any returned by socket() or bind() or
+// listen() or getsockname()
+//
+// Notes:
+//
+// During development of 0.3.1a+ (2003/07/04) passing wPort != 0
+// will result in an attempt to bind on the port given in wPort
+// if this port is taken then you will get an error, so be sure to check
+// for such conditions.
+//
+// passing wPort != 0 is for people who need to open a set port for
+// daemon activities, usually passing wPort==0 is what you want and
+// will result in a free port given by the TCP/IP socket layer and/or
+// seeded from the user selected port ranges.
+//
+// also note that wPort if != 0, will have be converted to network byte order
+//
+/* pExtra was added during 0.3.4+, prior its just two args, since we use the cdecl convention
+it shouldnt matter */
+
+#define NETLIBBIND_SIZEOF_V1 16 // sizeof(NETLIBBIND) prior to 0.3.4+ (2004/08/05)
+#define NETLIBBIND_SIZEOF_V2 20 // sizeof(NETLIBBIND) prior to 0.6+ (2006/07/03)
+
+typedef void (*NETLIBNEWCONNECTIONPROC_V2)(HANDLE hNewConnection,DWORD dwRemoteIP, void * pExtra);
+typedef void (*NETLIBNEWCONNECTIONPROC)(HANDLE hNewConnection,DWORD dwRemoteIP);
+/* This is NETLIBBIND prior to 2004/08/05+, DONT use this anymore unless you want to work
+with older cores, pExtra isnt available on older cores and never will be - for a period of time, the ABI
+for this service was broken and older NETLIBBINDs were not supported, if NULL is returned and the
+argument is good, then tell the user to upgrade to the latest CVS.
+
+The older structure was used til around 2004/08/05 */
+typedef struct {
+ int cbSize;
+ NETLIBNEWCONNECTIONPROC pfnNewConnection;
+ //function to call when there's a new connection. Params are: the
+ //new connection, IP of remote machine (host byte order)
+ DWORD dwInternalIP; //set on return, host byte order
+ WORD wPort; //set on return, host byte order
+} NETLIBBINDOLD;
+
+typedef struct {
+ int cbSize;
+ union { // new code should use V2
+ NETLIBNEWCONNECTIONPROC pfnNewConnection;
+ NETLIBNEWCONNECTIONPROC_V2 pfnNewConnectionV2;
+ };
+ //function to call when there's a new connection. Params are: the
+ //new connection, IP of remote machine (host byte order)
+ DWORD dwInternalIP; //set on return, host byte order
+ WORD wPort; //set on return, host byte order
+ void * pExtra; //argument is sent to callback, added during 0.3.4+
+ DWORD dwExternalIP; //set on return, host byte order
+ WORD wExPort; //set on return, host byte order
+} NETLIBBIND;
+#define MS_NETLIB_BINDPORT "Netlib/BindPort"
+
+//Open a connection
+//wParam=(WPARAM)(HANDLE)hUser
+//lParam=(LPARAM)(NETLIBOPENCONNECTION*)&nloc
+//Returns a HANDLE to the new connection on success, NULL on failure
+//hUser must have been returned by MS_NETLIB_REGISTERUSER
+//Internally this function is the equivalent of socket(), gethostbyname(),
+//connect()
+//If NLOCF_HTTP is set and hUser is configured for an HTTP or HTTPS proxy then
+//this function will connect() to the proxy server only, without performing any
+//initialisation conversation.
+//If hUser is configured for an HTTP proxy and does not support HTTP gateways
+//and you try to open a connection without specifying NLOCF_HTTP then this
+//function will first attempt to open an HTTPS connection, if that fails it
+//will try a direct connection, if that fails it will return failure with the
+//error from the connect() during the direct connection attempt.
+//Errors: ERROR_INVALID_PARAMETER, any returned by socket(), gethostbyname(),
+// connect(), MS_NETLIB_SEND, MS_NETLIB_RECV, select()
+// ERROR_TIMEOUT (during proxy communication)
+// ERROR_BAD_FORMAT (very invalid proxy reply)
+// ERROR_ACCESS_DENIED (by proxy)
+// ERROR_CONNECTION_UNAVAIL (socks proxy can't connect to identd)
+// ERROR_INVALID_ACCESS (proxy refused identd auth)
+// ERROR_INVALID_DATA (proxy returned invalid code)
+// ERROR_INVALID_ID_AUTHORITY (proxy requires use of auth method that's not supported)
+// ERROR_GEN_FAILURE (socks5/https general failure)
+// ERROR_CALL_NOT_IMPLEMENTED (socks5 command not supported)
+// ERROR_INVALID_ADDRESS (socks5 address type not supported)
+// HTTP: anything from nlu.pfnHttpGatewayInit, nlu.pfnHttpGatewayBegin,
+// MS_NETLIB_SENDHTTPREQUEST or MS_NETLIB_RECVHTTPHEADERS
+#define NLOCF_HTTP 0x0001 //this connection will be used for HTTP communications. If configured for an HTTP/HTTPS proxy the connection is opened as if there was no proxy.
+#define NLOCF_STICKYHEADERS 0x0002 //this connection should send the sticky headers associated with NetLib user apart of any HTTP request
+#define NLOCF_V2 0x0004 //this connection understands the newer structure, newer cbSize isnt enough
+#define NLOCF_UDP 0x0008 // this connection is UDP
+#define NLOCF_SSL 0x0010 // this connection is SSL
+#define NLOCF_HTTPGATEWAY 0x0020 // this connection is HTTP Gateway
+
+/* Added during 0.4.0+ development!! (2004/11/29) prior to this, connect() blocks til a connection is made or
+a hard timeout is reached, this can be anywhere between 30-60 seconds, and it stops Miranda from unloading whilst
+this is attempted, clearing sucking - so now you can set a timeout of any value, there is still a hard limit which is
+always reached by Windows, If a timeout occurs, or Miranda is exiting then you will get ERROR_TIMEOUT as soon as possible.
+*/
+#define NETLIBOPENCONNECTION_V1_SIZE 16 /* old sizeof() is 14 bytes, but there is padding of 2 bytes */
+struct NETLIBOPENCONNECTION_tag {
+ int cbSize;
+ const char *szHost; //can contain the string representation of an IP
+ WORD wPort; //host byte order
+ DWORD flags;
+ unsigned int timeout;
+ /* optional, called in the context of the thread that issued the attempt, if it returns 0 the connection attempt is
+ stopped, the remaining timeout value can also be adjusted */
+ int (*waitcallback) (unsigned int * timeout);
+};
+//typedef struct NETLIBOPENCONNECTION_tag NETLIBOPENCONNECTION; //(above for reasons of forward referencing)
+#define MS_NETLIB_OPENCONNECTION "Netlib/OpenConnection"
+
+//Sets the required information for an HTTP proxy connection
+//wParam=(WPARAM)(HANDLE)hConnection
+//lParam=(LPARAM)(NETLIBHTTPPROXYINFO*)&nlhpi
+//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+//This function is designed to be called from within pfnHttpGatewayInit
+//See notes below MS_NETLIB_REGISTERUSER.
+//Errors: ERROR_INVALID_PARAMETER
+#define NLHPIF_USEGETSEQUENCE 0x0001 //append sequence numbers to GET requests
+#define NLHPIF_USEPOSTSEQUENCE 0x0002 //append sequence numbers to POST requests
+#define NLHPIF_GETPOSTSAMESEQUENCE 0x0004 //GET and POST use the same sequence
+#define NLHPIF_HTTP11 0x0008 //HTTP 1.1 proxy
+typedef struct {
+ int cbSize;
+ DWORD flags;
+ char *szHttpPostUrl;
+ char *szHttpGetUrl;
+ int firstGetSequence,firstPostSequence;
+#if MIRANDA_VER >= 0x0900
+ int combinePackets;
+#endif
+} NETLIBHTTPPROXYINFO;
+#define MS_NETLIB_SETHTTPPROXYINFO "Netlib/SetHttpProxyInfo"
+
+//Gets the SOCKET associated with a netlib handle
+//wParam=(WPARAM)(HANDLE)hNetlibHandle
+//lParam=0
+//Returns the SOCKET on success, INVALID_SOCKET on failure
+//hNetlibHandle should have been returned by MS_NETLIB_BINDPORT or
+//MS_NETLIB_OPENCONNECTION only.
+//Be careful how you use this socket because you might be connected via an
+//HTTP proxy in which case calling send() or recv() will totally break things.
+//Errors: ERROR_INVALID_PARAMETER
+#define MS_NETLIB_GETSOCKET "Netlib/GetSocket"
+
+//URL-encode a string for x-www-form-urlencoded (and other) transmission
+//wParam=0
+//lParam=(LPARAM)(const char *)pszString
+//Returns a char* containing the new string. This must be freed with
+//HeapFree(GetProcessHeap(),0,pszReturnString) when you're done with it.
+//Returns NULL on error.
+//Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY
+#define MS_NETLIB_URLENCODE "Netlib/UrlEncode"
+
+//Base64 decode a string. See rfc1421.
+//wParam=0
+//lParam=(LPARAM)(NETLIBBASE64*)&nlb64
+//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+//nlb64.pszEncoded and nlb64.cchEncoded contain the input string and its length
+//(excluding terminating zero).
+//nlb64.pbDecoded and nlb64.cbDecoded contain the buffer in which to put the
+//output and the length of this buffer. The maximum output size for a given
+//input is available from the macro Netlib_GetBase64DecodedBufferSize() below.
+//On return nlb64.cbDecoded is set to the actual length of the decoded data.
+//Errors: ERROR_INVALID_PARAMETER, ERROR_INVALID_DATA, ERROR_BUFFER_OVERFLOW
+typedef struct {
+ char *pszEncoded;
+ int cchEncoded;
+ PBYTE pbDecoded;
+ int cbDecoded;
+} NETLIBBASE64;
+#define Netlib_GetBase64DecodedBufferSize(cchEncoded) (((cchEncoded)>>2)*3)
+#define MS_NETLIB_BASE64DECODE "Netlib/Base64Decode"
+
+//Base64 encode a string. See rfc1421.
+//wParam=0
+//lParam=(LPARAM)(NETLIBBASE64*)&nlb64
+//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+//nlb64.pbDecoded and nlb64.cbDecoded contain the input buffer and its length
+//nlb64.pszEncoded and nlb64.cchEncoded contain the buffer in which to put the
+//output and the length of this buffer. The maximum output size for a given
+//input is available from the macro Netlib_GetBase64EncodedBufferSize() below.
+//nlb64.pszEncoded is terminated with a 0.
+//On return nlb64.cchEncoded is set to the actual length of the decoded data,
+//excluding the terminating 0.
+//Errors: ERROR_INVALID_PARAMETER, ERROR_BUFFER_OVERFLOW
+#define Netlib_GetBase64EncodedBufferSize(cbDecoded) (((cbDecoded)*4+11)/12*4+1)
+#define MS_NETLIB_BASE64ENCODE "Netlib/Base64Encode"
+
+//Send an HTTP request over a connection
+//wParam=(WPARAM)(HANDLE)hConnection
+//lParam=(LPARAM)(NETLIBHTTPREQUEST*)&nlhr
+//Returns number of bytes sent on success, SOCKET_ERROR on failure
+//hConnection must have been returned by MS_NETLIB_OPENCONNECTION
+//Note that if you use NLHRF_SMARTAUTHHEADER and NTLM authentication is in use
+//then the full NTLM authentication transaction occurs, comprising sending the
+//domain, receiving the challenge, then sending the response.
+//nlhr.resultCode and nlhr.szResultDescr are ignored by this function.
+//Errors: ERROR_INVALID_PARAMETER, anything returned by MS_NETLIB_SEND
+typedef struct {
+ char *szName;
+ char *szValue;
+} NETLIBHTTPHEADER;
+
+#define REQUEST_RESPONSE 0 //used by structure returned by MS_NETLIB_RECVHTTPHEADERS
+#define REQUEST_GET 1
+#define REQUEST_POST 2
+#define REQUEST_CONNECT 3
+#define REQUEST_HEAD 4 // new in 0.5.1
+#define REQUEST_PUT 5
+#define REQUEST_DELETE 6
+
+#define NLHRF_GENERATEHOST 0x00000001 //auto-generate a "Host" header from szUrl
+#define NLHRF_REMOVEHOST 0x00000002 //remove any host and/or protocol portion of szUrl before sending it
+#define NLHRF_SMARTREMOVEHOST 0x00000004 //removes host and/or protocol from szUrl unless the connection was opened through an HTTP or HTTPS proxy.
+#define NLHRF_SMARTAUTHHEADER 0x00000008 //if the connection was opened through an HTTP or HTTPS proxy then send a Proxy-Authorization header if required.
+#define NLHRF_HTTP11 0x00000010 //use HTTP 1.1
+#define NLHRF_PERSISTENT 0x00000020 //preserve connection on exit, open connection provided in the nlc field of the reply
+ //it should be supplied in nlc field of request for reuse or closed if not needed
+#define NLHRF_SSL 0x00000040 //use SSL connection
+#define NLHRF_NOPROXY 0x00000080 //do not use proxy server
+#define NLHRF_REDIRECT 0x00000100 //handle HTTP redirect requests (response 30x), the resulting url provided in szUrl of the response
+#define NLHRF_NODUMP 0x00010000 //never dump this to the log
+#define NLHRF_NODUMPHEADERS 0x00020000 //don't dump http headers (only useful for POSTs and MS_NETLIB_HTTPTRANSACTION)
+#define NLHRF_DUMPPROXY 0x00040000 //this transaction is a proxy communication. For dump filtering only.
+#define NLHRF_DUMPASTEXT 0x00080000 //dump posted and reply data as text. Headers are always dumped as text.
+#define NLHRF_NODUMPSEND 0x00100000 //do not dump sent message.
+struct NETLIBHTTPREQUEST_tag {
+ int cbSize;
+ int requestType; //a REQUEST_
+ DWORD flags;
+ char *szUrl;
+ NETLIBHTTPHEADER *headers; //If this is a POST request and headers
+ //doesn't contain a Content-Length it'll be added automatically
+ int headersCount;
+ char *pData; //data to be sent in POST request.
+ int dataLength; //must be 0 for REQUEST_GET/REQUEST_CONNECT
+ int resultCode;
+ char *szResultDescr;
+ HANDLE nlc;
+};
+//typedef struct NETLIBHTTPREQUEST_tag NETLIBHTTPREQUEST; //(above for reasons of forward referencing)
+#define MS_NETLIB_SENDHTTPREQUEST "Netlib/SendHttpRequest"
+
+//Receive HTTP headers
+//wParam=(WPARAM)(HANDLE)hConnection
+//lParam=0
+//Returns a pointer to a NETLIBHTTPREQUEST structure on success, NULL on
+//failure.
+//Call MS_NETLIB_FREEHTTPREQUESTSTRUCT to free this.
+//hConnection must have been returned by MS_NETLIB_OPENCONNECTION
+//nlhr->pData=NULL and nlhr->dataLength=0 always. The requested data should
+//be retrieved using MS_NETLIB_RECV once the header has been parsed.
+//If the headers haven't finished within 60 seconds the function returns NULL
+//and ERROR_TIMEOUT.
+//Errors: ERROR_INVALID_PARAMETER, any from MS_NETLIB_RECV or select()
+// ERROR_HANDLE_EOF (connection closed before headers complete)
+// ERROR_TIMEOUT (headers still not complete after 60 seconds)
+// ERROR_BAD_FORMAT (invalid character or line ending in headers, or first line is blank)
+// ERROR_BUFFER_OVERFLOW (each header line must be less than 4096 chars long)
+// ERROR_INVALID_DATA (first header line is malformed ("http/[01].[0-9] [0-9]+ .*", or no colon in subsequent line)
+#define MS_NETLIB_RECVHTTPHEADERS "Netlib/RecvHttpHeaders"
+
+//Free the memory used by a NETLIBHTTPREQUEST structure
+//wParam=0
+//lParam=(LPARAM)(NETLIBHTTPREQUEST*)pnlhr
+//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+//This should only be called on structures returned by
+//MS_NETLIB_RECVHTTPHEADERS or MS_NETLIB_HTTPTRANSACTION. Calling it on an
+//arbitrary structure will have disastrous results.
+//Errors: ERROR_INVALID_PARAMETER
+#define MS_NETLIB_FREEHTTPREQUESTSTRUCT "Netlib/FreeHttpRequestStruct"
+
+//Do an entire HTTP transaction
+//wParam=(WPARAM)(HANDLE)hUser
+//lParam=(LPARAM)(NETLIBHTTPREQUEST*)&nlhr
+//Returns a pointer to another NETLIBHTTPREQUEST structure on success, NULL on
+//failure.
+//Call MS_NETLIB_FREEHTTPREQUESTSTRUCT to free this.
+//hUser must have been returned by MS_NETLIB_REGISTERUSER
+//nlhr.szUrl should be a full HTTP URL. If it does not start with http://, that
+//will be assumed (but it's best not to use this fact, for reasons of
+//extensibility).
+//This function is the equivalent of MS_NETLIB_OPENCONNECTION,
+//MS_NETLIB_SENDHTTPREQ, MS_NETLIB_RECVHTTPHEADERS, MS_NETLIB_RECV,
+//MS_NETLIB_CLOSEHANDLE
+//nlhr.headers will be augmented with the following headers unless they have
+//already been set by the caller:
+// "Host" (regardless of whether it is requested in nlhr.flags)
+// "User-Agent" (of the form "Miranda/0.1.2.2 (alpha)" or "Miranda/0.1.2.2")
+// "Content-Length" (for POSTs only. Set to nlhr.dataLength)
+//If you do not want to send one of these headers, create a nlhr.headers with
+//szValue=NULL.
+//In the return value headers, headerCount, pData, dataLength, resultCode and
+//szResultDescr are all valid.
+//In the return value pData[dataLength]==0 always, as an extra safeguard
+//against programming slips.
+//Note that the function can succeed (ie not return NULL) yet result in an HTTP
+//error code. You should check that resultCode==2xx before proceeding.
+//Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY, anything from the above
+// list of functions
+#define MS_NETLIB_HTTPTRANSACTION "Netlib/HttpTransaction"
+
+//Send data over a connection
+//wParam=(WPARAM)(HANDLE)hConnection
+//lParam=(LPARAM)(NETLIBBUFFER*)&nlb
+//Returns the number of bytes sent on success, SOCKET_ERROR on failure
+//Errors: ERROR_INVALID_PARAMETER
+// anything from send(), nlu.pfnHttpGatewayWrapSend()
+// HTTP proxy: ERROR_GEN_FAILURE (http result code wasn't 2xx)
+// anything from socket(), connect(),
+// MS_NETLIB_SENDHTTPREQUEST, MS_NETLIB_RECVHTTPHEADERS
+//flags:
+#define MSG_NOHTTPGATEWAYWRAP 0x010000 //don't wrap the outgoing packet using nlu.pfnHttpGatewayWrapSend
+#define MSG_NODUMP 0x020000 //don't dump this packet to the log
+#define MSG_DUMPPROXY 0x040000 //this is proxy communiciation. For dump filtering only.
+#define MSG_DUMPASTEXT 0x080000 //this is textual data, don't dump as hex
+#define MSG_RAW 0x100000 //send as raw data, bypass any HTTP proxy stuff
+#define MSG_DUMPSSL 0x200000 //this is SSL traffic. For dump filtering only.
+typedef struct {
+ char *buf;
+ int len;
+ int flags;
+} NETLIBBUFFER;
+#define MS_NETLIB_SEND "Netlib/Send"
+static __inline INT_PTR Netlib_Send(HANDLE hConn,const char *buf,int len,int flags) {
+ NETLIBBUFFER nlb={(char*)buf,len,flags};
+ return CallService(MS_NETLIB_SEND,(WPARAM)hConn,(LPARAM)&nlb);
+}
+
+//Receive data over a connection
+//wParam=(WPARAM)(HANDLE)hConnection
+//lParam=(LPARAM)(NETLIBBUFFER*)&nlb
+//Returns the number of bytes read on success, SOCKET_ERROR on failure,
+//0 if the connection has been closed
+//Flags supported: MSG_PEEK, MSG_NODUMP, MSG_DUMPPROXY, MSG_NOHTTPGATEWAYWRAP,
+// MSG_DUMPASTEXT, MSG_RAW
+//On using MSG_NOHTTPGATEWAYWRAP: Because packets through an HTTP proxy are
+// batched and cached and stuff, using this flag is not a guarantee that it
+// will be obeyed, and if it is it may even be propogated to future calls
+// even if you don't specify it then. Because of this, the flag should be
+// considered an all-or-nothing thing: either use it for the entire duration
+// of a connection, or not at all.
+//Errors: ERROR_INVALID_PARAMETER, anything from recv()
+// HTTP proxy: ERROR_GEN_FAILURE (http result code wasn't 2xx)
+// ERROR_INVALID_DATA (no Content-Length header in reply)
+// ERROR_NOT_ENOUGH_MEMORY (Content-Length very large)
+// ERROR_HANDLE_EOF (connection closed before Content-Length bytes recved)
+// anything from select(), MS_NETLIB_RECVHTTPHEADERS,
+// nlu.pfnHttpGatewayUnwrapRecv, socket(), connect(),
+// MS_NETLIB_SENDHTTPREQUEST
+#define MS_NETLIB_RECV "Netlib/Recv"
+static __inline INT_PTR Netlib_Recv(HANDLE hConn,char *buf,int len,int flags) {
+ NETLIBBUFFER nlb={buf,len,flags};
+ return CallService(MS_NETLIB_RECV,(WPARAM)hConn,(LPARAM)&nlb);
+}
+
+//Determine the status of one or more connections
+//wParam=0
+//lParam=(LPARAM)(NETLIBSELECT*)&nls
+//Returns the number of ready connections, SOCKET_ERROR on failure,
+//0 if the timeout expired.
+//All handles passed to this function must have been returned by either
+//MS_NETLIB_OPENCONNECTION or MS_NETLIB_BINDPORT.
+//The last handle in each list must be followed by either NULL or
+//INVALID_HANDLE_VALUE.
+//Errors: ERROR_INVALID_HANDLE, ERROR_INVALID_DATA, anything from select()
+typedef struct {
+ int cbSize;
+ DWORD dwTimeout; //in milliseconds, INFINITE is acceptable
+ HANDLE hReadConns[FD_SETSIZE+1];
+ HANDLE hWriteConns[FD_SETSIZE+1];
+ HANDLE hExceptConns[FD_SETSIZE+1];
+} NETLIBSELECT;
+
+typedef struct {
+ int cbSize;
+ DWORD dwTimeout; //in milliseconds, INFINITE is acceptable
+ HANDLE hReadConns[FD_SETSIZE+1];
+ HANDLE hWriteConns[FD_SETSIZE+1];
+ HANDLE hExceptConns[FD_SETSIZE+1];
+ /* Added in v0.3.3+ */
+ BOOL hReadStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */
+ BOOL hWriteStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */
+ BOOL hExceptStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */
+} NETLIBSELECTEX;
+
+#define MS_NETLIB_SELECT "Netlib/Select"
+// added in v0.3.3
+#define MS_NETLIB_SELECTEX "Netlib/SelectEx"
+
+//Shutdown connection
+//wParam=(WPARAM)(HANDLE)hConnection
+//lParam=(LPARAM)0
+//Returns 0
+#define MS_NETLIB_SHUTDOWN "Netlib/Shutdown"
+__inline static void Netlib_Shutdown(HANDLE h) {CallService(MS_NETLIB_SHUTDOWN,(WPARAM)h,0);}
+
+//Create a packet receiver
+//wParam=(WPARAM)(HANDLE)hConnection
+//lParam=(LPARAM)(int)maxPacketSize
+//Returns a HANDLE on success, NULL on failure
+//The packet receiver implements the common situation where you have variable
+//length packets coming in over a connection and you want to split them up
+//in order to handle them.
+//The major limitation is that the buffer is created in memory, so you can't
+//have arbitrarily large packets.
+//Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY
+#define MS_NETLIB_CREATEPACKETRECVER "Netlib/CreatePacketRecver"
+
+//Get the next set of packets from a packet receiver
+//wParam=(WPARAM)(HANDLE)hPacketRecver
+//lParam=(LPARAM)(NETLIBPACKETRECVER*)&nlpr
+//Returns the total number of bytes available in the buffer, 0 if the
+//connection was closed, SOCKET_ERROR on error.
+//hPacketRecver must have been returned by MS_NETLIB_CREATEPACKETRECVER
+//If nlpr.bytesUsed is set to zero and the buffer is already full up to
+//maxPacketSize, it is assumed that too large a packet has been received. All
+//data in the buffer is discarded and receiving is begun anew. This will
+//probably cause alignment problems so if you think this is likely to happen
+//then you should deal with it yourself.
+//Closing the packet receiver will not close the associated connection, but
+//will discard any bytes still in the buffer, so if you intend to carry on
+//reading from that connection, make sure you have processed the buffer first.
+//This function is the equivalent of a memmove() to remove the first bytesUsed
+//from the buffer, select() if dwTimeout is not INFINITE, then MS_NETLIB_RECV.
+//Errors: ERROR_INVALID_PARAMETER, ERROR_TIMEOUT,
+// anything from select(), MS_NETLIB_RECV
+typedef struct {
+ int cbSize;
+ DWORD dwTimeout; //fill before calling. In milliseconds. INFINITE is valid
+ int bytesUsed; //fill before calling. This many bytes are removed from the start of the buffer. Set to 0 on return
+ int bytesAvailable; //equal to the return value, unless the return value is 0
+ int bufferSize; //same as parameter to MS_NETLIB_CREATEPACKETRECVER
+ BYTE *buffer; //contains the recved data
+} NETLIBPACKETRECVER;
+#define MS_NETLIB_GETMOREPACKETS "Netlib/GetMorePackets"
+
+//Add a message to the log (if it's running)
+//wParam=(WPARAM)(HANDLE)hUser
+//lParam=(LPARAM)(const char *)szMessage
+//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+//Do not include a final line ending in szMessage.
+//Errors: ERROR_INVALID_PARAMETER
+#define MS_NETLIB_LOG "Netlib/Log"
+
+//Sets a gateway polling timeout interval
+//wParam=(WPARAM)(HANDLE)hConn
+//lParam=(LPARAM)timeout
+//Returns previous timeout value
+//Errors: -1
+#define MS_NETLIB_SETPOLLINGTIMEOUT "Netlib/SetPollingTimeout"
+
+//Makes connection SSL
+//wParam=(WPARAM)(HANDLE)hConn
+//lParam=(LPARAM)(NETLIBSSL*)&nlssl or null if no certficate validation required
+//Returns 0 on failure 1 on success
+#define MS_NETLIB_STARTSSL "Netlib/StartSsl"
+
+typedef struct
+{
+ int cbSize;
+ const char *host; //Expected host name
+ int flags; //Reserved
+} NETLIBSSL;
+
+
+//here's a handy piece of code to let you log using printf-style specifiers:
+//#include <stdarg.h> and <stdio.h> before including this header in order to
+//use it.
+#if defined va_start && (defined _STDIO_DEFINED || defined _STDIO_H_) && (!defined NETLIB_NOLOGGING)
+static INT_PTR Netlib_Logf(HANDLE hUser,const char *fmt,...)
+{
+ va_list va;
+ char szText[1024];
+
+ __try
+ {
+ va_start(va,fmt);
+ mir_vsnprintf(szText,sizeof(szText),fmt,va);
+ va_end(va);
+ return CallService(MS_NETLIB_LOG,(WPARAM)hUser,(LPARAM)szText);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER) {}
+ return 0;
+}
+#endif //defined va_start
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Security providers (0.6+)
+
+#define NNR_UNICODE 1
+
+#ifdef UNICODE
+#define NNR_TCHAR 1
+#else
+#define NNR_TCHAR 0
+#endif
+
+// Inits a required security provider. Right now only NTLM is supported
+// Returns HANDLE = NULL on error or non-null value on success
+#define MS_NETLIB_INITSECURITYPROVIDER "Netlib/InitSecurityProvider"
+
+static __inline HANDLE Netlib_InitSecurityProvider( char* szProviderName )
+{
+ return (HANDLE)CallService( MS_NETLIB_INITSECURITYPROVIDER, 0, (LPARAM)szProviderName );
+}
+
+typedef struct {
+ size_t cbSize;
+ const TCHAR* szProviderName;
+ const TCHAR* szPrincipal;
+ unsigned flags;
+}
+ NETLIBNTLMINIT2;
+
+#define MS_NETLIB_INITSECURITYPROVIDER2 "Netlib/InitSecurityProvider2"
+
+static __inline HANDLE Netlib_InitSecurityProvider2( const TCHAR* szProviderName, const TCHAR* szPrincipal )
+{
+ NETLIBNTLMINIT2 temp = { sizeof(temp), szProviderName, szPrincipal, NNR_TCHAR };
+ return (HANDLE)CallService( MS_NETLIB_INITSECURITYPROVIDER2, 0, (LPARAM)&temp );
+}
+
+
+// Destroys a security provider's handle, provided by Netlib_InitSecurityProvider.
+// Right now only NTLM is supported
+#define MS_NETLIB_DESTROYSECURITYPROVIDER "Netlib/DestroySecurityProvider"
+
+static __inline void Netlib_DestroySecurityProvider( char* szProviderName, HANDLE hProvider )
+{
+ CallService( MS_NETLIB_DESTROYSECURITYPROVIDER, (WPARAM)szProviderName, (LPARAM)hProvider );
+}
+
+// Returns the NTLM response string. The result value should be freed using mir_free
+
+typedef struct {
+ char* szChallenge;
+ char* userName;
+ char* password;
+}
+ NETLIBNTLMREQUEST;
+
+#define MS_NETLIB_NTLMCREATERESPONSE "Netlib/NtlmCreateResponse"
+
+static __inline char* Netlib_NtlmCreateResponse( HANDLE hProvider, char* szChallenge, char* login, char* psw )
+{
+ NETLIBNTLMREQUEST temp = { szChallenge, login, psw };
+ return (char*)CallService( MS_NETLIB_NTLMCREATERESPONSE, (WPARAM)hProvider, (LPARAM)&temp );
+}
+
+typedef struct {
+ size_t cbSize;
+ const char* szChallenge;
+ const TCHAR* szUserName;
+ const TCHAR* szPassword;
+ unsigned complete;
+ unsigned flags;
+}
+ NETLIBNTLMREQUEST2;
+
+#define MS_NETLIB_NTLMCREATERESPONSE2 "Netlib/NtlmCreateResponse2"
+
+static __inline char* Netlib_NtlmCreateResponse2( HANDLE hProvider, char* szChallenge, TCHAR* szLogin, TCHAR* szPass, unsigned *complete )
+{
+ NETLIBNTLMREQUEST2 temp = { sizeof(temp), szChallenge, szLogin, szPass, 0, NNR_TCHAR };
+ char* res = (char*)CallService( MS_NETLIB_NTLMCREATERESPONSE2, (WPARAM)hProvider, (LPARAM)&temp );
+ *complete = temp.complete;
+ return res;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Netlib hooks (0.8+)
+
+// WARNING: these hooks are being called in the context of the calling thread, without switching
+// to the first thread, like all another events do. The hook procedure should be ready for the
+// multithreaded mode
+//
+// Parameters:
+// wParam: NETLIBNOTIFY* - points to the data being sent/received
+// lParam: NETLIBUSER* - points to the protocol definition
+
+typedef struct {
+ NETLIBBUFFER* nlb; // pointer to the request buffer
+ int result; // amount of bytes really sent/received
+}
+ NETLIBNOTIFY;
+
+#define ME_NETLIB_FASTRECV "Netlib/OnRecv" // being called on every receive
+#define ME_NETLIB_FASTSEND "Netlib/OnSend" // being called on every send
+#define ME_NETLIB_FASTDUMP "Netlib/OnDump" // being called on every dump
+
+#endif // M_NETLIB_H__
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_options.h b/plugins/!NotAdopted/WinPopup/sdk/m_options.h
new file mode 100644
index 0000000000..0231efaedd
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_options.h
@@ -0,0 +1,138 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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_OPTIONS_H__
+#define M_OPTIONS_H__
+
+/* Opt/Initialise
+The user opened the options dialog. Modules should do whatever initialisation
+they need and call opt/addpage one or more times if they want pages displayed
+in the options dialog
+wParam=addInfo
+lParam=0
+addInfo should be passed straight to the wParam of opt/addpage
+*/
+#define ME_OPT_INITIALISE "Opt/Initialise"
+
+/* Opt/AddPage
+Must only be called during an opt/initialise hook
+Adds a page to the options dialog
+wParam=addInfo
+lParam=(LPARAM)(OPTIONSDIALOGPAGE*)odp
+addInfo must have come straight from the wParam of opt/initialise
+Pages in the options dialog operate just like pages in property sheets. See the
+Microsoft documentation for details on how they operate.
+Strings in the structure can be released as soon as the service returns, but
+icons must be kept around. This is not a problem if you're loading them from a
+resource.
+Prior to v0.1.2.1 the options dialog would resize to fit the largest page, but
+since then it is fixed in size. The largest page that fits neatly is 314x240
+DLUs.
+*/
+
+// WARNING: do not use Translate(TS) for pszTitle, pszGroup or pszTab as they
+// are translated by the core, which may lead to double translation.
+// Use LPGEN instead which are just dummy wrappers/markers for "lpgen.pl".
+typedef struct {
+ int cbSize;
+ int position; //a position number, lower numbers are topmost
+ union {
+ char* pszTitle; // [TRANSLATED-BY-CORE]
+ TCHAR* ptszTitle;
+ };
+ DLGPROC pfnDlgProc;
+ char *pszTemplate;
+ HINSTANCE hInstance;
+ HICON hIcon; //v0.1.0.1+
+ union {
+ char* pszGroup; //v0.1.0.1+ [TRANSLATED-BY-CORE]
+ TCHAR* ptszGroup; //v0.1.0.1+
+ };
+ int groupPosition; //v0.1.0.1+
+ HICON hGroupIcon; //v0.1.0.1+
+ DWORD flags; //v0.1.2.1+
+ int nIDBottomSimpleControl; //v0.1.2.1+ if in simple mode the dlg will be cut off after this control, 0 to disable
+ int nIDRightSimpleControl; //v0.1.2.1+ if in simple mode the dlg will be cut off after this control, 0 to disable
+ UINT *expertOnlyControls;
+ int nExpertOnlyControls; //v0.1.2.1+ these controls will be hidden in simple mode. Array must remain valid for duration of dlg.
+
+ #if MIRANDA_VER >= 0x0600
+ union {
+ char* pszTab; //v0.6.0.0+ [TRANSLATED-BY-CORE]
+ TCHAR* ptszTab; //v0.6.0.0+
+ };
+ #endif
+
+ #if MIRANDA_VER >= 0x0800
+ LPARAM dwInitParam; //v0.8.0.0+ a value to pass to lParam of WM_INITDIALOG message
+ #endif
+}
+ OPTIONSDIALOGPAGE;
+
+#define OPTIONPAGE_OLD_SIZE (offsetof(OPTIONSDIALOGPAGE, flags))
+#if MIRANDA_VER >= 0x0600
+ #define OPTIONPAGE_OLD_SIZE2 (offsetof(OPTIONSDIALOGPAGE, pszTab))
+#endif
+#if MIRANDA_VER >= 0x0800
+ #define OPTIONPAGE_OLD_SIZE3 (offsetof(OPTIONSDIALOGPAGE, dwInitParam))
+#endif
+
+#define ODPF_SIMPLEONLY 1 // page is only shown when in simple mode
+#define ODPF_EXPERTONLY 2 // " expert mode
+#define ODPF_BOLDGROUPS 4 // give group box titles a bold font
+#define ODPF_UNICODE 8 // string fields in OPTIONSDIALOGPAGE are WCHAR*
+#define ODPF_USERINFOTAB 16 // options page is tabbed
+
+#if defined( _UNICODE )
+ #define ODPF_TCHAR ODPF_UNICODE
+#else
+ #define ODPF_TCHAR 0
+#endif
+
+#define PSN_EXPERTCHANGED 2 //sent to pages via WM_NOTIFY when the expert checkbox is clicked. lParam=new state
+#define PSM_ISEXPERT (WM_USER+101) //returns true/false
+#define PSM_GETBOLDFONT (WM_USER+102) //returns HFONT used for group box titles
+#define MS_OPT_ADDPAGE "Opt/AddPage"
+
+//Opens the options dialog, optionally at the specified page v0.1.2.1+
+//wParam=0
+//lParam=(LPARAM)(OPENOPTIONSDIALOG*)&ood;
+//Returns 0 on success, nonzero on failure
+//The behaviour if the options dialog is already open is that it will just be
+//activated, the page won't be changed. This may change in the future.
+typedef struct {
+ int cbSize;
+ const char *pszGroup; //set to NULL if it's a root item
+ const char *pszPage; //set to NULL to just open the options at no
+ //specific page
+ const char *pszTab; //set to NULL to just open the options at no
+ //specific tab
+} OPENOPTIONSDIALOG;
+#define MS_OPT_OPENOPTIONS "Opt/OpenOptions"
+
+//Opens the options dialog, with only specified page v0.8.0.x+
+#define MS_OPT_OPENOPTIONSPAGE "Opt/OpenOptionsPage"
+
+#define SETTING_SHOWEXPERT_DEFAULT 1
+
+#endif //M_OPTIONS_H__
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_plugins.h b/plugins/!NotAdopted/WinPopup/sdk/m_plugins.h
new file mode 100644
index 0000000000..8cbd5a4ba1
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_plugins.h
@@ -0,0 +1,85 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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_PLUGINS_H__
+#define M_PLUGINS_H__
+
+/*
+ Undocumented: Do NOT use.
+ Version: 0.3.4.1+ (2004/10/04)
+*/
+#define DBPE_DONE 1
+#define DBPE_CONT 0
+#define DBPE_HALT (-1)
+typedef struct PLUGIN_DB_ENUM {
+ int cbSize;
+ // 0 = continue, 1 = found, -1 = stop now
+ int (*pfnEnumCallback) ( char * pluginname, /*DATABASELINK*/ void * link, LPARAM lParam);
+ LPARAM lParam;
+} PLUGIN_DB_ENUM;
+#define MS_PLUGINS_ENUMDBPLUGINS "Plugins/DbEnumerate"
+
+
+//#define DEFMOD_PROTOCOLICQ 1 //removed from v0.3 alpha
+//#define DEFMOD_PROTOCOLMSN 2 //removed from v0.1.2.0+
+#define DEFMOD_UIFINDADD 3
+#define DEFMOD_UIUSERINFO 4
+#define DEFMOD_SRMESSAGE 5
+#define DEFMOD_SRURL 6
+#define DEFMOD_SREMAIL 7
+#define DEFMOD_SRAUTH 8
+#define DEFMOD_SRFILE 9
+#define DEFMOD_UIHELP 10
+#define DEFMOD_UIHISTORY 11
+//#define DEFMOD_RNDCHECKUPD 12 //removed from v0.3.1 alpha
+//#define DEFMOD_RNDICQIMPORT 13 //removed from v0.3 alpha
+#define DEFMOD_RNDAUTOAWAY 14
+#define DEFMOD_RNDUSERONLINE 15
+//#define DEFMOD_RNDCRYPT 16 // v0.1.0.1-v0.1.2.0
+#define DEFMOD_SRAWAY 17 // v0.1.0.1+
+#define DEFMOD_RNDIGNORE 18 // v0.1.0.1+
+#define DEFMOD_UIVISIBILITY 19 // v0.1.1.0+, options page only
+#define DEFMOD_UICLUI 20 // v0.1.1.0+
+//#define DEFMOD_UIPLUGINOPTS 21 // removed from 0.4.0.1
+//#define DEFMOD_PROTOCOLNETLIB 22 // removed from 0.8.0.5
+#define DEFMOD_RNDIDLE 23 // v0.3.4a+
+#define DEFMOD_CLISTALL 24 // v0.3.4a+ (2004/09/28)
+#define DEFMOD_DB 25 // v0.3.4.3+ (2004/10/11)
+#define DEFMOD_FONTSERVICE 26 // v0.7.0+ (2006/11/17)
+#define DEFMOD_UPDATENOTIFY 27
+#define DEFMOD_SSL 28 // v0.8.0+
+#define DEFMOD_HIGHEST 28
+
+//plugins/getdisabledefaultarray
+//gets an array of the modules that the plugins report they want to replace
+//wParam=lParam=0
+//returns a pointer to an array of INT_PTR, with elements 1 or 0 indexed by the
+//DEFMOD_ constants. 1 to signify that the default module shouldn't be loaded.
+//this is primarily for use by the core's module initialiser, but could also
+//be used by modules that are doing naughty things that are very
+//feature-dependent
+#define MS_PLUGINS_GETDISABLEDEFAULTARRAY "Plugins/GetDisableDefaultArray"
+
+#endif // M_PLUGINS_H__
+
+
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_popup.h b/plugins/!NotAdopted/WinPopup/sdk/m_popup.h
new file mode 100644
index 0000000000..419f2bd396
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_popup.h
@@ -0,0 +1,424 @@
+/*
+===============================================================================
+ 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 2048
+#define MAX_SECONDLINE 2048
+
+// 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.
+ union
+ {
+ char lptzContactName[MAX_CONTACTNAME]; // This is the contact name or the first line in the plugin. Cannot be NULL.
+ char lpzContactName[MAX_CONTACTNAME];
+ };
+ union
+ {
+ char lptzText[MAX_SECONDLINE]; // This is the second line text. Users can choose to hide it. Cannot be NULL.
+ char lpzText[MAX_SECONDLINE];
+ };
+ 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;
+
+// Extended popup data
+typedef struct
+{
+ HANDLE lchContact;
+ HICON lchIcon;
+ union
+ {
+ char lptzContactName[MAX_CONTACTNAME];
+ char lpzContactName[MAX_CONTACTNAME];
+ };
+ union
+ {
+ char lptzText[MAX_SECONDLINE];
+ char lpzText[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.
+} POPUPDATAEX, *LPPOPUPDATAEX;
+
+// Unicode version of POPUPDATAEX
+typedef struct
+{
+ HANDLE lchContact;
+ HICON lchIcon;
+ union
+ {
+ WCHAR lptzContactName[MAX_CONTACTNAME];
+ WCHAR lpwzContactName[MAX_CONTACTNAME];
+ };
+ union
+ {
+ WCHAR lptzText[MAX_SECONDLINE];
+ WCHAR lpwzText[MAX_SECONDLINE];
+ };
+ COLORREF colorBack;
+ COLORREF colorText;
+ WNDPROC PluginWindowProc;
+ void * PluginData;
+ int iSeconds;
+ char cZero[16];
+} POPUPDATAW, *LPPOPUPDATAW;
+
+#if defined(_UNICODE) || defined(UNICODE)
+ typedef POPUPDATAW POPUPDATAT;
+ typedef LPPOPUPDATAW LPPOPUPDATAT;
+#else
+ typedef POPUPDATAEX POPUPDATAT;
+ typedef LPPOPUPDATAEX LPPOPUPDATAT;
+#endif
+
+/* PopUp/AddPopup
+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...
+
+Popup Plus 2.0.4.0+
+You may pass additional creation flags via lParam:
+ APF_RETURN_HWND ....... function returns handle to newly created popup window (however this calls are a bit slower)
+ APF_CUSTOM_POPUP ...... new popup is created in hidden state and doesn't obey to popup queue rules.
+ you may control it via UM_* messages and custom window procedure
+*/
+#define APF_RETURN_HWND 0x1
+#define APF_CUSTOM_POPUP 0x2
+
+#define MS_POPUP_ADDPOPUP "PopUp/AddPopUp"
+static INT_PTR __inline PUAddPopUp(POPUPDATA* ppdp) {
+ return CallService(MS_POPUP_ADDPOPUP, (WPARAM)ppdp,0);
+}
+
+#define MS_POPUP_ADDPOPUPEX "PopUp/AddPopUpEx"
+static INT_PTR __inline PUAddPopUpEx(POPUPDATAEX* ppdp) {
+ return CallService(MS_POPUP_ADDPOPUPEX, (WPARAM)ppdp,0);
+}
+
+#define MS_POPUP_ADDPOPUPW "PopUp/AddPopUpW"
+static INT_PTR __inline PUAddPopUpW(POPUPDATAW* ppdp) {
+ return CallService(MS_POPUP_ADDPOPUPW, (WPARAM)ppdp,0);
+}
+
+#if defined(_UNICODE) || defined(UNICODE)
+ #define MS_POPUP_ADDPOPUPT MS_POPUP_ADDPOPUPW
+ #define PUAddPopUpT PUAddPopUpW
+#else
+ #define MS_POPUP_ADDPOPUPT MS_POPUP_ADDPOPUPEX
+ #define PUAddPopUpT PUAddPopUpEx
+#endif
+
+
+/* PopUp/GetContact
+Returns the handle to the contact associated to the specified PopUpWindow.
+
+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);
+}
+
+/* PopUp/GetPluginData
+Returns custom plugin date associated with popup
+
+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);
+}
+
+/* PopUp/IsSecondLineShown
+Checks if second line is enable
+
+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);
+}
+
+/* PopUp/Query
+
+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
+Process this message if you have allocated your own memory. (i.e.: POPUPDATA.PluginData != NULL)
+
+wParam = 0
+lParam = 0
+*/
+#define UM_FREEPLUGINDATA (WM_USER + 0x0200)
+
+/* UM_DESTROYPOPUP
+Send this message when you want to destroy the popup, or use the function below.
+
+wParam = 0
+lParam = 0
+*/
+#define UM_DESTROYPOPUP (WM_USER + 0x0201)
+static int __inline PUDeletePopUp(HWND hWndPopUp) {
+ return (int)SendMessage(hWndPopUp, UM_DESTROYPOPUP,0,0);
+}
+
+/* UM_INITPOPUP
+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 ;-)
+
+wParam = (WPARAM)(HWND)hPopUpWindow (this is useless, you get message inside your popup window)
+lParam = 0
+*/
+#define UM_INITPOPUP (WM_USER + 0x0202)
+
+/* PopUp/Changetext
+Changes the text displayed in the second line of the popup.
+
+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...)
+*/
+#define MS_POPUP_CHANGETEXT "PopUp/Changetext"
+static int __inline PUChangeText(HWND hWndPopUp, LPCTSTR lpzNewText) {
+ return (int)CallService(MS_POPUP_CHANGETEXT, (WPARAM)hWndPopUp, (LPARAM)lpzNewText);
+}
+
+#define MS_POPUP_CHANGETEXTW "PopUp/ChangetextW"
+static int __inline PUChangeTextW(HWND hWndPopUp, LPCWSTR lpwzNewText) {
+ return (int)CallService(MS_POPUP_CHANGETEXTW, (WPARAM)hWndPopUp, (LPARAM)lpwzNewText);
+}
+
+#if defined(_UNICODE) || defined(UNICODE)
+ #define MS_POPUP_CHANGETEXTT MS_POPUP_CHANGETEXTW
+ #define PUChangeTextT PUChangeTextW
+#else
+ #define MS_POPUP_CHANGETEXTT MS_POPUP_CHANGETEXT
+ #define PUChangeTextT PUChangeText
+#endif
+
+/* PopUp/Change
+Changes the entire popup
+
+wParam = (WPARAM)(HWND)hPopUpWindow
+lParam = (LPARAM)(POPUPDATAEX*)newData
+*/
+#define MS_POPUP_CHANGE "PopUp/Change"
+static int __inline PUChange(HWND hWndPopUp, POPUPDATAEX *newData) {
+ return (int)CallService(MS_POPUP_CHANGE, (WPARAM)hWndPopUp, (LPARAM)newData);
+}
+
+#define MS_POPUP_CHANGEW "PopUp/ChangeW"
+static int __inline PUChangeW(HWND hWndPopUp, POPUPDATAW *newData) {
+ return (int)CallService(MS_POPUP_CHANGE, (WPARAM)hWndPopUp, (LPARAM)newData);
+}
+
+#if defined(_UNICODE) || defined(UNICODE)
+ #define MS_POPUP_CHANGET MS_POPUP_CHANGEW
+ #define PUChangeT PUChangeW
+#else
+ #define MS_POPUP_CHANGET MS_POPUP_CHANGE
+ #define PUChangeT PUChange
+#endif
+
+/* UM_CHANGEPOPUP
+This message is triggered by Change/ChangeText services. You also may post it directly :)
+
+wParam = Modification type
+lParam = value of type defined by wParam
+*/
+
+#define CPT_TEXT 1 // lParam = (char *)text
+#define CPT_TEXTW 2 // lParam = (WCHAR *)text
+#define CPT_TITLE 3 // lParam = (char *)title
+#define CPT_TITLEW 4 // lParam = (WCHAR *)title
+#define CPT_DATA 5 // lParam = (POPUPDATA *)data
+#define CPT_DATAEX 6 // lParam = (POPUPDATAEX *)data
+#define CPT_DATAW 7 // lParam = (POPUPDATAW *)data
+
+#define UM_CHANGEPOPUP (WM_USER + 0x0203)
+
+#if defined(_UNICODE) || defined(UNICODE)
+ #define CPT_TEXTT CPT_TEXTW
+ #define CPT_TITLET CPT_TITLEW
+ #define CPT_DATAT CPT_DATAW
+#else
+ #define CPT_TEXTT CPT_TEXT
+ #define CPT_TITLET CPT_TITLE
+ #define CPT_DATAT CPT_DATA
+#endif
+
+/* PopUp/ShowMessage
+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"
+#define MS_POPUP_SHOWMESSAGEW "PopUp/ShowMessageW"
+
+static int __inline PUShowMessage(char *lpzText, BYTE kind) {
+ return (int)CallService(MS_POPUP_SHOWMESSAGE, (WPARAM)lpzText,(LPARAM)kind);
+}
+
+static int __inline PUShowMessageW(wchar_t *lpwzText, BYTE kind) {
+ return (int)CallService(MS_POPUP_SHOWMESSAGEW, (WPARAM)lpwzText,(LPARAM)kind);
+}
+
+#ifdef _UNICODE
+#define PUShowMessageT PUShowMessageW
+#else
+#define PUShowMessageT PUShowMessage
+#endif
+
+//------------- Class API ----------------//
+
+typedef struct {
+ int cbSize;
+ int flags;
+ char *pszName;
+ union {
+ char *pszDescription;
+ wchar_t *pwszDescription;
+ TCHAR *ptszDescription;
+ };
+
+ HICON hIcon;
+
+ COLORREF colorBack;
+ COLORREF colorText;
+
+ WNDPROC PluginWindowProc;
+
+ int iSeconds;
+} POPUPCLASS;
+
+#define PCF_UNICODE 0x0001
+
+#ifdef _UNICODE
+#define PCF_TCHAR PCF_UNICODE
+#else
+#define PCF_TCHAR 0
+#endif
+
+// wParam = 0
+// lParam = (POPUPCLASS *)&pc
+#define MS_POPUP_REGISTERCLASS "PopUp/RegisterClass"
+
+typedef struct {
+ int cbSize;
+ char *pszClassName;
+ union {
+ const char *pszTitle;
+ const wchar_t *pwszTitle;
+ const TCHAR *ptszTitle;
+ };
+ union {
+ const char *pszText;
+ const wchar_t *pwszText;
+ const TCHAR *ptszText;
+ };
+ void *PluginData;
+ HANDLE hContact;
+} POPUPDATACLASS;
+
+// wParam = 0
+// lParam = (POPUPDATACLASS *)&pdc
+#define MS_POPUP_ADDPOPUPCLASS "PopUp/AddPopupClass"
+
+static INT_PTR __inline ShowClassPopup(char *name, char *title, char *text) {
+ POPUPDATACLASS d = {sizeof(d), name};
+ d.pszTitle = title;
+ d.pszText = text;
+ return CallService(MS_POPUP_ADDPOPUPCLASS, 0, (LPARAM)&d);
+}
+
+static INT_PTR __inline ShowClassPopupW(char *name, wchar_t *title, wchar_t *text) {
+ POPUPDATACLASS d = {sizeof(d), name};
+ d.pwszTitle = title;
+ d.pwszText = text;
+ return CallService(MS_POPUP_ADDPOPUPCLASS, 0, (LPARAM)&d);
+}
+
+#ifdef _UNICODE
+#define ShowClassPopupT ShowClassPopupW
+#else
+#define ShowClassPopupT ShowClassPopup
+#endif
+
+#endif // __m_popup_h__
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_protocols.h b/plugins/!NotAdopted/WinPopup/sdk/m_protocols.h
new file mode 100644
index 0000000000..d2032db977
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_protocols.h
@@ -0,0 +1,487 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+*/
+
+//this module was created in v0.1.1.0
+
+#ifndef M_PROTOCOLS_H__
+#define M_PROTOCOLS_H__ 1
+
+#include "statusmodes.h"
+
+//call a specific protocol service. See the PS_ constants in m_protosvc.h
+#if MIRANDA_VER < 0x800
+__inline static INT_PTR CallProtoService(const char *szModule,const char *szService,WPARAM wParam,LPARAM lParam)
+{
+ char str[MAXMODULELABELLENGTH];
+ _snprintf(str, sizeof(str), "%s%s", szModule, szService);
+ str[MAXMODULELABELLENGTH-1] = 0;
+ return CallService(str,wParam,lParam);
+}
+#endif
+
+//send a general request through the protocol chain for a contact
+//wParam=0
+//lParam=(LPARAM)(CCSDATA*)&ccs
+//returns the value as documented in the PS_ definition (m_protosvc.h)
+
+typedef struct {
+ HANDLE hContact;
+ const char *szProtoService; //a PS_ constant
+ WPARAM wParam;
+ LPARAM lParam;
+} CCSDATA;
+
+#define MS_PROTO_CALLCONTACTSERVICE "Proto/CallContactService"
+
+#if MIRANDA_VER < 0x800
+__inline static INT_PTR CallContactService(HANDLE hContact,const char *szProtoService,WPARAM wParam,LPARAM lParam)
+{
+ CCSDATA ccs;
+ ccs.hContact=hContact;
+ ccs.szProtoService=szProtoService;
+ ccs.wParam=wParam;
+ ccs.lParam=lParam;
+ return CallService(MS_PROTO_CALLCONTACTSERVICE,0,(LPARAM)&ccs);
+}
+#endif
+
+//a general network 'ack'
+//wParam=0
+//lParam=(LPARAM)(ACKDATA*)&ack
+//Note that just because definitions are here doesn't mean they will be sent.
+//Read the documentation for the function you are calling to see what replies
+//you will receive.
+typedef struct {
+ int cbSize;
+ const char *szModule; //the name of the protocol module which initiated this ack
+ HANDLE hContact;
+ int type; //an ACKTYPE_ constant
+ int result; //an ACKRESULT_ constant
+ HANDLE hProcess; //a caller-defined process code
+ LPARAM lParam; //caller-defined extra info
+} ACKDATA;
+#define ACKTYPE_MESSAGE 0
+#define ACKTYPE_URL 1
+#define ACKTYPE_FILE 2
+#define ACKTYPE_CHAT 3
+#define ACKTYPE_AWAYMSG 4
+#define ACKTYPE_AUTHREQ 5
+#define ACKTYPE_ADDED 6
+#define ACKTYPE_GETINFO 7
+#define ACKTYPE_SETINFO 8
+#define ACKTYPE_LOGIN 9
+#define ACKTYPE_SEARCH 10
+#define ACKTYPE_NEWUSER 11
+#define ACKTYPE_STATUS 12
+#define ACKTYPE_CONTACTS 13 //send/recv of contacts
+#define ACKTYPE_AVATAR 14 //send/recv of avatars from a protocol
+#define ACKTYPE_EMAIL 15 //notify if the unread emails changed
+
+#define ACKRESULT_SUCCESS 0
+#define ACKRESULT_FAILED 1
+
+//'in progress' result codes:
+#define ACKRESULT_CONNECTING 100
+#define ACKRESULT_CONNECTED 101
+#define ACKRESULT_INITIALISING 102
+#define ACKRESULT_SENTREQUEST 103 //waiting for reply...
+#define ACKRESULT_DATA 104 //blob of file data sent/recved, or search result
+#define ACKRESULT_NEXTFILE 105 //file transfer went to next file
+#define ACKRESULT_FILERESUME 106 //a file is about to be received, see PS_FILERESUME
+#define ACKRESULT_DENIED 107 //a file send has been denied
+#define ACKRESULT_STATUS 108 //an ack or a series of acks to do with a task have a status change
+#define ACKRESULT_LISTENING 109 //waiting for connection
+#define ACKRESULT_CONNECTPROXY 110 //connecting to file proxy
+#define ACKRESULT_SEARCHRESULT 111 //result of extended search
+
+#define ME_PROTO_ACK "Proto/Ack"
+
+// v0.3.2+: When result is ACKRESULT_FAILED or ACKRESULT_DENIED, lParam can point to
+// a human readable string with an explanation. For example: "The message was too
+// long to be delivered". If no error message is specified, lParam must be NULL.
+// Right now only explanations from ACKTYPE_MESSAGE is shown.
+
+//when type==ACKTYPE_FILE && (result==ACKRESULT_DATA || result==ACKRESULT_FILERESUME),
+//lParam points to this
+
+#if MIRANDA_VER >= 0x0900
+ #define FNAMECHAR TCHAR
+#else
+ #define FNAMECHAR char
+#endif
+
+#define PFTS_RECEIVING 0
+#define PFTS_SENDING 1
+#define PFTS_UNICODE 2
+#define PFTS_UTF 4
+
+#if defined( _UNICODE )
+ #define PFTS_TCHAR PFTS_UNICODE
+#else
+ #define PFTS_TCHAR 0
+#endif
+
+typedef struct tagPROTOFILETRANSFERSTATUS_V1
+{
+ size_t cbSize;
+ HANDLE hContact;
+ int sending;
+ char **files;
+ int totalFiles;
+ int currentFileNumber;
+ unsigned long totalBytes;
+ unsigned long totalProgress;
+ char *workingDir;
+ char *currentFile;
+ unsigned long currentFileSize;
+ unsigned long currentFileProgress;
+ unsigned long currentFileTime; //as seconds since 1970
+}
+PROTOFILETRANSFERSTATUS_V1;
+
+#if MIRANDA_VER < 0x0900
+
+typedef PROTOFILETRANSFERSTATUS_V1 PROTOFILETRANSFERSTATUS;
+
+#else
+
+typedef struct tagPROTOFILETRANSFERSTATUS
+{
+ size_t cbSize;
+ HANDLE hContact;
+ DWORD flags; // one of PFTS_* constants
+
+ union {
+ char **pszFiles;
+ TCHAR **ptszFiles;
+ WCHAR **pwszFiles;
+ };
+
+ int totalFiles;
+ int currentFileNumber;
+ unsigned __int64 totalBytes;
+ unsigned __int64 totalProgress;
+
+ union {
+ char *szWorkingDir;
+ TCHAR *tszWorkingDir;
+ WCHAR *wszWorkingDir;
+ };
+
+ union {
+ char *szCurrentFile;
+ TCHAR *tszCurrentFile;
+ WCHAR *wszCurrentFile;
+ };
+
+ unsigned __int64 currentFileSize;
+ unsigned __int64 currentFileProgress;
+ unsigned __int64 currentFileTime; //as seconds since 1970
+}
+PROTOFILETRANSFERSTATUS;
+
+#endif
+
+//Enumerate the currently running protocols
+//wParam=(WPARAM)(int*)&numberOfProtocols
+//lParam=(LPARAM)(PROTOCOLDESCRIPTOR***)&ppProtocolDescriptors
+//Returns 0 on success, nonzero on failure
+//Neither wParam nor lParam may be NULL
+//The list returned by this service is the protocol modules currently installed
+//and running. It is not the complete list of all protocols that have ever been
+//installed.
+//IMPORTANT NOTE #1: the list returned is not static, it may be changed in the
+//program's lifetime. Do not use this list in the global context, copy protocols
+//names otherwise.
+//IMPORTANT NOTE #2: in version 0.8 this service is mapped to the MS_PROTO_ENUMACCOUNTS
+//service to provide the compatibility with old plugins (first three members of
+//PROTOACCOUNT are equal to the old PROTOCOLDESCRIPTOR format). If you declare the
+//MIRANDA_VER macro with value greater or equal to 0x800, use MS_PROTO_ENUMPROTOS
+//service instead to obtain the list of running protocols instead of accounts.
+//Note that a protocol module need not be an interface to an Internet server,
+//they can be encryption and loads of other things, too.
+//And yes, before you ask, that is triple indirection. Deal with it.
+//Access members using ppProtocolDescriptors[index]->element
+
+#define PROTOCOLDESCRIPTOR_V3_SIZE (sizeof(size_t)+sizeof(INT_PTR)+sizeof(char*))
+
+ // initializes an empty account
+typedef struct tagPROTO_INTERFACE* ( *pfnInitProto )( const char* szModuleName, const TCHAR* szUserName );
+
+// deallocates an account instance
+typedef int ( *pfnUninitProto )( struct tagPROTO_INTERFACE* );
+
+// removes an account from the database
+typedef int ( *pfnDestroyProto )( struct tagPROTO_INTERFACE* );
+
+typedef struct {
+ size_t cbSize;
+ char *szName; // unique name of the module
+ int type; // module type, see PROTOTYPE_ constants
+
+ // 0.8.0+ additions
+ #if MIRANDA_VER >= 0x800
+ pfnInitProto fnInit; // initializes an empty account
+ pfnUninitProto fnUninit; // deallocates an account instance
+ pfnDestroyProto fnDestroy; // removes an account
+ #endif
+}
+ PROTOCOLDESCRIPTOR;
+
+// v0.3.3+:
+//
+// For recv, it will go from lower to higher, so in this case:
+// check ignore, decrypt (encryption), translate
+//
+// For send, it will go translate, encrypt, ignore(??), send
+//
+// The DB will store higher numbers here, LOWER in the protocol chain, and lower numbers
+// here HIGHER in the protocol chain
+//
+#define PROTOTYPE_IGNORE 50 // added during v0.3.3
+#define PROTOTYPE_PROTOCOL 1000
+#define PROTOTYPE_ENCRYPTION 2000
+#define PROTOTYPE_FILTER 3000
+#define PROTOTYPE_TRANSLATION 4000
+#define PROTOTYPE_OTHER 10000 //avoid using this if at all possible
+#define PROTOTYPE_DISPROTO 20000
+
+#if MIRANDA_VER >= 0x800
+ #define MS_PROTO_ENUMPROTOS "Proto/EnumProtos"
+ #define MS_PROTO_ENUMPROTOCOLS "Proto/EnumAccounts"
+#else
+ #define MS_PROTO_ENUMPROTOCOLS "Proto/EnumProtocols"
+#endif
+
+//determines if a protocol module is loaded or not
+//wParam=0
+//lParam=(LPARAM)(const char*)szName
+//Returns a pointer to the PROTOCOLDESCRIPTOR if the protocol is loaded, or
+//NULL if it isn't.
+#define MS_PROTO_ISPROTOCOLLOADED "Proto/IsProtocolLoaded"
+
+//gets the network-level protocol associated with a contact
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=0
+//Returns a char* pointing to the asciiz name of the protocol or NULL if the
+//contact has no protocol. There is no need to free() it or anything.
+//This is the name of the module that actually accesses the network for that
+//contact.
+#define MS_PROTO_GETCONTACTBASEPROTO "Proto/GetContactBaseProto"
+
+//determines whether the specified contact has the given protocol in its chain
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=(LPARAM)(const char*)szName
+//Returns -1 if it is base protocol, positive number if it is filter and 0 if it doesn't
+#define MS_PROTO_ISPROTOONCONTACT "Proto/IsProtoOnContact"
+
+#define PROTOTYPE_SELFTYPING_OFF 0
+#define PROTOTYPE_SELFTYPING_ON 1
+//This service is for notifying protocols that the user is typing a message v0.3.3+
+//in a message dialog.
+//This is typically sent by a message dialog when a user in the clist is typing.
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=(LPARAM)(int)typing state
+//NOTE: Only protocols should generally call this service
+#define MS_PROTO_SELFISTYPING "Proto/SelfIsTyping"
+
+#define PROTOTYPE_CONTACTTYPING_OFF 0
+#define PROTOTYPE_CONTACTTYPING_INFINITE 2147483647
+//This service is for notifying message dialogs/other plugins of a user typing. v0.3.3+
+//This is typically sent by a protocol when a user in the clist is typing.
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=(LPARAM)(int)time (secs)
+//NOTE: The time in seconds is used to tell a message dialog (or other plugin)
+//how long to display its notification. If time is 0, then notification
+//of typing ends.
+//NOTE: Only protocols should generally call this service
+#define MS_PROTO_CONTACTISTYPING "Proto/ContactIsTyping"
+
+//This hook notifies when a user is typing. If a message dialog supports sending v0.3.3+
+//typing notifications it should hook this event and fire the
+//ProtoService PSS_USERISTYPING to the contacts protocol *after* verifying
+//that the hContact is not NULL and the the user wishes to send notifications
+//to this user (checked visibility, individual typing blocking, etc).
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=(LPARAM)(int)typing state
+#define ME_PROTO_CONTACTISTYPING "Proto/ContactIsTypingEvent"
+
+// -------------- accounts support --------------------- 0.8.0+
+
+typedef struct tagACCOUNT
+{
+ int cbSize; // sizeof this structure
+ char* szModuleName; // unique physical account name (matches database module name)
+ int type; // always equal to PROTOTYPE_PROTOCOL
+ TCHAR* tszAccountName; // user-defined account name
+ char* szProtoName; // physical protocol name
+ int bIsEnabled; // is account enabled?
+ int bIsVisible; // is account visible?
+ int iOrder; // account order in various menus & lists
+ BOOL bOldProto; // old-styled account (one instance per dll)
+ struct tagPROTO_INTERFACE* ppro; // pointer to the underlying object
+
+ HWND hwndAccMgrUI;
+ BOOL bAccMgrUIChanged;
+ BOOL bDynDisabled; // dynamic disable flag, is never written to db
+}
+ PROTOACCOUNT;
+
+//account enumeration service
+//wParam=(WPARAM)(int*)piNumAccounts
+//lParam=(LPARAM)(PROTOACCOUNT**)paAccounts
+#define MS_PROTO_ENUMACCOUNTS "Proto/EnumAccounts"
+
+__inline static INT_PTR ProtoEnumAccounts( int* accNumber, PROTOACCOUNT*** accArray )
+{ return CallService( MS_PROTO_ENUMACCOUNTS, ( WPARAM )accNumber, (LPARAM)accArray );
+}
+
+//retrieves an account's interface by its physical name (database module)
+//wParam=0
+//lParam=(LPARAM)(char*)szAccountName
+//return value = PROTOACCOUNT* or NULL
+#define MS_PROTO_GETACCOUNT "Proto/GetAccount"
+
+__inline static PROTOACCOUNT* ProtoGetAccount( const char* accName )
+{ return (PROTOACCOUNT*)CallService( MS_PROTO_GETACCOUNT, 0, (LPARAM)accName );
+}
+
+//this event is fired when the accounts list gets changed
+//wParam = event type (1 - added, 2 - changed, 3 - deleted, 4 - upgraded, 5 - enabled/disabled)
+//lParam = (LPARAM)(PROTOACCOUNT*) - account being changed
+
+#define PRAC_ADDED 1
+#define PRAC_CHANGED 2
+#define PRAC_REMOVED 3
+#define PRAC_UPGRADED 4
+#define PRAC_CHECKED 5
+
+
+#define ME_PROTO_ACCLISTCHANGED "Proto/AccListChanged"
+
+//displays the Account Manager
+//wParam=0
+//lParam=0
+#define MS_PROTO_SHOWACCMGR "Protos/ShowAccountManager"
+
+//determines if an account is enabled or not
+//wParam = 0
+//lParam = (LPARAM)(PROTOACCOUNT*)
+//Returns 1 if an account is valid and enabled, 0 otherwise
+#define MS_PROTO_ISACCOUNTENABLED "Proto/IsAccountEnabled"
+
+__inline static int IsAccountEnabled( const PROTOACCOUNT* pa )
+{
+#if MIRANDA_VER < 0x0900
+ return pa && (( pa->bIsEnabled && !pa->bDynDisabled ) || pa->bOldProto );
+#else
+ return (int)CallService( MS_PROTO_ISACCOUNTENABLED, 0, (LPARAM)pa );
+#endif
+}
+
+//determines if an account is locked or not
+//wParam = 0
+//lParam = (LPARAM)(char*)szAccountName
+//Returns 1 if an account is locked and not supposed to change status, 0 otherwise
+#define MS_PROTO_ISACCOUNTLOCKED "Proto/IsAccountLocked"
+
+
+//gets the account associated with a contact
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=0
+//Returns a char* pointing to the asciiz name of the protocol or NULL if the
+//contact has no protocol. There is no need to mir_free() it or anything.
+//This is the name of the module that actually accesses the network for that
+//contact.
+#define MS_PROTO_GETCONTACTBASEACCOUNT "Proto/GetContactBaseAccount"
+
+/* -------------- avatar support ---------------------
+
+First a protocol must report it supports PF4_AVATARS via PS_GETCAPS, secondly
+it will return the following acks for certain events, the protocol must use
+ProtoBroadcastAck(), listeners must hook ME_PROTO_ACK, note that lParam = ACKDATA*
+
+*/
+
+/*
+
+ The following ACKs MUST be sent in order of .result via ProtoBroadcastAck()
+
+ .szModule = protocol module
+ .hContact = contact the avatar is for, or 0 if its for the user
+ .type = ACKTYPE_AVATAR
+ .result = ACKRESULT_CONNECTING, ACKRESULT_CONNECTED, ACKRESULT_SENTREQUEST, ACKRESULT_DATA
+ .hProcess = protocol specific
+ .lParam = 0
+
+ Once the transfer is complete the following ACKs MUST be sent by the protocol
+
+ .result = ACKRESULT_SUCCESS or ACKRESULT_FAILED
+ .hProcess = (HANDLE) &PROTO_AVATAR_INFORMATION
+ .lParam = 0;
+
+ Anytime before or during the ack or series of acks ACKRESULT_STATUS maybe sent, this might
+ be sent a long while before anything else happens (or after anything happening) For avatars
+ it allows callers to identify status information to do with the avatar, including the time
+ before background transport has been created, so that you know an avatar will be exchanged
+ sometime in the future.
+
+ When ACKRESULT_STATUS, hProcess is the result code - the value of this is protocol dependent,
+ See protocol documentation to do with avatars for what codes are defined and what they mean.
+
+*/
+
+#define PA_FORMAT_UNKNOWN 0 // the protocol can not determine much about the "bitmap"
+#define PA_FORMAT_PNG 1 // the image is PNG
+#define PA_FORMAT_JPEG 2
+#define PA_FORMAT_ICON 3
+#define PA_FORMAT_BMP 4
+#define PA_FORMAT_GIF 5
+#define PA_FORMAT_SWF 6
+#define PA_FORMAT_XML 7
+
+typedef struct {
+ int cbSize; // sizeof()
+ HANDLE hContact; // this might have to be set by the caller too
+ int format; // PA_FORMAT_*
+ char filename[MAX_PATH]; // full path to filename which contains the avatar
+} PROTO_AVATAR_INFORMATION;
+
+#define GAIF_FORCE 1 // force an update of the avatar if there is none
+
+#define GAIR_SUCCESS 0 // information about the avatar has been returned
+#define GAIR_WAITFOR 1 // you must hook ME_PROTO_ACK and wait for replies about avatar status
+#define GAIR_NOAVATAR 2 // sorry, this contact has no avatars
+
+/*
+ wParam : GAIF_*
+ lParam : (LPARAM) &PROTO_AVATAR_INFORMATION
+ Affect : Make a request to the protocol to return information about a hContact's avatar (or main user)
+ it can return information, tell you there is none, or if forced start requesting an avatar.
+ Note:
+ Version: 0.3.4+ (2004/09/13)
+*/
+#define PS_GETAVATARINFO "/GetAvatarInformation"
+
+
+#endif // M_PROTOCOLS_H
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_protomod.h b/plugins/!NotAdopted/WinPopup/sdk/m_protomod.h
new file mode 100644
index 0000000000..bae8146373
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_protomod.h
@@ -0,0 +1,136 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+*/
+//this module was created in v0.1.1.0
+
+//this header file is for the use of protocol modules only. Other users should
+//use the functions exposed in m_protocols.h and m_protosvc.h
+
+#ifndef M_PROTOMOD_H__
+#define M_PROTOMOD_H__ 1
+
+#include <stdio.h>
+
+#include "m_protocols.h"
+
+//notify the protocol manager that you're around
+//wParam=0
+//lParam=(PROTOCOLDESCRIPTOR*)&descriptor
+//returns 0 on success, nonzero on failure
+//This service must be called in your module's Load() routine.
+//descriptor.type can be a value other than the PROTOTYPE_ constants specified
+//above to provide more precise positioning information for the contact
+//protocol lists. It is strongly recommended that you give values relative to
+//the constants, however, by adding or subtracting small integers (<=100).
+//PROTOTYPE_PROTOCOL modules must not do this. The value must be exact.
+//See MS_PROTO_ENUMPROTOCOLS for more notes.
+#define MS_PROTO_REGISTERMODULE "Proto/RegisterModule"
+
+//adds the specified protocol module to the chain for a contact
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=(LPARAM)(const char*)szName
+//returns 0 on success, nonzero on failure
+//The module is added in the correct position according to the type given when
+//it was registered.
+#define MS_PROTO_ADDTOCONTACT "Proto/AddToContact"
+
+//removes the specified protocol module from the chain for a contact
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=(LPARAM)(const char*)szName
+//returns 0 on success, nonzero on failure
+#define MS_PROTO_REMOVEFROMCONTACT "Proto/RemoveFromContact"
+
+//Create a protocol service
+//Protocol services are called with wParam and lParam as standard if they are
+//to be called with CallProtoService() (as PS_ services are)
+//If they are called with CallContactService() (PSS_ and PSR_ services) then
+//they are called with lParam=(CCSDATA*)&ccs and wParam an opaque internal
+//reference that should be passed unchanged to MS_PROTO_CHAIN*.
+__inline static HANDLE CreateProtoServiceFunction(const char *szModule,const char *szService,MIRANDASERVICE serviceProc)
+{
+ char str[MAXMODULELABELLENGTH];
+ _snprintf(str, sizeof(str), "%s%s", szModule, szService);
+ str[MAXMODULELABELLENGTH-1] = 0;
+ return CreateServiceFunction(str,serviceProc);
+}
+
+//Call the next service in the chain for this send operation
+//wParam=wParam
+//lParam=lParam
+//The return value should be returned immediately
+//wParam and lParam should be passed as the parameters that your service was
+//called with. wParam must remain untouched but lParam is a CCSDATA structure
+//that can be copied and modified if needed.
+//Typically, the last line of any chaining protocol function is
+//return CallService(MS_PROTO_CHAINSEND,wParam,lParam);
+#define MS_PROTO_CHAINSEND "Proto/ChainSend"
+
+//Call the next service in the chain for this receive operation
+//wParam=wParam
+//lParam=lParam
+//The return value should be returned immediately
+//wParam and lParam should be passed as the parameters that your service was
+//called with. wParam must remain untouched but lParam is a CCSDATA structure
+//that can be copied and modified if needed.
+//When being initiated by the network-access protocol module, wParam should be
+//zero.
+//Thread safety: ms_proto_chainrecv is completely thread safe since 0.1.2.0
+//Calls to it are translated to the main thread and passed on from there. The
+//function will not return until all callees have returned, irrepective of
+//differences between threads the functions are in.
+#define MS_PROTO_CHAINRECV "Proto/ChainRecv"
+
+//Broadcast a ME_PROTO_ACK event
+//wParam=0
+//lParam=(LPARAM)(ACKDATA*)&ack
+//returns the return value of the notifyeventhooks() call
+//Thread safety: me_proto_ack is completely thread safe since 0.1.2.0
+//See the notes in core/modules.h under NotifyEventHooks()
+#define MS_PROTO_BROADCASTACK "Proto/BroadcastAck"
+__inline static INT_PTR ProtoBroadcastAck(const char *szModule,HANDLE hContact,int type,int result,HANDLE hProcess,LPARAM lParam)
+{
+ ACKDATA ack={0};
+ ack.cbSize=sizeof(ACKDATA);
+ ack.szModule=szModule; ack.hContact=hContact;
+ ack.type=type; ack.result=result;
+ ack.hProcess=hProcess; ack.lParam=lParam;
+ return CallService(MS_PROTO_BROADCASTACK,0,(LPARAM)&ack);
+}
+
+/* -- Added during 0.3.4 (2004/09/27) development! -----
+*/
+
+/*
+ wParam: (HANDLE)hContact
+ lParam: 0
+ Affect: Given a hContact, return the protocol that is registered for it, or NULL if no such protocol exists,
+ the returned string does not have to be freed and is valid even for multiple threads.
+ Note: Prior to 2004/09/28 this service WAS NOT THREAD SAFE and was slower
+ Note: Prior to 2004/09/28 this service would return NULL for a hContact if the protocol module
+ associated with the hContact was not currently loaded, no such check is performed now.
+ Version: 0.3.4 (2004/09/28)
+*/
+#define MS_PROTODIR_PROTOFROMCONTACT MS_PROTO_GETCONTACTBASEPROTO
+
+#endif // M_PROTOMOD_H__
+
+
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_protosvc.h b/plugins/!NotAdopted/WinPopup/sdk/m_protosvc.h
new file mode 100644
index 0000000000..c314bda3aa
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_protosvc.h
@@ -0,0 +1,775 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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.
+*/
+
+//this module was created in v0.1.1.0
+
+//none of these services should be used on their own (ie using CallService,
+//CreateServiceFunction(), etc), hence the PS_ prefix. Instead use the services
+//exposed in m_protocols.h
+
+#ifndef M_PROTOSVC_H__
+#define M_PROTOSVC_H__ 1
+
+#include "m_protocols.h"
+
+/*************************** NON-CONTACT SERVICES ************************/
+//these should be called with CallProtoService()
+
+//Get the capability flags of the module.
+//wParam=flagNum
+//lParam=0
+//Returns a bitfield corresponding to wParam. See the #defines below
+//Should return 0 for unknown values of flagNum
+//Non-network-access modules should return flags to represent the things they
+//actually actively use, not the values that it is known to pass through
+//correctly
+#define PFLAGNUM_1 1
+#define PF1_IMSEND 0x00000001 //supports IM sending
+#define PF1_IMRECV 0x00000002 //supports IM receiving
+#define PF1_IM (PF1_IMSEND|PF1_IMRECV)
+#define PF1_URLSEND 0x00000004 //supports separate URL sending
+#define PF1_URLRECV 0x00000008 //supports separate URL receiving
+#define PF1_URL (PF1_URLSEND|PF1_URLRECV)
+#define PF1_FILESEND 0x00000010 //supports file sending
+#define PF1_FILERECV 0x00000020 //supports file receiving
+#define PF1_FILE (PF1_FILESEND|PF1_FILERECV)
+#define PF1_MODEMSGSEND 0x00000040 //supports broadcasting away messages
+#define PF1_MODEMSGRECV 0x00000080 //supports reading others' away messages
+#define PF1_MODEMSG (PF1_MODEMSGSEND|PF1_MODEMSGRECV)
+#define PF1_SERVERCLIST 0x00000100 //contact lists are stored on the server, not locally. See notes below
+#define PF1_AUTHREQ 0x00000200 //will get authorisation requests for some or all contacts
+#define PF1_ADDED 0x00000400 //will get 'you were added' notifications
+#define PF1_VISLIST 0x00000800 //has an invisible list
+#define PF1_INVISLIST 0x00001000 //has a visible list for when in invisible mode
+#define PF1_INDIVSTATUS 0x00002000 //supports setting different status modes to each contact
+#define PF1_EXTENSIBLE 0x00004000 //the protocol is extensible and supports plugin-defined messages
+#define PF1_PEER2PEER 0x00008000 //supports direct (not server mediated) communication between clients
+#define PF1_NEWUSER 0x00010000 //supports creation of new user IDs
+#define PF1_CHAT 0x00020000 //has a realtime chat capability
+#define PF1_INDIVMODEMSG 0x00040000 //supports replying to a mode message request with different text depending on the contact requesting
+#define PF1_BASICSEARCH 0x00080000 //supports a basic user searching facility
+#define PF1_EXTSEARCH 0x00100000 //supports one or more protocol-specific extended search schemes
+#define PF1_CANRENAMEFILE 0x00200000 //supports renaming of incoming files as they are transferred
+#define PF1_FILERESUME 0x00400000 //can resume broken file transfers, see PS_FILERESUME below
+#define PF1_ADDSEARCHRES 0x00800000 //can add search results to the contact list
+#define PF1_CONTACTSEND 0x01000000 //can send contacts to other users
+#define PF1_CONTACTRECV 0x02000000 //can receive contacts from other users
+#define PF1_CONTACT (PF1_CONTACTSEND|PF1_CONTACTRECV)
+#define PF1_CHANGEINFO 0x04000000 //can change our user information stored on server
+#define PF1_SEARCHBYEMAIL 0x08000000 //supports a search by e-mail feature
+#define PF1_USERIDISEMAIL 0x10000000 //set if the uniquely identifying field of the network is the e-mail address
+#define PF1_SEARCHBYNAME 0x20000000 //supports searching by nick/first/last names
+#define PF1_EXTSEARCHUI 0x40000000 //has a dialog box to allow searching all the possible fields
+#define PF1_NUMERICUSERID 0x80000000 //the unique user IDs for this protocol are numeric
+
+#define PFLAGNUM_2 2 //the status modes that the protocol supports
+#define PF2_ONLINE 0x00000001 //an unadorned online mode
+#define PF2_INVISIBLE 0x00000002
+#define PF2_SHORTAWAY 0x00000004 //Away on ICQ, BRB on MSN
+#define PF2_LONGAWAY 0x00000008 //NA on ICQ, Away on MSN
+#define PF2_LIGHTDND 0x00000010 //Occupied on ICQ, Busy on MSN
+#define PF2_HEAVYDND 0x00000020 //DND on ICQ
+#define PF2_FREECHAT 0x00000040
+#define PF2_OUTTOLUNCH 0x00000080
+#define PF2_ONTHEPHONE 0x00000100
+#define PF2_IDLE 0x00000200 //added during 0.3.4 (2004/09/13)
+
+//the status modes that the protocol supports
+//away-style messages for. Uses the PF2_ flags.
+// PFLAGNUM_3 is implemented by protocol services that support away messages
+// there may be no support and 0 will be returned, if there is
+// support it will consist of a set of PF2_* bits
+#define PFLAGNUM_3 3
+
+// given a status will return what bit flags to test for
+static __inline unsigned long Proto_Status2Flag(int status)
+{
+ switch(status) {
+ case ID_STATUS_ONLINE: return PF2_ONLINE;
+ case ID_STATUS_OFFLINE: return 0;
+ case ID_STATUS_INVISIBLE: return PF2_INVISIBLE;
+ case ID_STATUS_OUTTOLUNCH: return PF2_OUTTOLUNCH;
+ case ID_STATUS_ONTHEPHONE: return PF2_ONTHEPHONE;
+ case ID_STATUS_AWAY: return PF2_SHORTAWAY;
+ case ID_STATUS_NA: return PF2_LONGAWAY;
+ case ID_STATUS_OCCUPIED: return PF2_LIGHTDND;
+ case ID_STATUS_DND: return PF2_HEAVYDND;
+ case ID_STATUS_FREECHAT: return PF2_FREECHAT;
+ case ID_STATUS_IDLE: return PF2_IDLE;
+ }
+ return 0;
+}
+
+#define PFLAGNUM_4 4 //misc options
+#define PF4_FORCEAUTH 0x00000001 // forces auth requests to be sent when adding users
+#define PF4_FORCEADDED 0x00000002 // forces "you were added" requests to be sent
+#define PF4_NOCUSTOMAUTH 0x00000004 // protocol doesn't support custom auth text (doesn't show auth text box)
+#define PF4_SUPPORTTYPING 0x00000008 // protocol supports user is typing messages v0.3.3+
+#define PF4_SUPPORTIDLE 0x00000010 // protocol understands idle, added during v0.3.4+ (2004/09/13)
+#define PF4_AVATARS 0x00000020 // protocol has avatar support, added during v0.3.4 (2004/09/13)
+#define PF4_OFFLINEFILES 0x00000040 // protocols supports sending files to offline users (v0.5.2)
+#define PF4_IMSENDUTF 0x00000080 // protocol is able to process messages in utf-8 (v.0.7.0+)
+#define PF4_IMSENDOFFLINE 0x00000100 // protocol supports sending offline messages (v0.8.0+)
+#define PF4_INFOSETTINGSVC 0x00000200 // protocol supports user info translation services (v0.8.0+)
+#define PF4_NOAUTHDENYREASON 0x00000400 // protocol doesn't support authorization deny reason (v0.9.0+)
+
+#define PFLAG_UNIQUEIDTEXT 100 //returns a static buffer of text describing the unique field by which this protocol identifies users (already translated), or NULL
+
+#define PFLAG_MAXCONTACTSPERPACKET 200 //v0.1.2.2+: returns the maximum number of contacts which can be sent in a single PSS_CONTACTS, lParam=(LPARAM)hContact.
+
+#define PFLAG_UNIQUEIDSETTING 300 // returns the setting name of where the unique id is stored
+
+#define PFLAG_MAXLENOFMESSAGE 400 // v0.3.2+: return the maximum length of an instant message, lParam=(LPARAM)hContact
+
+/*
+
+ A protocol might not support this cap, it allows a protocol to say that PFLAGNUM_2 is for
+ statuses contacts supports, and that PFLAGNUM_5 is for statuses a protocol can SET TO ITSELF,
+ if this is not replied to, then PFLAGNUM_2 is alone in telling you which statuses a protocol
+ can set to and what statuses a contact can set to as well.
+
+ E.g. A protocol might report 'wireless' users but a login of the protocol from Miranda can
+ not set itself to 'wireless' so PFLAGNUM_2 would return PF2_ONTHEPHONE and PFLAGNUM_5 would
+ return PF2_ONTHEPHONE as well, this means "I will get contacts who are on the phone but you can
+ not set on the phone" and so on.
+
+ Do note that the reply here is a NEGATION of bitflags reported for PFLAGNUM_2, e.g. returning
+ PF2_ONTHEPHONE for PFLAGNUM_2 and returning the same for PFLAGNUM_5 says that you DO NOT SUPPORT
+ PF2_ONTHEPHONE for the user to PS_SETSTATUS to, but you will expect other contacts to have
+ that status, e.g. you can get onthephone for users but can't go online with onthephone.
+
+ The same PF2_* status flags are used in the reply.
+
+Added during 0.3.4 (2004/09/14)
+*/
+#define PFLAGNUM_5 5
+
+/* Deleting contacts from protocols that store the contact list on the server:
+If a contact is deleted while the protocol is online, it is expected that the
+protocol will have hooked me_db_contact_deleted and take the appropriate
+action by itself.
+If a contact is deleted while the protocol is offline, the contact list will
+display a message to the user about the problem, and set the byte setting
+"CList"/"Delete" to 1. Each time such a protocol changes status from offline
+or connecting to online the contact list will check for contacts with this
+flag set and delete them at that time. Your hook for me_db_contact_deleted
+will pick this up and everything will be good.
+*/
+#define PS_GETCAPS "/GetCaps"
+
+//Get a human-readable name for the protocol
+//wParam=cchName
+//lParam=(LPARAM)(char*)szName
+//Returns 0 on success, nonzero on failure
+//cchName is the number of characters in the buffer szName
+//This should be translated before being returned
+//Some example strings are:
+//"ICQ", "AIM", "RSA-1024 Encryption"
+#define PS_GETNAME "/GetName"
+
+//Loads one of the protocol-specific icons
+//wParam=whichIcon
+//lParam=0
+//Returns the HICON, or NULL on failure
+//The returned HICON must be DestroyIcon()ed.
+//The UI should overlay the online icon with a further UI-specified icon to
+//represent the exact status mode.
+#define PLI_PROTOCOL 1 //An icon representing the protocol (eg the multicoloured flower for ICQ)
+#define PLI_ONLINE 2 //Online state icon for that protocol (eg green flower for ICQ)
+#define PLI_OFFLINE 3 //Offline state icon for that protocol (eg red flower for ICQ)
+#define PLIF_LARGE 0 //OR with one of the above to get the large (32x32 by default) icon
+#define PLIF_SMALL 0x10000 //OR with one of the above to get the small (16x16 by default) icon
+#define PLIF_ICOLIB 0x20000 //the returned HICON is managed by IcoLib, DO NOT DestroyIcon() it
+#define PLIF_ICOLIBHANDLE 0x40000 //the function will return IcoLib handle not HICON
+#define PS_LOADICON "/LoadIcon"
+
+//Change the protocol's status mode
+//wParam=newMode, from ui/contactlist/statusmodes.h
+//lParam=0
+//returns 0 on success, nonzero on failure
+//Will send an ack with:
+//type=ACKTYPE_STATUS, result=ACKRESULT_SUCCESS, hProcess=(HANDLE)previousMode, lParam=newMode
+//when the change completes. This ack is sent for all changes, not just ones
+//caused by calling this function.
+//Note that newMode can be ID_STATUS_CONNECTING<=newMode<ID_STATUS_CONNECTING+
+//MAX_CONNECT_RETRIES to signify that it's connecting and it's the nth retry.
+//Protocols are initially always in offline mode.
+//Non-network-level protocol modules do not have the concept of a status and
+//should leave this service unimplemented
+//If a protocol doesn't support the specific status mode, it should pick the
+//closest one that it does support, and change to that.
+//If the new mode requires that the protocol switch from offline to online then
+//it will do so, but errors will be reported in the form of an additional ack:
+//type=ACKTYPE_LOGIN, result=ACKRESULT_FAILURE, hProcess=NULL, lParam=LOGINERR_
+// (added during 0.3.4.3) the protocol will send LOGINERR_OTHERLOCATION if the login
+// was disconnected because of a login at another location
+#define LOGINERR_WRONGPASSWORD 1
+#define LOGINERR_NONETWORK 2
+#define LOGINERR_PROXYFAILURE 3
+#define LOGINERR_BADUSERID 4
+#define LOGINERR_NOSERVER 5
+#define LOGINERR_TIMEOUT 6
+#define LOGINERR_WRONGPROTOCOL 7
+#define LOGINERR_OTHERLOCATION 8
+//protocols may define more error codes starting at 1000
+#define PS_SETSTATUS "/SetStatus"
+
+//Sets the status-mode specific message for yourself
+//wParam=status mode
+//lParam=(LPARAM)(const char*)szMessage
+//Returns 0 on success, nonzero on failure
+//Note that this service will not be available unless PF1_MODEMSGSEND is set
+//and PF1_INDIVMODEMSG is *not* set.
+//If PF1_INDIVMODEMSG is set, then see PSS_AWAYMSG for details of
+//the operation of away messages
+//Protocol modules must support szMessage=NULL. It may either mean to use an
+//empty message, or (preferably) to not reply at all to any requests
+#define PS_SETAWAYMSG "/SetAwayMsg"
+
+//Get the status mode that a protocol is currently in
+//wParam=lParam=0
+//Returns the status mode
+//Non-network-level protocol modules do not have the concept of a status and
+//should leave this service unimplemented
+#define PS_GETSTATUS "/GetStatus"
+
+//Allow somebody to add us to their contact list
+//wParam=(WPARAM)(HANDLE)hDbEvent
+//lParam=0
+//Returns 0 on success, nonzero on failure
+//Auth requests come in the form of an event added to the database for the NULL
+//user. The form is:
+//DWORD protocolSpecific
+//ASCIIZ nick, firstName, lastName, e-mail, requestReason
+//hDbEvent must be the handle of such an event
+//One or more fields may be empty if the protocol doesn't support them
+#define PS_AUTHALLOW "/Authorize"
+
+//Deny an authorisation request
+//wParam=(WPARAM)(HANDLE)hDbEvent
+//lParam=(LPARAM)(const TCHAR*)szReason
+//Returns 0 on success, nonzero on failure
+//Protocol modules must be able to cope with szReason=NULL
+#define PS_AUTHDENY "/AuthDeny"
+
+// Send a "You were added" event
+// wParam=lParam=0
+// Returns 0 on success, nonzero on failure
+#define PSS_ADDED "/YouWereAdded"
+
+//Create account manager UI form
+//wParam=0
+//lParam=(LPARAM)(HWND)hwndAccMgr
+//Returns handle on newly created form.
+//Size for best fit is 186x134 DLUs, please avoid groupboxes
+//paddind and advanced options. This should provide minimal setup
+//for initial connect.
+#define PS_CREATEACCMGRUI "/CreateAccMgrUI"
+
+//Send a basic search request
+//wParam=0
+//lParam=(LPARAM)(const char*)szId
+//Returns a handle for the search, or zero on failure
+//All protocols identify users uniquely by a single field. This service will
+//search by that field.
+//Note that if users are identified by an integer (eg ICQ) szId should be a
+//string containing that integer, not the integer itself.
+//All search replies (even protocol-specific extended searches) are replied by
+//means of a series of acks:
+//result acks, one of more of:
+//type=ACKTYPE_SEARCH, result=ACKRESULT_DATA, lParam=(LPARAM)(PROTOSEARCHRESULT*)&psr
+//ending ack:
+//type=ACKTYPE_SEARCH, result=ACKRESULT_SUCCESS, lParam=0
+//Note that the pointers in the structure are not guaranteed to be valid after
+//the ack is complete.
+typedef struct {
+ int cbSize;
+ char *nick;
+ char *firstName;
+ char *lastName;
+ char *email;
+ char reserved[16];
+ //Protocols may extend this structure with extra members at will and supply
+ //a larger cbSize to reflect the new information, but they must not change
+ //any elements above this comment
+ //The 'reserved' field is part of the basic structure, not space to
+ //overwrite with protocol-specific information.
+ //If modules do this, they should take steps to ensure that information
+ //they put there will be retained by anyone trying to save this structure.
+} PROTOSEARCHRESULT;
+#define PS_BASICSEARCH "/BasicSearch"
+
+//Search for users by e-mail address v0.1.2.1+
+//wParam=0
+//lParam=(LPARAM)(char*)szEmail
+//Returns a HANDLE to the search, or NULL on failure
+//Results are returned as for PS_BASICSEARCH.
+//This function is only available if the PF1_SEARCHBYEMAIL capability is set
+//If the PF1_USERIDISEMAIL capability is set then this function and
+//PS_BASICSEARCH should have the same result (and it's best if they are the
+//same function).
+#define PS_SEARCHBYEMAIL "/SearchByEmail"
+
+//Search for users by name v0.1.2.1+
+//wParam=0
+//lParam=(LPARAM)(PROTOSEARCHBYNAME*)&psbn
+//Returns a HANDLE to the search, or NULL on failure
+//Results are returned as for PS_BASICSEARCH.
+//This function is only available if the PF1_SEARCHBYNAME capability is set
+typedef struct {
+ char *pszNick;
+ char *pszFirstName;
+ char *pszLastName;
+} PROTOSEARCHBYNAME;
+#define PS_SEARCHBYNAME "/SearchByName"
+
+//Create the advanced search dialog box v0.1.2.1+
+//wParam=0
+//lParam=(HWND)hwndOwner
+//Returns a HWND, or NULL on failure
+//This function is only available if the PF1_EXTSEARCHUI capability is set
+//Advanced search is very protocol-specific so it is left to the protocol
+//itself to supply a dialog containing the options. This dialog should not
+//have a title bar and contain only search fields. The rest of the UI is
+//supplied by Miranda.
+//The dialog should be created with CreateDialog() or its kin and still be
+//hidden when this function returns.
+//The dialog will be destroyed when the find/add dialog is closed.
+#define PS_CREATEADVSEARCHUI "/CreateAdvSearchUI"
+
+//Search using the advanced search dialog v0.1.2.1+
+//wParam=0
+//lParam=(LPARAM)(HWND)hwndAdvancedSearchDlg
+//Returns a HANDLE to the search, or NULL on failure
+//Results are returned as for PS_BASICSEARCH.
+//This function is only available if the PF1_EXTSEARCHUI capability is set
+#define PS_SEARCHBYADVANCED "/SearchByAdvanced"
+
+typedef struct {
+ size_t nSize;
+ int nFieldCount;
+ TCHAR ** pszFields;
+ PROTOSEARCHRESULT psr;
+} CUSTOMSEARCHRESULTS;
+
+//Adds a search result to the contact list
+//wParam=flags
+//lParam=(LPARAM)(PROTOSEARCHRESULT*)&psr
+//Returns a HANDLE to the new contact, or NULL on failure
+//psr must be a result returned by a search function, since the extended
+//information past the end of the official structure may contain important
+//data required by the protocol.
+//The protocol library should not allow duplicate contacts to be added, but if
+//such a request is received it should return the original hContact, and do the
+//appropriate thing with the temporary flag (ie newflag=(oldflag&thisflag))
+#define PALF_TEMPORARY 1 //add the contact temporarily and invisibly, just to get user info or something
+#define PS_ADDTOLIST "/AddToList"
+
+//Adds a contact to the contact list given an auth, added or contacts event
+//wParam=MAKEWPARAM(flags,iContact)
+//lParam=(LPARAM)(HANDLE)hDbEvent
+//Returns a HANDLE to the new contact, or NULL on failure
+//hDbEvent must be either EVENTTYPE_AUTHREQ or EVENTTYPE_ADDED
+//flags are the same as for PS_ADDTOLIST.
+//iContact is only used for contacts events. It is the 0-based index of the
+//contact in the event to add. There is no way to add two or more contacts at
+//once, you should just do lots of calls.
+#define PS_ADDTOLISTBYEVENT "/AddToListByEvent"
+
+//Changes our user details as stored on the server v0.1.2.0+
+//wParam=infoType
+//lParam=(LPARAM)(void*)pInfoData
+//Returns a HANDLE to the change request, or NULL on failure
+//The details information that is stored on the server is very protocol-
+//specific, so this service just supplies an outline for protocols to use.
+//See protocol-specific documentation for what infoTypes are available and
+//what pInfoData should be for each infoType.
+//Sends an ack type=ACKTYPE_SETINFO, result=ACKRESULT_SUCCESS/FAILURE,
+//lParam=0 on completion.
+#define PS_CHANGEINFO "/ChangeInfo"
+
+//Informs the protocol of the users chosen resume behaviour v0.1.2.2+
+//wParam=(WPARAM)(HANDLE)hFileTransfer
+//lParam=(LPARAM)(PROTOFILERESUME*)&pfr
+//Returns 0 on success, nonzero on failure
+//If the protocol supports file resume (PF1_FILERESUME) then before each
+//individual file receive begins (note: not just each file that already exists)
+//it will broadcast an ack with type=ACKTYPE_FILE, result=ACKRESULT_RESUME,
+//hProcess=hFileTransfer, lParam=(LPARAM)(PROTOFILETRANSFERSTATUS*)&fts. If the
+//UI processes this ack it must return nonzero from its hook. If all the hooks
+//complete without returning nonzero then the protocol will assume that no
+//resume UI was available and will continue the file receive with a default
+//behaviour (overwrite for ICQ). If a hook does return nonzero then that UI
+//must call this function, PS_FILERESUME, at some point. When the protocol
+//module receives this call it will proceed with the file receive using the
+//given information.
+//Having said that PS_FILERESUME must be called, it is also acceptable to call
+//PSS_FILECANCEL to completely abort the transfer instead.
+#define FILERESUME_OVERWRITE 1
+#define FILERESUME_RESUME 2
+#define FILERESUME_RENAME 3
+#define FILERESUME_SKIP 4
+typedef struct {
+ int action; //a FILERESUME_ flag
+ const FNAMECHAR *szFilename; //full path. Only valid if action==FILERESUME_RENAME
+} PROTOFILERESUME;
+#define PS_FILERESUME "/FileResume"
+
+//Asks a protocol to join the chatroom from contact v0.8.0+
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=(LPARAM)0
+//Returns 0 on success, nonzero on failure
+#define PS_JOINCHAT "/JoinChat"
+
+//Asks a protocol to leave the chatroom from contact v0.8.0+
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=(LPARAM)0
+//Returns 0 on success, nonzero on failure
+#define PS_LEAVECHAT "/LeaveChat"
+
+//Asks a protocol to read contact information and translate them (for a lookup fields) v0.8.0+
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=(LPARAM)(DBCONTACTGETSETTING*)&dbcgs
+//The flag PF4_INFOSETTINGSVC indicates that a protocol supports this. Basically it should
+//do the same as MS_DB_CONTACT_GETSETTING_STR, except that for a lookup settings (e.g. Language)
+//it returns string instead of an ID stored in the database.
+//Caller is responsible for free()ing dbcgs.pValue->pszVal and pbVal if they are
+//returned. You must **NOT** do this from your version of free() you have to use Miranda's free()
+//you can get a function pointer to Miranda's free() via MS_SYSTEM_GET_MMI, see m_system.h
+//Returns 0 on success or nonzero if the setting name was not found or hContact
+//was invalid
+#define PS_GETINFOSETTING "/GetInfoSetting"
+
+// Asks protocol for the status message for a status
+// wParam=(WORD) 0 for current status or a status id
+// lParam=SGMA_xxx
+// Returns status msg or NULL if there is none. The protocol have to handle only the current
+// status. Handling messages for other statuses is optional.
+// Remember to mir_free the return value
+
+#define SGMA_UNICODE 1 // return Unicode status
+#if defined( _UNICODE )
+ #define SGMA_TCHAR SGMA_UNICODE
+#else
+ #define SGMA_TCHAR 0
+#endif
+
+#define PS_GETMYAWAYMSG "/GetMyAwayMsg"
+
+// Set nickname for the user
+// wParam=(WPARAM)SMNN_xxx
+// lParam=(LPARAM)(char *) The new nickname for the user
+// return=0 for success
+
+#define SMNN_UNICODE 1 // return Unicode status
+#if defined( _UNICODE )
+ #define SMNN_TCHAR SMNN_UNICODE
+#else
+ #define SMNN_TCHAR 0
+#endif
+
+#define PS_SETMYNICKNAME "/SetNickname"
+
+// Get the max allowed length for the user nickname
+// Optional, default value is 1024
+// wParam=(WPARAM)0
+// lParam=(LPARAM)0
+// return= <=0 for error, >0 the max length of the nick
+#define PS_GETMYNICKNAMEMAXLENGTH "/GetMyNicknameMaxLength"
+
+// WAYD = What are you doing
+#define WAYD_UNICODE 1 // return Unicode texts
+#if defined( _UNICODE )
+ #define WAYD_TCHAR WAYD_UNICODE
+#else
+ #define WAYD_TCHAR 0
+#endif
+
+// Get the WAYD message for the user
+// wParam=(WPARAM)WAYD_xxx
+// lParam=(LPARAM)0
+// Returns the text or NULL if there is none. Remember to mir_free the return value.
+#define PS_GETMYWAYD "/GetMyWAYD"
+
+// Sets the WAYD message for the user
+// wParam=(WPARAM)WAYD_xxx
+// lParam=(LPARAM)(WCHAR * or char *)The message
+// Returns 0 on success, nonzero on failure
+#define PS_SETMYWAYD "/SetMyWAYD"
+
+// Get the max allowed length that a WAYD message can have
+// Optional, default value is 1024
+// wParam=(WPARAM)0
+// lParam=(LPARAM)0
+// Returns the max length
+#define PS_GETMYWAYDMAXLENGTH "/GetMyWAYDMaxLength"
+
+/****************************** SENDING SERVICES *************************/
+//these should be called with CallContactService()
+
+//Updates a contact's details from the server
+//wParam=flags
+//lParam=0
+//returns 0 on success, nonzero on failure
+//Will update all the information in the database, and then send acks with
+//type=ACKTYPE_GETINFO, result=ACKRESULT_SUCCESS, hProcess=(HANDLE)(int)nReplies, lParam=thisReply
+//Since some protocols do not allow the library to tell when it has got all
+//the information so it can send a final ack, one ack will be sent after each
+//chunk of data has been received. nReplies contains the number of distinct
+//acks that will be sent to get all the information, thisReply is the zero-
+//based index of this ack. When thisReply=0 the 'minimal' information has just
+//been received. All other numbering is arbitrary.
+#define SGIF_MINIMAL 1 //get only the most basic information. This should
+ //contain at least a Nick and e-mail.
+#define SGIF_ONOPEN 2 //set when the User Info form is being opened
+#define PSS_GETINFO "/GetInfo"
+
+//Send an instant message
+//wParam=flags
+//lParam=(LPARAM)(const char*)szMessage
+//returns a hProcess corresponding to the one in the ack event.
+//Will send an ack when the message actually gets sent
+//type=ACKTYPE_MESSAGE, result=success/failure, (char*)lParam=error message or NULL.
+//Protocols modules are free to define flags starting at 0x10000
+//The event will *not* be added to the database automatically.
+#define PSS_MESSAGE "/SendMsg"
+
+//Send an URL message
+//wParam=flags
+//lParam=(LPARAM)(const char*)szMessage
+//returns a hProcess corresponding to the one in the ack event.
+//szMessage should be encoded as the URL followed by the description, the
+//separator being a single nul (\0). If there is no description, do not forget
+//to end the URL with two nuls.
+//Will send an ack when the message actually gets sent
+//type=ACKTYPE_URL, result=success/failure, (char*)lParam=error message or NULL.
+//Protocols modules are free to define flags starting at 0x10000
+//The event will *not* be added to the database automatically.
+#define PSS_URL "/SendUrl"
+
+//Send a set of contacts
+//wParam=MAKEWPARAM(flags,nContacts)
+//lParam=(LPARAM)(HANDLE*)hContactsList
+//returns a hProcess corresponding to the one in the ack event, NULL on
+//failure.
+//hContactsList is an array of nContacts handles to contacts. If this array
+//includes one or more contacts that cannot be transferred using this protocol
+//the function will fail.
+//Will send an ack when the contacts actually get sent
+//type=ACKTYPE_CONTACTS, result=success/failure, (char*)lParam=error message or NULL.
+//No flags have yet been defined.
+//The event will *not* be added to the database automatically.
+#define PSS_CONTACTS "/SendContacts"
+
+//Send a request to retrieve somebody's mode message.
+//wParam=lParam=0
+//returns an hProcess identifying the request, or 0 on failure
+//This function will fail if the contact's current status mode doesn't have an
+//associated message
+//The reply will be in the form of an ack:
+//type=ACKTYPE_AWAYMSG, result=success/failure, lParam=(const char*)szMessage
+#define PSS_GETAWAYMSG "/GetAwayMsg"
+
+//Sends an away message reply to a user
+//wParam=(WPARAM)(HANDLE)hProcess (of ack)
+//lParam=(LPARAM)(const char*)szMessage
+//Returns 0 on success, nonzero on failure
+//This function must only be used if the protocol has PF1_MODEMSGSEND and
+//PF1_INDIVMODEMSG set. Otherwise, PS_SETAWAYMESSAGE should be used.
+//This function must only be called in response to an ack that a user has
+//requested our away message. The ack is sent as:
+//type=ACKTYPE_AWAYMSG, result=ACKRESULT_SENTREQUEST, lParam=0
+#define PSS_AWAYMSG "/SendAwayMsg"
+
+//Allows a file transfer to begin
+//wParam=(WPARAM)(HANDLE)hTransfer
+//lParam=(LPARAM)(const char*)szPath
+//Returns a new handle to the transfer, to be used from now on
+//If szPath does not point to a directory then:
+// if a single file is being transferred and the protocol supports file
+// renaming (PF1_CANRENAMEFILE) then the file is given this name
+// otherwise the filename is removed and the file(s) are placed in the
+// resulting directory
+//File transfers are marked by an EVENTTYPE_FILE added to the database. The
+//format is:
+//DWORD hTransfer
+//ASCIIZ filename(s), description
+#define PSS_FILEALLOW "/FileAllow"
+
+//Refuses a file transfer request
+//wParam=(WPARAM)(HANDLE)hTransfer
+//lParam=(LPARAM)(const char*)szReason
+//Returns 0 on success, nonzero on failure
+#define PSS_FILEDENY "/FileDeny"
+
+//Cancel an in-progress file transfer
+//wParam=(WPARAM)(HANDLE)hTransfer
+//lParam=0
+//Returns 0 on success, nonzero on failure
+#define PSS_FILECANCEL "/FileCancel"
+
+//Initiate a file send
+//wParam=(WPARAM)(const char*)szDescription
+//lParam=(LPARAM)(char **)ppszFiles
+//Returns a transfer handle on success, NULL on failure
+//All notification is done through acks, with type=ACKTYPE_FILE
+//If result=ACKRESULT_FAILED then lParam=(LPARAM)(const char*)szReason
+#define PSS_FILE "/SendFile"
+
+//Set the status mode you will appear in to a user
+//wParam=statusMode
+//lParam=0
+//Returns 0 on success, nonzero on failure
+//Set statusMode=0 to revert to normal behaviour for the contact
+//ID_STATUS_ONLINE is possible iff PF1_VISLIST
+//ID_STATUS_OFFLINE is possible iff PF1_INVISLIST
+//Other modes are possible iff PF1_INDIVSTATUS
+#define PSS_SETAPPARENTMODE "/SetApparentMode"
+
+// Send an auth request
+// wParam=0
+// lParam=(const TCHAR *)szMessage
+// Returns 0 on success, nonzero on failure
+#define PSS_AUTHREQUEST "/AuthRequest"
+
+// Send "User is Typing" (user is typing a message to the user) v0.3.3+
+// wParam=(WPARAM)(HANDLE)hContact
+// lParam=(LPARAM)(int)typing type - see PROTOTYPE_SELFTYPING_X defines in m_protocols.h
+#define PSS_USERISTYPING "/UserIsTyping"
+
+/**************************** RECEIVING SERVICES *************************/
+//These services are not for calling by general modules. They serve a specific
+//role in communicating through protocol module chains before the whole app is
+//notified that an event has occurred.
+//When the respective event is received over the network, the network-level
+//protocol module initiates the chain by calling MS_PROTO_CHAINRECV with wParam
+//set to zero and lParam pointing to the CCSDATA structure.
+//Protocol modules should continue the message up the chain by calling
+//MS_PROTO_CHAINRECV with the same wParam they received and a modified (or not)
+//lParam (CCSDATA). If they do not do this and return nonzero then all further
+//processing for the event will cease and the event will be ignored.
+//Once all non-network protocol modules have been called (in reverse order),
+//the network protocol module will be called so that it can finish its
+//processing using the modified information.
+//This final processing should consist of the protocol module adding the
+//event to the database, and it is the ME_DB_EVENT_ADDED event that people who
+//just want to know the final result should hook.
+//In all cases, the database should store what the user read/wrote.
+
+//An instant message has been received
+//wParam=0
+//lParam=(LPARAM)(PROTORECVEVENT*)&pre
+//DB event: EVENTTYPE_MESSAGE, blob contains szMessage without 0 terminator
+//Returns a handle to the newly added event, or NULL on failure
+typedef struct {
+ DWORD flags;
+ DWORD timestamp; //unix time
+ char *szMessage;
+ LPARAM lParam; //extra space for the network level protocol module
+} PROTORECVEVENT;
+#define PREF_CREATEREAD 1 //create the database event with the 'read' flag set
+#define PREF_UNICODE 2
+#define PREF_RTL 4 // 0.5+ addition: support for right-to-left messages
+#define PREF_UTF 8 // message is in utf-8 (0.7.0+)
+
+#if defined( _UNICODE )
+ #define PREF_TCHAR PREF_UNICODE
+#else
+ #define PREF_TCHAR 0
+#endif
+
+#define PSR_MESSAGE "/RecvMessage"
+
+#define MS_PROTO_RECVMSG "Proto/RecvMessage"
+
+//An URL has been received
+//wParam=0
+//lParam=(LPARAM)(PROTORECVEVENT*)&pre
+//szMessage is encoded the same as for PSS_URL
+//DB event: EVENTTYPE_URL, blob contains szMessage without 0 terminator
+#define PSR_URL "/RecvUrl"
+
+//Contacts have been received
+//wParam=0
+//lParam=(LPARAM)(PROTORECVEVENT*)&pre
+//pre.szMessage is actually a (PROTOSEARCHRESULT**) list.
+//pre.lParam is the number of contacts in that list.
+//pre.flags can contain PREF_UTF defining the strings as utf-8 encoded (0.7.0+)
+//PS_ADDTOLIST can be used to add the contacts to the contact list.
+#define PSR_CONTACTS "/RecvContacts"
+
+/* contacts database event format (EVENTTYPE_CONTACTS)
+repeat {
+ ASCIIZ userNick
+ ASCIIZ userId
+}
+userNick should be a human-readable description of the user. It need not
+be the nick, or even confined to displaying just one type of
+information. The dbe.flags can contain DBEF_UTF defining userNick as utf-8
+encoded.
+userId should be a machine-readable representation of the unique
+protocol identifying field of the user. Because of the need to be
+zero-terminated, binary data should be converted to text.
+Use PS_ADDTOLISTBYEVENT to add the contacts from one of these to the list.
+*/
+
+//File(s) have been received (0.9.x)
+//wParam=0
+//lParam=(LPARAM)(PROTORECVFILE*)&prf
+typedef struct {
+ DWORD flags;
+ DWORD timestamp; //unix time
+ TCHAR *tszDescription;
+ int fileCount;
+ TCHAR **ptszFiles;
+ LPARAM lParam; //extra space for the network level protocol module
+} PROTORECVFILET;
+
+#define MS_PROTO_RECVFILET "Proto/RecvFileT"
+
+#define PSR_FILE "/RecvFile"
+
+// left for compatibility with the old Miranda versions.
+
+typedef struct {
+ DWORD flags;
+ DWORD timestamp; //unix time
+ char *szDescription;
+ char **pFiles;
+ LPARAM lParam; //extra space for the network level protocol module
+} PROTORECVFILE;
+#define MS_PROTO_RECVFILE "Proto/RecvFile"
+
+//An away message reply has been received
+//wParam=statusMode
+//lParam=(LPARAM)(PROTORECVEVENT*)&pre
+#define PSR_AWAYMSG "/RecvAwayMsg"
+
+//An authorization request has been received
+//wParam=0
+//lParam=(LPARAM)(PROTORECVEVENT*)&pre
+//pre.szMessage is same format as blob
+//pre.lParam is the size of the blob
+#define PSR_AUTH "/RecvAuth"
+
+#endif // M_PROTOSVC_H__
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_system.h b/plugins/!NotAdopted/WinPopup/sdk/m_system.h
new file mode 100644
index 0000000000..bb330af7be
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_system.h
@@ -0,0 +1,631 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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_SYSTEM_H__
+#define M_SYSTEM_H__ 1
+
+#include <tchar.h>
+
+#ifndef MIRANDANAME
+ #define MIRANDANAME "Miranda IM"
+#endif
+#ifndef MIRANDACLASS
+ #define MIRANDACLASS "Miranda"
+#endif
+
+// set the default compatibility lever for Miranda 0.4.x
+#ifndef MIRANDA_VER
+ #define MIRANDA_VER 0x0400
+#endif
+
+#ifndef _MSC_VER
+ #ifndef FORCEINLINE
+ #define FORCEINLINE __inline
+ #endif
+ #define __forceinline static FORCEINLINE
+#else
+ #pragma warning(disable:4244 4245)
+#endif
+
+//miranda/system/modulesloaded
+//called after all modules have been successfully initialised
+//wParam=lParam=0
+//used to resolve double-dependencies in the module load order
+#define ME_SYSTEM_MODULESLOADED "Miranda/System/ModulesLoaded"
+
+//miranda/system/shutdown event
+//called just before the application terminates
+//the database is still guaranteed to be running during this hook.
+//wParam=lParam=0
+#define ME_SYSTEM_SHUTDOWN "Miranda/System/Shutdown"
+
+//restarts miranda ( 0.8+ )
+//wParam=lParam=0
+#define MS_SYSTEM_RESTART "Miranda/System/Restart"
+
+//miranda/system/oktoexit event
+//called before the app goes into shutdown routine to make sure everyone is
+//happy to exit
+//wParam=lParam=0
+//return nonzero to stop the exit cycle
+#define ME_SYSTEM_OKTOEXIT "Miranda/System/OkToExitEvent"
+
+//miranda/system/oktoexit service
+//Check if everyone is happy to exit
+//wParam=lParam=0
+//if everyone acknowleges OK to exit then returns true, otherwise false
+#define MS_SYSTEM_OKTOEXIT "Miranda/System/OkToExit"
+
+//gets the version number of Miranda encoded as a DWORD v0.1.0.1+
+//wParam=lParam=0
+//returns the version number, encoded as one version per byte, therefore
+//version 1.2.3.10 is 0x0102030a
+#define MS_SYSTEM_GETVERSION "Miranda/System/GetVersion"
+
+//gets the version of Miranda encoded as text v0.1.0.1+
+//wParam=cch
+//lParam=(LPARAM)(char*)pszVersion
+//cch is the size of the buffer pointed to by pszVersion, in bytes
+//may return a build qualifier, such as "0.1.0.1 alpha"
+//returns 0 on success, nonzero on failure
+#define MS_SYSTEM_GETVERSIONTEXT "Miranda/System/GetVersionText"
+
+//Adds a HANDLE to the list to be checked in the main message loop v0.1.2.0+
+//wParam=(WPARAM)(HANDLE)hObject
+//lParam=(LPARAM)(const char*)pszService
+//returns 0 on success or nonzero on failure
+//Causes pszService to be CallService()d (wParam=hObject,lParam=0) from the
+//main thread whenever hObject is signalled.
+//The Miranda message loop has a MsgWaitForMultipleObjects() call in it to
+//implement this feature. See the documentation for that function for
+//information on what objects are supported.
+//There is a limit of MAXIMUM_WAIT_OBJECTS minus one (MWO is defined in winnt.h
+//to be 64) on the number of handles MSFMO() can process. This service will
+//return nonzero if that many handles are already being waited on.
+
+//As of writing, the following parts of Miranda are thread-safe, so can be
+//called from any thread:
+//All of modules.h except NotifyEventHooks()
+//Read-only parts of m_database.h (since the write parts will call hooks)
+//All of m_langpack.h
+//for all other routines your mileage may vary, but I would strongly recommend
+//that you call them from the main thread, or ask about it on plugin-dev if you
+//think it really ought to work.
+
+//Update during 0.1.2.0 development, 16/10/01:
+//NotifyEventHooks() now translates all calls into the context of the main
+//thread, which means that all of m_database.h is now completely safe.
+
+//Update during 0.1.2.2 development, 17/4/02:
+//The main thread's message loop now also deals with asynchronous procedure
+//calls. Loop up QueueUserAPC() for a neater way to accomplish a lot of the
+//things that used to require ms_system_waitonhandle.
+
+//Miranda is compiled with the multithreaded runtime - don't forget to do the
+//same with your plugin.
+#define MS_SYSTEM_WAITONHANDLE "Miranda/System/WaitOnHandle"
+
+//Removes a HANDLE from the wait list v0.1.2.0+
+//wParam=(WPARAM)(HANDLE)hObject
+//lParam=0
+//returns 0 on success or nonzero on failure.
+#define MS_SYSTEM_REMOVEWAIT "Miranda/System/RemoveWait"
+
+/* Returns Miranda's RTL/CRT function poiners to malloc() free() realloc() -- 0.1.2.2+
+This is useful for preallocation of memory for use with Miranda's services
+that Miranda can free -- or reallocation of a block of memory passed with a service.
+Do not use with memory unless it is explicitly expected the memory *can*
+or *shall* be used in this way. the passed structure is expected to have it's .cbSize initialised
+
+wParam=0, lParam = (LPARAM) &MM_INTERFACE
+*/
+
+struct MM_INTERFACE
+{
+ size_t cbSize;
+ void* (*mmi_malloc) (size_t);
+ void* (*mmi_realloc) (void*, size_t);
+ void (*mmi_free) (void*);
+
+ #if MIRANDA_VER >= 0x0600
+ void* (*mmi_calloc) (size_t);
+ char* (*mmi_strdup) (const char *src);
+ wchar_t* (*mmi_wstrdup) (const wchar_t *src);
+ #endif
+ #if MIRANDA_VER >= 0x0700
+ int (*mir_snprintf) (char *buffer, size_t count, const char* fmt, ...);
+ int (*mir_sntprintf) (TCHAR *buffer, size_t count, const TCHAR* fmt, ...);
+ int (*mir_vsnprintf) (char *buffer, size_t count, const char* fmt, va_list va);
+ int (*mir_vsntprintf) (TCHAR *buffer, size_t count, const TCHAR* fmt, va_list va);
+
+ wchar_t* (*mir_a2u_cp) (const char* src, int codepage);
+ wchar_t* (*mir_a2u)(const char* src);
+ char* (*mir_u2a_cp)(const wchar_t* src, int codepage);
+ char* (*mir_u2a)( const wchar_t* src);
+ #endif
+};
+
+#define MS_SYSTEM_GET_MMI "Miranda/System/GetMMI"
+
+__forceinline INT_PTR mir_getMMI( struct MM_INTERFACE* dest )
+{
+ dest->cbSize = sizeof(*dest);
+ return CallService( MS_SYSTEM_GET_MMI, 0, (LPARAM)dest );
+}
+
+#ifndef _STATIC
+ extern struct MM_INTERFACE mmi;
+ #define mir_alloc(n) mmi.mmi_malloc(n)
+ #define mir_free(ptr) mmi.mmi_free(ptr)
+ #define mir_realloc(ptr,size) mmi.mmi_realloc(ptr,size)
+
+ #if MIRANDA_VER >= 0x0600
+ #define mir_calloc(n) mmi.mmi_calloc(n)
+ #define mir_strdup(str) mmi.mmi_strdup(str)
+ #define mir_wstrdup(str) mmi.mmi_wstrdup(str)
+ #else
+ __forceinline char* mir_strdup(const char *src)
+ { return (src == NULL) ? NULL : strcpy(( char* )mir_alloc( strlen(src)+1 ), src );
+ }
+
+ __forceinline WCHAR* mir_wstrdup(const WCHAR *src)
+ { return (src == NULL) ? NULL : wcscpy(( WCHAR* )mir_alloc(( wcslen(src)+1 )*sizeof( WCHAR )), src );
+ }
+ #endif
+ #if MIRANDA_VER >= 0x0700
+ #define mir_snprintf mmi.mir_snprintf
+ #define mir_sntprintf mmi.mir_sntprintf
+ #define mir_vsnprintf mmi.mir_vsnprintf
+ #define mir_vsntprintf mmi.mir_vsntprintf
+
+ #define mir_a2u_cp(src,cp) mmi.mir_a2u_cp(src,cp)
+ #define mir_a2u(src) mmi.mir_a2u(src)
+ #define mir_u2a_cp(src,cp) mmi.mir_u2a_cp(src,cp)
+ #define mir_u2a(src) mmi.mir_u2a(src)
+ #endif
+#else
+ char* mir_strdup(const char *src);
+ WCHAR* mir_wstrdup(const WCHAR *src);
+#endif
+
+#if defined( _UNICODE )
+ #define mir_tstrdup mir_wstrdup
+#else
+ #define mir_tstrdup mir_strdup
+#endif
+
+#define miranda_sys_free mir_free
+#define memoryManagerInterface mmi
+
+/* Returns the pointer to the simple lists manager.
+If the sortFunc member of the list gets assigned, the list becomes sorted
+
+wParam=0, lParam = (LPARAM)LIST_INTERFACE*
+*/
+
+#define LIST_INTERFACE_V1_SIZE (sizeof(size_t)+7*sizeof(void*))
+#define LIST_INTERFACE_V2_SIZE (sizeof(size_t)+9*sizeof(void*))
+#define LIST_INTERFACE_V3_SIZE (sizeof(size_t)+11*sizeof(void*))
+
+typedef int ( *FSortFunc )( void*, void* );
+
+typedef struct
+{
+ void** items;
+ int realCount;
+ int limit;
+ int increment;
+
+ FSortFunc sortFunc;
+}
+ SortedList;
+
+struct LIST_INTERFACE
+{
+ size_t cbSize;
+
+ SortedList* ( *List_Create )( int, int );
+ void ( *List_Destroy )( SortedList* );
+
+ void* ( *List_Find )( SortedList*, void* );
+ int ( *List_GetIndex )( SortedList*, void*, int* );
+ int ( *List_Insert )( SortedList*, void*, int );
+ int ( *List_Remove )( SortedList*, int );
+ int ( *List_IndexOf )( SortedList*, void* );
+
+ #if MIRANDA_VER >= 0x0600
+ int ( *List_InsertPtr)( SortedList* list, void* p );
+ int ( *List_RemovePtr)( SortedList* list, void* p );
+ #endif
+
+ #if MIRANDA_VER >= 0x0800
+ void ( *List_Copy )( SortedList* src, SortedList* dst, size_t );
+ void ( *List_ObjCopy )( SortedList* src, SortedList* dst, size_t );
+ #endif
+};
+
+#define MS_SYSTEM_GET_LI "Miranda/System/GetLI"
+
+__forceinline INT_PTR mir_getLI( struct LIST_INTERFACE* dest )
+{
+ dest->cbSize = sizeof(*dest);
+ return CallService( MS_SYSTEM_GET_LI, 0, (LPARAM)dest );
+}
+
+/*
+ UTF8 Manager interface. 0.5.2+
+
+ Contains functions for utf8-strings encoding & decoding
+*/
+
+#define UTF8_INTERFACE_SIZEOF_V1 (sizeof(size_t)+5*sizeof(void*))
+struct UTF8_INTERFACE
+{
+ size_t cbSize;
+
+ // decodes utf8 and places the result back into the same buffer.
+ // if the second parameter is present, the additional wchar_t* string gets allocated,
+ // and filled with the decoded utf8 content without any information loss.
+ // this string should be freed using mir_free()
+ char* ( *utf8_decode )( char* str, wchar_t** ucs2 );
+ char* ( *utf8_decodecp )( char* str, int codepage, wchar_t** ucs2 );
+
+ // encodes an ANSI string into a utf8 format using the current langpack code page,
+ // or CP_ACP, if lanpack is missing
+ // the resulting string should be freed using mir_free
+ char* ( *utf8_encode )( const char* src );
+ char* ( *utf8_encodecp )( const char* src, int codepage );
+
+ // encodes an WCHAR string into a utf8 format
+ // the resulting string should be freed using mir_free
+ char* ( *utf8_encodeW )( const wchar_t* src );
+ // decodes utf8 and returns the result as wchar_t* that should be freed using mir_free()
+ // the input buffer remains unchanged
+ wchar_t* ( *utf8_decodeW )( const char* str );
+};
+
+#define MS_SYSTEM_GET_UTFI "Miranda/System/GetUTFI"
+
+__forceinline INT_PTR mir_getUTFI( struct UTF8_INTERFACE* dest )
+{
+ dest->cbSize = sizeof(*dest);
+ return CallService( MS_SYSTEM_GET_UTFI, 0, (LPARAM)dest );
+}
+
+extern struct UTF8_INTERFACE utfi;
+
+#define mir_utf8decode(A,B) utfi.utf8_decode(A,B)
+#define mir_utf8decodecp(A,B,C) utfi.utf8_decodecp(A,B,C)
+#define mir_utf8decodeW(A) utfi.utf8_decodeW(A)
+#define mir_utf8encode(A) utfi.utf8_encode(A)
+#define mir_utf8encodecp(A,B) utfi.utf8_encodecp(A,B)
+#define mir_utf8encodeW(A) utfi.utf8_encodeW(A)
+
+__forceinline char* mir_utf8decodeA(const char* src)
+{
+ char* tmp = mir_strdup(src);
+ mir_utf8decode(tmp, NULL);
+ return tmp;
+}
+
+#if defined( _UNICODE )
+ #define mir_utf8decodeT mir_utf8decodeW
+ #define mir_utf8encodeT mir_utf8encodeW
+#else
+ #define mir_utf8decodeT mir_utf8decodeA
+ #define mir_utf8encodeT mir_utf8encode
+#endif
+
+/*
+
+ -- Thread Safety --
+
+ Proper thread safe shutdown was implemented in 0.3.0.0 (2003/04/18)
+ and not before, therefore it is improper that any MT plugins be used
+ with earlier versions of Miranda (as hav0c will result)
+
+ Note: This does not apply to MT plugins which included their own
+ thread-safe shutdown routines.
+
+ Shutdown thread safety works thusly:
+
+ All new threads must call MS_SYSTEM_THREAD_PUSH and MS_SYSTEM_THREAD_POP
+ when they return.
+
+ Due to the nature of thread creation, it is illegal to assume
+ just a call pair of MS_SYSTEM_THREAD_PUSH inside the thread will
+ be enough -- the source thread may only return when the new child
+ thread has actually executed MS_SYSTEM_THREAD_PUSH
+
+ This is because a thread maybe in an undefined state at the point
+ when the thread creation routine returns, thus Miranda may exit
+ thinking it is safe to do so, because MS_SYSTEM_THREAD_PUSH was not
+ called in time.
+
+ See miranda.c for how this can be done using an event object
+ which is signalled just after the MS_SYSTEM_THREAD_PUSH call is executed
+ and so the source thread knows that the created thread is known to Miranda.
+
+ -- What happens when Miranda exits --
+
+ Miranda will firstly set an event object to signalled, this will
+ make MS_SYSTEM_TERMINATED return TRUE, it will then fire ME_SYSTEM_PRESHUTDOWN
+ at this point, no plugins or modules are unloaded.
+
+ Miranda will then enumerate all active threads and queue an APC call
+ to each thread, so any thread in an alertable state will become active,
+ this functionailty may not be required by your threads: but if you use
+ the Winsock2 event object system or Sleep() please use the alertable
+ wait functions, so that the thread will 'wake up' when Miranda queues
+ a message to it, SleepEx() will return WAIT_IO_COMPLETION if this happens.
+
+ After all threads have been signalled, Miranda will spin on the unwind thread stack waiting
+ for it to become empty, in this time, it will carry on processing thread
+ switches, clearing it's own APC calls (used by NotifyEventHooks(), CallServiceSync())
+
+ So a thread should be written in this kind of form:
+
+ void mythread(void *arg)
+ {
+ // assume all thread pushing/popping is done by forkthread()
+ int run=1;
+ for (;run;)
+ {
+ Beep(4391,500);
+ SleepEx(1500,TRUE);
+ if (Miranda_Terminated()) {
+ Beep(5000,150); run=0;
+ } //if
+ } //for
+ }
+
+ The above will make a nice Beep every 1.5 seconds and when the UI
+ quits, it will make a lower beep and then return.
+
+ As many copies of this thread maybe running, the creator does not need
+ to worry about what to do with previous threads, as long as they're on the
+ unwind stack.If there are any global resources (and they're mutex) you can free() them
+ at Unload(), which will only be called, after all threads have returned.
+
+ -- Summary --
+
+ MS_SYSTEM_TERMINATED (will start returning TRUE)
+ ME_SYSTEM_PRESHUTDOWN will be fired (The CList won't be visible at this point)
+
+ All PROTOTYPE_PROTOCOL registered plugins will be sent ID_STATUS_OFFLINE
+ automatically.
+
+ All the threads will be notified via QueueUserAPC() and then Miranda
+ will poll on the unwind thread queue until it is empty.
+
+ ME_SYSTEM_SHUTDOWN will be fired, the database will be unloaded, the core
+ will be unloaded -- Miranda will return.
+
+*/
+
+/* 0.5.2+
+wParam=function address
+lParam=function parameter
+
+registers a thread in the core and forks it
+
+*/
+
+typedef void (__cdecl *pThreadFunc)(void*);
+
+#define MS_SYSTEM_FORK_THREAD "Miranda/Thread/Fork"
+
+__forceinline HANDLE mir_forkthread( pThreadFunc aFunc, void* arg )
+{
+ return (HANDLE)CallService( MS_SYSTEM_FORK_THREAD, (WPARAM)aFunc, (LPARAM)arg );
+}
+
+/* 0.5.2+
+wParam=void* - thread owner object
+lParam=FORK_THREADEX_PARAMS*
+
+registers a thread in the core and forks it
+passes the extended parameters info and returns the thread id
+
+*/
+
+typedef unsigned (__stdcall *pThreadFuncEx)(void* param);
+typedef unsigned (__cdecl *pThreadFuncOwner)(void *owner, void* param);
+
+typedef struct
+{
+ pThreadFuncEx pFunc;
+ int iStackSize;
+ void* arg;
+ unsigned* threadID;
+}
+ FORK_THREADEX_PARAMS;
+
+#define MS_SYSTEM_FORK_THREAD_EX "Miranda/Thread/ForkEx"
+
+static __inline HANDLE mir_forkthreadex( pThreadFuncEx aFunc, void* arg, int stackSize, unsigned* pThreadID )
+{
+ FORK_THREADEX_PARAMS params;
+ params.pFunc = aFunc;
+ params.arg = arg;
+ params.iStackSize = stackSize;
+ params.threadID = pThreadID;
+ return (HANDLE)CallService( MS_SYSTEM_FORK_THREAD_EX, 0, (LPARAM)&params );
+}
+
+/* 0.8.0+
+wParam=(void*)owner
+lParam=FORK_THREADEX_PARAMS*
+
+registers a thread, owned by some object, in the core and forks it
+passes the owner info and extended parameters info and returns the thread id
+
+*/
+
+static __inline HANDLE mir_forkthreadowner( pThreadFuncOwner aFunc, void* owner, void* arg, unsigned* pThreadID )
+{
+ FORK_THREADEX_PARAMS params;
+ params.pFunc = ( pThreadFuncEx )aFunc;
+ params.arg = arg;
+ params.iStackSize = 0;
+ params.threadID = pThreadID;
+ return (HANDLE)CallService( MS_SYSTEM_FORK_THREAD_EX, (WPARAM)owner, (LPARAM)&params );
+}
+
+
+/*
+wParam=0
+lParam=0
+
+Add a thread to the unwind wait stack that Miranda will poll on
+when it is tearing down modules.
+
+This must be called in the context of the thread that is to be pushed
+i.e. there are no args, it works out what thread is being called
+and gets itself a handle to the calling thread.
+
+*/
+#define MS_SYSTEM_THREAD_PUSH "Miranda/Thread/Push"
+
+/*
+wParam=0
+lParam=0
+
+Remove a thread from the unwind wait stack -- it is expected
+that the call be made in the context of the thread to be removed.
+
+Miranda will begin to tear down modules and plugins if/when the
+last thread from the unwind stack is removed.
+*/
+#define MS_SYSTEM_THREAD_POP "Miranda/Thread/Pop"
+
+/*
+wParam=0
+lParam=0
+
+This hook is fired just before the thread unwind stack is used,
+it allows MT plugins to shutdown threads if they have any special
+processing to do, etc.
+
+*/
+#define ME_SYSTEM_PRESHUTDOWN "Miranda/System/PShutdown"
+
+/*
+wParam=0
+lParam=0
+
+Returns TRUE when Miranda has got WM_QUIT and is in the process
+of shutting down
+*/
+#define MS_SYSTEM_TERMINATED "Miranda/SysTerm"
+
+/*
+ wParam : 0
+ lParam : (address) void (__cdecl *callback) (void)
+ Affect : Setup a function pointer to be called after main loop iterations, it allows for
+ idle processing, See notes
+ Returns: 1 on success, 0 on failure
+
+ Notes : This service will only allow one function to be registered, if one is registered, 0 will be returned
+ Remember that this uses __cdecl.
+ Version: Added during 0.3.4+
+
+*/
+#define MS_SYSTEM_SETIDLECALLBACK "Miranda/SetIdleCallback"
+
+/*
+ wParam : 0
+ lParam : &tick
+ Affect : return the last window tick where a monitored event was seen, currently WM_CHAR/WM_MOUSEMOVE
+ Returns: Always returns 0
+ Version: Added during 0.3.4+ (2004/09/12)
+*/
+#define MS_SYSTEM_GETIDLE "Miranda/GetIdle"
+
+/*
+ wParam: cchMax (max length of buffer)
+ lParam: pointer to buffer to fill
+ Affect: Returns the build timestamp of the core, as a string of YYYYMMDDhhmmss, this service might
+ not exist and therefore the build is before 2004-09-30
+ Returns: zero on success, non zero on failure
+ Version: 0.3.4a+ (2004/09/30)
+ DEFUNCT: This service was removed on 0.3.4.3+ (2004/11/19) use APILEVEL
+*/
+#define MS_SYSTEM_GETBUILDSTRING "Miranda/GetBuildString"
+
+#ifdef _STATIC
+INT_PTR MirandaIsTerminated(WPARAM, LPARAM);
+
+__inline static INT_PTR Miranda_Terminated(void)
+{
+ return MirandaIsTerminated(0, 0);
+}
+#else
+__inline static INT_PTR Miranda_Terminated(void)
+{
+ return CallService(MS_SYSTEM_TERMINATED,0,0);
+}
+#endif
+
+/* Missing service catcher
+Is being called when one calls the non-existent service.
+All parameters are stored in the special structure
+
+The event handler takes 0 as wParam and TMissingServiceParams* as lParam.
+
+0.4.3+ addition (2006/03/27)
+*/
+
+typedef struct
+{
+ const char* name;
+ WPARAM wParam;
+ LPARAM lParam;
+}
+ MISSING_SERVICE_PARAMS;
+
+#define ME_SYSTEM_MISSINGSERVICE "System/MissingService"
+
+/* Unhandled exceptions filter
+Is being called inside any thread launched via mir_forkthread, including the main thread.
+If a plugin's author executes a large piece of code inside __try/__except, he should
+obtain this filter and call it inside the __except section
+
+0.8.0+ addition (2008/07/20)
+*/
+
+typedef DWORD ( __cdecl *pfnExceptionFilter )( DWORD code, EXCEPTION_POINTERS* info );
+
+#define MS_SYSTEM_GETEXCEPTFILTER "System/GetExceptFilter"
+
+__inline static pfnExceptionFilter Miranda_GetExceptFilter( void )
+{ return ( pfnExceptionFilter )CallService( MS_SYSTEM_GETEXCEPTFILTER, 0, 0 );
+}
+
+#define MS_SYSTEM_SETEXCEPTFILTER "System/SetExceptFilter"
+
+__inline static pfnExceptionFilter Miranda_SetExceptFilter( pfnExceptionFilter foo )
+{ return ( pfnExceptionFilter )CallService( MS_SYSTEM_SETEXCEPTFILTER, 0, (LPARAM)foo );
+}
+
+
+#endif // M_SYSTEM_H
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_userinfo.h b/plugins/!NotAdopted/WinPopup/sdk/m_userinfo.h
new file mode 100644
index 0000000000..a30243e8ea
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_userinfo.h
@@ -0,0 +1,76 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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_USERINFO_H__
+#define M_USERINFO_H__ 1
+
+#include "m_options.h"
+
+//show the User Details dialog box
+//wParam=(WPARAM)(HANDLE)hContact
+//lParam=0
+#define MS_USERINFO_SHOWDIALOG "UserInfo/ShowDialog"
+
+/* UserInfo/Initialise v0.1.2.0+
+The user opened a details dialog. Modules should do whatever initialisation
+they need and call userinfo/addpage one or more times if they want pages
+displayed in the options dialog
+wParam=addInfo
+lParam=(LPARAM)hContact
+addInfo should be passed straight to the wParam of userinfo/addpage
+NB: The built-in userinfo module is loaded after all plugins, so calling
+HookEvent() in your plugin's Load() function will fail if you specify this
+hook. Look up core/m_system.h:me_system_modulesloaded.
+*/
+#define ME_USERINFO_INITIALISE "UserInfo/Initialise"
+
+/* UserInfo/AddPage v0.1.2.0+
+Must only be called during an userinfo/initialise hook
+Adds a page to the details dialog
+wParam=addInfo
+lParam=(LPARAM)(OPTIONSDIALOGPAGE*)odp
+addInfo must have come straight from the wParam of userinfo/initialise
+Pages in the details dialog operate just like pages in property sheets. See the
+Microsoft documentation for info on how they operate.
+When the pages receive WM_INITDIALOG, lParam=(LPARAM)hContact
+Strings in the structure can be released as soon as the service returns, but
+icons must be kept around. This is not a problem if you're loading them from a
+resource
+The 3 'group' elements in the structure are ignored, and will always be ignored
+Unlike the options dialog, the details dialog does not resize to fit its
+largest page. Details dialog pages should be 222x132 dlus.
+The details dialog (currently) has no Cancel button. I'm waiting to see if it's
+sensible to have one.
+Pages will be sent PSN_INFOCHANGED through WM_NOTIFY (idFrom=0) when a protocol
+ack is broadcast for the correct contact and with type=ACKTYPE_GETINFO.
+To help you out, PSN_INFOCHANGED will also be sent to each page just after it's
+created.
+All PSN_ WM_NOTIFY messages have PSHNOTIFY.lParam=(LPARAM)hContact
+*/
+#define PSN_INFOCHANGED 1
+#define PSN_PARAMCHANGED 2
+#define PSM_FORCECHANGED (WM_USER+100) //force-send a PSN_INFOCHANGED to all pages
+#define MS_USERINFO_ADDPAGE "UserInfo/AddPage"
+
+#endif // M_USERINFO_H__
+
diff --git a/plugins/!NotAdopted/WinPopup/sdk/m_utils.h b/plugins/!NotAdopted/WinPopup/sdk/m_utils.h
new file mode 100644
index 0000000000..7ace76dcd5
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/m_utils.h
@@ -0,0 +1,573 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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_UTILS_H__
+#define M_UTILS_H__ 1
+
+#ifdef _MSC_VER
+ #pragma warning(disable:4201)
+#endif
+
+#include <stdio.h>
+
+#if !defined(M_SYSTEM_H__)
+#include "m_system.h"
+#endif
+
+//this entire module is v0.1.0.1+
+//this module cannot be redefined by a plugin, because it's not useful for it
+//to be possible
+//There are some more utility services in the database for dealing with time
+//and simple string scrambling, but they are very db-orientated
+
+/* Opens a URL in the user's default web browser v0.1.0.1+
+wParam=bOpenInNewWindow
+lParam=(LPARAM)(const char*)szUrl
+returns 0 always
+bOpenInNewWindow should be zero to open the URL in the browser window the user
+last used, or nonzero to open in a new browser window. If there's no browser
+running, one will be opened to show the URL.
+*/
+#define MS_UTILS_OPENURL "Utils/OpenURL"
+
+/* Resizes a dialog by calling a custom routine to move the individual
+controls v0.1.0.1+
+wParam=0
+lParam=(LPARAM)(UTILRESIZEDIALOG*)&urd
+Returns 0 on success, or nonzero on failure
+Does not support dialogtemplateex dialog boxes, and will return failure if you
+try to resize one
+The dialog itself should have been resized prior to calling this service
+pfnResizer is called once for each control in the dialog
+pfnResizer should return a combination of one rd_anchorx_ and one rd_anchory
+constant
+*/
+typedef struct {
+ int cbSize;
+ UINT wId; //control ID
+ RECT rcItem; //original control rectangle, relative to dialog
+ //modify in-place to specify the new position
+ SIZE dlgOriginalSize; //size of dialog client area in template
+ SIZE dlgNewSize; //current size of dialog client area
+} UTILRESIZECONTROL;
+typedef int (*DIALOGRESIZERPROC)(HWND hwndDlg,LPARAM lParam,UTILRESIZECONTROL *urc);
+typedef struct {
+ int cbSize;
+ HWND hwndDlg;
+ HINSTANCE hInstance; //module containing the dialog template
+ LPCSTR lpTemplate; //dialog template
+ LPARAM lParam; //caller-defined
+ DIALOGRESIZERPROC pfnResizer;
+} UTILRESIZEDIALOG;
+#define RD_ANCHORX_CUSTOM 0 //function did everything required to the x axis, do no more processing
+#define RD_ANCHORX_LEFT 0 //move the control to keep it constant distance from the left edge of the dialog
+#define RD_ANCHORX_RIGHT 1 //move the control to keep it constant distance from the right edge of the dialog
+#define RD_ANCHORX_WIDTH 2 //size the control to keep it constant distance from both edges of the dialog
+#define RD_ANCHORX_CENTRE 4 //move the control to keep it constant distance from the centre of the dialog
+#define RD_ANCHORY_CUSTOM 0
+#define RD_ANCHORY_TOP 0
+#define RD_ANCHORY_BOTTOM 8
+#define RD_ANCHORY_HEIGHT 16
+#define RD_ANCHORY_CENTRE 32
+#define MS_UTILS_RESIZEDIALOG "Utils/ResizeDialog"
+
+/* Gets the name of a country given its number v0.1.2.0+
+wParam=countryId
+lParam=0
+Returns a pointer to the string containing the country name on success,
+or NULL on failure
+*/
+#define MS_UTILS_GETCOUNTRYBYNUMBER "Utils/GetCountryByNumber"
+
+/* Gets the full list of country IDs v0.1.2.0+
+wParam=(WPARAM)(int*)piCount
+lParam=(LPARAM)(struct CountryListEntry**)ppList
+Returns 0 always
+Neither wParam nor lParam can be NULL.
+The list is sorted alphabetically by country name, on the assumption that it's
+quicker to search numbers out of order than it is to search names out of order
+*/
+struct CountryListEntry {
+ int id;
+ const char *szName;
+};
+#define MS_UTILS_GETCOUNTRYLIST "Utils/GetCountryList"
+
+/******************************* Window lists *******************************/
+
+//allocate a window list v0.1.0.1+
+//wParam=lParam=0
+//returns a handle to the new window list
+#define MS_UTILS_ALLOCWINDOWLIST "Utils/AllocWindowList"
+
+//adds a window to the specified window list v0.1.0.1+
+//wParam=0
+//lParam=(LPARAM)(WINDOWLISTENTRY*)&wle
+//returns 0 on success, nonzero on failure
+typedef struct {
+ HANDLE hList;
+ HWND hwnd;
+ HANDLE hContact;
+} WINDOWLISTENTRY;
+#define MS_UTILS_ADDTOWINDOWLIST "Utils/AddToWindowList"
+__inline static INT_PTR WindowList_Add(HANDLE hList,HWND hwnd,HANDLE hContact) {
+ WINDOWLISTENTRY wle;
+ wle.hList=hList; wle.hwnd=hwnd; wle.hContact=hContact;
+ return CallService(MS_UTILS_ADDTOWINDOWLIST,0,(LPARAM)&wle);
+}
+//removes a window from the specified window list v0.1.0.1+
+//wParam=(WPARAM)(HANDLE)hList
+//lParam=(LPARAM)(HWND)hwnd
+//returns 0 on success, nonzero on failure
+#define MS_UTILS_REMOVEFROMWINDOWLIST "Utils/RemoveFromWindowList"
+__inline static INT_PTR WindowList_Remove(HANDLE hList,HWND hwnd) {
+ return CallService(MS_UTILS_REMOVEFROMWINDOWLIST,(WPARAM)hList,(LPARAM)hwnd);
+}
+
+//finds a window given the hContact v0.1.0.1+
+//wParam=(WPARAM)(HANDLE)hList
+//lParam=(WPARAM)(HANDLE)hContact
+//returns the window handle on success, or NULL on failure
+#define MS_UTILS_FINDWINDOWINLIST "Utils/FindWindowInList"
+__inline static HWND WindowList_Find(HANDLE hList,HANDLE hContact) {
+ return (HWND)CallService(MS_UTILS_FINDWINDOWINLIST,(WPARAM)hList,(LPARAM)hContact);
+}
+
+//broadcasts a message to all windows in a list v0.1.0.1+
+//wParam=(WPARAM)(HANDLE)hList
+//lParam=(LPARAM)(MSG*)&msg
+//returns 0 on success, nonzero on failure
+//Only msg.message, msg.wParam and msg.lParam are used
+#define MS_UTILS_BROADCASTTOWINDOWLIST "Utils/BroadcastToWindowList"
+__inline static INT_PTR WindowList_Broadcast(HANDLE hList,UINT message,WPARAM wParam,LPARAM lParam) {
+ MSG msg;
+ msg.message=message; msg.wParam=wParam; msg.lParam=lParam;
+ return CallService(MS_UTILS_BROADCASTTOWINDOWLIST,(WPARAM)hList,(LPARAM)&msg);
+}
+
+/*
+ Description: Broadcast a message to all windows in the given list using PostMessage()
+ Version: 0.3.0.0+
+ Inline helper: WindowList_BroadcastAsync
+
+ wParam=(WPARAM)(HANDLE)hList
+ lParam=(LPARAM)(MSG*)&msg
+
+ Returns 0 on success, nonzero on failure, this service does not fail, even if PostMessage() fails for whatever reason
+
+*/
+#define MS_UTILS_BROADCASTTOWINDOWLIST_ASYNC "Utils/BroadcastToWindowListAsync"
+
+__inline static INT_PTR WindowList_BroadcastAsync(HANDLE hList,UINT message,WPARAM wParam,LPARAM lParam) {
+ MSG msg;
+ msg.message=message; msg.wParam=wParam; msg.lParam=lParam;
+ return CallService(MS_UTILS_BROADCASTTOWINDOWLIST_ASYNC,(WPARAM)hList,(LPARAM)&msg);
+}
+
+/***************************** Hyperlink windows ********************************/
+
+//there aren't any services here, because you don't need them.
+#define WNDCLASS_HYPERLINK _T("Hyperlink")
+//the control will obey the SS_LEFT (0), SS_CENTER (1), and SS_RIGHT (2) styles
+//the control will send STN_CLICKED via WM_COMMAND when the link itself is clicked
+
+// Use this in a SendMessage to set the color of the url when control is enabled
+// wParam=DWORD color
+// lParam=not used
+#define HLK_SETENABLECOLOUR (WM_USER+101) // added in 0.3.1
+// Use this in a SendMessage to set the color of the url when control is disabled
+// wParam=DWORD color
+// lParam=not used
+#define HLK_SETDISABLECOLOUR (WM_USER+102) // added in 0.3.1
+
+/***************************** Window Position Saving ***************************/
+
+//saves the position of a window in the database v0.1.1.0+
+//wParam=0
+//lParam=(LPARAM)(SAVEWINDOWPOS*)&swp
+//returns 0 on success, nonzero on failure
+typedef struct {
+ HWND hwnd;
+ HANDLE hContact;
+ const char *szModule; //module name to store the setting in
+ const char *szNamePrefix; //text to prefix on "x", "width", etc, to form setting names
+} SAVEWINDOWPOS;
+#define MS_UTILS_SAVEWINDOWPOSITION "Utils/SaveWindowPos"
+__inline static INT_PTR Utils_SaveWindowPosition(HWND hwnd,HANDLE hContact,const char *szModule,const char *szNamePrefix) {
+ SAVEWINDOWPOS swp;
+ swp.hwnd=hwnd; swp.hContact=hContact; swp.szModule=szModule; swp.szNamePrefix=szNamePrefix;
+ return CallService(MS_UTILS_SAVEWINDOWPOSITION,0,(LPARAM)&swp);
+}
+
+//restores the position of a window from the database v0.1.1.0+
+//wParam=flags
+//lParam=(LPARAM)(SAVEWINDOWPOS*)&swp
+//returns 0 on success, nonzero on failure
+//if no position was found in the database, the function returns 1 and does
+//nothing
+//the NoSize version won't use stored size information: the window is left the
+//same size.
+#define RWPF_NOSIZE 1 //don't use stored size info: leave dialog same size
+#define RWPF_NOMOVE 2 //don't use stored position
+#define RWPF_NOACTIVATE 4 //show but don't activate v0.3.3.0+
+#define MS_UTILS_RESTOREWINDOWPOSITION "Utils/RestoreWindowPos"
+__inline static INT_PTR Utils_RestoreWindowPosition(HWND hwnd,HANDLE hContact,const char *szModule,const char *szNamePrefix) {
+ SAVEWINDOWPOS swp;
+ swp.hwnd=hwnd; swp.hContact=hContact; swp.szModule=szModule; swp.szNamePrefix=szNamePrefix;
+ return CallService(MS_UTILS_RESTOREWINDOWPOSITION,0,(LPARAM)&swp);
+}
+__inline static INT_PTR Utils_RestoreWindowPositionNoSize(HWND hwnd,HANDLE hContact,const char *szModule,const char *szNamePrefix) {
+ SAVEWINDOWPOS swp;
+ swp.hwnd=hwnd; swp.hContact=hContact; swp.szModule=szModule; swp.szNamePrefix=szNamePrefix;
+ return CallService(MS_UTILS_RESTOREWINDOWPOSITION,RWPF_NOSIZE,(LPARAM)&swp);
+}
+__inline static INT_PTR Utils_RestoreWindowPositionNoMove(HWND hwnd,HANDLE hContact,const char *szModule,const char *szNamePrefix) {
+ SAVEWINDOWPOS swp;
+ swp.hwnd=hwnd; swp.hContact=hContact; swp.szModule=szModule; swp.szNamePrefix=szNamePrefix;
+ return CallService(MS_UTILS_RESTOREWINDOWPOSITION,RWPF_NOMOVE,(LPARAM)&swp);
+}
+
+//Moves a RECT inside screen if it is outside.It works with multiple monitors v0.9.0.4+
+//wParam=RECT *
+//lParam=0
+//returns <0 on error, 0 if not changed the rect, 1 if changed the rect
+#define MS_UTILS_ASSERTINSIDESCREEN "Utils/AssertInsideScreen"
+__inline static INT_PTR Utils_AssertInsideScreen(RECT *rc) {
+ return CallService(MS_UTILS_ASSERTINSIDESCREEN,(WPARAM)rc,0);
+}
+
+/************************ Colour Picker Control (0.1.2.1+) **********************/
+
+#define WNDCLASS_COLOURPICKER _T("ColourPicker")
+
+#define CPM_SETCOLOUR 0x1000 //lParam=new colour
+#define CPM_GETCOLOUR 0x1001 //returns colour
+#define CPM_SETDEFAULTCOLOUR 0x1002 //lParam=default, used as first custom colour
+#define CPM_GETDEFAULTCOLOUR 0x1003 //returns colour
+#define CPN_COLOURCHANGED 1 //sent through WM_COMMAND
+
+/***************************** Bitmap Filter (0.1.2.1+) *************************/
+
+//Loads a bitmap v0.1.2.1+
+//wParam=0
+//lParam=(LPARAM)(const char*)filename
+//returns HBITMAP on success, NULL on failure
+//This function uses OleLoadPicturePath() so supports BMP, JPEG and GIF. It may
+//support PNG on future versions of Windows (or XP for that matter)
+//For speed, if the file extension is .bmp or .rle it'll use LoadImage() so as
+//to avoid the big lag loading OLE.
+//Remember to DeleteObject() when you're done
+#define MS_UTILS_LOADBITMAP "Utils/LoadBitmap"
+
+//Gets the filter strings for use in the open file dialog v0.1.2.1+
+//wParam=cbLengthOfBuffer
+//lParam=(LPARAM)(char*)pszBuffer
+//Returns 0 on success, nonzero on failure
+//See the MSDN under OPENFILENAME.lpstrFilter for the formatting
+//An 'All Bitmaps' item is always first and 'All Files' is last.
+//The returned string is already translated.
+#define MS_UTILS_GETBITMAPFILTERSTRINGS "Utils/GetBitmapFilterStrings"
+
+//Saves a path to a relative path (from the miranda directory)
+//Only saves as a relative path if the file is in the miranda directory (or
+//sub directory)
+//wParam=(WPARAM)(char*)pszPath
+//lParam=(LPARAM)(char*)pszNewPath
+//pszPath is the path to convert and pszNewPath is the buffer that
+//the new path is copied too. pszNewPath MUST be of the size MAX_PATH.
+//Returns numbers of chars copied.
+//Unicode version is available since 0.6.2
+#define MS_UTILS_PATHTORELATIVE "Utils/PathToRelative"
+
+//Saves a path to a absolute path (from the miranda directory)
+//wParam=(WPARAM)(char*)pszPath
+//lParam=(LPARAM)(char*)pszNewPath
+//pszPath is the path to convert and pszNewPath is the buffer that
+//the new path is copied too. pszNewPath MUST be of the size MAX_PATH.
+//Returns numbers of chars copied.
+//Unicode version is available since 0.6.2
+#define MS_UTILS_PATHTOABSOLUTE "Utils/PathToAbsolute"
+
+//Creates a directory tree (even more than one directories levels are missing) 0.7.0+
+//wParam=0 (unused)
+//lParam=(LPARAM)(char*)pszPath - directory to be created
+//Always returns 0
+//Unicode version is available since 0.7.0
+#define MS_UTILS_CREATEDIRTREE "Utils/CreateDirTree"
+
+// Generates Random number of any length
+//wParam=size - length of the random number to generate
+//lParam=(LPARAM)(char*)pszArray - pointer to array to fill with random number
+//Always returns 0
+#define MS_UTILS_GETRANDOM "Utils/GetRandom"
+
+//Replace variables in text
+//wParam=(char*/TCHAR*/WCHAR*)string (depends on RVF_UNICODE/RVF_TCHAR flag)
+//lParam=(REPLACEVARSDATA *) data about variables, item with key=0 terminates the list
+//returns new string, use mir_free to destroy
+typedef struct
+{
+ union
+ {
+ TCHAR *lptzKey;
+ char *lpszKey;
+ WCHAR *lpwzKey;
+ };
+ union
+ {
+ TCHAR *lptzValue;
+ char *lpszValue;
+ WCHAR *lpwzValue;
+ };
+} REPLACEVARSARRAY;
+
+typedef struct
+{
+ int cbSize;
+ DWORD dwFlags;
+ HANDLE hContact;
+ REPLACEVARSARRAY *variables;
+} REPLACEVARSDATA;
+
+#define RVF_UNICODE 1
+#ifdef _UNICODE
+ #define RVF_TCHAR RVF_UNICODE
+#else
+ #define RVF_TCHAR 0
+#endif
+
+#define MS_UTILS_REPLACEVARS "Utils/ReplaceVars"
+
+__inline static char* Utils_ReplaceVars(const char *szData) {
+ REPLACEVARSDATA dat = {0};
+ dat.cbSize = sizeof(dat);
+ return (char*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)szData, (LPARAM)&dat);
+}
+__inline static TCHAR* Utils_ReplaceVarsT(const TCHAR *szData) {
+ REPLACEVARSDATA dat = {0};
+ dat.cbSize = sizeof(dat);
+ dat.dwFlags = RVF_TCHAR;
+ return (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)szData, (LPARAM)&dat);
+}
+#ifdef _UNICODE
+ #define MS_UTILS_PATHTORELATIVEW "Utils/PathToRelativeW"
+ #define MS_UTILS_PATHTOABSOLUTEW "Utils/PathToAbsoluteW"
+ #define MS_UTILS_CREATEDIRTREEW "Utils/CreateDirTreeW"
+
+ #define MS_UTILS_PATHTORELATIVET MS_UTILS_PATHTORELATIVEW
+ #define MS_UTILS_PATHTOABSOLUTET MS_UTILS_PATHTOABSOLUTEW
+ #define MS_UTILS_CREATEDIRTREET MS_UTILS_CREATEDIRTREEW
+#else
+ #define MS_UTILS_PATHTORELATIVET MS_UTILS_PATHTORELATIVE
+ #define MS_UTILS_PATHTOABSOLUTET MS_UTILS_PATHTOABSOLUTE
+ #define MS_UTILS_CREATEDIRTREET MS_UTILS_CREATEDIRTREE
+#endif
+
+/*
+ MD5 interface. 0.7.0.12
+
+ Contains functions for md5 handling
+*/
+/* Define the state of the MD5 Algorithm. */
+typedef unsigned char mir_md5_byte_t; /* 8-bit byte */
+typedef unsigned int mir_md5_word_t; /* 32-bit word */
+
+typedef struct mir_md5_state_s {
+ mir_md5_word_t count[2]; /* message length in bits, lsw first */
+ mir_md5_word_t abcd[4]; /* digest buffer */
+ mir_md5_byte_t buf[64]; /* accumulate block */
+} mir_md5_state_t;
+
+struct MD5_INTERFACE
+{
+ int cbSize;
+ void (*md5_init) (mir_md5_state_t *pms);
+ void (*md5_append) (mir_md5_state_t *pms, const mir_md5_byte_t *data, int nbytes);
+ void (*md5_finish) (mir_md5_state_t *pms, mir_md5_byte_t digest[16]);
+ void (*md5_hash) (const mir_md5_byte_t *data, int len, mir_md5_byte_t digest[16]);
+};
+
+#define MS_SYSTEM_GET_MD5I "Miranda/System/GetMD5I"
+
+static __inline INT_PTR mir_getMD5I( struct MD5_INTERFACE* dest )
+{
+ dest->cbSize = sizeof(*dest);
+ return CallService( MS_SYSTEM_GET_MD5I, 0, (LPARAM)dest );
+}
+
+extern struct MD5_INTERFACE md5i;
+
+#define mir_md5_init(A) md5i.md5_init(A)
+#define mir_md5_append(A,B,C) md5i.md5_append(A,B,C)
+#define mir_md5_finish(A,B) md5i.md5_finish(A,B)
+#define mir_md5_hash(A,B,C) md5i.md5_hash(A,B,C)
+
+/*
+ SHA1 interface. 0.7.0.12
+
+ Contains functions for SHA1 handling
+*/
+typedef unsigned char mir_sha1_byte_t;
+typedef unsigned long mir_sha1_long_t;
+#define MIR_SHA1_HASH_SIZE 20
+
+typedef struct {
+ mir_sha1_long_t H[5];
+ mir_sha1_long_t W[80];
+ int lenW;
+ mir_sha1_long_t sizeHi,sizeLo;
+} mir_sha1_ctx;
+
+struct SHA1_INTERFACE
+{
+ int cbSize;
+ void (*sha1_init) (mir_sha1_ctx *ctx);
+ void (*sha1_append) (mir_sha1_ctx *ctx, mir_sha1_byte_t *dataIn, int len);
+ void (*sha1_finish) (mir_sha1_ctx *ctx, mir_sha1_byte_t hashout[20]);
+ void (*sha1_hash) (mir_sha1_byte_t *dataIn, int len, mir_sha1_byte_t hashout[20]);
+};
+
+#define MS_SYSTEM_GET_SHA1I "Miranda/System/GetSHA1I"
+
+static __inline INT_PTR mir_getSHA1I( struct SHA1_INTERFACE* dest )
+{
+ dest->cbSize = sizeof(*dest);
+ return CallService( MS_SYSTEM_GET_SHA1I, 0, (LPARAM)dest );
+}
+
+extern struct SHA1_INTERFACE sha1i;
+
+#define mir_sha1_init(A) sha1i.sha1_init(A)
+#define mir_sha1_append(A,B,C) sha1i.sha1_append(A,B,C)
+#define mir_sha1_finish(A,B) sha1i.sha1_finish(A,B)
+#define mir_sha1_hash(A,B,C) sha1i.sha1_hash(A,B,C)
+
+// Added in 0.4.0.1
+// Here are some string wrappers that are more safe than the win32 versions
+
+#if MIRANDA_VER < 0x0700
+static __inline int mir_snprintf(char *buffer, size_t count, const char* fmt, ...) {
+ va_list va;
+ int len;
+
+ va_start(va, fmt);
+ len = _vsnprintf(buffer, count-1, fmt, va);
+ va_end(va);
+ buffer[count-1] = 0;
+ return len;
+}
+
+static __inline int mir_sntprintf(TCHAR *buffer, size_t count, const TCHAR* fmt, ...) {
+ va_list va;
+ int len;
+
+ va_start(va, fmt);
+ len = _vsntprintf(buffer, count-1, fmt, va);
+ va_end(va);
+ buffer[count-1] = 0;
+ return len;
+}
+
+static __inline int mir_vsnprintf(char *buffer, size_t count, const char* fmt, va_list va) {
+ int len;
+
+ len = _vsnprintf(buffer, count-1, fmt, va);
+ buffer[count-1] = 0;
+ return len;
+}
+
+static __inline int mir_vsntprintf(TCHAR *buffer, size_t count, const TCHAR* fmt, va_list va) {
+ int len;
+
+ len = _vsntprintf(buffer, count-1, fmt, va);
+ buffer[count-1] = 0;
+ return len;
+}
+#endif
+
+// allows to include TCHAR* strings into mir_snprintf and NetLib_Logf calls
+#if defined( _UNICODE )
+ #define TCHAR_STR_PARAM "%S"
+#else
+ #define TCHAR_STR_PARAM "%s"
+#endif
+
+#if MIRANDA_VER < 0x0700
+static __inline wchar_t* mir_a2u_cp( const char* src, int codepage )
+{
+ int cbLen = MultiByteToWideChar( codepage, 0, src, -1, NULL, 0 );
+ wchar_t* result = ( wchar_t* )mir_alloc( sizeof( wchar_t )*(cbLen+1));
+ if ( result == NULL )
+ return NULL;
+
+ MultiByteToWideChar( codepage, 0, src, -1, result, cbLen );
+ result[ cbLen ] = 0;
+ return result;
+}
+
+static __inline wchar_t* mir_a2u( const char* src )
+{
+ return mir_a2u_cp( src, CallService("LangPack/GetCodePage", 0, 0 ));
+}
+
+static __inline char* mir_u2a_cp( const wchar_t* src, int codepage )
+{
+ int cbLen = WideCharToMultiByte( codepage, 0, src, -1, NULL, 0, NULL, NULL );
+ char* result = ( char* )mir_alloc( cbLen+1 );
+ if ( result == NULL )
+ return NULL;
+
+ WideCharToMultiByte( codepage, 0, src, -1, result, cbLen, NULL, NULL );
+ result[ cbLen ] = 0;
+ return result;
+}
+
+static __inline char* mir_u2a( const wchar_t* src )
+{
+ return mir_u2a_cp( src, CallService("LangPack/GetCodePage", 0, 0 ));
+}
+#endif
+
+#ifdef _UNICODE
+ #define mir_t2a(s) mir_u2a(s)
+ #define mir_a2t(s) mir_a2u(s)
+ #define mir_t2u(s) mir_wstrdup(s)
+ #define mir_u2t(s) mir_wstrdup(s)
+
+ #define mir_t2a_cp(s,c) mir_u2a_cp(s,c)
+ #define mir_a2t_cp(s,c) mir_a2u_cp(s,c)
+ #define mir_t2u_cp(s,c) mir_wstrdup(s)
+ #define mir_u2t_cp(s,c) mir_wstrdup(s)
+#else
+ #define mir_t2a(s) mir_strdup(s)
+ #define mir_a2t(s) mir_strdup(s)
+ #define mir_t2u(s) mir_a2u(s)
+ #define mir_u2t(s) mir_u2a(s)
+
+ #define mir_t2a_cp(s,c) mir_strdup(s)
+ #define mir_a2t_cp(s,c) mir_strdup(s)
+ #define mir_t2u_cp(s,c) mir_a2u_cp(s,c)
+ #define mir_u2t_cp(s,c) mir_u2a_cp(s,c)
+#endif
+
+#endif // M_UTILS_H__
diff --git a/plugins/!NotAdopted/WinPopup/sdk/newpluginapi.h b/plugins/!NotAdopted/WinPopup/sdk/newpluginapi.h
new file mode 100644
index 0000000000..b32abf3dc0
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/newpluginapi.h
@@ -0,0 +1,291 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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_NEWPLUGINAPI_H__
+#define M_NEWPLUGINAPI_H__
+
+#include "m_plugins.h"
+
+#define PLUGIN_MAKE_VERSION(a,b,c,d) (((((DWORD)(a))&0xFF)<<24)|((((DWORD)(b))&0xFF)<<16)|((((DWORD)(c))&0xFF)<<8)|(((DWORD)(d))&0xFF))
+#define MAXMODULELABELLENGTH 64
+
+#if defined( _UNICODE )
+ #define UNICODE_AWARE 1
+#else
+ #define UNICODE_AWARE 0
+#endif
+
+typedef struct {
+ int cbSize;
+ char *shortName;
+ DWORD version;
+ char *description; // [TRANSLATED-BY-CORE]
+ char *author;
+ char *authorEmail;
+ char *copyright;
+ char *homepage;
+ BYTE flags; // right now the only flag, UNICODE_AWARE, is recognized here
+ int replacesDefaultModule; //one of the DEFMOD_ constants in m_plugins.h or zero
+ //if non-zero, this will supress the loading of the specified built-in module
+ //with the implication that this plugin provides back-end-compatible features
+} PLUGININFO;
+
+/* 0.7+
+ New plugin loader implementation
+*/
+/* The UUID structure below is used to for plugin UUID's and module type definitions */
+typedef struct _MUUID {
+ unsigned long a;
+ unsigned short b;
+ unsigned short c;
+ unsigned char d[8];
+} MUUID;
+
+
+/* Used to define the end of the MirandaPluginInterface list */
+#define MIID_LAST {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
+
+/* Replaceable internal modules interface ids */
+#define MIID_HISTORY {0x5ca0cbc1, 0x999a, 0x4ea2, {0x8b, 0x44, 0xf8, 0xf6, 0x7d, 0x7f, 0x8e, 0xbe}}
+#define MIID_UIFINDADD {0xb22c528d, 0x6852, 0x48eb, {0xa2, 0x94, 0xe, 0x26, 0xa9, 0x16, 0x12, 0x13}}
+#define MIID_UIUSERINFO {0x570b931c, 0x9af8, 0x48f1, {0xad, 0x9f, 0xc4, 0x49, 0x8c, 0x61, 0x8a, 0x77}}
+#define MIID_SRURL {0x5192445c, 0xf5e8, 0x46c0, {0x8f, 0x9e, 0x2b, 0x6d, 0x43, 0xe5, 0xc7, 0x53}}
+#define MIID_SRAUTH {0x377780b9, 0x2b3b, 0x405b, {0x9f, 0x36, 0xb3, 0xc4, 0x87, 0x8e, 0x6f, 0x33}}
+#define MIID_SRAWAY {0x5ab54c76, 0x1b4c, 0x4a00, {0xb4, 0x4, 0x48, 0xcb, 0xea, 0x5f, 0xef, 0xe7}}
+#define MIID_SREMAIL {0xd005b5a6, 0x1b66, 0x445a, {0xb6, 0x3, 0x74, 0xd4, 0xd4, 0x55, 0x2d, 0xe2}}
+#define MIID_SRFILE {0x989d104d, 0xacb7, 0x4ee0, {0xb9, 0x6d, 0x67, 0xce, 0x46, 0x53, 0xb6, 0x95}}
+#define MIID_UIHELP {0xf2d35c3c, 0x861a, 0x4cc3, {0xa7, 0x8f, 0xd1, 0xf7, 0x85, 0x4, 0x41, 0xcb}}
+#define MIID_UIHISTORY {0x7f7e3d98, 0xce1f, 0x4962, {0x82, 0x84, 0x96, 0x85, 0x50, 0xf1, 0xd3, 0xd9}}
+#define MIID_AUTOAWAY {0x9c87f7dc, 0x3bd7, 0x4983, {0xb7, 0xfb, 0xb8, 0x48, 0xfd, 0xbc, 0x91, 0xf0}}
+#define MIID_USERONLINE {0x130829e0, 0x2463, 0x4ff8, {0xbb, 0xc8, 0xce, 0x73, 0xc0, 0x18, 0x84, 0x42}}
+#define MIID_IDLE {0x296f9f3b, 0x5b6f, 0x40e5, {0x8f, 0xb0, 0xa6, 0x49, 0x6c, 0x18, 0xbf, 0xa}}
+#define MIID_FONTSERVICE {0x56f39112, 0xe37f, 0x4234, {0xa9, 0xe6, 0x7a, 0x81, 0x17, 0x45, 0xc1, 0x75}}
+#define MIID_UPDATENOTIFY {0x4e68b12a, 0x6b54, 0x44de, {0x86, 0x37, 0xf1, 0x12, 0xd, 0xb6, 0x81, 0x40}}
+
+/* Common plugin interfaces (core plugins) */
+#define MIID_DATABASE {0xae77fd33, 0xe484, 0x4dc7, {0x8c, 0xbc, 0x9, 0x9f, 0xed, 0xcc, 0xcf, 0xdd}}
+#define MIID_CLIST {0x9d8da8bf, 0x665b, 0x4908, {0x9e, 0x61, 0x9f, 0x75, 0x98, 0xae, 0x33, 0xe}}
+#define MIID_CHAT {0x23576a43, 0x3a26, 0x4357, {0x9b, 0x1b, 0x4a, 0x71, 0x9e, 0x42, 0x5d, 0x48}}
+#define MIID_SRMM {0x58c7eea6, 0xf9db, 0x4dd9, {0x80, 0x36, 0xae, 0x80, 0x2b, 0xc0, 0x41, 0x4c}}
+#define MIID_IMPORT {0x5f3bcad4, 0x75f8, 0x476e, {0xb3, 0x6b, 0x2b, 0x30, 0x70, 0x32, 0x49, 0xc}}
+#define MIID_IMGSERVICES {0xf3974915, 0xc9d5, 0x4c87, {0x85, 0x64, 0xa0, 0xeb, 0xf9, 0xd2, 0x5a, 0xa0}}
+#define MIID_TESTPLUGIN {0x53b974f4, 0x3c74, 0x4dba, {0x8f, 0xc2, 0x6f, 0x92, 0xfe, 0x1, 0x3b, 0x8c}}
+
+/* Common plugin interfaces (non-core plugins) */
+#define MIID_VERSIONINFO {0xcfeb6325, 0x334e, 0x4052, {0xa6, 0x45, 0x56, 0x21, 0x93, 0xdf, 0xcc, 0x77}}
+#define MIID_FOLDERS {0xcfebec29, 0x39ef, 0x4b62, {0xad, 0x38, 0x9a, 0x65, 0x2c, 0xa3, 0x24, 0xed}}
+#define MIID_BIRTHDAYNOTIFY {0xcfba5784, 0x3701, 0x4d83, {0x81, 0x6a, 0x19, 0x9c, 0x00, 0xd4, 0xa6, 0x7a}}
+#define MIID_BONSAI {0xcfaae811, 0x30e1, 0x4a4f, {0x87, 0x84, 0x15, 0x3c, 0xcc, 0xb0, 0x03, 0x7a}}
+#define MIID_EXCHANGE {0xcfd79a89, 0x9959, 0x4e65, {0xb0, 0x76, 0x41, 0x3f, 0x98, 0xfe, 0x0d, 0x15}}
+#define MIID_MIRPY {0xcff91a5c, 0x1786, 0x41c1, {0x88, 0x86, 0x09, 0x4b, 0x14, 0x28, 0x1f, 0x15}}
+#define MIID_SERVICESLIST {0xcf4bdf02, 0x5d27, 0x4241, {0x99, 0xe5, 0x19, 0x51, 0xaa, 0xb0, 0xc4, 0x54}}
+#define MIID_TRANSLATOR {0xcfb637b0, 0x7217, 0x4c1e, {0xb2, 0x2a, 0xd9, 0x22, 0x32, 0x3a, 0x5d, 0x0b}}
+#define MIID_TOOLTIPS {0xbcbda043, 0x2716, 0x4404, {0xb0, 0xfa, 0x3d, 0x2d, 0x93, 0x81, 0x9e, 0x3}}
+#define MIID_POPUPS {0x33299069, 0x1919, 0x4ff8, {0xb1, 0x31, 0x1d, 0x7, 0x21, 0x78, 0xa7, 0x66}}
+#define MIID_LOGWINDOW {0xc53afb90, 0xfa44, 0x4304, {0xbc, 0x9d, 0x6a, 0x84, 0x1c, 0x39, 0x05, 0xf5}}
+#define MIID_EVENTNOTIFY {0xF3D7EC5A, 0xF7EF, 0x45DD, {0x8C, 0xA5, 0xB0, 0xF6, 0xBA, 0x18, 0x64, 0x7B}}
+#define MIID_SRCONTACTS {0x7CA6050E, 0xBAF7, 0x42D2, {0xB9, 0x36, 0x0D, 0xB9, 0xDF, 0x57, 0x2B, 0x95}}
+#define MIID_HISTORYEXPORT {0x18fa2ade, 0xe31b, 0x4b5d, {0x95, 0x3d, 0xa, 0xb2, 0x57, 0x81, 0xc6, 0x4}}
+
+/* Special exception interface for protocols.
+ This interface allows more than one plugin to implement it at the same time
+*/
+#define MIID_PROTOCOL {0x2a3c815e, 0xa7d9, 0x424b, {0xba, 0x30, 0x2, 0xd0, 0x83, 0x22, 0x90, 0x85}}
+
+#define MIID_SERVICEMODE {0x8a92c026, 0x953a, 0x4f5f, { 0x99, 0x21, 0xf2, 0xc2, 0xdc, 0x19, 0x5e, 0xc5}}
+
+/* Each service mode plugin must implement MS_SERVICEMODE_LAUNCH */
+#define MS_SERVICEMODE_LAUNCH "ServiceMode/Launch"
+
+typedef struct {
+ int cbSize;
+ char *shortName;
+ DWORD version;
+ char *description;
+ char *author;
+ char *authorEmail;
+ char *copyright;
+ char *homepage;
+ BYTE flags; // right now the only flag, UNICODE_AWARE, is recognized here
+ int replacesDefaultModule; //one of the DEFMOD_ constants in m_plugins.h or zero
+ //if non-zero, this will supress the loading of the specified built-in module
+ //with the implication that this plugin provides back-end-compatible features
+ /*********** WILL BE DEPRECATED in 0.8 * *************/
+ MUUID uuid; // Not required until 0.8.
+} PLUGININFOEX;
+
+#ifndef MODULES_H_
+ typedef int (*MIRANDAHOOK)(WPARAM,LPARAM);
+ typedef int (*MIRANDAHOOKPARAM)(WPARAM,LPARAM,LPARAM);
+ typedef int (*MIRANDAHOOKOBJ)(void*,WPARAM,LPARAM);
+ typedef int (*MIRANDAHOOKOBJPARAM)(void*,WPARAM,LPARAM,LPARAM);
+
+ typedef INT_PTR (*MIRANDASERVICE)(WPARAM,LPARAM);
+ typedef INT_PTR (*MIRANDASERVICEPARAM)(WPARAM,LPARAM,LPARAM);
+ typedef INT_PTR (*MIRANDASERVICEOBJ)(void*,WPARAM,LPARAM);
+ typedef INT_PTR (*MIRANDASERVICEOBJPARAM)(void*,WPARAM,LPARAM,LPARAM);
+
+#ifdef _WIN64
+ #define CALLSERVICE_NOTFOUND ((INT_PTR)0x8000000000000000)
+#else
+ #define CALLSERVICE_NOTFOUND ((int)0x80000000)
+#endif
+
+#endif
+
+//see modules.h for what all this stuff is
+typedef struct tagPLUGINLINK {
+ HANDLE (*CreateHookableEvent)(const char *);
+ int (*DestroyHookableEvent)(HANDLE);
+ int (*NotifyEventHooks)(HANDLE,WPARAM,LPARAM);
+ HANDLE (*HookEvent)(const char *,MIRANDAHOOK);
+ HANDLE (*HookEventMessage)(const char *,HWND,UINT);
+ int (*UnhookEvent)(HANDLE);
+ HANDLE (*CreateServiceFunction)(const char *,MIRANDASERVICE);
+ HANDLE (*CreateTransientServiceFunction)(const char *,MIRANDASERVICE);
+ int (*DestroyServiceFunction)(HANDLE);
+ INT_PTR (*CallService)(const char *,WPARAM,LPARAM);
+ int (*ServiceExists)(const char *); //v0.1.0.1+
+ INT_PTR (*CallServiceSync)(const char *,WPARAM,LPARAM); //v0.3.3+
+ int (*CallFunctionAsync) (void (__stdcall *)(void *), void *); //v0.3.4+
+ int (*SetHookDefaultForHookableEvent) (HANDLE, MIRANDAHOOK); // v0.3.4 (2004/09/15)
+ HANDLE (*CreateServiceFunctionParam)(const char *,MIRANDASERVICEPARAM,LPARAM); // v0.7+ (2007/04/24)
+ int (*NotifyEventHooksDirect)(HANDLE,WPARAM,LPARAM); // v0.7+
+ #if MIRANDA_VER >= 0x800
+ INT_PTR (*CallProtoService)(const char *, const char *, WPARAM, LPARAM );
+ INT_PTR (*CallContactService)( HANDLE, const char *, WPARAM, LPARAM );
+ HANDLE (*HookEventParam)(const char *,MIRANDAHOOKPARAM,LPARAM);
+ HANDLE (*HookEventObj)(const char *,MIRANDAHOOKOBJ, void* );
+ HANDLE (*HookEventObjParam)(const char *, MIRANDAHOOKOBJPARAM, void*, LPARAM);
+ HANDLE (*CreateServiceFunctionObj)(const char *,MIRANDASERVICEOBJ,void*);
+ HANDLE (*CreateServiceFunctionObjParam)(const char *,MIRANDASERVICEOBJPARAM,void*,LPARAM);
+ void (*KillObjectServices)(void *);
+ void (*KillObjectEventHooks)(void *);
+ #endif
+} PLUGINLINK;
+
+#ifndef MODULES_H_
+ #ifndef NODEFINEDLINKFUNCTIONS
+ //relies on a global variable 'pluginLink' in the plugins
+ extern PLUGINLINK *pluginLink;
+ #define CreateHookableEvent(a) pluginLink->CreateHookableEvent(a)
+ #define DestroyHookableEvent(a) pluginLink->DestroyHookableEvent(a)
+ #define NotifyEventHooks(a,b,c) pluginLink->NotifyEventHooks(a,b,c)
+ #define HookEventMessage(a,b,c) pluginLink->HookEventMessage(a,b,c)
+ #define HookEvent(a,b) pluginLink->HookEvent(a,b)
+ #define UnhookEvent(a) pluginLink->UnhookEvent(a)
+ #define CreateServiceFunction(a,b) pluginLink->CreateServiceFunction(a,b)
+ #define CreateTransientServiceFunction(a,b) pluginLink->CreateTransientServiceFunction(a,b)
+ #define DestroyServiceFunction(a) pluginLink->DestroyServiceFunction(a)
+ #define CallService(a,b,c) pluginLink->CallService(a,b,c)
+ #define ServiceExists(a) pluginLink->ServiceExists(a)
+ #define CallServiceSync(a,b,c) pluginLink->CallServiceSync(a,b,c)
+ #define CallFunctionAsync(a,b) pluginLink->CallFunctionAsync(a,b)
+ #define SetHookDefaultForHookableEvent(a,b) pluginLink->SetHookDefaultForHookableEvent(a,b)
+ #define CreateServiceFunctionParam(a,b,c) pluginLink->CreateServiceFunctionParam(a,b,c)
+ #define NotifyEventHooksDirect(a,b,c) pluginLink->NotifyEventHooksDirect(a,b,c)
+ #if MIRANDA_VER >= 0x800
+ #define CallProtoService(a,b,c,d) pluginLink->CallProtoService(a,b,c,d)
+ #define CallContactService(a,b,c,d) pluginLink->CallContactService(a,b,c,d)
+ #define HookEventParam(a,b,c) pluginLink->HookEventParam(a,b,c)
+ #define HookEventObj(a,b,c) pluginLink->HookEventObj(a,b,c)
+ #define HookEventObjParam(a,b,c,d) pluginLink->HookEventObjParam(a,b,c,d)
+ #define CreateServiceFunctionObj(a,b,c) pluginLink->CreateServiceFunctionObj(a,b,c)
+ #define CreateServiceFunctionObjParam(a,b,c,d) pluginLink->CreateServiceFunctionObjParam(a,b,c,d)
+ #define KillObjectServices(a) pluginLink->KillObjectServices(a)
+ #define KillObjectEventHooks(a) pluginLink->KillObjectEventHooks(a)
+ #endif
+ #endif
+#endif
+
+/*
+ Database plugin stuff
+*/
+
+// grokHeader() error codes
+#define EGROKPRF_NOERROR 0
+#define EGROKPRF_CANTREAD 1 // can't open the profile for reading
+#define EGROKPRF_UNKHEADER 2 // header not supported, not a supported profile
+#define EGROKPRF_VERNEWER 3 // header correct, version in profile newer than reader/writer
+#define EGROKPRF_DAMAGED 4 // header/version fine, other internal data missing, damaged.
+
+// makeDatabase() error codes
+#define EMKPRF_CREATEFAILED 1 // for some reason CreateFile() didnt like something
+
+typedef struct {
+ int cbSize;
+
+ /*
+ returns what the driver can do given the flag
+ */
+ int (*getCapability) ( int flag );
+
+ /*
+ 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
+ */
+ int (*getFriendlyName) ( char * buf, size_t cch, int shortName );
+
+ /*
+ 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_*
+ */
+ int (*makeDatabase) ( char * profile, int * 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
+ */
+ int (*grokHeader) ( char * profile, int * 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
+ */
+ int (*Load) ( char * profile, void * link );
+
+ /*
+ 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.
+ */
+ int (*Unload) ( int wasLoaded );
+
+} DATABASELINK;
+
+#endif // M_NEWPLUGINAPI_H__
diff --git a/plugins/!NotAdopted/WinPopup/sdk/statusmodes.h b/plugins/!NotAdopted/WinPopup/sdk/statusmodes.h
new file mode 100644
index 0000000000..da973ab79c
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/sdk/statusmodes.h
@@ -0,0 +1,52 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2008 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+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 STATUSMODES_H__
+#define STATUSMODES_H__ 1
+
+//add 1 to ID_STATUS_CONNECTING to mark retries (v0.1.0.1+)
+//eg ID_STATUS_CONNECTING+2 is the third connection attempt, or the second retry
+#define ID_STATUS_CONNECTING 1
+
+//max retries is just a marker so that the clist knows what numbers represent
+//retries. It does not set any kind of limit on the number of retries you can
+//and/or should do.
+#define MAX_CONNECT_RETRIES 10000
+
+#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 MAX_STATUS_COUNT (ID_STATUS_OUTTOLUNCH-ID_STATUS_OFFLINE+1)
+
+#endif // STATUSMODES_H__
+
+
diff --git a/plugins/!NotAdopted/WinPopup/search.cpp b/plugins/!NotAdopted/WinPopup/search.cpp
new file mode 100644
index 0000000000..d8b4a8ec96
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/search.cpp
@@ -0,0 +1,330 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2009 Nikolay Raspopov
+
+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 "stdafx.h"
+
+#include "winpopup_proto.h"
+#include "search.h"
+#include "netbios.h"
+
+search pluginSearch;
+
+//
+bool MatchPattern (LPCTSTR String, LPCTSTR Pattern);
+// NetBIOS-
+bool MatchPatternNetBIOS (LPCTSTR Host, LPCTSTR Pattern);
+
+search::search()
+ : m_count( 0 )
+ , m_event( NULL )
+{
+}
+
+INT_PTR search::StartSearch(LPCTSTR szId)
+{
+ LOG("Search \"%s\"", szId);
+
+ if (m_event)
+ //
+ SetEvent (m_event);
+ else
+ m_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+
+ //
+ if ( BasicSearchData* data = new BasicSearchData )
+ {
+ data->me = this;
+ HANDLE cookie = data->cookie = GenerateCookie();
+ data->id = szId;
+ data->id.MakeUpper();
+ data->root = NULL;
+ mir_forkthread( BasicSearchThread, data );
+ return (INT_PTR)cookie;
+ }
+
+ return 0;
+}
+
+void search::AskForDestroy()
+{
+ if ( m_event )
+ SetEvent( m_event );
+}
+
+void search::Destroy()
+{
+ if ( m_event )
+ {
+ while( m_count )
+ {
+ SetEvent( m_event );
+ Sleep( 250 );
+ }
+ CloseHandle( m_event );
+ m_event = NULL;
+ }
+}
+
+bool MatchPattern (LPCTSTR String, LPCTSTR Pattern)
+{
+ TCHAR c, p, l;
+ for (;;)
+ {
+ switch ( p = *Pattern++ )
+ {
+ case 0:
+ // end of pattern
+ return *String ? false : true; // if end of string TRUE
+
+ case _T('*'):
+ // match zero or more char
+ while (*String)
+ if (MatchPattern (String++, Pattern))
+ return true;
+ return MatchPattern (String, Pattern);
+
+ case _T('?'):
+ // match any one char
+ if (*String++ == 0)
+ return false; // not end of string
+ break;
+
+ case _T('['):
+ // match char set
+ if ((c = *String++) == 0)
+ return false; // syntax
+ l = 0;
+ if (*Pattern == _T('!'))
+ { // match a char if NOT in set []
+ ++Pattern;
+ while ((p = *Pattern++)!= _T('\0'))
+ {
+ if (p == _T(']')) // if end of char set, then
+ break; // no match found
+ if (p == _T('-'))
+ { // check a range of chars?
+ p = *Pattern;
+ // get high limit of range
+ if (p == 0 || p == _T(']'))
+ return false; // syntax
+ if (c >= l && c <= p)
+ return false; // if in range
+ }
+ l = p;
+ // if char matches this element
+ if (c == p)
+ return false;
+ }
+ }
+ else
+ { // match if char is in set []
+ while ((p = *Pattern++) != _T('\0'))
+ {
+ if (p == _T(']')) // if end of char set, then
+ return false; // no match found
+ if (p == _T('-')) { // check a range of chars?
+ p = *Pattern;
+ // get high limit of range
+ if (p == 0 || p == _T(']'))
+ return false; // syntax
+ if (c >= l && c <= p)
+ break; // if in range, move on
+ }
+ l = p;
+ // if char matches this element
+ if (c == p)
+ break; // move on
+ }
+ while (p && p != _T(']')) // got a match in char set
+ p = *Pattern++; // skip to end of set
+ }
+ break;
+
+ case _T('#'):
+ c = *String++;
+ if (c < _T('0') || c > _T('9'))
+ return false; // not a digit
+ break;
+
+ default:
+ // check for exact char
+ c = *String++;
+ if (c != p)
+ return false; // not a match
+ break;
+ }
+ }
+}
+
+bool MatchPatternNetBIOS (LPCTSTR Host, LPCTSTR Pattern)
+{
+ netbios_name_list names;
+ if ( pluginNetBIOS.GetNames( names, Host, false ) )
+ {
+ POSITION pos = names.GetHeadPosition ();
+ CString n;
+ while ( pos )
+ {
+ netbios_name& name = names.GetNext (pos);
+ if ( name.GetType() == 3 )
+ {
+ CA2T sName( name.original );
+ if ( MatchPattern( (LPCTSTR)sName, Pattern ) )
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void search::BasicSearchJob(const BasicSearchData* data)
+{
+ if (WaitForSingleObject (m_event, 0) != WAIT_TIMEOUT)
+ return;
+
+ HANDLE hEnum = NULL;
+ DWORD res = WNetOpenEnum (RESOURCE_GLOBALNET, RESOURCETYPE_ANY,
+ RESOURCEUSAGE_CONTAINER, data->root, &hEnum);
+ if (res == NO_ERROR)
+ {
+ for (;;)
+ {
+ if (WaitForSingleObject (m_event, 0) != WAIT_TIMEOUT)
+ return;
+
+ DWORD cCount = 1;
+ DWORD BufferSize = 4096;
+ char* Buffer = (char*)mir_alloc( BufferSize );
+ if ( ! Buffer )
+ break;
+ res = WNetEnumResource( hEnum, &cCount, Buffer, &BufferSize );
+ if ( res == NO_ERROR )
+ {
+ if (WaitForSingleObject (m_event, 0) != WAIT_TIMEOUT)
+ return;
+
+ LPNETRESOURCE lpnr = (LPNETRESOURCE)Buffer;
+ if ( lpnr->dwDisplayType == RESOURCEDISPLAYTYPE_SERVER )
+ {
+ //
+ // , ,
+ CharUpper (lpnr->lpRemoteName);
+ CString comment;
+ if (lpnr->lpComment)
+ {
+ comment = lpnr->lpComment;
+ CharUpper (lpnr->lpComment);
+ }
+ if (MatchPattern (lpnr->lpRemoteName + 2, data->id) ||
+ (lpnr->lpComment && MatchPattern (lpnr->lpComment, data->id)) ||
+ (data->root && MatchPattern (data->root->lpRemoteName, data->id)) ||
+ MatchPatternNetBIOS (lpnr->lpRemoteName + 2, data->id))
+ {
+ //
+ PROTOSEARCHRESULT psr = {};
+ psr.cbSize = sizeof( PROTOSEARCHRESULT );
+ CT2A RemoteNameA( lpnr->lpRemoteName );
+ psr.nick = RemoteNameA + 2;
+ CT2A commentA( comment );
+ psr.firstName = commentA;
+ CT2A RootNameA( data->root ? data->root->lpRemoteName : _T("") );
+ psr.lastName = RootNameA;
+ psr.email = "";
+ ProtoBroadcastAck (modname, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA,
+ data->cookie, (LPARAM) &psr);
+ }
+ }
+ else
+ {
+ if ( ( lpnr->dwUsage & 0xffff ) == RESOURCEUSAGE_CONTAINER )
+ {
+ if ( BasicSearchData* data1 = new BasicSearchData )
+ {
+ data1->me = data->me;
+ data1->cookie = data->cookie;
+ data1->id = data->id;
+ data1->root = lpnr;
+ Buffer = NULL;
+ res = (DWORD)InterlockedIncrement (&m_count);
+ mir_forkthread( BasicSearchThread, data1 );
+ }
+ }
+ }
+ mir_free( Buffer );
+ }
+ else
+ {
+ mir_free( Buffer );
+ break;
+ }
+ }
+ WNetCloseEnum (hEnum);
+ }
+}
+
+void search::BasicSearchThread(LPVOID param)
+{
+ if ( BasicSearchData* data = (BasicSearchData*)param )
+ {
+ data->me->BasicSearch( data );
+ if ( data->root ) mir_free( data->root );
+ delete data;
+ }
+}
+
+void search::BasicSearch(const BasicSearchData* data)
+{
+ // ?
+ if ( data->root == NULL )
+ {
+ while( m_count )
+ {
+ if ( ! pluginInstalled )
+ return;
+
+ // ,
+ Sleep (100);
+ }
+ InterlockedIncrement( &m_count );
+ ResetEvent( m_event );
+ }
+
+ // ?
+ if ( pluginInstalled )
+ {
+ BasicSearchJob( data );
+
+ LONG res = InterlockedDecrement( &m_count );
+ _ASSERTE( res >= 0 );
+ if ( res == 0 )
+ {
+ // ?
+ if ( WaitForSingleObject( m_event, 0 ) != WAIT_OBJECT_0 )
+ {
+ ProtoBroadcastAck (modname, NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, data->cookie, 0);
+ }
+ else
+ {
+ LOG("Search aborted by another search");
+ }
+ }
+ }
+}
diff --git a/plugins/!NotAdopted/WinPopup/search.h b/plugins/!NotAdopted/WinPopup/search.h
new file mode 100644
index 0000000000..04be93a14c
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/search.h
@@ -0,0 +1,60 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2009 Nikolay Raspopov
+
+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
+
+class search
+{
+public:
+ search();
+
+ //
+ INT_PTR StartSearch(LPCTSTR szId);
+
+ //
+ void AskForDestroy();
+
+ //
+ void Destroy();
+
+protected:
+ typedef struct _BasicSearchData
+ {
+ search* me; //
+ HANDLE cookie; //
+ CString id; // (uppercase)
+ LPNETRESOURCE root; // (mir_alloc)
+ } BasicSearchData;
+
+ HANDLE m_event; //
+ volatile LONG m_count; //
+
+ //
+ void BasicSearch(const BasicSearchData* data);
+
+ //
+ void BasicSearchJob(const BasicSearchData* data);
+
+ //
+ static void BasicSearchThread(LPVOID param);
+};
+
+extern search pluginSearch;
diff --git a/plugins/!NotAdopted/WinPopup/services.cpp b/plugins/!NotAdopted/WinPopup/services.cpp
new file mode 100644
index 0000000000..70462cf189
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/services.cpp
@@ -0,0 +1,1003 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2010 Nikolay Raspopov
+
+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 "stdafx.h"
+
+#include "m_uninstaller.h" // Uninstaller plugin
+#include "m_updater.h" // Updater plugin
+
+#include "winpopup_proto.h"
+#include "services.h"
+#include "netbios.h"
+#include "options.h"
+#include "user_info.h"
+#include "add_dialog.h"
+#include "chat.h"
+#include "search.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+// "\\Nick" ShellExecute() ("Nick" )
+// wParam=hContact
+// lParam=0
+// 0
+#define PS_EXPLORE "/Explore"
+
+// /
+// wParam=Position
+// lParam=0
+// 0
+#define PS_ADDDIALOG "/AddDialog"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+// WinPopup Protocol/Explore
+INT_PTR Explore(WPARAM wParam, LPARAM lParam);
+// WinPopup Protocol/AddDialog
+INT_PTR AddDialog(WPARAM wParam, LPARAM lParam);
+// WinPopup Protocol/GetCaps
+INT_PTR GetCaps(WPARAM flagNum, LPARAM lParam);
+// WinPopup Protocol/GetName
+INT_PTR GetName(WPARAM cchName, LPARAM szName);
+// WinPopup Protocol/LoadIcon
+INT_PTR LoadIcon(WPARAM whichIcon, LPARAM lParam);
+// WinPopup Protocol/SetStatus
+INT_PTR SetStatus(WPARAM newStatus, LPARAM lParam);
+// WinPopup Protocol/SetAwayMsg
+INT_PTR SetAwayMsg(WPARAM status_mode, LPARAM szMessage);
+// WinPopup Protocol/GetAwayMsg
+INT_PTR GetAwayMsg(WPARAM wParam, LPARAM lParam);
+// WinPopup Protocol/GetStatus
+INT_PTR GetStatus(WPARAM wParam, LPARAM lParam);
+// WinPopup Protocol/GetInfo
+INT_PTR GetInfo(WPARAM flags, LPARAM lParam);
+// WinPopup Protocol/RecvMessage
+INT_PTR RecvMessage(WPARAM flags, LPARAM lParam);
+// WinPopup Protocol/SendMsg
+INT_PTR SendMsg(WPARAM flags, LPARAM lParam);
+// WinPopup Protocol/BasicSearch
+INT_PTR BasicSearch(WPARAM wParam, LPARAM szId);
+// WinPopup Protocol/AddToList
+INT_PTR AddToList(WPARAM flags, LPARAM lParam);
+// WinPopup Protocol/GetAvatarCaps
+INT_PTR GetAvatarCaps(WPARAM wParam, LPARAM lParam);
+// WinPopup Protocol/GetAvatarInformation
+INT_PTR GetAvatarInfo(WPARAM flags, LPARAM lParam);
+// WinPopup Protocol/SetMyAvatar
+INT_PTR SetMyAvatar(WPARAM wParam, LPARAM lParam);
+// WinPopup Protocol/GetMyAvatar
+INT_PTR GetMyAvatar(WPARAM wParam, LPARAM lParam);
+// WinPopup Protocol/CreateAccMgrUI
+INT_PTR CreateAccMgrUI(WPARAM wParam, LPARAM lParam);
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+//
+PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion);
+// v.0.8+
+PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion);
+//
+const MUUID* MirandaPluginInterfaces(void);
+// ( Uninstall)
+int UninstallEx(PLUGINUNINSTALLPARAMS* ppup);
+//
+int Load(PLUGINLINK *link);
+//
+int Unload();
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+// ME_SYSTEM_MODULESLOADED
+int __cdecl SYSTEM_MODULESLOADED(WPARAM wParam, LPARAM lParam);
+// ME_SYSTEM_PRESHUTDOWN
+int __cdecl SYSTEM_PRESHUTDOWN(WPARAM wParam, LPARAM lParam);
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+const PROTOCOLDESCRIPTOR pluginPD =
+{
+ sizeof( PROTOCOLDESCRIPTOR ),
+ modname,
+ PROTOTYPE_PROTOCOL
+};
+
+static PLUGININFOEX pluginInfoEx =
+{
+ sizeof( PLUGININFOEX ),
+#ifdef _UNICODE
+ modname " (Unicode)",
+#else
+ modname,
+#endif
+ PLUGIN_MAKE_VERSION (0,0,0,18),
+ "Allows you to send and receive messages over Microsoft LAN. "
+ "WinPopup and Net Send replacement powered by Miranda IM.",
+ "Nikolay Raspopov",
+ "ryo-oh-ki@narod.ru",
+ " 2004-2010 Nikolay Raspopov",
+ "http://www.cherubicsoft.com/miranda/",
+ UNICODE_AWARE,
+ 0, /* TODO: DEFMOD_PROTOCOLSMB */
+#ifdef _UNICODE
+ // {DE6EE412-ACE3-45db-A329-D618FABB4291}
+ { 0xde6ee412, 0xace3, 0x45db, { 0xa3, 0x29, 0xd6, 0x18, 0xfa, 0xbb, 0x42, 0x91 } }
+#else
+ // {7682703D-753E-4074-80A4-F9105CA7E94D}
+ { 0x7682703d, 0x753e, 0x4074, { 0x80, 0xa4, 0xf9, 0x10, 0x5c, 0xa7, 0xe9, 0x4d } }
+#endif
+};
+
+const MUUID pluginInterfaces[] =
+{
+ MIID_PROTOCOL,
+ MIID_LAST
+};
+
+PLUGINLINK* pluginLink = NULL;
+MM_INTERFACE memoryManagerInterface = {};
+HANDLE plugin_FnGetCaps = NULL;
+HANDLE plugin_FnGetName = NULL;
+HANDLE plugin_FnLoadIcon = NULL;
+HANDLE plugin_FnSetStatus = NULL;
+HANDLE plugin_FnGetStatus = NULL;
+HANDLE plugin_FnGetAwayMsg = NULL;
+HANDLE plugin_FnSetAwayMsg = NULL;
+HANDLE plugin_FnGetInfo = NULL;
+HANDLE plugin_FnSendMsg = NULL;
+HANDLE plugin_FnRecvMessage = NULL;
+HANDLE plugin_FnBasicSearch = NULL;
+HANDLE plugin_FnAddToList = NULL;
+HANDLE plugin_FnExplore = NULL;
+HANDLE plugin_FnAddDialog = NULL;
+HANDLE plugin_FnGetAvatarCaps = NULL;
+HANDLE plugin_FnGetAvatarInfo = NULL;
+HANDLE plugin_FnSetMyAvatar = NULL;
+HANDLE plugin_FnGetMyAvatar = NULL;
+HANDLE plugin_FnCreateAccMgrUI = NULL;
+HANDLE plugin_SYSTEM_MODULESLOADED = NULL;
+HANDLE plugin_SYSTEM_PRESHUTDOWN = NULL;
+HANDLE plugin_OPT_INITIALISE = NULL;
+HANDLE plugin_USERINFO_INITIALISE = NULL;
+
+/////////////////////////////////////////////////////////////////////////////
+// DllLoader
+
+DllLoader pluginNetapi32 ( _T("netapi32.dll"), false);
+DllLoader pluginAdvapi32 ( _T("advapi32.dll"), false);
+FuncPtrType(NET_API_STATUS (NET_API_FUNCTION *) (LMSTR, DWORD, LPBYTE*) ) fnNetWkstaGetInfo;
+FuncPtrType(DWORD (NET_API_FUNCTION *) (LPVOID) ) fnNetApiBufferFree;
+FuncPtrType(DWORD (NET_API_FUNCTION *) (LPCWSTR, LPCWSTR, LPCWSTR, LPBYTE, DWORD) ) fnNetMessageBufferSend;
+FuncPtrType(SC_HANDLE (WINAPI *) (LPCTSTR, LPCTSTR, DWORD) ) fnOpenSCManager;
+FuncPtrType(SC_HANDLE (WINAPI *) (SC_HANDLE, LPCTSTR, DWORD) ) fnOpenService;
+FuncPtrType(BOOL (WINAPI *) (SC_HANDLE, DWORD, LPSERVICE_STATUS) ) fnControlService;
+FuncPtrType(BOOL (WINAPI *) (SC_HANDLE, LPSERVICE_STATUS) ) fnQueryServiceStatus;
+FuncPtrType(BOOL (WINAPI *) (SC_HANDLE) ) fnCloseServiceHandle;
+FuncPtrType(BOOL (WINAPI *) (SC_HANDLE, DWORD, LPCTSTR*) ) fnStartService;
+FuncPtrType(SC_LOCK (WINAPI *) (SC_HANDLE) ) fnLockServiceDatabase;
+FuncPtrType(BOOL (WINAPI *) (SC_LOCK) ) fnUnlockServiceDatabase;
+FuncPtrType(BOOL (WINAPI *) (SC_HANDLE, DWORD, DWORD, DWORD, LPCTSTR, LPCTSTR, LPDWORD, LPCTSTR, LPCTSTR, LPCTSTR, LPCTSTR) ) fnChangeServiceConfig;
+
+#define CreateHook( hService, szName, Function ) \
+ _ASSERT( hService == NULL ); \
+ hService = HookEvent( szName, Function ); \
+ _ASSERT ( hService != NULL ); \
+ if ( ! hService ) return 1;
+
+#define DestroyHook( hService ) \
+ if ( hService ) { \
+ UnhookEvent( hService ); \
+ hService = NULL; \
+ }
+
+#define CreateServiceFn( hService, szName, Function ) \
+ _ASSERT( hService == NULL ); \
+ hService = CreateServiceFunction( modname szName, Function ); \
+ _ASSERT( hService != NULL ); \
+ if ( ! hService ) return 1;
+
+#ifdef _DEBUG
+ #define DestroyServiceFn( hService ) \
+ if( hService ) { \
+ _ASSERT( DestroyServiceFunction( hService ) == 0 ); \
+ hService = NULL; \
+ }
+#else // _DEBUG
+ #define DestroyServiceFn( hService ) \
+ if( hService ) { \
+ DestroyServiceFunction( hService ); \
+ hService = NULL; \
+ }
+#endif // _DEBUG
+
+
+INT_PTR Explore(WPARAM wParam, LPARAM /* lParam */)
+{
+ CString sNick = GetNick( (HANDLE)wParam );
+ if ( pluginInstalled && ! sNick.IsEmpty() )
+ {
+ // UNC : \\Nick
+ CString cmd( _T("\\\\") );
+ cmd += sNick;
+ ShellExecute( NULL, NULL, cmd, NULL, NULL, SW_SHOWDEFAULT );
+ }
+ return 0;
+}
+
+INT_PTR AddDialog (WPARAM /* wParam */, LPARAM /* lParam */)
+{
+ AddDialog( NULL );
+ return 0;
+}
+
+INT_PTR GetCaps (WPARAM flagNum, LPARAM /* lParam */)
+{
+ INT_PTR nReturn = 0;
+ switch ( flagNum )
+ {
+ case PFLAGNUM_1:
+ nReturn = PF1_IM | PF1_BASICSEARCH | PF1_MODEMSG | PF1_PEER2PEER;
+ break;
+
+ case PFLAGNUM_2:
+ case PFLAGNUM_3:
+ nReturn = PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_LONGAWAY |
+ PF2_LIGHTDND | PF2_HEAVYDND | PF2_FREECHAT |
+ PF2_ONTHEPHONE | PF2_OUTTOLUNCH;
+ break;
+
+ case PFLAGNUM_4:
+ nReturn = PF4_AVATARS;
+ break;
+
+ case PFLAGNUM_5:
+ nReturn = 0;
+ break;
+
+ case PFLAG_UNIQUEIDTEXT:
+ nReturn = (INT_PTR)Translate ("Computer,User,Group");
+ break;
+
+ case PFLAG_UNIQUEIDSETTING:
+ nReturn = (INT_PTR)"Nick";
+ break;
+
+ case PFLAG_MAXLENOFMESSAGE:
+ // HANDLE hContact = (HANDLE) lParam;
+ nReturn = 0x7fffffff;
+ break;
+ }
+ return nReturn;
+}
+
+INT_PTR GetName(WPARAM cchName, LPARAM szName)
+{
+ lstrcpynA( (char*) szName, modtitle, static_cast <int>( cchName ) );
+ return 0;
+}
+
+INT_PTR LoadIcon(WPARAM whichIcon, LPARAM /* lParam */)
+{
+ UINT id;
+ switch ( whichIcon & 0xFFFF )
+ {
+ case PLI_PROTOCOL:
+ id = IDI_WINPOPUP;
+ break;
+
+ case PLI_ONLINE:
+ id = IDI_ONLINE;
+ break;
+
+ case PLI_OFFLINE:
+ id = IDI_OFFLINE;
+ break;
+
+ default:
+ return 0;
+ }
+ return (INT_PTR)LoadImage (pluginModule, MAKEINTRESOURCE (id), IMAGE_ICON,
+ (whichIcon & PLIF_SMALL ? 16 : 32), (whichIcon & PLIF_SMALL ? 16 : 32), 0);
+}
+
+INT_PTR SetStatus (WPARAM newStatus, LPARAM /* lParam */)
+{
+ if ( pluginInstalled && pluginCurrentStatus != (int)newStatus )
+ {
+ LOG ("SetStatus from \"%s\" to \"%s\"",
+ STATUS2TEXT(pluginCurrentStatus), STATUS2TEXT(newStatus));
+
+ pluginRequestedStatus = newStatus;
+ switch (newStatus) {
+ case ID_STATUS_OFFLINE:
+ GotoOffline ();
+ break;
+ case ID_STATUS_FREECHAT:
+ case ID_STATUS_INVISIBLE:
+ newStatus = ID_STATUS_ONLINE;
+ case ID_STATUS_ONLINE:
+ case ID_STATUS_AWAY:
+ case ID_STATUS_DND:
+ case ID_STATUS_NA:
+ case ID_STATUS_OCCUPIED:
+ case ID_STATUS_ONTHEPHONE:
+ case ID_STATUS_OUTTOLUNCH:
+ default:
+ GotoOnline ();
+ break;
+ }
+ }
+ return 0;
+}
+
+INT_PTR SetAwayMsg (WPARAM status_mode, LPARAM szMessage)
+{
+ pluginStatusMessage[ status_mode ] = ( szMessage ? (LPCSTR) szMessage : "" );
+ return 0;
+}
+
+INT_PTR GetAwayMsg(WPARAM /* wParam */, LPARAM lParam)
+{
+ CCSDATA *ccs = (CCSDATA*)lParam;
+ if ( pluginInstalled && ccs && ccs->hContact )
+ {
+ if ( ContactData* data = new ContactData )
+ {
+ data->hContact = ccs->hContact;
+ HANDLE cookie = data->cookie = GenerateCookie();
+ mir_forkthread( GetAwayMsgThread, data );
+ return (INT_PTR)cookie;
+ }
+ }
+ return 0;
+}
+
+INT_PTR GetStatus (WPARAM /* wParam */, LPARAM /* lParam */)
+{
+ return (INT_PTR)pluginCurrentStatus;
+}
+
+INT_PTR GetInfo (WPARAM /* flags */, LPARAM lParam)
+{
+ CCSDATA* ccs = (CCSDATA*)lParam;
+ if ( pluginInstalled && ccs && ccs->hContact )
+ {
+ mir_forkthread( GetInfoThread, ccs->hContact );
+ return 0;
+ }
+ return 1;
+}
+
+INT_PTR RecvMessage (WPARAM /* flags */, LPARAM lParam)
+{
+ CCSDATA* ccs = (CCSDATA*) lParam;
+ if ( pluginInstalled && ccs && ccs->hContact && ccs->lParam)
+ {
+ PROTORECVEVENT *pre = (PROTORECVEVENT*) ccs->lParam;
+
+ //
+ DBDeleteContactSetting (ccs->hContact, "CList", "Hidden");
+ DBEVENTINFO ei = { 0 };
+ ei.cbSize = sizeof (DBEVENTINFO);
+ ei.szModule = modname;
+ ei.timestamp = pre->timestamp;
+ ei.flags = (pre->flags & PREF_CREATEREAD) ? DBEF_READ : 0u;
+ ei.eventType = EVENTTYPE_MESSAGE;
+ ei.cbBlob = (DWORD)( lstrlenA (pre->szMessage) + 1 );
+ ei.pBlob = (PBYTE) pre->szMessage;
+ CallService (MS_DB_EVENT_ADD, (WPARAM) ccs->hContact, (LPARAM) &ei);
+ }
+ return 0;
+}
+
+INT_PTR SendMsg(WPARAM /* flags */, LPARAM lParam)
+{
+ CCSDATA* ccs = (CCSDATA*) lParam;
+ if ( pluginInstalled && ccs && ccs->hContact && ccs->lParam )
+ {
+ if ( SendMsgData* data = new SendMsgData )
+ {
+ data->hContact = ccs->hContact;
+ data->text = (LPCSTR)ccs->lParam;
+ HANDLE cookie = data->cookie = GenerateCookie();
+ mir_forkthread( SendMsgThread, data );
+ return (INT_PTR)cookie;
+ }
+ }
+ return 0;
+}
+
+INT_PTR BasicSearch(WPARAM /* wParam */, LPARAM szId)
+{
+ if ( pluginInstalled && szId )
+ {
+ return pluginSearch.StartSearch( CA2T( (LPCSTR)szId ) );
+ }
+ return 0;
+}
+
+INT_PTR AddToList(WPARAM flags, LPARAM lParam)
+{
+ PROTOSEARCHRESULT* psr = (PROTOSEARCHRESULT*) lParam;
+ if ( psr && psr->cbSize >= sizeof (PROTOSEARCHRESULT) && psr->nick && *psr->nick )
+ {
+ CString sName( psr->nick );
+ CString sNotes( psr->firstName );
+ return (INT_PTR)AddToListByName( sName, flags, sNotes, false, false );
+ }
+ return 0;
+}
+
+INT_PTR GetAvatarCaps(WPARAM wParam, LPARAM lParam)
+{
+ switch ( wParam )
+ {
+ case AF_MAXSIZE:
+ if ( POINT* size = (POINT*)lParam )
+ {
+ size->x = 300; // -1 - - avs.dll
+ size->y = 300; // -1 - - avs.dll
+ }
+ break;
+
+ case AF_PROPORTION:
+ return PIP_NONE;
+
+ case AF_FORMATSUPPORTED:
+ switch ( lParam )
+ {
+ case PA_FORMAT_UNKNOWN:
+ case PA_FORMAT_PNG:
+ case PA_FORMAT_JPEG:
+ case PA_FORMAT_ICON:
+ case PA_FORMAT_BMP:
+ case PA_FORMAT_GIF:
+ case PA_FORMAT_SWF:
+ case PA_FORMAT_XML:
+ return 1;
+ }
+ break;
+
+ case AF_ENABLED:
+ return 1;
+
+ case AF_DONTNEEDDELAYS:
+ return 1;
+
+ case AF_MAXFILESIZE:
+ return MAX_AVATAR_SIZE;
+
+ case AF_DELAYAFTERFAIL:
+ return 10 * 60 * 1000; // 10
+ }
+
+ return 0;
+}
+
+INT_PTR GetAvatarInfo(WPARAM /*flags*/, LPARAM lParam)
+{
+ PROTO_AVATAR_INFORMATION* pai = (PROTO_AVATAR_INFORMATION*)lParam;
+ if ( pai && pai->cbSize >= sizeof( PROTO_AVATAR_INFORMATION ) )
+ {
+ if ( ContactData* data = new ContactData )
+ {
+ data->hContact = pai->hContact;
+ /*HANDLE cookie =*/ data->cookie = GenerateCookie();
+ mir_forkthread( GetAvatarInfoThread, data );
+ return GAIR_WAITFOR;
+ }
+ }
+ return GAIR_NOAVATAR;
+}
+
+INT_PTR SetMyAvatar(WPARAM /*wParam*/, LPARAM lParam)
+{
+ CA2T szFilename( (LPCSTR)lParam );
+
+ TCHAR szPath[ MAX_PATH ];
+ GetAvatarCache( szPath );
+
+ if ( szFilename )
+ {
+ //
+ lstrcat( szPath, _T("MyAvatar") );
+ lstrcat( szPath, _tcsrchr( szFilename, _T('.') ) );
+
+ if ( lstrcmpi( szPath, szFilename ) == 0 )
+ {
+ // -
+ }
+ else
+ {
+ // -
+ SHFILEOPSTRUCT sfo = {};
+ sfo.hwnd = GetDesktopWindow();
+ sfo.wFunc = FO_COPY;
+ TCHAR szFrom[ MAX_PATH ] = {};
+ lstrcpy( szFrom, szFilename );
+ sfo.pFrom = szFrom;
+ sfo.pTo = szPath;
+ sfo.fFlags = FOF_ALLOWUNDO | FOF_FILESONLY | FOF_NORECURSION |
+ FOF_NOCONFIRMATION;
+ SHFileOperation( &sfo );
+ }
+
+ DBWriteContactSettingTString( NULL, modname, "AvatarFile",
+ _tcsrchr( szPath, _T('\\') ) + 1 );
+ }
+ else
+ {
+ //
+ DBVARIANT dbv = {};
+ if ( ! DBGetContactSettingTString( NULL, modname, "AvatarFile", &dbv ) )
+ {
+ lstrcat( szPath, dbv.ptszVal );
+
+ SHFILEOPSTRUCT sfo = {};
+ sfo.hwnd = GetDesktopWindow();
+ sfo.wFunc = FO_DELETE;
+ sfo.pFrom = szPath;
+ sfo.fFlags = FOF_ALLOWUNDO | FOF_FILESONLY | FOF_NORECURSION |
+ FOF_NOCONFIRMATION;
+ SHFileOperation( &sfo );
+
+ DBFreeVariant( &dbv );
+
+ DBDeleteContactSetting( NULL, modname, "AvatarFile" );
+ }
+ }
+
+ return 0;
+}
+
+INT_PTR GetMyAvatar(WPARAM wParam, LPARAM lParam)
+{
+ LPSTR szFilename = (LPSTR)wParam;
+ int nLength = (int)lParam;
+ bool ret = false;
+
+ if ( szFilename == NULL || nLength < MAX_PATH )
+ return -1;
+
+ TCHAR szPath[ MAX_PATH ];
+ GetAvatarCache( szPath );
+
+ DBVARIANT dbv = {};
+ if ( ! DBGetContactSettingTString( NULL, modname, "AvatarFile", &dbv ) )
+ {
+ lstrcat( szPath, dbv.ptszVal );
+
+ ret = ( GetFileAttributes( szPath ) != INVALID_FILE_ATTRIBUTES );
+
+ DBFreeVariant( &dbv );
+ }
+
+ if ( ! ret )
+ return -1;
+
+ lstrcpyA( szFilename, CT2A( szPath ) );
+
+ return 0;
+}
+
+static INT_PTR CALLBACK DlgProcCreateAccMgrUI(HWND hwndDlg, UINT Msg,
+ WPARAM /*wParam*/, LPARAM /*lParam*/)
+{
+ switch ( Msg )
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault( hwndDlg );
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+INT_PTR CreateAccMgrUI(WPARAM /*wParam*/, LPARAM lParam)
+{
+ return (INT_PTR)CreateDialogParam( pluginModule, MAKEINTRESOURCE( IDD_CREATE ),
+ (HWND)lParam, DlgProcCreateAccMgrUI, 0 );
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ pluginInfoEx.cbSize = sizeof( PLUGININFO );
+ return ( mirandaVersion < MIRANDA_VER ) ? NULL : (PLUGININFO*)&pluginInfoEx;
+}
+
+PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ pluginInfoEx.cbSize = sizeof( PLUGININFOEX );
+ return ( mirandaVersion < MIRANDA_VER ) ? NULL : &pluginInfoEx;
+}
+
+const MUUID* MirandaPluginInterfaces(void)
+{
+ return pluginInterfaces;
+}
+
+int Load(PLUGINLINK *link)
+{
+ _ASSERT (pluginLink == NULL);
+ pluginLink = link;
+
+ _ASSERT (pluginLink != NULL);
+ if ( ! pluginLink )
+ return 1;
+
+ GetVersionEx( &pluginOS );
+
+ if (pluginNetapi32.LoadLibrary (pluginModule))
+ {
+ pluginNetapi32.LoadFunc (fnNetWkstaGetInfo, "NetWkstaGetInfo");
+ pluginNetapi32.LoadFunc (fnNetApiBufferFree, "NetApiBufferFree");
+ pluginNetapi32.LoadFunc (fnNetMessageBufferSend, "NetMessageBufferSend");
+ }
+
+ if (pluginAdvapi32.LoadLibrary (pluginModule))
+ {
+#ifdef _UNICODE
+ pluginAdvapi32.LoadFunc (fnOpenSCManager, "OpenSCManagerW");
+ pluginAdvapi32.LoadFunc (fnOpenService, "OpenServiceW");
+ pluginAdvapi32.LoadFunc (fnStartService, "StartServiceW");
+ pluginAdvapi32.LoadFunc (fnChangeServiceConfig, "ChangeServiceConfigW");
+#else
+ pluginAdvapi32.LoadFunc (fnOpenSCManager, "OpenSCManagerA");
+ pluginAdvapi32.LoadFunc (fnOpenService, "OpenServiceA");
+ pluginAdvapi32.LoadFunc (fnStartService, "StartServiceA");
+ pluginAdvapi32.LoadFunc (fnChangeServiceConfig, "ChangeServiceConfigA");
+#endif
+ pluginAdvapi32.LoadFunc (fnControlService, "ControlService");
+ pluginAdvapi32.LoadFunc (fnQueryServiceStatus, "QueryServiceStatus");
+ pluginAdvapi32.LoadFunc (fnCloseServiceHandle, "CloseServiceHandle");
+ pluginAdvapi32.LoadFunc (fnLockServiceDatabase, "LockServiceDatabase");
+ pluginAdvapi32.LoadFunc (fnUnlockServiceDatabase, "UnlockServiceDatabase");
+ }
+
+ _ASSERT( pluginInternalState == NULL );
+ pluginInternalState = CreateEvent( NULL, TRUE, TRUE, NULL );
+ _ASSERT( pluginInternalState != NULL );
+
+ memoryManagerInterface.cbSize = sizeof( MM_INTERFACE );
+ CallService( MS_SYSTEM_GET_MMI, 0, (LPARAM)&memoryManagerInterface );
+
+ INT_PTR retCallService = CallService (MS_PROTO_REGISTERMODULE, 0, (LPARAM) &pluginPD);
+ _ASSERT (retCallService != CALLSERVICE_NOTFOUND);
+ if ( retCallService == CALLSERVICE_NOTFOUND ) return 1;
+
+ CreateServiceFn( plugin_FnGetCaps, PS_GETCAPS, GetCaps );
+ CreateServiceFn( plugin_FnGetName, PS_GETNAME, GetName );
+ CreateServiceFn( plugin_FnLoadIcon, PS_LOADICON, LoadIcon );
+ CreateServiceFn( plugin_FnSetStatus, PS_SETSTATUS, SetStatus );
+ CreateServiceFn( plugin_FnGetStatus, PS_GETSTATUS, GetStatus );
+ CreateServiceFn( plugin_FnSetAwayMsg, PS_SETAWAYMSG, SetAwayMsg );
+ CreateServiceFn( plugin_FnGetAwayMsg, PSS_GETAWAYMSG, GetAwayMsg );
+ CreateServiceFn( plugin_FnGetInfo, PSS_GETINFO, GetInfo );
+ CreateServiceFn( plugin_FnSendMsg, PSS_MESSAGE, SendMsg );
+ CreateServiceFn( plugin_FnRecvMessage, PSR_MESSAGE, RecvMessage );
+ CreateServiceFn( plugin_FnBasicSearch, PS_BASICSEARCH, BasicSearch );
+ CreateServiceFn( plugin_FnAddToList, PS_ADDTOLIST, AddToList );
+ CreateServiceFn( plugin_FnExplore, PS_EXPLORE, Explore );
+ CreateServiceFn( plugin_FnAddDialog, PS_ADDDIALOG, AddDialog);
+ CreateServiceFn( plugin_FnGetAvatarCaps, PS_GETAVATARCAPS, GetAvatarCaps );
+ CreateServiceFn( plugin_FnGetAvatarInfo, PS_GETAVATARINFO, GetAvatarInfo );
+ CreateServiceFn( plugin_FnSetMyAvatar, PS_SETMYAVATAR, SetMyAvatar );
+ CreateServiceFn( plugin_FnGetMyAvatar, PS_GETMYAVATAR, GetMyAvatar );
+ CreateServiceFn( plugin_FnCreateAccMgrUI, PS_CREATEACCMGRUI, CreateAccMgrUI );
+
+ CreateHook( plugin_SYSTEM_MODULESLOADED, ME_SYSTEM_MODULESLOADED, SYSTEM_MODULESLOADED );
+ CreateHook( plugin_SYSTEM_PRESHUTDOWN, ME_SYSTEM_PRESHUTDOWN, SYSTEM_PRESHUTDOWN );
+
+ pluginInstalled = true;
+
+ return 0;
+}
+
+int Unload()
+{
+#ifdef CHAT_ENABLED
+ ChatUnregister();
+#endif // CHAT_ENABLED
+
+ DestroyHook( plugin_USERINFO_INITIALISE );
+ DestroyHook( plugin_OPT_INITIALISE );
+ DestroyHook( plugin_SYSTEM_PRESHUTDOWN );
+ DestroyHook( plugin_SYSTEM_MODULESLOADED );
+
+ DestroyServiceFn( plugin_FnExplore );
+ DestroyServiceFn( plugin_FnAddDialog );
+ DestroyServiceFn( plugin_FnGetCaps );
+ DestroyServiceFn( plugin_FnGetName );
+ DestroyServiceFn( plugin_FnLoadIcon );
+ DestroyServiceFn( plugin_FnSetStatus );
+ DestroyServiceFn( plugin_FnGetStatus );
+ DestroyServiceFn( plugin_FnSetAwayMsg );
+ DestroyServiceFn( plugin_FnGetAwayMsg );
+ DestroyServiceFn( plugin_FnGetInfo );
+ DestroyServiceFn( plugin_FnSendMsg );
+ DestroyServiceFn( plugin_FnRecvMessage );
+ DestroyServiceFn( plugin_FnBasicSearch );
+ DestroyServiceFn( plugin_FnAddToList );
+ DestroyServiceFn( plugin_FnGetAvatarCaps );
+ DestroyServiceFn( plugin_FnGetAvatarInfo );
+ DestroyServiceFn( plugin_FnSetMyAvatar );
+ DestroyServiceFn( plugin_FnGetMyAvatar );
+ DestroyServiceFn( plugin_FnCreateAccMgrUI );
+
+ if ( pluginNetLibUser != NULL )
+ Netlib_CloseHandle( pluginNetLibUser );
+ pluginNetLibUser = NULL;
+
+ if ( pluginInternalState != NULL )
+ CloseHandle( pluginInternalState );
+ pluginInternalState = NULL;
+
+ pluginLink = NULL;
+
+ pluginNetapi32.FreeLibrary();
+ pluginAdvapi32.FreeLibrary();
+
+ return 0;
+}
+
+int UninstallEx (PLUGINUNINSTALLPARAMS* ppup)
+{
+ pluginInstalled = false;
+
+ // ( )
+ if ( ppup->bIsMirandaRunning == TRUE )
+ {
+ GotoOffline();
+ WaitForSingleObject( pluginInternalState, INFINITE );
+ }
+
+ //
+ const char* apszFiles[] =
+ {
+ "winpopup_proto_readme.txt",
+ "winpopup_proto_translation.txt",
+ NULL
+ };
+ PUIRemoveFilesInDirectory(ppup->pszPluginsPath, apszFiles);
+
+ if (ppup->bDoDeleteSettings == TRUE)
+ {
+ if (ppup->bIsMirandaRunning == TRUE)
+ {
+ PUIRemoveDbSettingGlobally ("Icons", "WinPopup Protocol40071");
+ PUIRemoveDbSettingGlobally ("Icons", "WinPopup Protocol40072");
+ PUIRemoveDbSettingGlobally ("Icons", "WinPopup Protocol40073");
+ PUIRemoveDbSettingGlobally ("Icons", "WinPopup Protocol40074");
+ PUIRemoveDbSettingGlobally ("Icons", "WinPopup Protocol40075");
+ PUIRemoveDbSettingGlobally ("Icons", "WinPopup Protocol40076");
+ PUIRemoveDbSettingGlobally ("Icons", "WinPopup Protocol40077");
+ PUIRemoveDbSettingGlobally ("Icons", "WinPopup Protocol40078");
+ PUIRemoveDbSettingGlobally ("Icons", "WinPopup Protocol40079");
+ PUIRemoveDbSettingGlobally ("Icons", "WinPopup Protocol40080");
+ PUIRemoveDbModule (modname);
+ }
+ }
+
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+//
+
+int __cdecl SYSTEM_MODULESLOADED (WPARAM /* wParam */, LPARAM /* lParam */)
+{
+ _ASSERT (pluginInstalled == true);
+ _ASSERT (pluginInitialized == false);
+
+ _ASSERT (pluginNetLibUser == NULL);
+ const NETLIBUSER nlu =
+ {
+ sizeof( NETLIBUSER ),
+ modname,
+ modname,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0
+ };
+ pluginNetLibUser = (HANDLE)CallService( MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu );
+ _ASSERT (pluginNetLibUser);
+
+ CreateHook( plugin_OPT_INITIALISE, ME_OPT_INITIALISE, OPT_INITIALISE );
+ CreateHook( plugin_USERINFO_INITIALISE, ME_USERINFO_INITIALISE, USERINFO_INITIALISE );
+
+ //
+ struct
+ {
+ int icon_id;
+ int status;
+ }
+ const StatusIcons [] =
+ {
+ { IDI_OFFLINE, ID_STATUS_OFFLINE },
+ { IDI_ONLINE, ID_STATUS_ONLINE },
+ { IDI_AWAY, ID_STATUS_AWAY },
+ { IDI_DND, ID_STATUS_DND },
+ { IDI_NA, ID_STATUS_NA },
+ { IDI_OCCUPIED, ID_STATUS_OCCUPIED },
+ { IDI_FREECHAT, ID_STATUS_FREECHAT },
+ { IDI_INVISIBLE, ID_STATUS_INVISIBLE },
+ { IDI_ONTHEPHONE, ID_STATUS_ONTHEPHONE },
+ { IDI_OUTTOLUNCH, ID_STATUS_OUTTOLUNCH },
+ { 0, 0 }
+ };
+ TCHAR path [ MAX_PATH * 2 ] = { 0 };
+ TCHAR icon [ 32 ] = { 0 };
+ DWORD len = GetModuleFileName (pluginModule, path, MAX_PATH);
+ lstrcpy( path + len, _T(",-") );
+ len += 2;
+ for (int i = 0; StatusIcons[i].icon_id ; i++)
+ {
+ wsprintf( path + len, _T("%d"), StatusIcons[i].icon_id );
+ wsprintf( icon, modname_t _T("%d"), StatusIcons[i].status );
+ DBVARIANT dbv = {};
+ if ( ! DBGetContactSetting( NULL, "Icons", CT2A( icon ), &dbv ) )
+ DBFreeVariant( &dbv );
+ else
+ DBWriteContactSettingTString( NULL, "Icons", CT2A( icon ), path );
+ }
+
+ //
+ DWORD iMachineNameLength = MAX_COMPUTERNAME_LENGTH + 2;
+ GetComputerName(
+ pluginMachineName.GetBuffer( (int)iMachineNameLength ), &iMachineNameLength );
+ pluginMachineName.ReleaseBuffer();
+ SetNick( NULL, pluginMachineName );
+
+ //
+ DWORD iUserNameLength = UNLEN + 2;
+ GetUserName(
+ pluginUserName.GetBuffer( (int)iUserNameLength ), &iUserNameLength );
+ pluginUserName.ReleaseBuffer();
+ DBWriteContactSettingTString( NULL, modname, "User", pluginUserName );
+
+ //
+ if ( pluginOS.dwPlatformId == VER_PLATFORM_WIN32_NT )
+ {
+ WKSTA_INFO_100* info = NULL;
+ NET_API_STATUS err = fnNetWkstaGetInfo (NULL, 100, (LPBYTE*) &info);
+ if (err == NERR_Success && info)
+ {
+ LPTSTR langroup = mir_u2t( info->wki100_langroup );
+ pluginDomainName = langroup;
+ fnNetApiBufferFree (info);
+ mir_free( langroup );
+ }
+ // ?
+ // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
+ // DefaultDomainName
+ }
+ else
+ {
+ HKEY hKey = NULL;
+ if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE,
+ _T("System\\CurrentControlSet\\Services\\VxD\\VNETSUP"), 0, KEY_READ, &hKey))
+ {
+ DWORD type, size = MAX_PATH;
+ RegQueryValueEx (hKey, _T("Workgroup"), 0, &type,
+ (LPBYTE) pluginDomainName.GetBuffer (MAX_PATH + 1), &size);
+ pluginDomainName.ReleaseBuffer( (int)size );
+ RegCloseKey (hKey);
+ }
+ }
+ DBWriteContactSettingTString (NULL, modname, "Workgroup", pluginDomainName);
+
+ // Updater
+ CallService( MS_UPDATE_REGISTERFL, 1202, (LPARAM)&pluginInfoEx );
+
+ // Chat
+#ifdef CHAT_ENABLED
+ pluginChatEnabled = ChatRegister();
+#endif // CHAT_ENABLED
+
+ //
+ CLISTMENUITEM miExplore =
+ {
+ sizeof( CLISTMENUITEM ),
+ (LPSTR)TranslateT( "Explore" ),
+ CMIF_TCHAR,
+ 0,
+ (HICON)LoadImage( pluginModule, MAKEINTRESOURCE( IDI_EXPLORE ),
+ IMAGE_ICON, 16, 16, LR_SHARED ),
+ modname PS_EXPLORE,
+ NULL,
+ 0,
+ 0,
+ modname
+ };
+ CallService( MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&miExplore );
+
+ CLISTMENUITEM miAddContact =
+ {
+ sizeof( CLISTMENUITEM ),
+ NULL,
+ CMIF_TCHAR,
+ 500090000,
+ (HICON)LoadImage( pluginModule, MAKEINTRESOURCE( IDI_WINPOPUP ),
+ IMAGE_ICON, 16, 16, LR_SHARED ),
+ modname PS_ADDDIALOG,
+ NULL,
+ 0,
+ 0,
+ NULL
+ };
+ miAddContact.ptszName = (LPTSTR)TranslateT( "Add contact..." );
+ miAddContact.ptszPopupName = (LPTSTR)modtitle_t;
+
+ HANDLE hMenuItem =
+ (HANDLE)CallService( MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&miAddContact );
+ //
+ miAddContact.flags = CMIM_ICON;
+ miAddContact.hIcon = (HICON)LoadImage( pluginModule,
+ MAKEINTRESOURCE( IDI_ADD_COMPUTER ), IMAGE_ICON, 16, 16, LR_SHARED ),
+ CallService( MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenuItem, (LPARAM)&miAddContact );
+
+ // (, )
+ pluginInitialized = true;
+
+ //
+ SetStatus( pluginRequestedStatus, 0 );
+
+ return 0;
+}
+
+int __cdecl SYSTEM_PRESHUTDOWN (WPARAM /* wParam */, LPARAM /* lParam */)
+{
+ // (, )
+ pluginInstalled = false;
+
+ // , ..
+ // ,
+ do
+ {
+ MSG msg;
+ while ( PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE ) )
+ {
+ if ( IsDialogMessage( msg.hwnd, &msg ) ) continue;
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+ }
+ while ( MsgWaitForMultipleObjects( 1, &pluginInternalState, FALSE,
+ INFINITE, QS_ALLINPUT ) == WAIT_OBJECT_0 + 1 );
+
+ return 0;
+}
diff --git a/plugins/!NotAdopted/WinPopup/services.h b/plugins/!NotAdopted/WinPopup/services.h
new file mode 100644
index 0000000000..d2b439b0a1
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/services.h
@@ -0,0 +1,36 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2009 Nikolay Raspopov
+
+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
+
+// DllLoader
+extern FuncPtrType(NET_API_STATUS (NET_API_FUNCTION *) (LMSTR, DWORD, LPBYTE*) ) fnNetWkstaGetInfo;
+extern FuncPtrType(DWORD (NET_API_FUNCTION *) (LPVOID) ) fnNetApiBufferFree;
+extern FuncPtrType(DWORD (NET_API_FUNCTION *) (LPCWSTR, LPCWSTR, LPCWSTR, LPBYTE, DWORD) ) fnNetMessageBufferSend;
+extern FuncPtrType(SC_HANDLE (WINAPI *) (LPCTSTR, LPCTSTR, DWORD) ) fnOpenSCManager;
+extern FuncPtrType(SC_HANDLE (WINAPI *) (SC_HANDLE, LPCTSTR, DWORD) ) fnOpenService;
+extern FuncPtrType(BOOL (WINAPI *) (SC_HANDLE, DWORD, LPSERVICE_STATUS) ) fnControlService;
+extern FuncPtrType(BOOL (WINAPI *) (SC_HANDLE, LPSERVICE_STATUS) ) fnQueryServiceStatus;
+extern FuncPtrType(BOOL (WINAPI *) (SC_HANDLE) ) fnCloseServiceHandle;
+extern FuncPtrType(BOOL (WINAPI *) (SC_HANDLE, DWORD, LPCTSTR*) ) fnStartService;
+extern FuncPtrType(SC_LOCK (WINAPI *) (SC_HANDLE) ) fnLockServiceDatabase;
+extern FuncPtrType(BOOL (WINAPI *) (SC_LOCK) ) fnUnlockServiceDatabase;
+extern FuncPtrType(BOOL (WINAPI *) (SC_HANDLE, DWORD, DWORD, DWORD, LPCTSTR, LPCTSTR, LPDWORD, LPCTSTR, LPCTSTR, LPCTSTR, LPCTSTR) ) fnChangeServiceConfig;
diff --git a/plugins/!NotAdopted/WinPopup/smbconst.h b/plugins/!NotAdopted/WinPopup/smbconst.h
new file mode 100644
index 0000000000..e876df693f
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/smbconst.h
@@ -0,0 +1,108 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2006 Nikolay Raspopov
+
+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
+
+#define SMBmkdir 0x00 /* create directory */
+#define SMBrmdir 0x01 /* delete directory */
+#define SMBopen 0x02 /* open file */
+#define SMBcreate 0x03 /* create file */
+#define SMBclose 0x04 /* close file */
+#define SMBflush 0x05 /* flush file */
+#define SMBunlink 0x06 /* delete file */
+#define SMBmv 0x07 /* rename file */
+#define SMBgetatr 0x08 /* get file attributes */
+#define SMBsetatr 0x09 /* set file attributes */
+#define SMBread 0x0A /* read from file */
+#define SMBwrite 0x0B /* write to file */
+#define SMBlock 0x0C /* lock byte range */
+#define SMBunlock 0x0D /* unlock byte range */
+#define SMBctemp 0x0E /* create temporary file */
+#define SMBmknew 0x0F /* make new file */
+#define SMBchkpth 0x10 /* check directory path */
+#define SMBexit 0x11 /* process exit */
+#define SMBlseek 0x12 /* seek */
+#define SMBtcon 0x70 /* tree connect */
+#define SMBtconX 0x75 /* tree connect and X*/
+#define SMBtdis 0x71 /* tree disconnect */
+#define SMBnegprot 0x72 /* negotiate protocol */
+#define SMBdskattr 0x80 /* get disk attributes */
+#define SMBsearch 0x81 /* search directory */
+#define SMBsplopen 0xC0 /* open print spool file */
+#define SMBsplwr 0xC1 /* write to print spool file */
+#define SMBsplclose 0xC2 /* close print spool file */
+#define SMBsplretq 0xC3 /* return print queue */
+#define SMBsends 0xD0 /* send single block message */
+#define SMBsendb 0xD1 /* send broadcast message */
+#define SMBfwdname 0xD2 /* forward user name */
+#define SMBcancelf 0xD3 /* cancel forward */
+#define SMBgetmac 0xD4 /* get machine name */
+#define SMBsendstrt 0xD5 /* send start of multi-block message */
+#define SMBsendend 0xD6 /* send end of multi-block message */
+#define SMBsendtxt 0xD7 /* send text of multi-block message */
+
+/* Core+ protocol */
+#define SMBlockread 0x13 /* Lock a range and read */
+#define SMBwriteunlock 0x14 /* Unlock a range then write */
+#define SMBreadbraw 0x1a /* read a block of data with no smb header */
+#define SMBwritebraw 0x1d /* write a block of data with no smb header */
+#define SMBwritec 0x20 /* secondary write request */
+#define SMBwriteclose 0x2c /* write a file then close it */
+
+/* dos extended protocol */
+#define SMBreadBraw 0x1A /* read block raw */
+#define SMBreadBmpx 0x1B /* read block multiplexed */
+#define SMBreadBs 0x1C /* read block (secondary response) */
+#define SMBwriteBraw 0x1D /* write block raw */
+#define SMBwriteBmpx 0x1E /* write block multiplexed */
+#define SMBwriteBs 0x1F /* write block (secondary request) */
+#define SMBwriteC 0x20 /* write complete response */
+#define SMBsetattrE 0x22 /* set file attributes expanded */
+#define SMBgetattrE 0x23 /* get file attributes expanded */
+#define SMBlockingX 0x24 /* lock/unlock byte ranges and X */
+#define SMBtrans 0x25 /* transaction - name, bytes in/out */
+#define SMBtranss 0x26 /* transaction (secondary request/response) */
+#define SMBioctl 0x27 /* IOCTL */
+#define SMBioctls 0x28 /* IOCTL (secondary request/response) */
+#define SMBcopy 0x29 /* copy */
+#define SMBmove 0x2A /* move */
+#define SMBecho 0x2B /* echo */
+#define SMBopenX 0x2D /* open and X */
+#define SMBreadX 0x2E /* read and X */
+#define SMBwriteX 0x2F /* write and X */
+#define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */
+#define SMBffirst 0x82 /* find first */
+#define SMBfunique 0x83 /* find unique */
+#define SMBfclose 0x84 /* find close */
+#define SMBinvalid 0xFE /* invalid command */
+
+/* Extended 2.0 protocol */
+#define SMBtrans2 0x32 /* TRANS2 protocol set */
+#define SMBtranss2 0x33 /* TRANS2 protocol set, secondary command */
+#define SMBfindclose 0x34 /* Terminate a TRANSACT2_FINDFIRST */
+#define SMBfindnclose 0x35 /* Terminate a TRANSACT2_FINDNOTIFYFIRST */
+#define SMBulogoffX 0x74 /* user logoff */
+
+/* NT SMB extensions. */
+#define SMBnttrans 0xA0 /* NT transact */
+#define SMBnttranss 0xA1 /* NT transact secondary */
+#define SMBntcreateX 0xA2 /* NT create and X */
+#define SMBntcancel 0xA4 /* NT cancel */
diff --git a/plugins/!NotAdopted/WinPopup/stdafx.cpp b/plugins/!NotAdopted/WinPopup/stdafx.cpp
new file mode 100644
index 0000000000..d994fedc70
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/stdafx.cpp
@@ -0,0 +1,22 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2009 Nikolay Raspopov
+
+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 "stdafx.h"
diff --git a/plugins/!NotAdopted/WinPopup/stdafx.h b/plugins/!NotAdopted/WinPopup/stdafx.h
new file mode 100644
index 0000000000..7814d6681c
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/stdafx.h
@@ -0,0 +1,136 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2011 Nikolay Raspopov
+
+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
+
+//
+#define WINVER 0x0500 // Windows 2000 compatible
+#define _WIN32_WINNT 0x0500 // Windows 2000 compatible
+#define _WIN32_WINDOWS 0x0500 // Windows 2000 compatible
+#define _WIN32_IE 0x0500 // IE 5 compatible
+
+#define MIRANDA_VER 0x0700 // Miranda 0.7.x compatible
+
+#define STRICT
+#define WIN32_LEAN_AND_MEAN
+#define NOCOMM
+#define NOSERVICE
+#define NOHELP
+#define NOSOUND
+#define NOPRINT
+
+#define _ATL_NO_COM_SUPPORT
+#define _ATL_NO_EXCEPTIONS
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+#define _ATL_CSTRING_NO_CRT
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
+
+#define _CRT_SECURE_NO_WARNINGS
+
+// Disable warnings enabled by /Wall option
+#pragma warning (disable: 4619) // warning C4619: #pragma warning : there is no warning number
+#pragma warning (disable: 4625) // warning C4625: '' : copy constructor could not be generated because a base class copy constructor is inaccessible
+#pragma warning (disable: 4626) // warning C4626: '' : assignment operator could not be generated because a base class assignment operator is inaccessible
+#pragma warning (disable: 4711) // warning C4711: function '' selected for automatic inline expansion
+
+// Temporary disable warnings
+#pragma warning (disable: 4100)
+#pragma warning (disable: 4191)
+#pragma warning (disable: 4365)
+
+#include "resource.h"
+
+// Common headers
+#include <atlbase.h>
+#include <atlstr.h>
+#include <atlcoll.h>
+#include <atlfile.h>
+
+#include <prsht.h>
+#include <winsock.h>
+#include <lm.h>
+#include <nb30.h>
+#include <process.h>
+#include <commctrl.h>
+#include <psapi.h>
+#include <tlhelp32.h>
+#include <shellapi.h>
+
+#ifdef _DEBUG
+ #define _CRTDBG_MAP_ALLOC
+ #include <crtdbg.h>
+ #define DEBUG_NEW new(_CLIENT_BLOCK,THIS_FILE,__LINE__)
+#else
+ #define DEBUG_NEW
+#endif // _DEBUG
+
+// Miranda SDK headers
+#include "statusmodes.h"
+#include "newpluginapi.h" // uses m_plugins.h
+#include "m_system.h"
+#include "m_clist.h"
+#include "m_database.h"
+#include "m_langpack.h"
+#include "m_netlib.h" // uses m_utils.h
+#include "m_options.h"
+#include "m_popup.h"
+#include "m_protocols.h"
+#include "m_protomod.h"
+#include "m_protosvc.h"
+#include "m_userinfo.h"
+#include "m_chat.h"
+#include "m_avatars.h"
+
+using namespace ATL;
+
+typedef class CComCritSecLock< CComAutoCriticalSection > CLock;
+
+#ifdef _DEBUG
+ #define ALMOST_INFINITE (INFINITE) //
+#else
+ #define ALMOST_INFINITE (20000) // 20
+#endif
+
+inline LPSTR lstrnchr(LPSTR s, const CHAR c, int n) throw ()
+{
+ for (; n; --n, ++s)
+ if (c == *s)
+ return s;
+ return NULL;
+}
+
+inline LPTSTR lstrnrchr(LPTSTR s, const TCHAR c, int n) throw ()
+{
+ s += n;
+ for (; n; --n, --s)
+ if (c == *s)
+ return s;
+ return NULL;
+}
+
+#include "dllLoaderMinimal.h"
+
+// Enable warnings
+#pragma warning (default: 4100)
+#pragma warning (default: 4191)
+#pragma warning (default: 4365)
+
+// #define CHAT_ENABLED
diff --git a/plugins/!NotAdopted/WinPopup/user_info.cpp b/plugins/!NotAdopted/WinPopup/user_info.cpp
new file mode 100644
index 0000000000..ddaf2cda37
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/user_info.cpp
@@ -0,0 +1,334 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2011 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "winpopup_proto.h"
+#include "user_info.h"
+#include "netbios.h"
+#include "chat.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+#define WM_FILLTREE (WM_USER+75)
+
+typedef struct _FillTreeThreadData
+{
+ HMODULE hContact;
+ HWND hwndDlg;
+} FillTreeThreadData;
+
+typedef struct _FillTreeData
+{
+ netbios_name_list nns;
+ CString host;
+ CString about;
+} FillTreeData;
+
+typedef struct _DlgDataUserInfo
+{
+ HMODULE hContact;
+ HIMAGELIST hTreeImages;
+ bool bWorking;
+} DlgDataUserInfo;
+
+static void FillTreeThread (LPVOID param)
+{
+ FillTreeThreadData* fttd = (FillTreeThreadData*)param;
+
+ //
+ CString sNick = GetNick( fttd->hContact );
+ if ( ! sNick.IsEmpty() )
+ {
+ bool bGroup = IsGroup( fttd->hContact );
+
+ //
+ if ( FillTreeData* ftd = new FillTreeData )
+ {
+ ftd->host = sNick;
+
+ if ( ! bGroup )
+ // NetBIOS-
+ pluginNetBIOS.GetNames( ftd->nns, ftd->host, false );
+
+ //
+ DWORD buf_size = 4096;
+ if ( NETRESOURCE* buf = (NETRESOURCE*)mir_alloc( buf_size ) )
+ {
+ CString remote( _T("\\\\") );
+ if ( bGroup )
+ remote = (LPCTSTR)ftd->host;
+ else
+ remote += (LPCTSTR)ftd->host;
+
+ NETRESOURCE nr = {};
+ nr.dwScope = RESOURCE_GLOBALNET;
+ nr.lpRemoteName = const_cast <LPTSTR>(static_cast <LPCTSTR>(remote));
+ LPTSTR sys = NULL;
+ if ( WNetGetResourceInformation( &nr, buf, &buf_size, &sys ) == NO_ERROR )
+ {
+ ftd->about = buf->lpComment;
+ DBWriteContactSettingTString( fttd->hContact, modname,
+ "About", ftd->about );
+ }
+
+ mir_free( buf );
+ }
+
+ // ...
+ if ( ! IsWindow( fttd->hwndDlg ) ||
+ ! PostMessage( fttd->hwndDlg, WM_FILLTREE, 0, reinterpret_cast< LPARAM >( ftd ) ) )
+ delete ftd;
+ }
+ }
+
+ mir_free( fttd );
+}
+
+static INT_PTR CALLBACK DlgProcUserInfo (HWND hwndDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ DlgDataUserInfo* data = reinterpret_cast <DlgDataUserInfo*> (GetWindowLongPtr(hwndDlg, DWLP_USER));
+
+ switch (Msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault (hwndDlg);
+
+ data = (DlgDataUserInfo*)mir_alloc( sizeof( DlgDataUserInfo ) );
+ if ( ! data )
+ return FALSE;
+
+ SetWindowLongPtr (hwndDlg, DWLP_USER, reinterpret_cast <LONG> (data));
+ data->hTreeImages = ImageList_Create (16, 16, ILC_COLOR8 | ILC_MASK, 5, 0);
+ data->bWorking = false;
+
+ ImageList_AddIcon (data->hTreeImages, reinterpret_cast <HICON> (LoadImage ( // 0
+ pluginModule, MAKEINTRESOURCE (IDI_COMPUTER), IMAGE_ICON, 16, 16, LR_SHARED )));
+
+ ImageList_AddIcon (data->hTreeImages, reinterpret_cast <HICON> (LoadImage ( // 1
+ pluginModule, MAKEINTRESOURCE (IDI_GOOD_NAME), IMAGE_ICON, 16, 16, LR_SHARED )));
+
+ ImageList_AddIcon (data->hTreeImages, reinterpret_cast <HICON> (LoadImage ( // 2
+ pluginModule, MAKEINTRESOURCE (IDI_GOOD_NAMES), IMAGE_ICON, 16, 16, LR_SHARED )));
+
+ ImageList_AddIcon (data->hTreeImages, reinterpret_cast <HICON> (LoadImage ( // 3
+ pluginModule, MAKEINTRESOURCE (IDI_LANA), IMAGE_ICON, 16, 16, LR_SHARED )));
+
+ ImageList_AddIcon (data->hTreeImages, reinterpret_cast <HICON> (LoadImage ( // 4
+ pluginModule, MAKEINTRESOURCE (IDI_COMPUTER_ERROR), IMAGE_ICON, 16, 16, LR_SHARED )));
+
+ TreeView_SetImageList (GetDlgItem (hwndDlg, IDC_TREE), data->hTreeImages, TVSIL_NORMAL);
+
+ return TRUE;
+ }
+
+ case WM_DESTROY:
+ {
+ SetWindowLongPtr (hwndDlg, DWLP_USER, NULL);
+ if (data) {
+ ImageList_Destroy (data->hTreeImages);
+ mir_free( data );
+ }
+ break;
+ }
+
+ case WM_FILLTREE:
+ // ...
+ if ( FillTreeData* ftd = reinterpret_cast <FillTreeData*> (lParam) )
+ {
+ if ( data )
+ {
+ //
+ HWND hTree = GetDlgItem (hwndDlg, IDC_TREE);
+ TreeView_DeleteAllItems (hTree);
+ TVINSERTSTRUCT tvis = { 0 };
+ tvis.hParent = TVI_ROOT;
+ tvis.hInsertAfter = TVI_LAST;
+ tvis.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
+ tvis.item.pszText = const_cast <LPTSTR>(static_cast<LPCTSTR>(ftd->host));
+ tvis.item.iImage = tvis.item.iSelectedImage =
+ IsGroup( data->hContact ) ? 2 :
+ ( ftd->nns.GetCount() ? 0 : 4 );
+ tvis.hParent = TreeView_InsertItem (hTree, &tvis);
+ if ( ftd->nns.GetCount() )
+ {
+ for (POSITION pos = ftd->nns.GetHeadPosition (); pos;)
+ {
+ netbios_name& nname = ftd->nns.GetNext (pos);
+ CA2T textT( nname.GetANSIFullName() );
+ tvis.item.pszText = (LPTSTR) (LPCTSTR) textT;
+ tvis.item.iImage = tvis.item.iSelectedImage = (nname.IsGroupName () ? 2 : 1);
+ TreeView_InsertItem (hTree, &tvis);
+ }
+ }
+ TreeView_Expand (hTree, tvis.hParent, TVE_EXPAND);
+
+ SetDlgItemText (hwndDlg, IDC_ABOUT, ftd->about);
+
+ data->bWorking = false;
+ }
+ delete ftd;
+ }
+ return TRUE;
+
+ case WM_NOTIFY:
+ {
+ LPPSHNOTIFY lpHdr = reinterpret_cast <LPPSHNOTIFY> (lParam);
+ if (lpHdr->hdr.idFrom == 0)
+ {
+ //
+ data->hContact = reinterpret_cast <HMODULE> (lpHdr->lParam);
+ switch (lpHdr->hdr.code)
+ {
+ case PSN_INFOCHANGED:
+ {
+ // "Always Online"
+ BOOL b = DBGetContactSettingByte ( data->hContact, modname,
+ "AlwaysOnline", FALSE );
+ CheckDlgButton (hwndDlg, IDC_ONLINE_CHECK,
+ (UINT)( b ? BST_CHECKED : BST_UNCHECKED ) );
+ EnableWindow (GetDlgItem (hwndDlg, IDC_ONLINE_CHECK),
+ data->hContact != NULL );
+
+ // "Legacy online status detection"
+ CheckDlgButton( hwndDlg, IDC_CHECK00FORONLINE,(UINT)(
+ IsLegacyOnline( data->hContact ) ? BST_CHECKED : BST_UNCHECKED ) );
+ EnableWindow( GetDlgItem( hwndDlg, IDC_CHECK00FORONLINE ),
+ data->hContact != NULL );
+
+ // "Group Contact"
+ CheckDlgButton (hwndDlg, IDC_GROUP, (UINT)(
+ IsGroup( data->hContact ) ? BST_CHECKED : BST_UNCHECKED ) );
+ EnableWindow( GetDlgItem( hwndDlg, IDC_GROUP ),
+ data->hContact != NULL );
+
+ // NetBIOS-
+ if ( data && ! data->bWorking )
+ {
+ HWND hTree = GetDlgItem (hwndDlg, IDC_TREE);
+ data->bWorking = true;
+ TreeView_DeleteAllItems (hTree);
+ TVINSERTSTRUCT tvis = { 0 };
+ tvis.hParent = TVI_ROOT;
+ tvis.hInsertAfter = TVI_LAST;
+ tvis.item.mask = TVIF_TEXT;
+ tvis.item.pszText = TranslateT ("Retrieving...");
+ TreeView_InsertItem (hTree, &tvis);
+
+ SetDlgItemText (hwndDlg, IDC_ABOUT, _T(""));
+
+ if ( FillTreeThreadData* fttd = (FillTreeThreadData*)mir_alloc( sizeof( FillTreeThreadData ) ) )
+ {
+ fttd->hContact = data->hContact;
+ fttd->hwndDlg = hwndDlg;
+ mir_forkthread( FillTreeThread, fttd );
+ }
+ }
+ break;
+ }
+
+ case PSN_KILLACTIVE:
+ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE);
+ return TRUE;
+
+ case PSN_APPLY:
+ {
+ BOOL f_now = (IsDlgButtonChecked (hwndDlg, IDC_ONLINE_CHECK) ==
+ BST_CHECKED) ? TRUE : FALSE;
+ BOOL f_old = DBGetContactSettingByte ( data->hContact, modname,
+ "AlwaysOnline", FALSE );
+ DBWriteContactSettingByte (data->hContact, modname,
+ "AlwaysOnline", (BYTE)( f_now ? TRUE : FALSE ) );
+ if ( ! f_old && f_now )
+ SetContactStatus( data->hContact, ID_STATUS_ONLINE, true );
+ else if ( f_old && ! f_now )
+ SetContactStatus( data->hContact, ID_STATUS_OFFLINE, true );
+
+ SetLegacyOnline( data->hContact, ( IsDlgButtonChecked( hwndDlg,
+ IDC_CHECK00FORONLINE ) == BST_CHECKED ) );
+
+ SetGroup( data->hContact,
+ IsDlgButtonChecked( hwndDlg, IDC_GROUP ) == BST_CHECKED );
+
+ SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR );
+ return TRUE;
+ }
+ }
+ }
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_ONLINE_CHECK:
+ {
+ BOOL f_now = (IsDlgButtonChecked (hwndDlg, IDC_ONLINE_CHECK) ==
+ BST_CHECKED) ? TRUE : FALSE;
+ BOOL f_old = DBGetContactSettingByte ( data->hContact, modname,
+ "AlwaysOnline", FALSE );
+
+ if ( f_old != f_now )
+ PropSheet_Changed (GetParent (hwndDlg), hwndDlg);
+ else
+ PropSheet_UnChanged (GetParent (hwndDlg), hwndDlg);
+
+ return TRUE;
+ }
+
+ case IDC_CHECK00FORONLINE:
+ {
+ PropSheet_Changed (GetParent (hwndDlg), hwndDlg);
+ return TRUE;
+ }
+
+ case IDC_GROUP:
+ {
+ PropSheet_Changed (GetParent (hwndDlg), hwndDlg);
+ return TRUE;
+ }
+ }
+ break;
+ }
+ }
+ return FALSE;
+}
+
+int __cdecl USERINFO_INITIALISE (WPARAM wParam, LPARAM lParam)
+{
+ HANDLE hContact = (HANDLE)lParam;
+ if ( ! hContact || ( IsMyContact( hContact ) /*&& ! IsChatRoom( hContact )*/ ) )
+ {
+ OPTIONSDIALOGPAGE odp = {};
+ odp.cbSize = sizeof( OPTIONSDIALOGPAGE );
+ odp.hInstance = pluginModule;
+ odp.pszTemplate = MAKEINTRESOURCEA( IDD_USERINFO );
+ odp.pszTitle = modtitle;
+ odp.pfnDlgProc = DlgProcUserInfo;
+ CallService (MS_USERINFO_ADDPAGE, wParam, (LPARAM)&odp);
+ }
+ return 0;
+}
diff --git a/plugins/!NotAdopted/WinPopup/user_info.h b/plugins/!NotAdopted/WinPopup/user_info.h
new file mode 100644
index 0000000000..6873c91783
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/user_info.h
@@ -0,0 +1,24 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2006 Nikolay Raspopov
+
+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
+
+int __cdecl USERINFO_INITIALISE (WPARAM wParam, LPARAM lParam);
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto.cpp b/plugins/!NotAdopted/WinPopup/winpopup_proto.cpp
new file mode 100644
index 0000000000..8fdf41db70
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto.cpp
@@ -0,0 +1,1217 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2011 Nikolay Raspopov
+
+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 "stdafx.h"
+#include "winpopup_proto.h"
+#include "services.h"
+#include "mailslot.h"
+#include "netbios.h"
+#include "scanner.h"
+#include "messenger.h"
+#include "messagebox.h"
+#include "scanner.h"
+#include "search.h"
+#include "chat.h"
+#include "md5.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+volatile WPARAM pluginRequestedStatus = ID_STATUS_OFFLINE;
+volatile WPARAM pluginCurrentStatus = ID_STATUS_OFFLINE;
+CIntStrMap pluginStatusMessage;
+CString pluginMachineName;
+CString pluginUserName;
+CString pluginDomainName;
+HMODULE pluginModule = NULL;
+volatile bool pluginBusy = false;
+volatile bool pluginInstalled = false;
+volatile bool pluginInitialized = false;
+HANDLE pluginNetLibUser = NULL;
+HANDLE pluginInternalState = NULL;
+bool pluginChatEnabled = false;
+OSVERSIONINFO pluginOS = { sizeof( OSVERSIONINFO ) };
+
+CComAutoCriticalSection pluginGuard; // :
+CThreadContactMap pluginAwayThreadMap; // -
+CThreadContactMap pluginAvatarThreadMap; //
+
+CString GetNick(HANDLE hContact)
+{
+ CString sNick;
+ DBVARIANT dbv = {};
+ if ( ! DBGetContactSettingTString( hContact, modname, "Nick", &dbv ) )
+ {
+ sNick = dbv.ptszVal;
+ DBFreeVariant( &dbv );
+ }
+ return sNick;
+}
+
+void SetNick(HANDLE hContact, LPCTSTR szNick)
+{
+ DBWriteContactSettingTString( hContact, modname, "Nick", szNick );
+}
+
+CComAutoCriticalSection _LOG_SECTION;
+
+int LOG(const char *fmt,...)
+{
+ CComCritSecLock< CComAutoCriticalSection > _Lock( _LOG_SECTION );
+
+ int ret = 0;
+ const int size = 512;
+ if ( char* szText = (char*)mir_alloc( size ) )
+ {
+ *szText = 0;
+ va_list va;
+ va_start( va, fmt );
+ mir_vsnprintf( szText, size, fmt, va );
+ va_end( va );
+ ret = CallService( MS_NETLIB_LOG, (WPARAM)pluginNetLibUser, (LPARAM)szText );
+ mir_free( szText );
+ }
+ return ret;
+}
+
+void GetAvatarCache(LPTSTR szPath)
+{
+ //
+ if ( ServiceExists( MS_UTILS_REPLACEVARS ) )
+ {
+ LPTSTR szAvatarCache = Utils_ReplaceVarsT(
+ _T("%miranda_avatarcache%\\") modname_t _T("\\") );
+ if ( szAvatarCache && szAvatarCache != (LPTSTR)0x80000000 )
+ {
+ lstrcpyn( szPath, szAvatarCache, MAX_PATH );
+
+ //
+ CallService( MS_UTILS_CREATEDIRTREET, 0, (LPARAM)szPath );
+ return;
+ }
+ }
+
+ //
+ char szProfilePath[ MAX_PATH ], szProfileName[ MAX_PATH ];
+ CallService( MS_DB_GETPROFILEPATH, MAX_PATH, (LPARAM)szProfilePath );
+ CallService( MS_DB_GETPROFILENAME, MAX_PATH, (LPARAM)szProfileName );
+ char *pos = strrchr( szProfileName, '.' );
+ if ( lstrcmpA( pos, ".dat" ) == 0 )
+ *pos = 0;
+ lstrcpy( szPath, CA2T( szProfilePath ) );
+ lstrcat( szPath, _T("\\") );
+ lstrcat( szPath, CA2T( szProfileName ) );
+ lstrcat( szPath, _T("\\AvatarCache\\") modname_t _T("\\") );
+
+ //
+ CallService( MS_UTILS_CREATEDIRTREET, 0, (LPARAM)szPath );
+ return;
+}
+
+static LONG cookie = (LONG)GetTickCount();
+
+HANDLE GenerateCookie()
+{
+ return (HANDLE)InterlockedIncrement( &cookie );
+}
+
+DWORD time()
+{
+ LARGE_INTEGER lft = {};
+ GetSystemTimeAsFileTime ((FILETIME*) &lft);
+ return (DWORD) ((lft.QuadPart - 116444736000000000) / 10000000);
+}
+
+bool IsMyContact(HANDLE hContact)
+{
+ if ( ! hContact )
+ //
+ return false;
+
+ char* proto = (char*)CallService( MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0 );
+ if ( ! proto )
+ //
+ return false;
+
+ if ( lstrcmpA( proto, modname ) )
+ //
+ return false;
+
+ //
+ return true;
+}
+
+void SetPluginStatus(WPARAM status)
+{
+ WPARAM old = pluginCurrentStatus;
+ pluginCurrentStatus = status;
+ if (pluginInstalled)
+ {
+ ProtoBroadcastAck (modname, NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS,
+ (HANDLE) old, (LPARAM) pluginCurrentStatus);
+
+ if ( old != pluginCurrentStatus &&
+ pluginCurrentStatus >= ID_STATUS_OFFLINE &&
+ pluginCurrentStatus <= ID_STATUS_OUTTOLUNCH )
+ {
+ pluginNetBIOS.BroadcastStatus();
+ }
+ }
+}
+
+bool InternalStartup()
+{
+ _ASSERT( pluginInstalled == true );
+
+ LOG ("Startup begin");
+
+ ResetEvent( pluginInternalState );
+
+ bool err = false;
+
+ BYTE method = (BYTE) DBGetContactSettingByte (NULL, modname, "SendMethod", 0);
+ if ( method == 2 )
+ {
+ // " "
+ if (pluginMessenger.Create (TRUE))
+ err = true;
+ LOG ("Startup : Messenger");
+
+ // NetBIOS
+ if (!pluginNetBIOS.Create (FALSE))
+ err = true;
+ LOG ("Startup : NetBIOS");
+ }
+ else
+ {
+ // " "
+ if (pluginMessenger.Create (FALSE))
+ err = true;
+
+ //
+ if ( ! pluginMailslot.Create( MESSENGER_MAIL ) )
+ err = true;
+ LOG ("Startup : Mailslot");
+
+ // NetBIOS
+ if (!pluginNetBIOS.Create (TRUE))
+ err = true;
+ LOG ("Startup : NetBIOS");
+ }
+
+ //
+ if (!pluginScanner.Create ())
+ err = true;
+ LOG ("Startup : Scanner");
+
+ LOG ("Startup end");
+
+ return !err;
+}
+
+void InternalShutdown ()
+{
+ LOG ("Shutdown begin");
+
+ //
+ pluginSearch.AskForDestroy();
+ pluginMailslot.AskForDestroy();
+ pluginScanner.AskForDestroy();
+ pluginNetBIOS.AskForDestroy();
+ pluginMessenger.AskForDestroy();
+
+ // ()
+ pluginMailslot.Destroy ();
+ LOG ("Shutdown : Mailslot");
+
+ // (, )
+ pluginSearch.Destroy();
+ LOG ("Shutdown : Search");
+
+ // NetBIOS ()
+ pluginNetBIOS.Destroy ();
+ LOG ("Shutdown : NetBIOS");
+
+ // (, )
+ pluginScanner.Destroy ();
+ LOG ("Shutdown : Scanner");
+
+ // " " (, )
+ pluginMessenger.Destroy ();
+ LOG ("Shutdown : Messenger");
+
+ LOG ("Shutdown end");
+ SetEvent( pluginInternalState );
+}
+
+void GotoOnline ()
+{
+ if ( pluginCurrentStatus != ID_STATUS_OFFLINE )
+ {
+ //
+ if ( pluginCurrentStatus != ID_STATUS_CONNECTING )
+ {
+ //
+ SetPluginStatus (pluginRequestedStatus);
+ return;
+ }
+ }
+
+ SetPluginStatus (ID_STATUS_CONNECTING);
+
+ if (!pluginInstalled || !pluginInitialized || pluginBusy)
+ // ( )
+ return;
+ pluginBusy = true;
+
+ //
+ mir_forkthread( GotoOnlineTread, NULL );
+}
+
+void GotoOffline()
+{
+ //
+ SetPluginStatus (ID_STATUS_OFFLINE);
+
+ if (pluginBusy)
+ //
+ return;
+ pluginBusy = true;
+
+ //
+ FOR_EACH_CONTACT( hContact ) {
+ SetContactStatus (hContact, ID_STATUS_OFFLINE, true);
+ }
+
+ //
+ mir_forkthread( GotoOfflineTread, NULL );
+}
+
+void GotoOnlineTread(LPVOID /* status */)
+{
+ //
+ InternalStartup();
+ pluginBusy = false;
+ Sleep( 1000 );
+
+ //
+ if ( ! pluginInstalled || pluginRequestedStatus == ID_STATUS_OFFLINE )
+ // ,
+ GotoOffline ();
+ else
+ // ,
+ SetPluginStatus (pluginRequestedStatus);
+}
+
+void GotoOfflineTread(LPVOID /* status */)
+{
+ //
+ InternalShutdown ();
+ pluginBusy = false;
+ Sleep( 1000 );
+
+ //
+ if ( pluginInstalled && pluginRequestedStatus != ID_STATUS_OFFLINE )
+ // ,
+ GotoOnline ();
+ else
+ //
+ SetPluginStatus (ID_STATUS_OFFLINE);
+}
+
+void GetAwayMsgThread(LPVOID param)
+{
+ // ""
+ Sleep( 250 );
+
+ ContactData* data = (ContactData*)param;
+
+ bool ret = false;
+
+ bool bGroup = IsGroup( data->hContact );
+ CString sNick = GetNick( data->hContact );
+ if ( ! bGroup && ! sNick.IsEmpty() )
+ {
+ ThreadEvent te = { CreateEvent( NULL, TRUE, FALSE, NULL ), data->cookie };
+
+ //
+ {
+ CLock oLock( pluginGuard );
+ pluginAwayThreadMap.SetAt( data->hContact, te );
+ }
+
+ // -
+ ret = pluginNetBIOS.AskAway( netbios_name( sNick, 0x03, false ) );
+
+ // (3 )
+ ret = ret && ( WaitForSingleObject( te.evt, 3000 ) == WAIT_OBJECT_0 );
+
+ //
+ {
+ CLock oLock( pluginGuard );
+ pluginAwayThreadMap.Lookup( data->hContact, te );
+ pluginAwayThreadMap.RemoveKey( data->hContact );
+ }
+
+ CloseHandle( te.evt );
+ }
+
+ if ( ! ret )
+ {
+ //
+ ProtoBroadcastAck (modname, data->hContact, ACKTYPE_AWAYMSG,
+ ACKRESULT_SUCCESS /* ACKRESULT_FAILED */, data->cookie, (LPARAM)"" );
+ LOG( "Get away message failed" );
+ }
+
+ delete data;
+}
+
+void SetContactAway(HANDLE hContact, LPCSTR away)
+{
+ if ( ! pluginInstalled )
+ return;
+
+ //
+ bool ret = false;
+ ThreadEvent te = {};
+ {
+ CLock oLock( pluginGuard );
+ if ( pluginAwayThreadMap.Lookup( hContact, te ) )
+ {
+ SetEvent( te.evt );
+ ret = true;
+ }
+ }
+
+ if ( ret )
+ {
+ // -
+ ProtoBroadcastAck( modname, hContact, ACKTYPE_AWAYMSG,
+ ACKRESULT_SUCCESS, te.cookie, (LPARAM)away );
+ }
+ else
+ {
+ // -
+ }
+}
+
+void GetInfoThread(LPVOID param)
+{
+ // ""
+ Sleep( 500 );
+
+ HANDLE hContact = (HANDLE)param;
+
+ ProtoBroadcastAck( modname, hContact, ACKTYPE_GETINFO,
+ ACKRESULT_SUCCESS, (HANDLE)0, 0 );
+}
+
+void Autoanswer(HANDLE hContact)
+{
+ switch ( pluginCurrentStatus )
+ {
+ case ID_STATUS_AWAY:
+ case ID_STATUS_DND:
+ case ID_STATUS_NA:
+ case ID_STATUS_OCCUPIED:
+ case ID_STATUS_ONTHEPHONE:
+ case ID_STATUS_OUTTOLUNCH:
+ {
+ CString msg;
+ if ( pluginStatusMessage.Lookup( pluginCurrentStatus, msg ) )
+ {
+ //
+ CString answer (TranslateT ("Auto-reply"));
+ answer += _T(":\r\n");
+ answer += msg;
+ DWORD foo;
+ SendContactMessage( hContact, answer, foo );
+
+ //
+ DBEVENTINFO ei = {};
+ ei.cbSize = sizeof (DBEVENTINFO);
+ ei.szModule = modname;
+ ei.timestamp = time();
+ ei.flags = DBEF_SENT;
+ ei.eventType = EVENTTYPE_MESSAGE;
+ ei.cbBlob = (DWORD)answer.GetLength () + 1;
+ ei.pBlob = (PBYTE) (LPCTSTR) answer;
+ CallServiceSync( MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&ei );
+ }
+ }
+ break;
+ }
+}
+
+void ReceiveContactMessage(LPCTSTR msg_from, LPCTSTR msg_to, LPCTSTR msg_text, int msg_len)
+{
+ if ( ! pluginInstalled )
+ return;
+
+ CString from( msg_from );
+ CString to( msg_to );
+ CString text( msg_text, msg_len );
+
+ from.MakeUpper();
+ to.MakeUpper();
+
+ // ?
+ if ( IsItMe( from ) )
+ {
+ LOG ( "Ignoring my message." );
+ return;
+ }
+
+ //
+ Normalize( text );
+
+ // ?
+ if (DBGetContactSettingByte (NULL, modname, "Filter-dups", TRUE))
+ {
+ //
+ static FILETIME last_time = { 0, 0 };
+ FILETIME current_time;
+ GetSystemTimeAsFileTime (&current_time);
+ ULONGLONG elapsed =
+ ((ULONGLONG) current_time.dwLowDateTime |
+ (ULONGLONG) current_time.dwHighDateTime << 32) -
+ ((ULONGLONG) last_time.dwLowDateTime |
+ (ULONGLONG) last_time.dwHighDateTime << 32);
+
+ // MD5-
+ MD5Context ctx;
+ md5init (&ctx);
+ md5update (&ctx, (const unsigned char*)(LPCTSTR)from,
+ from.GetLength() * sizeof (TCHAR));
+ unsigned char digest_from_current [16] = {0};
+ static unsigned char digest_from_last [16] = {0};
+ md5final (digest_from_current, &ctx);
+
+ // MD5-
+ md5init (&ctx);
+ md5update (&ctx, (const unsigned char*)(LPCTSTR)text,
+ text.GetLength() * sizeof (TCHAR));
+ unsigned char digest_text_current [16] = {0};
+ static unsigned char digest_text_last [16] = {0};
+ md5final (digest_text_current, &ctx);
+
+ // 2
+ if (elapsed < 20000000)
+ {
+ //
+ if (memcmp (digest_from_current, digest_from_last, 16) == 0)
+ {
+ //
+ if (memcmp (digest_text_current, digest_text_last, 16) == 0)
+ {
+ //
+ LOG ("Duplicate message detected");
+ return;
+ }
+ }
+ }
+ last_time = current_time;
+ CopyMemory (digest_from_last, digest_from_current, 16);
+ CopyMemory (digest_text_last, digest_text_current, 16);
+ }
+
+#ifdef CHAT_ENABLED
+ if ( ! IsItMe( to ) && pluginChatEnabled ) // ?
+ {
+ //
+ if ( ChatNewSession( to ) )
+ {
+ //
+ ATLVERIFY( ChatAddGroup( to, _T("Normal") ) );
+
+ //
+ ATLVERIFY( ChatJoinMe( to, _T("Normal") ) );
+
+ // " "
+ ATLVERIFY( ChatJoinUser( to, from, _T("Normal") ) );
+
+ //
+ ATLVERIFY( ChatInitDone( to ) );
+
+ // -
+ ATLVERIFY( ChatOnline( to ) );
+
+ //
+ ATLVERIFY( ChatMessage( to, from, text ) );
+ }
+ }
+ else
+#endif // CHAT_ENABLED
+ {
+ //
+ HANDLE hContact = AddToListByName( from, 0, NULL, false, false );
+ if ( hContact )
+ {
+ PROTORECVEVENT pre = { 0 };
+ pre.timestamp = time ();
+ CT2A textA( text );
+ pre.szMessage = (LPSTR)(LPCSTR)textA;
+ CCSDATA ccs = { 0 };
+ ccs.szProtoService = PSR_MESSAGE;
+ ccs.hContact = hContact;
+ DBDeleteContactSetting (ccs.hContact, "CList", "Hidden");
+ ccs.lParam = (LPARAM) &pre;
+ CallServiceSync (MS_PROTO_CHAINRECV, 0, (LPARAM) &ccs);
+
+ //
+ SetContactStatus( hContact, contact_scanner::ScanContact( hContact ), true );
+
+ // -
+ if ( DBGetContactSettingByte( NULL, modname, "Auto-answer", FALSE ) )
+ Autoanswer( hContact );
+ }
+ }
+}
+
+void Normalize(CString& msg)
+{
+ enum { CR, LF, NOP };
+ int line_break = NOP;
+ int i = 0;
+ for (; i < msg.GetLength (); ++i)
+ {
+ switch (msg [i])
+ {
+ case _T('\r'):
+ case _T('\xb6'):
+ switch (line_break)
+ {
+ case CR: // CRCR
+ case LF: // LFCR
+ msg.Delete (i);
+ msg.Delete (i - 1);
+ msg.Insert (i - 1, _T('\r'));
+ msg.Insert (i, _T('\n'));
+ line_break = NOP;
+ break;
+ default: // xxCR
+ line_break = CR;
+ }
+ break;
+ case _T('\n'):
+ switch (line_break)
+ {
+ case CR: // CRLF
+ line_break = NOP;
+ break;
+ case LF: // LFLF
+ msg.Delete (i);
+ msg.Delete (i - 1);
+ msg.Insert (i - 1, _T('\r'));
+ msg.Insert (i, _T('\n'));
+ line_break = NOP;
+ break;
+ default: // xxLF
+ line_break = LF;
+ }
+ break;
+ default:
+ switch (line_break)
+ {
+ case CR: // CR LF
+ case LF: // LF CR
+ msg.Delete (i - 1);
+ msg.Insert (i - 1, _T('\r'));
+ msg.Insert (i, _T('\n'));
+ ++i;
+ break;
+ }
+ line_break = NOP;
+ }
+ }
+ switch (line_break)
+ {
+ case CR: // CR LF
+ case LF: // LF CR
+ msg.Delete (i - 1);
+ msg.Insert (i - 1, _T('\r'));
+ msg.Insert (i, _T('\n'));
+ break;
+ }
+}
+
+HANDLE AddToListByName(const CString& sName, WPARAM flags, LPCTSTR about, bool bInteractive, bool bGroup)
+{
+ ip addr = INADDR_NONE;
+ CString sShortName( sName );
+
+ if ( ! bGroup )
+ {
+ // IP
+ if ( addr == INADDR_NONE )
+ addr = ResolveToIP( sShortName );
+
+ // NetBIOS-
+ if ( addr == INADDR_NONE )
+ addr = pluginNetBIOS.FindNameIP( sName );
+
+ //
+ if ( addr == INADDR_NONE && bInteractive )
+ {
+ if ( MessageBox( NULL,
+ TranslateT("Cannot resolve contacts IP-address. Add it anyway?"),
+ modname_t, MB_YESNO | MB_ICONQUESTION ) != IDYES )
+ {
+ return NULL;
+ }
+ }
+ }
+
+ //
+ HANDLE hContact = GetContact( sShortName );
+ if ( ! hContact )
+ {
+ //
+ hContact = (HANDLE)CallService( MS_DB_CONTACT_ADD, 0, 0 );
+ if ( hContact )
+ {
+ CallService( MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)modname );
+ SetNick( hContact, sShortName );
+ SetGroup( hContact, bGroup );
+ DBWriteContactSettingTString( hContact, "CList", "MyHandle", sShortName );
+ DBWriteContactSettingByte( hContact, "CList", "NotOnList", 1 );
+ DBWriteContactSettingByte( hContact, "CList", "Hidden", 1 );
+ SetContactIP( hContact, addr );
+ SetElapsed( hContact, "IPTime" );
+ if ( about )
+ DBWriteContactSettingTString( hContact, modname, "About", about );
+
+ contact_scanner::ScanContact( hContact );
+ }
+ }
+ if ( hContact && ! ( flags & PALF_TEMPORARY ) &&
+ DBGetContactSettingByte( hContact, "CList", "NotOnList", 1 ) )
+ {
+ //
+ DBDeleteContactSetting( hContact, "CList", "NotOnList" );
+ DBDeleteContactSetting( hContact, "CList", "Hidden" );
+ }
+ return hContact;
+}
+
+DWORD GetElapsed (HANDLE hContact, const char* name)
+{
+ FILETIME current = {};
+ GetSystemTimeAsFileTime (&current);
+ LARGE_INTEGER currentL = {};
+ currentL.LowPart = current.dwLowDateTime;
+ currentL.HighPart = (LONG)current.dwHighDateTime;
+ LARGE_INTEGER lastseenL = {};
+ lastseenL.LowPart = DBGetContactSettingDword (hContact, modname,
+ CStringA (name) + "L", 0);
+ lastseenL.HighPart = (LONG)DBGetContactSettingDword (hContact, modname,
+ CStringA (name) + "H", 0);
+ return (DWORD) (((currentL.QuadPart - lastseenL.QuadPart) / 10000000L) & 0xffffffff);
+}
+
+void SetElapsed (HANDLE hContact, const char* name)
+{
+ FILETIME current = {};
+ GetSystemTimeAsFileTime (&current);
+ DBWriteContactSettingDword (hContact, modname,
+ CStringA (name) + "L", current.dwLowDateTime);
+ DBWriteContactSettingDword (hContact, modname,
+ CStringA (name) + "H", current.dwHighDateTime);
+}
+
+HANDLE GetContact (ip addr)
+{
+ //
+ FOR_EACH_CONTACT( hContact )
+ {
+ //
+ ip contact_addr = DBGetContactSettingDword (hContact, modname, "IP", 0);
+ if (contact_addr && (contact_addr == addr))
+ //
+ break;
+ }
+ return hContact;
+}
+
+HANDLE GetContact (LPCTSTR name)
+{
+ //
+ FOR_EACH_CONTACT( hContact )
+ {
+ //
+ CString sNick = GetNick( hContact );
+ if ( ! sNick.IsEmpty() )
+ {
+ //
+ if ( sNick.CompareNoCase( name ) == 0 )
+ //
+ break;
+ }
+ }
+ return hContact;
+}
+
+void SetContactStatus (HANDLE hContact, int status, bool simple)
+{
+ if ( ! pluginInstalled )
+ return;
+
+ SetElapsed (hContact, "LastSeen");
+
+#ifdef CHAT_ENABLED
+ if ( IsChatRoom( hContact ) )
+ {
+ CString sSession = GetChatSession( hContact );
+ if ( pluginChatEnabled && ! sSession.IsEmpty() )
+ {
+ if ( status != ID_STATUS_OFFLINE )
+ ChatOnline( sSession );
+ else
+ ChatOffline( sSession );
+ }
+ }
+ else
+#endif // CHAT_ENABLED
+ {
+ int ns = DBGetContactSettingWord (hContact, modname, "Status", -1);
+ if ( ns != status )
+ {
+ //
+ if ( ! simple )
+ //
+ DBWriteContactSettingWord (hContact, modname, "Status", (WORD) status);
+ else if ( ns == -1 || ns == ID_STATUS_OFFLINE || status != ID_STATUS_ONLINE )
+ //
+ DBWriteContactSettingWord (hContact, modname, "Status", (WORD) status);
+ }
+ }
+}
+
+void GetAvatarInfoThread(LPVOID param)
+{
+ // ""
+ Sleep( 500 );
+
+ ContactData* data = (ContactData*)param;
+
+ bool ret = false;
+ ThreadEvent te = { CreateEvent( NULL, TRUE, FALSE, NULL ), data->cookie };
+ PROTO_AVATAR_INFORMATION pai = { sizeof( PROTO_AVATAR_INFORMATION ), data->hContact };
+
+ TCHAR szPath[ MAX_PATH ];
+ GetAvatarCache( szPath );
+
+ //
+ DBVARIANT dbv = {};
+ if ( ! DBGetContactSettingTString( data->hContact, modname, "AvatarFile", &dbv ) )
+ {
+ lstrcat( szPath, dbv.ptszVal );
+
+ if ( GetFileAttributes( szPath ) != INVALID_FILE_ATTRIBUTES )
+ {
+ ret = true;
+
+ lstrcpyA( pai.filename, CT2A( szPath ) );
+
+ //
+ LPCTSTR szExt = _tcsrchr( dbv.ptszVal, _T('.') );
+ if ( ! szExt )
+ {
+ pai.format = PA_FORMAT_UNKNOWN;
+ }
+ else if ( lstrcmpi( szExt, _T(".png") ) == 0 || lstrcmpi( szExt, _T(".dat") ) == 0 )
+ {
+ pai.format = PA_FORMAT_PNG;
+ }
+ else if ( lstrcmpi( szExt, _T(".jpg") ) == 0 )
+ {
+ pai.format = PA_FORMAT_JPEG;
+ }
+ else if ( lstrcmpi( szExt, _T(".ico") ) == 0 )
+ {
+ pai.format = PA_FORMAT_ICON;
+ }
+ else if ( lstrcmpi( szExt, _T(".bmp") ) == 0 )
+ {
+ pai.format = PA_FORMAT_BMP;
+ }
+ else if ( lstrcmpi( szExt, _T(".gif") ) == 0 )
+ {
+ pai.format = PA_FORMAT_GIF;
+ }
+ else if ( lstrcmpi( szExt, _T(".swf") ) == 0 )
+ {
+ pai.format = PA_FORMAT_SWF;
+ }
+ else if ( lstrcmpi( szExt, _T(".xml") ) == 0 )
+ {
+ pai.format = PA_FORMAT_XML;
+ }
+ else
+ {
+ pai.format = PA_FORMAT_UNKNOWN;
+ }
+ }
+ DBFreeVariant( &dbv );
+ }
+ if ( ret )
+ {
+ ProtoBroadcastAck( modname, data->hContact, ACKTYPE_AVATAR,
+ ACKRESULT_SUCCESS, &pai, 0 );
+ LOG( "Returned cached avatar." );
+ }
+ else
+ {
+ bool bGroup = IsGroup( data->hContact );
+ CString sNick = GetNick( data->hContact );
+ if ( ! bGroup && ! sNick.IsEmpty() )
+ {
+ //
+ ProtoBroadcastAck( modname, data->hContact, ACKTYPE_AVATAR,
+ ACKRESULT_SENTREQUEST, &pai, 0 );
+
+ //
+ {
+ CLock oLock( pluginGuard );
+ pluginAvatarThreadMap.SetAt( data->hContact, te );
+ }
+
+ ret = pluginNetBIOS.AskAvatar( netbios_name( sNick, 0x03 ) );
+
+ // (3 )
+ ret = ret && ( WaitForSingleObject( te.evt, 3000 ) == WAIT_OBJECT_0 );
+
+ //
+ {
+ CLock oLock( pluginGuard );
+ pluginAvatarThreadMap.Lookup( data->hContact, te );
+ pluginAvatarThreadMap.RemoveKey( data->hContact );
+ }
+ }
+ if ( ! ret )
+ {
+ ProtoBroadcastAck( modname, data->hContact, ACKTYPE_AVATAR,
+ ACKRESULT_FAILED, &pai, 0 );
+ LOG( "Get avatar failed" );
+ }
+ }
+
+ if ( te.evt )
+ CloseHandle( te.evt );
+
+ delete data;
+}
+
+void SetContactAvatar(HANDLE hContact, LPCVOID pBuffer, DWORD nLength)
+{
+ if ( ! pluginInstalled )
+ return;
+
+ PROTO_AVATAR_INFORMATION pai = { sizeof( PROTO_AVATAR_INFORMATION ), hContact };
+
+ CString sFilename, sNick = GetNick( hContact );
+ if ( sNick.IsEmpty() || sNick.FindOneOf( _T("/\\*?:|\"<>%") ) != -1 )
+ {
+ //
+ DBVARIANT dbv = {};
+ if ( ! DBGetContactSettingTString( hContact, modname, "AvatarFile", &dbv ) )
+ {
+ sFilename = dbv.ptszVal;
+ DBFreeVariant( &dbv );
+ }
+ else
+ //
+ sFilename.Format( _T("%08x_avt"), (DWORD)hContact );
+ }
+ else
+ //
+ sFilename.Format( _T("%s_%08x_avt"), sNick, (DWORD)hContact );
+
+ //
+ if ( ! memcmp( pBuffer, "%PNG", 4 ) )
+ {
+ pai.format = PA_FORMAT_PNG;
+ sFilename += _T(".png");
+ }
+ else if ( *(DWORD*)pBuffer == 0xE0FFD8FFul || *(DWORD*)pBuffer == 0xE1FFD8FFul )
+ {
+ pai.format = PA_FORMAT_JPEG;
+ sFilename += _T(".jpg");
+ }
+ else if ( *(DWORD*)pBuffer == 0x00010000 )
+ {
+ pai.format = PA_FORMAT_ICON;
+ sFilename += _T(".ico");
+ }
+ else if ( ! memcmp( pBuffer, "BM", 2 ) )
+ {
+ pai.format = PA_FORMAT_BMP;
+ sFilename += _T(".bmp");
+ }
+ else if ( ! memcmp( pBuffer, "GIF", 3 ) )
+ {
+ pai.format = PA_FORMAT_GIF;
+ sFilename += _T(".gif");
+ }
+ else if ( ! memcmp( pBuffer, "CWS", 3 ) )
+ {
+ pai.format = PA_FORMAT_SWF;
+ sFilename += _T(".swf");
+ }
+ else if ( ! memcmp( pBuffer, "<?xml", 5 ) )
+ {
+ pai.format = PA_FORMAT_XML;
+ sFilename += _T(".xml");
+ }
+ else
+ {
+ pai.format = PA_FORMAT_UNKNOWN;
+ sFilename += _T(".dat");
+ }
+
+ //
+ TCHAR szPath[ MAX_PATH ];
+ GetAvatarCache( szPath );
+
+ lstrcat( szPath, sFilename );
+
+ CAtlFile oAvatarFile;
+ if ( FAILED( oAvatarFile.Create( szPath, GENERIC_WRITE,
+ FILE_SHARE_READ, CREATE_ALWAYS ) ) )
+ //
+ return;
+
+ if ( FAILED( oAvatarFile.Write( pBuffer, nLength ) ) )
+ //
+ return;
+
+ oAvatarFile.Close();
+
+ DBWriteContactSettingTString( hContact, modname, "AvatarFile", sFilename );
+
+ //
+ bool ret = false;
+ ThreadEvent te = {};
+ {
+ CLock oLock( pluginGuard );
+ if ( pluginAvatarThreadMap.Lookup( hContact, te ) )
+ {
+ SetEvent( te.evt );
+ ret = true;
+ }
+ }
+
+ lstrcpyA( pai.filename, CT2A( szPath ) );
+
+ if ( ret )
+ {
+ //
+ ProtoBroadcastAck( modname, hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &pai, 0 );
+ }
+ else
+ {
+ // , -
+ if ( ServiceExists( MS_AV_SETAVATAR ) )
+ {
+ CallService( MS_AV_SETAVATAR, (WPARAM)hContact, (LPARAM)pai.filename );
+ }
+ }
+}
+
+ip GetContactIP (HANDLE hContact)
+{
+ ip addr = INADDR_NONE;
+ bool got_nick = false, nick_invalid = false;
+ DBVARIANT dbv = {};
+ if ( hContact )
+ {
+ CString sNick = GetNick( hContact );
+ if ( ! sNick.IsEmpty() )
+ {
+ got_nick = true;
+ }
+ else if ( ! DBGetContactSettingTString( hContact, "CList", "MyHandle", &dbv ) )
+ {
+ nick_invalid = true;
+ got_nick = true;
+ }
+
+ if ( got_nick )
+ {
+ //
+ if ( nick_invalid )
+ SetNick( hContact, dbv.ptszVal );
+
+ // ,
+ DWORD elapsed = GetElapsed (hContact, "IPTime");
+ if (elapsed <= MAX_TRUSTED_IP_TIME)
+ addr = DBGetContactSettingDword (hContact, modname, "IP", 0);
+ if (addr == INADDR_NONE) {
+ // DNS-
+ CString name (dbv.pszVal);
+ addr = ResolveToIP (name);
+ if (addr != INADDR_NONE)
+ SetElapsed (hContact, "IPTime");
+ }
+ if (addr != INADDR_NONE)
+ SetContactIP (hContact, addr);
+ DBFreeVariant (&dbv);
+ }
+ }
+ return addr;
+}
+
+void SetContactIP(HANDLE hContact, ip addr)
+{
+ if ( ! pluginInstalled )
+ return;
+
+ if ( hContact )
+ {
+ DBWriteContactSettingDword (hContact, modname, "IP", addr);
+ DBWriteContactSettingDword (hContact, modname, "RealIP", addr);
+ }
+}
+
+bool IsGroup(HANDLE hContact)
+{
+ return ( DBGetContactSettingByte( hContact, modname, "Group", 0u ) != 0u );
+}
+
+void SetGroup(HANDLE hContact, bool bGroup)
+{
+ DBWriteContactSettingByte( hContact, modname, "Group", ( bGroup ? 1u : 0u ) );
+}
+
+bool IsLegacyOnline(HANDLE hContact)
+{
+ return ( DBGetContactSettingByte( hContact, modname, "Check00ForOnline", 0u ) != 0u );
+}
+
+void SetLegacyOnline(HANDLE hContact, bool bOnline)
+{
+ DBWriteContactSettingByte( hContact, modname, "Check00ForOnline", ( bOnline ? 1u : 0u ) );
+}
+
+bool SendContactMessage(HANDLE hContact, LPCTSTR msg, DWORD& err)
+{
+ //
+ BYTE method = (BYTE)DBGetContactSettingByte( NULL, modname, "SendMethod", 0 );
+ switch ( method )
+ {
+ case 0:
+ return pluginMailslot.SendMailslotMessage( hContact, msg, err );
+ case 1:
+ return pluginNetBIOS.SendNetBIOSMessage( hContact, msg, err );
+ case 2:
+ return pluginMessenger.SendMessengerMessage( hContact, msg, err );
+ default:
+ return false;
+ }
+}
+
+void SendMsgThread(LPVOID param)
+{
+ SendMsgData* data = (SendMsgData*)param;
+
+ DWORD dwLastError = 0;
+ if ( SendContactMessage( data->hContact, data->text, dwLastError ) )
+ {
+ ProtoBroadcastAck ( modname, data->hContact, ACKTYPE_MESSAGE,
+ ACKRESULT_SUCCESS, data->cookie, 0 );
+ }
+ else
+ {
+ //
+ CString msg, buf;
+ GetErrorMessage (dwLastError, buf);
+ msg.Format( _T("%s\r\n%s"), TranslateT ("Cannot send message"), (LPCTSTR)buf);
+ ProtoBroadcastAck (modname, data->hContact, ACKTYPE_MESSAGE,
+ ACKRESULT_FAILED, data->cookie, (LPARAM)(LPCTSTR)msg );
+
+ //
+ WarningBox( data->hContact, dwLastError, TranslateT("Cannot send message") );
+ }
+
+ delete data;
+}
+
+bool IsItMe(LPCTSTR name)
+{
+ return ! pluginMachineName.CompareNoCase( name ) ||
+ ! pluginUserName.CompareNoCase( name );
+}
+
+void EnumWorkgroups(CAtlList< CString >& lst, LPNETRESOURCE hRoot)
+{
+ HANDLE hEnum = NULL;
+ DWORD res = WNetOpenEnum( RESOURCE_GLOBALNET, RESOURCETYPE_ANY,
+ RESOURCEUSAGE_CONTAINER, hRoot, &hEnum );
+ if ( res == NO_ERROR )
+ {
+ for (;;)
+ {
+ DWORD cCount = 1;
+ DWORD BufferSize = 4096;
+ char* Buffer = (char*)mir_alloc( BufferSize );
+ if ( ! Buffer )
+ break;
+ res = WNetEnumResource( hEnum, &cCount, Buffer, &BufferSize );
+ if ( res == NO_ERROR )
+ {
+ LPNETRESOURCE lpnr = (LPNETRESOURCE)Buffer;
+ if ( lpnr->dwDisplayType == RESOURCEDISPLAYTYPE_DOMAIN )
+ {
+ CharUpper ( lpnr->lpRemoteName );
+ lst.AddTail( lpnr->lpRemoteName );
+ }
+ else if ( ( lpnr->dwUsage & 0xffff ) == RESOURCEUSAGE_CONTAINER )
+ {
+ EnumWorkgroups( lst, lpnr );
+ }
+ mir_free( Buffer );
+ }
+ else
+ {
+ mir_free( Buffer );
+ break;
+ }
+ }
+ WNetCloseEnum (hEnum);
+ }
+}
+
+BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID /*lpReserved*/)
+{
+ if ( dwReason == DLL_PROCESS_ATTACH )
+ {
+ pluginModule = hModule;
+
+ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF |
+ _CRTDBG_CHECK_CRT_DF | _CRTDBG_DELAY_FREE_MEM_DF |
+ _CRTDBG_LEAK_CHECK_DF );
+ }
+ return TRUE;
+}
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto.def b/plugins/!NotAdopted/WinPopup/winpopup_proto.def
new file mode 100644
index 0000000000..1bbd10cedd
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto.def
@@ -0,0 +1,27 @@
+;
+; WinPopup Protocol plugin for Miranda IM.
+;
+; Copyright (C) 2004-2009 Nikolay Raspopov
+;
+; 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.
+;
+
+EXPORTS
+ Load
+ MirandaPluginInfo
+ MirandaPluginInfoEx
+ MirandaPluginInterfaces
+ Unload
+ UninstallEx
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto.h b/plugins/!NotAdopted/WinPopup/winpopup_proto.h
new file mode 100644
index 0000000000..763447881d
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto.h
@@ -0,0 +1,322 @@
+/*
+
+WinPopup Protocol plugin for Miranda IM.
+
+Copyright (C) 2004-2010 Nikolay Raspopov
+
+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 "network.h"
+
+// Miranda IM
+//
+// :
+// Nick String - (.)
+// User String - (.)
+// Workgroup String - (.)
+// Auto-answer BYTE - - (-: 0)
+// Filter-dups BYTE - (-: 1)
+// SendMethod BYTE - : 0 - mailslot, 1 - NetBIOS, 2 - Messenger (-: 0)
+// RegisterNick BYTE - NetBIOS Nick<01> Nick<03> (-: 1)
+// RegisterUser BYTE - NetBIOS User<03> (-: 1)
+// RegisterStatus BYTE - NetBIOS MNS_STATUS<ab> (-: 1)
+// Check00ForOnline BYTE - NetBIOS Nick<00> , ( : 0) ( AlwaysCheck00ForOnline)
+// AvatarFile String -
+//
+// :
+// Nick String -
+// IP DWORD -
+// RealIP DWORD - ( IP)
+// IPTimeL DWORD -
+// IPTimeH DWORD
+// LastSeenL DWORD -
+// LastSeenH DWORD
+// PingCounter WORD - ( )
+// Status WORD -
+// About String -
+// AlwaysOnline BYTE - online-
+// Check00ForOnline BYTE - NetBIOS Nick<00> ( : 0)
+// AvatarFile String -
+// Group BYTE - 1/0 -
+//
+// :
+// ChatRoom BYTE - 1/0 -
+// ChatRoomID String - ,
+//
+// CList ( ) :
+// MyHandle String - (. )
+// NotOnList BYTE -
+// Hidden BYTE -
+//
+// Icons ( ) :
+// WinPopup Protocol40071 String -
+// WinPopup Protocol40072 String -
+// WinPopup Protocol40073 String -
+// WinPopup Protocol40074 String -
+// WinPopup Protocol40075 String -
+// WinPopup Protocol40076 String -
+// WinPopup Protocol40077 String -
+// WinPopup Protocol40078 String -
+// WinPopup Protocol40079 String -
+// WinPopup Protocol40080 String -
+
+//
+#define modname "WinPopup Protocol"
+#define modname_t _T( modname )
+//
+#define modtitle "WinPopup"
+#define modtitle_t _T( modtitle )
+// " "
+#define T_STOP_ERROR TranslateT("Cannot stop Messenger service")
+// " "
+#define T_START_ERROR TranslateT("Cannot start Messenger service")
+// " "
+#define T_ENABLE_ERROR TranslateT("Cannot enable Messenger service")
+// " "
+#define T_CREATE_ERROR TranslateT("Cannot create receiving mailslot")
+// ""
+#define T_ERROR TranslateT("Error")
+// Messenger
+#define MESSENGER _T("Messenger")
+// Messenger
+#define MESSENGER_MAIL _T("messngr")
+// IP (3 )
+#define MAX_TRUSTED_IP_TIME 3*60*60
+// ( 30 )
+#define MIN_PING_INTERVAL 30
+
+typedef struct _ContactData
+{
+ HANDLE cookie; //
+ HANDLE hContact; //
+} ContactData;
+
+typedef struct _SendMsgData
+{
+ HANDLE cookie; //
+ HANDLE hContact; //
+ CString text;
+} SendMsgData;
+
+typedef struct _ThreadEvent
+{
+ HANDLE evt; //
+ HANDLE cookie; //
+} ThreadEvent;
+
+typedef CAtlMap < WPARAM, CString > CIntStrMap;
+typedef CAtlMap < HANDLE, ThreadEvent > CThreadContactMap;
+
+// ANSI OEM
+class COemString
+{
+public:
+ COemString(LPCTSTR ansi) :
+ len( (size_t)lstrlen( ansi ) + 1 ),
+ pos( 0 )
+ {
+ oem = (LPSTR)mir_alloc( len );
+ CharToOemBuff( ansi, oem, (DWORD)len );
+ }
+
+ ~COemString()
+ {
+ mir_free( oem );
+ }
+
+ inline operator LPCSTR() const
+ {
+ return oem + pos;
+ }
+
+ // ( null)
+ inline int GetLength() const
+ {
+ return (int)( len - pos - 1 );
+ }
+
+ // ""
+ inline void CutFromStart(int n)
+ {
+ if ( GetLength() > n )
+ pos += n;
+ else
+ pos = len - 1;
+ }
+
+protected:
+ size_t len;
+ size_t pos;
+ LPSTR oem;
+};
+
+// OEM ANSI
+class CAnsiString
+{
+public:
+ CAnsiString(LPCSTR oem) :
+ len( lstrlenA( oem ) + 1 ),
+ pos( 0 )
+ {
+ ansi = (LPTSTR)mir_alloc( len * sizeof( TCHAR ) );
+ OemToCharBuff( oem, ansi, (DWORD)len );
+ }
+ ~CAnsiString()
+ {
+ mir_free( ansi );
+ }
+ inline operator LPCTSTR() const
+ {
+ return ansi + pos;
+ }
+ // ( null)
+ inline int GetLength() const
+ {
+ return len - pos - 1;
+ }
+ // ""
+ inline void CutFromStart(int n)
+ {
+ if ( len - pos - 1 > n )
+ pos += n;
+ else
+ pos = len - 1;
+ }
+protected:
+ int len;
+ int pos;
+ LPTSTR ansi;
+};
+
+extern volatile WPARAM pluginRequestedStatus; //
+extern volatile WPARAM pluginCurrentStatus; //
+extern CIntStrMap pluginStatusMessage; //
+extern CString pluginMachineName; //
+extern CString pluginUserName; //
+extern CString pluginDomainName; //
+extern HMODULE pluginModule; //
+extern volatile bool pluginInstalled; // ,
+ // false
+ //
+extern volatile bool pluginInitialized; //
+extern HANDLE pluginNetLibUser; // NetLib
+extern HANDLE pluginInternalState; // ( - )
+extern bool pluginChatEnabled; // Chat-?
+extern OSVERSIONINFO pluginOS; //
+
+//
+CString GetNick(HANDLE hContact);
+//
+void SetNick(HANDLE hContact, LPCTSTR szNick);
+// NetLib
+int LOG(const char *fmt,...);
+//
+void GetAvatarCache(LPTSTR szPath);
+// ""
+HANDLE GenerateCookie();
+// Win32 API time() ( CRT)
+DWORD time();
+//
+bool IsMyContact(HANDLE hContact);
+//
+void SetPluginStatus(WPARAM status);
+//
+bool InternalStartup();
+//
+void InternalShutdown();
+// Online
+void GotoOnline();
+// Offline
+void GotoOffline();
+// Online
+void GotoOnlineTread(LPVOID status);
+// Offline
+void GotoOfflineTread(LPVOID status);
+// -
+void GetAwayMsgThread(LPVOID param);
+//
+void GetInfoThread(LPVOID param);
+//
+void Autoanswer(HANDLE hContact);
+// , , Miranda IM
+void ReceiveContactMessage(LPCTSTR msg_from, LPCTSTR msg_to, LPCTSTR msg_text, int msg_len);
+// ( IP-)
+HANDLE AddToListByName (const CString& sName, WPARAM flags, LPCTSTR notes, bool bInteractive, bool bGroup);
+// "nameL" | ("nameH" << 32)
+DWORD GetElapsed(HANDLE hContact, const char* name);
+// "LastSeen"
+void SetElapsed(HANDLE hContact, const char* name);
+// "IP"
+HANDLE GetContact(ip addr);
+// "Nick"
+HANDLE GetContact(LPCTSTR name);
+// (simple == true - online/offline)
+void SetContactStatus(HANDLE hContact, int status, bool simple);
+// -
+void SetContactAway(HANDLE hContact, LPCSTR away);
+//
+void SetContactAvatar(HANDLE hContact, LPCVOID pBuffer, DWORD nLength);
+// IP- ( , )
+ip GetContactIP(HANDLE hContact);
+// "IP"
+void SetContactIP(HANDLE hContact, ip addr);
+// ?
+bool IsGroup(HANDLE hContact);
+//
+void SetGroup(HANDLE hContact, bool bGroup);
+// -?
+bool IsLegacyOnline(HANDLE hContact);
+// -
+void SetLegacyOnline(HANDLE hContact, bool bOnline);
+//
+bool SendContactMessage(HANDLE hContact, LPCTSTR msg, DWORD& err);
+//
+void SendMsgThread(LPVOID param);
+//
+void GetAvatarInfoThread(LPVOID param);
+// ?
+bool IsItMe(LPCTSTR name);
+//
+void Normalize(CString& msg);
+// /
+void EnumWorkgroups(CAtlList< CString >& lst, LPNETRESOURCE hRoot = NULL);
+
+//
+#define FOR_EACH_CONTACT(h) \
+ HANDLE h = (HANDLE)CallService( MS_DB_CONTACT_FINDFIRST, 0, 0 ); \
+ for ( ; h != NULL; \
+ h = (HANDLE)CallService( MS_DB_CONTACT_FINDNEXT, (WPARAM)h, 0 ) ) \
+ if ( IsMyContact( h ) )
+
+// ()
+#define STATUS2TEXT(s) \
+ ((((s) == ID_STATUS_OFFLINE) ? "Offline" : \
+ (((s) == ID_STATUS_ONLINE) ? "Online" : \
+ (((s) == ID_STATUS_AWAY) ? "Away" : \
+ (((s) == ID_STATUS_DND) ? "DND" : \
+ (((s) == ID_STATUS_NA) ? "NA" : \
+ (((s) == ID_STATUS_OCCUPIED) ? "Occupied" : \
+ (((s) == ID_STATUS_FREECHAT) ? "Free to chat" : \
+ (((s) == ID_STATUS_INVISIBLE) ? "Invisible" : \
+ (((s) == ID_STATUS_ONTHEPHONE) ? "On the phone" : \
+ (((s) == ID_STATUS_OUTTOLUNCH) ? "Out to lunch" : \
+ (((s) == ID_STATUS_IDLE) ? "Idle" : \
+ (((s) == (ID_STATUS_CONNECTING + 0)) ? "Connecting 1" : \
+ (((s) == (ID_STATUS_CONNECTING + 1)) ? "Connecting 2" : \
+ (((s) < (ID_STATUS_CONNECTING + MAX_CONNECT_RETRIES)) ? "Connecting > 2" : \
+ "Unknown")))))))))))))))
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto.rc b/plugins/!NotAdopted/WinPopup/winpopup_proto.rc
new file mode 100644
index 0000000000..96470ddeac
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto.rc
@@ -0,0 +1,251 @@
+// 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(1251)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,0,0,19
+ PRODUCTVERSION 0,0,0,19
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "CompanyName", "http://www.cherubicsoft.com/"
+ VALUE "FileDescription", "WinPopup Protocol plugin for Miranda IM"
+ VALUE "FileVersion", "0, 0, 0, 19"
+ VALUE "InternalName", "winpopup_proto"
+ VALUE "LegalCopyright", "Copyright 2004-2011 Nikolay Raspopov"
+ VALUE "OriginalFilename", "winpopup_proto.dll"
+ VALUE "ProductName", "WinPopup Protocol plugin for Miranda IM"
+ VALUE "ProductVersion", "0, 0, 0, 19"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_WINPOPUP ICON "icons/winpopup_proto.ico"
+IDI_ONLINE ICON "icons/online.ico"
+IDI_OFFLINE ICON "icons/offline.ico"
+IDI_AWAY ICON "icons/away.ico"
+IDI_FREECHAT ICON "icons/freechat.ico"
+IDI_INVISIBLE ICON "icons/invisible.ico"
+IDI_NA ICON "icons/na.ico"
+IDI_DND ICON "icons/dnd.ico"
+IDI_OCCUPIED ICON "icons/occupied.ico"
+IDI_ONTHEPHONE ICON "icons/onthephone.ico"
+IDI_OUTTOLUNCH ICON "icons/outtolunch.ico"
+IDI_LANA ICON "icons/lana.ico"
+IDI_COMPUTER ICON "icons/computer.ico"
+IDI_GOOD_NAME ICON "icons/good_name.ico"
+IDI_BAD_NAME ICON "icons/bad_name.ico"
+IDI_OTHER_NAME ICON "icons/other_name.ico"
+IDI_OTHER_NAMES ICON "icons/other_names.ico"
+IDI_BAD_NAMES ICON "icons/bad_names.ico"
+IDI_GOOD_NAMES ICON "icons/good_names.ico"
+IDI_EXPLORE ICON "icons/explore.ico"
+IDI_COMPUTER_ERROR ICON "icons/computer_error.ico"
+IDI_ADD_COMPUTER ICON "icons/add.ico"
+
+#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
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPTIONS DIALOGEX 0, 0, 306, 229
+STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ CONTROL "Auto-reply to users with your status message while away",IDC_AUTOANSWER,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,10,291,10
+ CONTROL "Filter Duplicate Messages (RECOMMENDED)",IDC_DUPS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,20,291,10
+ CONTROL "Use Mailslot when sending (RECOMMENDED)",IDC_USE_MAILSLOT,
+ "Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,7,30,291,10
+ CONTROL "Use NetBIOS when sending",IDC_USE_NETBIOS,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,40,291,10
+ CONTROL "Use Messenger service when sending and receiving",IDC_USE_NETSEND,
+ "Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,50,291,10
+ CONTROL "Nick",IDC_CHECK_NICK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,85,80,10
+ EDITTEXT IDC_NICK1,93,84,100,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP
+ CONTROL "Username",IDC_CHECK_USER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,101,80,10
+ EDITTEXT IDC_USER,93,100,100,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP
+ EDITTEXT IDC_NICK2,198,84,100,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_TABSTOP
+ CONTROL "",IDC_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_DISABLEDRAGDROP | WS_BORDER | WS_TABSTOP,7,128,141,73
+ PUSHBUTTON "Add contact...",IDC_ADD,0,215,73,14
+ GROUPBOX "NetBIOS names registration",IDC_STATIC,0,73,305,136
+ ICON "",IDC_LEGEND_1,154,128,20,20
+ LTEXT "Successful names",IDC_STATIC,181,128,117,8
+ ICON "",IDC_LEGEND_2,154,142,20,20
+ LTEXT "Failed names",IDC_STATIC,181,142,117,8
+ ICON "",IDC_LEGEND_3,154,155,20,20
+ LTEXT "Other names",IDC_STATIC,181,155,117,8
+ ICON "",IDC_LEGEND_4,166,128,20,20
+ ICON "",IDC_LEGEND_5,166,142,20,20
+ ICON "",IDC_LEGEND_6,166,155,20,20
+ GROUPBOX "Options",IDC_STATIC,0,0,305,72
+ LTEXT "Status:",IDC_STATIC,7,117,24,8
+ CONTROL "Legacy online status detection",IDC_ALWAYSCHECK00FORONLINE,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,60,291,10
+END
+
+IDD_ADD DIALOGEX 0, 0, 186, 46
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Add contact..."
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ EDITTEXT IDC_NAME,7,7,115,14,ES_AUTOHSCROLL
+ DEFPUSHBUTTON "OK",IDOK,129,7,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,129,25,50,14
+ CONTROL "Group contact",IDC_GROUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,29,61,10
+END
+
+IDD_USERINFO DIALOGEX 0, 0, 222, 132
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ CONTROL "",IDC_TREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_DISABLEDRAGDROP | WS_BORDER | WS_HSCROLL | WS_TABSTOP,5,14,125,82
+ CONTROL "Always Online",IDC_ONLINE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,32,82,24
+ EDITTEXT IDC_ABOUT,5,107,125,20,ES_AUTOHSCROLL | ES_READONLY
+ LTEXT "NetBIOS names:",IDC_STATIC,5,5,125,8
+ LTEXT "Comment:",IDC_STATIC,5,97,125,8
+ CONTROL "Legacy online status detection",IDC_CHECK00FORONLINE,
+ "Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,135,5,82,24
+ CONTROL "Group contact",IDC_GROUP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,135,59,82,24
+END
+
+IDD_CREATE DIALOGEX 0, 0, 186, 134
+STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_OPTIONS, DIALOG
+ BEGIN
+ VERTGUIDE, 7
+ VERTGUIDE, 87
+ VERTGUIDE, 93
+ VERTGUIDE, 148
+ VERTGUIDE, 154
+ VERTGUIDE, 193
+ VERTGUIDE, 198
+ VERTGUIDE, 298
+ HORZGUIDE, 10
+ HORZGUIDE, 26
+ HORZGUIDE, 121
+ HORZGUIDE, 136
+ HORZGUIDE, 149
+ END
+
+ IDD_ADD, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 179
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 39
+ END
+
+ IDD_USERINFO, DIALOG
+ BEGIN
+ LEFTMARGIN, 5
+ RIGHTMARGIN, 217
+ VERTGUIDE, 135
+ TOPMARGIN, 5
+ BOTTOMMARGIN, 127
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto_7.sln b/plugins/!NotAdopted/WinPopup/winpopup_proto_7.sln
new file mode 100644
index 0000000000..056cc5afa1
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto_7.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winpopup_proto", "winpopup_proto_7.vcproj", "{56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ Debug = Debug
+ Release = Release
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}.Debug.ActiveCfg = Debug|Win32
+ {56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}.Debug.Build.0 = Debug|Win32
+ {56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}.Release.ActiveCfg = Release|Win32
+ {56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}.Release.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto_7.vcproj b/plugins/!NotAdopted/WinPopup/winpopup_proto_7.vcproj
new file mode 100644
index 0000000000..2b569e7183
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto_7.vcproj
@@ -0,0 +1,406 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.10"
+ Name="winpopup_proto"
+ ProjectGUID="{56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}"
+ RootNamespace="winpopup_proto"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="Debug"
+ IntermediateDirectory="Debug"
+ ConfigurationType="2"
+ UseOfATL="1"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="sdk"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"
+ StringPooling="TRUE"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="FALSE"
+ UsePrecompiledHeader="3"
+ BrowseInformation="1"
+ WarningLevel="4"
+ DebugInformationFormat="3"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="TRUE"
+ AdditionalDependencies="comctl32.lib Mpr.lib WSock32.Lib Netapi32.lib"
+ OutputFile="$(OutDir)\winpopup_proto.dll"
+ SuppressStartupBanner="TRUE"
+ ModuleDefinitionFile="winpopup_proto.def"
+ DelayLoadDLLs=""
+ GenerateDebugInformation="TRUE"
+ SubSystem="2"
+ BaseAddress="0x18a30000"
+ ImportLibrary=""
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Copy"
+ CommandLine="copy &quot;$(TargetPath)&quot; &quot;C:\Program Files\Miranda IM\Plugins\$(TargetFileName)&quot;"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="Release"
+ IntermediateDirectory="Release"
+ ConfigurationType="2"
+ UseOfATL="1"
+ ATLMinimizesCRunTimeLibraryUsage="FALSE"
+ CharacterSet="2"
+ WholeProgramOptimization="TRUE">
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ GlobalOptimizations="TRUE"
+ InlineFunctionExpansion="1"
+ EnableIntrinsicFunctions="TRUE"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="TRUE"
+ OptimizeForProcessor="1"
+ AdditionalIncludeDirectories="sdk"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+ StringPooling="TRUE"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="3"
+ BrowseInformation="1"
+ WarningLevel="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="TRUE"
+ AdditionalDependencies="comctl32.lib Mpr.lib WSock32.Lib Netapi32.lib"
+ ShowProgress="0"
+ OutputFile="$(OutDir)\winpopup_proto.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="TRUE"
+ IgnoreDefaultLibraryNames=""
+ ModuleDefinitionFile="winpopup_proto.def"
+ DelayLoadDLLs=""
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ OptimizeForWindows98="1"
+ SetChecksum="TRUE"
+ BaseAddress="0x18a30000"
+ ImportLibrary=""
+ TargetMachine="1"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Copy"
+ CommandLine="copy &quot;$(TargetPath)&quot; &quot;C:\Program Files\Miranda IM\Plugins\$(TargetFileName)&quot;"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ <Tool
+ Name="VCXMLDataGeneratorTool"/>
+ <Tool
+ Name="VCWebDeploymentTool"/>
+ <Tool
+ Name="VCManagedWrapperGeneratorTool"/>
+ <Tool
+ Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+ <File
+ RelativePath="add_dialog.cpp">
+ </File>
+ <File
+ RelativePath="mailslot.cpp">
+ </File>
+ <File
+ RelativePath="messagebox.cpp">
+ </File>
+ <File
+ RelativePath="messenger.cpp">
+ </File>
+ <File
+ RelativePath="netbios.cpp">
+ </File>
+ <File
+ RelativePath="netbios_name.cpp">
+ </File>
+ <File
+ RelativePath="network.cpp">
+ </File>
+ <File
+ RelativePath="options.cpp">
+ </File>
+ <File
+ RelativePath="processapi.cpp">
+ </File>
+ <File
+ RelativePath="scanner.cpp">
+ </File>
+ <File
+ RelativePath="services.cpp">
+ </File>
+ <File
+ RelativePath="stdafx.cpp">
+ <FileConfiguration
+ Name="Debug|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32">
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"/>
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="user_info.cpp">
+ </File>
+ <File
+ RelativePath="winpopup_proto.cpp">
+ </File>
+ <File
+ RelativePath="winpopup_proto.def">
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc">
+ <File
+ RelativePath="add_dialog.h">
+ </File>
+ <File
+ RelativePath="dllLoaderMinimal.h">
+ </File>
+ <File
+ RelativePath="mailslot.h">
+ </File>
+ <File
+ RelativePath="md5.h">
+ </File>
+ <File
+ RelativePath="messagebox.h">
+ </File>
+ <File
+ RelativePath="messenger.h">
+ </File>
+ <File
+ RelativePath="netbios.h">
+ </File>
+ <File
+ RelativePath="netbios_name.h">
+ </File>
+ <File
+ RelativePath="network.h">
+ </File>
+ <File
+ RelativePath="options.h">
+ </File>
+ <File
+ RelativePath="processapi.h">
+ </File>
+ <File
+ RelativePath="resource.h">
+ </File>
+ <File
+ RelativePath="scanner.h">
+ </File>
+ <File
+ RelativePath="services.h">
+ </File>
+ <File
+ RelativePath="smbconst.h">
+ </File>
+ <File
+ RelativePath="stdafx.h">
+ </File>
+ <File
+ RelativePath="user_info.h">
+ </File>
+ <File
+ RelativePath="winpopup_proto.h">
+ </File>
+ <Filter
+ Name="sdk"
+ Filter="h;hpp;hxx;hm;inl;inc">
+ <File
+ RelativePath="sdk\m_clist.h">
+ </File>
+ <File
+ RelativePath="sdk\m_database.h">
+ </File>
+ <File
+ RelativePath="sdk\m_langpack.h">
+ </File>
+ <File
+ RelativePath="sdk\m_netlib.h">
+ </File>
+ <File
+ RelativePath="sdk\m_options.h">
+ </File>
+ <File
+ RelativePath="sdk\m_plugins.h">
+ </File>
+ <File
+ RelativePath="sdk\m_popup.h">
+ </File>
+ <File
+ RelativePath="sdk\m_protomod.h">
+ </File>
+ <File
+ RelativePath="sdk\m_protosvc.h">
+ </File>
+ <File
+ RelativePath="sdk\m_system.h">
+ </File>
+ <File
+ RelativePath="sdk\m_userinfo.h">
+ </File>
+ <File
+ RelativePath="sdk\m_utils.h">
+ </File>
+ <File
+ RelativePath="sdk\newpluginapi.h">
+ </File>
+ <File
+ RelativePath="sdk\statusmodes.h">
+ </File>
+ </Filter>
+ <Filter
+ Name="3d party"
+ Filter="h;hpp;hxx;hm;inl;inc">
+ <File
+ RelativePath="m_uninstaller.h">
+ </File>
+ <File
+ RelativePath="m_updater.h">
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+ <File
+ RelativePath="winpopup_proto.rc">
+ </File>
+ <Filter
+ Name="icons"
+ Filter="">
+ <File
+ RelativePath="icons\add.ico">
+ </File>
+ <File
+ RelativePath="icons\away.ico">
+ </File>
+ <File
+ RelativePath="icons\bad_name.ico">
+ </File>
+ <File
+ RelativePath="icons\bad_names.ico">
+ </File>
+ <File
+ RelativePath="icons\computer.ico">
+ </File>
+ <File
+ RelativePath="icons\computer_error.ico">
+ </File>
+ <File
+ RelativePath="icons\dnd.ico">
+ </File>
+ <File
+ RelativePath="icons\explore.ico">
+ </File>
+ <File
+ RelativePath="icons\freechat.ico">
+ </File>
+ <File
+ RelativePath="icons\good_name.ico">
+ </File>
+ <File
+ RelativePath="icons\good_names.ico">
+ </File>
+ <File
+ RelativePath="icons\invisible.ico">
+ </File>
+ <File
+ RelativePath="icons\lana.ico">
+ </File>
+ <File
+ RelativePath="icons\na.ico">
+ </File>
+ <File
+ RelativePath="icons\occupied.ico">
+ </File>
+ <File
+ RelativePath="icons\offline.ico">
+ </File>
+ <File
+ RelativePath="icons\online.ico">
+ </File>
+ <File
+ RelativePath="icons\onthephone.ico">
+ </File>
+ <File
+ RelativePath="icons\other_name.ico">
+ </File>
+ <File
+ RelativePath="icons\other_names.ico">
+ </File>
+ <File
+ RelativePath="icons\outtolunch.ico">
+ </File>
+ <File
+ RelativePath="icons\winpopup_proto.ico">
+ </File>
+ </Filter>
+ </Filter>
+ <File
+ RelativePath="winpopup_proto_readme.txt">
+ </File>
+ <File
+ RelativePath="winpopup_proto_translation.txt">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto_9.icproj b/plugins/!NotAdopted/WinPopup/winpopup_proto_9.icproj
new file mode 100644
index 0000000000..8f6b27af17
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto_9.icproj
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Intel C++ Project"
+ Version="11.0"
+ Name="winpopup_proto"
+ ProjectGUID="{C495B4C8-8D1E-4B56-BF3A-3998861493D3}"
+ VCNestedProjectGUID="{56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}"
+ VCNestedProjectFileName="winpopup_proto_9.vcproj">
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32">
+ <Tool
+ Name="CppCmplrTool"
+ DisableSpecificDiagnostics="82,981,2270,2273"
+ LevelOfStaticAnalysis="1"/>
+ </Configuration>
+ <Configuration
+ Name="Debug|x64">
+ <Tool
+ Name="CppCmplrTool"
+ DisableSpecificDiagnostics="82,981,2270,2273"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32">
+ <Tool
+ Name="CppCmplrTool"
+ DisableSpecificDiagnostics="82,981,2270,2273"/>
+ </Configuration>
+ <Configuration
+ Name="Release|x64">
+ <Tool
+ Name="CppCmplrTool"
+ DisableSpecificDiagnostics="82,981,2270,2273"/>
+ </Configuration>
+ </Configurations>
+ <Files/>
+</VisualStudioProject>
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto_9.sln b/plugins/!NotAdopted/WinPopup/winpopup_proto_9.sln
new file mode 100644
index 0000000000..b95e500d14
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto_9.sln
@@ -0,0 +1,28 @@
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winpopup_proto", "winpopup_proto_9.vcproj", "{56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}"
+EndProject
+Global
+ GlobalSection(DPCodeReviewSolutionGUID) = preSolution
+ DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}
+ EndGlobalSection
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}.Debug|Win32.Build.0 = Debug|Win32
+ {56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}.Debug|x64.ActiveCfg = Debug|x64
+ {56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}.Debug|x64.Build.0 = Debug|x64
+ {56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}.Release|Win32.ActiveCfg = Release|Win32
+ {56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}.Release|Win32.Build.0 = Release|Win32
+ {56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}.Release|x64.ActiveCfg = Release|x64
+ {56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto_9.vcproj b/plugins/!NotAdopted/WinPopup/winpopup_proto_9.vcproj
new file mode 100644
index 0000000000..7bdafe032a
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto_9.vcproj
@@ -0,0 +1,773 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="winpopup_proto"
+ ProjectGUID="{56F4BA4F-5155-4D7A-99BB-F7EA0A854CCE}"
+ RootNamespace="winpopup_proto"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ UseOfATL="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="sdk"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"
+ ExceptionHandling="0"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ EnableFunctionLevelLinking="true"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="comctl32.lib Mpr.lib WSock32.Lib Netapi32.lib"
+ LinkIncremental="2"
+ ModuleDefinitionFile="winpopup_proto.def"
+ DelayLoadDLLs=""
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ BaseAddress="0x18a30000"
+ ImportLibrary=""
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ AssemblyIdentity="WinPopup_Proto.WinPopup_Proto, version=0.0.0.18, processorArchitecture=x86, type=win32"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Copy..."
+ CommandLine="if exist &quot;C:\Program Files (x86)&quot; copy &quot;$(TargetPath)&quot; &quot;C:\Program Files (x86)\Miranda IM\Plugins\$(TargetFileName)&quot;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ UseOfATL="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ 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="sdk"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"
+ ExceptionHandling="0"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ EnableFunctionLevelLinking="true"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="comctl32.lib Mpr.lib WSock32.Lib Netapi32.lib"
+ LinkIncremental="2"
+ ModuleDefinitionFile="winpopup_proto.def"
+ DelayLoadDLLs=""
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ BaseAddress=""
+ ImportLibrary=""
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ AssemblyIdentity="WinPopup_Proto.WinPopup_Proto, version=0.0.0.18, processorArchitecture=x86, type=win32"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Copy..."
+ CommandLine="copy &quot;$(TargetPath)&quot; &quot;C:\Program Files\Miranda IM\Plugins\$(TargetFileName)&quot;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ UseOfATL="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/Wall"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="2"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="sdk"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="0"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ WarningLevel="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="comctl32.lib Mpr.lib WSock32.Lib Netapi32.lib"
+ LinkIncremental="1"
+ IgnoreDefaultLibraryNames=""
+ ModuleDefinitionFile="winpopup_proto.def"
+ DelayLoadDLLs=""
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ SetChecksum="true"
+ BaseAddress="0x18a30000"
+ ImportLibrary=""
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ AssemblyIdentity="WinPopup_Proto.WinPopup_Proto, version=0.0.0.18, processorArchitecture=x86, type=win32"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Copy..."
+ CommandLine="if exist &quot;C:\Program Files (x86)&quot; copy &quot;$(TargetPath)&quot; &quot;C:\Program Files (x86)\Miranda IM\Plugins\$(TargetFileName)&quot;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ UseOfATL="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ 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="2"
+ OmitFramePointers="true"
+ AdditionalIncludeDirectories="sdk"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+ StringPooling="true"
+ ExceptionHandling="0"
+ RuntimeLibrary="0"
+ FloatingPointModel="2"
+ RuntimeTypeInfo="false"
+ UsePrecompiledHeader="2"
+ WarningLevel="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ IgnoreImportLibrary="true"
+ AdditionalDependencies="comctl32.lib Mpr.lib WSock32.Lib Netapi32.lib"
+ LinkIncremental="1"
+ IgnoreDefaultLibraryNames=""
+ ModuleDefinitionFile="winpopup_proto.def"
+ DelayLoadDLLs=""
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ SetChecksum="true"
+ BaseAddress=""
+ ImportLibrary=""
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ AssemblyIdentity="WinPopup_Proto.WinPopup_Proto, version=0.0.0.18, processorArchitecture=x86, type=win32"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Copy..."
+ CommandLine="copy &quot;$(TargetPath)&quot; &quot;C:\Program Files\Miranda IM\Plugins\$(TargetFileName)&quot;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+ >
+ <File
+ RelativePath="add_dialog.cpp"
+ >
+ </File>
+ <File
+ RelativePath="chat.cpp"
+ >
+ </File>
+ <File
+ RelativePath="mailslot.cpp"
+ >
+ </File>
+ <File
+ RelativePath="messagebox.cpp"
+ >
+ </File>
+ <File
+ RelativePath="messenger.cpp"
+ >
+ </File>
+ <File
+ RelativePath="netbios.cpp"
+ >
+ </File>
+ <File
+ RelativePath="netbios_name.cpp"
+ >
+ </File>
+ <File
+ RelativePath="network.cpp"
+ >
+ </File>
+ <File
+ RelativePath="options.cpp"
+ >
+ </File>
+ <File
+ RelativePath="processapi.cpp"
+ >
+ </File>
+ <File
+ RelativePath="scanner.cpp"
+ >
+ </File>
+ <File
+ RelativePath="search.cpp"
+ >
+ </File>
+ <File
+ RelativePath="services.cpp"
+ >
+ </File>
+ <File
+ RelativePath="stdafx.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|x64"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="user_info.cpp"
+ >
+ </File>
+ <File
+ RelativePath="winpopup_proto.cpp"
+ >
+ </File>
+ <File
+ RelativePath="winpopup_proto.def"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc"
+ >
+ <File
+ RelativePath="add_dialog.h"
+ >
+ </File>
+ <File
+ RelativePath="chat.h"
+ >
+ </File>
+ <File
+ RelativePath="dllLoaderMinimal.h"
+ >
+ </File>
+ <File
+ RelativePath="mailslot.h"
+ >
+ </File>
+ <File
+ RelativePath="md5.h"
+ >
+ </File>
+ <File
+ RelativePath="messagebox.h"
+ >
+ </File>
+ <File
+ RelativePath="messenger.h"
+ >
+ </File>
+ <File
+ RelativePath="netbios.h"
+ >
+ </File>
+ <File
+ RelativePath="netbios_name.h"
+ >
+ </File>
+ <File
+ RelativePath="network.h"
+ >
+ </File>
+ <File
+ RelativePath="options.h"
+ >
+ </File>
+ <File
+ RelativePath="processapi.h"
+ >
+ </File>
+ <File
+ RelativePath="resource.h"
+ >
+ </File>
+ <File
+ RelativePath="scanner.h"
+ >
+ </File>
+ <File
+ RelativePath="search.h"
+ >
+ </File>
+ <File
+ RelativePath="services.h"
+ >
+ </File>
+ <File
+ RelativePath="smbconst.h"
+ >
+ </File>
+ <File
+ RelativePath="stdafx.h"
+ >
+ </File>
+ <File
+ RelativePath="user_info.h"
+ >
+ </File>
+ <File
+ RelativePath="winpopup_proto.h"
+ >
+ </File>
+ <Filter
+ Name="sdk"
+ Filter="h;hpp;hxx;hm;inl;inc"
+ >
+ <File
+ RelativePath="sdk\m_avatars.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_chat.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_clist.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_database.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_langpack.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_netlib.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_options.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_plugins.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_popup.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_protomod.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_protosvc.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_system.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_userinfo.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\m_utils.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\newpluginapi.h"
+ >
+ </File>
+ <File
+ RelativePath="sdk\statusmodes.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="3d party"
+ Filter="h;hpp;hxx;hm;inl;inc"
+ >
+ <File
+ RelativePath="m_uninstaller.h"
+ >
+ </File>
+ <File
+ RelativePath="m_updater.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ <File
+ RelativePath="winpopup_proto.rc"
+ >
+ </File>
+ <Filter
+ Name="icons"
+ >
+ <File
+ RelativePath="icons\add.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\away.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\bad_name.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\bad_names.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\computer.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\computer_error.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\dnd.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\explore.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\freechat.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\good_name.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\good_names.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\invisible.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\lana.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\na.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\occupied.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\offline.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\online.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\onthephone.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\other_name.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\other_names.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\outtolunch.ico"
+ >
+ </File>
+ <File
+ RelativePath="icons\winpopup_proto.ico"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <File
+ RelativePath=".\winpopup_proto_pack.cmd"
+ >
+ </File>
+ <File
+ RelativePath="winpopup_proto_readme.txt"
+ >
+ </File>
+ <File
+ RelativePath="winpopup_proto_translation.txt"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto_pack.cmd b/plugins/!NotAdopted/WinPopup/winpopup_proto_pack.cmd
new file mode 100644
index 0000000000..5d7557b1f8
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto_pack.cmd
@@ -0,0 +1,6 @@
+set version=0.0.0.19
+md "setup"
+del "setup\winpopup_proto-%version%.zip"
+"%ProgramFiles%\WinRar\winrar.exe" a -ep -m5 -cfg- -afzip "setup\winpopup_proto-%version%.zip" winpopup_proto_readme.txt winpopup_proto_translation.txt Win32\release\winpopup_proto.dll
+del "setup\winpopup_proto_src-%version%.zip"
+"%ProgramFiles%\WinRar\winrar.exe" a -m5 -ed -ep1 -r -cfg- -afzip "setup\winpopup_proto_src-%version%.zip" *.* -x*\.svn\* -x*\debug\* -x*\release\* -x*\setup\* -x*.user -x*.aps -x*.ncb -x*.suo \ No newline at end of file
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto_readme.txt b/plugins/!NotAdopted/WinPopup/winpopup_proto_readme.txt
new file mode 100644
index 0000000000..d4dfb8bd9b
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto_readme.txt
@@ -0,0 +1,245 @@
+WinPopup Protocol plugin for Miranda IM
+
+Copyright (C) 2004-2011 Nikolay Raspopov
+mailto: ryo-oh-ki[at]narod[dot]ru
+http://www.cherubicsoft.com/miranda/
+
+Communicate with users over LAN, compatible with "net send", WinPopup,
+VikPoup, RealPopup, Netter and Miranda`s net_send_protocol, mNetSend plugins.
+Uses Mailslot, NetBIOS and Messenger service for sending and receiving messages.
+
+System requirements:
+
+ Network with NetBIOS over TCP/IP enabled
+
+ for 0.0.0.17
+ Miranda IM 0.5.2.x
+ Windows 95,98,ME,NT.
+
+ for 0.0.0.18
+ Miranda IM 0.7.x.x
+ Windows 2000,XP,2003,Vista,7.
+
+Notes:
+
+ Search supports wildcards (case insensitive):
+ ? - any single symbol,
+ * - any number of symbols including zero,
+ # - any digital symbol,
+ [abcd] - symbol set,
+ [a-z] - sumbol range,
+ [!...] - NOT in symbol set or range.
+
+ How to send group messages:
+ 1) Open plugin options page;
+ 2) Check "Use Mailslot when sending" option;
+ 3) Press "Add Contact..." button;
+ 4) Type domain/workgroup name or * for everybody and check "Group contact" option;
+ 5) Send messge using newly created contact.
+
+ You got "Access Denied" error when switching to online:
+ Try to check "Use Messenger service when sending and receiving" option
+ in plugin options.
+
+ "Legacy online status detection" option:
+ Detection online status by <00> NetBIOS-name also,
+ normally status detected by <03> NetBIOS-name (aka Messenger).
+
+Installation:
+
+ 1) Close similar applications - WinPopup, VikPopup, RealPopup, HiBuddy, NetHail,
+ NetSend, Netter, OfficePopup, LanTalk XP etc.
+ 2) Disable similar Miranda IM plugins - net_send_protocol, mNetSend.
+ 3) Unzip winpopup_proto.dll to ..Miranda IM\Plugin\ folder.
+ 4) Restart Miranda IM.
+
+Files:
+
+ winpopup_proto.dll - WinPopup Protocol Plugin
+ winpopup_proto_readme.txt - This file
+ winpopup_proto_translation.txt - Translation template for language pack authors only
+
+History:
+
+ Old versions available at: http://www.cherubicsoft.com/miranda/
+
+ 0.0.0.19
+ - Tweaked NetBIOS time-outs
+ - More NetBIOS debug messages
+ - Fixed <CR><LF> sending over NetBIOS
+
+ 0.0.0.18
+ - Headers updated up to Miranda IM 0.9
+ - Added Unicode support
+ - Added 64-bit support
+ - Added avatar support
+ - Added group contact support
+ - Performance optimizations
+ - Added support for NetLib log
+ - Fixed crash at miranda exit when contact still scanning
+ - Fixed resource leaks (icons)
+ - Fixed small memory leaks by replacing internal ForkThread() with Miranda mir_forkthread()
+ - Fixed contact status detection when "Always Online" option set
+ - Fixed extra requests of contact status retrieving
+ - Fixed contact away message requesting
+ - Fixed potential security problems
+ - Reduced miranda exit time
+ - Changed system requirements (removed Win9x/NT support, added Vista/7 support)
+ - Project upgraded up to VS 2008
+
+ 0.0.0.17
+ - Headers updated up to Miranda IM 0.8
+ - Added main menu
+ - Added "Legacy online status detection" option (by Anatoliy Samara)
+
+ 0.0.0.16
+ - Headers updated up to Miranda IM 0.6 and plugin's sources were commented
+ - Added support for non-latin (OEM) user/computer names
+ - Added "Always Online" checkbox to contact's options
+ - Added mNetSend contact's status support
+ - Added "Free for chat" and "Invisible" statuses
+ - Now Messenger service can be started even from disabled state (Administrators only)
+ - Contact status check delay reduced from 60 to 30 seconds
+ - Fixed plugin hangup is some cases during Miranda shutdown on Win9x
+ - Updated translation file
+
+ 0.0.0.15
+ - Fixed duplicated NetBIOS-names of options page
+ - Fixed non-Messenger dialogs stealing
+ - Fixed false NetBIOS error 13 when computer and user names are equal
+ - Fixed false Access Denied error when unprivileged user starts Miranda IM and
+ Messenger service already stopped or started
+ - Fixed incompatibility with WinNT 4.0 (since 0.0.0.14)
+ - Fixed empty NetBIOS names registration (some rare plugins combinations)
+ - Changed infinite message popups timeout to 10 second timeout
+ - Added message boxes with timeouts (used when Popup plugin is absent)
+ - Added item "Explore" of contacts menu
+ - Added NetBIOS names registration separate selection
+ - Added automatic applying (switching to offline/online) of changed options
+ - Added remote computer comment field to user info
+ - Updated translation file
+
+ 0.0.0.14
+ - Added full implementation of "Messenger sevice" mode
+ - Added enhanced network error messages
+ - Added support for Popup plugin
+ - Fixed unexpected long timeout of contact online status scanning
+ - Fixed missed Translate() calls
+ - Fixed worker threads handling (more robust way, like Miranda IM itself)
+ - Updated translation file
+ - Some minor fixes
+
+ 0.0.0.13
+ - System requirements lowered to Win95
+ - ICMP CODS (contact online detection system :) replaced by NetBIOS CODS
+ - Fixed empty message appearance when unsupported type of SMB-packet recieved
+ (by Andrew O. Shadoura)
+ - Fixed "missed names" in NetBIOS reciever
+ - Fixed "connecting 2" plugin status (now "offline")
+ - Added NetBIOS method of sending
+ - Added NetMessageBufferSend method of sending
+ (WinNT + started Messenger service)
+ - Added "patient" NetBIOS-names deregistration routines
+ - Added search cancellation capabilities
+ - Added page with NetBIOS information to User Info dialog
+ - Added "NetBIOS names registration status" to Options dialog
+ - Added support for Updater plugin
+ (http://addons.miranda-im.org/details.php?action=viewfile&id=2254)
+ - Updated translation file
+ - Some minor fixes
+
+ 0.0.0.12
+ - Version fix
+
+ 0.0.0.11
+ - Fixed crash after Miranda exit (DestroyServiceFunction bug)
+ - Persistent protocol status icons changed to customized
+
+ 0.0.0.10
+ - Fixed crash if invalid computer name consists of upper ASCII table symbols
+ (russian symbols, germany umlauts etc.) in CharUpper WinAPI32 function
+ - Fixed incorrect IP resolving if invalid computer name begins with digital
+ - Fixed forgotten "unpingable" contacts (by Andrey anl_public3[at]mail.ru)
+ - Fixed 100% CPU usage if network connection was lost (now switching to offline)
+ - Added simple NetBIOS-names lookup
+ - Allowed contacts with unknown IP (user responsibility)
+ - Updated translation file
+
+ 0.0.0.9
+ - Now searching for computer names, comments or workgroups (using wildcards)
+ - Added protection vs mailslot BO-attack
+ - Added duplicate message filtering
+ - Some small NetBIOS fixes
+ - Removed 256 chars message limitation (doh!)
+ - Fixed big message (> 424 bytes) handling error
+
+ 0.0.0.8
+ - Fixed unexpected locking inside Win32 API function ReadFile when
+ reading from mailslot created with MAILSLOT_WAIT_FOREVER flag under Win98
+ (MAILSLOT_WAIT_FOREVER replaced with 2000 ms timeout)
+ - Added big message splitting (424 bytes parts)
+ - Added send message throttle (1000 ms) to preventing receivers mailslot overloading
+ - Added direct contact addition (inside Options page) by name or IP
+ - Added "RealIP" (equal "IP") and "About" (computer comment) settings to contact
+ - Changed translation file
+
+ 0.0.0.7
+ - Added options page
+ - Added "Connecting" status (more smoother startup and shutdown)
+ - Added translation template file
+ - Added self message recognition
+ - Added message CR-LF-B6 normalization
+ - Added uninstaller support (PluginUninstaller 1.1.2.1)
+ - Some titles renamed from "WinPopup Protocol" to "WinPopup"
+ - Extended error messages
+ - Project updated up to Visual Studio .NET 2003
+ - Project refactored (STL to ATL -> file size changed from 112Kb to 72Kb)
+
+ 0.0.0.6
+ - Fixed "Unknown Contact" in some poor interface plugins
+ - Added persistent protocol status icons
+
+ 0.0.0.5
+ - Added "IP" setting to contacts (good for some plugins)
+ - Optimized ping detection routine
+ - Optimized LAN names search routine (now multithreaded, NetBIOS search not yet implemented)
+ - Optimized message sender (now multithreaded)
+ - Added NetBIOS message receiver
+ - Fixed Stop/Restart Windows Messenger Service routine
+
+ 0.0.0.4
+ - Added experimental support for NetBIOS name registration (computer, current user, nick)
+ - Added restoring Microsoft Network Messenger after closing Miranda IM
+ - Fixed false contact status detection (was bug in ping functions)
+
+ 0.0.0.3
+ - Plugin file renamed to winpopup_proto.dll
+ - Fixed tiny memory leak in ReceiveMessage function
+ - Added online/offline status checker
+ - Added auto-answer
+ - Added support for extended statuses (away, na, dnd, etc.)
+ - Added Miranda-aware safe threads handling
+ - Fixed hidden contact of first message
+
+ 0.0.0.2
+ - Fixed tiny memory leak in SendMsg function
+ - Mailslot-receiver thread code refactored
+
+ 0.0.0.1
+ - Released first version
+
+License:
+
+ 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.
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto_todo.txt b/plugins/!NotAdopted/WinPopup/winpopup_proto_todo.txt
new file mode 100644
index 0000000000..98409ccb7a
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto_todo.txt
@@ -0,0 +1,9 @@
+; this is a WinPopup Protocol plugin TODO list (russian)
+
+- Ввести кеширование поиска по сети (сбор имен все время?)
+- Ввести контакты на пользователя, а не на компьютер
+- Попробовать реализовать смену ника отправителя
+- Добавить поиск по IP
+- Ввести сравку и/или поддержку тултипов
+- Доделать в коде класса mailslot определение конфликтных процессов
+ (найти способ определения процесса - владельца мейлслота)
diff --git a/plugins/!NotAdopted/WinPopup/winpopup_proto_translation.txt b/plugins/!NotAdopted/WinPopup/winpopup_proto_translation.txt
new file mode 100644
index 0000000000..d8e26340ee
--- /dev/null
+++ b/plugins/!NotAdopted/WinPopup/winpopup_proto_translation.txt
@@ -0,0 +1,43 @@
+; this is a template for translation of WinPopup Protocol plugin
+; last updated 25 Feb 2010 for 0.0.0.18
+
+[Add contact...]
+[Always Online]
+[Auto-reply]
+[Auto-reply to users with your status message while away]
+[Cancel]
+[Cannot send message]
+[Cannot create receiving mailslot]
+[Cannot operate Messenger service]
+[Cannot register NetBIOS name]
+[Cannot resolve contacts IP-address. Add it anyway?]
+[Cannot start Messenger service]
+[Cannot stop Messenger service]
+[Computer,User,Group]
+[Comment:]
+[Error]
+[Explore]
+[Failed names]
+[Filter Duplicate Messages (RECOMMENDED)]
+[Group contact]
+[LAN adapter]
+[Legacy online status detection]
+[NetBIOS names:]
+[NetBIOS names registration]
+[Network]
+[Nick]
+[No progress]
+[OK]
+[Offline]
+[Options]
+[Other names]
+[Please shutdown any other IM applications and/or Messenger service]
+[Plugins]
+[Retrieving...]
+[Successful names]
+[Status:]
+[Unexpected service status change]
+[Use Mailslot when sending (RECOMMENDED)]
+[Use NetBIOS when sending]
+[Use Messenger service when sending and receiving]
+[Username]