From eb304eedf191bd847c7a4ea00b302149301cfa4e Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Sun, 29 Jul 2012 21:43:45 +0000 Subject: git-svn-id: http://svn.miranda-ng.org/main/trunk@1261 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Msg_Export/msg_export_10.vcxproj | 162 ++ plugins/Msg_Export/msg_export_10.vcxproj.filters | 63 + plugins/Msg_Export/res/export_m.ico | Bin 0 -> 9062 bytes plugins/Msg_Export/res/langpack_msg_export.txt | 325 +++ plugins/Msg_Export/res/notick.ico | Bin 0 -> 318 bytes plugins/Msg_Export/res/resource.rc | 327 +++ plugins/Msg_Export/res/tick.ico | Bin 0 -> 318 bytes plugins/Msg_Export/src/FileViewer.cpp | 1424 ++++++++++++ plugins/Msg_Export/src/FileViewer.h | 38 + plugins/Msg_Export/src/Glob.h | 29 + plugins/Msg_Export/src/main.cpp | 404 ++++ plugins/Msg_Export/src/options.cpp | 1483 +++++++++++++ plugins/Msg_Export/src/options.h | 26 + plugins/Msg_Export/src/resource.h | 59 + plugins/Msg_Export/src/utils.cpp | 1738 +++++++++++++++ plugins/Msg_Export/src/utils.h | 125 ++ plugins/New_GPG/Makefile | 23 + plugins/New_GPG/README | 6 + plugins/New_GPG/dependencies/include/utf8.h | 34 + .../New_GPG/dependencies/include/utf8/checked.h | 327 +++ plugins/New_GPG/dependencies/include/utf8/core.h | 329 +++ .../New_GPG/dependencies/include/utf8/unchecked.h | 228 ++ plugins/New_GPG/new_gpg_10.vcxproj | 1031 +++++++++ plugins/New_GPG/new_gpg_10.vcxproj.filters | 103 + plugins/New_GPG/new_gpg_lang_ru.txt | 115 + plugins/New_GPG/res/icons/secured.ico | Bin 0 -> 2550 bytes plugins/New_GPG/res/icons/unsecured.ico | Bin 0 -> 2550 bytes plugins/New_GPG/res/new_gpg.rc | 419 ++++ plugins/New_GPG/src/clist.cpp | 41 + plugins/New_GPG/src/commonheaders.h | 88 + plugins/New_GPG/src/constants.h | 5 + plugins/New_GPG/src/globals.h | 22 + plugins/New_GPG/src/gpg_wrapper.cpp | 163 ++ plugins/New_GPG/src/gpg_wrapper.h | 50 + plugins/New_GPG/src/icons.cpp | 152 ++ plugins/New_GPG/src/init.cpp | 288 +++ plugins/New_GPG/src/jabber_account.cpp | 85 + plugins/New_GPG/src/jabber_account.h | 43 + plugins/New_GPG/src/log.cpp | 91 + plugins/New_GPG/src/log.h | 35 + plugins/New_GPG/src/m_extraicons.h | 158 ++ plugins/New_GPG/src/m_metacontacts.h | 166 ++ plugins/New_GPG/src/main.cpp | 2305 ++++++++++++++++++++ plugins/New_GPG/src/main.h | 31 + plugins/New_GPG/src/messages.cpp | 1058 +++++++++ plugins/New_GPG/src/metacontacts.cpp | 88 + plugins/New_GPG/src/metacontacts.h | 24 + plugins/New_GPG/src/options.cpp | 1387 ++++++++++++ plugins/New_GPG/src/resource.h | 96 + plugins/New_GPG/src/srmm.cpp | 88 + plugins/New_GPG/src/utilities.cpp | 1824 ++++++++++++++++ plugins/New_GPG/src/utilities.h | 104 + 52 files changed, 17210 insertions(+) create mode 100755 plugins/Msg_Export/msg_export_10.vcxproj create mode 100755 plugins/Msg_Export/msg_export_10.vcxproj.filters create mode 100755 plugins/Msg_Export/res/export_m.ico create mode 100755 plugins/Msg_Export/res/langpack_msg_export.txt create mode 100755 plugins/Msg_Export/res/notick.ico create mode 100755 plugins/Msg_Export/res/resource.rc create mode 100755 plugins/Msg_Export/res/tick.ico create mode 100755 plugins/Msg_Export/src/FileViewer.cpp create mode 100755 plugins/Msg_Export/src/FileViewer.h create mode 100755 plugins/Msg_Export/src/Glob.h create mode 100755 plugins/Msg_Export/src/main.cpp create mode 100755 plugins/Msg_Export/src/options.cpp create mode 100755 plugins/Msg_Export/src/options.h create mode 100755 plugins/Msg_Export/src/resource.h create mode 100755 plugins/Msg_Export/src/utils.cpp create mode 100755 plugins/Msg_Export/src/utils.h create mode 100755 plugins/New_GPG/Makefile create mode 100755 plugins/New_GPG/README create mode 100755 plugins/New_GPG/dependencies/include/utf8.h create mode 100755 plugins/New_GPG/dependencies/include/utf8/checked.h create mode 100755 plugins/New_GPG/dependencies/include/utf8/core.h create mode 100755 plugins/New_GPG/dependencies/include/utf8/unchecked.h create mode 100755 plugins/New_GPG/new_gpg_10.vcxproj create mode 100755 plugins/New_GPG/new_gpg_10.vcxproj.filters create mode 100755 plugins/New_GPG/new_gpg_lang_ru.txt create mode 100755 plugins/New_GPG/res/icons/secured.ico create mode 100755 plugins/New_GPG/res/icons/unsecured.ico create mode 100755 plugins/New_GPG/res/new_gpg.rc create mode 100755 plugins/New_GPG/src/clist.cpp create mode 100755 plugins/New_GPG/src/commonheaders.h create mode 100755 plugins/New_GPG/src/constants.h create mode 100755 plugins/New_GPG/src/globals.h create mode 100755 plugins/New_GPG/src/gpg_wrapper.cpp create mode 100755 plugins/New_GPG/src/gpg_wrapper.h create mode 100755 plugins/New_GPG/src/icons.cpp create mode 100755 plugins/New_GPG/src/init.cpp create mode 100755 plugins/New_GPG/src/jabber_account.cpp create mode 100755 plugins/New_GPG/src/jabber_account.h create mode 100755 plugins/New_GPG/src/log.cpp create mode 100755 plugins/New_GPG/src/log.h create mode 100755 plugins/New_GPG/src/m_extraicons.h create mode 100755 plugins/New_GPG/src/m_metacontacts.h create mode 100755 plugins/New_GPG/src/main.cpp create mode 100755 plugins/New_GPG/src/main.h create mode 100755 plugins/New_GPG/src/messages.cpp create mode 100755 plugins/New_GPG/src/metacontacts.cpp create mode 100755 plugins/New_GPG/src/metacontacts.h create mode 100755 plugins/New_GPG/src/options.cpp create mode 100755 plugins/New_GPG/src/resource.h create mode 100755 plugins/New_GPG/src/srmm.cpp create mode 100755 plugins/New_GPG/src/utilities.cpp create mode 100755 plugins/New_GPG/src/utilities.h diff --git a/plugins/Msg_Export/msg_export_10.vcxproj b/plugins/Msg_Export/msg_export_10.vcxproj new file mode 100755 index 0000000000..59f399d181 --- /dev/null +++ b/plugins/Msg_Export/msg_export_10.vcxproj @@ -0,0 +1,162 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + + + + + + + + + + + + + + + + + + + {4CE78D43-FF23-4134-A5AC-B2CF0F8D9F3B} + msg_export + msg_export + + + + DynamicLibrary + false + + + DynamicLibrary + false + Unicode + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + false + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + true + false + false + AllRules.ruleset + + + AllRules.ruleset + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/msg_export.tlb + + + + + MinSpace + OnlyExplicitInline + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);_CRT_SECURE_NO_DEPRECATE;UNICODE;_UNICODE + true + MultiThreaded + true + + + Level4 + true + ..\..\include;..\..\plugins\ExternalAPI;libgadu;%(AdditionalIncludeDirectories) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + /filealign:0x200 %(AdditionalOptions) + comctl32.lib;%(AdditionalDependencies) + true + false + 0x22100000 + false + + + MachineX86 + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\msg_export___Win32_Debug/msg_export.tlb + + + + + Disabled + _DEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions);_CRT_SECURE_NO_DEPRECATE;UNICODE;_UNICODE + MultiThreadedDebug + + + true + Level4 + true + ProgramDatabase + ..\..\include;..\..\plugins\ExternalAPI;libgadu;%(AdditionalIncludeDirectories) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + /filealign:0x200 %(AdditionalOptions) + comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName)$(TargetExt) + true + false + true + 0x22100000 + false + + + MachineX86 + $(SolutionDir)\lib + + + + + + \ No newline at end of file diff --git a/plugins/Msg_Export/msg_export_10.vcxproj.filters b/plugins/Msg_Export/msg_export_10.vcxproj.filters new file mode 100755 index 0000000000..ada2a79e40 --- /dev/null +++ b/plugins/Msg_Export/msg_export_10.vcxproj.filters @@ -0,0 +1,63 @@ + + + + + {8b9237c4-9104-49cd-9e02-a216d059bfb6} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {f8f2c8ef-4b67-43be-b1c4-cf53c2e15bd7} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + {a4d03f87-3170-4821-9a81-648b77757e88} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/Msg_Export/res/export_m.ico b/plugins/Msg_Export/res/export_m.ico new file mode 100755 index 0000000000..5f85a18803 Binary files /dev/null and b/plugins/Msg_Export/res/export_m.ico differ diff --git a/plugins/Msg_Export/res/langpack_msg_export.txt b/plugins/Msg_Export/res/langpack_msg_export.txt new file mode 100755 index 0000000000..2397ac0acb --- /dev/null +++ b/plugins/Msg_Export/res/langpack_msg_export.txt @@ -0,0 +1,325 @@ +;; ====== Message Export =========== +; This file contains all the strings used in the Message Export +; plugin. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Contact menu item +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[Open E&xported History] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Main options Tree +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[Plugins] +[Message export] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Main options dialog +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Static +[Export directory] +[Browse] +[Default file] +[Export format] +[Max column width] +[Time format] + +; ListCtrl +[File] +[Nick] +[UIN] + +; Buttons +[Auto filename] +[Clear all] +[Help] +[Export all history] + +; Errors / Questions +[You have unapplyed changes do you wish to apply these first ?] +[No contacts found to export] +[Failed to export at least one contact] +[Max line width must be at least %d] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Dialog Export all, Progress bar +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[Exporting old messages] +[Reading database information ( Phase 1 of 2 )] +[Sorting and writing database information ( Phase 2 of 2 )] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Folder Browse dialog +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[Select Destination Directory] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Strings written to export file +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[The following user added you to their contact list:] +[The following user made an authorization request:] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; General Error dialogs +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[Message has not been saved !] +[Failed to get the path to Msg_Export.dll\nPlease locate Msg_Export.txt your self] +[Failed to move to the end of the file :\n] +[Failed to open or create file :\n] + +;///////////////////// +;// Version 1.4.0 // +;///////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Strings written to export file +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[The following user added you to their contact list:] +[The following user made an authorization request:] +[Nick :] +[FirstName :] +[LastName :] +[e-mail :] +[Reason :] + +; Errors + +;///////////////////// +;// Version 1.4.1 // +;///////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; General Error dialogs +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[Failed to write message to the file :\n] +[Failed to write URL/File to the file :\n] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Strings written to export file +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[URL: ] +[File: ] +[Description: ] + + +;///////////////////// +;// Version 1.5.0 // +;///////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Strings written to export file +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[EmailExpress from:] +[No from address] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; General Error dialogs +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[Failed to write EmailExpress to the file :\n] + + +;///////////////////// +;// Version 1.6.0 // +;///////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; General Error dialogs +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[Failed to write SMS to the file :\n] + + + +;///////////////////// +;// Version 1.7.0 // +;///////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Main options dialog +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[Replace miranda history] +[Use internal viewer] +[You need to restart miranda to change the history function] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; File Viewer dialog +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[History file for %s (%s)] +[Find...] +[Close] +[External] + +[Search string was not found !] + +;///////////////////// +;// Version 1.8.0 // +;///////////////////// + +[File name for the user \"%s\" has changed !\n\nfrom:\t%s\nto:\t%s\n\nDo you wish to rename file ?] +[Failed to rename file\n\nfrom:\t%s\nto:\t%s\n\nFailed with error: %s] +[&Yes] +[Yes to &All] +[&No] +[No to A&ll] + +;///////////////////// +;// Version 1.9.0 // +;///////////////////// + +; File Viewer menu item +[Color...] + +;///////////////////// +;// Version 1.9.1 // +;///////////////////// + +; File Viewer menu item +[Font...] + + +;///////////////////// +;// Version 1.9.5 // +;///////////////////// + +; Errors / Questions +[Failed to delete the file] + + +;///////////////////// +;// Version 1.9.6 // +;///////////////////// + +Removed : [Failed to read ProfileDir from mirandaboot.ini] +Removed : [Failed to get path to Miranda.exe] + +;///////////////////// +;// Version 1.9.7 // +;///////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Main options dialog +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +[Prompt to delete file] + + +;///////////////////// +;// Version 1.9.8 // +;///////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; General Error dialogs +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +[Failed to replace Miranda History.\r\nThis is most likely due to changes in Miranda.] + + +;///////////////////// +;// Version 2.0.1 // +;///////////////////// + +Removed : [Unknowen event type %d, size %d] +Removed : [Invalid Database event received. Type %d, size %d] +Removed : [User has been deleted do you want to delete the file ?\r\n%s] +Removed : [Failed to HookEvent ME_DB_EVENT_ADDED] +Removed : [Failed to HookEvent ME_OPT_INITIALISE] +Removed : [Failed to HookEvent ME_SYSTEM_MODULESLOADED] +Removed : [Failed to add menu item Open Exported History\nCallService(MS_CLIST_ADDCONTACTMENUITEM,...)] +Removed : [Failed to CreateServiceFunction MS_SHOW_EXPORT_HISTORY] +Removed : [Failed to get the shells allocator !] +Removed : [Failed to Allocate buffer space] + +; Errors / Questions +[User has been deleted do you want to delete the file ?] + +;/////////////////////// +;// Version 2.03.00 // +;/////////////////////// + +; File Viewer menu item +[Syntax highlight] + + +;/////////////////////// +;// Version 2.04.00 // +;/////////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Main options dialog +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +[File viewer] +[Append extra new line] + + +;/////////////////////// +;// Version 2.05.00 // +;/////////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Strings written to export file +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +[WebPager from:] + +;/////////////////////// +;// Version 2.06.00 // +;/////////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Main options dialog +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; ListCtrl right click menu +[User &Details] +; These were not added in 2.06.00 but were forgotten in previous versions. +[Export selected] +[Set to default filename] + +;/////////////////////// +;// Version 2.09.00 // +;/////////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Main options dialog +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +[Use << and >>] + + +;/////////////////////// +;// Version 2.12.00 // +;/////////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Main options dialog +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +Removed : [User has been deleted do you want to delete the file ?] + +[When filename changes] +[When user is deleted] +[Prompt for action] +[Rename file] +[Do nothing] +[Delete file] + + +;/////////////////////// +;// Version 2.15.00 // +;/////////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Main options dialog +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +[Export Protocols] + + +;/////////////////////// +;// Version 3.00.00 // +;/////////////////////// + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Main options dialog +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +[Use UTF8 in new files] \ No newline at end of file diff --git a/plugins/Msg_Export/res/notick.ico b/plugins/Msg_Export/res/notick.ico new file mode 100755 index 0000000000..4ff17dfa7b Binary files /dev/null and b/plugins/Msg_Export/res/notick.ico differ diff --git a/plugins/Msg_Export/res/resource.rc b/plugins/Msg_Export/res/resource.rc new file mode 100755 index 0000000000..cb3a5fd4e0 --- /dev/null +++ b/plugins/Msg_Export/res/resource.rc @@ -0,0 +1,327 @@ +// Microsoft Visual C++ generated resource script. +// +#include "src/resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include +#include +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral (Default) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUD) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 3,1,0,3 + PRODUCTVERSION 3,1,0,3 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", "Message export plugin for Miranda IM (mod by ring0)" + VALUE "CompanyName", "Tip Top Tools" + VALUE "FileDescription", "Message export" + VALUE "FileVersion", "3, 1, 0, 3" + VALUE "InternalName", "Msg_export" + VALUE "LegalCopyright", "© 2002 Kennet Nielsen, mod by ring0" + VALUE "OriginalFilename", "Msg_Export" + VALUE "ProductName", "Message export (mod by ring0)" + VALUE "ProductVersion", "3, 1, 0, 3" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +#endif // Neutral (Default) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Danish resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DAN) +#ifdef _WIN32 +LANGUAGE LANG_DANISH, SUBLANG_DEFAULT +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + ID_EDIT_COPY "Copies the selection and puts it on the Clipboard\nCopy" +END + +#endif // Danish resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// German (Germany) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include \r\n" + "#include \0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // German (Germany) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPT_MSGEXPORT DIALOGEX 0, 0, 314, 240 +STYLE DS_SETFONT | DS_3DLOOK | DS_CENTER | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + COMBOBOX IDC_EXPORT_DIR,11,12,125,114,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Browse",IDC_EXPORT_DIR_BROWSE,141,11,43,14 + COMBOBOX IDC_DEFAULT_FILE,53,29,83,112,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + CONTROL "Use internal viewer",IDC_USE_INTERNAL_VIEWER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,61,76,10 + CONTROL "Replace miranda history",IDC_REPLACE_MIRANDA_HISTORY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,61,91,10 + COMBOBOX IDC_FILE_VIEWER,11,75,125,89,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Browse",IDC_FILE_VIEWER_BROWSE,141,74,43,14 + EDITTEXT IDC_MAX_CLOUMN_WIDTH,264,11,39,14,ES_AUTOHSCROLL | ES_NUMBER + COMBOBOX IDC_EXPORT_TIMEFORMAT,246,29,57,122,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + CONTROL "Use UTF8 in new files",IDC_USE_UTF8_IN_NEW_FILES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,46,85,10 + CONTROL "Append extra new line",IDC_APPEND_NEWLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,59,86,10 + CONTROL "Use << and >>",IDC_USE_LESS_AND_GREATER_IN_EXPORT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,72,63,10 + CONTROL "List1",IDC_MAP_USER_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_EDITLABELS | WS_BORDER | WS_TABSTOP,5,100,304,120 + PUSHBUTTON "Auto filename",IDC_AUTO_FILENAME,5,226,63,14 + PUSHBUTTON "Clear all",IDC_CLEAR_ALL,86,226,63,14 + PUSHBUTTON "Help",IDC_OPEN_HELP,161,226,63,14 + PUSHBUTTON "Export all history",IDC_EXPORTALL,242,226,63,14 + GROUPBOX "Export directory",IDC_STATIC,5,0,186,46 + LTEXT "Max column width",IDC_STATIC,201,14,58,8 + LTEXT "Time format",IDC_STATIC,201,31,38,8 + GROUPBOX "Export format",IDC_STATIC,195,0,114,94 + LTEXT "Default file",IDC_STATIC,11,32,34,8 + GROUPBOX "File viewer",IDC_STATIC,5,49,186,45 +END + +IDD_EXPORT_ALL_DLG DIALOGEX 0, 0, 252, 46 +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Exporting old messages" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "Progress1",IDC_EXPORT_PROGRESS,"msctls_progress32",WS_BORDER,7,7,238,15 + LTEXT "",IDC_EXP_ALL_STATUS,7,31,238,8 +END + +IDD_FILE_VIEWER DIALOG 0, 0, 346, 259 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "History file for %s (%s format %s)" +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "",IDC_RICHEDIT,"RICHEDIT",TCS_HOTTRACK | TCS_VERTICAL | TCS_BUTTONS | TCS_RAGGEDRIGHT | TCS_MULTISELECT | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,6,7,333,224 + PUSHBUTTON "&Find...",IDC_FV_FIND,46,238,50,14 + PUSHBUTTON "&External",IDC_FV_EXTERNAL,142,238,50,14 + DEFPUSHBUTTON "&Close",IDOK,246,238,50,14 +END + +IDD_OPT_MSGEXPORT2 DIALOGEX 0, 0, 314, 240 +STYLE DS_SETFONT | DS_3DLOOK | DS_CENTER | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + CONTROL "Prompt for action",IDC_FC_PROMPT,"Button",BS_AUTORADIOBUTTON | WS_GROUP,51,53,69,10 + GROUPBOX "When filename changes",IDC_STATIC,43,38,100,56 + CONTROL "Rename file",IDC_FC_RENAME,"Button",BS_AUTORADIOBUTTON,51,66,53,10 + CONTROL "Do nothing",IDC_FC_NOTHING,"Button",BS_AUTORADIOBUTTON,51,79,51,10 + GROUPBOX "When user is deleted",IDC_STATIC,171,39,100,56 + CONTROL "Prompt for action",IDC_FD_PROMPT,"Button",BS_AUTORADIOBUTTON | WS_GROUP,180,53,69,10 + CONTROL "Delete file",IDC_FD_DELETE,"Button",BS_AUTORADIOBUTTON,180,66,47,10 + CONTROL "Do nothing",IDC_FD_NOTHING,"Button",BS_AUTORADIOBUTTON,180,79,51,10 + CONTROL "List1",IDC_EXPORT_PROTOS,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_EDITLABELS | WS_BORDER | WS_TABSTOP,44,101,227,106 + PUSHBUTTON "Debug",IDC_DEBUG_INFO,237,214,32,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OPT_MSGEXPORT, DIALOG + BEGIN + RIGHTMARGIN, 313 + VERTGUIDE, 5 + VERTGUIDE, 11 + VERTGUIDE, 136 + VERTGUIDE, 141 + VERTGUIDE, 201 + VERTGUIDE, 303 + VERTGUIDE, 309 + HORZGUIDE, 18 + HORZGUIDE, 36 + HORZGUIDE, 46 + HORZGUIDE, 66 + END + + IDD_EXPORT_ALL_DLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 245 + TOPMARGIN, 7 + BOTTOMMARGIN, 39 + END + + IDD_FILE_VIEWER, DIALOG + BEGIN + LEFTMARGIN, 6 + RIGHTMARGIN, 339 + TOPMARGIN, 7 + BOTTOMMARGIN, 252 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_EXPORT_MESSAGE ICON "export_m.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MSG_EXPORT MENU +BEGIN + POPUP "UserList" + BEGIN + MENUITEM "User &Details", ID_USERLIST_USERDETAILS + MENUITEM "Export selected", ID_EXPORTSELECTED + MENUITEM "Set to default filename", ID_SET_TO_DEFAULT + MENUITEM SEPARATOR + MENUITEM "Auto filename", IDC_AUTO_FILENAME + MENUITEM "Clear all", IDC_CLEAR_ALL + END +END + +IDR_FV_EDIT MENU +BEGIN + POPUP "1" + BEGIN + MENUITEM "Copy", ID_EDIT_COPY + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.K.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_TICK ICON "tick.ico" +IDI_NOTICK ICON "notick.ico" +#endif // English (U.K.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/Msg_Export/res/tick.ico b/plugins/Msg_Export/res/tick.ico new file mode 100755 index 0000000000..d24d6adbbf Binary files /dev/null and b/plugins/Msg_Export/res/tick.ico differ diff --git a/plugins/Msg_Export/src/FileViewer.cpp b/plugins/Msg_Export/src/FileViewer.cpp new file mode 100755 index 0000000000..191f744571 --- /dev/null +++ b/plugins/Msg_Export/src/FileViewer.cpp @@ -0,0 +1,1424 @@ + +//This file is part of Msg_Export a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ ) +// +//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., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include + +#include +#include + +using namespace std; + + +#include "Utils.h" +#include "Glob.h" +#include "FileViewer.h" + +#include "resource.h" + +#include +#include + +//#include + +#define szFileViewDB "FileV_" + +#define WM_RELOAD_FILE (WM_USER+10) + +using namespace std; + +static UINT UM_FIND_CMD = RegisterWindowMessage( FINDMSGSTRING ); + +#define ID_FV_FONT 0x0010 +#define ID_FV_COLOR 0x0020 +#define ID_FV_SYNTAX_HL 0x0030 +#define ID_FV_SAVE_AS_RTF 0x0040 +// ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); +// ASSERT(IDM_ABOUTBOX < 0xF000); + + +// Specifies if history is opened internaly or externaly +bool bUseIntViewer = true; + +// External program used to view files +tstring sFileViewerPrg; + +// handle to the RichEditDll. We need to load this dll to use a RichEdit. +HMODULE hRichEditDll = NULL; + + +#define CONT(i) ((in[i]&0xc0) == 0x80) +#define VAL(i, s) ((in[i]&0x3f) << s) + +void swap(char &c1, char &c2) { + char ch; + ch=c1; + c1=c2; + c2=ch; +} + +int DecodeUTF8(const char *pcBuff,int /*iBufSize*/,char *pcOutBuf) { + int iBytesInOut=0; + int /*cp,*/i; + char ch,*p; + +//Parse UTF-8 sequence +//Support only chars up to three bytes (UCS-4 - go away!) +//Warning: Partial decoding is possible! + i=0; + ch=pcBuff[i]; + if(!(ch&0x80)) { + pcOutBuf[iBytesInOut++]=ch; + pcOutBuf[iBytesInOut++]='\0'; + } + else if(!(ch&0x20)) { + pcOutBuf[iBytesInOut++]=(ch>>2)&0x07; + i++; + pcOutBuf[iBytesInOut++]=(pcBuff[i]&0x3F)|(ch<<6); + swap(pcOutBuf[iBytesInOut-1],pcOutBuf[iBytesInOut-2]); + } + else if(!(ch&0x10)) { + i++; + + pcOutBuf[iBytesInOut++]=(ch<<4)|((pcBuff[i]>>2)&0x0F); + ch=pcBuff[i]; + i++; + pcOutBuf[iBytesInOut++]=(pcBuff[i]&0x3F)|(ch<<6); + swap(pcOutBuf[iBytesInOut-1],pcOutBuf[iBytesInOut-2]); + } + else { + p=(char*)&pcBuff[i]; + pcOutBuf[iBytesInOut++]='\x3F'; + pcOutBuf[iBytesInOut++]='\0'; + if(!(ch&0x08)) i+=3; + else if(!(ch&0x04)) i+=4; + else if(!(ch&0x02)) i+=5; + } + + i++; + + return i; +} + + +int __utf8_get_char(const char *in, int *chr) +{ /* 2-byte, 0x80-0x7ff */ + return DecodeUTF8(in,256,(char *)chr); +} + +// there is one instance of CLHistoryDlg for every history dialog on screeen. +class CLHistoryDlg +{ + public: + HWND hWnd; + + HANDLE hContact; + tstring sPath; + + WNDPROC wpOrigEditProc; + + HWND hFindDlg; + FINDREPLACE fr; + _TCHAR acFindStr[100]; + + bool bFirstLoad; + bool bUtf8File; + + CLHistoryDlg( HANDLE hContact ) : hContact( hContact ) + { + hFindDlg = NULL; + acFindStr[0] = 0; + ZeroMemory( &fr , sizeof( fr )); + fr.lStructSize = sizeof( fr ); + fr.hInstance = hInstance; + fr.Flags = FR_NOUPDOWN|FR_HIDEUPDOWN;//|FR_MATCHCASE|FR_WHOLEWORD; + // FR_DOWN|FR_FINDNEXT|FR_NOMATCHCASE; + fr.lpstrFindWhat = acFindStr; + fr.wFindWhatLen = sizeof(acFindStr); + bFirstLoad = true; + bUtf8File = false; + } +}; + +// List of all open history windows +list< CLHistoryDlg* > clHistoryDlgList; +// CRITICAL_SECTION used to access the window list +// this is nesery because UpdateFileViews is called from callback thread. +CRITICAL_SECTION csHistoryList; + + +// CLStreamRTFInfo is used when reading RTF into rich edit from a stream. +// RTF is used when Syntax highlighting is used. +class CLStreamRTFInfo +{ + private: + HANDLE hFile; + bool bHeaderWriten; + bool bTailWriten; + bool bCheckFirstForNick; + bool bLastColorMyNick; + + // buffer size supplyed on win XP 4092 byte when streamin in + // optimal size it to fully use this buffer but we can guess + // how may bytes need converting in the file we are reading. + BYTE abBuf[3300]; + char szMyNick[100]; + int nNickLen; + static int nOptimalReadLen; + + int nWriteHeader( char * pszTarget , int nLen ); + public: + bool bUtf8File; + CLStreamRTFInfo( HANDLE hFile ) + { + this->hFile = hFile; + bHeaderWriten = false; + bTailWriten = false; + bCheckFirstForNick = false; + bLastColorMyNick = false; + bUtf8File = false; + nNickLen = 0; + } + int nLoadFileStream( LPBYTE pbBuff , LONG cb ); +}; +int CLStreamRTFInfo::nOptimalReadLen = 3300; + +///////////////////////////////////////////////////////////////////// +// Member Function : nWriteHeader +// Type : Private / Public / Protected +// Parameters : pszTarget - ? +// nLen - ? +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 030204 , 04 February 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int CLStreamRTFInfo::nWriteHeader( char * pszTarget , int nLen ) +{ + COLORREF cMyText = DBGetContactSettingDword(NULL,"SRMsg","Font3Col",RGB(64,0,128)); + COLORREF cYourText = DBGetContactSettingDword(NULL,"SRMsg","Font0Col",RGB(240,0,0)); + +/* original header !! + "{\\rtf1\\ansi\\deff0{\\fonttbl{\\f0\\fnil\\fcharset0 Courier New;}}\r\n" + "{\\colortbl ;\\red%d\\green%d\\blue%d;\\red%d\\green%d\\blue%d;}\r\n" + "\\viewkind4\\uc1\\pard\\cf2\\lang1033\\f0\\fs16 " , + +*/ + char szRtfHeader[400]; + int nSrcLen = _snprintf( szRtfHeader , sizeof( szRtfHeader ) , + "{\\rtf1\\ansi\r\n" + "{\\colortbl ;\\red%d\\green%d\\blue%d;\\red%d\\green%d\\blue%d;}\r\n" + "\\viewkind4\\uc1\\pard\\cf2 " , + GetRValue( cMyText ) ,GetGValue( cMyText ) ,GetBValue( cMyText ) , + GetRValue( cYourText ) ,GetGValue( cYourText ) ,GetBValue( cYourText ) ); + + if( nSrcLen > nLen ) + { + MessageBox( NULL , _T("Failed to write to the RichEdit the buffer was to small."),MSG_BOX_TITEL,MB_OK ); + return 0; // target buffer to small + } + + memcpy( pszTarget , szRtfHeader , nSrcLen ); + bHeaderWriten = true; + return nSrcLen; +} + +const char szNewLine[] = "\n\\par "; +const char szRtfEnd[] = "\r\n\\par }\r\n\0"; + +///////////////////////////////////////////////////////////////////// +// Member Function : nLoadFileStream +// Type : Private / Public / Protected +// Parameters : pbBuff - ? +// cb - ? +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 030204 , 04 February 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int CLStreamRTFInfo::nLoadFileStream( LPBYTE pbBuff , LONG cb ) +{ + if( bTailWriten ) + return 0; + + if( nOptimalReadLen < 500 ) + { + MessageBox( NULL , _T("Error: Optimal buffer size decrecied to a to low size !!"),MSG_BOX_TITEL,MB_OK ); + return 0; + } + + DWORD dwRead; + DWORD dwToRead = nOptimalReadLen; + + if( ! ReadFile(hFile , abBuf, dwToRead , &dwRead, (LPOVERLAPPED)NULL) ) + return 0; + + DWORD dwCurrent = 0; + DWORD n = 0; + if( ! bHeaderWriten ) + { + if( dwRead >= 3 ) + { + bUtf8File = bIsUtf8Header( abBuf ); + if( bUtf8File ) + n = 3; + } + dwCurrent += nWriteHeader( (char*)pbBuff , cb ); + + tstring sMyNick = NickFromHandle(0); +#ifdef _UNICODE + nNickLen = WideCharToMultiByte(bUtf8File ? CP_UTF8 : CP_ACP , 0, sMyNick.c_str(), sMyNick.length() , szMyNick , sizeof( szMyNick ), NULL , NULL ); +#else + strcpy( szMyNick , sMyNick.c_str() ); + nNickLen = sMyNick.length(); +#endif + } + else + { + if( bCheckFirstForNick ) + { + // Test against "<<" also + if( ( (memcmp( abBuf , szMyNick , nNickLen ) == 0) || + (abBuf[0] == '<' && abBuf[1] == '<') + ) != bLastColorMyNick ) + { + // we shut only get here if we need to change color !! + bLastColorMyNick = !bLastColorMyNick; + // change color + memcpy( &pbBuff[dwCurrent] , bLastColorMyNick ? "\\cf1 " : "\\cf2 ", 5 ); + } + bCheckFirstForNick = false; + } + } + + bool bIsFileEnd = dwRead < dwToRead; + + for( ; n < dwRead ; n++ ) + { + // worst case is a file ending with \n or a unicode letter. resulting in a big unicode string + // here we need szNewLine and szRtfEnd. the 10 is a small safty margin. + if( dwCurrent + (sizeof( szNewLine ) + sizeof( szRtfEnd ) + 10 ) > (DWORD)cb ) + { + // oh no !!! we have almost reached the end of the windows supplyed buffer + // we are writing to. we need to abort mision *S*!! + // and rewinde file + // we will adjust the optima buffer size + nOptimalReadLen -= 50; + SetFilePointer( hFile , n - dwRead , NULL , FILE_CURRENT ); + return dwCurrent; + } + + if( abBuf[n] == '\n' ) + { + memcpy( &pbBuff[dwCurrent] , szNewLine , sizeof( szNewLine )-1 ); + dwCurrent += sizeof( szNewLine )-1; + + if( n + 1 >= dwRead ) + { + // this is an anoing case because here we have read \n as the last char in the file + // this means that the if the next data read from file begins with it has + // to be highlighted + if( !bIsFileEnd ) + bCheckFirstForNick = true; + break; + } + + if( abBuf[n+1] == ' ' || abBuf[n+1] == '\t' || abBuf[n+1] == '\r' ) + continue; + + if( n + nNickLen >= dwRead ) + { + if( !bIsFileEnd ) + { + // here we have a problem we haven't read this data yet + // the data we need to compare to is still in the file. + // we can't read more data from the file because the we + // might just move the problem. if file contains \n\n\n\n\n ... + + LONG lExtraRead = (n+1) - dwRead; + if( lExtraRead >= 0 ) + MessageBox( NULL , _T("Internal error !! (lExtraRead >= 0)"),MSG_BOX_TITEL,MB_OK ); + SetFilePointer( hFile , lExtraRead , NULL , FILE_CURRENT ); + bCheckFirstForNick = true; + return dwCurrent; + } + + if( ! bLastColorMyNick ) + continue; + // else the last color user was my nick + // we needd to change color to the other user color. + + + /* old code !! + DWORD dwAddedToBuf; + if( ! ReadFile(hFile , &abBuf[dwRead], dwNeeded , &dwAddedToBuf, (LPOVERLAPPED)NULL) ) + return 0; + dwToRead += dwNeeded; + dwRead += dwAddedToBuf;*/ + } + else + { + // the data we need is here just compare + if( ( ( memcmp( &abBuf[n+1] , szMyNick , nNickLen ) == 0) || + ( abBuf[n+1] == '<' && abBuf[n+2] == '<') + ) == bLastColorMyNick ) + continue; + } + // we shut only get here if we need to change color !! + bLastColorMyNick = !bLastColorMyNick; + + // change color + memcpy( &pbBuff[dwCurrent] , bLastColorMyNick ? "\\cf1 " : "\\cf2 ", 5 ); + dwCurrent += 5; + continue; + } + else if( abBuf[n] == '\\' || abBuf[n] == '}' || abBuf[n] == '{') + { + pbBuff[dwCurrent++]='\\'; + } + else if( bUtf8File && (abBuf[n] & 0x80) ) + { + int nValue; + int nLen = __utf8_get_char( (const char *)&abBuf[n] , &nValue ); + if(nLen+n>dwRead) { + SetFilePointer(hFile,n-dwRead,NULL,FILE_CURRENT); + break; + } + dwCurrent += sprintf( (char*)&pbBuff[dwCurrent] , "\\u%d?" , nValue ); + //continue; +/* // Then we have an extended char in the UTF8 file. + // we need to convert this to UCS-2 and then to \uN in the RTF + int nUtf8Len = 1; + while( ( (n + nUtf8Len) < dwRead ) && ((abBuf[ n + nUtf8Len ] & 0xC0) == 0x80) ) + nUtf8Len++; + wchar_t szWstr[2]; + if( MultiByteToWideChar( CP_UTF8 , 0 , (char*)&abBuf[n] , nUtf8Len , szWstr , 2 ) == 1 ) + { + if( (int)(szWstr[0]) != nValue ) + __utf8_get_char( (const char *)&abBuf[n] , &nValue ); + +// dwCurrent += sprintf( (char*)&pbBuff[dwCurrent] , "\\u%d?" , (int)(szWstr[0]) ); +// n += nUtf8Len - 1; +// continue; + }*/ + n += nLen-1; + continue; + } + pbBuff[dwCurrent++] = abBuf[n]; + } + + if( bIsFileEnd ) + {// write end + memcpy( &pbBuff[dwCurrent] , szRtfEnd , sizeof( szRtfEnd )-1 ); + dwCurrent += sizeof( szRtfEnd )-1; + bTailWriten = true; + } + //memcpy( pbBuff , abBuf , dwRead ); + return dwCurrent; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : Initilize +// Type : Global +// Parameters : None +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 021213 , 13 December 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void Initilize() +{ + InitializeCriticalSection( &csHistoryList ); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : Uninitilize +// Type : Global +// Parameters : None +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 021213 , 13 December 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void Uninitilize() +{ + DeleteCriticalSection( &csHistoryList ); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : UpdateFileViews +// Type : Global +// Parameters : pszFile - File which has been updated +// Returns : void +// Description : Send a message to alle to windows that need updating +// +// References : - +// Remarks : - +// Created : 021213 , 13 December 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void UpdateFileViews( const _TCHAR * pszFile ) +{ + EnterCriticalSection( &csHistoryList ); + + list< CLHistoryDlg* >::const_iterator iterator; + for( iterator = clHistoryDlgList.begin() ; iterator != clHistoryDlgList.end() ; ++iterator ) + { + CLHistoryDlg* pcl = (*iterator); + if( pcl->sPath == pszFile ) + { + PostMessage( pcl->hWnd , WM_RELOAD_FILE , 0 , 0 ); + } + } + LeaveCriticalSection( &csHistoryList ); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bOpenExternaly +// Type : Global +// Parameters : hContact - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 021010 , 10 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bOpenExternaly( HANDLE hContact ) +{ + tstring sPath = GetFilePathFromUser( hContact ); + + if( sFileViewerPrg.empty() ) + { + SHELLEXECUTEINFO st = {0}; + st.cbSize = sizeof(st); + st.fMask = SEE_MASK_INVOKEIDLIST; + st.hwnd = NULL; + st.lpFile = sPath.c_str(); + st.nShow = SW_SHOWDEFAULT; + ShellExecuteEx(&st); + return true; + } + tstring sTmp = sFileViewerPrg; + sTmp += _T(" "); + sTmp += sPath; + //sTmp += '\"'; + + STARTUPINFO sStartupInfo = { 0 }; + GetStartupInfo(&sStartupInfo); // we parse oure owne info on + sStartupInfo.lpTitle = (_TCHAR*)sFileViewerPrg.c_str(); + PROCESS_INFORMATION stProcesses = {0}; + + if( ! CreateProcess( NULL, + (_TCHAR*)sTmp.c_str(), + NULL, + NULL, + FALSE, + CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP , + NULL, + NULL, + &sStartupInfo, + &stProcesses ) ) + { + DisplayLastError( _T("Faile to execute external file view") ); + } + return true; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : bGetInternalViewer +// Type : Global +// Parameters : None +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 021016 , 16 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bUseInternalViewer() +{ + return bUseIntViewer; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bUseInternalViewer +// Type : Global +// Parameters : bNew - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 021016 , 16 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bUseInternalViewer( bool bNew ) +{ + bUseIntViewer = bNew; + if( bUseIntViewer && !hRichEditDll ) + { + hRichEditDll = LoadLibraryA("RICHED32.DLL"); + if( !hRichEditDll ) + { + DisplayLastError( _T("Failed to load Rich Edit ( RICHED32.DLL )" )); + return false; + } + } + else if( !bUseIntViewer && hRichEditDll ) + { + if( ::FreeLibrary(hRichEditDll) == 0 ) + { + DisplayLastError( _T("Failed to unload Rich Edit ( RICHED32.DLL )") ); + hRichEditDll = NULL; + return false; + } + hRichEditDll = NULL; + } + return true; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : RichEditStreamLoadFile +// Type : Global +// Parameters : dwCookie - ? +// pbBuff - ? +// cb - ? +// pcb - ? +// Returns : DWORD CALLBACK +// Description : +// +// References : - +// Remarks : - +// Created : 021010 , 10 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +DWORD CALLBACK RichEditStreamLoadFile(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) +{ + ReadFile((HANDLE)dwCookie, pbBuff, (DWORD)cb, (DWORD *)pcb, (LPOVERLAPPED)NULL); + return (DWORD) ( *pcb >= 0 ? NOERROR : ( *pcb = 0, E_FAIL ) ); +} + +DWORD CALLBACK RichEditRTFStreamLoadFile(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) +{ + *pcb = ((CLStreamRTFInfo *)dwCookie)->nLoadFileStream( pbBuff, cb ); + if( *pcb ) + return NOERROR; + return (DWORD)E_FAIL; +} + +DWORD CALLBACK RichEditStreamSaveFile(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) +{ + WriteFile((HANDLE)dwCookie, pbBuff, cb , (DWORD*)pcb, (LPOVERLAPPED)NULL); + return *pcb != cb; +} + +/* +DWORD dwCurPos = 0; +DWORD dwDataRead = 0; +BYTE * pabFileData = NULL; + +DWORD CALLBACK RichEditStreamLoadFile(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) +{ + *pcb = 0; + while( dwCurPos < dwDataRead && *pcb < cb ) + { + pbBuff[ *pcb ] = pabFileData[ dwCurPos ]; + dwCurPos++; + (*pcb)++; + } + return (DWORD) ( *pcb >= 0 ? NOERROR : ( *pcb = 0, E_FAIL ) ); +} +*/ +///////////////////////////////////////////////////////////////////// +// Member Function : bLoadFile +// Type : Global +// Parameters : hwndDlg - ? +// hContact - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 021010 , 10 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bLoadFile( HWND hwndDlg , CLHistoryDlg * pclDlg ) +{ + DWORD dwStart = GetTickCount(); + + HWND hRichEdit = GetDlgItem( hwndDlg , IDC_RICHEDIT ); + if( ! hRichEdit ) + { + MessageBox( hwndDlg , _T("Failed to get handle to RichEdit!"),MSG_BOX_TITEL,MB_OK ); + return false; + } + + + HANDLE hFile = CreateFile( pclDlg->sPath.c_str() , GENERIC_READ , + FILE_SHARE_READ | FILE_SHARE_WRITE , NULL , + OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL ); + + + if( hFile == INVALID_HANDLE_VALUE ) + { + int nDBCount = CallService( MS_DB_EVENT_GETCOUNT , (WPARAM)(pclDlg->hContact) ,0 ); + _TCHAR szTmp[1500]; + + if( nDBCount == -1 ) + { + mir_sntprintf(szTmp, 1499, _T("Failed to open file\r\n%s\r\n\r\nContact handle is invalid") , pclDlg->sPath.c_str()); + } + else + { + mir_sntprintf( szTmp , 1499, _T("Failed to open file\r\n%s\r\n\r\nMiranda database contains %d events") , pclDlg->sPath.c_str() , nDBCount ); + } + + SETTEXTEX stText = {0}; + stText.codepage = CP_ACP; + SendMessage( hRichEdit , EM_SETTEXTEX, (WPARAM) &stText, (LPARAM) szTmp ); + return false; + } + + POINT ptOldPos; + SendMessage( hRichEdit , EM_GETSCROLLPOS , 0 , (LPARAM) &ptOldPos ); + + bool bScrollToBottom = true; + if( pclDlg->bFirstLoad ) + pclDlg->bFirstLoad = false; + else + { + SCROLLINFO sScrollInfo = { 0 }; + sScrollInfo.cbSize = sizeof( SCROLLINFO ); + sScrollInfo.fMask = SIF_POS | SIF_RANGE | SIF_PAGE; + if( GetScrollInfo( hRichEdit,SB_VERT,&sScrollInfo) ) + bScrollToBottom = sScrollInfo.nPos + (int)sScrollInfo.nPage + 50 > sScrollInfo.nMax; + } + + + HMENU hSysMenu = GetSystemMenu( hwndDlg , FALSE ); + bool bUseSyntaxHL = (GetMenuState( hSysMenu , ID_FV_SYNTAX_HL , MF_BYCOMMAND ) & MF_CHECKED)!=0; + +/* + DWORD dwSize = GetFileSize( hFile , NULL ); + dwCurPos = 0; + pabFileData = new BYTE[ dwSize ]; + ReadFile( hFile , pabFileData, dwSize , &dwDataRead, (LPOVERLAPPED)NULL); +*/ + + + // SendMessage( hRichEdit , EM_SETBKGNDCOLOR, 0 , RGB( 0 , 0 , 128 ) ); + // SendMessage( hRichEdit , EM_SETTEXTMODE, TM_RICHTEXT ,0); + + // DWORD dw = SendMessage( hRichEdit , EM_GETLIMITTEXT, NULL, NULL); + + EDITSTREAM eds; + eds.dwError = 0; + + if( bUseSyntaxHL ) + { + SendMessage( hRichEdit , // handle to destination window + EM_EXLIMITTEXT, // message to send + 0, // not used; must be zero + 0x7FFFFFFF ); + + CLStreamRTFInfo clInfo( hFile ); + eds.dwCookie = (DWORD)&clInfo; + eds.pfnCallback = RichEditRTFStreamLoadFile; + + SendMessage(hRichEdit, EM_STREAMIN, (WPARAM)SF_RTF , (LPARAM)&eds); + pclDlg->bUtf8File = clInfo.bUtf8File; + } + else + { + eds.dwCookie = (DWORD )hFile; + eds.pfnCallback = RichEditStreamLoadFile; + + SendMessage(hRichEdit, EM_STREAMIN, (WPARAM)SF_TEXT , (LPARAM)&eds); + } + + CloseHandle( hFile ); + //delete [] pabFileData; + + _TCHAR szTmp[100]; + mir_sntprintf( szTmp , 99, _T("File open time %d\n") , GetTickCount() - dwStart ); + OutputDebugString( szTmp ); + + + GETTEXTLENGTHEX sData = { 0 }; + sData.flags = GTL_NUMCHARS; + sData.flags = GTL_DEFAULT; + + DWORD dwDataRead = SendMessage( hRichEdit , EM_GETTEXTLENGTHEX, (WPARAM)&sData , 0 ); + SendMessage( hRichEdit , EM_SETSEL , dwDataRead - 1, dwDataRead - 1 ); + + if( ! bScrollToBottom ) + SendMessage( hRichEdit , EM_SETSCROLLPOS , 0 , (LPARAM) &ptOldPos ); + + mir_sntprintf( szTmp , 99, _T("With scroll to bottom %d\n") , GetTickCount() - dwStart ); + OutputDebugString( szTmp ); + + return true; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bAdvancedCopy +// Type : Global +// Parameters : hwnd - handle to RichEdit control +// Returns : Returns true if text was copied to the clipboard +// Description : +// +// References : - +// Remarks : - +// Created : 030730 , 30 juli 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bAdvancedCopy(HWND hwnd) +{ + CHARRANGE sSelectRange; + SendMessage( hwnd, EM_EXGETSEL, 0 , (LPARAM)&sSelectRange ); + int nSelLenght = sSelectRange.cpMax - sSelectRange.cpMin + 1; // +1 for null termination + if( nSelLenght > 1 ) + { + OpenClipboard(NULL); + EmptyClipboard(); + + _TCHAR * pszSrcBuf = new _TCHAR[ nSelLenght]; + pszSrcBuf[0] = 0; + SendMessage( hwnd, EM_GETSELTEXT, 0 , (LPARAM)pszSrcBuf ); + + HANDLE hDecMem = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, nSelLenght ); + _TCHAR * pszCurDec = (_TCHAR*)GlobalLock(hDecMem); + + bool bInSpaces = false; + for( _TCHAR * pszCur = pszSrcBuf ; pszCur[0] ; pszCur++ ) + { + if( bInSpaces ) + { + if( pszCur[0] == ' ' ) + continue; + bInSpaces = false; + } + + if( pszCur[0] == '\n' ) + { + bInSpaces = true; + } + pszCurDec[0] = pszCur[0]; + pszCurDec++; + } + pszCurDec[0] = 0; + GlobalUnlock(hDecMem); + + SetClipboardData(CF_TEXT,hDecMem); + delete [] pszSrcBuf; + CloseClipboard(); + return true; + } + return false; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : EditSubclassProc +// Type : Global +// Parameters : hwnd - ? +// uMsg - ? +// wParam - ? +// lParam - ? +// Returns : LRESULT CALLBACK +// Description : +// +// References : - +// Remarks : - +// Created : 021013 , 13 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +LRESULT CALLBACK EditSubclassProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CLHistoryDlg * pclDlg = (CLHistoryDlg *)GetWindowLong(hwnd,GWL_USERDATA); + + switch( msg ) + { + case WM_CONTEXTMENU: + { + HMENU nMenu = LoadMenu( hInstance, MAKEINTRESOURCE( IDR_FV_EDIT ) ); + HMENU nSubMenu = GetSubMenu( nMenu , 0 ); + POINT pt; + pt.x=(short)LOWORD(lParam); + pt.y=(short)HIWORD(lParam); + + if(pt.x==-1 && pt.y==-1) + { + DWORD dwStart,dwEnd; + SendMessage( hwnd , EM_GETSEL , (WPARAM)&dwStart, (LPARAM)&dwEnd ); + SendMessage( hwnd , EM_POSFROMCHAR, (WPARAM)&pt, (LPARAM)dwEnd); + ClientToScreen( hwnd , &pt ); + } + TrackPopupMenu( nSubMenu , TPM_RIGHTBUTTON , pt.x , pt.y , 0 , hwnd , 0 ); + + DestroyMenu( nSubMenu ); + DestroyMenu( nMenu ); + return TRUE; + } + case WM_GETDLGCODE: + { + return DLGC_WANTARROWS; + } + case WM_COPY: + { // not working for "CTRL + C" + if( bAdvancedCopy( hwnd ) ) + return TRUE; + break; + } + case WM_KEYDOWN: + { + if( (wParam == VK_INSERT || wParam == 'C') && (GetKeyState(VK_CONTROL) & 0x80) ) + { + if( bAdvancedCopy( hwnd ) ) + return TRUE; + } + break; + } + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case ID_EDIT_COPY: + { + SendMessage( hwnd , WM_COPY, 0, 0 ); + return TRUE; + } + } + } + } + if( msg == UM_FIND_CMD ) + { + FINDREPLACE *fr = (FINDREPLACE *)lParam; + if( fr->Flags & FR_DIALOGTERM ) + { + pclDlg->hFindDlg = NULL; + return 0; + } + + FINDTEXT ft = { 0 }; + + if( fr->Flags & FR_FINDNEXT) + { + ft.lpstrText = fr->lpstrFindWhat; + + SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&ft.chrg); + ft.chrg.cpMin = ft.chrg.cpMax+1; + ft.chrg.cpMax = -1; + int res = SendMessage(hwnd, EM_FINDTEXT, (WPARAM)fr->Flags,(LPARAM)&ft); + if(res == -1) + { + ft.chrg.cpMin = 0; + res = SendMessage(hwnd, EM_FINDTEXT, (WPARAM)fr->Flags,(LPARAM)&ft); + if(res == -1) + { + MessageBox( hwnd , TranslateTS(_T("Search string was not found !")),MSG_BOX_TITEL,MB_OK ); + return 0; + } + } + ft.chrg.cpMin = res; + ft.chrg.cpMax = res + _tcslen(fr->lpstrFindWhat); + SendMessage(hwnd , EM_EXSETSEL, 0, (LPARAM)&ft.chrg); + return 0; + } + + } + return CallWindowProc(pclDlg->wpOrigEditProc, hwnd, msg, wParam, lParam); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : SetWindowsCtrls +// Type : Global +// Parameters : hwndDlg - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 021001 , 01 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void SetWindowsCtrls( HWND hwndDlg ) +{ + RECT rNewSize; + GetClientRect( hwndDlg , &rNewSize ); + + RECT rCurSize; + + const int nSpacing = 12; + + + HWND hButton = GetDlgItem( hwndDlg , IDOK ); + GetWindowRect( hButton , &rCurSize ); + int nButtonHeight = rCurSize.bottom - rCurSize.top; + + SetWindowPos( GetDlgItem( hwndDlg , IDC_RICHEDIT ) , 0 , + nSpacing , nSpacing , + rNewSize.right - (nSpacing * 2) , + rNewSize.bottom - ( nSpacing * 3 + nButtonHeight ), + SWP_NOZORDER ); + + + int nButtonWidth = rCurSize.right - rCurSize.left; + int nButtonSpace = (rNewSize.right - ( 3 * nButtonWidth )) / 4; + int nButtonTop = rNewSize.bottom - ( nSpacing + nButtonHeight ); + int nCurLeft = nButtonSpace; + + SetWindowPos( GetDlgItem( hwndDlg , IDC_FV_FIND ) , 0 , + nCurLeft , nButtonTop , 0 , 0 , SWP_NOZORDER | SWP_NOSIZE ); + + nCurLeft += nButtonSpace + nButtonWidth; + + SetWindowPos( GetDlgItem( hwndDlg , IDC_FV_EXTERNAL ) , 0 , + nCurLeft , nButtonTop , 0 , 0 , SWP_NOZORDER | SWP_NOSIZE ); + + nCurLeft += nButtonSpace + nButtonWidth; + + SetWindowPos( hButton , 0 , + nCurLeft , nButtonTop , 0 , 0 , SWP_NOZORDER | SWP_NOSIZE ); + +} + +///////////////////////////////////////////////////////////////////// +// Member Function : SetRichEditFont +// Type : Global +// Parameters : hRichEdit - RichEdit to set the font in +// bUseSyntaxHL - Is Syntax hilighting is used the color +// will not be set +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 030205 , 05 February 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void SetRichEditFont(HWND hRichEdit, bool bUseSyntaxHL ) +{ + CHARFORMAT ncf = { 0 }; + ncf.cbSize = sizeof( CHARFORMAT ); + ncf.dwMask = CFM_BOLD | CFM_FACE | CFM_ITALIC | CFM_SIZE | CFM_UNDERLINE; + ncf.dwEffects = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "TEffects" , 0 ); + ncf.yHeight = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "THeight" , 165 ); + _tcscpy( ncf.szFaceName , _DBGetString( NULL , MODULE , szFileViewDB "TFace" , _T("Courier New")).c_str() ); + + if( ! bUseSyntaxHL ) + { + ncf.dwMask |= CFM_COLOR; + ncf.crTextColor = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "TColor" , 0 ); + } + SendMessage(hRichEdit, EM_SETCHARFORMAT, (WPARAM)SCF_ALL, (LPARAM)&ncf); + +} + +///////////////////////////////////////////////////////////////////// +// Member Function : DlgProcFileViewer +// Type : Global +// Parameters : hwndDlg - ? +// msg - ? +// wParam - ? +// lParam - ? +// Returns : static BOOL CALLBACK +// Description : +// +// References : - +// Remarks : - +// Created : 020929 , 29 September 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +static BOOL CALLBACK DlgProcFileViewer(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + CLHistoryDlg * pclDlg = (CLHistoryDlg *)GetWindowLong(hwndDlg,GWL_USERDATA); + + switch (msg) + { + case WM_INITDIALOG: + { + SetWindowLong(hwndDlg,GWL_USERDATA,lParam); + CLHistoryDlg * pclDlg = (CLHistoryDlg *)lParam; +#ifdef _UNICODE + EnableWindow( GetDlgItem( hwndDlg , IDC_FV_FIND ) , FALSE ); +#endif + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, + (LPARAM)LoadIcon( hInstance, MAKEINTRESOURCE(IDI_EXPORT_MESSAGE))); + + HWND hRichEdit = GetDlgItem( hwndDlg , IDC_RICHEDIT ); + pclDlg->wpOrigEditProc = (WNDPROC) SetWindowLongPtr( hRichEdit, GWL_WNDPROC, (LONG) EditSubclassProc); + + SetWindowLongPtr( hRichEdit, GWLP_USERDATA, (LONG) pclDlg ); + + SendMessage( hRichEdit , EM_SETEVENTMASK , 0 , ENM_LINK); + SendMessage( hRichEdit , EM_AUTOURLDETECT , TRUE , 0 ); + + HMENU hSysMenu = GetSystemMenu( hwndDlg , FALSE ); + + InsertMenu( hSysMenu , 0 , MF_SEPARATOR | MF_BYPOSITION , 0 , 0 ); + InsertMenu( hSysMenu , 0 , MF_STRING | MF_BYPOSITION , ID_FV_SAVE_AS_RTF, TranslateTS(_T("Save as RTF")) ); + + InsertMenu( hSysMenu , 0 , MF_SEPARATOR | MF_BYPOSITION , 0 , 0 ); + + BYTE bUseCC = (BYTE)DBGetContactSettingByte( NULL , MODULE , szFileViewDB "UseCC" , 0 ); + InsertMenu( hSysMenu , 0 , MF_STRING | MF_BYPOSITION | ( bUseCC ? MF_CHECKED : 0 ) , ID_FV_COLOR, TranslateTS(_T("Color...")) ); + + if( bUseCC ) + { + SendMessage( hRichEdit , EM_SETBKGNDCOLOR, 0 , + DBGetContactSettingDword( NULL , MODULE , szFileViewDB "CustomC" , RGB(255,255,255) ) + ); + } + + InsertMenu( hSysMenu , 0 , MF_STRING | MF_BYPOSITION , ID_FV_FONT, TranslateTS(_T("Font...")) ); + + + bool bUseSyntaxHL = DBGetContactSettingByte( NULL , MODULE , szFileViewDB "UseSyntaxHL" , 1 )!=0; + InsertMenu( hSysMenu , 0 , MF_STRING | MF_BYPOSITION | ( bUseSyntaxHL ? MF_CHECKED : 0 ) , ID_FV_SYNTAX_HL, TranslateTS(_T("Syntax highlight")) ); + + SetRichEditFont( hRichEdit , bUseSyntaxHL ); + + TranslateDialogDefault(hwndDlg); + + int cx= DBGetContactSettingDword( NULL , MODULE , szFileViewDB "cx" , 0 ); + int cy= DBGetContactSettingDword( NULL , MODULE , szFileViewDB "cy" , 0 ); + + if( cx > 0 && cy > 0) + { + int x = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "x" , 0 ); + int y = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "y" , 0 ); + + SetWindowPos( hwndDlg , NULL , x , y , cx , cy , SWP_NOZORDER ); + } + + pclDlg->sPath = GetFilePathFromUser( pclDlg->hContact ); + + SetWindowsCtrls( hwndDlg ); + + + bLoadFile(hwndDlg , pclDlg ); + + { // set Title + _TCHAR szFormat[200]; + _TCHAR szTitle[200]; + if( GetWindowText( hwndDlg , szFormat , sizeof( szFormat ) ) ) + { + const _TCHAR * pszNick = NickFromHandle( pclDlg->hContact ); + tstring sPath = pclDlg->sPath; + string::size_type n = sPath.find_last_of( '\\' ); + if( n != sPath.npos ) + sPath.erase( 0 , n + 1 ); + + if( _sntprintf( szTitle , sizeof( szTitle ) , szFormat , pszNick , sPath.c_str() , (pclDlg->bUtf8File ? _T("UTF8"):_T("ANSI")) ) > 0 ) + { + SetWindowText( hwndDlg , szTitle); + } + } + } + + return TRUE; + } + case WM_RELOAD_FILE: + { + bLoadFile(hwndDlg , pclDlg ); + return TRUE; + } + case WM_SIZE: + case WM_SIZING: + { + SetWindowsCtrls( hwndDlg ); + return TRUE; + } + case WM_NCDESTROY: + { + EnterCriticalSection( &csHistoryList ); + clHistoryDlgList.remove( pclDlg ); + LeaveCriticalSection( &csHistoryList ); + + delete pclDlg; + SetWindowLong(hwndDlg,GWL_USERDATA,NULL); + return 0; + } + case WM_DESTROY: + { + RECT rSize; + if( GetWindowRect( hwndDlg , &rSize ) ) + { + // first we make sure the window has resonable dimentions. + // if it is minimized it will not have that. + if( rSize.left <= -32000 || rSize.top <= -32000 ) + return 0; + if( rSize.right <= -32000 || rSize.bottom <= -32000 ) + return 0; + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "x" , rSize.left ); + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "y" , rSize.top ); + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "cx" , rSize.right - rSize.left ); + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "cy" , rSize.bottom - rSize.top ); + } + return 0; + } + case WM_SYSCOMMAND: + { + HMENU hSysMenu = GetSystemMenu( hwndDlg , FALSE ); + bool bUseSyntaxHL = (GetMenuState( hSysMenu , ID_FV_SYNTAX_HL , MF_BYCOMMAND ) & MF_CHECKED)!=0; + HWND hRichEdit = GetDlgItem( hwndDlg , IDC_RICHEDIT ); + + if ((wParam & 0xFFF0) == ID_FV_FONT) + { + LOGFONT lf = { 0 }; + lf.lfHeight = 14L; + + { DWORD dwEffects = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "TEffects" , 0 ); + lf.lfWeight = (dwEffects & CFE_BOLD) ? FW_BOLD : 0; + lf.lfUnderline = (dwEffects & CFE_UNDERLINE) != 0; + lf.lfStrikeOut = (dwEffects & CFE_STRIKEOUT) != 0; + lf.lfItalic = (dwEffects & CFE_ITALIC) != 0; + } + _tcscpy(lf.lfFaceName, _DBGetString( NULL , MODULE , szFileViewDB "TFace" , _T("Courier New")).c_str()); + CHOOSEFONT cf = { 0 }; + cf.lStructSize = sizeof( cf ); + cf.hwndOwner = hwndDlg; + cf.lpLogFont = &lf; + cf.rgbColors = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "TColor" , 0 ); + cf.Flags = CF_EFFECTS | CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT; + + if( ChooseFont( &cf ) ) + { + DWORD dwEffects = (lf.lfWeight == FW_BOLD ? CFE_BOLD : 0) | + (lf.lfItalic ? CFE_ITALIC : 0) | + (lf.lfStrikeOut ? CFE_STRIKEOUT : 0) | + (lf.lfUnderline ? CFE_UNDERLINE : 0); + + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "TEffects" , dwEffects ); + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "THeight" , cf.iPointSize * 2 ); + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "TColor" , cf.rgbColors ); + DBWriteContactSettingTString( NULL , MODULE , szFileViewDB "TFace" , lf.lfFaceName ); + SetRichEditFont( hRichEdit , bUseSyntaxHL ); + } + return TRUE; + } + else if ((wParam & 0xFFF0) == ID_FV_COLOR) + { + BYTE bUseCC = ! DBGetContactSettingByte( NULL , MODULE , szFileViewDB "UseCC" , 0 ); + if( bUseCC ) + { + CHOOSECOLOR cc = {0}; + cc.lStructSize = sizeof( cc ); + cc.hwndOwner = hwndDlg; + cc.rgbResult = DBGetContactSettingDword( NULL , MODULE , szFileViewDB "CustomC" , RGB(255,255,255) ); + cc.Flags = CC_ANYCOLOR | CC_FULLOPEN | CC_RGBINIT; + static COLORREF MyCustColors[16] = { 0xFFFFFFFF }; + cc.lpCustColors = MyCustColors; + if( ChooseColor( &cc ) ) + { + SendMessage( hRichEdit , EM_SETBKGNDCOLOR, 0 , cc.rgbResult ); + DBWriteContactSettingDword( NULL , MODULE , szFileViewDB "CustomC" , cc.rgbResult ); + } + else + { + /*DWORD dwError =*/ CommDlgExtendedError(); + return TRUE; + } + } + else + { + SendMessage( hRichEdit , EM_SETBKGNDCOLOR, TRUE , 0 ); + } + CheckMenuItem( hSysMenu , ID_FV_COLOR , MF_BYCOMMAND | (bUseCC ? MF_CHECKED : 0) ); + DBWriteContactSettingByte( NULL , MODULE , szFileViewDB "UseCC" , bUseCC ); + return TRUE; + } + else if ((wParam & 0xFFF0) == ID_FV_SYNTAX_HL) + { + // we use the current state from the menu not the DB value + // because we want to toggel the option for this window + // still the new option selected will be stored. + // so user may open 2 windows, now he can set SyntaxHL in both. + + bUseSyntaxHL = !bUseSyntaxHL; + CheckMenuItem( hSysMenu , ID_FV_SYNTAX_HL , MF_BYCOMMAND | (bUseSyntaxHL ? MF_CHECKED : 0) ); + DBWriteContactSettingByte( NULL , MODULE , szFileViewDB "UseSyntaxHL" , bUseSyntaxHL ); + + if( bUseSyntaxHL ) + bLoadFile(hwndDlg , pclDlg ); + else + SetRichEditFont( hRichEdit , bUseSyntaxHL ); + + return TRUE; + } + else if ((wParam & 0xFFF0) == ID_FV_SAVE_AS_RTF) + { + tstring sFile = pclDlg->sPath; + sFile += _T(".rtf"); + HANDLE hFile = CreateFile( sFile.c_str() , GENERIC_WRITE , + FILE_SHARE_READ , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ); + + if( hFile == INVALID_HANDLE_VALUE ) + { + DisplayLastError( _T("Failed to create file") ); + return TRUE; + } + + EDITSTREAM eds; + eds.dwCookie = (DWORD )hFile; + eds.dwError = 0; + eds.pfnCallback = RichEditStreamSaveFile; + int nWriteOk = SendMessage(hRichEdit, EM_STREAMOUT, (WPARAM)SF_RTF , (LPARAM)&eds); + if( nWriteOk <= 0 || eds.dwError != 0 ) + { + DisplayLastError( _T("Failed to save file") ); + CloseHandle( hFile ); + return TRUE; + } + CloseHandle( hFile ); + tstring sReport = _T("History was saved successfully in file\r\n"); + sReport += sFile; + MessageBox( NULL , sReport.c_str() ,MSG_BOX_TITEL ,MB_OK ); + return TRUE; + } + return FALSE; + } + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDCANCEL: + case IDOK: + DestroyWindow(hwndDlg); + return TRUE; + case IDC_FV_EXTERNAL: + bOpenExternaly( pclDlg->hContact ); + return TRUE; + case IDC_FV_FIND: + { + if( pclDlg->hFindDlg ) + { + BringWindowToTop( pclDlg->hFindDlg ); + return TRUE; + } + pclDlg->fr.hwndOwner = GetDlgItem( hwndDlg , IDC_RICHEDIT ); + pclDlg->hFindDlg = FindText( &pclDlg->fr ); + return TRUE; + } + } + break; + } + case WM_NOTIFY: + { + if( ((NMHDR*)lParam)->idFrom == IDC_RICHEDIT ) + { + if( ((NMHDR*)lParam)->code == EN_LINK ) + { + ENLINK* pstLink = (ENLINK*)lParam; + if( pstLink->msg == WM_LBUTTONUP ) + { + _TCHAR szUrl[ 500 ]; + if( (pstLink->chrg.cpMax - pstLink->chrg.cpMin) > (sizeof( szUrl ) - 2) ) + return FALSE; + + TEXTRANGE stToGet; + stToGet.chrg = pstLink->chrg; + stToGet.lpstrText = szUrl; + if( SendMessage( pstLink->nmhdr.hwndFrom , EM_GETTEXTRANGE , 0 , (LPARAM)&stToGet ) > 0 ) + { + CallService(MS_UTILS_OPENURL,1,(LPARAM)szUrl); + } + return TRUE; + } + } + } + break; + } + case WM_CLOSE: + { + DestroyWindow(hwndDlg); + return TRUE; + } + } + return FALSE; +//FALSE;//DefWindowProc( hwndDlg, msg, wParam, lParam ); +//DefDlgProc( hwndDlg, msg, wParam, lParam ); +} + + + +///////////////////////////////////////////////////////////////////// +// Member Function : bShowFileViewer +// Type : Global +// Parameters : hContact - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 020929 , 29 September 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bShowFileViewer( HANDLE hContact ) +{ + CLHistoryDlg * pcl = new CLHistoryDlg( hContact ); + pcl->hWnd = CreateDialogParam( hInstance,MAKEINTRESOURCE(IDD_FILE_VIEWER),NULL,DlgProcFileViewer,(LPARAM)pcl); + if( pcl->hWnd ) + { + EnterCriticalSection( &csHistoryList ); + clHistoryDlgList.push_front( pcl ); + LeaveCriticalSection( &csHistoryList ); + + ShowWindow( pcl->hWnd , SW_SHOWNORMAL ); + return true; + } + DisplayLastError( _T("Failed to create history dialog") ); + delete pcl; + return false; +} diff --git a/plugins/Msg_Export/src/FileViewer.h b/plugins/Msg_Export/src/FileViewer.h new file mode 100755 index 0000000000..6da79c9620 --- /dev/null +++ b/plugins/Msg_Export/src/FileViewer.h @@ -0,0 +1,38 @@ + +//This file is part of Msg_Export a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ ) +// +//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., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef MSG_EXP_FILE_VIEWER +#define MSG_EXP_FILE_VIEWER + +#include + +void Initilize(); +void Uninitilize(); + +void UpdateFileViews( const _TCHAR * pszFile ); + +bool bOpenExternaly( HANDLE hContact ); +bool bShowFileViewer( HANDLE hContact ); + +bool bUseInternalViewer( bool bNew ); +bool bUseInternalViewer(); + +extern tstring sFileViewerPrg; + +#endif + diff --git a/plugins/Msg_Export/src/Glob.h b/plugins/Msg_Export/src/Glob.h new file mode 100755 index 0000000000..8de2c0843e --- /dev/null +++ b/plugins/Msg_Export/src/Glob.h @@ -0,0 +1,29 @@ + +//This file is part of Msg_Export a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ ) +// +//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., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef MSG_EXP_GLOB_H +#define MSG_EXP_GLOB_H + +#include + +#define MODULE "Msg_Export" +#define MSG_BOX_TITEL _T("Miranda (Msg_Export.dll)") + +extern HINSTANCE hInstance; + +#endif \ No newline at end of file diff --git a/plugins/Msg_Export/src/main.cpp b/plugins/Msg_Export/src/main.cpp new file mode 100755 index 0000000000..5d9ce233dc --- /dev/null +++ b/plugins/Msg_Export/src/main.cpp @@ -0,0 +1,404 @@ + +//This file is part of Msg_Export a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ ) +// +//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., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include +#include + +//#include "../Miranda-IM/resource.h" + +#include "utils.h" +#include "options.h" +#include "FileViewer.h" +#include "Glob.h" + +#include "resource.h" + + +#define MS_SHOW_EXPORT_HISTORY "History/ShowExportHistory" + +HINSTANCE hInstance = NULL; +int hLangpack = 0; + +// static so they can not be used from other modules ( sourcefiles ) +static HANDLE hEventOptionsInitialize = 0; +static HANDLE hDBEventAdded = 0; +static HANDLE hDBContactDeleted = 0; +static HANDLE hEventSystemInit = 0; +static HANDLE hEventSystemShutdown = 0; + +static HANDLE hServiceFunc = 0; + +static HANDLE hOpenHistoryMenuItem = 0; + +///////////////////////////////////////////////////// +// Remember to update the Version in the resource !!! +///////////////////////////////////////////////////// + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + "Message export (mod by ring0)", + PLUGIN_MAKE_VERSION(3,1,0,3), + "Exports every message, URL or File you receive to a text file.\r\n" + "Messages are exported to one file per user, users may be set to use the same file", + "Kennet Nielsen, mod by ring0", + "Kennet_N@ofir.dk", + "© 2002 Kennet Nielsen", + "http://sourceforge.net/projects/msg-export/", + UNICODE_AWARE, + #ifdef _UNICODE + { 0x46102b07, 0xc215, 0x4162, { 0x9c, 0x83, 0xd3, 0x77, 0x88, 0x1d, 0xa7, 0xcc } } // {46102B07-C215-4162-9C83-D377881DA7CC} + #else + { 0x13ff3b7e, 0x4976, 0x471f, { 0xa4, 0x75, 0x16, 0x62, 0xa4, 0xdd, 0xc, 0x3e } } // {13FF3B7E-4976-471f-A475-1662A4DD0C3E} + #endif +}; + + +///////////////////////////////////////////////////////////////////// +// Member Function : ShowExportHistory +// Type : Global +// Parameters : wParam - (WPARAM)(HANDLE)hContact +// lParam - ? +// Returns : static int +// Description : Called when user selects my menu item "Open Exported History" +// +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +static int ShowExportHistory(WPARAM wParam,LPARAM /*lParam*/) +{ + if( bUseInternalViewer() ) + { + bShowFileViewer( (HANDLE)wParam ); + return 0; + } + bOpenExternaly( (HANDLE)wParam ); + return 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : nSystemShutdown +// Type : Global +// Parameters : wparam - 0 +// lparam - 0 +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 020428 , 28 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int nSystemShutdown(WPARAM /*wparam*/,LPARAM /*lparam*/) +{ + if( hEventOptionsInitialize ) + { + UnhookEvent(hEventOptionsInitialize); + hEventOptionsInitialize = 0; + } + + if( hDBEventAdded ) + { + UnhookEvent(hDBEventAdded); + hDBEventAdded = 0; + } + + if( hDBContactDeleted ) + { + UnhookEvent(hDBContactDeleted); + hDBContactDeleted = 0; + } + + if( hServiceFunc ) + { + DestroyServiceFunction( hServiceFunc ); + hServiceFunc = 0; + } + + if( hEventSystemInit ) + { + UnhookEvent(hEventSystemInit); + hEventSystemInit = 0; + } + + if( hEventSystemShutdown ) + { + UnhookEvent(hEventSystemShutdown); // here we unhook the fun we are in, might not bee good + hEventSystemShutdown = 0; + } + return 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : MainInit +// Type : Global +// Parameters : wparam - ? +// lparam - ? +// Returns : int +// Description : Called when system modules has been loaded +// +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int MainInit(WPARAM /*wparam*/,LPARAM /*lparam*/) +{ + + Initilize(); + + bReadMirandaDirAndPath(); + UpdateFileToColWidth(); + + hDBEventAdded = HookEvent( ME_DB_EVENT_ADDED , nExportEvent ); + if( !hDBEventAdded ) + MessageBox( NULL , _T("Failed to HookEvent ME_DB_EVENT_ADDED") , MSG_BOX_TITEL , MB_OK ); + + + hDBContactDeleted = HookEvent( ME_DB_CONTACT_DELETED , nContactDeleted ); + if( !hDBContactDeleted ) + MessageBox( NULL , _T("Failed to HookEvent ME_DB_CONTACT_DELETED") , MSG_BOX_TITEL , MB_OK ); + + + hEventOptionsInitialize = HookEvent( ME_OPT_INITIALISE , OptionsInitialize ); + if( !hEventOptionsInitialize ) + MessageBox( NULL , _T("Failed to HookEvent ME_OPT_INITIALISE") , MSG_BOX_TITEL , MB_OK ); + + + CLISTMENUITEM mi; + ZeroMemory(&mi,sizeof(mi)); + mi.cbSize=sizeof(mi); + mi.flags=0; + mi.pszContactOwner=NULL; //all contacts + mi.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_EXPORT_MESSAGE)); + + if( bReplaceHistory ) + { + mi.position= 1000090000; + mi.pszName=Translate("View &History"); + mi.pszService=MS_HISTORY_SHOWCONTACTHISTORY; + } + else + { + mi.position = 1000090100; + mi.pszName=Translate("Open E&xported History"); + mi.pszService=MS_SHOW_EXPORT_HISTORY; + } + hOpenHistoryMenuItem = Menu_AddContactMenuItem(&mi); + + if( !hOpenHistoryMenuItem ) + MessageBox( NULL , _T("Failed to add menu item Open Exported History\nCallService(MS_CLIST_ADDCONTACTMENUITEM,...)") , MSG_BOX_TITEL , MB_OK ); + +/* + hEventSystemShutdown = HookEvent( ME_SYSTEM_SHUTDOWN , nSystemShutdown ); + + if( !hEventSystemShutdown ) + MessageBox( NULL , "Failed to HookEvent ME_SYSTEM_SHUTDOWN" , MSG_BOX_TITEL , MB_OK ); +*/ + +/* + _TCHAR szBuf[ 10000 ]; + for( int n = 0 ; n < 1000 ; n++ ) + { + for( int y = 0 ; y < n ; y++ ) + { + szBuf[ y ] = '0' + y%10;//((n + y) % 8 ) ? ('0' + ((n + y) % 10)) : ' ' ; + } + szBuf[ y ] = 0; + + HANDLE hFile = CreateFile( "C:\\test.txt" , GENERIC_WRITE , FILE_SHARE_READ , 0 ,OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ); + SetFilePointer( hFile , 0 , 0 , FILE_END ); + + bWriteNewLine( hFile , 10 ); + bWriteNewLine( hFile , 0 ); + bWriteNewLine( hFile , 120 ); + + DWORD dwBytesWritten; + WriteFile( hFile , "\r\n\r\n" , 4 , &dwBytesWritten , NULL ); + + CloseHandle( hFile ); + //}*/ + + return 0; +} + + + +///////////////////////////////////////////////////////////////////// +// Member Function : DllMain +// Type : Global +// Parameters : hinst - ? +// fdwReason - ? +// lpvReserved - ? +// Returns : BOOL WINAPI +// Description : +// +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +BOOL WINAPI DllMain(HINSTANCE hinst,DWORD /*fdwReason*/,LPVOID /*lpvReserved*/) +{ + hInstance=hinst; + return 1; +} + + +#ifdef __cplusplus +extern "C" { +#endif + + +///////////////////////////////////////////////////////////////////// +// Member Function : MirandaPluginInfo +// Type : Global +// Parameters : mirandaVersion - ? +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +__declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD /*mirandaVersion*/) +{ + return &pluginInfo; +} + +static const MUUID interfaces[] = { MIID_HISTORYEXPORT, MIID_LAST}; +extern "C" __declspec(dllexport) const MUUID * MirandaPluginInterfaces(void) +{ + return interfaces; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : Load +// Type : Global +// Parameters : link - ? +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int __declspec(dllexport)Load() +{ + mir_getLP(&pluginInfo); + hEventSystemInit = HookEvent(ME_SYSTEM_MODULESLOADED,MainInit); + + if( !hEventSystemInit ) + { + MessageBox( NULL , _T("Failed to HookEvent ME_SYSTEM_MODULESLOADED") , MSG_BOX_TITEL , MB_OK ); + return 0; + } + + nMaxLineWidth = DBGetContactSettingWord( NULL , MODULE , "MaxLineWidth" , nMaxLineWidth ); + if( nMaxLineWidth < 5 ) + nMaxLineWidth = 5; + + sExportDir = _DBGetString( NULL , MODULE , "ExportDir" , _T("%dbpath%\\MsgExport\\") ); + sDefaultFile = _DBGetString( NULL , MODULE , "DefaultFile" , _T("%nick%.txt") ); + + sTimeFormat = _DBGetString( NULL , MODULE , "TimeFormat" , _T("d s") ); + + sFileViewerPrg = _DBGetString( NULL , MODULE , "FileViewerPrg" , _T("") ); + bUseInternalViewer( DBGetContactSettingByte( NULL , MODULE , "UseInternalViewer" , bUseInternalViewer() ) != 0 ); + + bReplaceHistory = DBGetContactSettingByte( NULL , MODULE , "ReplaceHistory" , bReplaceHistory ) != 0; + bAppendNewLine = DBGetContactSettingByte( NULL , MODULE , "AppendNewLine" , bAppendNewLine ) != 0; + bUseUtf8InNewFiles = DBGetContactSettingByte( NULL , MODULE , "UseUtf8InNewFiles" , bUseUtf8InNewFiles ) != 0; + bUseLessAndGreaterInExport = DBGetContactSettingByte( NULL , MODULE , "UseLessAndGreaterInExport" , bUseLessAndGreaterInExport ) != 0; + + enRenameAction = (ENDialogAction)DBGetContactSettingByte( NULL , MODULE , "RenameAction" , enRenameAction ); + enDeleteAction = (ENDialogAction)DBGetContactSettingByte( NULL , MODULE , "DeleteAction" , enDeleteAction );; + + // Plugin sweeper support + DBWriteContactSettingTString(NULL,"Uninstall","Message Export",_T(MODULE)); + + if( bReplaceHistory ) + { + hServiceFunc = CreateServiceFunction(MS_HISTORY_SHOWCONTACTHISTORY,ShowExportHistory); //this need new code +/* if( hServiceFunc ) + { + int *disableDefaultModule=(int*)CallService(MS_PLUGINS_GETDISABLEDEFAULTARRAY,0,0); + if( disableDefaultModule ) + { + disableDefaultModule[DEFMOD_UIHISTORY] = TRUE; + } + else + { + DestroyServiceFunction( hServiceFunc ); + hServiceFunc = 0; + } + }*/ + + if( ! hServiceFunc ) + MessageBox( NULL , TranslateTS(_T("Failed to replace Miranda History.\r\nThis is most likely due to changes in Miranda.")) , MSG_BOX_TITEL , MB_OK ); + } + + if( ! hServiceFunc ) + { + hServiceFunc = CreateServiceFunction(MS_SHOW_EXPORT_HISTORY,ShowExportHistory); + } + + if( ! hServiceFunc ) + { + MessageBox( NULL , _T("Failed to CreateServiceFunction MS_SHOW_EXPORT_HISTORY") , MSG_BOX_TITEL , MB_OK ); + } + + return 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : Unload +// Type : Global +// Parameters : none +// Returns : +// Description : +// +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +__declspec(dllexport)int Unload(void) +{ + //if( !hEventSystemShutdown ) // we will try to unload anyway + { + nSystemShutdown(0,0); + } + Uninitilize(); + bUseInternalViewer( false ); + return 0; +} + +#ifdef __cplusplus +} +#endif diff --git a/plugins/Msg_Export/src/options.cpp b/plugins/Msg_Export/src/options.cpp new file mode 100755 index 0000000000..17bc917bb7 --- /dev/null +++ b/plugins/Msg_Export/src/options.cpp @@ -0,0 +1,1483 @@ + +//This file is part of Msg_Export a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ ) +// +//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., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#include +#include +#include "Shlobj.h" + + +#include "Utils.h" +#include "Glob.h" +#include "FileViewer.h" + +#include "resource.h" + +#include +#include +//#include + +#define STRINGIZE(x) #x +#define EVAL_STRINGIZE(x) STRINGIZE(x) +#define __LOC__ __FILE__ "("EVAL_STRINGIZE(__LINE__)") : " + + +#pragma message ( __LOC__ "My warning: STD list contains a bug when sorting lists of more than 32,768 elements, you need to fix this") +/* Change code for VC 6.0 + if (_I == _MAXN) + _A[_I].merge(_X); + SHOULD BE + if (_I == _MAXN) + _A[_I - 1].merge(_X); + + - And - + + if (_I == _MAXN) + _A[_I].merge(_X, _Pr); + SHOULD BE + if (_I == _MAXN) + _A[_I - 1].merge(_X, _Pr); + +You need to change this in the file function sort() and sort(_Pr3 _Pr) +*/ + +using namespace std; + + +// width in pixels of the UIN column in the List Ctrl +const int nUINColWitdh = 80; +// width in pixels of the UIN column in the List Ctrl +const int nProtoColWitdh = 40; + + +// Used to controle the sending of the PSM_CHANGED to miranda +// and to se if the user has unapplyed changes when he presses the +// Export All button +BOOL bUnaplyedChanges = FALSE; + + +///////////////////////////////////////////////////////////////////// +// Class : CLDBEvent +// Superclass : +// Project : Mes_export +// Designer : Kennet Nielsen +// Version : 1.0.0 +// Date : 020422 , 22 April 2002 +// +// +// Description: This class is used to store one DB event dyring the export +// All history function +// +// Version History: +// Ver: Initials: Date: Text: +// 1.0.0 KN 020422 First edition +// +///////////////////////////////////////////////////////////////////// + +class CLDBEvent +{ + DWORD time; + public: + HANDLE hUser; + HANDLE hDbEvent; + + CLDBEvent( HANDLE hU , HANDLE hDBE ) + { + hUser = hU; + hDbEvent = hDBE; + + DBEVENTINFO dbei={0}; //dbei.cbBlob=0; + dbei.cbSize=sizeof(dbei); + CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei); + time = dbei.timestamp; + } + bool operator <(const CLDBEvent& rOther) const + { + return time < rOther.time; + } +}; + +///////////////////////////////////////////////////////////////////// +// Member Function : CompareFunc +// Type : Global +// Parameters : lParam1 - ? +// lParam2 - ? +// lParamSort - ? +// Returns : int CALLBACK +// Description : Used to sort list view by Nick +// +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) +{ + if( lParamSort == 1 ) + { + return _tcsicmp( NickFromHandle((HANDLE)lParam1) , NickFromHandle((HANDLE)lParam2) ); + } + + if( lParamSort == 2 ) + { + return _DBGetString( (HANDLE)lParam1 , "Protocol" , "p" , _T("") ).compare( + _DBGetString( (HANDLE)lParam2 , "Protocol" , "p" , _T("") ) + ); + } + if( lParamSort == 3 ) + { + DWORD dwUin1 = DBGetContactSettingDword( + (HANDLE)lParam1, + _DBGetStringA( (HANDLE)lParam1 , "Protocol" , "p" , "" ).c_str(), + "UIN", + 0); + DWORD dwUin2 = DBGetContactSettingDword( + (HANDLE)lParam2, + _DBGetStringA( (HANDLE)lParam2 , "Protocol" , "p" , "" ).c_str(), + "UIN", + 0); + + if( dwUin1 == dwUin2 ) + return 0; + if( dwUin1 > dwUin2 ) + return -1; + return 1; + } + return 0; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : DialogProc +// Type : Global +// Parameters : hwndDlg - ? +// uMsg - ? +// wParam - ? +// parameter - ? +// Returns : INT_PTR CALLBACK +// Description : Progress bar window function +// +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +INT_PTR CALLBACK __stdcall DialogProc( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM /*wParam*/, // first message parameter + LPARAM /*lParam*/ // second message parameter +) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + return TRUE; + } + } + return FALSE; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : nExportCompleatList +// Type : Global +// Parameters : hParent - handle to the parrent, ( Options Dlg ) +// bOnlySelected - Only Export the userges that hase been selected in the list view +// Returns : int not used currently +// Description : +// +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int nExportCompleatList(HWND hParent , bool bOnlySelected ) +{ + HWND hMapUser = GetDlgItem( hParent , IDC_MAP_USER_LIST ); + + int nTotalContacts = ListView_GetItemCount( hMapUser ); + + int nContacts; + if( bOnlySelected ) + nContacts = ListView_GetSelectedCount( hMapUser ); + else + nContacts = nTotalContacts; + + if( !hMapUser || nContacts <= 0 ) + { + MessageBox( hParent , TranslateTS(_T("No contacts found to export")),MSG_BOX_TITEL,MB_OK ); + return 0; + } + + HWND hDlg = CreateDialog( hInstance, MAKEINTRESOURCE( IDD_EXPORT_ALL_DLG ) , hParent , DialogProc ); + HWND hProg = GetDlgItem( hDlg , IDC_EXPORT_PROGRESS ); + HWND hStatus = GetDlgItem( hDlg , IDC_EXP_ALL_STATUS ); + + SendMessage( hProg , PBM_SETRANGE , 0 , MAKELPARAM( 0 , nContacts ) ); + + SetWindowText( hStatus , TranslateTS(_T("Reading database information ( Phase 1 of 2 )")) ); + + { // position and show proigrassbar dialog + + RECT rParrent; + RECT rDlg; + if( GetWindowRect( hParent , &rParrent ) && GetWindowRect( hDlg , &rDlg ) ) + { + int x = ( (rParrent.right + rParrent.left) / 2 ) - ( (rDlg.right - rDlg.left) / 2 ); + int y = ( (rParrent.bottom + rParrent.top) / 2 ) - ( (rDlg.bottom - rDlg.top) / 2 ); + SetWindowPos( hDlg , 0 , x , y , 0 ,0 , SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW ); + } + else + ShowWindow( hDlg , SW_SHOWNORMAL ); + } + + // map with list to stored all DB history before it is exported + map, less > AllEvents; + + { // reading from the database !!! + LVITEM sItem = { 0 }; + sItem.mask = LVIF_PARAM; + + for( int nCur = 0 ; nCur < nTotalContacts ; nCur++ ) + { + if( bOnlySelected ) + { + if( ! (ListView_GetItemState( hMapUser , nCur , LVIS_SELECTED ) & LVIS_SELECTED) ) + continue; + } + + sItem.iItem = nCur; + if( ! ListView_GetItem( hMapUser, &sItem ) ) + { + MessageBox( hParent , TranslateTS(_T("Failed to export at least one contact")),MSG_BOX_TITEL,MB_OK ); + continue; + } + + HANDLE hContact = (HANDLE)sItem.lParam; + + list< CLDBEvent > & rclCurList = AllEvents[ GetFilePathFromUser( hContact ) ]; + + HANDLE hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDFIRST,(WPARAM)hContact,0); + while( hDbEvent ) + { + rclCurList.push_back( CLDBEvent( hContact , hDbEvent ) ); + + // Get next event in chain + hDbEvent = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0); + } + + SendMessage( hProg , PBM_SETPOS , nCur , 0); + RedrawWindow( hDlg , NULL , NULL , RDW_ALLCHILDREN | RDW_UPDATENOW ); + } + +/* + if( hContact ) + MessageBox( hParent , TranslateTS(_T("Failed to export at least one contact")),MSG_BOX_TITEL,MB_OK ); + */ + } + + + { // window text update + + SetWindowText( hStatus , TranslateTS(_T("Sorting and writing database information ( Phase 2 of 2 )")) ); + SendMessage( hProg , PBM_SETRANGE , 0 , MAKELPARAM( 0 , AllEvents.size() ) ); + SendMessage( hProg , PBM_SETPOS , 0 , 0); + } + + { // time to write to files !!! + map, less >::iterator FileIterator; + + int nCur=0; + for( FileIterator = AllEvents.begin() ; FileIterator != AllEvents.end() ; ++FileIterator ) + { + (FileIterator->second).sort(); // Sort is preformed here !! + // events with same time will not be swaped, they will + // remain in there original order + + list< CLDBEvent >::const_iterator iterator; + for( iterator = FileIterator->second.begin() ; iterator != FileIterator->second.end() ; ++iterator ) + { + HANDLE hDbEvent = (*iterator).hDbEvent; + nExportEvent( (WPARAM) (*iterator).hUser , (LPARAM) hDbEvent ); + } + SendMessage( hProg , PBM_SETPOS , ++nCur , 0); + RedrawWindow( hDlg , NULL , NULL , RDW_ALLCHILDREN | RDW_UPDATENOW ); + } + } + + DestroyWindow( hDlg ); + return 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : SetToDefault +// Type : Global +// Parameters : hwndDlg - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 021228 , 28 December 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void SetToDefault( HWND hParent ) +{ + HWND hMapUser = GetDlgItem( hParent , IDC_MAP_USER_LIST ); + + int nContacts = ListView_GetItemCount( hMapUser ); + + if( !hMapUser || nContacts <= 0 ) + { + return; + } + + _TCHAR szTemp[ 500 ]; + if( ! GetDlgItemText( hParent , IDC_DEFAULT_FILE , szTemp , sizeof( szTemp ) ) ) + return; + + LVITEM sItem = { 0 }; + + for( int nCur = 0 ; nCur < nContacts ; nCur++ ) + { + if( ! (ListView_GetItemState( hMapUser , nCur , LVIS_SELECTED ) & LVIS_SELECTED) ) + continue; + + sItem.iItem = nCur; + sItem.mask = LVIF_PARAM; + if( ! ListView_GetItem( hMapUser, &sItem ) ) + continue; + + tstring sFileName = szTemp; + ReplaceDefines( (HANDLE)sItem.lParam , sFileName ); + ReplaceTimeVariables( sFileName ); + + sItem.mask = LVIF_TEXT; + sItem.pszText = (_TCHAR*)sFileName.c_str(); + ListView_SetItem( hMapUser, &sItem ); + + if( ! bUnaplyedChanges ) + { + bUnaplyedChanges = TRUE; + SendMessage(GetParent(hParent), PSM_CHANGED, 0, 0); + } + } +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bApplyChanges +// Type : Global +// Parameters : hwndDlg - handle to the parrent, ( Options Dlg ) +// Returns : Returns true if the changes was applyed +// Description : but since we cant abort an apply opperation , +// this can not currently be used +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +BOOL bApplyChanges( HWND hwndDlg ) +{ + BOOL bTrans; + BOOL bRet = true; + _TCHAR szTemp[500]; + + int nTmp = GetDlgItemInt( hwndDlg , IDC_MAX_CLOUMN_WIDTH , &bTrans , TRUE ); + if( !bTrans || nTmp < 5 ) + { + _sntprintf( szTemp , sizeof( szTemp ) ,CheckedTranslate(_T("Max line width must be at least %d"),1) , 5 ); + MessageBox( hwndDlg , szTemp ,MSG_BOX_TITEL,MB_OK ); + bRet = false; + } + else + { + nMaxLineWidth = nTmp; + } + + GetDlgItemText( hwndDlg , IDC_EXPORT_TIMEFORMAT , szTemp , sizeof( szTemp ) ); + sTimeFormat = szTemp; + + GetDlgItemText( hwndDlg , IDC_EXPORT_DIR , szTemp , sizeof( szTemp ) ); + sExportDir = szTemp; + + GetDlgItemText( hwndDlg , IDC_DEFAULT_FILE , szTemp , sizeof( szTemp ) ); + sDefaultFile = szTemp; + + GetDlgItemText( hwndDlg , IDC_FILE_VIEWER , szTemp , sizeof( szTemp ) ); + sFileViewerPrg = szTemp; + + bUseInternalViewer( IsDlgButtonChecked( hwndDlg , IDC_USE_INTERNAL_VIEWER ) == BST_CHECKED ); + + bool bNewRp = IsDlgButtonChecked( hwndDlg , IDC_REPLACE_MIRANDA_HISTORY ) == BST_CHECKED; + if( bReplaceHistory != bNewRp ) + { + bReplaceHistory = bNewRp; + MessageBox( hwndDlg , TranslateTS(_T("You need to restart miranda to change the history function")) ,MSG_BOX_TITEL,MB_OK ); + } + + bAppendNewLine = IsDlgButtonChecked( hwndDlg , IDC_APPEND_NEWLINE ) == BST_CHECKED; + bUseUtf8InNewFiles = IsDlgButtonChecked( hwndDlg , IDC_USE_UTF8_IN_NEW_FILES ) == BST_CHECKED; + + bUseLessAndGreaterInExport = IsDlgButtonChecked( hwndDlg , IDC_USE_LESS_AND_GREATER_IN_EXPORT ) == BST_CHECKED; + + + HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST ); + int nCount = ListView_GetItemCount( hMapUser ); + for( int nCur = 0 ; nCur < nCount ; nCur++ ) + { + LVITEM sItem = { 0 }; + sItem.iItem = nCur; + sItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + sItem.pszText = szTemp; + sItem.cchTextMax = sizeof( szTemp ); + + if( ListView_GetItem( hMapUser, &sItem ) ) + { + HANDLE hUser = (HANDLE)sItem.lParam; + if( _tcslen( szTemp ) > 0 ) + DBWriteContactSettingTString( hUser , MODULE , "FileName" , szTemp ); + else + DBDeleteContactSetting( hUser , MODULE , "FileName" ); + + if( sItem.iImage ) + DBDeleteContactSetting( hUser , MODULE , "EnableLog" ); // default is Enabled !! + else + DBWriteContactSettingByte( hUser , MODULE , "EnableLog",0); + } + } + UpdateFileToColWidth(); + + SaveSettings(); + + + bUnaplyedChanges = FALSE; + return bRet; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : ClearAllFileNames +// Type : Global +// Parameters : hwndDlg - handle to the parrent, ( Options Dlg ) +// Returns : void +// Description : Just clear all file name's entered +// +// References : - +// Remarks : - +// Created : 020422 , 23 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void ClearAllFileNames(HWND hwndDlg) +{ + LVITEM sItem = { 0 }; + sItem.mask = LVIF_TEXT; + sItem.pszText = _T(""); + + HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST ); + int nCount = ListView_GetItemCount( hMapUser ); + for( int nCur = 0 ; nCur < nCount ; nCur++ ) + { + sItem.iItem = nCur; + ListView_SetItem( hMapUser, &sItem ); + } + if( ! bUnaplyedChanges ) + { + bUnaplyedChanges = TRUE; + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } +} + +///////////////////////////////////////////////////////////////////// +// Member Function : AutoFindeFileNames +// Type : Global +// Parameters : hwndDlg - handle to the parrent, ( Options Dlg ) +// Returns : void +// Description : Try to finde new file names for user's with 2or more UIN's +// +// References : - +// Remarks : - +// Created : 020422 , 23 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void AutoFindeFileNames(HWND hwndDlg) +{ + + _TCHAR szDefaultFile[500]; + GetDlgItemText( hwndDlg , IDC_DEFAULT_FILE , szDefaultFile , sizeof( szDefaultFile ) ); + + LVITEM sItem = { 0 }; + + HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST ); + int nCount = ListView_GetItemCount( hMapUser ); + for( int nCur = 0 ; nCur < nCount ; nCur++ ) + { + _TCHAR szSearch[ 100 ]; + + sItem.mask = LVIF_TEXT; + sItem.iItem = nCur; + sItem.iSubItem = 1; + sItem.pszText = szSearch; + sItem.cchTextMax = sizeof( szSearch ); + + if( ! ListView_GetItem( hMapUser, &sItem ) ) + { + continue; + } + + int nShortestMatch = 0xFFFF; + HANDLE hStortest = 0; + int nStortestIndex = -1; + for( int nSubCur = 0 ; nSubCur < nCount ; nSubCur++ ) + { + if( nSubCur == nCur ) + continue; + _TCHAR szSubCur[ 100 ]; + sItem.mask = LVIF_TEXT | LVIF_PARAM; + sItem.iItem = nSubCur; + sItem.iSubItem = 1; + sItem.pszText = szSubCur; + sItem.cchTextMax = sizeof( szSubCur ); + if( ListView_GetItem( hMapUser, &sItem ) ) + { + int nLen = _tcslen( szSubCur ); + if( _tcsncicmp( szSubCur , szSearch , nLen ) == 0 ) + { + if( nLen < nShortestMatch ) + { + nShortestMatch = nLen; + nStortestIndex = nSubCur; + hStortest = (HANDLE)sItem.lParam; + } + } + } + } + if( nShortestMatch != 0xFFFF ) + { + tstring sFileName; + szSearch[0] = 0; + ListView_GetItemText( hMapUser, nCur , 0 , szSearch , sizeof( szSearch )); + bool bPriHasFileName = szSearch[0] != 0; + if( bPriHasFileName ) + sFileName = szSearch; + + szSearch[0] = 0; + ListView_GetItemText( hMapUser, nStortestIndex , 0 , szSearch , sizeof( szSearch )); + bool bSubHasFileName = szSearch[0] != 0; + if( bSubHasFileName ) + sFileName = szSearch; + + if( sFileName.empty() ) + { + sFileName = szDefaultFile; + ReplaceDefines( hStortest , sFileName ); + ReplaceTimeVariables( sFileName ); + } + + if( !bPriHasFileName ) + ListView_SetItemText( hMapUser, nCur , 0 , (_TCHAR*)sFileName.c_str() ); + + if( !bSubHasFileName ) + ListView_SetItemText( hMapUser, nStortestIndex , 0 , (_TCHAR*)sFileName.c_str() ); + + if( ! bUnaplyedChanges ) + { + bUnaplyedChanges = TRUE; + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + } + } +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : OpenHelp +// Type : Global +// Parameters : hwndDlg - handle to the parrent, ( Options Dlg ) +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 020427 , 27 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void OpenHelp(HWND hwndDlg) +{ + _TCHAR szPath[MAX_PATH]; + if( GetModuleFileName( hInstance , szPath , sizeof( szPath ) ) ) + { + int nLen = _tcslen( szPath ); + if( nLen > 3 ) + { + szPath[nLen-1] = 't'; + szPath[nLen-2] = 'x'; + szPath[nLen-3] = 't'; + + SHELLEXECUTEINFO st = {0}; + st.cbSize = sizeof(st); + st.fMask = SEE_MASK_INVOKEIDLIST; + st.hwnd = NULL; + st.lpFile = szPath; + st.nShow = SW_SHOWDEFAULT; + ShellExecuteEx(&st); + + return; + } + } + + MessageBox( hwndDlg , TranslateTS(_T("Failed to get the path to Msg_Export.dll\nPlease locate Msg_Export.txt your self")),MSG_BOX_TITEL,MB_OK ); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : DlgProcMsgExportOpts +// Type : Global +// Parameters : hwndDlg - handle to this dialog +// msg - ? +// wParam - ? +// lParam - ? +// Returns : static BOOL CALLBACK +// Description : Main message prossing fore my options dialog +// +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +static BOOL CALLBACK DlgProcMsgExportOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ +// Used to prevent sending the PSM_CHANGED to miranda +// when initilizing + static BOOL bWindowTextSet = FALSE; + + switch (msg) + { + case WM_INITDIALOG: + { + bWindowTextSet = FALSE; + + HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST ); + + { // init adv. win styles + DWORD dw = ListView_GetExtendedListViewStyle( hMapUser ); + dw |= LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT; + ListView_SetExtendedListViewStyle( hMapUser , dw /*| LVS_EX_LABELTIP*/); + } + + + int nColumnWidth = 100; + RECT rListSize; + if( GetWindowRect( hMapUser , &rListSize ) ) + { + nColumnWidth = (rListSize.right - rListSize.left- GetSystemMetrics(SM_CXVSCROLL) - 5 - nUINColWitdh - nProtoColWitdh) / 2; + if( nColumnWidth < 10 ) + nColumnWidth = 10; + } + + { // header setup !! + + LVCOLUMN cCol = { 0 }; + cCol.mask = LVCF_TEXT | LVCF_WIDTH; + cCol.cx = nColumnWidth; + cCol.pszText = TranslateTS(_T("File")); + ListView_InsertColumn( hMapUser , 0 , &cCol ); + cCol.pszText = TranslateTS(_T("Nick")); + ListView_InsertColumn( hMapUser , 1 , &cCol ); + cCol.cx = nProtoColWitdh; + cCol.pszText = TranslateTS(_T("Proto")); + ListView_InsertColumn( hMapUser , 2 , &cCol ); + cCol.cx = nUINColWitdh; + cCol.mask |= LVCF_FMT; + cCol.fmt = LVCFMT_RIGHT; + cCol.pszText = TranslateTS(_T("UIN")); + + ListView_InsertColumn( hMapUser , 3 , &cCol ); + + /* + int nOrder[3] = { 1 , 2 , 0 }; + ListView_SetColumnOrderArray( hMapUser , 3 , nOrder );*/ + } + + { + HIMAGELIST hIml; + hIml = ImageList_Create( GetSystemMetrics(SM_CXSMICON) , GetSystemMetrics(SM_CYSMICON),ILC_COLOR4|ILC_MASK,2,2); + ImageList_AddIcon(hIml,LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_NOTICK))); + ImageList_AddIcon(hIml,LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_TICK))); + ListView_SetImageList( hMapUser, hIml, LVSIL_SMALL); + } + + { + tstring sTmp; + LVITEM sItem = { 0 }; + HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + for( int nUser = 0; /*hContact*/ ; nUser++ ) + { + sItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; + sItem.iItem = nUser; + sItem.iSubItem = 0; + sItem.iImage = DBGetContactSettingByte(hContact,MODULE,"EnableLog",1); + sItem.lParam = (LPARAM) hContact; + + + sTmp = _DBGetString( hContact , MODULE , "FileName" , _T("") ); + sItem.pszText = (_TCHAR*)sTmp.c_str(); + + ListView_InsertItem( hMapUser , &sItem ); + + sItem.mask = LVIF_TEXT; + sItem.iSubItem = 1; + sItem.pszText = (_TCHAR*)NickFromHandle(hContact); + ListView_SetItem( hMapUser , &sItem ); + + sItem.iSubItem = 2; + + sTmp = _DBGetString( hContact , "Protocol" , "p" , _T("") ); + string sTmpA = _DBGetStringA( hContact , "Protocol" , "p" , "" ); + sItem.pszText = (_TCHAR*)sTmp.c_str(); + ListView_SetItem( hMapUser , &sItem ); + + + DWORD dwUIN = DBGetContactSettingDword(hContact, sTmpA.c_str(), "UIN", 0); + _TCHAR szTmp[50]; + _sntprintf( szTmp , sizeof(szTmp) ,_T("%d") , dwUIN ); + sItem.iSubItem = 3; + sItem.pszText = szTmp; + ListView_SetItem( hMapUser , &sItem ); + + if( ! hContact ) // written like this to add the current user ( handle = 0 ) + break; + + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } + ListView_SortItems( hMapUser , CompareFunc , 1 ); + + sItem.mask = LVIF_STATE; + sItem.iItem = 0; + sItem.iSubItem = 0; + sItem.state = LVIS_FOCUSED; + sItem.stateMask = LVIS_FOCUSED; + ListView_SetItem( hMapUser , &sItem ); + + } + HWND hComboBox; + + SetDlgItemInt( hwndDlg , IDC_MAX_CLOUMN_WIDTH , nMaxLineWidth , TRUE ); + + {// Export dir + SetDlgItemText( hwndDlg , IDC_EXPORT_DIR , sExportDir.c_str() ); + hComboBox = GetDlgItem( hwndDlg , IDC_EXPORT_DIR ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%dbpath%\\MsgExport\\") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("C:\\Backup\\MsgExport\\") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%dbpath%\\MsgExport\\%group% - ") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%dbpath%\\MsgExport\\%group%\\") ); + } + {// default file + SetDlgItemText( hwndDlg , IDC_DEFAULT_FILE , sDefaultFile.c_str() ); + hComboBox = GetDlgItem( hwndDlg , IDC_DEFAULT_FILE ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%nick%.txt") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%UIN%.txt") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%group%.txt") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%e-mail%.txt") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%identifier%.txt") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%year%-%month%-%day%.txt") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%group%\\%nick%.txt") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%group%\\%UIN%.txt") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%group%\\%identifier%.txt") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("%protocol%\\%nick%.txt") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("History.txt")); + } + {// time format + SetDlgItemText( hwndDlg , IDC_EXPORT_TIMEFORMAT , sTimeFormat.c_str() ); + hComboBox = GetDlgItem( hwndDlg , IDC_EXPORT_TIMEFORMAT ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("d t") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("d s") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("d m") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("D s") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("D m :")); + } + {// File viewer + SetDlgItemText( hwndDlg , IDC_FILE_VIEWER , sFileViewerPrg.c_str() ); + hComboBox = GetDlgItem( hwndDlg , IDC_FILE_VIEWER ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("C:\\Windows\\Notepad.exe") ); + SendMessage( hComboBox , CB_ADDSTRING, 0 , (LPARAM)_T("C:\\WinNT\\Notepad.exe") ); + //EnableWindow( GetDlgItem( hwndDlg , IDC_FILE_VIEWER ) , ! bUseInternalViewer() ); + } + + + CheckDlgButton( hwndDlg , IDC_USE_INTERNAL_VIEWER , bUseInternalViewer() ? BST_CHECKED : BST_UNCHECKED ); + CheckDlgButton( hwndDlg , IDC_REPLACE_MIRANDA_HISTORY , bReplaceHistory ? BST_CHECKED : BST_UNCHECKED ); + CheckDlgButton( hwndDlg , IDC_APPEND_NEWLINE , bAppendNewLine ? BST_CHECKED : BST_UNCHECKED ); + CheckDlgButton( hwndDlg , IDC_USE_UTF8_IN_NEW_FILES , bUseUtf8InNewFiles ? BST_CHECKED : BST_UNCHECKED ); + CheckDlgButton( hwndDlg , IDC_USE_LESS_AND_GREATER_IN_EXPORT , bUseLessAndGreaterInExport ? BST_CHECKED : BST_UNCHECKED ); + + + TranslateDialogDefault(hwndDlg); + + bWindowTextSet = TRUE; + return TRUE; + } + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case ID_EXPORTSELECTED: + case IDC_EXPORTALL: + { + if( bUnaplyedChanges ) + { + DWORD res = MessageBox( hwndDlg , TranslateTS(_T("You have unapplyed changes do you wish to apply these first ?")),MSG_BOX_TITEL,MB_YESNOCANCEL ); + if( res == IDCANCEL ) + return TRUE; + if( res == IDYES ) + { + if( ! bApplyChanges( hwndDlg ) ) + { + return TRUE; + } + } + } + nExportCompleatList( hwndDlg , LOWORD(wParam) == ID_EXPORTSELECTED ); + return TRUE; + } + case IDC_EXPORT_DIR: + case IDC_EXPORT_TIMEFORMAT: + case IDC_DEFAULT_FILE: + case IDC_FILE_VIEWER: + { + if( !bWindowTextSet ) + return TRUE; + + if( HIWORD(wParam) == CBN_EDITUPDATE || HIWORD(wParam) == CBN_SELCHANGE ) + { + bUnaplyedChanges = TRUE; + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + return TRUE; + } + case IDC_MAX_CLOUMN_WIDTH: + { + if( !bWindowTextSet ) + return TRUE; + + if( HIWORD(wParam) == EN_CHANGE ) + { + bUnaplyedChanges = TRUE; + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + return TRUE; + } + case IDC_USE_INTERNAL_VIEWER: +/* { + EnableWindow( + GetDlgItem( hwndDlg , IDC_FILE_VIEWER ) , + !IsDlgButtonChecked( hwndDlg , IDC_USE_INTERNAL_VIEWER ) + ); + }// fall thru here !!*/ + case IDC_REPLACE_MIRANDA_HISTORY: + case IDC_APPEND_NEWLINE: + case IDC_USE_UTF8_IN_NEW_FILES: + case IDC_USE_LESS_AND_GREATER_IN_EXPORT: + { + if( HIWORD(wParam) == BN_CLICKED ) + { + bUnaplyedChanges = TRUE; + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + return TRUE; + } + case ID_USERLIST_USERDETAILS: + { + LVITEM sItem = { 0 }; + sItem.mask = LVIF_PARAM; + HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST ); + sItem.iItem = ListView_GetNextItem( hMapUser , -1 , LVIS_SELECTED ); + if( sItem.iItem >= 0 && ListView_GetItem( hMapUser, &sItem )) + { + CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)sItem.lParam ,0); + } + return TRUE; + } + case IDC_AUTO_FILENAME: + { + AutoFindeFileNames(hwndDlg); + return TRUE; + } + case IDC_CLEAR_ALL: + { + ClearAllFileNames(hwndDlg); + return TRUE; + + } + case IDC_OPEN_HELP: + { + OpenHelp(hwndDlg); + return TRUE; + } + case ID_SET_TO_DEFAULT: + { + SetToDefault( hwndDlg ); + return TRUE; + } + case IDC_FILE_VIEWER_BROWSE: + { + OPENFILENAME ofn = { 0 }; // common dialog box structure + _TCHAR szFile[260]; // buffer for file name + + GetDlgItemText( hwndDlg , IDC_FILE_VIEWER , szFile , sizeof(szFile)); + // Initialize OPENFILENAME + //ZeroMemory(&ofn, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwndDlg; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = _T("Executable files (*.exe;*.com;*.bat;*.cmd)\0*.exe;*.com;*.bat;*.cmd\0All files(*.*)\0*.*\0"); + ofn.nFilterIndex = 1; + //ofn.lpstrFileTitle = NULL; + //ofn.nMaxFileTitle = 0; + //ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; + + // Display the Open dialog box. + + if (GetOpenFileName(&ofn)) + { + SetDlgItemText( hwndDlg , IDC_FILE_VIEWER , szFile ); + bUnaplyedChanges = TRUE; + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + // OPENFILENAME + //GetOpenFileName( + return TRUE; + } + case IDC_EXPORT_DIR_BROWSE: + { + LPMALLOC pMalloc; + + //CoInitializeEx(NULL,COINIT_APARTMENTTHREADED ); + // Get the shells allocator + if (FAILED(SHGetMalloc(&pMalloc))) // we need to use this to support old Windows versions + { + MessageBox( hwndDlg , _T("Failed to get the shells allocator !"),MSG_BOX_TITEL,MB_OK ); + return TRUE; // TRUE because we have handled the message , sort of *S* + } + + // Allocate the Dest Dir buffer to receive browse info + _TCHAR * lpDestDir = (_TCHAR * ) pMalloc->Alloc(MAX_PATH+100); + if ( ! lpDestDir ) + { + pMalloc->Release(); + MessageBox( hwndDlg , _T("Failed to Allocate buffer space"),MSG_BOX_TITEL,MB_OK ); + return TRUE; + } + + BROWSEINFO sBrowseInfo; + sBrowseInfo.hwndOwner = hwndDlg; + sBrowseInfo.pidlRoot = NULL; + sBrowseInfo.pszDisplayName = lpDestDir; + sBrowseInfo.lpszTitle = TranslateTS(_T("Select Destination Directory")); + sBrowseInfo.ulFlags = BIF_NEWDIALOGSTYLE | BIF_EDITBOX;; + sBrowseInfo.lpfn = NULL; + sBrowseInfo.lParam = 0; + sBrowseInfo.iImage = 0; + + LPITEMIDLIST psItemIDList = SHBrowseForFolder(&sBrowseInfo); + if( psItemIDList ) + { + SHGetPathFromIDList(psItemIDList, lpDestDir); + int n = _tcslen( lpDestDir ); + if( n > 0 && lpDestDir[n] != '\\' ) + { + lpDestDir[n] = '\\' ; + lpDestDir[n+1] = 0; + } + SetDlgItemText( hwndDlg , IDC_EXPORT_DIR , lpDestDir ); + bUnaplyedChanges = TRUE; + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + // Clean up + pMalloc->Free( psItemIDList ); + } + pMalloc->Free( lpDestDir ); + pMalloc->Release(); + return TRUE; + } + } + break; + } + case WM_CONTEXTMENU: + { + if( wParam != (WPARAM)GetDlgItem( hwndDlg , IDC_MAP_USER_LIST ) ) + return FALSE; + + HMENU hMainMenu = LoadMenu(hInstance ,MAKEINTRESOURCE(IDR_MSG_EXPORT)); + if( hMainMenu ) + { + HMENU hMenu = GetSubMenu(hMainMenu,0); + + POINT pt; + pt.x=(short)LOWORD(lParam); + pt.y=(short)HIWORD(lParam); + if( pt.x == -1 && pt.y == -1 ) + { + HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST ); + int nFirst = ListView_GetNextItem( hMapUser , -1 , LVNI_FOCUSED ); + if( nFirst >= 0 ) + { + ListView_GetItemPosition( hMapUser , nFirst , &pt ); + } + + if( pt.y < 16 ) + pt.y = 16; + else + { + RECT rUserList; + GetClientRect( hMapUser , &rUserList ); + if( pt.y > rUserList.bottom - 16 ) + pt.y = rUserList.bottom - 16; + else + pt.y += 8; + } + pt.x = 8; + ClientToScreen(hMapUser,&pt); + } + + CallService(MS_LANGPACK_TRANSLATEMENU,(WPARAM)hMenu,0); + TrackPopupMenu(hMenu,TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON,pt.x,pt.y,0,hwndDlg,NULL); + + DestroyMenu(hMainMenu); + } + return TRUE; + } + case WM_NOTIFY: + { + NMHDR * p = ((LPNMHDR)lParam); + if( p->idFrom == IDC_MAP_USER_LIST ) + { + switch (p->code) + { + case NM_CLICK: + { LVHITTESTINFO hti; + LVITEM lvi; + hti.pt=((NMLISTVIEW*)lParam)->ptAction; + ListView_SubItemHitTest( p->hwndFrom ,&hti); + + if( hti.flags != LVHT_ONITEMICON ) + break; + + lvi.mask=LVIF_IMAGE; + lvi.iItem=hti.iItem; + lvi.iSubItem=0; + ListView_GetItem( p->hwndFrom , &lvi); + lvi.iImage^=1; + ListView_SetItem( p->hwndFrom , &lvi); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + case LVN_ENDLABELEDIT: + { + NMLVDISPINFO * pdi = (NMLVDISPINFO *) lParam; + if( pdi->item.mask & LVIF_TEXT ) + { + pdi->item.mask &= LVIF_TEXT; + ListView_SetItem( p->hwndFrom , &pdi->item ); + + bUnaplyedChanges = TRUE; + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + return TRUE; + } + case LVN_KEYDOWN: + { + NMLVKEYDOWN * lpnmk = (NMLVKEYDOWN *) lParam; + if( lpnmk->wVKey == 'A' && (GetKeyState( VK_CONTROL ) & 0x8000) ) + { + // select all + int nCount = ListView_GetItemCount( p->hwndFrom ); + for( int nCur = 0 ; nCur < nCount ; nCur++ ) + { + ListView_SetItemState( p->hwndFrom , nCur , LVIS_SELECTED , LVIS_SELECTED ); + } + return TRUE; + } + + + if( lpnmk->wVKey == VK_F2 || + ( lpnmk->wVKey >= 'A' && lpnmk->wVKey <= 'Z') || + ( lpnmk->wVKey >= '1' && lpnmk->wVKey <= '9') || + lpnmk->wVKey == VK_BACK + ) + { + HWND hEdit = ListView_EditLabel( p->hwndFrom , ListView_GetSelectionMark(p->hwndFrom) ); + if( hEdit && lpnmk->wVKey != VK_F2 ) + { + if( isupper( lpnmk->wVKey ) ) + SendMessage( hEdit , WM_CHAR , tolower( lpnmk->wVKey ) , 0 ); + else + SendMessage( hEdit , WM_CHAR , lpnmk->wVKey , 0 ); + } + } + return TRUE; + } + case NM_DBLCLK: + { + NMITEMACTIVATE * pdi = (NMITEMACTIVATE *) lParam; + if( pdi->iItem >= 0 ) + { + ListView_EditLabel( p->hwndFrom , pdi->iItem ); + } + return TRUE; + } + case NM_CUSTOMDRAW: + { + LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam; + switch(lplvcd->nmcd.dwDrawStage) + { + case CDDS_PREPAINT: + { + SetWindowLong(hwndDlg, DWL_MSGRESULT, CDRF_NOTIFYITEMDRAW); + return true; + } + case CDDS_ITEMPREPAINT: + { + if( lplvcd->nmcd.lItemlParam == 0 ) + { + lplvcd->clrText = RGB( 0 , 0 , 255 ); + } + SetWindowLong(hwndDlg, DWL_MSGRESULT, CDRF_NEWFONT); + return true; + } + } + return FALSE; + } + } + } + else + { + switch (p->code) + { + case PSN_APPLY: + { + bApplyChanges( hwndDlg ); + return TRUE; + } + case HDN_ITEMCLICK: + { + NMHEADER * phdr = (LPNMHEADER) p; + if( phdr->iButton == 0 )// 0 => Left button + { + HWND hMapUser = GetDlgItem( hwndDlg , IDC_MAP_USER_LIST ); + ListView_SortItems( hMapUser , CompareFunc , phdr->iItem ); + return TRUE; + } + return FALSE; + } + } + } + break; + } + } + return FALSE; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bApplyChanges2 +// Type : Global +// Parameters : hwndDlg - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 050429 , 29 april 2005 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +BOOL bApplyChanges2( HWND hwndDlg ) +{ + if( IsDlgButtonChecked( hwndDlg , IDC_FC_PROMPT ) == BST_CHECKED ) + enRenameAction = eDAPromptUser; + else if( IsDlgButtonChecked( hwndDlg , IDC_FC_RENAME ) == BST_CHECKED ) + enRenameAction = eDAAutomatic; + else if( IsDlgButtonChecked( hwndDlg , IDC_FC_NOTHING ) == BST_CHECKED ) + enRenameAction = eDANothing; + + if( IsDlgButtonChecked( hwndDlg , IDC_FD_PROMPT ) == BST_CHECKED ) + enDeleteAction = eDAPromptUser; + else if( IsDlgButtonChecked( hwndDlg , IDC_FD_DELETE ) == BST_CHECKED ) + enDeleteAction = eDAAutomatic; + else if( IsDlgButtonChecked( hwndDlg , IDC_FD_NOTHING ) == BST_CHECKED ) + enDeleteAction = eDANothing; + + char szTemp[ 500 ]; + strcpy( szTemp , "DisableProt_" ); + + HWND hMapUser = GetDlgItem( hwndDlg , IDC_EXPORT_PROTOS ); + int nCount = ListView_GetItemCount( hMapUser ); + for( int nCur = 0 ; nCur < nCount ; nCur++ ) + { + LVITEMA sItem = { 0 }; + sItem.iItem = nCur; + sItem.mask = LVIF_TEXT | LVIF_IMAGE; + sItem.pszText = &szTemp[12]; + sItem.cchTextMax = sizeof( szTemp )-15; + if( ::SendMessage(hMapUser, LVM_GETITEMA, 0, (LPARAM)&sItem ) ) + { + if( sItem.iImage ) + DBDeleteContactSetting( NULL , MODULE , szTemp ); // default is Enabled !! + else + DBWriteContactSettingByte( NULL , MODULE , szTemp,0); + } + } + SaveSettings(); + return TRUE; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : DlgProcMsgExportOpts2 +// Type : Global +// Parameters : hwndDlg - ? +// msg - ? +// wParam - ? +// lParam - ? +// Returns : static BOOL CALLBACK +// Description : +// +// References : - +// Remarks : - +// Created : 040205 , 05 februar 2004 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +static BOOL CALLBACK DlgProcMsgExportOpts2(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static BOOL bWindowTextSet = FALSE; + + switch (msg) + { + case WM_INITDIALOG: + { + bWindowTextSet = FALSE; + switch( enRenameAction ) + { + case eDAPromptUser: + CheckDlgButton( hwndDlg , IDC_FC_PROMPT , true ); + break; + case eDAAutomatic: + CheckDlgButton( hwndDlg , IDC_FC_RENAME , true ); + break; + case eDANothing: + CheckDlgButton( hwndDlg , IDC_FC_NOTHING , true ); + break; + } + switch( enDeleteAction ) + { + case eDAPromptUser: + CheckDlgButton( hwndDlg , IDC_FD_PROMPT , true ); + break; + case eDAAutomatic: + CheckDlgButton( hwndDlg , IDC_FD_DELETE , true ); + break; + case eDANothing: + CheckDlgButton( hwndDlg , IDC_FD_NOTHING , true ); + break; + } + HWND hMapUser = GetDlgItem( hwndDlg , IDC_EXPORT_PROTOS ); +/* + { // init adv. win styles + DWORD dw = ListView_GetExtendedListViewStyle( hMapUser ); + dw |= LVS_EX_HEADERDRAGDROP | LVS_EX_FULLROWSELECT; + ListView_SetExtendedListViewStyle( hMapUser , dw /); + } +*/ + int nColumnWidth = 100; + RECT rListSize; + if( GetWindowRect( hMapUser , &rListSize ) ) + { + nColumnWidth = (rListSize.right - rListSize.left- GetSystemMetrics(SM_CXVSCROLL) - 5 ); + if( nColumnWidth < 10 ) + nColumnWidth = 10; + } + + { // header setup !! + LVCOLUMN cCol = { 0 }; + cCol.mask = LVCF_TEXT | LVCF_WIDTH; + cCol.cx = nColumnWidth; + cCol.pszText = TranslateTS(_T("Export Protocols")); + ListView_InsertColumn( hMapUser , 0 , &cCol ); + } + + { + HIMAGELIST hIml; + hIml = ImageList_Create( GetSystemMetrics(SM_CXSMICON) , GetSystemMetrics(SM_CYSMICON),ILC_COLOR4|ILC_MASK,2,2); + ImageList_AddIcon(hIml,LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_NOTICK))); + ImageList_AddIcon(hIml,LoadIcon(GetModuleHandle(NULL),MAKEINTRESOURCE(IDI_TICK))); + ListView_SetImageList( hMapUser, hIml, LVSIL_SMALL); + } + + { + PROTOCOLDESCRIPTOR **proto; + int nCount; + LVITEMA sItem = { 0 }; + sItem.mask = LVIF_TEXT | LVIF_IMAGE; + char szTemp[ 500 ]; + + CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&nCount,(LPARAM)&proto); + + for( int i=0 ; i < nCount ; i++) + { + if( proto[i]->type==PROTOTYPE_IGNORE) //PROTOTYPE_PROTOCOL + continue; + _snprintf( szTemp , sizeof( szTemp ) , "DisableProt_%s" , proto[i]->szName ); + sItem.pszText = proto[i]->szName; + sItem.iImage = DBGetContactSettingByte(NULL,MODULE,szTemp,1); + ::SendMessage( hMapUser , LVM_INSERTITEMA , 0 ,(LPARAM)&sItem ); + sItem.iItem++; + } + } + + TranslateDialogDefault(hwndDlg); + + bWindowTextSet = TRUE; + return TRUE; + } + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case IDC_FC_PROMPT: + case IDC_FC_RENAME: + case IDC_FC_NOTHING: + case IDC_FD_PROMPT: + case IDC_FD_DELETE: + case IDC_FD_NOTHING: + { + if( !bWindowTextSet ) + return TRUE; + + if( HIWORD(wParam) == BN_CLICKED ) + { + bUnaplyedChanges = TRUE; + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + } + return TRUE; + } + case IDC_DEBUG_INFO: + { + ShowDebugInfo(); + return TRUE; + } + } + break; + } + case WM_NOTIFY: + { + NMHDR * p = ((LPNMHDR)lParam); + if( p->idFrom == IDC_EXPORT_PROTOS ) + { + switch (p->code) + { + case NM_CLICK: + { LVHITTESTINFO hti; + LVITEM lvi; + hti.pt=((NMLISTVIEW*)lParam)->ptAction; + ListView_SubItemHitTest( p->hwndFrom ,&hti); + + if( hti.flags != LVHT_ONITEMICON ) + break; + + lvi.mask=LVIF_IMAGE; + lvi.iItem=hti.iItem; + lvi.iSubItem=0; + ListView_GetItem( p->hwndFrom , &lvi); + lvi.iImage^=1; + ListView_SetItem( p->hwndFrom , &lvi); + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + } + break; + } + switch (p->code) + { + case PSN_APPLY: + { + bApplyChanges2(hwndDlg); + return TRUE; + } + case HDN_ITEMCLICK: + { + return FALSE; + } + } + break; + } + } + // + return FALSE; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : OptionsInitialize +// Type : Global +// Parameters : wParam - ? +// lParam - ? +// Returns : int +// Description : Called when the user openes the options dialog +// I need to add my options page. +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int OptionsInitialize(WPARAM wParam,LPARAM /*lParam*/) +{ + OPTIONSDIALOGPAGE odp; + + bUnaplyedChanges = FALSE; + + ZeroMemory(&odp,sizeof(odp)); + odp.cbSize = sizeof(odp); + odp.position = 100000000; + odp.hInstance = hInstance; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MSGEXPORT); + odp.flags = ODPF_BOLDGROUPS; + odp.pszTitle = Translate("Message export"); + odp.pszGroup = Translate("Plugins"); + odp.groupPosition = 100000000; + odp.pfnDlgProc = DlgProcMsgExportOpts; + Options_AddPage(wParam,&odp); + + + odp.position = 100000001; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_MSGEXPORT2); + odp.pszTitle = Translate("Message export2"); + odp.pfnDlgProc = DlgProcMsgExportOpts2; + Options_AddPage(wParam,&odp); + return 0; +} diff --git a/plugins/Msg_Export/src/options.h b/plugins/Msg_Export/src/options.h new file mode 100755 index 0000000000..60debd4b77 --- /dev/null +++ b/plugins/Msg_Export/src/options.h @@ -0,0 +1,26 @@ + +//This file is part of Msg_Export a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ ) +// +//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., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef MSG_EXP_OPTIONS_H +#define MSG_EXP_OPTIONS_H + +int OptionsInitialize( WPARAM , LPARAM ); +int nExportCompleatList(HWND hParent , bool bOnlySelected ); + +#endif \ No newline at end of file diff --git a/plugins/Msg_Export/src/resource.h b/plugins/Msg_Export/src/resource.h new file mode 100755 index 0000000000..cd12714f9a --- /dev/null +++ b/plugins/Msg_Export/src/resource.h @@ -0,0 +1,59 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// +#define IDI_EXPORT_MESSAGE 108 +#define IDD_EXPORT_ALL_DLG 110 +#define IDR_MSG_EXPORT 114 +#define IDD_FILE_VIEWER 116 +#define IDR_FV_EDIT 117 +#define IDD_OPT_MSGEXPORT2 123 +#define IDI_NOTICK 205 +#define IDI_TICK 206 +#define IDD_OPT_MSGEXPORT 999 +#define IDC_EXPORTALL 1001 +#define IDC_EXPORT_DIR 1002 +#define IDC_MAX_CLOUMN_WIDTH 1003 +#define IDC_EXPORT_TIMEFORMAT 1004 +#define IDC_EXPORT_DIR_BROWSE 1032 +#define IDC_MAP_USER_LIST 1034 +#define IDC_AUTO_FILENAME 1035 +#define IDC_CLEAR_ALL 1036 +#define IDC_EXPORT_PROGRESS 1037 +#define IDC_EXP_ALL_STATUS 1039 +#define IDC_OPEN_HELP 1041 +#define IDC_DEFAULT_FILE 1043 +#define IDC_RICHEDIT 1046 +#define IDC_USE_INTERNAL_VIEWER 1048 +#define IDC_FV_EXTERNAL 1049 +#define IDC_FV_FIND 1050 +#define IDC_REPLACE_MIRANDA_HISTORY 1054 +#define IDC_DEBUG_INFO 1060 +#define IDC_FILE_VIEWER_BROWSE 1063 +#define IDC_FILE_VIEWER 1064 +#define IDC_APPEND_NEWLINE 1065 +#define IDC_USE_LESS_AND_GREATER_IN_EXPORT 1066 +#define IDC_FC_PROMPT 1067 +#define IDC_FC_RENAME 1068 +#define IDC_FC_NOTHING 1069 +#define IDC_FD_PROMPT 1070 +#define IDC_FD_DELETE 1071 +#define IDC_FD_NOTHING 1072 +#define IDC_EXPORT_PROTOS 1073 +#define IDC_USE_UTF8_IN_NEW_FILES 1074 +#define ID_EXPORTSELECTED 40002 +#define ID_EDIT_COPY 40003 +#define ID_SET_TO_DEFAULT 40004 +#define ID_USERLIST_USERDETAILS 40005 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 124 +#define _APS_NEXT_COMMAND_VALUE 40006 +#define _APS_NEXT_CONTROL_VALUE 1075 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/Msg_Export/src/utils.cpp b/plugins/Msg_Export/src/utils.cpp new file mode 100755 index 0000000000..15ed559553 --- /dev/null +++ b/plugins/Msg_Export/src/utils.cpp @@ -0,0 +1,1738 @@ + +//This file is part of Msg_Export a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ ) +// +//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., 675 Mass Ave, Cambridge, MA 02139, USA. + + + +#include + +#include "Glob.h" +#include "Utils.h" +#include "FileViewer.h" + +#pragma warning (disable:4996) +#include +#include +#pragma warning (default:4996) + +// Default error string used upon errors +const _TCHAR *pszNickError = _T("No_Nick"); +const _TCHAR *pszGroupError = _T("No_Group"); +const _TCHAR *pszDbPathError = _T("."); + +// Replacement for chareteres not alowed in file names. +const _TCHAR cBadCharReplace = _T('_'); + +// sTimeFormat +tstring sTimeFormat; + +// path from options dialog +tstring sExportDir; + +// The default filename. Used if no other file name is specifyed in DB. +tstring sDefaultFile; + +// path used then %dbpath% is used in export file path +tstring sDBPath = pszDbPathError; + +// path to miranda exe file used when to avoid relative paths +tstring sMirandaPath = pszDbPathError; + +// Used to store the width of the user name for a file. +// if a file contains events from many users the one user name +// may be shorter. so to make all event have the same first +// column width this map contains the largest user name +map > clFileTo1ColWidth; + +// default line width +int nMaxLineWidth = 80; + +const _TCHAR *pszReplaceList[] = +{ + _T("%FirstName%") , + _T("%LastName%") , + _T("%e-mail%") , + _T("%Nick%") , + _T("%City%") , + _T("%State%") , + _T("%Phone%") , + _T("%Homepage%") , + _T("%About%") +}; +const char *pszReplaceListA[] = +{ + "FirstName" , + "LastName" , + "e-mail" , + "Nick" , + "City" , + "State" , + "Phone" , + "Homepage" , + "About" +}; + +// Alowes this plugin to replace the history function of miranda !! +bool bReplaceHistory = false; + +// This enum define the actions which MsgExport must take when a File is renamed +ENDialogAction enRenameAction = eDAPromptUser; + +// This enum define the actions which MsgExport must take when a user is delete +ENDialogAction enDeleteAction = eDAPromptUser; + +// If true MsgExport will use << and >> insted of the nick in the exported format +bool bUseLessAndGreaterInExport = false; + +bool bAppendNewLine = true; +bool bUseUtf8InNewFiles = true; + +const char szUtf8ByteOrderHeader[] = "\xEF\xBB\xBF"; +bool bIsUtf8Header( BYTE * pucByteOrder ) +{ + return memcmp( pucByteOrder , szUtf8ByteOrderHeader , 3 ) == 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : ShowDebugInfo +// Type : Global +// Parameters : None +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 021228 , 28 December 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void ShowDebugInfo() +{ + tstring sDebug = _T("Debug information\r\nsDBPath :"); + sDebug += sDBPath; + sDebug += _T("\r\nsMirandaPath :"); + sDebug += sMirandaPath; + sDebug += _T("\r\nsDefaultFile :"); + sDebug += sDefaultFile; + + sDebug += _T("\r\nGetFilePathFromUser( NULL ) :"); + sDebug += GetFilePathFromUser( NULL ); + + MessageBox( NULL , sDebug.c_str() ,MSG_BOX_TITEL,MB_OK ); +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : nGetFormatCount +// Type : Global +// Parameters : pszToCheck - ? +// Returns : int +// Description : +// +// References : - +// Remarks : - +// Created : 030107 , 07 January 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int nGetFormatCount( const _TCHAR * pszToCheck ) +{ + if( !pszToCheck || pszToCheck[0] == 0 ) + return 0; + + int nCount = 0; + for( ; pszToCheck[1] != 0 ; pszToCheck++) + { + if( pszToCheck[0] == '%' && pszToCheck[1] != '%' ) + nCount++; + } + return nCount; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : CheckedTranslate +// Type : Global +// Parameters : szEng - ? +// nFormatCount - ? +// Returns : _TCHAR * +// Description : +// +// References : - +// Remarks : - +// Created : 030107 , 07 January 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +_TCHAR * CheckedTranslate( const _TCHAR *szEng , int nFormatCount /*= -1*/ ) +{ + _TCHAR * szRet = TranslateTS( szEng ); + if( szEng == szRet ) + return (_TCHAR*)szEng; + + if( nFormatCount == -1 ) + nFormatCount = nGetFormatCount( szEng ); + + if( nFormatCount != nGetFormatCount( szRet ) ) + { + tstring sError = _T("The language pack you are using has an error in the transalation of\r\n"); + sError += szEng; + sError += _T("\r\n--------------- It was translated to ---------------\r\n"); + sError += szRet; + MessageBox( NULL , sError.c_str() ,MSG_BOX_TITEL ,MB_OK ); + return (_TCHAR*)szEng; + } + return szRet; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : sGetErrorString +// Type : Global +// Parameters : dwError - ? +// Returns : string +// Description : +// +// References : - +// Remarks : - +// Created : 021012 , 12 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +tstring sGetErrorString(DWORD dwError) +{ + LPVOID lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dwError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL ); + // Process any inserts in lpMsgBuf. + // ... + // Display the string. + tstring ret = (LPCTSTR)lpMsgBuf; + ReplaceAll( ret , _T("\r") , _T(" ")); + ReplaceAll( ret , _T("\n") , _T(" ")); + ReplaceAll( ret , _T(" ") , _T(" ")); + + // Free the buffer. + LocalFree( lpMsgBuf ); + return ret; +} + +tstring sGetErrorString() +{ + return sGetErrorString(GetLastError()); +} + +void DisplayLastError(const _TCHAR * pszError) +{ + tstring sError = pszError; + DWORD error = GetLastError(); + + _TCHAR szTemp[50]; + _sntprintf( szTemp , sizeof( szTemp ) , _T("\r\nErrorCode : %d\r\n") , error ); + sError += szTemp; + sError += sGetErrorString(error); + MessageBox( NULL , sError.c_str() ,MSG_BOX_TITEL ,MB_OK ); +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : NickFromHandle +// Type : Global +// Parameters : hContact - ? +// Returns : _TCHAR* +// Description : Reads a Nick from the database and returns a +// pointer to this. +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +const _TCHAR* NickFromHandle(HANDLE hContact) +{ + const _TCHAR * psz = (const _TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR ); + if( psz ) + return psz; + return pszNickError; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : _DBGetString +// Type : Global +// Parameters : hContact - ? +// szModule - ? +// szSetting - ? +// pszError - ? +// Returns : string +// Description : Reads a string from the database +// Just like those in database.h +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +tstring _DBGetStringW(HANDLE hContact,const char *szModule,const char *szSetting , const _TCHAR * pszError ) +{ + tstring ret; + DBVARIANT dbv = {0}; + //DBGetContactSetting + if( ! DBGetContactSettingWString( hContact , szModule , szSetting , &dbv ) ) + { + if( dbv.type != DBVT_WCHAR) + { + MessageBox(NULL,_T("DB: Attempt to get wrong type of value, string"),MSG_BOX_TITEL,MB_OK); + ret = pszError; + } + else + { + ret = (_TCHAR*)dbv.pszVal; + } + } + else + ret = pszError; + DBFreeVariant(&dbv); + return ret; +} + +string _DBGetStringA(HANDLE hContact,const char *szModule,const char *szSetting , const char * pszError ) +{ + string ret; + DBVARIANT dbv = {0}; + if( ! DBGetContactSetting( hContact , szModule , szSetting , &dbv ) ) + { + if( dbv.type != DBVT_ASCIIZ) + { + MessageBox(NULL,_T("DB: Attempt to get wrong type of value, string"),MSG_BOX_TITEL,MB_OK); + ret = pszError; + } + else + { + ret = dbv.pszVal; + } + } + else + ret = pszError; + DBFreeVariant(&dbv); + return ret; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : ReplaceAll +// Type : Global +// Parameters : sSrc - string to replace in +// pszReplace - what to replace +// sNew - the string to insert insted of pszReplace +// Returns : void +// Description : will replace all acurances of a string with another string +// used to replace %user% , and other user +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void ReplaceAll( tstring &sSrc , const _TCHAR * pszReplace , const tstring &sNew) +{ + string::size_type nCur = 0; + while( (nCur = sSrc.find(pszReplace,nCur)) != sSrc.npos ) + { + sSrc.replace( nCur , _tcslen( pszReplace ) , sNew ); + nCur += sNew.size(); + } +} + +void ReplaceAll( tstring &sSrc , const _TCHAR * pszReplace , const _TCHAR * pszNew) +{ + tstring sNew = pszNew; + ReplaceAll( sSrc , pszReplace , sNew ); +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : bCreatePathToFile +// Type : Global +// Parameters : sFilePath - File name to create path to ( file name may be empty ( i.e. c:\Folder\ ) +// Returns : Returns true if the path is created or already exists +// Description : +// +// References : - +// Remarks : - +// Created : 020525 , 25 May 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bCreatePathToFile( tstring sFilePath ) +{ + string::size_type nPos = sFilePath.rfind( '\\' ); + if( nPos != string::npos ) + { + if( nPos + 1 < sFilePath.size() ) + sFilePath.erase( nPos + 1); + } + else + { + // cant find \ + return false; + } + + // create directory + if( ! CreateDirectory( sFilePath.c_str() , NULL ) ) + { + DWORD dwE = GetLastError(); + if( dwE == 183 ) // Cannot create a file when that file already exists. + return true; + if( ! bCreatePathToFile( sFilePath.substr( 0 , nPos ) ) ) + return false; + + // try again + if( ! CreateDirectory( sFilePath.c_str() , NULL ) ) + { + return false; + } + } + return true; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bWriteToFile +// Type : Global +// Parameters : hFile - ? +// pszSrc - in UTF8 or ANSII +// nLen - ? +// Returns : Returns true if all the data was written to the file +// Description : +// +// References : - +// Remarks : - +// Created : 020629 , 29 June 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bWriteToFile( HANDLE hFile , const char * pszSrc , int nLen = -1 ) +{ + if( nLen < 0 ) + nLen = strlen( pszSrc ); + DWORD dwBytesWritten; + return WriteFile( hFile , pszSrc , nLen , &dwBytesWritten , NULL ) && (dwBytesWritten == (DWORD)nLen); +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : bWriteTextToFile +// Type : Global +// Parameters : hFile - ? +// pszSrc - ? +// bUtf8File - ? +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 060130 , 30 januar 2006 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bWriteTextToFile( HANDLE hFile , const _TCHAR * pszSrc , bool bUtf8File ,int nLen = -1 ) +{ + if( nLen < 0 ) + nLen = _tcslen( pszSrc ); + if( ! bUtf8File ) + { +#ifdef _UNICODE // We need to downgrade text to ansi + char * pszAstr = new char[nLen]; + int nAnsiLen = WideCharToMultiByte(CP_ACP, 0, pszSrc, nLen, pszAstr , nLen , NULL , NULL ); + bool bRet = bWriteToFile( hFile , pszAstr , nAnsiLen ); + delete [] pszAstr; + return bRet; +#else + return bWriteToFile( hFile , pszSrc , nLen ); +#endif + } +#ifndef _UNICODE + wchar_t * pszWstr = new wchar_t[nLen]; + if( MultiByteToWideChar(CP_ACP, 0, pszSrc, nLen, pszWstr, nLen ) != nLen ) + { + delete [] pszWstr; + return false; + } + char * pszUtf8 = new char[nLen*2];// Ansi can't generate more then this. + int nUtf8Len = WideCharToMultiByte(CP_UTF8, 0, pszWstr, nLen, pszUtf8 , nLen * 2 , NULL , NULL ); + delete [] pszWstr; + if( nUtf8Len < nLen ) // Not all was converted ? + { + delete [] pszUtf8; + return false; + } + bool bRet = bWriteToFile( hFile , pszUtf8 , nUtf8Len ); + delete [] pszUtf8; +#else + char * pszUtf8 = new char[nLen*3];// UCS-2 can't generate more then this. + int nUtf8Len = WideCharToMultiByte(CP_UTF8, 0, pszSrc, nLen, pszUtf8 , nLen * 3 , NULL , NULL ); + bool bRet = bWriteToFile( hFile , pszUtf8 , nUtf8Len ); +#endif + return bRet; +} + +#ifdef _UNICODE +bool bWriteTextToFile( HANDLE hFile , const char * pszSrc , bool bUtf8File ,int nLen = -1 ) +{ + if( nLen == -1 ) + nLen = strlen( pszSrc ); + wchar_t * pszWstr = new wchar_t[nLen]; + bool bRet = false; + if( MultiByteToWideChar(CP_ACP, 0, pszSrc, nLen, pszWstr, nLen ) == nLen ) + { + bRet = bWriteTextToFile( hFile , pszWstr , bUtf8File , nLen ); + } + return bRet; +} +#endif + + +///////////////////////////////////////////////////////////////////// +// Member Function : bWriteNewLine +// Type : Global +// Parameters : hFile - ? +// nIndent - ? +// Returns : Returns true if all the data was written to the file +// Description : +// +// References : - +// Remarks : - +// Created : 020629 , 29 June 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +const char szNewLineIndent[] = "\r\n "; +bool bWriteNewLine( HANDLE hFile , DWORD dwIndent ) +{ + if( dwIndent > sizeof( szNewLineIndent ) - 2 ) + dwIndent = sizeof( szNewLineIndent ) - 2; + return bWriteToFile( hFile , szNewLineIndent , dwIndent + 2 ); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bWriteHexToFile +// Type : Global +// Parameters : hFile - ? +// - ? +// nSize - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 021203 , 03 December 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bWriteHexToFile( HANDLE hFile , void * pData, int nSize ) +{ + char cBuf[10]; + BYTE * p = (BYTE*)pData; + for( int n = 0 ; n < nSize ; n++ ) + { + sprintf( cBuf , "%.2X " , p[n] ); + if( ! bWriteToFile( hFile , cBuf , 3 ) ) + return false; + } + return true; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : bReadMirandaDirAndPath +// Type : Global +// Parameters : None +// Returns : void +// Description : Used to set the internal path. +// Handles the reading from the mirandaboot.ini to get the %dbpath% +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + + +bool bReadMirandaDirAndPath() +{ + _TCHAR szDBPath[MAX_PATH]; + char tmp[MAX_PATH]; + TCHAR *tmp2; + _tcscpy( szDBPath , pszDbPathError ); + CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"miranda32.exe", (LPARAM)tmp); + tmp2 = mir_utf8decodeT(tmp); + sMirandaPath = tmp2; + sMirandaPath.erase(sMirandaPath.find_last_of(_T("\\"))); + CallService(MS_DB_GETPROFILEPATHT, (WPARAM)MAX_PATH - 1, (LPARAM)szDBPath); + sDBPath = szDBPath; + CallService(MS_DB_GETPROFILENAMET, (WPARAM)MAX_PATH - 1, (LPARAM)szDBPath); + sDBPath.append(_T("\\")).append(szDBPath); + sDBPath.erase(sDBPath.size()-4); + return true; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : ReplaceDBPath +// Type : Global +// Parameters : sRet - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 021020 , 20 October 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void ReplaceDBPath( tstring &sRet ) +{ + ReplaceAll( sRet , _T("%dbpath%") , sDBPath ); + // Try to firure out if it is a relative path ( ..\..\MsgExport\ ) + if( sRet.size() <= 2 || ! ( sRet[1] == ':' || + ( sRet[0] == '\\' && sRet[1] == '\\' ) ) + ) + { + // Relative path + // we will prepend the mirande exe path to avoid problems + // if the current directory changes ( User receives a file ) + sRet = sMirandaPath + sRet; + } +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : GetFilePathFromUser +// Type : Global +// Parameters : hContact - Handle to user +// Returns : string contaning the compleate file name and path +// Description : +// +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +tstring GetFilePathFromUser( HANDLE hContact ) +{ + tstring sFilePath = sExportDir + _DBGetString( hContact , MODULE , "FileName" , sDefaultFile.c_str() ); + + bool bNickUsed = sFilePath.find( _T("%nick%") ) != string::npos; + + ReplaceDefines( hContact , sFilePath ); + + tstring sNoDBPath = sFilePath; + + ReplaceTimeVariables( sFilePath ); + ReplaceDBPath( sFilePath ); + + // Previous file name check to see if it has changed !! + tstring sPrevFileName = _DBGetString( hContact , MODULE , "PrevFileName" , _T("") ); + if( sNoDBPath != sPrevFileName ) + { + if( ! sPrevFileName.empty() ) + { + ReplaceDBPath( sPrevFileName ); + + // Here we will try to avoide the (Unknown Contact) in cases where the protocol for + // this user has been removed. + if( bNickUsed && ( _tcsstr( NickFromHandle( hContact ),TranslateTS(_T("(Unknown Contact)"))) != 0) ) + { + // Then the filename must have changed from a correct path to one including the (Unknown Contact) + return sPrevFileName; + } + + // file name has changed + + if( enRenameAction != eDANothing ) + { + + // we can not use FILE_SHARE_DELETE because this is not supported by + // win 98 / ME + HANDLE hPrevFile = CreateFile( sPrevFileName.c_str() , + GENERIC_READ , + FILE_SHARE_READ | FILE_SHARE_WRITE , + NULL, + OPEN_EXISTING , + FILE_ATTRIBUTE_NORMAL , + NULL ); + + if( hPrevFile != INVALID_HANDLE_VALUE ) + { + CloseHandle( hPrevFile ); + _TCHAR szTemp[500]; + // There is a previous file we can move + // ask user ? + bool bTryRename; + + if( enRenameAction != eDAAutomatic ) + { + tstring sRemoteUser = NickFromHandle(hContact); + _sntprintf( szTemp , sizeof( szTemp ) , + CheckedTranslate(_T("File name for the user \"%s\" has changed !\n\nfrom:\t%s\nto:\t%s\n\nDo you wish to rename file ?"),3) , + sRemoteUser.c_str(), + sPrevFileName.c_str(), + sFilePath.c_str() ); + bTryRename = MessageBox( NULL , szTemp ,MSG_BOX_TITEL ,MB_YESNO ) == IDYES; + } + else + bTryRename = true; + + + if( bTryRename ) + { + if( ! MoveFile( sPrevFileName.c_str(), sFilePath.c_str() ) ) + { + // this might be because the new path isent created + // so we will try to create it + bCreatePathToFile( sFilePath ); + + while( ! MoveFile( sPrevFileName.c_str(), sFilePath.c_str() ) ) + { + _sntprintf( szTemp , sizeof( szTemp ) , + CheckedTranslate(_T("Failed to rename file\n\nfrom:\t%s\nto:\t%s\n\nFailed with error: %s"),3) , + sPrevFileName.c_str(), + sFilePath.c_str() , + sGetErrorString().c_str() ); + + if( MessageBox( NULL , szTemp ,MSG_BOX_TITEL,MB_RETRYCANCEL ) != IDRETRY ) + break; + } + } + } + } + } + } + + // Store the Filename used so that we can check if it changes. + DBWriteContactSettingTString( hContact , MODULE , "PrevFileName" , sNoDBPath.c_str() ); + } + + return sFilePath; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : FileNickFromHandle +// Type : Global +// Parameters : hContact - ? +// Returns : string +// Description : Replaceses invalid file name chars +// References : - +// Remarks : - +// Created : 030107 , 07 January 2003 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +tstring FileNickFromHandle( HANDLE hContact) +{ + tstring ret = NickFromHandle( hContact ); + string::size_type nCur = 0; + while( (nCur = ret.find_first_of(_T(":\\"),nCur)) != ret.npos ) + ret[nCur] = cBadCharReplace; + return ret; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : ReplaceAllNoColon +// Type : Global +// Parameters : sSrc - ? +// pszReplace - ? +// sNew - ? +// Returns : void +// Description : Removes any ':' in the new string +// +// References : - +// Remarks : - +// Created : 040205 , 05 februar 2004 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void ReplaceAllNoColon( tstring &sSrc , const _TCHAR * pszReplace , tstring &sNew) +{ + tstring::size_type nCur = 0; + while( (nCur = sNew.find_first_of(_T(':'),nCur)) != sNew.npos ) + sNew[nCur] = cBadCharReplace; + ReplaceAll( sSrc , pszReplace , sNew ); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : ReplaceDefines +// Type : Global +// Parameters : hContact - Handle to user +// sTarget - String with either %user% or %UIN%, to replace in +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 020525 , 25 May 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void ReplaceDefines( HANDLE hContact , tstring & sTarget ) +{ + if( sTarget.find( _T("%nick%") ) != string::npos ) + { + ReplaceAll( sTarget , _T("%nick%") , FileNickFromHandle( hContact ) ); + } + + bool bUINUsed = sTarget.find( _T("%UIN%") ) != string::npos; + bool bEMailUsed = sTarget.find( _T("%e-mail%") ) != string::npos; + bool bProtoUsed = sTarget.find( _T("%protocol%") ) != string::npos; + bool bIdentifierUsed = sTarget.find( _T("%identifier%") ) != string::npos; + + if( bUINUsed || bEMailUsed || bProtoUsed || bIdentifierUsed ) + { + string sProto = _DBGetStringA( hContact , "Protocol" , "p" , "" ); + if( bUINUsed || ( bIdentifierUsed && sProto == "ICQ" ) ) + { + DWORD dwUIN = DBGetContactSettingDword(hContact, sProto.c_str(), "UIN", 0); + tstring sReplaceUin; + if( dwUIN ) + { + _TCHAR sTmp[20]; + _sntprintf( sTmp , sizeof( sTmp ) ,_T("%d") , dwUIN ); + sReplaceUin = sTmp; + } + else + { + sReplaceUin = FileNickFromHandle( hContact ); + } + + if( bUINUsed ) + ReplaceAll( sTarget , _T("%UIN%") , sReplaceUin ); + if( bIdentifierUsed && sProto == "ICQ" ) + { + bIdentifierUsed = false; + ReplaceAll( sTarget , _T("%identifier%") , sReplaceUin ); + } + } + + if( bEMailUsed || ( bIdentifierUsed && sProto == "MSN")) + { + tstring sEMail = _DBGetString( hContact , sProto.c_str() , "e-mail" , _T("") ); + if( sEMail.empty() ) + { + sEMail = _DBGetString( hContact , "MSN" , "e-mail" , _T("") ); + if( sEMail.empty() ) + { + // We can't finde the E-mail address we will use the the nick + sEMail = FileNickFromHandle( hContact ); + } + } + if( bEMailUsed ) + ReplaceAllNoColon( sTarget , _T("%e-mail%") , sEMail ); + if( bIdentifierUsed && sProto == "MSN") + { + bIdentifierUsed = false; + ReplaceAllNoColon( sTarget , _T("%identifier%") , sEMail ); + } + } + if( bIdentifierUsed && sProto == "Jabber" ) + { + tstring sReplace = _DBGetString( hContact , "Jabber" , "jid" , _T("") ); + if( sReplace.empty() ) + { + sReplace = FileNickFromHandle( hContact ); + } + bIdentifierUsed = false; + ReplaceAll( sTarget , _T("%identifier%") , sReplace ); + } + if( bProtoUsed ) + { + tstring tmp = _DBGetString( hContact , "Protocol" , "p" , _T("") ); + ReplaceAllNoColon( sTarget , _T("%protocol%") , tmp ); + } + if( bIdentifierUsed ) + { + // It has still not been replaced we will just use nick + ReplaceAll( sTarget , _T("%nick%") , FileNickFromHandle( hContact ) ); + } + } + + if( sTarget.find( _T("%group%") ) != string::npos ) + { + tstring sGroup = _DBGetString( hContact , "CList" , "Group" , _T("") ); + ReplaceAllNoColon( sTarget , _T("%group%") , sGroup ); + } + + // We can't replace the : here because if the user uses C:\... in the file path + // this will also be replaced + string::size_type nCur = 0; + while( (nCur = sTarget.find_first_of(_T("/*?<>|\""),nCur)) != sTarget.npos ) + sTarget[nCur] = cBadCharReplace; + +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : ReplaceTimeVariables +// Type : Global +// Parameters : sRet - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 040219 , 19 februar 2004 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void ReplaceTimeVariables( tstring &sRet ) +{ + if( sRet.find( _T("%year%") ) != string::npos || + sRet.find( _T("%month%") ) != string::npos || + sRet.find( _T("%day%") ) != string::npos ) + { + SYSTEMTIME stTime; + GetLocalTime( &stTime ); + _TCHAR sTmp[20]; + + _sntprintf( sTmp , sizeof( sTmp ) ,_T("%d") , stTime.wYear ); + ReplaceAll( sRet , _T("%year%") , sTmp ); + _sntprintf( sTmp , sizeof( sTmp ) ,_T("%.2d") , stTime.wMonth ); + ReplaceAll( sRet , _T("%month%") , sTmp ); + _sntprintf( sTmp , sizeof( sTmp ) ,_T("%.2d") , stTime.wDay ); + ReplaceAll( sRet , _T("%day%") , sTmp ); + } +} + +///////////////////////////////////////////////////////////////////// +// Member Function : UpdateFileToColWidth +// Type : Global +// Parameters : None +// Returns : void +// Description : updates clFileTo1ColWidth, +// +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void UpdateFileToColWidth() +{ + clFileTo1ColWidth.clear(); + + HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + for(;;) + { + tstring sNick = NickFromHandle( hContact ); + string::size_type &rnValue = clFileTo1ColWidth[ GetFilePathFromUser( hContact ) ]; + if( rnValue < sNick.size() ) + rnValue = sNick.size(); + + if( ! hContact ) + break; + + hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); + } +} + + + +///////////////////////////////////////////////////////////////////// +// Member Function : DisplayErrorDialog +// Type : Global +// Parameters : pszError - ? +// sFile - ? +// dbei - ? +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 021203 , 03 December 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void DisplayErrorDialog( const _TCHAR * pszError , tstring& sFilePath , DBEVENTINFO * dbei ) +{ + tstring sError = TranslateTS( pszError ); + sError += sFilePath; + sError += _T("\nError :"); + sError += sGetErrorString(); + sError += _T("\n"); + sError += TranslateTS(_T("Message has not been saved !\n")); + sError += TranslateTS(_T("Do you wish to save debug information ?")); + if( MessageBox( NULL , sError.c_str() ,MSG_BOX_TITEL,MB_YESNO ) == IDYES ) + { + OPENFILENAME ofn; // common dialog box structure + _TCHAR szFile[260]; // buffer for file name + _tcscpy( szFile , _T("DebugInfo.txt") ); + + // Initialize OPENFILENAME + ZeroMemory(&ofn, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + //ofn.hwndOwner = NULL; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrFilter = _T("All\0*.*\0Text\0*.TXT\0\0"); + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.Flags = 0 /*OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST*/; + ofn.lpstrDefExt = _T("TXT"); + + // Display the Open dialog box. + + if( GetSaveFileName(&ofn) ) + { + HANDLE hf; // file handle + hf = CreateFile(ofn.lpstrFile, GENERIC_WRITE, + 0, (LPSECURITY_ATTRIBUTES) NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, + (HANDLE) NULL); + + bWriteTextToFile( hf , sError.c_str() , false ); + if( dbei ) + { + bWriteToFile( hf , "\r\ndbei :" ); + + bWriteHexToFile( hf , dbei , sizeof( DBEVENTINFO )); + if( dbei->pBlob ) + { + bWriteToFile( hf , "\r\ndbei.pBlob :" ); + bWriteHexToFile( hf , dbei->pBlob , min( dbei->cbBlob , 10000 )); + } + if( dbei->szModule ) + { + bWriteToFile( hf , "\r\ndbei.szModule :" ); + bWriteToFile( hf , dbei->szModule ); + } + } + CloseHandle( hf ); + } + } +} + +///////////////////////////////////////////////////////////////////// +// Member Function : ExportDBEventInfo +// Type : Global +// Parameters : hContact - handle to contact +// dbei - Event to export +// Returns : void +// Description : +// +// References : - +// Remarks : - +// Created : 050429 , 29 april 2005 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void ExportDBEventInfo(HANDLE hContact, DBEVENTINFO &dbei ) +{ + _TCHAR szTemp[500]; + tstring sFilePath = GetFilePathFromUser( hContact ); + + GetLastError();// Clear last error !! + + HANDLE hFile = CreateFile( sFilePath.c_str() , GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ , 0 ,OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ); + if( hFile == INVALID_HANDLE_VALUE ) + { + // this might be because the path isent created + // so we will try to create it + if( bCreatePathToFile( sFilePath ) ) + { + hFile = CreateFile( sFilePath.c_str() , GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ , 0 ,OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ); + } + } + + if( hFile == INVALID_HANDLE_VALUE ) + { + DisplayErrorDialog( _T("Failed to open or create file :\n") , sFilePath , NULL ); + return; + } + + tstring sLocalUser; + tstring sRemoteUser; + string::size_type nFirstColumnWidth; + + if( bUseLessAndGreaterInExport ) + { + sLocalUser = _T("<<"); + sRemoteUser = _T(">>"); + nFirstColumnWidth = 4; + } + else + { + sLocalUser = NickFromHandle(0); + sRemoteUser = NickFromHandle(hContact); + nFirstColumnWidth = max( sRemoteUser.size() , clFileTo1ColWidth[sFilePath] ); + nFirstColumnWidth = max( sLocalUser.size() , nFirstColumnWidth ); + nFirstColumnWidth += 2; + } + + bool bWriteUTF8Format = false; + + { + DWORD dwLowSize; + DWORD dwHighSize = 0; + + dwLowSize = GetFileSize( hFile , &dwHighSize ); + + if( dwLowSize == INVALID_FILE_SIZE || dwLowSize != 0 || dwHighSize != 0 ) + { + DWORD dwDataRead = 0; + BYTE ucByteOrder[3]; + if( ReadFile( hFile , ucByteOrder , 3 , &dwDataRead , NULL ) ) + { + bWriteUTF8Format = bIsUtf8Header( ucByteOrder ); + } + DWORD dwPtr = SetFilePointer( hFile , 0 , 0 , FILE_END ); + if( dwPtr == INVALID_SET_FILE_POINTER ) + { + // we need to aborte mission here because if we continue we risk + // overwriting old log. + DisplayErrorDialog( _T("Failed to move to the end of the file :\n") , sFilePath , NULL ); + CloseHandle( hFile ); + return; + } + } + else + { + bWriteUTF8Format = bUseUtf8InNewFiles; + if( bWriteUTF8Format ) + { + if( ! bWriteToFile( hFile , szUtf8ByteOrderHeader, sizeof( szUtf8ByteOrderHeader ) - 1 ) ) + { + DisplayErrorDialog( _T("Failed to UTF8 byte order code to file :\n") , sFilePath , NULL ); + CloseHandle( hFile ); + return; + } + } + tstring output = _T("------------------------------------------------\r\n") + _T(" History for\r\n") + _T("User : %User%\r\n") + _T("Protocol : %Proto%\r\n") + _T("UIN : %UIN%\r\n") + _T("FirstName : %FirstName%\r\n") + _T("LastName : %LastName%\r\n") + _T("Age : %Age%\r\n") + _T("Gender : %Gender%\r\n") + _T("e-mail : %e-mail%\r\n") + _T("Nick : %Nick% \r\n") + _T("City : %City%\r\n") + _T("State : %State%\r\n") + _T("Phone : %Phone%\r\n") + _T("Homepage : %Homepage%\r\n") + _T("- About -\r\n%About%\r\n") + _T("------------------------------------------------\r\n"); + + // This is written this way because I expect this will become a string the user may set + // in the options dialog. + ReplaceAll( output , _T("%User%") , sRemoteUser ); + + string sProto = _DBGetStringA( hContact , "Protocol" , "p" , "" ); + ReplaceAll( output , _T("%Proto%") , _DBGetString( hContact , "Protocol" , "p" , _T("") ) ); + + for( int nCur = 0 ; nCur < 9 ; nCur++ ) + { + ReplaceAll( output , pszReplaceList[nCur] , _DBGetString( hContact , sProto.c_str() , pszReplaceListA[nCur] , _T("") ) ); + } + + _sntprintf( szTemp , sizeof( szTemp ) , _T("%d") , DBGetContactSettingDword(hContact, sProto.c_str(), "UIN", 0) ); + ReplaceAll( output , _T("%UIN%") , szTemp ); + + _sntprintf( szTemp , sizeof( szTemp ) , _T("%d") , DBGetContactSettingWord(hContact, sProto.c_str(), "Age", 0)); + ReplaceAll( output , _T("%Age%") , szTemp ); + + szTemp[0] = (_TCHAR)DBGetContactSettingByte(hContact, sProto.c_str(), "Gender", 0); + szTemp[1] = 0; + ReplaceAll( output , _T("%Gender%") , szTemp ); + + if( ! bWriteTextToFile( hFile , output.data(), bWriteUTF8Format, output.size() ) ) + { + DisplayErrorDialog( _T("Failed to write user details to file :\n") , sFilePath , NULL ); + CloseHandle( hFile ); + return; + } + } + } + + int nIndent; + { // Get time stamp + + nIndent = _sntprintf( szTemp , sizeof( szTemp ) , _T("%-*s") , + nFirstColumnWidth , + dbei.flags & DBEF_SENT ? sLocalUser.c_str() : sRemoteUser.c_str() ); + + DBTIMETOSTRINGT dbtts; + dbtts.cbDest = sizeof(szTemp) - nIndent - 2; + dbtts.szDest = &szTemp[nIndent]; + dbtts.szFormat = (_TCHAR*)sTimeFormat.c_str(); +#ifdef _UNICODE + CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT,dbei.timestamp,(LPARAM)&dbtts); +#else + CallService(MS_DB_TIME_TIMESTAMPTOSTRING,dbei.timestamp,(LPARAM)&dbtts); +#endif + nIndent = _tcslen( szTemp ); + szTemp[nIndent++] = ' '; + + // Write first part of line with name and timestamp + if( ! bWriteTextToFile( hFile , szTemp , bWriteUTF8Format , nIndent ) ) + { + DisplayErrorDialog( _T("Failed to write timestamp and username to file :\n") , sFilePath , &dbei ); + CloseHandle( hFile ); + return; + } + } + + if( dbei.pBlob != NULL && dbei.cbBlob >= 2 ) + { + dbei.pBlob[ dbei.cbBlob ] = 0; + + switch(dbei.eventType) + { + case EVENTTYPE_MESSAGE: + { + TCHAR* msg = DbGetEventTextT( &dbei, CP_ACP ); + if( ! bWriteIndentedToFile( hFile , nIndent , msg , bWriteUTF8Format ) ) + { + DisplayErrorDialog( _T("Failed to write message to the file :\n") , sFilePath , &dbei ); + } + mir_free(msg); + break; +/* + const char * pszData = (const char*)dbei.pBlob; + bool bConvertedToUtf8 = false; + if( bWriteUTF8Format )// Write UTF-8 format in file ? + { + int nAnsiLen = strlen((char *) dbei.pBlob)+1; + if( nAnsiLen < (int)dbei.cbBlob ) + { + // Message is also encoded in unicode UTF-16/UCS-2, little endian. + if( WideCharToMultiByte( CP_UTF8 , 0 , (wchar_t*)&dbei.pBlob[ nAnsiLen ] , nAnsiLen , szTemp , sizeof(szTemp) , 0 , 0 ) ) + { + pszData = szTemp; + bConvertedToUtf8 = true; + } + } + // We need to write in UTF8 format so we have to convert ansi string to UTF8 + } + if( ! bWriteIndentedToFile( hFile , nIndent , pszData , bWriteUTF8Format ) ) + { + DisplayErrorDialog( _T("Failed to write message to the file :\n") , sFilePath , &dbei ); + } + break;*/ + } + case EVENTTYPE_URL: + case EVENTTYPE_FILE: + { + const _TCHAR * pszType; + const char * pszData; + + if( dbei.eventType == EVENTTYPE_URL ) + { + pszType = TranslateTS(_T("URL: ")); + pszData = (char *)dbei.pBlob; + } + else + { + pszType = TranslateTS(_T("File: ")); + pszData = (char *)(dbei.pBlob + sizeof( DWORD )); + } + + bool bWriteOk = false; + + int nLen = strlen( pszData ); + if( (pszData - (char *)dbei.pBlob) + nLen < (int)dbei.cbBlob ) + { + if( bWriteTextToFile( hFile , pszType , bWriteUTF8Format ) && + bWriteIndentedToFile( hFile , nIndent , pszData , bWriteUTF8Format ) ) + { + pszData += nLen + 1; + if( (pszData - (char *)dbei.pBlob) >= (int)dbei.cbBlob ) + { + bWriteOk = true; + } + else + { + nLen = strlen( pszData ); + if( (pszData - (char *)dbei.pBlob) + nLen < (int)dbei.cbBlob ) + { + if( bWriteNewLine( hFile , nIndent ) && + bWriteTextToFile( hFile , TranslateTS(_T("Description: ")) , bWriteUTF8Format) && + bWriteIndentedToFile( hFile , nIndent , pszData , bWriteUTF8Format ) ) + { + bWriteOk = true; + } + } + } + } + } + + if( ! bWriteOk ) + DisplayErrorDialog( _T("Failed to write URL/File to the file :\n") , sFilePath , &dbei ); + break; + } + case EVENTTYPE_AUTHREQUEST: + case EVENTTYPE_ADDED: + { + const _TCHAR * pszTypes[] = { + _T("Nick :"), + _T("FirstName :"), + _T("LastName :"), + _T("e-mail :"), + _T("Reason :")}; + + /*// test code + dbei.pBlob = (BYTE*)("\xED\xA8\x29\x09nick\0first\0last\0email"); + dbei.cbBlob = 26; + */ + + if( dbei.cbBlob < 8 || dbei.cbBlob > 5000 ) + { + int n = _sntprintf( szTemp , sizeof( szTemp ) ,_T("Invalid Database event received. Type %d, size %d"),dbei.eventType, dbei.cbBlob ); + if( ! bWriteTextToFile( hFile , szTemp , bWriteUTF8Format , n ) ) + DisplayErrorDialog( _T("Failed to write Invalid Database event the file :\n") , sFilePath , &dbei ); + break; + } + + bool bWriteOk = false; + + int nStringCount; + const _TCHAR * pszTitle; + if( dbei.eventType == EVENTTYPE_AUTHREQUEST ) + { // request + //blob is: uin(DWORD), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ), reason(ASCIIZ) + nStringCount = 5; + pszTitle = TranslateTS(_T("The following user made an authorization request:")); + } + else + { // Added + //blob is: uin(DWORD), nick(ASCIIZ), first(ASCIIZ), last(ASCIIZ), email(ASCIIZ) + nStringCount = 4; + pszTitle = TranslateTS(_T("The following user added you to their contact list:")); + } + + if( bWriteTextToFile( hFile , pszTitle , bWriteUTF8Format ) && + bWriteNewLine( hFile , nIndent ) && + bWriteTextToFile( hFile , TranslateTS(_T("UIN :")) , bWriteUTF8Format ) ) + { + DWORD uin = *((PDWORD)(dbei.pBlob)); + int n = _sntprintf( szTemp , sizeof( szTemp ) ,_T("%d"), uin ); + if( bWriteTextToFile( hFile , szTemp , bWriteUTF8Format , n ) ) + { + char * pszCurBlobPos = (char *) (dbei.pBlob + sizeof( DWORD )); + char * pszEnd = (char *) (dbei.pBlob + dbei.cbSize); + for( int n = 0 ; n < nStringCount && pszCurBlobPos < pszEnd ; n++ ) + { + if( *pszCurBlobPos ) + { + if( ! bWriteNewLine( hFile , nIndent ) || + ! bWriteTextToFile( hFile , TranslateTS(pszTypes[ n ]) , bWriteUTF8Format ) || + ! bWriteIndentedToFile( hFile , nIndent , pszCurBlobPos , bWriteUTF8Format ) ) + { + break; + } + pszCurBlobPos += strlen( pszCurBlobPos ); + } + pszCurBlobPos++; + } + bWriteOk = true; + } + } + + if( ! bWriteOk ) + DisplayErrorDialog( _T("Failed to write AUTHREQUEST or ADDED to the file :\n") , sFilePath , &dbei ); + + break; + } + case ICQEVENTTYPE_EMAILEXPRESS: + case ICQEVENTTYPE_WEBPAGER: + { + //e-mail express + //db event added to NULL contact + //blob format is: + //ASCIIZ text, usually of the form "Subject: %s\r\n%s" + //ASCIIZ from name + //ASCIIZ from e-mail + + //www pager + //db event added to NULL contact + //blob format is: + //ASCIIZ text, usually "Sender IP: xxx.xxx.xxx.xxx\r\n%s" + //ASCIIZ from name + //ASCIIZ from e-mail + const char* pszStr = (const char*)dbei.pBlob; + + if( dbei.eventType == ICQEVENTTYPE_EMAILEXPRESS ) + bWriteTextToFile( hFile , TranslateTS(_T("EmailExpress from:")) , bWriteUTF8Format); + else + bWriteTextToFile( hFile , TranslateTS(_T("WebPager from:")) , bWriteUTF8Format ); + + bWriteNewLine( hFile , nIndent ); + + size_t nMsgLenght = strlen( pszStr ) + 1; + if( nMsgLenght < dbei.cbBlob ) + { + size_t nFriendlyLen = strlen( &pszStr[nMsgLenght] ); + bWriteTextToFile( hFile , &pszStr[nMsgLenght] , bWriteUTF8Format , nFriendlyLen ); + size_t nEmailOffset = nMsgLenght + nFriendlyLen + 1; + if( nEmailOffset < dbei.cbBlob ) + { + bWriteTextToFile( hFile , _T("<") , bWriteUTF8Format ); + size_t nEmailLen = strlen( &pszStr[nEmailOffset] ); + bWriteTextToFile( hFile , &pszStr[nEmailOffset] , bWriteUTF8Format , nEmailLen ); + bWriteTextToFile( hFile , _T(">") , bWriteUTF8Format ); + } + } + else + { + bWriteTextToFile( hFile , TranslateTS(_T("No from address")) , bWriteUTF8Format ); + } + + if( ! bWriteNewLine( hFile , nIndent ) || + ! bWriteIndentedToFile( hFile , nIndent , pszStr , bWriteUTF8Format ) ) + { + DisplayErrorDialog( _T("Failed to write EmailExpress to the file :\n") , sFilePath , &dbei ); + } + break; + } + case ICQEVENTTYPE_SMS: + { + if( ! bWriteIndentedToFile( hFile , nIndent , (const char*)dbei.pBlob , bWriteUTF8Format ) ) + { + DisplayErrorDialog( _T("Failed to write SMS to the file :\n") , sFilePath , &dbei ); + } + break; + } + default: + { + int n = _sntprintf( szTemp , sizeof( szTemp ) ,_T("Unknown event type %d, size %d") , dbei.eventType, dbei.cbBlob ); + if( ! bWriteTextToFile( hFile , szTemp , bWriteUTF8Format , n ) ) + { + DisplayErrorDialog( _T("Failed to write Unknown event to the file :\n") , sFilePath , &dbei ); + } + break; + } + } + } + else + { + int n = _sntprintf( szTemp , sizeof( szTemp ) ,_T("Unknown event type %d, size %d") , dbei.eventType, dbei.cbBlob ); + bWriteTextToFile( hFile , szTemp , bWriteUTF8Format , n ); + } + bWriteToFile( hFile , bAppendNewLine ? "\r\n\r\n" : "\r\n" ); + + CloseHandle( hFile ); + + UpdateFileViews( sFilePath.c_str() ); +} + +///////////////////////////////////////////////////////////////////// +// Member Function : nExportEvent +// Type : Global +// Parameters : wparam - handle to contact +// lparam - handle to the new DB event +// Returns : int +// Description : Called when an event is added to the DB +// Or from the Export All funktion +// References : - +// Remarks : - +// Created : 020422 , 22 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + + +int nExportEvent(WPARAM wparam,LPARAM lparam) +{ + HANDLE hContact = (HANDLE)wparam; + + if( ! DBGetContactSettingByte(hContact,MODULE,"EnableLog",1) ) + return 0; + + DBEVENTINFO dbei={0}; + dbei.cbSize=sizeof(dbei); + char szTemp[500]; + + { // Get Blob data size + + int nSize = CallService(MS_DB_EVENT_GETBLOBSIZE,(WPARAM)lparam,0); + if( nSize > 0 ) + { + dbei.cbBlob = nSize; + dbei.pBlob = (PBYTE)malloc(dbei.cbBlob + 2 ); + dbei.pBlob[dbei.cbBlob] = 0; + dbei.pBlob[dbei.cbBlob+1] = 0; + // Double null terminate, this shut pervent most errors + // where the blob received has an invalid format + } + // else dbei.cbBlob will be 0 + } + + if( ! CallService(MS_DB_EVENT_GET,(WPARAM)lparam,(LPARAM)&dbei) ) + { + if( dbei.eventType != EVENTTYPE_STATUSCHANGE ) + { + _snprintf( szTemp , sizeof( szTemp ) , "DisableProt_%s" , dbei.szModule ); + if( DBGetContactSettingByte(NULL,MODULE,szTemp,1) ) + { + ExportDBEventInfo( hContact , dbei ); + } + } + } + if( dbei.pBlob ) + free(dbei.pBlob); + return 0; +} + +#ifdef _UNICODE +bool bWriteIndentedToFile( HANDLE hFile , int nIndent , const char * pszSrc , bool bUtf8File ) +{ + int nLen = strlen( pszSrc ); + wchar_t * pszWstr = new wchar_t[nLen+1]; + bool bRet = false; + if( MultiByteToWideChar(CP_ACP, 0, pszSrc, nLen, pszWstr, nLen ) == nLen ) + { + pszWstr[nLen] = NULL; + bRet = bWriteIndentedToFile( hFile , nIndent , pszWstr , bUtf8File ); + } + return bRet; +} +#endif + +///////////////////////////////////////////////////////////////////// +// Member Function : bWriteIndentedToFile +// Type : Global +// Parameters : hFile - ? +// nIndent - ? +// pszSrc - +// Returns : Returns true if +// Description : +// +// References : - +// Remarks : - +// Created : 020629 , 29 June 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +bool bWriteIndentedToFile( HANDLE hFile , int nIndent , const _TCHAR * pszSrc , bool bUtf8File ) +{ + bool bOk = true; + bool bFirstLine = true; + + while( *pszSrc ) + { // first we will scan forward in string to finde either new line or "max line with" + int nLineLen = 0; + do + { +/* if( bUtf8Src ) + { // need to do some stuff here + }*/ + if( pszSrc[nLineLen] == _T('\n') || pszSrc[nLineLen] == _T('\r')) + { // the line naturly broken here stop scan + break; + } + + if( nLineLen >= nMaxLineWidth ) + { // ok the line was not broken. we need to force a break + // we will scan backwards again to finde a space !! + // then we will look for a ? and so on. + + const _TCHAR ac[] = { _T(' '),_T('?'),_T('-'),_T('.'),_T(',') }; + for( int y = 0 ; y < sizeof( ac ) ; y++) + { + for( int n = nLineLen ; n > 0 ; n-- ) + { + if( pszSrc[n] == ac[y] ) + { + nLineLen = n; + goto SuperBreak; + } + } + } + break; + } + nLineLen++; + } + while( pszSrc[nLineLen] ); + + // trim away traling spaces !! + if( nLineLen > 0 ) + { + while( pszSrc[nLineLen-1] == ' ' ) + nLineLen--; + } + +SuperBreak: + + + // nLineLen should contain the number af chars we need to write to the file + if( nLineLen > 0 ) + { + if( !bFirstLine ) + { + if( ! bWriteNewLine( hFile , nIndent ) ) + { + bOk = false; + } + } +/* if( bUtf8Src ) + { + // Programming error writing UTF8 string to ansi file + if( ! bUtf8File ) + { + MessageBox( NULL , _T("Programming error writing UTF8 string to ansi file") ,MSG_BOX_TITEL,MB_OK ); + // bUtf8File must be true here + } + if( !bWriteToFile( hFile , pszSrc , nLineLen ) ) + { + bOk = false; + } + } + else*/ + {// Text format !! + if( ! bWriteTextToFile( hFile , pszSrc , bUtf8File , nLineLen ) ) + bOk = false; + } + } + bFirstLine = false; + + // skip any noice chars, MAC style '\r' '\r' '\n' + // and excess spaces + const _TCHAR * pszPrev = pszSrc; + pszSrc += nLineLen; + while( *pszSrc == _T(' ') || *pszSrc == _T('\n') || *pszSrc == _T('\r') ) + pszSrc++; + + if( pszPrev == pszSrc ) + { + // this is an programming error we have not moved forward in string + MessageBox( NULL , _T("Programming error on line __LINE__ please report this") ,MSG_BOX_TITEL,MB_OK ); + break; + } + } + + // if bOk if false file writing failed + return bOk; +} + + +///////////////////////////////////////////////////////////////////// +// Member Function : nContactDeleted +// Type : Global +// Parameters : wparam - handle to the deleted Contact +// lparam - 0 +// Returns : int +// Description : Called when an contact is about to be deleted +// +// References : - +// Remarks : - +// Created : 021222 , 22 December 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +int nContactDeleted(WPARAM wparam,LPARAM /*lparam*/) +{ + if( enDeleteAction == eDANothing ) + return 0; + + HANDLE hContact = (HANDLE)wparam; + + tstring sFilePath = GetFilePathFromUser( hContact ); + + { // Test if there is another user using this file + HANDLE hOtherContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + for(;;) + { + if( hContact != hOtherContact && sFilePath == GetFilePathFromUser( hOtherContact ) ) + { + return 0; // we found another contact abort mission :-) + } + + if( ! hOtherContact ) + break; + hOtherContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hOtherContact, 0); + } + } + + // Test to see if there is a file to delete + HANDLE hPrevFile = CreateFile( sFilePath.c_str() , + GENERIC_READ , + FILE_SHARE_READ | FILE_SHARE_WRITE , + NULL, + OPEN_EXISTING , + FILE_ATTRIBUTE_NORMAL , + NULL ); + + if( hPrevFile != INVALID_HANDLE_VALUE ) + { + CloseHandle( hPrevFile ); + + _TCHAR szTemp[500]; + _sntprintf( szTemp , sizeof( szTemp ) , _T("%s\r\n%s") , + TranslateTS(_T("User has been deleted do you want to delete the file ?")) , + sFilePath.c_str() ); + + if( enDeleteAction == eDAAutomatic || + MessageBox( NULL , szTemp ,MSG_BOX_TITEL,MB_YESNO ) == IDYES ) + { + if( ! DeleteFile( sFilePath.c_str() ) ) + { + _sntprintf( szTemp , sizeof( szTemp ) , + _T("%s\r\n%s"), + TranslateTS(_T("Failed to delete the file")), + sFilePath.c_str() ); + + DisplayLastError( szTemp ); + } + } + } + return 0; +} + +///////////////////////////////////////////////////////////////////// +// Member Function : SaveSettings +// Type : Global +// Parameters : None +// Returns : void +// Description : Save Settings +// +// References : - +// Remarks : - +// Created : 020429 , 29 April 2002 +// Developer : KN +///////////////////////////////////////////////////////////////////// + +void SaveSettings() +{ + DBWriteContactSettingWord( NULL , MODULE , "MaxLineWidth" , (WORD) nMaxLineWidth ); + DBWriteContactSettingTString( NULL , MODULE , "ExportDir" , sExportDir.c_str() ); + DBWriteContactSettingTString( NULL , MODULE , "DefaultFile" , sDefaultFile.c_str() ); + DBWriteContactSettingTString( NULL , MODULE , "TimeFormat" , sTimeFormat.c_str() ); + + DBWriteContactSettingTString( NULL , MODULE , "FileViewerPrg" , sFileViewerPrg.c_str() ); + DBWriteContactSettingByte( NULL , MODULE , "UseInternalViewer" , bUseInternalViewer() ); + DBWriteContactSettingByte( NULL , MODULE , "ReplaceHistory" , bReplaceHistory ); + DBWriteContactSettingByte( NULL , MODULE , "AppendNewLine" , bAppendNewLine ); + DBWriteContactSettingByte( NULL , MODULE , "UseUtf8InNewFiles" , bUseUtf8InNewFiles ); + DBWriteContactSettingByte( NULL , MODULE , "UseLessAndGreaterInExport" , bUseLessAndGreaterInExport ); + + DBWriteContactSettingByte( NULL , MODULE , "RenameAction" , (BYTE)enRenameAction ); + DBWriteContactSettingByte( NULL , MODULE , "DeleteAction" , (BYTE)enDeleteAction ); +} + diff --git a/plugins/Msg_Export/src/utils.h b/plugins/Msg_Export/src/utils.h new file mode 100755 index 0000000000..f2ca584cde --- /dev/null +++ b/plugins/Msg_Export/src/utils.h @@ -0,0 +1,125 @@ + +//This file is part of Msg_Export a Miranda IM plugin +//Copyright (C)2002 Kennet Nielsen ( http://sourceforge.net/projects/msg-export/ ) +// +//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., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef MSG_EXP_UTILS_H +#define MSG_EXP_UTILS_H + +#include + +#if defined ( _MSC_VER ) // A Microsoft C Compiler + #ifdef _DEBUG // The _ASSERT macro contains a constant expression + #pragma warning( disable : 4786 ) + #endif +#endif // defined ( _MSC_VER ) + +#pragma warning (push, 3 ) +#pragma warning (disable:4996) + +#include "stdio.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EVENTTYPE_STATUSCHANGE 25368 + +#include +#include +#include +#pragma warning (default:4996) +#pragma warning (pop) + +using namespace std; + +#ifdef _UNICODE + #define tstring wstring + #define _DBGetString _DBGetStringW +#else + #define tstring string + #define _DBGetString _DBGetStringA +#endif + +enum ENDialogAction +{ + eDAPromptUser, + eDAAutomatic, + eDANothing +}; + +extern ENDialogAction enRenameAction; +extern ENDialogAction enDeleteAction; + +extern int nMaxLineWidth; +extern tstring sExportDir; +extern tstring sDefaultFile; +extern tstring sTimeFormat; +extern map > clFileTo1ColWidth; + +extern bool bAppendNewLine; +extern bool bUseUtf8InNewFiles; +extern bool bUseLessAndGreaterInExport; + +extern bool bReplaceHistory; + +tstring sGetErrorString(DWORD dwError); +tstring sGetErrorString(); +void DisplayLastError(const _TCHAR * pszError); + +_TCHAR * CheckedTranslate( const _TCHAR *szEng , int nFormatCount = -1 ); + +void SaveSettings(); +void ShowDebugInfo(); + +int nExportEvent(WPARAM wparam,LPARAM lparam); +int nContactDeleted(WPARAM wparam,LPARAM lparam); + +const _TCHAR *NickFromHandle(HANDLE hContact); + +tstring __inline _DBGetStringW(HANDLE hContact,const char *szModule,const char *szSetting , const _TCHAR * pszError ); +string __inline _DBGetStringA(HANDLE hContact,const char *szModule,const char *szSetting , const char * pszError ); + +void ReplaceAll( tstring &sSrc , const _TCHAR * pszReplace , const tstring &sNew); +void ReplaceAll( tstring &sSrc , const _TCHAR * pszReplace , const _TCHAR * pszNew); + +void UpdateFileToColWidth(); + +bool bReadMirandaDirAndPath(); +tstring GetFilePathFromUser( HANDLE hContact ); + +void ReplaceDefines( HANDLE hContact , tstring & sTarget ); +void ReplaceTimeVariables( tstring &sRet ); + +bool bCreatePathToFile( tstring sFilePath ); +#ifdef _UNICODE +bool bWriteIndentedToFile( HANDLE hFile , int nIndent , const char * pszSrc , bool bUtf8File ); +#endif +bool bWriteIndentedToFile( HANDLE hFile , int nIndent , const _TCHAR * pszSrc , bool bUtf8File ); +bool bWriteNewLine( HANDLE hFile , DWORD dwIndent ); +bool bIsUtf8Header( BYTE * pucByteOrder ); + + +#endif \ No newline at end of file diff --git a/plugins/New_GPG/Makefile b/plugins/New_GPG/Makefile new file mode 100755 index 0000000000..183390389b --- /dev/null +++ b/plugins/New_GPG/Makefile @@ -0,0 +1,23 @@ +CFLAGS=-g -mdll -mwindows -I../miranda-im/miranda/include -I./ -I/home/sss/temp/windows/libs/utf8cpp/include -D DEBUG -D _UNICODE -D UNICODE -DBOOST_SYSTEM_STATIC_LINK=1 -DBOOST_THREAD_USE_LIB +CXXFLAGS=${CFLAGS} +LDFLAGS=-static-libgcc -Wl,-O1 -shared -s -Wl,--subsystem,windows,--kill-at -lshlwapi -lcomdlg32 -lboost_system-mt -lboost_thread_win32-mt -lboost_random-mt -lboost_date_time-mt +CPPFLAGS = +CC=i686-pc-mingw32-gcc +CXX=i686-pc-mingw32-g++ +STRIP=i686-pc-mingw32-strip +LD=i686-pc-mingw32-ld +LNK_COMMON=-lkernel32 + +MAINOBJS=jabber_account.o clist.o init.o options.o gpg_wrapper.o srmm.o messages.o utilities.o metacontacts.o main.o log.o icons.o + +WINDRES=i686-pc-mingw32-windres + +all: main +main: $(MAINOBJS) + $(WINDRES) -i new_gpg.rc -o resources.o + $(CXX) $(MAINOBJS) resources.o $(LNK_COMMON) $(LDFLAGS) -o new_gpg.dll + $(STRIP) new_gpg.dll + upx --best --compress-icons=0 new_gpg.dll +clean: + rm *.o + rm new_gpg.dll diff --git a/plugins/New_GPG/README b/plugins/New_GPG/README new file mode 100755 index 0000000000..be5551c7ac --- /dev/null +++ b/plugins/New_GPG/README @@ -0,0 +1,6 @@ +* Build Dependencies + 1. boost (http://www.boost.org/) + 2. utf8cpp (http://utfcpp.sourceforge.net/) + 3. c++ compiller (because of miranda have compiled with MSVC, only msvc compiled builds working fine (i have no success with mingw, please report your result :) )) +* Runtime Dependencies + 1. MIranda NG diff --git a/plugins/New_GPG/dependencies/include/utf8.h b/plugins/New_GPG/dependencies/include/utf8.h new file mode 100755 index 0000000000..4e4451403f --- /dev/null +++ b/plugins/New_GPG/dependencies/include/utf8.h @@ -0,0 +1,34 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8/checked.h" +#include "utf8/unchecked.h" + +#endif // header guard diff --git a/plugins/New_GPG/dependencies/include/utf8/checked.h b/plugins/New_GPG/dependencies/include/utf8/checked.h new file mode 100755 index 0000000000..3b00644444 --- /dev/null +++ b/plugins/New_GPG/dependencies/include/utf8/checked.h @@ -0,0 +1,327 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "core.h" +#include + +namespace utf8 +{ + // Base for the exceptions that may be thrown from the library + class exception : public ::std::exception { + }; + + // Exceptions that may be thrown from the library functions. + class invalid_code_point : public exception { + uint32_t cp; + public: + invalid_code_point(uint32_t cp) : cp(cp) {} + virtual const char* what() const throw() { return "Invalid code point"; } + uint32_t code_point() const {return cp;} + }; + + class invalid_utf8 : public exception { + uint8_t u8; + public: + invalid_utf8 (uint8_t u) : u8(u) {} + virtual const char* what() const throw() { return "Invalid UTF-8"; } + uint8_t utf8_octet() const {return u8;} + }; + + class invalid_utf16 : public exception { + uint16_t u16; + public: + invalid_utf16 (uint16_t u) : u16(u) {} + virtual const char* what() const throw() { return "Invalid UTF-16"; } + uint16_t utf16_word() const {return u16;} + }; + + class not_enough_room : public exception { + public: + virtual const char* what() const throw() { return "Not enough space"; } + }; + + /// The library API - functions intended to be called by the users + + template + octet_iterator append(uint32_t cp, octet_iterator result) + { + if (!utf8::internal::is_code_point_valid(cp)) + throw invalid_code_point(cp); + + if (cp < 0x80) // one octet + *(result++) = static_cast(cp); + else if (cp < 0x800) { // two octets + *(result++) = static_cast((cp >> 6) | 0xc0); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp < 0x10000) { // three octets + *(result++) = static_cast((cp >> 12) | 0xe0); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else { // four octets + *(result++) = static_cast((cp >> 18) | 0xf0); + *(result++) = static_cast(((cp >> 12) & 0x3f) | 0x80); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + return result; + } + + template + output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement) + { + while (start != end) { + octet_iterator sequence_start = start; + internal::utf_error err_code = utf8::internal::validate_next(start, end); + switch (err_code) { + case internal::UTF8_OK : + for (octet_iterator it = sequence_start; it != start; ++it) + *out++ = *it; + break; + case internal::NOT_ENOUGH_ROOM: + throw not_enough_room(); + case internal::INVALID_LEAD: + utf8::append (replacement, out); + ++start; + break; + case internal::INCOMPLETE_SEQUENCE: + case internal::OVERLONG_SEQUENCE: + case internal::INVALID_CODE_POINT: + utf8::append (replacement, out); + ++start; + // just one replacement mark for the sequence + while (start != end && utf8::internal::is_trail(*start)) + ++start; + break; + } + } + return out; + } + + template + inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out) + { + static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd); + return utf8::replace_invalid(start, end, out, replacement_marker); + } + + template + uint32_t next(octet_iterator& it, octet_iterator end) + { + uint32_t cp = 0; + internal::utf_error err_code = utf8::internal::validate_next(it, end, cp); + switch (err_code) { + case internal::UTF8_OK : + break; + case internal::NOT_ENOUGH_ROOM : + throw not_enough_room(); + case internal::INVALID_LEAD : + case internal::INCOMPLETE_SEQUENCE : + case internal::OVERLONG_SEQUENCE : + throw invalid_utf8(*it); + case internal::INVALID_CODE_POINT : + throw invalid_code_point(cp); + } + return cp; + } + + template + uint32_t peek_next(octet_iterator it, octet_iterator end) + { + return utf8::next(it, end); + } + + template + uint32_t prior(octet_iterator& it, octet_iterator start) + { + // can't do much if it == start + if (it == start) + throw not_enough_room(); + + octet_iterator end = it; + // Go back until we hit either a lead octet or start + while (utf8::internal::is_trail(*(--it))) + if (it == start) + throw invalid_utf8(*it); // error - no lead byte in the sequence + return utf8::peek_next(it, end); + } + + /// Deprecated in versions that include "prior" + template + uint32_t previous(octet_iterator& it, octet_iterator pass_start) + { + octet_iterator end = it; + while (utf8::internal::is_trail(*(--it))) + if (it == pass_start) + throw invalid_utf8(*it); // error - no lead byte in the sequence + octet_iterator temp = it; + return utf8::next(temp, end); + } + + template + void advance (octet_iterator& it, distance_type n, octet_iterator end) + { + for (distance_type i = 0; i < n; ++i) + utf8::next(it, end); + } + + template + typename std::iterator_traits::difference_type + distance (octet_iterator first, octet_iterator last) + { + typename std::iterator_traits::difference_type dist; + for (dist = 0; first < last; ++dist) + utf8::next(first, last); + return dist; + } + + template + octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) + { + while (start != end) { + uint32_t cp = utf8::internal::mask16(*start++); + // Take care of surrogate pairs first + if (utf8::internal::is_lead_surrogate(cp)) { + if (start != end) { + uint32_t trail_surrogate = utf8::internal::mask16(*start++); + if (utf8::internal::is_trail_surrogate(trail_surrogate)) + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + else + throw invalid_utf16(static_cast(trail_surrogate)); + } + else + throw invalid_utf16(static_cast(cp)); + + } + // Lone trail surrogate + else if (utf8::internal::is_trail_surrogate(cp)) + throw invalid_utf16(static_cast(cp)); + + result = utf8::append(cp, result); + } + return result; + } + + template + u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) + { + while (start != end) { + uint32_t cp = utf8::next(start, end); + if (cp > 0xffff) { //make a surrogate pair + *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); + } + else + *result++ = static_cast(cp); + } + return result; + } + + template + octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) + { + while (start != end) + result = utf8::append(*(start++), result); + + return result; + } + + template + u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) + { + while (start != end) + (*result++) = utf8::next(start, end); + + return result; + } + + // The iterator class + template + class iterator : public std::iterator { + octet_iterator it; + octet_iterator range_start; + octet_iterator range_end; + public: + iterator () {}; + explicit iterator (const octet_iterator& octet_it, + const octet_iterator& range_start, + const octet_iterator& range_end) : + it(octet_it), range_start(range_start), range_end(range_end) + { + if (it < range_start || it > range_end) + throw std::out_of_range("Invalid utf-8 iterator position"); + } + // the default "big three" are OK + octet_iterator base () const { return it; } + uint32_t operator * () const + { + octet_iterator temp = it; + return utf8::next(temp, range_end); + } + bool operator == (const iterator& rhs) const + { + if (range_start != rhs.range_start || range_end != rhs.range_end) + throw std::logic_error("Comparing utf-8 iterators defined with different ranges"); + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const + { + return !(operator == (rhs)); + } + iterator& operator ++ () + { + utf8::next(it, range_end); + return *this; + } + iterator operator ++ (int) + { + iterator temp = *this; + utf8::next(it, range_end); + return temp; + } + iterator& operator -- () + { + utf8::prior(it, range_start); + return *this; + } + iterator operator -- (int) + { + iterator temp = *this; + utf8::prior(it, range_start); + return temp; + } + }; // class iterator + +} // namespace utf8 + +#endif //header guard + + diff --git a/plugins/New_GPG/dependencies/include/utf8/core.h b/plugins/New_GPG/dependencies/include/utf8/core.h new file mode 100755 index 0000000000..693d388c07 --- /dev/null +++ b/plugins/New_GPG/dependencies/include/utf8/core.h @@ -0,0 +1,329 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include + +namespace utf8 +{ + // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers + // You may need to change them to match your system. + // These typedefs have the same names as ones from cstdint, or boost/cstdint + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + +// Helper code - not intended to be directly called by the library users. May be changed at any time +namespace internal +{ + // Unicode constants + // Leading (high) surrogates: 0xd800 - 0xdbff + // Trailing (low) surrogates: 0xdc00 - 0xdfff + const uint16_t LEAD_SURROGATE_MIN = 0xd800u; + const uint16_t LEAD_SURROGATE_MAX = 0xdbffu; + const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u; + const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu; + const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); + const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; + + // Maximum valid value for a Unicode code point + const uint32_t CODE_POINT_MAX = 0x0010ffffu; + + template + inline uint8_t mask8(octet_type oc) + { + return static_cast(0xff & oc); + } + template + inline uint16_t mask16(u16_type oc) + { + return static_cast(0xffff & oc); + } + template + inline bool is_trail(octet_type oc) + { + return ((utf8::internal::mask8(oc) >> 6) == 0x2); + } + + template + inline bool is_lead_surrogate(u16 cp) + { + return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX); + } + + template + inline bool is_trail_surrogate(u16 cp) + { + return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); + } + + template + inline bool is_surrogate(u16 cp) + { + return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); + } + + template + inline bool is_code_point_valid(u32 cp) + { + return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp)); + } + + template + inline typename std::iterator_traits::difference_type + sequence_length(octet_iterator lead_it) + { + uint8_t lead = utf8::internal::mask8(*lead_it); + if (lead < 0x80) + return 1; + else if ((lead >> 5) == 0x6) + return 2; + else if ((lead >> 4) == 0xe) + return 3; + else if ((lead >> 3) == 0x1e) + return 4; + else + return 0; + } + + template + inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length) + { + if (cp < 0x80) { + if (length != 1) + return true; + } + else if (cp < 0x800) { + if (length != 2) + return true; + } + else if (cp < 0x10000) { + if (length != 3) + return true; + } + + return false; + } + + enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT}; + + /// Helper for get_sequence_x + template + utf_error increase_safely(octet_iterator& it, octet_iterator end) + { + if (++it == end) + return NOT_ENOUGH_ROOM; + + if (!utf8::internal::is_trail(*it)) + return INCOMPLETE_SEQUENCE; + + return UTF8_OK; + } + + #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;} + + /// get_sequence_x functions decode utf-8 sequences of the length x + template + utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + return UTF8_OK; + } + + template + utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f); + + return UTF8_OK; + } + + template + utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point += (*it) & 0x3f; + + return UTF8_OK; + } + + template + utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point += (utf8::internal::mask8(*it) << 6) & 0xfff; + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point += (*it) & 0x3f; + + return UTF8_OK; + } + + #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR + + template + utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point) + { + // Save the original value of it so we can go back in case of failure + // Of course, it does not make much sense with i.e. stream iterators + octet_iterator original_it = it; + + uint32_t cp = 0; + // Determine the sequence length based on the lead octet + typedef typename std::iterator_traits::difference_type octet_difference_type; + const octet_difference_type length = utf8::internal::sequence_length(it); + + // Get trail octets and calculate the code point + utf_error err = UTF8_OK; + switch (length) { + case 0: + return INVALID_LEAD; + case 1: + err = utf8::internal::get_sequence_1(it, end, cp); + break; + case 2: + err = utf8::internal::get_sequence_2(it, end, cp); + break; + case 3: + err = utf8::internal::get_sequence_3(it, end, cp); + break; + case 4: + err = utf8::internal::get_sequence_4(it, end, cp); + break; + } + + if (err == UTF8_OK) { + // Decoding succeeded. Now, security checks... + if (utf8::internal::is_code_point_valid(cp)) { + if (!utf8::internal::is_overlong_sequence(cp, length)){ + // Passed! Return here. + code_point = cp; + ++it; + return UTF8_OK; + } + else + err = OVERLONG_SEQUENCE; + } + else + err = INVALID_CODE_POINT; + } + + // Failure branch - restore the original value of the iterator + it = original_it; + return err; + } + + template + inline utf_error validate_next(octet_iterator& it, octet_iterator end) { + uint32_t ignored; + return utf8::internal::validate_next(it, end, ignored); + } + +} // namespace internal + + /// The library API - functions intended to be called by the users + + // Byte order mark + const uint8_t bom[] = {0xef, 0xbb, 0xbf}; + + template + octet_iterator find_invalid(octet_iterator start, octet_iterator end) + { + octet_iterator result = start; + while (result != end) { + utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end); + if (err_code != internal::UTF8_OK) + return result; + } + return result; + } + + template + inline bool is_valid(octet_iterator start, octet_iterator end) + { + return (utf8::find_invalid(start, end) == end); + } + + template + inline bool starts_with_bom (octet_iterator it, octet_iterator end) + { + return ( + ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) && + ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) && + ((it != end) && (utf8::internal::mask8(*it)) == bom[2]) + ); + } + + //Deprecated in release 2.3 + template + inline bool is_bom (octet_iterator it) + { + return ( + (utf8::internal::mask8(*it++)) == bom[0] && + (utf8::internal::mask8(*it++)) == bom[1] && + (utf8::internal::mask8(*it)) == bom[2] + ); + } +} // namespace utf8 + +#endif // header guard + + diff --git a/plugins/New_GPG/dependencies/include/utf8/unchecked.h b/plugins/New_GPG/dependencies/include/utf8/unchecked.h new file mode 100755 index 0000000000..b4547fad94 --- /dev/null +++ b/plugins/New_GPG/dependencies/include/utf8/unchecked.h @@ -0,0 +1,228 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "core.h" + +namespace utf8 +{ + namespace unchecked + { + template + octet_iterator append(uint32_t cp, octet_iterator result) + { + if (cp < 0x80) // one octet + *(result++) = static_cast(cp); + else if (cp < 0x800) { // two octets + *(result++) = static_cast((cp >> 6) | 0xc0); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp < 0x10000) { // three octets + *(result++) = static_cast((cp >> 12) | 0xe0); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else { // four octets + *(result++) = static_cast((cp >> 18) | 0xf0); + *(result++) = static_cast(((cp >> 12) & 0x3f)| 0x80); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + return result; + } + + template + uint32_t next(octet_iterator& it) + { + uint32_t cp = utf8::internal::mask8(*it); + typename std::iterator_traits::difference_type length = utf8::internal::sequence_length(it); + switch (length) { + case 1: + break; + case 2: + it++; + cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f); + break; + case 3: + ++it; + cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); + ++it; + cp += (*it) & 0x3f; + break; + case 4: + ++it; + cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); + ++it; + cp += (utf8::internal::mask8(*it) << 6) & 0xfff; + ++it; + cp += (*it) & 0x3f; + break; + } + ++it; + return cp; + } + + template + uint32_t peek_next(octet_iterator it) + { + return utf8::unchecked::next(it); + } + + template + uint32_t prior(octet_iterator& it) + { + while (utf8::internal::is_trail(*(--it))) ; + octet_iterator temp = it; + return utf8::unchecked::next(temp); + } + + // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous) + template + inline uint32_t previous(octet_iterator& it) + { + return utf8::unchecked::prior(it); + } + + template + void advance (octet_iterator& it, distance_type n) + { + for (distance_type i = 0; i < n; ++i) + utf8::unchecked::next(it); + } + + template + typename std::iterator_traits::difference_type + distance (octet_iterator first, octet_iterator last) + { + typename std::iterator_traits::difference_type dist; + for (dist = 0; first < last; ++dist) + utf8::unchecked::next(first); + return dist; + } + + template + octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) + { + while (start != end) { + uint32_t cp = utf8::internal::mask16(*start++); + // Take care of surrogate pairs first + if (utf8::internal::is_lead_surrogate(cp)) { + uint32_t trail_surrogate = utf8::internal::mask16(*start++); + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + } + result = utf8::unchecked::append(cp, result); + } + return result; + } + + template + u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) + { + while (start < end) { + uint32_t cp = utf8::unchecked::next(start); + if (cp > 0xffff) { //make a surrogate pair + *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); + } + else + *result++ = static_cast(cp); + } + return result; + } + + template + octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) + { + while (start != end) + result = utf8::unchecked::append(*(start++), result); + + return result; + } + + template + u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) + { + while (start < end) + (*result++) = utf8::unchecked::next(start); + + return result; + } + + // The iterator class + template + class iterator : public std::iterator { + octet_iterator it; + public: + iterator () {}; + explicit iterator (const octet_iterator& octet_it): it(octet_it) {} + // the default "big three" are OK + octet_iterator base () const { return it; } + uint32_t operator * () const + { + octet_iterator temp = it; + return utf8::unchecked::next(temp); + } + bool operator == (const iterator& rhs) const + { + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const + { + return !(operator == (rhs)); + } + iterator& operator ++ () + { + ::std::advance(it, utf8::internal::sequence_length(it)); + return *this; + } + iterator operator ++ (int) + { + iterator temp = *this; + ::std::advance(it, utf8::internal::sequence_length(it)); + return temp; + } + iterator& operator -- () + { + utf8::unchecked::prior(it); + return *this; + } + iterator operator -- (int) + { + iterator temp = *this; + utf8::unchecked::prior(it); + return temp; + } + }; // class iterator + + } // namespace utf8::unchecked +} // namespace utf8 + + +#endif // header guard + diff --git a/plugins/New_GPG/new_gpg_10.vcxproj b/plugins/New_GPG/new_gpg_10.vcxproj new file mode 100755 index 0000000000..7dfa1d30fb --- /dev/null +++ b/plugins/New_GPG/new_gpg_10.vcxproj @@ -0,0 +1,1031 @@ + + + + + Debug + Win32 + + + Debug + X64 + + + Release + Win32 + + + Release + X64 + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {F29D0C8D-141A-43CF-86B2-34A04653F8D4} + new_gpg + new_gpg + + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + true + + + DynamicLibrary + false + Unicode + true + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)64\Plugins\ + $(Configuration)\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + false + false + false + .\Debug\ + $(SolutionDir)$(Configuration)\Plugins\ + $(SolutionDir)$(Configuration)64\Plugins\ + .\Debug\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + true + true + true + true + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + false + false + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + false + false + false + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + false + false + false + $(Configuration)\ + $(Configuration)\ + true + AllRules.ruleset + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release Unicode/testplug.tlb + + + + + Full + OnlyExplicitInline + Size + true + true + X:\install\git\miranda\mim_plugs;X:\install\git\miranda\miranda-im\miranda\include;../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_UNICODE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + StreamingSIMDExtensions + Precise + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + true + X:\install\git\miranda\mim_plugs\lib;%(AdditionalLibraryDirectories) + true + true + true + UseLinkTimeCodeGeneration + false + + + .\Release Unicode/testplug.lib + + + true + .\Release Unicode/testplug.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release Unicode/testplug.tlb + + + + + Full + OnlyExplicitInline + Size + true + true + .\dependencies\include;..\..\..\boost_1_49_0;..\..\include + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_UNICODE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + StreamingSIMDExtensions + Fast + Level3 + true + Use + commonheaders.h + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + shlwapi.lib;%(AdditionalDependencies) + true + $(SolutionDir)\lib;..\..\..\boost_1_49_0\lib;%(AdditionalLibraryDirectories) + true + true + true + UseLinkTimeCodeGeneration + false + + + $(IntDir)$(TargetName).lib + Windows + + + true + .\Release Unicode/testplug.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release Unicode/testplug.tlb + + + + + Full + OnlyExplicitInline + Size + true + true + .\dependencies\include;..\..\..\boost_1_49_0;..\..\include + WIN64;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_UNICODE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + StreamingSIMDExtensions + Fast + Level3 + true + Use + commonheaders.h + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + shlwapi.lib;%(AdditionalDependencies) + true + $(SolutionDir)\lib;..\..\..\boost_1_49_0\lib64;%(AdditionalLibraryDirectories) + true + true + true + UseLinkTimeCodeGeneration + false + + + $(IntDir)$(TargetName).lib + Windows + + + true + .\Release Unicode/testplug.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testplug.tlb + + + + + Disabled + x:\temp\windows\libs\utf8cpp\include;x:\temp\windows\libs\boost;x:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;TESTPLUG_EXPORTS;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + Use + commonheaders.h + + + true + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + shlwapi.lib;%(AdditionalDependencies) + true + x:\temp\windows\libs\boost\lib;%(AdditionalLibraryDirectories) + true + false + + + .\Debug/testplug.lib + + + true + .\Debug/testplug.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testplug.tlb + + + + + Disabled + .\dependencies\include;..\..\..\boost_1_49_0;..\..\include + WIN32;_DEBUG;_WINDOWS;_USRDLL;TESTPLUG_EXPORTS;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Use + commonheaders.h + true + Level3 + true + true + true + CompileAsCpp + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + shlwapi.lib;%(AdditionalDependencies) + true + $(SolutionDir)\lib;..\..\..\boost_1_49_0\lib;%(AdditionalLibraryDirectories) + true + false + + + $(IntDir)$(TargetName).lib + $(TargetDir)$(TargetName).pdb + Windows + + + true + .\Debug/testplug.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testplug.tlb + + + + + Disabled + .\dependencies\include;..\..\..\boost_1_49_0;..\..\include + WIN64;_DEBUG;_WINDOWS;_USRDLL;TESTPLUG_EXPORTS;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Use + commonheaders.h + true + Level3 + true + true + true + CompileAsCpp + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + shlwapi.lib;%(AdditionalDependencies) + true + $(SolutionDir)\lib;..\..\..\boost_1_49_0\lib64;%(AdditionalLibraryDirectories) + true + false + + + $(IntDir)$(TargetName).lib + $(TargetDir)$(TargetName).pdb + Windows + + + true + .\Debug/testplug.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testplug.tlb + + + + + Disabled + x:\temp\windows\libs\utf8cpp\include;X:\temp\windows\libs\Boost\include;x:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;TESTPLUG_EXPORTS;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + Use + commonheaders.h + c:\temp\new_gpg.pch + + + .\Debug/ + .\Debug/ + .\Debug/ + true + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + shlwapi.lib;%(AdditionalDependencies) + true + X:\temp\windows\libs\Boost\lib64;%(AdditionalLibraryDirectories) + true + true + false + false + false + + + .\Debug/testplug.lib + c:\debug\$(TargetName).pdb + + + true + .\Debug/testplug.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release Unicode (static)/testplug.tlb + + + + + MinSpace + OnlyExplicitInline + Size + true + true + x:\temp\windows\libs\utf8cpp\include;C:\Boost\include\boost-1_45;x:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_UNICODE;%(PreprocessorDefinitions) + true + MultiThreaded + true + StreamingSIMDExtensions + Precise + Use + commonheaders.h + c:\temp\new_gpg.pch + .\Release Unicode (static)/ + .\Release Unicode (static)/ + .\Release Unicode (static)/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + shlwapi.lib;%(AdditionalDependencies) + true + x:\temp\windows\libs\boost\lib;%(AdditionalLibraryDirectories) + false + NotSet + true + true + UseLinkTimeCodeGeneration + false + + + .\Release Unicode (static)/testplug.lib + + + true + .\Release Unicode (static)/testplug.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release Unicode (static)/testplug.tlb + + + + + MinSpace + OnlyExplicitInline + Size + true + true + x:\temp\windows\libs\utf8cpp\include;x:\temp\windows\libs\Boost\include;x:\install\git\miranda\miranda-im\miranda\include;x:\install\git\miranda\mim_plugs;../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;_UNICODE;%(PreprocessorDefinitions) + true + MultiThreaded + true + StreamingSIMDExtensions + Precise + Use + commonheaders.h + c:\temp\new_gpg.pch + .\Release Unicode (static)/ + .\Release Unicode (static)/ + .\Release Unicode (static)/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + shlwapi.lib;%(AdditionalDependencies) + true + x:\temp\windows\libs\Boost\lib64;%(AdditionalLibraryDirectories) + true + NotSet + true + true + UseLinkTimeCodeGeneration + false + + + .\Release Unicode (static)/testplug.lib + c:\debug\$(TargetName).pdb + + + true + .\Release Unicode (static)/testplug.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release Unicode (static)/testplug.tlb + + + + + Full + OnlyExplicitInline + Size + true + true + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + StreamingSIMDExtensions + Precise + .\Release Unicode (static)/testplug.pch + .\Release Unicode (static)/ + .\Release Unicode (static)/ + .\Release Unicode (static)/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + true + true + true + true + UseLinkTimeCodeGeneration + false + + + .\Release Unicode (static)/testplug.lib + + + true + .\Release Unicode (static)/testplug.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release Unicode (static)/testplug.tlb + + + + + Full + OnlyExplicitInline + Size + true + true + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + StreamingSIMDExtensions + Precise + .\Release Unicode (static)/testplug.pch + .\Release Unicode (static)/ + .\Release Unicode (static)/ + .\Release Unicode (static)/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + true + true + true + true + UseLinkTimeCodeGeneration + false + + + .\Release Unicode (static)/testplug.lib + + + true + .\Release Unicode (static)/testplug.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release Unicode (static)/testplug.tlb + + + + + Full + OnlyExplicitInline + Size + true + true + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreaded + true + StreamingSIMDExtensions + Precise + .\Release Unicode (static)/testplug.pch + .\Release Unicode (static)/ + .\Release Unicode (static)/ + .\Release Unicode (static)/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + true + true + true + true + UseLinkTimeCodeGeneration + false + + + .\Release Unicode (static)/testplug.lib + + + true + .\Release Unicode (static)/testplug.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release Unicode (static)/testplug.tlb + + + + + Full + OnlyExplicitInline + Size + true + true + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + StreamingSIMDExtensions + Precise + .\Release Unicode (static)/testplug.pch + .\Release Unicode (static)/ + .\Release Unicode (static)/ + .\Release Unicode (static)/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + true + true + true + true + UseLinkTimeCodeGeneration + false + + + .\Release Unicode (static)/testplug.lib + + + true + .\Release Unicode (static)/testplug.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release Unicode (static)/testplug.tlb + + + + + Full + OnlyExplicitInline + Size + true + true + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + StreamingSIMDExtensions + Precise + .\Release Unicode (static)/testplug.pch + .\Release Unicode (static)/ + .\Release Unicode (static)/ + .\Release Unicode (static)/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + true + true + true + true + UseLinkTimeCodeGeneration + false + + + .\Release Unicode (static)/testplug.lib + + + true + .\Release Unicode (static)/testplug.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release Unicode (static)/testplug.tlb + + + + + Full + OnlyExplicitInline + Size + true + true + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + StreamingSIMDExtensions + Precise + .\Release Unicode (static)/testplug.pch + .\Release Unicode (static)/ + .\Release Unicode (static)/ + .\Release Unicode (static)/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + + + true + true + true + true + UseLinkTimeCodeGeneration + false + + + .\Release Unicode (static)/testplug.lib + + + true + .\Release Unicode (static)/testplug.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testplug.tlb + + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;TESTPLUG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + .\Debug/testplug.pch + .\Debug/ + .\Debug/ + .\Debug/ + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + + + true + true + false + + + .\Debug/testplug.lib + + + true + .\Debug/testplug.bsc + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/New_GPG/new_gpg_10.vcxproj.filters b/plugins/New_GPG/new_gpg_10.vcxproj.filters new file mode 100755 index 0000000000..37e663c898 --- /dev/null +++ b/plugins/New_GPG/new_gpg_10.vcxproj.filters @@ -0,0 +1,103 @@ + + + + + {56a6d5fd-c491-4d42-95e0-d0e98979acff} + + + {8159144c-7020-4568-8bb4-53f4699faac6} + + + {65abe24a-f835-47f5-9ebf-fbd3f55f993c} + + + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + Sources + + + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + Headers + + + + + Resources + + + + + Resources + + + Resources + + + \ No newline at end of file diff --git a/plugins/New_GPG/new_gpg_lang_ru.txt b/plugins/New_GPG/new_gpg_lang_ru.txt new file mode 100755 index 0000000000..4cf3659695 --- /dev/null +++ b/plugins/New_GPG/new_gpg_lang_ru.txt @@ -0,0 +1,115 @@ +;============================================================ +; File: new_gpg.dll +; Module: new GPG encryption plugin +; Versions: 0.0.0.11 +; URL: http://addons.miranda-im.org/details.php?action=viewfile&id=958 +; Source: git://sss.chaoslab.ru/mim_plugs.git (checkout new_gpg) +; Authors: sss +;============================================================ + +[Your GPG version is supported. The language file was found.\nGPG plugin should work fine.\nPress OK to continue.] +Âàøà âåðñèÿ GPG ïîääåðæèâàåòñÿ. ßçûêîâûå ôàéëû íàéäåíû.\nGPG Äîëæåí ðàáîòàòü íîðìàëüíî.\nÍàæìèòå ÎÊ. +[Copy own key] +Êîïèð. ñâîé êëþ÷ +[Select own key] +Âûáðàòü ñâîé êëþ÷ +[Export PubKey] +Ñîõðàíèòü êëþ÷ +[GnuPG Variables] +Ïóòè ê GPG +[Turn on debug log] +Âêë. çàïèñü îòëàäêè +[Accept] +Ïðèíÿòü +[Accept and enable encryption] +Ïðèíÿòü è âêëþ÷èòü øèôðîâàíèå +[Replace] +Çàìåíèòü +[Import key] +Èìïîðò êëþ÷à +[Load from file] +Èìïîðò èç ôàéëà +[Load other] +Çàãðóçèòü +[Delete key] +Óäàëèòü êëþ÷ +[Select existing] +Âûáðàòü ñóùåñòâóþùèé +[Turn on encryption] +Âêëþ÷èòü øèôðîâàíèå +[Import key from keyserver] +Èìïîðò êëþ÷à ñ ñåðâåðà êëþ÷åé +[New public key was received, do you want to import it?] +Ïîëó÷åí íîâûé îòðûòûé êëþ÷. Âû õîòèòå åãî ïðèíÿòü? +[There is existing key for contact, would you like to replace with new key ?] +Ïîëó÷åí êëþ÷, íî ó êîíòàêòà óæå åñòü êëþ÷. Âû õîòèòå åãî çàìåíèòü íîâûì? +[The new public key was recieved] +Ïîëó÷åí íîâûé îòðûòûé êëþ÷. +[Received key from] +Ïîëó÷åí êëþ÷ îò +[Do you want to remove key from entire metacontact (all subcontacts) ?] +Âû õîòèòå óáðàòü êëþ÷ äëÿ ìåòàêîíòàêòà (âñåõ ñóáêîíòàêòîâ)? +[Select existing public key from list] +Âûáðàòü îòêðûòûé êëþ÷ èç ñïèñêà +[Encrypt file transfers] +Øèôðîâàííàÿ ïåðåäà÷à ôàéëîâ +[Use jabber api on Miranda IM >= 0.9 (recomended)] +Èñïîëüçîâàòü jabber api åñëè Miranda IM >= 0.9 (Ðåêîìåíäóåòñÿ) +[Current private key id] +Çàêðûòûé êëþ÷ +[This is not gnupg binary !\nrecommended to use GnuPG v1.x.x with this plugn.] +Âûáðàííûé âàìè exe íå GnuPG!\nÐåêîìåíäóåòñÿ èñïîëüçîâàòü GnuPG v1.x.x ñ ýòèì ïëàãèíîì. +[Unsupported gnupg version found, use at you own risk!\nrecommended to use GnuPG v1.x.x with this plugn.] +Âàøà âåðñèÿ GnuPG íå ïîääåðæèâàåòñÿ è ìîæåò ðàáîòàòü íå ïðàâèëüíî!\nÐåêîìåíäóåòñÿ èñïîëüçîâàòü GnuPG v1.x.x ñ ýòèì ïëàãèíîì. +[Generate key] +Ñãåíåðèðîâàòü +[Select key for use] +Âûáðàòü êëþ÷ +[Generate and use random key] +Ñãåíåðèðîâàòü è èñïîëüçîâàòü êëþ÷ +[GnuPG binary:] +Ïóòü ê exe: +[Home directory:] +Äîìàøíèé êàòàëîã: +[Turn on key autoexchange] +Âêëþ÷èòü àâòîîáìåí êëþ÷àìè +[Key type:] +Òèï êëþ÷à: +[Key length:] +Äëèííà êëþ÷à +[Key password:] +Ïàðîëü êëþ÷à: +[Real name:] +Èìÿ/Íèê: +[Comment:] +Êîììåíòàðèé: +[Expire date:] +Îêîí÷àíèå äåéñòâèÿ êëþ÷à: +[ex.: 2010-08-15] +ïðèìåð: 2010-08-15 +[From 1024 to 4096] +îò 1024 äî 4096 +[It can take a long time, be patient] +* Ýòî ìîæåò çàíÿòü íåñêîëüêî ìèíóò. +[0 - does not expire] +0 - íèêîãäà íå çàêàí÷èâàåòñÿ +[Save password to database] +Ñîõðàíèòü ïàðîëü â áàçó +[Default password] +Ïàðîëü ïî óìîë÷àíèþ +[Import] +Èìïîðòèðîâàòü +[Select keyserver for key search:] +Âûáðàòü ñåðâåð êëþ÷åé äëÿ ïîèñêà: +[Userlist:] +Ëèñò ïîëüçîâàòåëåé: +[Add tags to encoded and decoded messages] +Äîáàâëÿòü ìåòêè ê ñîîáùåíèÿì +[Incomming message tags:] +Äîáàâëÿòü ìåòêè ê âõîäÿùèì ñîîáùåíèÿì: +[Outgoing message tags:] +Äîáàâëÿòü ìåòêè èñõîäÿùèì ñîîáùåíèÿñ: +[Open:] +Íà÷àëî +[Close:] +Êîíåö diff --git a/plugins/New_GPG/res/icons/secured.ico b/plugins/New_GPG/res/icons/secured.ico new file mode 100755 index 0000000000..8d84167e56 Binary files /dev/null and b/plugins/New_GPG/res/icons/secured.ico differ diff --git a/plugins/New_GPG/res/icons/unsecured.ico b/plugins/New_GPG/res/icons/unsecured.ico new file mode 100755 index 0000000000..567367b389 Binary files /dev/null and b/plugins/New_GPG/res/icons/unsecured.ico differ diff --git a/plugins/New_GPG/res/new_gpg.rc b/plugins/New_GPG/res/new_gpg.rc new file mode 100755 index 0000000000..f72f9ea9c5 --- /dev/null +++ b/plugins/New_GPG/res/new_gpg.rc @@ -0,0 +1,419 @@ +// Microsoft Visual C++ generated resource script. +// +#include "src/resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Ðóññêèé (Ðîññèÿ) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) + +#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_LOAD_PUBLIC_KEY DIALOGEX 0, 0, 338, 190 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Load Public GPG key" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "ÎÊ",ID_OK,7,169,50,14 + PUSHBUTTON "Load from file",ID_LOAD_FROM_FILE,273,169,58,14 + EDITTEXT IDC_PUBLIC_KEY_EDIT,7,7,324,134,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_VSCROLL,WS_EX_STATICEDGE + PUSHBUTTON "Select existing",IDC_SELECT_EXISTING,113,169,97,14 + CONTROL "Turn on encryption",IDC_ENABLE_ENCRYPTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,143,196,10 + PUSHBUTTON "Import key from keyserver",IDC_IMPORT,140,152,188,14,WS_DISABLED +END + +IDD_FIRST_RUN DIALOGEX 0, 0, 291, 230 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Set own key" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "ÎÊ",ID_OK,12,209,50,14,WS_DISABLED + CONTROL "",IDC_KEY_LIST,"SysListView32",LVS_REPORT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,44,277,105 + PUSHBUTTON "Generate key",IDC_GENERATE_KEY,8,152,74,14 + LTEXT "Select key for use",IDC_STATIC,16,33,186,8 + EDITTEXT IDC_KEY_PASSWORD,94,168,77,14,ES_PASSWORD | ES_AUTOHSCROLL + RTEXT "Key password:",IDC_STATIC,12,170,76,8 + PUSHBUTTON "Load other",IDC_OTHER,83,152,64,14 + PUSHBUTTON "Delete key",IDC_DELETE_KEY,149,152,70,14 + PUSHBUTTON "Generate and use random key",IDC_GENERATE_RANDOM,99,184,118,14 + LTEXT "",IDC_GENERATING_KEY,82,207,174,8 + LTEXT "Account:",IDC_STATIC,15,12,42,8 + LTEXT "key id: ",IDC_KEY_ID,178,12,99,8 + COMBOBOX IDC_ACCOUNT,66,9,104,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +END + +IDD_BIN_PATH DIALOGEX 0, 0, 354, 108 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Set GPG bin path and keyring home dir." +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Continue",ID_OK,7,87,50,14 + LTEXT "Home directory:",IDC_STATIC,9,34,325,8 + LTEXT "GnuPG binary:",IDC_STATIC,10,7,147,8 + PUSHBUTTON "Browse",IDC_SET_BIN_PATH,293,18,54,14 + PUSHBUTTON "Browse",IDC_SET_HOME_DIR,293,44,54,14 + EDITTEXT IDC_HOME_DIR,7,44,277,14,ES_AUTOHSCROLL + EDITTEXT IDC_BIN_PATH,7,17,277,14,ES_AUTOHSCROLL + PUSHBUTTON "Generate and use random key",IDC_GENERATE_RANDOM,166,87,118,14 + CONTROL "Turn on key autoexchange",IDC_AUTO_EXCHANGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,64,277,10 +END + +IDD_NEW_KEY DIALOGEX 0, 0, 427, 68 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "The new public key was recieved" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Import key",ID_IMPORT,9,47,46,14 + PUSHBUTTON "Accept and enable encryption",IDC_IMPORT_AND_USE,156,47,119,14 + PUSHBUTTON "Ignore",IDC_IGNORE_KEY,368,47,52,14 + CTEXT "Ñòàòè÷åñêèé",IDC_MESSAGE,18,25,392,8 + CTEXT "Ñòàòè÷åñêèé",IDC_KEY_FROM,16,12,395,8 +END + +IDD_KEY_GEN DIALOGEX 0, 0, 284, 169 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Key Generation dialog" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,7,148,50,14 + PUSHBUTTON "Cancel",IDCANCEL,227,148,50,14 + COMBOBOX IDC_KEY_TYPE,120,14,48,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_GROUP | WS_TABSTOP + EDITTEXT IDC_KEY_LENGTH,120,30,40,14,ES_AUTOHSCROLL | ES_NUMBER | WS_GROUP + EDITTEXT IDC_KEY_PASSWD,120,46,55,14,ES_AUTOHSCROLL | WS_GROUP + EDITTEXT IDC_KEY_REAL_NAME,120,61,55,14,ES_AUTOHSCROLL | WS_GROUP + EDITTEXT IDC_KEY_EMAIL,120,76,55,14,ES_AUTOHSCROLL | WS_GROUP + EDITTEXT IDC_KEY_COMMENT,120,91,55,14,ES_AUTOHSCROLL | WS_GROUP + EDITTEXT IDC_KEY_EXPIRE_DATE,120,106,55,14,ES_AUTOHSCROLL | WS_GROUP + LTEXT "Key type:",IDC_STATIC,8,16,96,8 + LTEXT "Key length:",IDC_STATIC,7,32,106,8 + LTEXT "Key password:",IDC_STATIC,7,49,105,8 + LTEXT "Real name:",IDC_STATIC,7,63,105,8 + LTEXT "Email:",IDC_STATIC,7,79,108,8 + LTEXT "Comment:",IDC_STATIC,7,92,107,8 + LTEXT "Expire date:",IDC_STATIC,7,109,111,8 + LTEXT "ex.: 2010-08-15",IDC_STATIC,182,108,75,8 + LTEXT "From 1024 to 4096",IDC_STATIC,168,33,89,8 + LTEXT "It can take a long time, be patient",IDC_GENERATING_TEXT,15,132,246,8 + LTEXT "0 - does not expire",IDC_STATIC,122,122,141,8 +END + +IDD_LOAD_EXISTING_KEY DIALOGEX 0, 0, 370, 257 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Select existing public key from list" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "ÎÊ",IDOK,7,236,50,14,WS_DISABLED + PUSHBUTTON "Cancel",IDCANCEL,313,236,50,14 + CONTROL "",IDC_EXISTING_KEY_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,14,356,217 +END + +IDD_KEY_PASSWD DIALOGEX 0, 0, 207, 108 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Enter password for your secret key" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "ÎÊ",IDOK,7,87,50,14 + PUSHBUTTON "Cancel",IDCANCEL,150,87,50,14 + EDITTEXT IDC_PASSWORD,13,38,179,14,ES_PASSWORD | ES_AUTOHSCROLL + LTEXT "Password:",IDC_STATIC,14,28,34,8 + CONTROL "Save password to database",IDC_SAVE_PASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,56,124,10 + LTEXT "",IDC_KEYID,14,14,179,8 + CONTROL "Default password",IDC_DEFAULT_PASSWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,67,151,10 +END + +IDD_IMPORT_KEY DIALOGEX 0, 0, 161, 81 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Set GPG bin path and keyring home dir." +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + PUSHBUTTON "Import",IDC_IMPORT,15,56,50,14 + LTEXT "Select keyserver for key search:",IDC_STATIC,16,20,122,8 + COMBOBOX IDC_KEYSERVER,15,34,125,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_LOAD_PUBLIC_KEY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 331 + TOPMARGIN, 7 + BOTTOMMARGIN, 183 + END + + IDD_FIRST_RUN, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 284 + VERTGUIDE, 15 + TOPMARGIN, 7 + BOTTOMMARGIN, 223 + HORZGUIDE, 20 + END + + IDD_BIN_PATH, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 347 + VERTGUIDE, 284 + TOPMARGIN, 7 + BOTTOMMARGIN, 101 + END + + IDD_NEW_KEY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 420 + TOPMARGIN, 6 + BOTTOMMARGIN, 61 + END + + IDD_KEY_GEN, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 277 + TOPMARGIN, 7 + BOTTOMMARGIN, 162 + END + + IDD_LOAD_EXISTING_KEY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 363 + TOPMARGIN, 7 + BOTTOMMARGIN, 250 + END + + IDD_KEY_PASSWD, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 200 + TOPMARGIN, 7 + BOTTOMMARGIN, 101 + END + + IDD_IMPORT_KEY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 154 + TOPMARGIN, 7 + BOTTOMMARGIN, 74 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_SECURED ICON "icons\\secured.ico" +IDI_UNSECURED ICON "icons\\unsecured.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 0,0,0,11 + PRODUCTVERSION 0,9,0,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041904b0" + BEGIN + VALUE "FileDescription", "new_gpg" + VALUE "FileVersion", "0.0.0.11" + VALUE "InternalName", "new_gpg" + VALUE "LegalCopyright", "Copyright (C) 2010-2011 sss" + VALUE "OriginalFilename", "new_gpg" + VALUE "ProductName", "new_gpg" + VALUE "ProductVersion", "0.9.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x419, 1200 + END +END + +#endif // Ðóññêèé (Ðîññèÿ) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Àíãëèéñêèé (ÑØÀ) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPT_GPG DIALOGEX 0, 0, 286, 214 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x0 +BEGIN + CONTROL "",IDC_USERLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,17,272,112 + CTEXT "Userlist:",IDC_STATIC,25,7,201,8 + PUSHBUTTON "Export PubKey",IDC_SAVE_KEY_BUTTON,8,135,75,14 + PUSHBUTTON "Delete key",IDC_DELETE_KEY_BUTTON,90,135,70,14 + PUSHBUTTON "Select own key",IDC_SELECT_KEY,205,193,74,14 + CONTROL "Turn on debug log",IDC_DEBUG_LOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,181,159,89,10 + EDITTEXT IDC_LOG_FILE_EDIT,11,157,98,14,ES_AUTOHSCROLL + PUSHBUTTON "Browse",IDC_LOG_FILE_SET,119,156,50,14 + CONTROL "Use jabber api on Miranda IM >= 0.9 (recomended)",IDC_JABBER_API, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,175,251,10 + LTEXT "Default key",IDC_CURRENT_KEY,12,196,110,8 + CONTROL "Encrypt file transfers",IDC_FILE_TRANSFERS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,185,137,10 + CONTROL "Automatic key exchange",IDC_AUTO_EXCHANGE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,163,137,111,10 + PUSHBUTTON "Copy own key",IDC_COPY_KEY,127,193,74,14 +END + +IDD_OPT_GPG_BIN DIALOGEX 0, 0, 282, 214 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x0 +BEGIN + PUSHBUTTON "Browse",IDC_SET_BIN_PATH,216,17,60,14 + PUSHBUTTON "Browse",IDC_SET_HOME_DIR,217,44,57,14 + EDITTEXT IDC_BIN_PATH,7,17,195,14,ES_AUTOHSCROLL + EDITTEXT IDC_HOME_DIR,7,44,195,14,ES_AUTOHSCROLL + LTEXT "GnuPG binary:",IDC_STATIC,10,7,147,8 + LTEXT "Home directory:",IDC_STATIC,9,34,144,8 +END + +IDD_OPT_GPG_MESSAGES DIALOGEX 0, 0, 302, 241 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x0 +BEGIN + CONTROL "Add tags to encoded and decoded messages",IDC_APPEND_TAGS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,65,243,10 + EDITTEXT IDC_IN_OPEN_TAG,39,20,88,14,ES_AUTOHSCROLL + EDITTEXT IDC_IN_CLOSE_TAG,151,20,90,14,ES_AUTOHSCROLL + LTEXT "Incomming message tags:",IDC_STATIC,15,10,84,8 + LTEXT "Outgoing message tags:",IDC_STATIC,13,36,79,8 + RTEXT "Open:",IDC_STATIC,13,23,26,8 + RTEXT "Close:",IDC_STATIC,127,23,23,8 + EDITTEXT IDC_OUT_OPEN_TAG,39,46,88,14,ES_AUTOHSCROLL + EDITTEXT IDC_OUT_CLOSE_TAG,151,46,90,14,ES_AUTOHSCROLL + RTEXT "Open:",IDC_STATIC,13,49,26,8 + RTEXT "Close:",IDC_STATIC,127,49,23,8 + CONTROL "Strip all tags in outgoing messages",IDC_STRIP_TAGS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,76,233,10 +END + +IDD_OPT_GPG_ADVANCED DIALOGEX 0, 0, 286, 214 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x0 +BEGIN + CONTROL "Turn on presence signing (Jabber)",IDC_PRESCENSE_SUBSCRIPTION, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,9,190,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OPT_GPG, DIALOG + BEGIN + END + + IDD_OPT_GPG_BIN, DIALOG + BEGIN + END + + IDD_OPT_GPG_MESSAGES, DIALOG + BEGIN + END + + IDD_OPT_GPG_ADVANCED, DIALOG + BEGIN + VERTGUIDE, 12 + END +END +#endif // APSTUDIO_INVOKED + +#endif // Àíãëèéñêèé (ÑØÀ) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/New_GPG/src/clist.cpp b/plugins/New_GPG/src/clist.cpp new file mode 100755 index 0000000000..c64fb17798 --- /dev/null +++ b/plugins/New_GPG/src/clist.cpp @@ -0,0 +1,41 @@ +// Copyright © 2010-2012 SecureIM developers (baloo and others), sss +// +// 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 "commonheaders.h" + +extern HANDLE g_hCLIcon; +void RefreshContactListIcons(void); + +int onExtraImageListRebuilding(WPARAM, LPARAM) +{ + if(g_hCLIcon && ServiceExists(MS_CLIST_EXTRA_ADD_ICON) ) + RefreshContactListIcons(); + return 0; +} + + +int onExtraImageApplying(WPARAM wParam, LPARAM) +{ + void setClistIcon(HANDLE); + if(g_hCLIcon && ServiceExists(MS_CLIST_EXTRA_SET_ICON)) + { +// IconExtraColumn iec = {0}; //need to init this + if( g_hCLIcon ) + setClistIcon((HANDLE)wParam); +// ExtraIcon_SetIcon(g_hCLIcon, (HANDLE)wParam, iec.hImage); + } + return 0; +} diff --git a/plugins/New_GPG/src/commonheaders.h b/plugins/New_GPG/src/commonheaders.h new file mode 100755 index 0000000000..459d76ef64 --- /dev/null +++ b/plugins/New_GPG/src/commonheaders.h @@ -0,0 +1,88 @@ +// Copyright © 2010-2012 sss +// +// 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 COMMONHEADERS_H +#define COMMONHEADERS_H +#define MIRANDA_VER 0x0901 +//windows +#include +#include +#include +#include +#include +#include +//c +#include +#include +#include +//c++ +#include +#include +using std::map; +#include +using std::list; +#include +using std::vector; +#include +using std::string; +using std::wstring; +#include +using std::wfstream; +using std::fstream; + +//boost +#include +#include +#include +#include +#include +#include + + +//utf8cpp +#include + +//miranda +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "m_extraicons.h" +#include "m_metacontacts.h" +#include "resource.h" + + +//internal +#include "constants.h" +#include "log.h" +#include "globals.h" +#include "utilities.h" +#include "main.h" +#include "gpg_wrapper.h" +#include "jabber_account.h" +#include "metacontacts.h" +#endif diff --git a/plugins/New_GPG/src/constants.h b/plugins/New_GPG/src/constants.h new file mode 100755 index 0000000000..2982f31489 --- /dev/null +++ b/plugins/New_GPG/src/constants.h @@ -0,0 +1,5 @@ +#ifndef CONSTANTS_H +#define CONSTANTS_H +#define szGPGModuleName "GPG" +#define PREF_METANODB 0x2000 +#endif diff --git a/plugins/New_GPG/src/globals.h b/plugins/New_GPG/src/globals.h new file mode 100755 index 0000000000..e84ae1e505 --- /dev/null +++ b/plugins/New_GPG/src/globals.h @@ -0,0 +1,22 @@ +// Copyright © 2010-2012 sss +// +// 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 GLOBALS_H +#define GLOBALS_H +extern bool bAppendTags, bPresenceSigning, bStripTags, gpg_valid, gpg_keyexist, tabsrmm_used; +extern TCHAR *inopentag, *inclosetag, *outopentag, *outclosetag; +extern logtofile debuglog; +#endif diff --git a/plugins/New_GPG/src/gpg_wrapper.cpp b/plugins/New_GPG/src/gpg_wrapper.cpp new file mode 100755 index 0000000000..38f86889a4 --- /dev/null +++ b/plugins/New_GPG/src/gpg_wrapper.cpp @@ -0,0 +1,163 @@ +// Copyright © 2010-2012 sss +// +// 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 "commonheaders.h" + +//thx gpg module from Harald Treder, Zakhar V. Bardymov + +//boost::mutex gpg_mutex; + + +pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result, HANDLE hProcess, PROCESS_INFORMATION *pr) +{ +// gpg_mutex.lock(); + if(!gpg_valid) + return pxNotConfigured; + extern logtofile debuglog; + BOOL success; + STARTUPINFO sinfo = {0}; + SECURITY_ATTRIBUTES sattrs = {0}; + SECURITY_DESCRIPTOR sdesc = {0}; + PROCESS_INFORMATION pri = {0}; + HANDLE newstdin, newstdout, readstdout, writestdin; + char *inputpos; + unsigned long transfered; + int size; + + wstring commandline; + + sattrs.nLength=sizeof(SECURITY_ATTRIBUTES); + sattrs.bInheritHandle=TRUE; + InitializeSecurityDescriptor(&sdesc,SECURITY_DESCRIPTOR_REVISION); + SetSecurityDescriptorDacl(&sdesc,TRUE,NULL,FALSE); + sattrs.lpSecurityDescriptor=&sdesc; + + success=CreatePipe(&newstdin,&writestdin,&sattrs,0); + if (!success) + { + *result = pxCreatePipeFailed; + return pxCreatePipeFailed; + } + + success=CreatePipe(&readstdout,&newstdout,&sattrs,0); + if (!success) + { + CloseHandle(newstdin); + CloseHandle(writestdin); + *result = pxCreatePipeFailed; + return pxCreatePipeFailed; + } + + GetStartupInfo(&sinfo); + sinfo.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; + sinfo.wShowWindow=SW_HIDE; + sinfo.hStdOutput=newstdout; + sinfo.hStdError=newstdout; + sinfo.hStdInput=newstdin; + + char *mir_path = new char [MAX_PATH]; + CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); + SetCurrentDirectoryA(mir_path); + delete [] mir_path; + + TCHAR *bin_path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T("")); + { + if(_waccess(bin_path, 0) == -1) + { + if(errno == ENOENT) + { + mir_free(bin_path); + debuglog<c_str(); + + WaitForSingleObject(pri.hProcess,INFINITE); + + CloseHandle(pri.hThread); + CloseHandle(pri.hProcess); + CloseHandle(newstdin); + CloseHandle(newstdout); + CloseHandle(readstdout); + CloseHandle(writestdin); + + *result = pxSuccess; +// gpg_mutex.unlock(); + return pxSuccess; +} + +void pxEexcute_thread(void *param) +{ + gpg_execution_params *params = (gpg_execution_params*)param; + pxResult result = pxExecute(params->cmd, params->useless, params->out, params->code, params->result, params->hProcess, params->proc); +} diff --git a/plugins/New_GPG/src/gpg_wrapper.h b/plugins/New_GPG/src/gpg_wrapper.h new file mode 100755 index 0000000000..5501297baf --- /dev/null +++ b/plugins/New_GPG/src/gpg_wrapper.h @@ -0,0 +1,50 @@ +// Copyright © 2010-2012 sss +// +// 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 GPG_WRAPPER_H +#define GPG_WRAPPER_H +typedef enum { + pxSuccess, + pxSuccessExitCodeInvalid, + pxCreatePipeFailed, + pxDuplicateHandleFailed, + pxCloseHandleFailed, + pxCreateProcessFailed, + pxThreadWaitFailed, + pxReadFileFailed, + pxBufferOverflow, + pxNotFound, + pxNotConfigured +} +pxResult; + +pxResult pxExecute(wstring *acommandline, char *ainput, string *aoutput, LPDWORD aexitcode, pxResult *result); + +struct gpg_execution_params +{ + wstring *cmd; + char *useless; + string *out; + LPDWORD code; + pxResult *result; + HANDLE hProcess; + PROCESS_INFORMATION *proc; +}; + +void pxEexcute_thread(void *param); + +#endif \ No newline at end of file diff --git a/plugins/New_GPG/src/icons.cpp b/plugins/New_GPG/src/icons.cpp new file mode 100755 index 0000000000..c981eea46c --- /dev/null +++ b/plugins/New_GPG/src/icons.cpp @@ -0,0 +1,152 @@ +// Copyright © 2010-2012 SecureIM developers (baloo and others), sss +// +// 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 "commonheaders.h" + +HANDLE IconLibDefine(TCHAR* desc, TCHAR* section, char* ident, HICON icon, char* def_file, int def_idx, int size) +{ + SKINICONDESC sid = {0}; + HANDLE hIcon; + + if(!size) + size = 16; + + sid.cbSize = sizeof( SKINICONDESC ); + sid.ptszSection = section; + sid.ptszDescription = desc; + sid.flags = SIDF_TCHAR; + + sid.pszName = ident; + sid.pszDefaultFile = def_file; + sid.iDefaultIndex = def_idx; + sid.hDefaultIcon = icon; + sid.cx = sid.cy = size; + + hIcon = Skin_AddIcon(&sid); + + return hIcon; +} + + +void InitIconLib() +{ + extern HINSTANCE hInst; + char lib[MAX_PATH]; + GetModuleFileNameA(hInst, lib, MAX_PATH); + TCHAR *module = mir_a2t(szGPGModuleName); + + IconLibDefine(_T("Secured"), module, "secured", NULL, lib, -IDI_SECURED,0); + IconLibDefine(_T("Unsecured"), module, "unsecured", NULL, lib, -IDI_UNSECURED,0); + mir_free(module); +} + + + + + +HICON IconLibGetIcon(const char* ident) +{ + return (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)ident); +} + + + +void IconLibReleaseIcon(const char* ident) +{ + CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM)ident); +} + + + +HANDLE IconLibHookIconsChanged(MIRANDAHOOK hook) +{ + return HookEvent(ME_SKIN2_ICONSCHANGED, hook); +} + + +void setClistIcon(HANDLE hContact) +{ + bool enabled = isContactSecured(hContact); + extern HANDLE g_hCLIcon; + HANDLE hMC = hContact; + if(metaIsSubcontact(hContact)) + hMC = metaGetContact(hContact); + else if(metaIsProtoMetaContacts(hContact)) + hMC = metaGetContact(hContact); + if(g_hCLIcon && enabled) + { + HICON icon = IconLibGetIcon("secured"); + IconExtraColumn iec = {0}; + iec.cbSize = sizeof(iec); + iec.hImage = (HANDLE)CallService(MS_CLIST_EXTRA_ADD_ICON, (WPARAM)icon, (LPARAM)0); + ExtraIcon_SetIcon(g_hCLIcon, hContact, iec.hImage); + if(hMC) + ExtraIcon_SetIcon(g_hCLIcon, hMC, iec.hImage); + } + else + { + ExtraIcon_SetIcon(g_hCLIcon, hContact, (HANDLE)0); // is it right ? hmm.., at least working.... + if(hMC) + ExtraIcon_SetIcon(g_hCLIcon, hMC, (HANDLE)0); + } +} + +void setSrmmIcon(HANDLE h) +{ + HANDLE hContact = metaIsProtoMetaContacts(h)?metaGetMostOnline(h):h; + bool enabled = isContactSecured(hContact); + HANDLE hMC = hContact; + if(metaIsSubcontact(hContact)) + hMC = metaGetContact(hContact); + else if(metaIsProtoMetaContacts(hContact)) + hMC = metaGetContact(hContact); + if(ServiceExists(MS_MSG_MODIFYICON)) + { + StatusIconData sid = {0}; + sid.cbSize = sizeof(sid); + sid.szModule = szGPGModuleName; + sid.hIcon = IconLibGetIcon("secured"); + sid.dwId = 0x00000001; + sid.flags = enabled?0:MBF_HIDDEN; + CallService(MS_MSG_MODIFYICON, (WPARAM)hContact, (LPARAM)&sid); + if( hMC ) + CallService(MS_MSG_MODIFYICON, (WPARAM)hMC, (LPARAM)&sid); + ZeroMemory(&sid, sizeof(sid)); + sid.cbSize = sizeof(sid); + sid.szModule = szGPGModuleName; + sid.hIcon = IconLibGetIcon("unsecured"); + sid.dwId = 0x00000002; + sid.flags = enabled?MBF_HIDDEN:0; + CallService(MS_MSG_MODIFYICON, (WPARAM)hContact, (LPARAM)&sid); + if( hMC ) + CallService(MS_MSG_MODIFYICON, (WPARAM)hMC, (LPARAM)&sid); + } +} + + +void RefreshContactListIcons() +{ + HANDLE hContact; + extern HANDLE g_hCLIcon; + CallService(MS_CLUI_LISTBEGINREBUILD,0,0); + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact) + { + setClistIcon(hContact); + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + CallService(MS_CLUI_LISTENDREBUILD,0,0); +} diff --git a/plugins/New_GPG/src/init.cpp b/plugins/New_GPG/src/init.cpp new file mode 100755 index 0000000000..90030b0547 --- /dev/null +++ b/plugins/New_GPG/src/init.cpp @@ -0,0 +1,288 @@ +// Copyright © 2010-2012 sss +// +// 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 "commonheaders.h" + +//global variables +bool bAppendTags = false, bDebugLog = false, bJabberAPI = false, bPresenceSigning = false, bIsMiranda09 = false, bMetaContacts = false, bFileTransfers = false, bAutoExchange = false, bStripTags = false, tabsrmm_used = false; +TCHAR *inopentag = NULL, *inclosetag = NULL, *outopentag = NULL, *outclosetag = NULL, *password = NULL; + +list Accounts; + +HINSTANCE hInst; +HANDLE hLoadPubKey = NULL, hToggleEncryption = NULL, hOnPreBuildContactMenu = NULL, hSendKey = NULL, g_hCLIcon = NULL, hExportGpgKeys = NULL, hImportGpgKeys = NULL; +IconExtraColumn g_IEC = {0}; +static int OnModulesLoaded(WPARAM wParam,LPARAM lParam); +extern char *date(); +RECT key_from_keyserver_rect = {0}, firstrun_rect = {0}, new_key_rect = {0}, key_gen_rect = {0}, load_key_rect = {0}, import_key_rect = {0}, key_password_rect = {0}, load_existing_key_rect = {0}; +XML_API xi = {0}; +int hLangpack = 0; +logtofile debuglog; +bool gpg_valid = false, gpg_keyexist = false; +std::map hcontact_data; + + +#define MIID_GPG { 0x4227c050, 0x8d97, 0x48d2, { 0x91, 0xec, 0x6a, 0x95, 0x2b, 0x3d, 0xab, 0x94 } } + +PLUGININFOEX pluginInfo={ + sizeof(PLUGININFOEX), + 0, + PLUGIN_MAKE_VERSION(0,0,0,11), + "new GPG encryption support plugin, based on code from old gpg plugin and secureim", + "sss", + "sss123next@list.ru", + "© 2010-2012 sss", + "http://sss.chaoslab.ru/tracker/mim_plugs/", + 1, //unicode + MIID_GPG +}; + +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInst=hinstDLL; + return TRUE; +} + + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + static char plugname[52]; + strcpy(plugname, szGPGModuleName" ["); + strcat(plugname, date()); + strcat(plugname, " "); + strcat(plugname, __TIME__); + strcat(plugname, "]"); + pluginInfo.shortName = plugname; + return &pluginInfo; +} + +static const MUUID interfaces[] = {MIID_GPG, MIID_LAST}; +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +int LoadKey(WPARAM w, LPARAM l); +int ToggleEncryption(WPARAM w, LPARAM l); +int SendKey(WPARAM w, LPARAM l); +int ExportGpGKeys(WPARAM w, LPARAM l); +int ImportGpGKeys(WPARAM w, LPARAM l); + +void init_vars() +{ + bAppendTags = DBGetContactSettingByte(NULL, szGPGModuleName, "bAppendTags", 0); + bStripTags = DBGetContactSettingByte(NULL, szGPGModuleName, "bStripTags", 0); + inopentag = UniGetContactSettingUtf(NULL, szGPGModuleName, "szInOpenTag", _T("")); + inclosetag = UniGetContactSettingUtf(NULL, szGPGModuleName, "szInCloseTag", _T("")); + outopentag = UniGetContactSettingUtf(NULL, szGPGModuleName, "szOutOpenTag", _T("")); + outclosetag = UniGetContactSettingUtf(NULL, szGPGModuleName, "szOutCloseTag", _T("")); + bDebugLog = DBGetContactSettingByte(NULL, szGPGModuleName, "bDebugLog", 0); + bAutoExchange = DBGetContactSettingByte(NULL, szGPGModuleName, "bAutoExchange", 0); + password = UniGetContactSettingUtf(NULL, szGPGModuleName, "szKeyPassword", _T("")); + debuglog.init(); + bJabberAPI = DBGetContactSettingByte(NULL, szGPGModuleName, "bJabberAPI", bIsMiranda09?1:0); + bPresenceSigning = DBGetContactSettingByte(NULL, szGPGModuleName, "bPresenceSigning", 0); + bFileTransfers = DBGetContactSettingByte(NULL, szGPGModuleName, "bFileTransfers", 0); + firstrun_rect.left = DBGetContactSettingDword(NULL, szGPGModuleName, "FirstrunWindowX", 0); + firstrun_rect.top = DBGetContactSettingDword(NULL, szGPGModuleName, "FirstrunWindowY", 0); + key_password_rect.left = DBGetContactSettingDword(NULL, szGPGModuleName, "PasswordWindowX", 0); + key_password_rect.top = DBGetContactSettingDword(NULL, szGPGModuleName, "PasswordWindowY", 0); + key_gen_rect.left = DBGetContactSettingDword(NULL, szGPGModuleName, "KeyGenWindowX", 0); + key_gen_rect.top = DBGetContactSettingDword(NULL, szGPGModuleName, "KeyGenWindowY", 0); + load_key_rect.left = DBGetContactSettingDword(NULL, szGPGModuleName, "LoadKeyWindowX", 0); + load_key_rect.top = DBGetContactSettingDword(NULL, szGPGModuleName, "LoadKeyWindowY", 0); + import_key_rect.left = DBGetContactSettingDword(NULL, szGPGModuleName, "ImportKeyWindowX", 0); + import_key_rect.top = DBGetContactSettingDword(NULL, szGPGModuleName, "ImportKeyWindowY", 0); + new_key_rect.left = DBGetContactSettingDword(NULL, szGPGModuleName, "NewKeyWindowX", 0); + new_key_rect.top = DBGetContactSettingDword(NULL, szGPGModuleName, "NewKeyWindowY", 0); + load_existing_key_rect.left = DBGetContactSettingDword(NULL, szGPGModuleName, "LoadExistingKeyWindowX", 0); + load_existing_key_rect.top = DBGetContactSettingDword(NULL, szGPGModuleName, "LoadExistingKeyWindowY", 0); + tabsrmm_used = isTabsrmmUsed(); +} + +extern "C" int __declspec(dllexport) Load() +{ + HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded); + mir_getXI(&xi); //TODO: check if we have access to api + mir_getLP(&pluginInfo); + init_vars(); + CreateServiceFunction("/LoadPubKey",(MIRANDASERVICE)LoadKey); + CreateServiceFunction("/ToggleEncryption",(MIRANDASERVICE)ToggleEncryption); + CreateServiceFunction("/SendKey",(MIRANDASERVICE)SendKey); + CreateServiceFunction("/ExportGPGKeys",(MIRANDASERVICE)ExportGpGKeys); + CreateServiceFunction("/ImportGPGKeys",(MIRANDASERVICE)ImportGpGKeys); + CLISTMENUITEM mi = {0}; + mi.cbSize=sizeof(mi); + mi.position=-0x7FFFFFFF; + mi.flags=0; + mi.hIcon=LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + mi.pszName="Load GPG public key"; + mi.pszService="/LoadPubKey"; + hLoadPubKey = Menu_AddContactMenuItem(&mi); + ZeroMemory(&mi,sizeof(mi)); + mi.cbSize=sizeof(mi); + mi.position=-0x7FFFFFFe; + mi.flags=0; + mi.hIcon=LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + mi.pszName="Toggle GPG encryption"; + mi.pszService="/ToggleEncryption"; + hToggleEncryption = Menu_AddContactMenuItem(&mi); + ZeroMemory(&mi,sizeof(mi)); + mi.cbSize=sizeof(mi); + mi.position=-0x7FFFFFFe; + mi.flags=0; + mi.hIcon=LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + mi.pszName="Send public key"; + mi.pszService="/SendKey"; + hSendKey = Menu_AddContactMenuItem(&mi); + ZeroMemory(&mi,sizeof(mi)); + mi.cbSize=sizeof(mi); + mi.position=-0x7FFFFFFF; + mi.flags=0; + mi.hIcon=LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + mi.pszName="Export GPG Public keys from all users"; + mi.pszService="/ExportGPGKeys"; + hExportGpgKeys = Menu_AddMainMenuItem(&mi); + ZeroMemory(&mi,sizeof(mi)); + mi.cbSize=sizeof(mi); + mi.position=-0x7FFFFFFF; + mi.flags=0; + mi.hIcon=LoadSkinnedIcon(SKINICON_OTHER_MIRANDA); + mi.pszName="Import GPG Public keys from all users"; + mi.pszService="/ImportGPGKeys"; + hImportGpgKeys = Menu_AddMainMenuItem(&mi); + + return 0; +} + +int AddContact(WPARAM w, LPARAM l) +{ + CallService(MS_PROTO_ADDTOCONTACT,w,(LPARAM)szGPGModuleName); + return 0; +} + + +static int OnModulesLoaded(WPARAM wParam,LPARAM lParam) +{ + + int GpgOptInit(WPARAM wParam,LPARAM lParam); + int OnPreBuildContactMenu(WPARAM w, LPARAM l); + int RecvMsgSvc(WPARAM w, LPARAM l); + int SendMsgSvc(WPARAM w, LPARAM l); + int HookSendMsg(WPARAM w, LPARAM l); +// int TestHook(WPARAM w, LPARAM l); + int GetJabberInterface(WPARAM w, LPARAM l); + int onWindowEvent(WPARAM wParam, LPARAM lParam); + int onIconPressed(WPARAM wParam, LPARAM lParam); + int onExtraImageListRebuilding(WPARAM, LPARAM); + int onExtraImageApplying(WPARAM wParam, LPARAM); + int onProtoAck(WPARAM, LPARAM); + int onSendFile(WPARAM, LPARAM); + void InitIconLib(); + + void InitCheck(); + void FirstRun(); + bIsMiranda09 = (DWORD)CallService(MS_SYSTEM_GETVERSION, 0, 0) >= 0x00090001?true:false; + FirstRun(); + InitCheck(); + InitIconLib(); + if(ServiceExists(MS_MSG_ADDICON)) + { + HICON IconLibGetIcon(const char* ident); + StatusIconData sid = {0}; + sid.cbSize = sizeof(sid); + sid.szModule = szGPGModuleName; + sid.flags = MBF_HIDDEN; + sid.dwId = 0x00000001; + sid.hIcon = IconLibGetIcon("secured"); + sid.szTooltip = Translate("GPG Turn off encryption"); + CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid); + ZeroMemory(&sid, sizeof(sid)); + sid.cbSize = sizeof(sid); + sid.szModule = szGPGModuleName; + sid.flags = MBF_HIDDEN; + sid.dwId = 0x00000002; + sid.hIcon = IconLibGetIcon("unsecured"); + sid.szTooltip = Translate("GPG Turn on encryption"); + CallService(MS_MSG_ADDICON, 0, (LPARAM)&sid); + } + + + bMetaContacts = ServiceExists(MS_MC_GETMETACONTACT); + + if(bJabberAPI && bIsMiranda09) + GetJabberInterface(0,0); + + HookEvent(ME_OPT_INITIALISE, GpgOptInit); + HookEvent(ME_DB_EVENT_FILTER_ADD, HookSendMsg); + if(bJabberAPI && bIsMiranda09) + HookEvent(ME_PROTO_ACCLISTCHANGED, GetJabberInterface); + + HookEvent(ME_PROTO_ACK, onProtoAck); //filetransfer unimplemented now + + HookEvent(ME_CLIST_PREBUILDCONTACTMENU, OnPreBuildContactMenu); + + HookEvent(ME_MSG_WINDOWEVENT, onWindowEvent); + HookEvent(ME_MSG_ICONPRESSED, onIconPressed); + + if(ServiceExists(MS_EXTRAICON_REGISTER)) + g_hCLIcon = ExtraIcon_Register(szGPGModuleName, Translate("GPG encryption status"), "secured", (MIRANDAHOOK)onExtraImageListRebuilding, (MIRANDAHOOK)onExtraImageApplying); + + + + PROTOCOLDESCRIPTOR pd = {0}; + pd.cbSize=sizeof(PROTOCOLDESCRIPTOR); + pd.szName=szGPGModuleName; + pd.type=PROTOTYPE_ENCRYPTION; + CallService(MS_PROTO_REGISTERMODULE,0,(LPARAM)&pd); + + CreateProtoServiceFunction(szGPGModuleName, PSR_MESSAGE, (MIRANDASERVICE)RecvMsgSvc); + CreateProtoServiceFunction(szGPGModuleName, PSS_MESSAGE, (MIRANDASERVICE)SendMsgSvc); + CreateProtoServiceFunction(szGPGModuleName, PSR_MESSAGE"W", (MIRANDASERVICE)RecvMsgSvc); + CreateProtoServiceFunction(szGPGModuleName, PSS_MESSAGE"W", (MIRANDASERVICE)SendMsgSvc); + + CreateProtoServiceFunction(szGPGModuleName, PSS_FILE, (MIRANDASERVICE)onSendFile); + CreateProtoServiceFunction(szGPGModuleName, PSS_FILE"W", (MIRANDASERVICE)onSendFile); + + for (HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); hContact; hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) + if (!CallService(MS_PROTO_ISPROTOONCONTACT, (WPARAM)hContact, (LPARAM)szGPGModuleName)) + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)szGPGModuleName); + + HookEvent(ME_DB_CONTACT_ADDED,AddContact); + + + return 0; +} + +extern list transfers; +extern "C" int __declspec(dllexport) Unload(void) +{ +// for (HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); hContact; hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) +// DBDeleteContactSetting(hContact, szGPGModuleName, "KeyID_Prescense"); + if(!transfers.empty()) + { + for(list::iterator p = transfers.begin(); p != transfers.end(); p++) + if(!(*p).empty()) + DeleteFile((*p).c_str()); + } + mir_free(inopentag); + mir_free(inclosetag); + mir_free(outopentag); + mir_free(outclosetag); + if(password) + mir_free(password); + return 0; +} diff --git a/plugins/New_GPG/src/jabber_account.cpp b/plugins/New_GPG/src/jabber_account.cpp new file mode 100755 index 0000000000..6a264a490d --- /dev/null +++ b/plugins/New_GPG/src/jabber_account.cpp @@ -0,0 +1,85 @@ +// Copyright © 2010-2012 sss +// +// 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 "commonheaders.h" + +void JabberAccount::setAccountName(TCHAR *Name) +{ + AccountName = Name; +} +void JabberAccount::setAccountNumber(int Number) +{ + AccountNumber = Number; +} +void JabberAccount::setJabberInterface(IJabberInterface *JIf) +{ + JabberInterface = JIf; +} +void JabberAccount::setSendHandler(HJHANDLER hHandler) +{ + hSendHandler = hHandler; +} +void JabberAccount::setPrescenseHandler(HJHANDLER hHandler) +{ + hPrescenseHandler = hHandler; +} +void JabberAccount::setMessageHandler(HJHANDLER hHandler) +{ + hMessageHandler = hHandler; +} + + +TCHAR *JabberAccount::getAccountName() +{ + return AccountName; +} +int JabberAccount::getAccountNumber() +{ + return AccountNumber; +} +IJabberInterface *JabberAccount::getJabberInterface() +{ + return JabberInterface; +} +HJHANDLER JabberAccount::getSendHandler() +{ + return hSendHandler; +} +HJHANDLER JabberAccount::getPrescenseHandler() +{ + return hPrescenseHandler; +} + +HJHANDLER JabberAccount::getMessageHandler() +{ + return hMessageHandler; +} + + +JabberAccount::JabberAccount() +{ + AccountName = NULL; + hSendHandler = INVALID_HANDLE_VALUE; + hPrescenseHandler = INVALID_HANDLE_VALUE; + hMessageHandler = INVALID_HANDLE_VALUE; + AccountNumber = -1; + JabberInterface = NULL; +} +JabberAccount::~JabberAccount() +{ + if(AccountName) + mir_free(AccountName); +} \ No newline at end of file diff --git a/plugins/New_GPG/src/jabber_account.h b/plugins/New_GPG/src/jabber_account.h new file mode 100755 index 0000000000..b643ed1636 --- /dev/null +++ b/plugins/New_GPG/src/jabber_account.h @@ -0,0 +1,43 @@ +// Copyright © 2010-2012 sss +// +// 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 JABBER_ACCOUNT_H +#define JABBER_ACCOUNT_H +class JabberAccount +{ +public: + void setAccountName(TCHAR *Name); + void setAccountNumber(int Number); + void setJabberInterface(IJabberInterface *JIf); + void setSendHandler(HJHANDLER hHandler); + void setPrescenseHandler(HJHANDLER hHandler); + void setMessageHandler(HJHANDLER hHandler); + + TCHAR *getAccountName(); + int getAccountNumber(); + IJabberInterface *getJabberInterface(); + HJHANDLER getSendHandler(); + HJHANDLER getPrescenseHandler(); + HJHANDLER getMessageHandler(); + ~JabberAccount(); + JabberAccount(); +private: + TCHAR *AccountName; + int AccountNumber; + IJabberInterface *JabberInterface; + HJHANDLER hSendHandler, hPrescenseHandler, hMessageHandler; +}; + +#endif \ No newline at end of file diff --git a/plugins/New_GPG/src/log.cpp b/plugins/New_GPG/src/log.cpp new file mode 100755 index 0000000000..7618914f66 --- /dev/null +++ b/plugins/New_GPG/src/log.cpp @@ -0,0 +1,91 @@ +// Copyright © 2010-2012 sss +// +// 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 "commonheaders.h" + + +logtofile& logtofile::operator<<(TCHAR *buf) +{ + extern bool bDebugLog; + if(bDebugLog) + { + log_mutex.lock(); + log.open(toUTF8(path).c_str(), std::ios::app |std::ios::ate); + log<", p); + tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str()); + ListView_SetItemText(hwndList, iRow, 1, tmp); + mir_free(tmp); + p = out.find("ssb ", p2) + 6; + p = out.find(" ", p) + 1; + p2 = out.find("\n", p); + tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p-1)).c_str()); + ListView_SetItemText(hwndList, iRow, 3, tmp); + mir_free(tmp); + ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);// not sure about this + ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 4, LVSCW_AUTOSIZE); + i++; + } + } + } + { + SendMessageA(GetDlgItem(hwndDlg, IDC_ACCOUNT), CB_ADDSTRING, 0, (LPARAM)Translate("Default")); + int count = 0; + PROTOACCOUNT **accounts; + ProtoEnumAccounts(&count, &accounts); + for(int i = 0; i < count; i++) + { + if(StriStr(accounts[i]->szModuleName, "metacontacts")) + continue; + if(StriStr(accounts[i]->szModuleName, "weather")) + continue; + SendMessageA(GetDlgItem(hwndDlg, IDC_ACCOUNT), CB_ADDSTRING, 0, (LPARAM)accounts[i]->szModuleName); + } + SendMessageA(GetDlgItem(hwndDlg, IDC_ACCOUNT), CB_SELECTSTRING, 0, (LPARAM)Translate("Default")); + string keyinfo = Translate("key id"); + keyinfo += ": "; + char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", ""); + keyinfo += (strlen(keyid) > 0)?keyid:Translate("not set"); + mir_free(keyid); + SetDlgItemTextA(hwndDlg, IDC_KEY_ID, keyinfo.c_str()); + } + return TRUE; + } + + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_GENERATE_KEY: + void ShowKeyGenDialog(); + ShowKeyGenDialog(); + break; + case ID_OK: + { + ListView_GetItemText(hwndList, itemnum, 0, fp, 16); + TCHAR *name = new TCHAR [64]; + ListView_GetItemText(hwndList, itemnum, 2, name, 64); + { + if(_tcschr(name, _T('('))) + { + wstring str = name; + wstring::size_type p = str.find(_T("("))-1; + _tcscpy(name, str.substr(0, p).c_str()); + } + } + string out; + DWORD code; + wstring cmd = _T("--batch -a --export "); + cmd += fp; +// cmd += _T("\""); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog< user_data; + extern int item_num; + item_num = 0; //black magic here + user_data[1] = 0; + ShowLoadPublicKeyDialog(); + ListView_DeleteAllItems(hwndList); + { + int i = 1, iRow = 0; + item.mask = LVIF_TEXT; + item.iItem = i; + item.iSubItem = 0; + item.pszText = _T(""); + {//parse gpg output + string out; + DWORD code; + wstring::size_type p = 0, p2 = 0, stop = 0; + { + wstring cmd = _T("--batch --list-secret-keys"); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<", p); + tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str()); + ListView_SetItemText(hwndList, iRow, 1, tmp); + mir_free(tmp); + p = out.find("ssb ", p2) + 6; + p = out.find(" ", p) + 1; + p2 = out.find("\n", p); + tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p-1)).c_str()); + ListView_SetItemText(hwndList, iRow, 3, tmp); + mir_free(tmp); + ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);// not sure about this + ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 4, LVSCW_AUTOSIZE); + i++; + } + } + } + } + break; + case IDC_DELETE_KEY: + ListView_GetItemText(hwndList, itemnum, 0, fp, 16); + { + string out; + DWORD code; + wstring cmd = _T("--batch --fingerprint "); + cmd += fp; + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread->timed_join(boost::posix_time::seconds(10))) + { + delete gpg_thread; + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<timed_join(boost::posix_time::seconds(10))) + { + delete gpg_thread; + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog< 0)?keyid:Translate("not set"); + mir_free(keyid); + SetDlgItemTextA(hwndDlg, IDC_KEY_ID, keyinfo.c_str()); + } + else + { + string keyinfo = Translate("key id"); + keyinfo += ": "; + char setting[64]; + strcpy(setting, buf); + strcat(setting, "_KeyID"); + char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, setting, ""); + keyinfo += (strlen(keyid) > 0)?keyid:Translate("not set"); + mir_free(keyid); + SetDlgItemTextA(hwndDlg, IDC_KEY_ID, keyinfo.c_str()); + } + } + break; + + } + break; + } + + case WM_NOTIFY: + { + if(hdr && IsWindowVisible(hdr->hdr.hwndFrom) && hdr->iItem != (-1)) + { + if(hdr->hdr.code == NM_CLICK) + { + EnableWindow(GetDlgItem(hwndDlg, ID_OK), 1); + itemnum = hdr->iItem; + } + } +/* switch(LOWORD(wParam)) + { + default: + break; + }; */ +/* switch (((LPNMHDR)lParam)->code) + { + default: + break; + } */ + } + break; + case WM_CLOSE: + DestroyWindow(hwndDlg); + break; + case WM_DESTROY: + { + GetWindowRect(hwndDlg, &firstrun_rect); + DBWriteContactSettingDword(NULL, szGPGModuleName, "FirstrunWindowX", firstrun_rect.left); + DBWriteContactSettingDword(NULL, szGPGModuleName, "FirstrunWindowY", firstrun_rect.top); + } + hwndFirstRun = NULL; + break; + + } + + return FALSE; +} + +void ShowFirstRunDialog(); + +static BOOL CALLBACK DlgProcGpgBinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TCHAR *tmp = NULL; + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + TCHAR *path = new TCHAR [MAX_PATH]; + bool gpg_exists = false, lang_exists = false; + { + char *mir_path = new char [MAX_PATH]; + CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); + SetCurrentDirectoryA(mir_path); + tmp = mir_a2t(mir_path); + mir_free(mir_path); + mir_realloc(path, (_tcslen(path)+128)*sizeof(TCHAR)); + TCHAR *gpg_path = new TCHAR [MAX_PATH], *gpg_lang_path = new TCHAR [MAX_PATH]; + _tcscpy(gpg_path, tmp); + _tcscat(gpg_path, _T("\\GnuPG\\gpg.exe")); + _tcscpy(gpg_lang_path, tmp); + _tcscat(gpg_lang_path, _T("\\GnuPG\\gnupg.nls\\en@quot.mo")); + mir_free(tmp); + if(_waccess(gpg_path, 0) != -1) + { + gpg_exists = true; + _tcscpy(path, _T("GnuPG\\gpg.exe")); + } + if(_waccess(gpg_lang_path, 0) != -1) + lang_exists = true; + if(gpg_exists && !lang_exists) //TODO: check gpg version + MessageBox(0, TranslateT("gpg binary found in miranda folder, but english locale does not exists.\nit's highly recommended to place \\gnupg.nls\\en@quot.mo in gnupg folder under miranda root.\nwithout this file you may expirense many problem with gpg output on non english systems.\nand plugin may completely do not work.\nyou have beed warned."), TranslateT("Warning"), MB_OK); + mir_free(gpg_path); + mir_free(gpg_lang_path); + } + DWORD len = MAX_PATH; + if(!gpg_exists) + { + tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", (SHGetValue(HKEY_CURRENT_USER, _T("Software\\GNU\\GnuPG"), _T("gpgProgram"), 0, path, &len) == ERROR_SUCCESS)?path:_T("")); + if(tmp[0]) + { + char *mir_path = new char [MAX_PATH]; + CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); + SetCurrentDirectoryA(mir_path); + delete [] mir_path; + if(_waccess(tmp, 0) == -1) + { + if(errno == ENOENT) + MessageBox(0, TranslateT("wrong gpg binary location found in system.\nplease choose another location"), TranslateT("Warning"), MB_OK); + } + } + } + else + tmp = mir_wstrdup(path); + delete [] path; + SetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp); + bool bad_version = false; + if(gpg_exists && lang_exists) + { + DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp); + string out; + DWORD code; + wstring cmd = _T("--version"); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + gpg_valid = true; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<code) + { + default: + break; + }*/ + } + break; + case WM_CLOSE: + DestroyWindow(hwndDlg); + break; + case WM_DESTROY: + hwndSetDirs = NULL; + break; + + } + return FALSE; +} + +static BOOL CALLBACK DlgProcNewKeyDialog(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + extern HANDLE new_key_hcnt; + extern boost::mutex new_key_hcnt_mutex; + static HANDLE hContact = INVALID_HANDLE_VALUE; + void ImportKey(); + TCHAR *tmp = NULL; + switch (msg) + { + case WM_INITDIALOG: + { + hContact = new_key_hcnt; + new_key_hcnt_mutex.unlock(); + SetWindowPos(hwndDlg, 0, new_key_rect.left, new_key_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW); + TranslateDialogDefault(hwndDlg); + TCHAR *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); + SetDlgItemText(hwndDlg, IDC_MESSAGE, tmp[0]?TranslateT("There is existing key for contact, would you like to replace with new key ?"):TranslateT("New public key was received, do you want to import it?")); + EnableWindow(GetDlgItem(hwndDlg, IDC_IMPORT_AND_USE), DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0)?0:1); + SetDlgItemText(hwndDlg, ID_IMPORT, tmp[0]?TranslateT("Replace"):TranslateT("Accept")); + mir_free(tmp); + tmp = new TCHAR [256]; + _tcscpy(tmp, TranslateT("Received key from ")); + _tcscat(tmp, (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, (LPARAM)GCDNF_TCHAR)); + SetDlgItemText(hwndDlg, IDC_KEY_FROM, tmp); + delete [] tmp; + return TRUE; + } + + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case ID_IMPORT: + ImportKey(); + DestroyWindow(hwndDlg); + break; + case IDC_IMPORT_AND_USE: + ImportKey(); + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 1); + void setSrmmIcon(HANDLE hContact); + void setClistIcon(HANDLE hContact); + setSrmmIcon(hContact); + setClistIcon(hContact); + DestroyWindow(hwndDlg); + break; + case IDC_IGNORE_KEY: + DestroyWindow(hwndDlg); + break; + default: + break; + } + + break; + } + + case WM_NOTIFY: + { +/* switch (((LPNMHDR)lParam)->code) + { + default: + break; + }*/ + } + break; + case WM_CLOSE: + DestroyWindow(hwndDlg); + break; + case WM_DESTROY: + { + GetWindowRect(hwndDlg, &new_key_rect); + DBWriteContactSettingDword(NULL, szGPGModuleName, "NewKeyWindowX", new_key_rect.left); + DBWriteContactSettingDword(NULL, szGPGModuleName, "NewKeyWindowY", new_key_rect.top); + } + hwndNewKey = NULL; + break; + + } + return FALSE; +} +static BOOL CALLBACK DlgProcKeyGenDialog(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + { + SetWindowPos(hwndDlg, 0, key_gen_rect.left, key_gen_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW); + TranslateDialogDefault(hwndDlg); + SetWindowText(hwndDlg, TranslateT("Key Generation dialog")); + ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_KEY_TYPE), _T("RSA"), 0); + ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_KEY_TYPE), _T("DSA"), 1); + SendDlgItemMessage(hwndDlg, IDC_KEY_TYPE, CB_SETCURSEL, (WPARAM)1, 0); + SetDlgItemInt(hwndDlg, IDC_KEY_EXPIRE_DATE, 0, 0); + SetDlgItemInt(hwndDlg, IDC_KEY_LENGTH, 4096, 0); + return TRUE; + } + + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDCANCEL: + DestroyWindow(hwndDlg); + break; + case IDOK: + { + wstring path; + { //data sanity checks + TCHAR *tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*5); + GetDlgItemText(hwndDlg, IDC_KEY_TYPE, tmp, 5); + if(_tcslen(tmp) < 3) + { + mir_free(tmp); tmp = NULL; + MessageBox(0, TranslateT("You must set encryption algorythm first"), TranslateT("Error"), MB_OK); + break; + } + if(tmp) + mir_free(tmp); + tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*6); + GetDlgItemText(hwndDlg, IDC_KEY_LENGTH, tmp, 5); + int length = _ttoi(tmp); + mir_free(tmp); + if(length < 1024 || length > 4096) + { + MessageBox(0, TranslateT("Key length must be of length from 1024 to 4096 bits"), TranslateT("Error"), MB_OK); + break; + } + tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*12); + GetDlgItemText(hwndDlg, IDC_KEY_EXPIRE_DATE, tmp, 11); + if(_tcslen(tmp) != 10 && tmp[0] != '0') + { + MessageBox(0, TranslateT("Invalid date"), TranslateT("Error"), MB_OK); + mir_free(tmp); + break; + } + mir_free(tmp); + tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*128); + GetDlgItemText(hwndDlg, IDC_KEY_REAL_NAME, tmp, 127); + if(_tcslen(tmp) < 5) + { + MessageBox(0, TranslateT("Name must contain at least 5 characters"), TranslateT("Error"), MB_OK); + mir_free(tmp); + break; + } + else if (_tcschr(tmp, _T('(')) || _tcschr(tmp, _T(')'))) + { + MessageBox(0, TranslateT("Name cannot contain '(' or ')'"), TranslateT("Error"), MB_OK); + mir_free(tmp); + break; + } + mir_free(tmp); + tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*128); + GetDlgItemText(hwndDlg, IDC_KEY_EMAIL, tmp, 128); + if((_tcslen(tmp)) < 5 || (!_tcschr(tmp, _T('@'))) || (!_tcschr(tmp, _T('.')))) + { + MessageBox(0, TranslateT("Invalid Email"), TranslateT("Error"), MB_OK); + mir_free(tmp); + break; + } + mir_free(tmp); + } + { //generating key file + TCHAR *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + char *tmp2;// = mir_t2a(tmp); + path = tmp; + mir_free(tmp); + // mir_free(tmp2); + path.append(_T("\\new_key")); + wfstream f(path.c_str(), std::ios::out); + if(!f.is_open()) + { + MessageBox(0, TranslateT("Failed to open file"), TranslateT("Error"), MB_OK); + break; + } + f<<"Key-Type: "; + tmp = (TCHAR*)mir_alloc(sizeof(TCHAR)*5); + GetDlgItemText(hwndDlg, IDC_KEY_TYPE, tmp, 5); + tmp2 = mir_t2a(tmp); + mir_free(tmp); + char *subkeytype = (char*)mir_alloc(6); + if(strstr(tmp2, "RSA")) + strcpy(subkeytype, "RSA"); + else if(strstr(tmp2, "DSA")) //this is useless check for now, but it will be required if someone add another key types support + strcpy(subkeytype, "ELG-E"); + f<", p); + tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str()); + ListView_SetItemText(hwndList_g, iRow, 1, tmp); + mir_free(tmp); + p = out.find("ssb ", p2) + 6; + p = out.find(" ", p) + 1; + p2 = out.find("\n", p); + tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p-1)).c_str()); + ListView_SetItemText(hwndList_g, iRow, 3, tmp); + mir_free(tmp); + ListView_SetColumnWidth(hwndList_g, 0, LVSCW_AUTOSIZE);// not sure about this + ListView_SetColumnWidth(hwndList_g, 1, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList_g, 2, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList_g, 3, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList_g, 4, LVSCW_AUTOSIZE); + i++; + } + } + } + break; + default: + break; + } + + break; + } + + case WM_NOTIFY: + { +/* switch (((LPNMHDR)lParam)->code) + { + default: + break; + } */ + } + break; + case WM_CLOSE: + DestroyWindow(hwndDlg); + break; + case WM_DESTROY: + { + GetWindowRect(hwndDlg, &key_gen_rect); + DBWriteContactSettingDword(NULL, szGPGModuleName, "KeyGenWindowX", key_gen_rect.left); + DBWriteContactSettingDword(NULL, szGPGModuleName, "KeyGenWindowY", key_gen_rect.top); + } + hwndKeyGen = NULL; + break; + + } + return FALSE; +} + +int itemnum2 = 0; + +static BOOL CALLBACK DlgProcLoadExistingKey(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) +{ + HWND hwndList=GetDlgItem(hwndDlg, IDC_EXISTING_KEY_LIST); + hwndList_g = hwndList; + LVCOLUMN col = {0}; + LVITEM item = {0}; + NMLISTVIEW * hdr = (NMLISTVIEW *) lParam; + TCHAR id[16] = {0}; + switch (msg) + { + case WM_INITDIALOG: + { + SetWindowPos(hwndDlg, 0, load_existing_key_rect.left, load_existing_key_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW); + TranslateDialogDefault(hwndDlg); + col.pszText = _T("Key ID"); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 50; + ListView_InsertColumn(hwndList, 0, &col); + ZeroMemory(&col,sizeof(col)); + col.pszText = _T("Email"); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 30; + ListView_InsertColumn(hwndList, 1, &col); + ZeroMemory(&col,sizeof(col)); + col.pszText = _T("Name"); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 250; + ListView_InsertColumn(hwndList, 2, &col); + ZeroMemory(&col,sizeof(col)); + col.pszText = _T("Creation date"); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 30; + ListView_InsertColumn(hwndList, 3, &col); + ZeroMemory(&col,sizeof(col)); + col.pszText = _T("Expiration date"); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 30; + ListView_InsertColumn(hwndList, 4, &col); + ZeroMemory(&col,sizeof(col)); + col.pszText = _T("Key length"); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 30; + ListView_InsertColumn(hwndList, 5, &col); + ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_FULLROWSELECT); + int i = 1, iRow = 0; + { + item.mask = LVIF_TEXT; + item.iItem = i; + item.iSubItem = 0; + item.pszText = _T(""); + {//parse gpg output + string out; + DWORD code; + string::size_type p = 0, p2 = 0, stop = 0; + { + wstring cmd = _T("--batch --list-keys"); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<", p3); + tmp = mir_wstrdup(toUTF16(out.substr(p3,p4-p3)).c_str()); + ListView_SetItemText(hwndList, iRow, 1, tmp); + mir_free(tmp); + } + else + p2--; + p = out.find_first_not_of(" ", p); + tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p)).c_str()); + ListView_SetItemText(hwndList, iRow, 2, tmp); + mir_free(tmp); +// p = out.find("sub ", p2) + 6; +// p = out.find(" ", p) + 1; +// p2 = out.find("\n", p); +// tmp = mir_wstrdup(toUTF16(out.substr(p,p2-p-1)).c_str()); +// ListView_SetItemText(hwndList, iRow, 3, tmp); +// mir_free(tmp); + ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);// not sure about this + ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 4, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 5, LVSCW_AUTOSIZE); + i++; + } + } + } + return TRUE; + } + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDOK: + { + ListView_GetItemText(hwndList, itemnum2, 0, id, 16); + extern HWND hPubKeyEdit; + string out; + DWORD code; + wstring cmd = _T("--batch -a --export "); + cmd += id; + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<hdr.hwndFrom) && hdr->iItem != (-1)) + { + if(hdr->hdr.code == NM_CLICK) + { + EnableWindow(GetDlgItem(hwndDlg, IDOK), 1); + itemnum2 = hdr->iItem; + } + } + + switch (((LPNMHDR)lParam)->code) + { + + case PSN_APPLY: + { + return TRUE; + } + } + } + break; + case WM_CLOSE: + DestroyWindow(hwndDlg); + break; + case WM_DESTROY: + { + GetWindowRect(hwndDlg, &load_existing_key_rect); + DBWriteContactSettingDword(NULL, szGPGModuleName, "LoadExistingKeyWindowX", load_existing_key_rect.left); + DBWriteContactSettingDword(NULL, szGPGModuleName, "LoadExistingKeyWindowY", load_existing_key_rect.top); + } + hwndSelectExistingKey = NULL; + break; + + } + + return FALSE; +} +static BOOL CALLBACK DlgProcImportKeyDialog(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + extern HANDLE new_key_hcnt; + extern boost::mutex new_key_hcnt_mutex; + HANDLE hContact = INVALID_HANDLE_VALUE; + switch (msg) + { + case WM_INITDIALOG: + { + hContact = new_key_hcnt; + new_key_hcnt_mutex.unlock(); + SetWindowPos(hwndDlg, 0 , import_key_rect.left, import_key_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW); + TranslateDialogDefault(hwndDlg); + ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_KEYSERVER), _T("subkeys.pgp.net"), 0); + ComboBoxAddStringUtf(GetDlgItem(hwndDlg, IDC_KEYSERVER), _T("keys.gnupg.net"), 0); + return TRUE; + } + + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_IMPORT: + { + string out; + DWORD code; + wstring cmd = _T(" --keyserver \""); + TCHAR *server= new TCHAR [128]; + GetDlgItemText(hwndDlg, IDC_KEYSERVER, server, 128); + cmd += server; + delete [] server; + cmd += _T("\" --recv-keys "); +// char *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyID_Prescense", ""); +// TCHAR *tmp2 = mir_a2t(tmp); +// mir_free(tmp); + cmd += toUTF16(hcontact_data[hContact].key_in_prescense); +// mir_free(tmp2); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<code) + { + default: + break; + } */ + } + break; + case WM_CLOSE: + DestroyWindow(hwndDlg); + break; + case WM_DESTROY: + { + GetWindowRect(hwndDlg, &import_key_rect); + DBWriteContactSettingDword(NULL, szGPGModuleName, "ImportKeyWindowX", import_key_rect.left); + DBWriteContactSettingDword(NULL, szGPGModuleName, "ImportKeyWindowY", import_key_rect.top); + } + break; + + } + return FALSE; +} + + +extern HINSTANCE hInst; + + +void ShowFirstRunDialog() +{ + if (hwndFirstRun == NULL) + { + hwndFirstRun = CreateDialog(hInst, MAKEINTRESOURCE(IDD_FIRST_RUN), NULL, (DLGPROC)DlgProcFirstRun); + } + SetForegroundWindow(hwndFirstRun); +} + + +void ShowSetDirsDialog() +{ + if (hwndSetDirs == NULL) + { + hwndSetDirs = CreateDialog(hInst, MAKEINTRESOURCE(IDD_BIN_PATH), NULL, (DLGPROC)DlgProcGpgBinOpts); + } + SetForegroundWindow(hwndSetDirs); +} + +void ShowNewKeyDialog() +{ + hwndNewKey = CreateDialog(hInst, MAKEINTRESOURCE(IDD_NEW_KEY), NULL, (DLGPROC)DlgProcNewKeyDialog); + SetForegroundWindow(hwndNewKey); +} + +void ShowKeyGenDialog() +{ + if (hwndKeyGen == NULL) + { + hwndKeyGen = CreateDialog(hInst, MAKEINTRESOURCE(IDD_KEY_GEN), NULL, (DLGPROC)DlgProcKeyGenDialog); + } + SetForegroundWindow(hwndKeyGen); +} + +void ShowSelectExistingKeyDialog() +{ + if (hwndSelectExistingKey == NULL) + { + hwndSelectExistingKey = CreateDialog(hInst, MAKEINTRESOURCE(IDD_LOAD_EXISTING_KEY), NULL, (DLGPROC)DlgProcLoadExistingKey); + } + SetForegroundWindow(hwndSelectExistingKey); +} + +void ShowImportKeyDialog() +{ + CreateDialog(hInst, MAKEINTRESOURCE(IDD_IMPORT_KEY), NULL, (DLGPROC)DlgProcImportKeyDialog); +} + + + + +void FirstRun() +{ + DWORD pid = 0; + if(!DBGetContactSettingByte(NULL, szGPGModuleName, "FirstRun", 1)) + return; + ShowSetDirsDialog(); +} + +void InitCheck() +{ + {//parse gpg output + gpg_valid = isGPGValid(); + bool home_dir_access = false, temp_access = false; + TCHAR *home_dir = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + std::wstring test_path = home_dir; + mir_free(home_dir); + test_path += _T("/"); + test_path += toUTF16(get_random(13)); + wfstream test_file; + test_file.open(test_path, std::ios::trunc | std::ios::out); + if(test_file.is_open() && test_file.good()) + { + test_file<<_T("access_test\n"); + if(test_file.good()) + home_dir_access = true; + test_file.close(); + DeleteFile(test_path.c_str()); + } + home_dir = _tgetenv(_T("TEMP")); + test_path = home_dir; + test_path += _T("/"); + test_path += toUTF16(get_random(13)); + test_file.open(test_path, std::ios::trunc | std::ios::out); + if(test_file.is_open() && test_file.good()) + { + test_file<<_T("access_test\n"); + if(test_file.good()) + temp_access = true; + test_file.close(); + DeleteFile(test_path.c_str()); + } + if(!home_dir_access || !temp_access || !gpg_valid) + { + char buf[4096]; + strcpy(buf, gpg_valid?Translate("GPG binary is set and valid (this is good).\n"):Translate("GPG binary unset or invalid (plugin will not work).\n")); + strcat(buf, home_dir_access?Translate("Home dir write access granted (this is good).\n"):Translate("Home dir have not write access (plugin most probably will not work).\n")); + strcat(buf, temp_access?Translate("Temp dir write access granted (this is good).\n"):Translate("Temp dir have not write access (plugin should work, but may have some problems, filetransfers will not work).")); + if(!gpg_valid) + strcat(buf, Translate("\nGPG will be disabled until you solve this problems")); + MessageBoxA(0, buf, Translate("GPG plugin problems"), MB_OK); + } + if(!gpg_valid) + return; + gpg_keyexist = isGPGKeyExist(); + string out; + DWORD code; + pxResult result; + wstring::size_type p = 0, p2 = 0, stop = 0; + { + gpg_execution_params params; + wstring cmd = _T("--batch --list-secret-keys"); + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<szProtoName); + strcat(svc, PS_ICQ_ADDCAPABILITY); + if(ServiceExists(svc)) + CallService(svc, 0, (LPARAM)&cap); + } + } +} + +void ImportKey() +{ + extern wstring new_key; + extern HANDLE new_key_hcnt; + extern boost::mutex new_key_hcnt_mutex; + HANDLE hContact = new_key_hcnt; + new_key_hcnt_mutex.unlock(); + bool for_all_sub = false; + if(metaIsProtoMetaContacts(hContact)) + if(MessageBox(0, TranslateT("Do you want load key for all subcontacts ?"), TranslateT("Metacontact detected"), MB_YESNO) == IDYES) + for_all_sub = true; + if(metaIsProtoMetaContacts(hContact)) + { + HANDLE hcnt = NULL; + if(for_all_sub) + { + int count = metaGetContactsNum(hContact); + for(int i = 0; i < count; i++) + { + hcnt = metaGetSubcontact(hContact, i); + if(hcnt) + DBWriteContactSettingTString(hcnt, szGPGModuleName, "GPGPubKey", new_key.c_str()); + } + } + else + DBWriteContactSettingTString(metaGetMostOnline(hContact), szGPGModuleName, "GPGPubKey", new_key.c_str()); + } + else + DBWriteContactSettingTString(hContact, szGPGModuleName, "GPGPubKey", new_key.c_str()); + new_key.clear(); + { //gpg execute block + wstring cmd; + TCHAR tmp2[MAX_PATH] = {0}; + TCHAR *ptmp; + string output; + DWORD exitcode; + { + ptmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + _tcscpy(tmp2, ptmp); + mir_free(ptmp); + _tcscat(tmp2, _T("\\")); + _tcscat(tmp2, _T("temporary_exported.asc")); + DeleteFile(tmp2); + wfstream f(tmp2, std::ios::out); + if(metaIsProtoMetaContacts(hContact)) + ptmp = UniGetContactSettingUtf(metaGetMostOnline(hContact), szGPGModuleName, "GPGPubKey", _T("")); + else + ptmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); + wstring new_key = ptmp; + mir_free(ptmp); + f< output.find("<", s)) + s2 = output.find("<", s); + tmp = new char [output.substr(s,s2-s-1).length()+1]; + strcpy(tmp, output.substr(s,s2-s-1).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyMainName", tmp); + mir_free(tmp); + if((s = output.find(")", s2)) == string::npos) + s = output.find(">", s2); + else if(s > output.find(">", s2)) + s = output.find(">", s2); + s2++; + if(output[s] == ')') + { + tmp = new char [output.substr(s2,s-s2).length()+1]; + strcpy(tmp, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyComment", tmp); + mir_free(tmp); + s+=3; + s2 = output.find(">", s); + tmp = new char [output.substr(s,s2-s).length()+1]; + strcpy(tmp, output.substr(s,s2-s).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyMainEmail", tmp); + mir_free(tmp); + } + else + { + tmp = new char [output.substr(s2,s-s2).length()+1]; + strcpy(tmp, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); + mir_free(tmp); + } + DBDeleteContactSetting(hcnt, szGPGModuleName, "bAlwatsTrust"); + } + } + } + else + { + char *tmp = NULL; + string::size_type s = output.find("gpg: key ") + strlen("gpg: key "); + string::size_type s2 = output.find(":", s); + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str()); + s2+=2; + s = output.find("“", s2); + if(s == string::npos) + { + s = output.find("\"", s2); + s += 1; + } + else + s += 3; + if((s2 = output.find("(", s)) == string::npos) + s2 = output.find("<", s); + else if(s2 > output.find("<", s)) + s2 = output.find("<", s); + tmp = new char [output.substr(s,s2-s-1).length()+1]; + strcpy(tmp, output.substr(s,s2-s-1).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainName", tmp); + mir_free(tmp); + if((s = output.find(")", s2)) == string::npos) + s = output.find(">", s2); + else if(s > output.find(">", s2)) + s = output.find(">", s2); + s2++; + if(output[s] == ')') + { + tmp = new char [output.substr(s2,s-s2).length()+1]; + strcpy(tmp, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyComment", tmp); + mir_free(tmp); + s+=3; + s2 = output.find(">", s); + tmp = new char [output.substr(s,s2-s).length()+1]; + strcpy(tmp, output.substr(s,s2-s).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainEmail", tmp); + mir_free(tmp); + } + else + { + tmp = new char [output.substr(s2,s-s2).length()+1]; + strcpy(tmp, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); + mir_free(tmp); + } + DBDeleteContactSetting(metaGetMostOnline(hContact), szGPGModuleName, "bAlwatsTrust"); + } + } + else + { + char *tmp = NULL; + string::size_type s = output.find("gpg: key ") + strlen("gpg: key "); + string::size_type s2 = output.find(":", s); + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str()); + s2+=2; + s = output.find("“", s2); + if(s == string::npos) + { + s = output.find("\"", s2); + s += 1; + } + else + s += 3; + if((s2 = output.find("(", s)) == string::npos) + s2 = output.find("<", s); + else if(s2 > output.find("<", s)) + s2 = output.find("<", s); + tmp = new char [output.substr(s,s2-s-1).length()+1]; + strcpy(tmp, output.substr(s,s2-s-1).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainName", tmp); + mir_free(tmp); + if((s = output.find(")", s2)) == string::npos) + s = output.find(">", s2); + else if(s > output.find(">", s2)) + s = output.find(">", s2); + s2++; + if(output[s] == ')') + { + tmp = new char [output.substr(s2,s-s2).length()+1]; + strcpy(tmp, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyComment", tmp); + mir_free(tmp); + s+=3; + s2 = output.find(">", s); + tmp = new char [output.substr(s,s2-s).length()+1]; + strcpy(tmp, output.substr(s,s2-s).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", tmp); + mir_free(tmp); + } + else + { + tmp = new char [output.substr(s2,s-s2).length()+1]; + strcpy(tmp, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); + mir_free(tmp); + } + DBDeleteContactSetting(hContact, szGPGModuleName, "bAlwatsTrust"); + } + } + ptmp = mir_wstrdup(toUTF16(output).c_str()); + MessageBox(0, ptmp, _T(""), MB_OK); + mir_free(ptmp); + DeleteFile(tmp2); + } +} \ No newline at end of file diff --git a/plugins/New_GPG/src/main.h b/plugins/New_GPG/src/main.h new file mode 100755 index 0000000000..23627a415a --- /dev/null +++ b/plugins/New_GPG/src/main.h @@ -0,0 +1,31 @@ +// Copyright © 2010-2012 sss +// +// 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 MAIN_H +#define MAIN_H + +struct contact_data +{ + list msgs_to_send, msgs_to_pass; + string key_in_prescense; +}; + +extern std::map hcontact_data; +extern bool bAutoExchange; +extern RECT key_from_keyserver_rect, firstrun_rect, new_key_rect, key_gen_rect, load_key_rect, import_key_rect, key_password_rect, load_existing_key_rect; + +#endif + + diff --git a/plugins/New_GPG/src/messages.cpp b/plugins/New_GPG/src/messages.cpp new file mode 100755 index 0000000000..ba9a36c29c --- /dev/null +++ b/plugins/New_GPG/src/messages.cpp @@ -0,0 +1,1058 @@ +// Copyright © 2010-2012 sss +// +// 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 "commonheaders.h" + + +wstring new_key; +HANDLE new_key_hcnt = NULL; +boost::mutex new_key_hcnt_mutex; +bool _terminate = false; +int returnNoError(HANDLE hContact); + +std::list sent_msgs; + +int RecvMsgSvc_func(HANDLE hContact, std::wstring str, char *msg, DWORD flags, DWORD timestamp) +{ + DWORD dbflags = DBEF_UTF; + { //check for gpg related data + wstring::size_type s1 = wstring::npos, s2 = wstring::npos; + + s1 = str.find(_T("-----BEGIN PGP MESSAGE-----")); + s2 = str.find(_T("-----END PGP MESSAGE-----")); + if((s2 != wstring::npos) && (s1 != wstring::npos)) + { //this is generic encrypted data block + void setSrmmIcon(HANDLE); + void setClistIcon(HANDLE); + bool isContactHaveKey(HANDLE hContact); + if(!isContactSecured(hContact)) + { + debuglog< user_data; + extern int item_num; + item_num = 0; //black magic here + user_data[1] = hContact; + ShowLoadPublicKeyDialog(); + } + else + { + DBWriteContactSettingByte(metaIsProtoMetaContacts(hContact)?metaGetMostOnline(hContact):hContact, szGPGModuleName, "GPGEncryption", 1); + setSrmmIcon(hContact); + setClistIcon(hContact); + } + if(isContactHaveKey(hContact)) + { + DBWriteContactSettingByte(metaIsProtoMetaContacts(hContact)?metaGetMostOnline(hContact):hContact, szGPGModuleName, "GPGEncryption", 1); + setSrmmIcon(hContact); + setClistIcon(hContact); + } + } + else if(MessageBox(0, _T("Do you want try to decrypt encrypted message ?"), _T("Warning"), MB_YESNO) == IDNO) + { + + HistoryLog(hContact, db_event(msg, timestamp, 0, dbflags)); + return 0; + } + } + { + wstring::size_type p = 0; + while((p = str.find(_T("\r"), p)) != wstring::npos) + str.erase(p, 1); + } + s2 += _tcslen(_T("-----END PGP MESSAGE-----")); + char *tmp = mir_t2a(str.substr(s1,s2-s1).c_str()); + TCHAR *tmp2 = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + wstring path = tmp2; + wstring encfile = toUTF16(get_random(10)); + wstring decfile = toUTF16(get_random(10)); + path.append(_T("\\tmp\\")); + path.append(encfile); + DeleteFile(path.c_str()); + fstream f(path.c_str(), std::ios::out); + while(!f.is_open()) + f.open(path.c_str(), std::ios::out); + f<timed_join(boost::posix_time::seconds(10))) + { + delete gpg_thread; + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<timed_join(boost::posix_time::seconds(10))) + { + delete gpg_thread; + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<timed_join(boost::posix_time::seconds(10))) + { + delete gpg_thread; + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<lParam); + if (!pre) + return CallService(MS_PROTO_CHAINRECV, w, l); + char *msg = pre->szMessage; + if (!msg) + return CallService(MS_PROTO_CHAINRECV, w, l); + wstring str = toUTF16(msg); + wstring::size_type s1 = wstring::npos, s2 = wstring::npos; + DWORD dbflags = DBEF_UTF; + if((str.find(_T("-----PGP KEY RESPONSE-----")) != wstring::npos) && !metaIsProtoMetaContacts(ccs->hContact)) + { + s2 = str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")); + s1 = str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")); + if(s1 != wstring::npos && s2 != wstring::npos) + { + s2 += _tcslen(_T("-----END PGP PUBLIC KEY BLOCK-----")); + DBWriteContactSettingTString(ccs->hContact, szGPGModuleName, "GPGPubKey", str.substr(s1,s2-s1).c_str()); + DBWriteContactSettingByte(ccs->hContact, szGPGModuleName, "GPGEncryption", 1); + { //gpg execute block + wstring cmd; + TCHAR tmp2[MAX_PATH] = {0}; + TCHAR *ptmp; + string output; + DWORD exitcode; + { + ptmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + _tcscpy(tmp2, ptmp); + mir_free(ptmp); + _tcscat(tmp2, _T("\\")); + _tcscat(tmp2, _T("temporary_exported.asc")); + DeleteFile(tmp2); + wfstream f(tmp2, std::ios::out); + while(!f.is_open()) + f.open(tmp2, std::ios::out); + ptmp = UniGetContactSettingUtf(ccs->hContact, szGPGModuleName, "GPGPubKey", _T("")); + wstring new_key = ptmp; + mir_free(ptmp); + f<hContact, szGPGModuleName, "KeyID", output.substr(s,s2-s).c_str()); + s2+=2; + s = output.find("“", s2); + if(s == string::npos) + { + s = output.find("\"", s2); + s += 1; + } + else + s += 3; + if((s2 = output.find("(", s)) == string::npos) + s2 = output.find("<", s); + else if(s2 > output.find("<", s)) + s2 = output.find("<", s); + tmp = (char*)mir_alloc(output.substr(s,s2-s-1).length()+1); + strcpy(tmp, output.substr(s,s2-s-1).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(ccs->hContact, szGPGModuleName, "KeyMainName", tmp); + mir_free(tmp); + if((s = output.find(")", s2)) == string::npos) + s = output.find(">", s2); + else if(s > output.find(">", s2)) + s = output.find(">", s2); + s2++; + if(output[s] == ')') + { + tmp = (char*)mir_alloc(output.substr(s2,s-s2).length()+1); + strcpy(tmp, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(ccs->hContact, szGPGModuleName, "KeyComment", tmp); + mir_free(tmp); + s+=3; + s2 = output.find(">", s); + tmp = (char*)mir_alloc(output.substr(s,s2-s).length()+1); + strcpy(tmp, output.substr(s,s2-s).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(ccs->hContact, szGPGModuleName, "KeyMainEmail", tmp); + mir_free(tmp); + } + else + { + tmp = (char*)mir_alloc(output.substr(s2,s-s2).length()+1); + strcpy(tmp, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp, 0); + DBWriteContactSettingString(ccs->hContact, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); + mir_free(tmp); + } + DBWriteContactSettingByte(ccs->hContact, szGPGModuleName, "bAlwatsTrust", 1); + void setSrmmIcon(HANDLE); + void setClistIcon(HANDLE); + setSrmmIcon(ccs->hContact); + setClistIcon(ccs->hContact); + if(metaIsSubcontact(ccs->hContact)) + { + setSrmmIcon(metaGetContact(ccs->hContact)); + setClistIcon(metaGetContact(ccs->hContact)); + HistoryLog(metaGetContact(ccs->hContact), "PGP Encryption turned on by key autoexchange feature"); + } + HistoryLog(ccs->hContact, "PGP Encryption turned on by key autoexchange feature"); + } + } + return 1; + } + } + if((str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")) != wstring::npos) && (str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")) != wstring::npos)) + { + s2 = str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")); + s1 = str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")); + } + else if((str.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")) != wstring::npos) && (str.find(_T("-----END PGP PRIVATE KEY BLOCK-----")) != wstring::npos)) + { + s2 = str.find(_T("-----END PGP PRIVATE KEY BLOCK-----")); + s1 = str.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")); + } + if((s2 != wstring::npos) && (s1 != wstring::npos)) + { //this is public key + if(metaIsProtoMetaContacts(ccs->hContact)) + { + HistoryLog(ccs->hContact, db_event(msg, 0, 0, dbflags)); + return 0; + } + debuglog<hContact, GCDNF_TCHAR)<<"\n"; + s1 = 0; + while((s1 = str.find(_T("\r"), s1)) != wstring::npos) + { + str.erase(s1, 1); + } + void ShowNewKeyDialog(); + if((str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")) != wstring::npos) && (str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")) != wstring::npos)) + { + s2 = str.find(_T("-----END PGP PUBLIC KEY BLOCK-----")); + s1 = str.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")); + s2 += _tcslen(_T("-----END PGP PUBLIC KEY BLOCK-----")); + } + else if((str.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")) != wstring::npos) && (str.find(_T("-----END PGP PRIVATE KEY BLOCK-----")) != wstring::npos)) + { + s2 = str.find(_T("-----END PGP PRIVATE KEY BLOCK-----")); + s1 = str.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")); + s2 += _tcslen(_T("-----END PGP PRIVATE KEY BLOCK-----")); + } + new_key.append(str.substr(s1,s2-s1)); + new_key_hcnt_mutex.lock(); + new_key_hcnt = ccs->hContact; + ShowNewKeyDialog(); + HistoryLog(ccs->hContact, db_event(msg, 0, 0, dbflags)); + return 0; + } + if(bAutoExchange && strstr(msg, "-----PGP KEY REQUEST-----") && gpg_valid && gpg_keyexist) + { + char *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", ""); + if(tmp[0]) + { + DBWriteContactSettingByte(ccs->hContact, szGPGModuleName, "GPGEncryption", 0); + string str = "-----PGP KEY RESPONSE-----"; + str.append(tmp); + CallContactService(ccs->hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)str.c_str()); + DBWriteContactSettingByte(ccs->hContact, szGPGModuleName, "GPGEncryption", 1); + } + mir_free(tmp); + return returnNoError(ccs->hContact); + } + else if(!isContactHaveKey(ccs->hContact) && bAutoExchange && gpg_valid && gpg_keyexist) + { + LPSTR proto = (LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ccs->hContact, 0); + DWORD uin = DBGetContactSettingDword(ccs->hContact, proto, "UIN", 0); + if(uin) + { + char *proto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ccs->hContact, 0); + char svc[64]; + strcpy(svc, proto); + strcat(svc, PS_ICQ_CHECKCAPABILITY); + if(ServiceExists(svc)) + { + ICQ_CUSTOMCAP cap = {0}; + strcpy(cap.caps, "GPG AutoExchange"); + if(CallService(svc, (WPARAM)ccs->hContact, (LPARAM)&cap)) + { + CallContactService(ccs->hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)"-----PGP KEY REQUEST-----"); + return returnNoError(ccs->hContact); + } + } + } + else + { + TCHAR *jid = UniGetContactSettingUtf(ccs->hContact, proto, "jid", _T("")); + if(jid[0]) + { + extern list Accounts; + list::iterator end = Accounts.end(); + for(list::iterator p = Accounts.begin(); p != end; p++) + { + TCHAR *caps = (*p)->getJabberInterface()->Net()->GetResourceFeatures(jid); + if(caps) + { + wstring str; + for(int i =0;;i++) + { + str.push_back(caps[i]); + if(caps[i] == '\0') + if(caps[i+1] == '\0') + break; + } + mir_free(caps); + if(str.find(_T("GPG_Key_Auto_Exchange:0")) != string::npos) + { + CallContactService(ccs->hContact, PSS_MESSAGE, (WPARAM)0, (LPARAM)"-----PGP KEY REQUEST-----"); + return returnNoError(ccs->hContact); + } + } + } + } + } + } + if(!(strstr(msg, "-----BEGIN PGP MESSAGE-----") && strstr(msg, "-----END PGP MESSAGE-----"))) + return CallService(MS_PROTO_CHAINRECV, w, l); + boost::thread *thr = new boost::thread(boost::bind(RecvMsgSvc_func, ccs->hContact, str, msg, ccs->wParam, pre->timestamp)); + return returnNoError(ccs->hContact); +} + +int SendMsgSvc_func(HANDLE hContact, char *msg, DWORD flags) +{ + wstring str; + bool isansi = false; + DWORD dbflags = 0; + if(flags & PREF_UTF) + dbflags |= DBEF_UTF; + if(!metaIsSubcontact(hContact)) + str = toUTF16(msg); + else + {//workaround ... + wchar_t *tmp = mir_utf8decodeW(msg); + if(!tmp) + { + tmp = mir_a2t(msg); + isansi = true; + } + str.append(tmp); + mir_free(tmp); + } + if(bStripTags && bAppendTags) + { + std::wstring::size_type p; + for(p = str.find(inopentag); p != std::wstring::npos; p = str.find(inopentag)) + str.erase(p, _tcslen(inopentag)); + for(p = str.find(inclosetag); p != std::wstring::npos; p = str.find(inclosetag)) + str.erase(p, _tcslen(inclosetag)); + for(p = str.find(outopentag); p != std::wstring::npos; p = str.find(outopentag)) + str.erase(p, _tcslen(outopentag)); + for(p = str.find(outclosetag); p != std::wstring::npos; p = str.find(outclosetag)) + str.erase(p, _tcslen(outclosetag)); + } +/* for(std::wstring::size_type i = str.find(_T("\r\n")); i != std::wstring::npos; i = str.find(_T("\r\n"), i+1)) + str.replace(i, 2, _T("\n")); */ + string out; + DWORD code; + wstring cmd; + wstring file = toUTF16(get_random(10)); + wstring path; + extern bool bJabberAPI, bIsMiranda09; + char *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyID", ""); + if(!tmp[0]) + { + mir_free(tmp); + HistoryLog(hContact, db_event("Failed to encrypt message with GPG", 0,0, DBEF_SENT)); + hcontact_data[hContact].msgs_to_pass.push_back("Failed to encrypt message with GPG"); + mir_free(msg); + return CallContactService(hContact, PSS_MESSAGE, (WPARAM)flags, (LPARAM)msg); + } + if(!bJabberAPI || !bIsMiranda09) //force jabber to handle encrypted message by itself + cmd += _T("--comment \"\" --no-version "); + if(DBGetContactSettingByte(hContact, szGPGModuleName, "bAlwaysTrust", 0)) + cmd += _T("--trust-model always "); + cmd += _T("--batch --yes -e -a -t -r "); + TCHAR *tmp2 = mir_a2t(tmp); + mir_free(tmp); + cmd += tmp2; + mir_free(tmp2); + cmd += _T(" \""); + tmp2 = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + path.append(tmp2); + cmd += tmp2; + mir_free(tmp2); + cmd += _T("\\tmp\\"); + cmd += file; + path.append(_T("\\tmp\\")); + path += file; + cmd += _T("\""); + { + char *tmp; + tmp = mir_strdup(toUTF8(str).c_str()); + fstream f(path.c_str(), std::ios::out); + while(!f.is_open()) + f.open(path.c_str(), std::ios::out); + f<lParam)); + if (!msg) + { + mir_free(msg); + return CallService(MS_PROTO_CHAINSEND, w, l); + } + if(strstr(msg,"-----BEGIN PGP MESSAGE-----")) + return CallService(MS_PROTO_CHAINSEND, w, l); + if(!isContactHaveKey(ccs->hContact)) + { + if(bAutoExchange && !strstr(msg, "-----PGP KEY REQUEST-----") && !strstr(msg, "-----BEGIN PGP PUBLIC KEY BLOCK-----") && gpg_valid) + { + void send_encrypted_msgs_thread(HANDLE hContact); + LPSTR proto = (LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ccs->hContact, 0); + DWORD uin = DBGetContactSettingDword(ccs->hContact, proto, "UIN", 0); + if(uin) + { + char *proto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)ccs->hContact, 0); + char svc[64]; + strcpy(svc, proto); + strcat(svc, PS_ICQ_CHECKCAPABILITY); + + if(ServiceExists(svc)) + { + ICQ_CUSTOMCAP cap = {0}; + strcpy(cap.caps, "GPG AutoExchange"); + if(CallService(svc, (WPARAM)ccs->hContact, (LPARAM)&cap)) + { + CallContactService(ccs->hContact, PSS_MESSAGE, (WPARAM)ccs->wParam, (LPARAM)"-----PGP KEY REQUEST-----"); + hcontact_data[ccs->hContact].msgs_to_send.push_back(msg); + boost::thread *thr = new boost::thread(boost::bind(send_encrypted_msgs_thread, ccs->hContact)); + mir_free(msg); + return returnNoError(ccs->hContact); + } + } + } + else + { + TCHAR *jid = UniGetContactSettingUtf(ccs->hContact, proto, "jid", _T("")); + if(jid[0]) + { + extern list Accounts; + list::iterator end = Accounts.end(); + for(list::iterator p = Accounts.begin(); p != end; p++) + { + TCHAR *caps = (*p)->getJabberInterface()->Net()->GetResourceFeatures(jid); + if(caps) + { + wstring str; + for(int i=0;;i++) + { + str.push_back(caps[i]); + if(caps[i] == '\0') + if(caps[i+1] == '\0') + break; + } + mir_free(caps); + if(str.find(_T("GPG_Key_Auto_Exchange:0")) != string::npos) + { + CallContactService(ccs->hContact, PSS_MESSAGE, (WPARAM)ccs->wParam, (LPARAM)"-----PGP KEY REQUEST-----"); + hcontact_data[ccs->hContact].msgs_to_send.push_back(msg); + boost::thread *thr = new boost::thread(boost::bind(send_encrypted_msgs_thread, ccs->hContact)); + mir_free(msg); + return returnNoError(ccs->hContact); + } + } + } + } + } + } + else + { + mir_free(msg); + return CallService(MS_PROTO_CHAINSEND, w, l); + } + } + if(!isContactSecured(ccs->hContact) || metaIsProtoMetaContacts(ccs->hContact)) + { + mir_free(msg); + return CallService(MS_PROTO_CHAINSEND, w, l); + } + boost::thread *thr = new boost::thread(boost::bind(SendMsgSvc_func, ccs->hContact, msg, (DWORD)ccs->wParam)); + return returnNoError(ccs->hContact); +} + +boost::mutex event_processing_mutex; + +int HookSendMsg(WPARAM w, LPARAM l) +{ + if(!l) + return 0; + DBEVENTINFO * dbei = (DBEVENTINFO*)l; + if(dbei->eventType != EVENTTYPE_MESSAGE) + return 0; + if(dbei->flags & DBEF_SENT) + { + if(strstr((char*)dbei->pBlob, "-----BEGIN PGP MESSAGE-----") || strstr((char*)dbei->pBlob, "-----PGP KEY RESPONSE-----") || strstr((char*)dbei->pBlob, "-----PGP KEY REQUEST-----") || strstr((char*)dbei->pBlob, "-----PGP KEY RESPONSE-----")) //our service data, can be double added by metacontacts e.t.c. + return 1; + } + HANDLE hContact = (HANDLE)w; + if(isContactSecured(hContact) && (dbei->flags & DBEF_SENT)) //aggressive outgoing events filtering + { + if(!hcontact_data[hContact].msgs_to_pass.empty()) + { + event_processing_mutex.lock(); + std::list::iterator end = hcontact_data[hContact].msgs_to_pass.end(); + for(std::list::iterator i = hcontact_data[hContact].msgs_to_pass.begin(); i != end; ++i) + { + if(!strcmp((*i).c_str(), (char*)dbei->pBlob)) + { + hcontact_data[hContact].msgs_to_pass.erase(i); + debuglog<pBlob<<"\" passed event filter, contact "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)<<", message is in allowed list\n"; + event_processing_mutex.unlock(); + return 0; + } + } + event_processing_mutex.unlock(); + } + if(metaIsProtoMetaContacts(hContact) && !isContactSecured(metaGetMostOnline(hContact))) + return 0; + return 1; + } + if(!isContactSecured(hContact)) + { + debuglog<pBlob<<"\" passed event filter, contact "<<(TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR)<<" is unsecured\n"; + return 0; + } + if(!(dbei->flags & DBEF_SENT) && metaIsProtoMetaContacts((HANDLE)w)) + { + char tmp[29]; + strncpy(tmp, (char*)dbei->pBlob, 27); + tmp[28] = '\0'; + if(strstr(tmp, "-----BEGIN PGP MESSAGE-----")) + return 1; + } + return 0; +} + + +static BOOL CALLBACK DlgProcKeyPassword(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + char *inkeyid = NULL; + switch (msg) + { + case WM_INITDIALOG: + { + inkeyid = UniGetContactSettingUtf(new_key_hcnt, szGPGModuleName, "InKeyID", ""); + new_key_hcnt_mutex.unlock(); + TCHAR *tmp = NULL; + + SetWindowPos(hwndDlg, 0, key_password_rect.left, key_password_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW); + TranslateDialogDefault(hwndDlg); + string questionstr = "Please enter password for key with ID: "; + questionstr += inkeyid; + SetDlgItemTextA(hwndDlg, IDC_KEYID, questionstr.c_str()); + EnableWindow(GetDlgItem(hwndDlg, IDC_DEFAULT_PASSWORD), 0); + return TRUE; + } + + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDOK: + { + TCHAR tmp[64]; + GetDlgItemText(hwndDlg, IDC_KEY_PASSWORD, tmp, 64); + if(tmp[0]) + { + extern TCHAR *password; + if(IsDlgButtonChecked(hwndDlg, IDC_SAVE_PASSWORD)) + { + if(inkeyid && inkeyid[0] && !IsDlgButtonChecked(hwndDlg, IDC_DEFAULT_PASSWORD)) + { + string dbsetting = "szKey_"; + dbsetting += inkeyid; + dbsetting += "_Password"; + DBWriteContactSettingTString(NULL, szGPGModuleName, dbsetting.c_str(), tmp); + } + else + DBWriteContactSettingTString(NULL, szGPGModuleName, "szKeyPassword", tmp); + } + if(password) + delete [] password; + password = new TCHAR [_tcslen(tmp)+1]; + _tcscpy(password, tmp); + } + mir_free(tmp); + mir_free(inkeyid); + DestroyWindow(hwndDlg); + break; + } + case IDCANCEL: + mir_free(inkeyid); + _terminate = true; + DestroyWindow(hwndDlg); + break; + default: + break; + } + + break; + } + + case WM_NOTIFY: + { +/* switch (((LPNMHDR)lParam)->code) + { + default: + EnableWindow(GetDlgItem(hwndDlg, IDC_DEFAULT_PASSWORD), IsDlgButtonChecked(hwndDlg, IDC_SAVE_PASSWORD)?1:0); + break; + }*/ + } + break; + case WM_CLOSE: + mir_free(inkeyid); + DestroyWindow(hwndDlg); + break; + case WM_DESTROY: + { + GetWindowRect(hwndDlg, &key_password_rect); + DBWriteContactSettingDword(NULL, szGPGModuleName, "PasswordWindowX", key_password_rect.left); + DBWriteContactSettingDword(NULL, szGPGModuleName, "PasswordWindowY", key_password_rect.top); + } + break; + + } + return FALSE; +} + +void ShowLoadKeyPasswordWindow() +{ + extern HINSTANCE hInst; + DialogBox(hInst, MAKEINTRESOURCE(IDD_KEY_PASSWD), NULL, (DLGPROC)DlgProcKeyPassword); +} diff --git a/plugins/New_GPG/src/metacontacts.cpp b/plugins/New_GPG/src/metacontacts.cpp new file mode 100755 index 0000000000..1abc2aaeac --- /dev/null +++ b/plugins/New_GPG/src/metacontacts.cpp @@ -0,0 +1,88 @@ +// Copyright © 2010-2012 SecureIM developers (baloo and others), sss +// +// 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 "commonheaders.h" + +extern bool bMetaContacts; + +bool metaIsProtoMetaContacts(HANDLE hContact) +{ + if(bMetaContacts) { + LPSTR proto = (LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if( proto && strcmp(proto,"MetaContacts")==0 ) { + return true; + } + } + return false; +} + + +bool metaIsDefaultSubContact(HANDLE hContact) +{ + + if(bMetaContacts) + return (HANDLE)CallService(MS_MC_GETDEFAULTCONTACT,(WPARAM)CallService(MS_MC_GETMETACONTACT,(WPARAM)hContact,0),0)==hContact; + return false; +} + + +HANDLE metaGetContact(HANDLE hContact) +{ + if(bMetaContacts) + if(metaIsSubcontact(hContact)) + return (HANDLE)CallService(MS_MC_GETMETACONTACT,(WPARAM)hContact,0); + return NULL; +} +bool metaIsSubcontact(HANDLE hContact) +{ + if(bMetaContacts) + return (HANDLE)CallService(MS_MC_GETMETACONTACT,(WPARAM)hContact,0); + return false; +} + + +HANDLE metaGetMostOnline(HANDLE hContact) +{ + + if(bMetaContacts) + if(metaIsProtoMetaContacts(hContact)) + return (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT,(WPARAM)hContact,0); + return NULL; +} +HANDLE metaGetDefault(HANDLE hContact) +{ + + if(bMetaContacts) + if(metaIsProtoMetaContacts(hContact)) + return (HANDLE)CallService(MS_MC_GETDEFAULTCONTACT,(WPARAM)hContact,0); + return NULL; +} + + +DWORD metaGetContactsNum(HANDLE hContact) +{ + if(bMetaContacts) + return CallService(MS_MC_GETNUMCONTACTS, (WPARAM)hContact, 0); + return 0; +} +HANDLE metaGetSubcontact(HANDLE hContact, int num) +{ + if(bMetaContacts) + return (HANDLE)CallService(MS_MC_GETSUBCONTACT, (WPARAM)hContact, (LPARAM)num); + return 0; +} + + diff --git a/plugins/New_GPG/src/metacontacts.h b/plugins/New_GPG/src/metacontacts.h new file mode 100755 index 0000000000..8b8873edcc --- /dev/null +++ b/plugins/New_GPG/src/metacontacts.h @@ -0,0 +1,24 @@ +// Copyright © 2010-2012 sss +// +// 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. + +bool metaIsProtoMetaContacts(HANDLE hContact); +bool metaIsDefaultSubContact(HANDLE hContact) ; +HANDLE metaGetContact(HANDLE hContact); +bool metaIsSubcontact(HANDLE hContact); +HANDLE metaGetMostOnline(HANDLE hContact); +HANDLE metaGetDefault(HANDLE hContact); +DWORD metaGetContactsNum(HANDLE hContact); +HANDLE metaGetSubcontact(HANDLE hContact, int num); \ No newline at end of file diff --git a/plugins/New_GPG/src/options.cpp b/plugins/New_GPG/src/options.cpp new file mode 100755 index 0000000000..f03879c48b --- /dev/null +++ b/plugins/New_GPG/src/options.cpp @@ -0,0 +1,1387 @@ +// Copyright © 2010-2012 sss +// +// 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 "commonheaders.h" + +extern HINSTANCE hInst; + +static BOOL CALLBACK DlgProcGpgOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static BOOL CALLBACK DlgProcGpgBinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static BOOL CALLBACK DlgProcGpgMsgOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static BOOL CALLBACK DlgProcGpgAdvOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +BOOL CheckStateLoadDB(HWND hwndDlg, int idCtrl, const char* szSetting, BYTE bDef) +{ + BOOL state = DBGetContactSettingByte(NULL, szGPGModuleName, szSetting, bDef); + CheckDlgButton(hwndDlg, idCtrl, state); + return state; +} + +BOOL CheckStateStoreDB(HWND hwndDlg, int idCtrl, const char* szSetting) +{ + BOOL state = IsDlgButtonChecked(hwndDlg, idCtrl); + DBWriteContactSettingByte(NULL, szGPGModuleName, szSetting, (BYTE)state); + return state; +} + + +int GpgOptInit(WPARAM wParam,LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_GPG); + odp.pszTitle = szGPGModuleName; + odp.pszGroup = "Services"; + odp.pszTab = "Main"; + odp.flags=ODPF_BOLDGROUPS; + odp.pfnDlgProc = (DLGPROC)DlgProcGpgOpts; + Options_AddPage(wParam, &odp); + + ZeroMemory(&odp, sizeof(odp)); + + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_GPG_BIN); + odp.pszTitle = szGPGModuleName; + odp.pszGroup = "Services"; + odp.pszTab = "GnuPG Variables"; + odp.flags=ODPF_BOLDGROUPS; + odp.pfnDlgProc = (DLGPROC)DlgProcGpgBinOpts; + Options_AddPage(wParam, &odp); + + ZeroMemory(&odp, sizeof(odp)); + + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_GPG_MESSAGES); + odp.pszTitle = szGPGModuleName; + odp.pszGroup = "Services"; + odp.pszTab = "Messages"; + odp.flags=ODPF_BOLDGROUPS; + odp.pfnDlgProc = (DLGPROC)DlgProcGpgMsgOpts; + Options_AddPage(wParam, &odp); + + ZeroMemory(&odp, sizeof(odp)); + + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_GPG_ADVANCED); + odp.pszTitle = szGPGModuleName; + odp.pszGroup = "Services"; + odp.pszTab = "Advanced"; + odp.flags=ODPF_BOLDGROUPS | ODPF_EXPERTONLY; + odp.pfnDlgProc = (DLGPROC)DlgProcGpgAdvOpts; + Options_AddPage(wParam, &odp); + + return 0; +} + +map user_data; + +int item_num = 0; +HWND hwndList_p = NULL; +HWND hwndCurKey_p = NULL; + +void ShowLoadPublicKeyDialog(); +static BOOL CALLBACK DlgProcGpgOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND hwndList=GetDlgItem(hwndDlg, IDC_USERLIST); + hwndList_p = hwndList; + hwndCurKey_p = GetDlgItem(hwndDlg, IDC_CURRENT_KEY); + LVCOLUMN col = {0}; + LVITEM item = {0}; + TCHAR *tmp = NULL; + char *tmp2 = NULL; + extern bool bIsMiranda09, bJabberAPI; + NMLISTVIEW * hdr = (NMLISTVIEW *) lParam; + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + col.pszText = TranslateW(_T("Contact")); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 60; + ListView_InsertColumn(hwndList, 0, &col); + ZeroMemory(&col,sizeof(col)); + col.pszText = TranslateW(_T("Key ID")); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 50; + ListView_InsertColumn(hwndList, 1, &col); + ZeroMemory(&col,sizeof(col)); + col.pszText = TranslateW(_T("Name")); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 50; + ListView_InsertColumn(hwndList, 2, &col); + ZeroMemory(&col,sizeof(col)); + col.pszText = TranslateW(_T("Email")); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 50; + ListView_InsertColumn(hwndList, 3, &col); + ZeroMemory(&col,sizeof(col)); + col.pszText = TranslateW(_T("Protocol")); + col.mask = LVCF_TEXT | LVCF_WIDTH; + col.fmt = LVCFMT_LEFT; + col.cx = 60; + ListView_InsertColumn(hwndList, 4, &col); + ListView_SetExtendedListViewStyleEx(hwndList, 0, LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT); + int i = 1, iRow = 0; + bool isContactHaveKey(HANDLE); + for(HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); hContact != NULL; hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) + { + if(isContactHaveKey(hContact)) + { + TCHAR *name = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR); + item.mask = LVIF_TEXT; + item.iItem = i; + item.iSubItem = 0; + item.pszText = name; + iRow = ListView_InsertItem(hwndList, &item); + ListView_SetItemText(hwndList, iRow, 0, name); + TCHAR *tmp = mir_a2t((char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0)); + ListView_SetItemText(hwndList, iRow, 4, tmp); + mir_free(tmp); + tmp2 = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyID", ""); + tmp = mir_a2t(tmp2); + mir_free(tmp2); + ListView_SetItemText(hwndList, iRow, 1, (_tcslen(tmp) > 1)?tmp:_T("not set")); + mir_free(tmp); + char *tmp2 = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyMainName", ""); + if(!toUTF16(tmp2).empty()) + tmp = mir_wstrdup(toUTF16(tmp2).c_str()); + else + tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyMainName", _T("")); + mir_free(tmp2); + ListView_SetItemText(hwndList, iRow, 2, (_tcslen(tmp) > 1)?tmp:_T("not set")); + mir_free(tmp); + tmp2 = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyMainEmail", ""); + if(!toUTF16(tmp2).empty()) + tmp = mir_wstrdup(toUTF16(tmp2).c_str()); + else + tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyMainEmail", _T("")); + mir_free(tmp2); + ListView_SetItemText(hwndList, iRow, 3, (_tcslen(tmp) > 1)?tmp:_T("not set")); + mir_free(tmp); + if(DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0)) + ListView_SetCheckState(hwndList, iRow, 1); + user_data[i] = hContact; + ZeroMemory(&item,sizeof(item)); + ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE);// not sure about this + ListView_SetColumnWidth(hwndList, 1, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 2, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 3, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList, 4, LVSCW_AUTOSIZE); + i++; + } + } + tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szLogFilePath", _T("")); + SetDlgItemText(hwndDlg, IDC_LOG_FILE_EDIT, (_tcslen(tmp) > 1)?tmp:_T("c:\\GPGdebug.log")); + mir_free(tmp); + CheckStateLoadDB(hwndDlg, IDC_DEBUG_LOG, "bDebugLog", 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_JABBER_API), bIsMiranda09); + EnableWindow(GetDlgItem(hwndDlg, IDC_AUTO_EXCHANGE), (bIsMiranda09 && bJabberAPI)); + { + string keyinfo = Translate("Default private key id"); + keyinfo += ": "; + char *keyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", ""); + keyinfo += (strlen(keyid) > 0)?keyid:Translate("not set"); + mir_free(keyid); + SetDlgItemTextA(hwndDlg, IDC_CURRENT_KEY, keyinfo.c_str()); + } + if(bIsMiranda09) + CheckStateLoadDB(hwndDlg, IDC_JABBER_API, "bJabberAPI", 1); + CheckStateLoadDB(hwndDlg, IDC_FILE_TRANSFERS, "bFileTransfers", 0); + CheckStateLoadDB(hwndDlg, IDC_AUTO_EXCHANGE, "bAutoExchange", 0); + return TRUE; + } + + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_DELETE_KEY_BUTTON: + void setClistIcon(HANDLE hContact); + void setSrmmIcon(HANDLE hContact); + { //gpg execute block + TCHAR tmp2[MAX_PATH] = {0}; + TCHAR *ptmp; + char *tmp; + bool keep = false; + bool ismetacontact = false; + HANDLE meta = NULL; + HANDLE hContact = user_data[item_num+1]; + if(metaIsProtoMetaContacts(hContact)) + { + meta = hContact; + hContact = metaGetMostOnline(hContact); + ismetacontact = true; + } + else if((meta = metaGetContact(user_data[item_num+1])) != NULL) + { + hContact = metaGetMostOnline(meta); + ismetacontact = true; + } + tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyID", ""); + for(HANDLE hcnttmp = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); hcnttmp != NULL; hcnttmp = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hcnttmp, 0)) + { + if(hcnttmp != hContact) + { + char *tmp2 = UniGetContactSettingUtf(hcnttmp, szGPGModuleName, "KeyID", ""); + if(!strcmp(tmp, tmp2)) + { + mir_free(tmp2); + keep = true; + break; + } + mir_free(tmp2); + } + } + if(!keep) + if(MessageBox(0, _T("This key not used by any contact, do you want to remove it from public keyring ?"), _T("Key info"), MB_YESNO) == IDYES) + { + wstring cmd; + string output; + DWORD exitcode; + cmd += _T(" --batch --yes --delete-key "); + ptmp = mir_a2t(tmp); + cmd += ptmp; + mir_free(ptmp); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &output; + params.code = &exitcode; + params.result = &result; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<hdr.hwndFrom) && hdr->iItem != (-1)) + { + if(hdr->hdr.code == NM_CLICK) + { + item_num = hdr->iItem; + } + else if(hdr->hdr.code == LVN_ITEMCHANGED) + { + void setClistIcon(HANDLE hContact); + void setSrmmIcon(HANDLE hContact); + if(ListView_GetCheckState(hwndList, item_num)) + DBWriteContactSettingByte(user_data[item_num+1], szGPGModuleName, "GPGEncryption", 1); + else + DBWriteContactSettingByte(user_data[item_num+1], szGPGModuleName, "GPGEncryption", 0); + setClistIcon(user_data[item_num+1]); + setSrmmIcon(user_data[item_num+1]); + } + } + switch (((LPNMHDR)lParam)->code) + { + + case PSN_APPLY: + { + extern bool bDebugLog, bJabberAPI, bFileTransfers; + bDebugLog = CheckStateStoreDB(hwndDlg, IDC_DEBUG_LOG, "bDebugLog"); + if(bDebugLog) + debuglog.init(); + bJabberAPI = CheckStateStoreDB(hwndDlg, IDC_JABBER_API, "bJabberAPI"); + bFileTransfers = CheckStateStoreDB(hwndDlg, IDC_FILE_TRANSFERS, "bFileTransfers"); + bAutoExchange = CheckStateStoreDB(hwndDlg, IDC_AUTO_EXCHANGE, "bAutoExchange"); + { + TCHAR tmp[512]; + GetDlgItemText(hwndDlg, IDC_LOG_FILE_EDIT, tmp, 512); + DBWriteContactSettingTString(NULL, szGPGModuleName, "szLogFilePath", tmp); + } + return TRUE; + } + } + } + break; + } + + return FALSE; +} + + +static BOOL CALLBACK DlgProcGpgBinOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TCHAR *tmp = NULL; + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T("gpg.exe")); + SetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp); + mir_free(tmp); + tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("gpg")); + SetDlgItemText(hwndDlg, IDC_HOME_DIR, tmp); + mir_free(tmp); + return TRUE; + } + + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_SET_BIN_PATH: + { + GetFilePath(_T("Choose gpg.exe"), "szGpgBinPath", _T("*.exe"), _T("EXE Executables")); + tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T("gpg.exe")); + SetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp); + bool gpg_exists = false; + { + if(_waccess(tmp, 0) != -1) + gpg_exists = true; + if(gpg_exists) + { + bool bad_version = false; + TCHAR *tmp_path = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T("")); + DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp); + string out; + DWORD code; + wstring cmd = _T("--version"); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + } + DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp_path); + mir_free(tmp_path); + string::size_type p1 = out.find("(GnuPG) "); + if(p1 != string::npos) + { + p1 += strlen("(GnuPG) "); + if(out[p1] != '1') + bad_version = true; + } + else + { + bad_version = false; + MessageBox(0, TranslateT("This is not gnupg binary !\nrecommended to use GnuPG v1.x.x with this plugn."), _T("Warning"), MB_OK); + } +/* if(bad_version) //looks like working fine with gpg2 + MessageBox(0, TranslateT("Unsupported gnupg version found, use at you own risk!\nrecommended to use GnuPG v1.x.x with this plugn."), _T("Warning"), MB_OK); */ + } + } + char mir_path[MAX_PATH]; + char *atmp = mir_t2a(tmp); + mir_free(tmp); + CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); + char* p_path = NULL; + if(StriStr(atmp, mir_path)) + { + p_path = atmp + strlen(mir_path); + tmp = mir_a2t(p_path); + SetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp); + } + } + break; + case IDC_SET_HOME_DIR: + { + GetFolderPath(_T("Set home diractory"), "szHomePath"); + tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + SetDlgItemText(hwndDlg, IDC_HOME_DIR, tmp); + char mir_path[MAX_PATH]; + char *atmp = mir_t2a(tmp); + mir_free(tmp); + CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); + char* p_path = NULL; + if(StriStr(atmp, mir_path)) + { + p_path = atmp + strlen(mir_path); + tmp = mir_a2t(p_path); + SetDlgItemText(hwndDlg, IDC_HOME_DIR, tmp); + } + } + break; + default: + break; + } + + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + + case WM_NOTIFY: + { + switch (((LPNMHDR)lParam)->code) + { + + case PSN_APPLY: + { + TCHAR tmp[512]; + GetDlgItemText(hwndDlg, IDC_BIN_PATH, tmp, 512); + DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp); + GetDlgItemText(hwndDlg, IDC_HOME_DIR, tmp, 512); + while(tmp[_tcslen(tmp)-1] == '\\') + tmp[_tcslen(tmp)-1] = '\0'; + DBWriteContactSettingTString(NULL, szGPGModuleName, "szHomePath", tmp); + return TRUE; + } + } + } + break; + } + return FALSE; +} + +static BOOL CALLBACK DlgProcGpgMsgOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + CheckStateLoadDB(hwndDlg, IDC_APPEND_TAGS, "bAppendTags", 0); + CheckStateLoadDB(hwndDlg, IDC_STRIP_TAGS, "bStripTags", 0); + { + TCHAR *tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szInOpenTag", _T("")); + SetDlgItemText(hwndDlg, IDC_IN_OPEN_TAG, tmp); + mir_free(tmp); + tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szInCloseTag", _T("")); + SetDlgItemText(hwndDlg, IDC_IN_CLOSE_TAG, tmp); + mir_free(tmp); + tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szOutOpenTag", _T("")); + SetDlgItemText(hwndDlg, IDC_OUT_OPEN_TAG, tmp); + mir_free(tmp); + tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szOutCloseTag", _T("")); + SetDlgItemText(hwndDlg, IDC_OUT_CLOSE_TAG, tmp); + mir_free(tmp); + } + return TRUE; + } + + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_APPEND_TAGS: + break; + default: + break; + } + + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + + case WM_NOTIFY: + { + switch (((LPNMHDR)lParam)->code) + { + + case PSN_APPLY: + { + bAppendTags = CheckStateStoreDB(hwndDlg, IDC_APPEND_TAGS, "bAppendTags"); + bStripTags = CheckStateStoreDB(hwndDlg, IDC_STRIP_TAGS, "bStripTags"); + { + TCHAR tmp[128]; + GetDlgItemText(hwndDlg, IDC_IN_OPEN_TAG, tmp, 128); + DBWriteContactSettingTString(NULL, szGPGModuleName, "szInOpenTag", tmp); + mir_free(inopentag); + inopentag = new TCHAR [_tcslen(tmp)+1]; + _tcscpy(inopentag, tmp); + GetDlgItemText(hwndDlg, IDC_IN_CLOSE_TAG, tmp, 128); + DBWriteContactSettingTString(NULL, szGPGModuleName, "szInCloseTag", tmp); + mir_free(inclosetag); + inclosetag = new TCHAR [_tcslen(tmp)+1]; + _tcscpy(inclosetag, tmp); + GetDlgItemText(hwndDlg, IDC_OUT_OPEN_TAG, tmp, 128); + DBWriteContactSettingTString(NULL, szGPGModuleName, "szOutOpenTag", tmp); + mir_free(outopentag); + outopentag = new TCHAR [_tcslen(tmp)+1]; + _tcscpy(outopentag, tmp); + GetDlgItemText(hwndDlg, IDC_OUT_CLOSE_TAG, tmp, 128); + DBWriteContactSettingTString(NULL, szGPGModuleName, "szOutCloseTag", tmp); + mir_free(outclosetag); + outclosetag = new TCHAR [_tcslen(tmp)+1]; + _tcscpy(outclosetag, tmp); + } + return TRUE; + } + } + } + break; + } + return FALSE; +} + +static BOOL CALLBACK DlgProcGpgAdvOpts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + { + extern bool bJabberAPI; + TranslateDialogDefault(hwndDlg); + CheckStateLoadDB(hwndDlg, IDC_PRESCENSE_SUBSCRIPTION, "bPresenceSigning", 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_PRESCENSE_SUBSCRIPTION), bJabberAPI); + + return TRUE; + } + + + case WM_COMMAND: + { + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + } + + case WM_NOTIFY: + { + switch (((LPNMHDR)lParam)->code) + { + + case PSN_APPLY: + { + bPresenceSigning = CheckStateStoreDB(hwndDlg, IDC_PRESCENSE_SUBSCRIPTION, "bPresenceSigning"); + return TRUE; + } + } + } + break; + } + return FALSE; +} + +HWND hPubKeyEdit = NULL; + +LONG_PTR default_edit_proc = NULL; + +static BOOL CALLBACK editctrl_ctrl_a(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) +{ + LRESULT ret = 0; + switch(msg) + { + case WM_KEYDOWN: + if(wParam == 0x41 && GetKeyState(VK_CONTROL)< 0 ) + SendMessage(hwndDlg, EM_SETSEL, 0, -1); + break; + default: + ret = CallWindowProc((WNDPROC)default_edit_proc, hwndDlg, msg, wParam, lParam); + break; + } + return ret; +} + +static BOOL CALLBACK DlgProcLoadPublicKey(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) +{ + static HANDLE hContact = user_data[item_num+1]; + + + TCHAR *tmp = NULL; + + wstring key_buf; + wstring::size_type ws1 = 0, ws2 = 0; + switch (msg) + { + case WM_INITDIALOG: + { + default_edit_proc = GetWindowLong(GetDlgItem(hwndDlg, IDC_PUBLIC_KEY_EDIT), GWLP_WNDPROC); + SetWindowPos(hwndDlg, 0, load_key_rect.left, load_key_rect.top, 0, 0, SWP_NOSIZE|SWP_SHOWWINDOW); + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_PUBLIC_KEY_EDIT), GWLP_WNDPROC, (LONG_PTR)editctrl_ctrl_a); + HANDLE hcnt = hContact; + if(metaIsProtoMetaContacts(hcnt)) + hcnt = metaGetMostOnline(hcnt); + TranslateDialogDefault(hwndDlg); + { + string msg = Translate("Load Public GPG Key for "); + msg += (char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hcnt, 0); + SetWindowTextA(hwndDlg, msg.c_str()); + } + bool isContactSecured(HANDLE); + if(!hcnt) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_SELECT_EXISTING), 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_ENCRYPTION), 0); + } + if(isContactSecured(hcnt)) + SetDlgItemText(hwndDlg, IDC_ENABLE_ENCRYPTION, TranslateW(_T("Turn off encryption"))); + else + { + SetDlgItemText(hwndDlg, IDC_ENABLE_ENCRYPTION, TranslateW(_T("Turn on encryption"))); + CheckDlgButton(hwndDlg, IDC_ENABLE_ENCRYPTION, 1); + } + if(hcnt) + { + tmp = UniGetContactSettingUtf(hcnt, szGPGModuleName, "GPGPubKey", _T("")); + wstring str = tmp; + mir_free(tmp); tmp = NULL; + wstring::size_type p = 0, stop = 0; + if(!str.empty()) + { + for(;;) + { + if((p = str.find(_T("\n"), p+2)) != wstring::npos) + { + if(p > stop) + { + stop = p; + str.insert(p, _T("\r")); + } + else + break; + } + } + } +// char *tmp = UniGetContactSettingUtf(hcnt, szGPGModuleName, "KeyID_Prescense", ""); + if(!hcontact_data[hcnt].key_in_prescense.empty()) + { + char *tmp2 = UniGetContactSettingUtf(hcnt, szGPGModuleName, "KeyID", ""); + if(!tmp2[0]) + { + string out; + DWORD code; + wstring cmd = _T(" --export -a "); +// TCHAR *tmp3 = mir_a2t(tmp); + cmd += toUTF16(hcontact_data[hcnt].key_in_prescense); +// mir_free(tmp3); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog< stop) + { + stop = p; + out.insert(p, "\r"); + } + else + break; + } + } + TCHAR *tmp3 = mir_a2t(out.c_str()); + str.clear(); + str.append(tmp3); + string msg = "Load Public GPG Key for "; + msg += (char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hcnt, 0); + msg += " (Key ID: "; + msg += hcontact_data[hcnt].key_in_prescense; + msg += " found in prescense, and exists in keyring.)"; + SetWindowTextA(hwndDlg, msg.c_str()); + } + else + { + string msg = "Load Public GPG Key (Key ID: "; + msg += hcontact_data[hcnt].key_in_prescense; + msg += " found in prescense.)"; + SetWindowTextA(hwndDlg, msg.c_str()); + EnableWindow(GetDlgItem(hwndDlg, IDC_IMPORT), 1); + } + } + mir_free(tmp2); + } + if(tmp) + mir_free(tmp); + SetDlgItemText(hwndDlg, IDC_PUBLIC_KEY_EDIT, !str.empty()?str.c_str():_T("")); + } + hPubKeyEdit = GetDlgItem(hwndDlg, IDC_PUBLIC_KEY_EDIT); + return TRUE; + } + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case ID_OK: + { + tmp = new TCHAR [40960]; + TCHAR *begin, *end; + GetDlgItemText(hwndDlg, IDC_PUBLIC_KEY_EDIT, tmp, 40960); + key_buf.append(tmp); + key_buf.append(_T("\n")); //no new line at end of file ) + delete [] tmp; + while((ws1 = key_buf.find(_T("\r"), ws1)) != wstring::npos) + { + key_buf.erase(ws1, 1); //remove windows specific trash + } + ws1 = 0; + if(((ws2 = key_buf.find(_T("-----END PGP PUBLIC KEY BLOCK-----"))) != wstring::npos) && ((ws1 = key_buf.find(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----"))) != wstring::npos)) + { + begin = (TCHAR*)mir_alloc(sizeof(TCHAR) * (_tcslen(_T("-----BEGIN PGP PUBLIC KEY BLOCK-----")) + 1)); + _tcscpy(begin, _T("-----BEGIN PGP PUBLIC KEY BLOCK-----")); + end = (TCHAR*)mir_alloc(sizeof( TCHAR) * (_tcslen(_T("-----END PGP PUBLIC KEY BLOCK-----")) + 1)); + _tcscpy(end, _T("-----END PGP PUBLIC KEY BLOCK-----")); + } + else if(((ws2 = key_buf.find(_T("-----END PGP PRIVATE KEY BLOCK-----"))) != wstring::npos) && ((ws1 = key_buf.find(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----"))) != wstring::npos)) + { + begin = (TCHAR*)mir_alloc(sizeof(TCHAR) * (_tcslen(_T("-----BEGIN PGP PRIVATE KEY BLOCK-----")) + 1)); + _tcscpy(begin, _T("-----BEGIN PGP PRIVATE KEY BLOCK-----")); + end = (TCHAR*)mir_alloc(sizeof(TCHAR) * (_tcslen(_T("-----END PGP PRIVATE KEY BLOCK-----")) + 1)); + _tcscpy(end, _T("-----END PGP PRIVATE KEY BLOCK-----")); + } + else + { + MessageBox(0, _T("This is not public or private key"), _T("INFO"), MB_OK); + break; + } + ws2 += _tcslen(end); + bool allsubcontacts = false; + { + if(metaIsProtoMetaContacts(hContact)) + { + HANDLE hcnt = NULL; + if(MessageBox(0, _T("Do you want load key for all subcontacts ?"), _T("Metacontact detected"), MB_YESNO) == IDYES) + { + allsubcontacts = true; + int count = metaGetContactsNum(hContact); + for(int i = 0; i < count; i++) + { + hcnt = metaGetSubcontact(hContact, i); + if(hcnt) + DBWriteContactSettingTString(hcnt, szGPGModuleName, "GPGPubKey", key_buf.substr(ws1,ws2-ws1).c_str()); + } + } + else + DBWriteContactSettingTString(metaGetMostOnline(hContact), szGPGModuleName, "GPGPubKey", key_buf.substr(ws1,ws2-ws1).c_str()); + } + else + DBWriteContactSettingTString(hContact, szGPGModuleName, "GPGPubKey", key_buf.substr(ws1,ws2-ws1).c_str()); + } + tmp = (TCHAR*)mir_alloc(sizeof( TCHAR) * (key_buf.length()+1)); + _tcscpy(tmp, key_buf.substr(ws1,ws2-ws1).c_str()); + { //gpg execute block + wstring cmd; + TCHAR tmp2[MAX_PATH] = {0}; + TCHAR *ptmp; + string output; + DWORD exitcode; + { + HANDLE hcnt = hContact; + if(metaIsProtoMetaContacts(hcnt)) + hcnt = metaGetMostOnline(hcnt); + ptmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + _tcscpy(tmp2, ptmp); + mir_free(ptmp); + _tcscat(tmp2, _T("\\")); + _tcscat(tmp2, _T("temporary_exported.asc")); + DeleteFile(tmp2); + wfstream f(tmp2, std::ios::out); + ptmp = UniGetContactSettingUtf(hcnt, szGPGModuleName, "GPGPubKey", _T("")); + wstring str = ptmp; + mir_free(ptmp); + wstring::size_type s = 0; + while((s = str.find(_T("\r"), s)) != wstring::npos) + { + str.erase(s, 1); + } + f< output.find("<", s)) + s2 = output.find("<", s); + if(s2 != string::npos) + { + tmp2 = (char*)mir_alloc(output.substr(s,s2-s-1).length()+1); + strcpy(tmp2, output.substr(s,s2-s-1).c_str()); + mir_utf8decode(tmp2, 0); + if(hContact) + { + if(metaIsProtoMetaContacts(hContact)) + { + HANDLE hcnt = NULL; + if(allsubcontacts) + { + int count = metaGetContactsNum(hContact); + for(int i = 0; i < count; i++) + { + hcnt = metaGetSubcontact(hContact, i); + if(hcnt) + DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyMainName", output.substr(s,s2-s-1).c_str()); + } + } + else + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainName", output.substr(s,s2-s-1).c_str()); + } + else + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainName", output.substr(s,s2-s-1).c_str()); + } + mir_free(tmp2); + tmp = mir_wstrdup(toUTF16(output.substr(s,s2-s-1)).c_str()); + if(hContact && hwndList_p) + ListView_SetItemText(hwndList_p, item_num, 2, tmp); + mir_free(tmp); + if((s = output.find(")", s2)) == string::npos) + s = output.find(">", s2); + else if(s > output.find(">", s2)) + s = output.find(">", s2); + s2++; + if(output[s] == ')') + { + tmp2 = new char [output.substr(s2,s-s2).length()+1]; + strcpy(tmp2, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp2, 0); + if(hContact) + { + if(metaIsProtoMetaContacts(hContact)) + { + HANDLE hcnt = NULL; + if(allsubcontacts) + { + int count = metaGetContactsNum(hContact); + for(int i = 0; i < count; i++) + { + hcnt = metaGetSubcontact(hContact, i); + if(hcnt) + DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyComment", output.substr(s2,s-s2).c_str()); + } + } + else + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyComment", output.substr(s2,s-s2).c_str()); + } + else + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyComment", output.substr(s2,s-s2).c_str()); + } + mir_free(tmp2); + s+=3; + s2 = output.find(">", s); + tmp2 = new char [output.substr(s,s2-s).length()+1]; + strcpy(tmp2, output.substr(s,s2-s).c_str()); + mir_utf8decode(tmp2, 0); + if(hContact) + { + if(metaIsProtoMetaContacts(hContact)) + { + HANDLE hcnt = NULL; + if(allsubcontacts) + { + int count = metaGetContactsNum(hContact); + for(int i = 0; i < count; i++) + { + hcnt = metaGetSubcontact(hContact, i); + if(hcnt) + DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyMainEmail", output.substr(s,s2-s).c_str()); + } + } + else + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainEmail", output.substr(s,s2-s).c_str()); + } + else + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s,s2-s).c_str()); + } + mir_free(tmp2); + tmp = mir_wstrdup(toUTF16(output.substr(s,s2-s)).c_str()); + if(hContact && hwndList_p) + ListView_SetItemText(hwndList_p, item_num, 3, tmp); + mir_free(tmp); + } + else + { + tmp2 = (char*)mir_alloc(output.substr(s2,s-s2).length()+1); + strcpy(tmp2, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp2, 0); + if(hContact) + { + if(metaIsProtoMetaContacts(hContact)) + { + HANDLE hcnt = NULL; + if(allsubcontacts) + { + int count = metaGetContactsNum(hContact); + for(int i = 0; i < count; i++) + { + hcnt = metaGetSubcontact(hContact, i); + if(hcnt) + DBWriteContactSettingString(hcnt, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); + } + } + else + DBWriteContactSettingString(metaGetMostOnline(hContact), szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); + } + else + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); + } + mir_free(tmp2); + tmp = mir_wstrdup(toUTF16(output.substr(s2,s-s2)).c_str()); + if(hContact && hwndList_p) + ListView_SetItemText(hwndList_p, item_num, 3, tmp); + mir_free(tmp); + } + } + if(hContact && hwndList_p) + { + ListView_SetColumnWidth(hwndList_p, 0, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList_p, 1, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList_p, 2, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(hwndList_p, 3, LVSCW_AUTOSIZE); + } + } + if(!hContact) + { + TCHAR *fp = UniGetContactSettingUtf(hContact, szGPGModuleName, "KeyID", _T("")); + { + string out; + DWORD code; + wstring cmd = _T("--batch -a --export "); + cmd += fp; + mir_free(fp); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<code) + { + + case PSN_APPLY: + { + return TRUE; + } + } + } + break; + case WM_CLOSE: + DestroyWindow(hwndDlg); + break; + case WM_DESTROY: + { + GetWindowRect(hwndDlg, &load_key_rect); + DBWriteContactSettingDword(NULL, szGPGModuleName, "LoadKeyWindowX", load_key_rect.left); + DBWriteContactSettingDword(NULL, szGPGModuleName, "LoadKeyWindowY", load_key_rect.top); + } + break; + } + + return FALSE; +} + + + +void ShowLoadPublicKeyDialog() +{ + DialogBox(hInst, MAKEINTRESOURCE(IDD_LOAD_PUBLIC_KEY), NULL, (DLGPROC)DlgProcLoadPublicKey); +} diff --git a/plugins/New_GPG/src/resource.h b/plugins/New_GPG/src/resource.h new file mode 100755 index 0000000000..027e27965c --- /dev/null +++ b/plugins/New_GPG/src/resource.h @@ -0,0 +1,96 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by new_gpg.rc +// +#define IDD_LOAD_PUBLIC_KEY 102 +#define IDD_FIRST_RUN 103 +#define IDD_OPT_GPG 104 +#define IDD_OPT_GPG_BIN 105 +#define IDD_BIN_PATH 106 +#define IDD_OPT_GPG_MESSAGES 107 +#define IDD_NEW_KEY 108 +#define IDD_KEY_GEN 109 +#define IDD_LOAD_EXISTING_KEY 110 +#define IDD_KEY_PASSWD 111 +#define IDI_SECURED 112 +#define IDD_IMPORT_KEY 112 +#define IDI_UNSECURED 113 +#define IDD_OPT_GPG_ADVANCED 113 +#define IDC_SET_BIN_PATH 1016 +#define IDC_SET_HOME_DIR 1017 +#define IDC_BIN_PATH 1018 +#define IDC_HOME_DIR 1019 +#define IDC_USERLIST 1020 +#define IDC_LOAD_KEY_BUTTON 1022 +#define ID_OK 1023 +#define ID_LOD_FROM_FILE 1024 +#define ID_LOAD_FROM_FILE 1024 +#define IDC_EDIT1 1025 +#define IDC_PUBLIC_KEY_EDIT 1025 +#define IDC_KEY_PASSWORD 1025 +#define IDC_IN_OPEN_TAG 1025 +#define IDC_KEY_PASSWD 1025 +#define IDC_PASSWORD 1025 +#define IDC_LOG_FILE_EDIT 1025 +#define IDC_BUTTON1 1026 +#define IDC_SAVE_KEY_BUTTON 1026 +#define IDC_GENERATE_KEY 1026 +#define IDC_IGNORE_KEY 1026 +#define IDC_SELECT_EXISTING 1026 +#define IDC_KEY_EMAIL 1026 +#define IDC_DELETE_KEY_BUTTON 1027 +#define IDC_IN_CLOSE_TAG 1027 +#define IDC_KEY_REAL_NAME 1027 +#define IDC_KEY_LIST 1028 +#define IDC_KEY_COMMENT 1028 +#define IDC_OUT_OPEN_TAG 1029 +#define IDC_APPEND_TAGS 1030 +#define IDC_OUT_CLOSE_TAG 1031 +#define IDC_SELECT_KEY 1033 +#define IDC_MESSAGE 1034 +#define ID_IMPORT 1035 +#define IDC_IMPORT_AND_USE 1036 +#define IDC_KEY_TYPE 1039 +#define IDC_KEY_LENGTH 1040 +#define IDC_KEY_EXPIRE_DATE 1043 +#define IDC_EXISTING_KEY_LIST 1045 +#define IDC_BUTTON2 1046 +#define IDC_OTHER 1046 +#define IDC_LOG_FILE_SET 1046 +#define IDC_IMPORT 1046 +#define IDC_SAVE_PASSWORD 1047 +#define IDC_DEBUG_LOG 1048 +#define IDC_JABBER_API 1049 +#define IDC_ENABLE_ENCRYPTION 1050 +#define IDC_KEY_FROM 1051 +#define IDC_DELETE_KEY 1052 +#define IDC_KEYID 1053 +#define IDC_CURRENT_KEY 1054 +#define IDC_DEFAULT_PASSWORD 1055 +#define IDC_KEYSERVER 1058 +#define IDC_FILE_TRANSFERS 1061 +#define IDC_REMOVE_FILTERS 1062 +#define IDC_GENERATE_RANDOM 1063 +#define IDC_AUTO_EXCHANGE 1064 +#define IDC_AUT_EXCHANGE 1065 +#define IDC_BUTTON3 1066 +#define IDC_COPY_KEY 1066 +#define IDC_STRIP_TAGS 1067 +#define IDC_CHECK1 1068 +#define IDC_PRESCENSE_SUBSCRIPTION 1068 +#define IDC_GENERATING_KEY 1069 +#define IDC_GENERATING_TEXT 1070 +#define IDC_KEY_ID 1071 +#define IDC_COMBO1 1072 +#define IDC_ACCOUNT 1072 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 114 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1073 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/New_GPG/src/srmm.cpp b/plugins/New_GPG/src/srmm.cpp new file mode 100755 index 0000000000..6fc204a9a9 --- /dev/null +++ b/plugins/New_GPG/src/srmm.cpp @@ -0,0 +1,88 @@ +// Copyright © 2010-2012 SecureIM developers (baloo and others), sss +// +// 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 "commonheaders.h" + +void ShowStatusIcon(HANDLE hContact); +void setSrmmIcon(HANDLE hContact); + +int __cdecl onWindowEvent(WPARAM wParam, LPARAM lParam) { + + MessageWindowEventData *mwd = (MessageWindowEventData *)lParam; + if(mwd->uType == MSG_WINDOW_EVT_OPEN || mwd->uType == MSG_WINDOW_EVT_OPENING) + { + setSrmmIcon(mwd->hContact); + } + return 0; +} + + +int __cdecl onIconPressed(WPARAM wParam, LPARAM lParam) { + HANDLE hContact = (HANDLE)wParam; + HANDLE hMeta = NULL; + if(metaIsProtoMetaContacts(hContact)) + { + hMeta = hContact; + hContact = metaGetMostOnline(hContact); // âîçüìåì òîò, ÷åðåç êîòîðûé ïîéäåò ñîîáùåíèå + } + else if(metaIsSubcontact(hContact)) + hMeta = metaGetContact(hContact); + StatusIconClickData *sicd = (StatusIconClickData *)lParam; + if(strcmp(sicd->szModule, szGPGModuleName)) + return 0; // not our event + + void setSrmmIcon(HANDLE); + void setClistIcon(HANDLE); + bool isContactHaveKey(HANDLE hContact); + BYTE enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); + if(enc) + { + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); + hMeta?DBWriteContactSettingByte(hMeta, szGPGModuleName, "GPGEncryption", 0):0; + setSrmmIcon(hContact); + setClistIcon(hContact); + } + else if(!enc) + { + if(!isContactHaveKey(hContact)) + { + void ShowLoadPublicKeyDialog(); + extern map user_data; + extern int item_num; + item_num = 0; //black magic here + user_data[1] = hContact; + ShowLoadPublicKeyDialog(); + } + else + { + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 1); + hMeta?DBWriteContactSettingByte(hMeta, szGPGModuleName, "GPGEncryption", 1):0; + setSrmmIcon(hContact); + setClistIcon(hContact); + return 0; + } + if(isContactHaveKey(hContact)) + { + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 1); + hMeta?DBWriteContactSettingByte(hMeta, szGPGModuleName, "GPGEncryption", 1):0; + setSrmmIcon(hContact); + setClistIcon(hContact); + } + } + return 0; +} diff --git a/plugins/New_GPG/src/utilities.cpp b/plugins/New_GPG/src/utilities.cpp new file mode 100755 index 0000000000..242ccc4b67 --- /dev/null +++ b/plugins/New_GPG/src/utilities.cpp @@ -0,0 +1,1824 @@ +// Copyright © 2010-2012 sss +// +// 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 "commonheaders.h" + + +TCHAR* __stdcall UniGetContactSettingUtf(HANDLE hContact, const char *szModule,const char* szSetting, TCHAR* szDef) +{ + DBVARIANT dbv = {DBVT_DELETED}; + TCHAR* szRes; + if (DBGetContactSettingTString(hContact, szModule, szSetting, &dbv)) + return mir_tstrdup(szDef); + if(dbv.pszVal) + szRes = mir_tstrdup(dbv.ptszVal); + DBFreeVariant(&dbv); + return szRes; +} + +char* __stdcall UniGetContactSettingUtf(HANDLE hContact, const char *szModule,const char* szSetting, char* szDef) +{ + DBVARIANT dbv = {DBVT_DELETED}; + char* szRes; + if (DBGetContactSettingString(hContact, szModule, szSetting, &dbv)) + return mir_strdup(szDef); + if(dbv.pszVal) + szRes = mir_strdup(dbv.pszVal); + DBFreeVariant(&dbv); + return szRes; +} + + +char *date() +{ + setlocale( LC_ALL, "C" ); + static char d[11]; + char *tmp = __DATE__, m[4], mn[3] = "01"; + m[0]=tmp[0]; + m[1]=tmp[1]; + m[2]=tmp[2]; + if(strstr(m,"Jan")) + strcpy(mn,"01"); + else if(strstr(m,"Feb")) + strcpy(mn,"02"); + else if(strstr(m,"Mar")) + strcpy(mn,"03"); + else if(strstr(m,"Apr")) + strcpy(mn,"04"); + else if(strstr(m,"May")) + strcpy(mn,"05"); + else if(strstr(m,"Jun")) + strcpy(mn,"06"); + else if(strstr(m,"Jul")) + strcpy(mn,"07"); + else if(strstr(m,"Aug")) + strcpy(mn,"08"); + else if(strstr(m,"Sep")) + strcpy(mn,"09"); + else if(strstr(m,"Oct")) + strcpy(mn,"10"); + else if(strstr(m,"Nov")) + strcpy(mn,"11"); + else if(strstr(m,"Dec")) + strcpy(mn,"12"); + d[0]=tmp[7]; + d[1]=tmp[8]; + d[2]=tmp[9]; + d[3]=tmp[10]; + d[4]='.'; + d[5]=mn[0]; + d[6]=mn[1]; + d[7]='.'; + if (tmp[4] == ' ') + d[8] = '0'; + else + d[8]=tmp[4]; + d[9]=tmp[5]; + return d; +} + +void GetFilePath(TCHAR *WindowTittle, char *szSetting, TCHAR *szExt, TCHAR *szExtDesc) +{ + TCHAR str[MAX_PATH+2] = {0}, *tmp; + OPENFILENAME ofn={0}; + TCHAR filter[512], *pfilter; + ofn.lStructSize=CDSIZEOF_STRUCT(OPENFILENAME,lpTemplateName); + ofn.Flags=OFN_EXPLORER; + ofn.lpstrTitle=TranslateW(WindowTittle); + _tcscpy(filter,TranslateW(szExtDesc)); + pfilter=filter+_tcslen(filter)+1; + _tcscpy(pfilter, szExt); + pfilter[_tcslen(pfilter)+1] = '\0'; + pfilter[_tcslen(pfilter)+2] = '\0'; + ofn.lpstrFilter=filter; + tmp = UniGetContactSettingUtf(0, szGPGModuleName, szSetting, _T("")); + _tcscpy(str, tmp); + mir_free(tmp); + if(_tcslen(str)< 2) + str[0] = '\0'; + ofn.lpstrFile=str; + ofn.nMaxFile=_MAX_PATH; + ofn.nMaxFileTitle=MAX_PATH; + if(!GetOpenFileName(&ofn)) + return; + DBWriteContactSettingTString(0, szGPGModuleName, szSetting, str); +} + +TCHAR *GetFilePath(TCHAR *WindowTittle, TCHAR *szExt, TCHAR *szExtDesc, bool save_file) +{ + TCHAR *str = new TCHAR [MAX_PATH+2]; + OPENFILENAME ofn={0}; + TCHAR filter[512], *pfilter; + ofn.lStructSize=CDSIZEOF_STRUCT(OPENFILENAME,lpTemplateName); + ofn.Flags=OFN_EXPLORER; + ofn.lpstrTitle=TranslateW(WindowTittle); + _tcscpy(filter,TranslateW(szExtDesc)); + pfilter=filter+_tcslen(filter)+1; + _tcscpy(pfilter, szExt); + pfilter[_tcslen(pfilter)+1] = '\0'; + pfilter[_tcslen(pfilter)+2] = '\0'; + ofn.lpstrFilter=filter; + _tcscpy(str, _T("")); + if(_tcslen(str)< 2) + str[0] = '\0'; + ofn.lpstrFile=str; + ofn.nMaxFile=_MAX_PATH; + ofn.nMaxFileTitle=MAX_PATH; + if(!save_file) + { + if(!GetOpenFileName(&ofn)) + { + delete [] str; + return NULL; + } + } + else + { + if(!GetSaveFileName(&ofn)) + { + delete [] str; + return NULL; + } + } + return str; +} + +void GetFolderPath(TCHAR *WindowTittle, char *szSetting) +{ + BROWSEINFO pbi = {0}; + pbi.lpszTitle = WindowTittle; + pbi.ulFlags = BIF_EDITBOX|BIF_NEWDIALOGSTYLE|BIF_SHAREABLE; + LPITEMIDLIST pidl = SHBrowseForFolder(&pbi); + if (pidl != 0) + { + TCHAR path[MAX_PATH]; + if (SHGetPathFromIDList(pidl, path)) + { + DBWriteContactSettingTString(NULL, szGPGModuleName, "szHomePath", path); + } + IMalloc * imalloc = 0; + if (SUCCEEDED(SHGetMalloc(&imalloc))) + { + imalloc->Free(pidl); + imalloc->Release(); + } + } +} + +int LoadKey(WPARAM w, LPARAM l) +{ + void ShowLoadPublicKeyDialog(); + extern map user_data; + extern int item_num; + item_num = 0; //black magic here + user_data[1] = (HANDLE)w; + ShowLoadPublicKeyDialog(); + return 0; +} + +int SendKey(WPARAM w, LPARAM l) +{ + HANDLE hContact = (HANDLE)w; + if(metaIsProtoMetaContacts(hContact)) + hContact = metaGetMostOnline(hContact); + char *szMessage; + { + char *proto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + char setting[64]; + if(proto) + { + strcpy(setting, proto); + strcat(setting, "_GPGPubKey"); + szMessage = UniGetContactSettingUtf(NULL, szGPGModuleName, setting, ""); + } + if(!szMessage[0]) + { + mir_free(szMessage); + szMessage = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", ""); + } + } + if(szMessage[0]) + { + BYTE enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); + CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)szMessage); + HistoryLog(hContact, db_event("Public key sent", 0, 0, DBEF_SENT)); + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc); + } + mir_free(szMessage); + return 0; +} + +extern HANDLE hLoadPublicKey, hToggleEncryption; + +int ToggleEncryption(WPARAM w, LPARAM l) +{ + HANDLE hContact = (HANDLE)w; + BYTE enc = 0; + if(metaIsProtoMetaContacts(hContact)) + enc = DBGetContactSettingByte(metaGetMostOnline(hContact), szGPGModuleName, "GPGEncryption", 0); + else + enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); + if(metaIsProtoMetaContacts(hContact)) + { + HANDLE hcnt = NULL; + if(MessageBox(0, _T("Do you want to toggle encryption for all subcontacts ?"), _T("Metacontact detected"), MB_YESNO) == IDYES) + { + int count = metaGetContactsNum(hContact); + for(int i = 0; i < count; i++) + { + hcnt = metaGetSubcontact(hContact, i); + if(hcnt) + DBWriteContactSettingByte(hcnt, szGPGModuleName, "GPGEncryption", enc?0:1); + } + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc?0:1); + } + } + else + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", enc?0:1); + void setSrmmIcon(HANDLE hContact); + void setClistIcon(HANDLE hContact); + setSrmmIcon(hContact); + setClistIcon(hContact); + enc = enc?0:1; + CLISTMENUITEM mi = {0}; + mi.cbSize=sizeof(mi); + mi.flags = CMIM_NAME; + enc?mi.pszName="Turn off GPG encryption":mi.pszName="Turn on GPG encryption"; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hToggleEncryption, (LPARAM)&mi); + return 0; +} + +int OnPreBuildContactMenu(WPARAM w, LPARAM l) +{ + HANDLE hContact = (HANDLE)w; + if(metaIsProtoMetaContacts(hContact)) + hContact = metaGetMostOnline(hContact); + CLISTMENUITEM mi = {0}; + mi.cbSize=sizeof(mi); + mi.flags = CMIM_NAME; + TCHAR *tmp = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", _T("")); + if(_tcslen(tmp) < 1) + { + DBDeleteContactSetting(hContact, szGPGModuleName, "GPGEncryption"); + mi.flags += CMIM_FLAGS | CMIF_GRAYED; + } + else + mi.flags = CMIM_NAME | CMIM_FLAGS; + mi.pszName = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0)?"Turn off GPG encryption":"Turn on GPG encryption"; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hToggleEncryption, (LPARAM)&mi); + return 0; +} + + +list transfers; +extern bool bFileTransfers; + +int onProtoAck(WPARAM w, LPARAM l) +{ + ACKDATA *ack=(ACKDATA*)l; + CCSDATA *ccs=(CCSDATA*)ack->lParam; + + if(ack->type == ACKTYPE_FILE && bFileTransfers) + { + switch(ack->result) + { + case ACKRESULT_DENIED: case ACKRESULT_FAILED: + break; + case ACKRESULT_SUCCESS: + { + PROTOFILETRANSFERSTATUS *f = (PROTOFILETRANSFERSTATUS*) ack->hProcess; + TCHAR *filename = NULL; + if(f->flags & PFTS_UNICODE) + { + if(f->tszCurrentFile && f->tszCurrentFile[0]) + filename = mir_wstrdup(f->tszCurrentFile); + if(!filename) + return 0; + } + else + { + if(f->szCurrentFile && f->szCurrentFile[0]) + filename = mir_utf8decodeT(f->szCurrentFile); + if(!filename) + return 0; + } + if(_tcsstr(filename, _T(".gpg"))) //decrypt it + { //process encrypted file + if(_waccess(f->tszCurrentFile, 0) == -1) + { + if(errno == ENOENT) + return 0; + } + string out; + DWORD code; + pxResult result; + wstring cmd = _T(" -o "); + wstring file = filename; + wstring::size_type p1 = file.rfind(_T(".gpg")); + file.erase(p1, _tcslen(_T(".gpg"))); + if(_waccess(file.c_str(), 0) != -1) + { + if(MessageBox(0, _T("Target file exists, do you want to replace it ?"), _T("Warning"), MB_YESNO) == IDNO) + return 0; + } + DeleteFile(file.c_str()); + file.insert(0, _T("\"")); + file.insert(file.length(), _T("\" ")); + cmd += file; + extern TCHAR *password; + { // password + TCHAR *pass = NULL; + char *keyid = UniGetContactSettingUtf(ack->hContact, szGPGModuleName, "KeyID", ""); + if(strlen(keyid) > 0) + { + string dbsetting = "szKey_"; + dbsetting += keyid; + dbsetting += "_Password"; + pass = UniGetContactSettingUtf(NULL, szGPGModuleName, dbsetting.c_str(), _T("")); + if(_tcslen(pass) > 0) + debuglog<hContact, GCDNF_TCHAR)<<" with password\n"; + } + else + { + pass = UniGetContactSettingUtf(NULL, szGPGModuleName, "szKeyPassword", _T("")); + if(_tcslen(pass) > 0) + debuglog<hContact, GCDNF_TCHAR)<<" with password\n"; + } + if(_tcslen(pass) > 0) + { + cmd += _T("--passphrase \""); + cmd += pass; + cmd += _T("\" "); + } + else if(password) + { + debuglog<hContact, GCDNF_TCHAR)<<" with password\n"; + cmd += _T("--passphrase \""); + cmd += password; + cmd += _T("\" "); + } + else + debuglog<hContact, GCDNF_TCHAR)<<" with out password\n"; + mir_free(pass); + mir_free(keyid); + } + cmd += _T(" -d \""); + cmd += filename; + cmd += _T("\""); + gpg_execution_params params; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread->timed_join(boost::posix_time::minutes(15))) + { + delete gpg_thread; + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<hContact, GCDNF_TCHAR)<<" password needed, trying to get one\n"; + if(_terminate) + break; + { //save inkey id + string::size_type s = out.find(" encrypted with "); + s = out.find(" ID ", s); + s += strlen(" ID "); + string::size_type s2 = out.find(",",s); + if(metaIsProtoMetaContacts(ack->hContact)) + DBWriteContactSettingString(metaGetMostOnline(ack->hContact), szGPGModuleName, "InKeyID", out.substr(s, s2-s).c_str()); + else + DBWriteContactSettingString(ack->hContact, szGPGModuleName, "InKeyID", out.substr(s, s2-s).c_str()); + } + void ShowLoadKeyPasswordWindow(); + new_key_hcnt_mutex.lock(); + new_key_hcnt = ack->hContact; + ShowLoadKeyPasswordWindow(); + wstring cmd2 = cmd; + if(password) + { + debuglog<hContact, GCDNF_TCHAR)<<"\n"; + wstring tmp = _T("--passphrase \""); + tmp += password; + tmp += _T("\" "); + cmd2.insert(0, tmp); + } + out.clear(); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd2; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + gpg_thread = gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread->timed_join(boost::posix_time::seconds(15))) + { + delete gpg_thread; + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<type == ACKTYPE_MESSAGE) + { + extern std::list sent_msgs; + if(!sent_msgs.empty()) + { + if(ack->result == ACKRESULT_FAILED) + { + std::list::iterator it = std::find(sent_msgs.begin(), sent_msgs.end(), ack->hProcess); + if(it != sent_msgs.end()) + { + HistoryLog(ack->hContact, db_event("Failed to send encrypted message", 0,0, 0)); + + } + } + else if(ack->result == ACKRESULT_SUCCESS) + { + std::list::iterator it = std::find(sent_msgs.begin(), sent_msgs.end(), ack->hProcess); + if(it != sent_msgs.end()) + sent_msgs.erase(it); + } + } + } + return 0; +} + +std::wstring encrypt_file(HANDLE hContact, TCHAR *filename) +{ + string out; + DWORD code; + pxResult result; + HANDLE hcnt = metaIsProtoMetaContacts(hContact)?metaGetMostOnline(hContact):hContact; + wstring cmd = _T("--batch --yes -r "); + char *keyid = UniGetContactSettingUtf(hcnt, szGPGModuleName, "KeyID", ""); + TCHAR *szKeyid = mir_a2t(keyid); + TCHAR *name = _tcsrchr(filename,_T('\\')); + if( !name ) + name = filename; + else + name++; + TCHAR *file_out = new TCHAR [_tcslen(filename)+4]; + mir_sntprintf(file_out, _tcslen(name)+7, _T("%s.gpg"), name); + cmd += szKeyid; + if(DBGetContactSettingByte(hcnt, szGPGModuleName, "bAlwaysTrust", 0)) + cmd += _T(" --trust-model always "); + mir_free(szKeyid); + mir_free(keyid); + cmd += _T(" -o \""); + TCHAR *temp = _tgetenv(_T("TEMP")); + cmd += temp; + cmd += _T("\\"); + cmd += file_out; + wstring path_out = temp; + path_out += _T("\\"); + path_out += file_out; + DeleteFile(path_out.c_str()); + cmd += _T("\" "); + mir_free(temp); + cmd += _T(" -e \""); + cmd += filename; + cmd += _T("\" "); + gpg_execution_params params; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + mir_free(keyid); + delete [] file_out; + boost::thread *gpg_thread = new boost::thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread->timed_join(boost::posix_time::seconds(180))) + { + delete gpg_thread; + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<timed_join(boost::posix_time::seconds(180))) + { + delete gpg_thread; + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog<hContact)) + { + + DWORD flags = (DWORD)ccs->wParam; //check for PFTS_UNICODE here + int i; +// if(flags & PFTS_UNICODE) //this does not work .... + if(StriStr(ccs->szProtoService, "/sendfilew")) + { + TCHAR **file=(TCHAR **)ccs->lParam; + for(i = 0; file[i]; i++) + { + if(_waccess(file[i], 0) == -1) + if(errno == ENOENT) + return 0; //we do not want to send file unencrypted (sometimes ack have wrong info) + if (_tcsstr(file[i],_T(".gpg"))) + continue; + std::wstring path_out = encrypt_file(ccs->hContact, file[i]); + mir_free(file[i]); + file[i] = mir_tstrdup(path_out.c_str()); + transfers.push_back(path_out); + } + } + else + { + char **file = (char**) ccs->lParam; + for(i = 0; file[i]; i++) + { + if(_access(file[i], 0) == -1) + if(errno == ENOENT) + return 0; //we do not want to send file unencrypted (sometimes ack have wrong info) + if (strstr(file[i],".gpg")) + continue; + TCHAR *tmp = mir_utf8decodeT(file[i]); + std::wstring path_out = encrypt_file(ccs->hContact, tmp); + mir_free(tmp); + char* tmp2 = mir_utf8encodeW(path_out.c_str()); + mir_free(file[i]); + file[i] = tmp2; + transfers.push_back(path_out); + + } + } + } + return CallService(MS_PROTO_CHAINSEND, w, l); +} + +void storeOutput(HANDLE ahandle, string *output) +{ + BOOL success; + char readbuffer[4096] = {0}; + unsigned long transfered, available; + + do { + PeekNamedPipe(ahandle,NULL,0,NULL,&available,NULL); + if (!available) + continue; + success=ReadFile(ahandle,readbuffer,sizeof(readbuffer),&transfered,NULL); + if (success && transfered) + output->append(readbuffer, 4096); + } while (available>0); +} + +void HistoryLog(HANDLE hContact, db_event evt) +{ + DBEVENTINFO Event = {0}; + Event.cbSize = sizeof(Event); + Event.szModule = szGPGModuleName; + Event.eventType = evt.eventType; + Event.flags = evt.flags; + if(!evt.timestamp) + Event.timestamp = (DWORD)time(NULL); + else + Event.timestamp = evt.timestamp; + Event.cbBlob = strlen((char*)evt.pBlob)+1; + Event.pBlob = (PBYTE)_strdup((char*)evt.pBlob); + CallService(MS_DB_EVENT_ADD, (WPARAM)(HANDLE)hContact,(LPARAM)&Event); +} + +static int ControlAddStringUtf(HWND ctrl, DWORD msg, const TCHAR *szString) +{ + int item = -1; + item = SendMessage(ctrl, msg, 0, (LPARAM)szString); + return item; +} + +int ComboBoxAddStringUtf(HWND hCombo, const TCHAR *szString, DWORD data) +{ + int item = ControlAddStringUtf(hCombo, CB_ADDSTRING, szString); + SendMessage(hCombo, CB_SETITEMDATA, item, data); + + return item; +} + + +int GetJabberInterface(WPARAM w, LPARAM l) //get interface for all jabber accounts, options later +{ + extern list Accounts; + void AddHandlers(); + int count = 0; + PROTOACCOUNT **accounts; + ProtoEnumAccounts(&count, &accounts); + list ::iterator p; + Accounts.clear(); + Accounts.push_back(new JabberAccount); + p = Accounts.begin(); + (*p)->setAccountNumber(0); + for(int i = 0; i < count; i++) //get only jabber accounts from all accounts + { + IJabberInterface *JIftmp = getJabberApi(accounts[i]->szModuleName); + int a = 0; + if(JIftmp) + { + (*p)->setJabberInterface(JIftmp); + if(accounts[i]->tszAccountName) + { + TCHAR* tmp = mir_tstrdup(accounts[i]->tszAccountName); + (*p)->setAccountName(tmp); + } + else + { + TCHAR *tmp = mir_a2t(accounts[i]->szModuleName); + (*p)->setAccountName(tmp); + } + (*p)->setAccountNumber(a); + a++; + Accounts.push_back(new JabberAccount); + p++; + } + } + Accounts.pop_back(); + AddHandlers(); + return 0; +} + +static JABBER_HANDLER_FUNC SendHandler(IJabberInterface *ji, HXML node, void *pUserData) +{ + HXML local_node = node; + for(int n = 0; n <= xi.getChildCount(node); n++) + { + LPCTSTR str = xi.getText(local_node); + LPCTSTR nodename = xi.getName(local_node); + if(str) + { + if(_tcsstr(str, _T("-----BEGIN PGP MESSAGE-----")) && _tcsstr(str, _T("-----END PGP MESSAGE-----"))) + { + wstring data = str; + xi.setText(local_node, _T("This message is encrypted.")); + wstring::size_type p1 = data.find(_T("-----BEGIN PGP MESSAGE-----")) + _tcslen(_T("-----BEGIN PGP MESSAGE-----")); + while(data.find(_T("Version: "), p1) != wstring::npos) + { + p1 = data.find(_T("Version: "), p1); + p1 = data.find(_T("\n"), p1); + } + while(data.find(_T("Comment: "), p1) != wstring::npos) + { + p1 = data.find(_T("Comment: "), p1); + p1 = data.find(_T("\n"), p1); + } + while(data.find(_T("Encoding: "), p1) != wstring::npos) + { + p1 = data.find(_T("Encoding: "), p1); + p1 = data.find(_T("\n"), p1); + } + p1+=2; + wstring::size_type p2 = data.find(_T("-----END PGP MESSAGE-----")); + HXML encrypted_data = xi.addChild(node, _T("x"), data.substr(p1, p2-p1).c_str()); + xi.addAttr(encrypted_data, _T("xmlns"), _T("jabber:x:encrypted")); + return FALSE; + } + } + if(bPresenceSigning && nodename) + { + if(_tcsstr(nodename, _T("status"))) + { + TCHAR *path_c = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + wstring path_out = path_c; + wstring file = toUTF16(get_random(10)); + mir_free(path_c); + path_out += _T("\\tmp\\"); + path_out += file; + DeleteFile(path_out.c_str()); + wfstream f(path_out.c_str(), std::ios::out); + f<Sys()->GetModuleName(); + char setting[64]; + strcpy(setting, proto); + strcat(setting, "_KeyID"); + inkeyid = UniGetContactSettingUtf(NULL, szGPGModuleName, setting, ""); + if(!inkeyid[0]) + { + mir_free(inkeyid); + inkeyid = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", ""); + } + } + TCHAR *pass = NULL; + if(inkeyid[0]) + { + string dbsetting = "szKey_"; + dbsetting += inkeyid; + dbsetting += "_Password"; + pass = UniGetContactSettingUtf(NULL, szGPGModuleName, dbsetting.c_str(), _T("")); + if(pass[0]) + debuglog< Accounts; + list ::iterator p = Accounts.begin(); + for(unsigned int i = 0; i < Accounts.size(); i++, p++) + { + if(!(*p)) + break; + hContact = (*p)->getJabberInterface()->Sys()->ContactFromJID(xi.getAttrValue(node, _T("from"))); + if(hContact) + hcontact_data[hContact].key_in_prescense = out.substr(p1, p2-p1-1).c_str(); + } + } + } + } + } + return FALSE; + } + } + } + } + local_node = xi.getChild(node, n); + } + return FALSE; +} + +static JABBER_HANDLER_FUNC MessageHandler(IJabberInterface *ji, HXML node, void *pUserData) +{ + return FALSE; +} + + + + +void AddHandlers() +{ + extern list Accounts; + list::iterator end = Accounts.end(); + for(list::iterator p = Accounts.begin(); p != end; p++) + { + if(!(*p)) + break; + if((*p)->getSendHandler() == INVALID_HANDLE_VALUE) + (*p)->setSendHandler((*p)->getJabberInterface()->Net()->AddSendHandler((JABBER_HANDLER_FUNC)SendHandler)); + if((*p)->getPrescenseHandler() == INVALID_HANDLE_VALUE) + (*p)->setPrescenseHandler((*p)->getJabberInterface()->Net()->AddPresenceHandler((JABBER_HANDLER_FUNC)PrescenseHandler)); +// if((*p)->getMessageHandler() == INVALID_HANDLE_VALUE) +// (*p)->setMessageHandler((*p)->getJabberInterface()->Net()->AddMessageHandler((JABBER_HANDLER_FUNC)MessageHandler, JABBER_MESSAGE_TYPE_ANY ,NULL,NULL)); + if(bAutoExchange) + { + (*p)->getJabberInterface()->Net()->RegisterFeature(_T("GPG_Key_Auto_Exchange:0"), _T("Indicates that gpg installed and configured to public key auto exchange (currently implemented in new_gpg Miranda IM plugin)")); + (*p)->getJabberInterface()->Net()->AddFeatures(_T("GPG_Key_Auto_Exchange:0\0\0")); + } + } +} + +bool isContactSecured(HANDLE hContact) +{ + BYTE gpg_enc = DBGetContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 0); + if(!gpg_enc) + { + debuglog< 0) + { + mir_free(key); + return true; + } + mir_free(key); + return false; +} + +bool isGPGKeyExist() +{ + TCHAR *id = UniGetContactSettingUtf(NULL, szGPGModuleName, "KeyID", _T("")); + char *key = UniGetContactSettingUtf(NULL, szGPGModuleName, "GPGPubKey", ""); + if(id[0] && key[0]) + { + mir_free(id); + mir_free(key); + return true; + } + mir_free(id); + mir_free(key); + return false; +} +bool isGPGValid() +{ + TCHAR *tmp; + bool gpg_exists = false, is_valid = true; + tmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szGpgBinPath", _T("")); + if(_waccess(tmp, 0) != -1) + gpg_exists = true; + else + { + mir_free(tmp); + TCHAR *path = (TCHAR*)mir_alloc(sizeof(TCHAR)*MAX_PATH); + char *mir_path = (char*)mir_alloc(MAX_PATH); + CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)"\\", (LPARAM)mir_path); + SetCurrentDirectoryA(mir_path); + tmp = mir_a2t(mir_path); + mir_free(mir_path); + //mir_realloc(path, (_tcslen(path)+64)*sizeof(TCHAR)); + TCHAR *gpg_path = (TCHAR*)mir_alloc(sizeof(TCHAR)*MAX_PATH); + _tcscpy(gpg_path, tmp); + _tcscat(gpg_path, _T("\\GnuPG\\gpg.exe")); + mir_free(tmp); + if(_waccess(gpg_path, 0) != -1) + { + gpg_exists = true; + _tcscpy(path, _T("GnuPG\\gpg.exe")); + } + mir_free(gpg_path); + tmp = mir_tstrdup(path); + mir_free(path); + } + DWORD len = MAX_PATH; + if(gpg_exists) + { + DBWriteContactSettingTString(NULL, szGPGModuleName, "szGpgBinPath", tmp); + string out; + DWORD code; + wstring cmd = _T("--version"); + gpg_execution_params params; + pxResult result; + params.cmd = &cmd; + params.useless = ""; + params.out = &out; + params.code = &code; + params.result = &result; + gpg_valid = true; + boost::thread gpg_thread(boost::bind(&pxEexcute_thread, ¶ms)); + if(!gpg_thread.timed_join(boost::posix_time::seconds(10))) + { + gpg_thread.~thread(); + TerminateProcess(params.hProcess, 1); + params.hProcess = NULL; + debuglog< + +struct TFakeAckParams { + inline TFakeAckParams( HANDLE p1, HANDLE p2, LONG p3, LPCSTR p4 ) : + hEvent( p1 ), + hContact( p2 ), + id( p3 ), + msg( p4 ) + {} + + HANDLE hEvent; + HANDLE hContact; + LONG id; + LPCSTR msg; +}; + +int SendBroadcast( HANDLE hContact, int type, int result, HANDLE hProcess, LPARAM lParam ) { + ACKDATA ack; + memset(&ack,0,sizeof(ack)); + ack.cbSize = sizeof( ACKDATA ); + ack.szModule = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + ack.hContact = hContact; + ack.type = type; + ack.result = result; + ack.hProcess = hProcess; + ack.lParam = lParam; + return CallService( MS_PROTO_BROADCASTACK, 0, ( LPARAM )&ack ); +} + + + +unsigned __stdcall sttFakeAck( LPVOID param ) { + + TFakeAckParams* tParam = ( TFakeAckParams* )param; + WaitForSingleObject( tParam->hEvent, INFINITE ); + + Sleep( 100 ); + if ( tParam->msg == NULL ) + SendBroadcast( tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, ( HANDLE )tParam->id, 0 ); + else + SendBroadcast( tParam->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, ( HANDLE )tParam->id, LPARAM( tParam->msg )); + + CloseHandle( tParam->hEvent ); + delete tParam; + + return 0; +} + + +int returnNoError(HANDLE hContact) { + HANDLE hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + unsigned int tID; + CloseHandle( (HANDLE) _beginthreadex(NULL, 0, sttFakeAck, new TFakeAckParams(hEvent,hContact,777,0), 0, &tID) ); + SetEvent( hEvent ); + return 777; +} +// end from secureim + + +string toUTF8(wstring str) +{ + string ustr; + try{ + utf8::utf16to8(str.begin(), str.end(), back_inserter(ustr)); + } + catch(const utf8::exception& e) + { + debuglog<> gen(rng, boost::uniform_int<>(0, chars.length()-1)); + for(int i = 0; i < length; ++i) + data += chars[gen()]; + return data; +} + +void send_encrypted_msgs_thread(HANDLE hContact) +{ + while(true) + { + char *key = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", ""); + while(!isContactSecured(hContact)) + boost::this_thread::sleep(boost::posix_time::seconds(1)); + if(!hcontact_data[hContact].msgs_to_send.empty()) + { + boost::this_thread::sleep(boost::posix_time::seconds(1)); + list::iterator end = hcontact_data[hContact].msgs_to_send.end(); + extern std::list sent_msgs; + for(list::iterator p = hcontact_data[hContact].msgs_to_send.begin(); p != end; ++p) + { + sent_msgs.push_back((HANDLE)CallContactService(hContact, PSS_MESSAGE, (WPARAM)PREF_UTF, (LPARAM)p->c_str())); + HistoryLog(hContact, db_event((char*)p->c_str(),0,0, DBEF_SENT)); + boost::this_thread::sleep(boost::posix_time::seconds(1)); + } + hcontact_data[hContact].msgs_to_send.clear(); + return; + } + else + return; + } +} + +string time_str() +{ + boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); + return (string)boost::posix_time::to_simple_string(now); +} + +int handleEnum(const char *szSetting, LPARAM lParam) +{ + if(!*(bool*)lParam && szSetting[0] && StriStr(szSetting, "tabsrmm")) + { + bool f = false, *found = (bool*)lParam; + f = !DBGetContactSettingByte(NULL, "PluginDisable", szSetting, 0); + if(f) + *found = f; + } + return 0; +} + +bool isTabsrmmUsed() +{ + DBCONTACTENUMSETTINGS enm = {0}; + bool found = false; + enm.lParam = (LPARAM)&found; + enm.pfnEnumProc = (DBSETTINGENUMPROC)&handleEnum; + enm.szModule = "PluginDisable"; + if(CallService(MS_DB_CONTACT_ENUMSETTINGS, (WPARAM)NULL, (LPARAM)&enm) == -1) + return false; + + return found; +} + + +int ExportGpGKeys(WPARAM w, LPARAM l) +{ + TCHAR *p = GetFilePath(_T("Choose file to export public keys"), _T("*"), _T("Any file"), true); + if(!p || !p[0]) + { + delete [] p; + //TODO: handle error + return 1; + } + char *path = mir_t2a(p); + delete [] p; + std::ofstream file; + file.open(path, std::ios::trunc | std::ios::out); + mir_free(path); + int exported_keys = 0; + if(!file.is_open()) + return 1; //TODO: handle error + for(HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); hContact; hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)) + { + char *k = UniGetContactSettingUtf(hContact, szGPGModuleName, "GPGPubKey", ""); + if(!k[0]) + { + mir_free(k); + continue; + } + std::string key = k; + mir_free(k); + + const char* proto = (const char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + std::string id = "Comment: login "; + const char * uid = (const char*)CallProtoService(proto, PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0); + DBVARIANT dbv = {0}; + DBCONTACTGETSETTING dbcgs = {0}; + dbcgs.pValue = &dbv; + dbcgs.szModule = proto; + dbcgs.szSetting = uid; + CallService(MS_DB_CONTACT_GETSETTING, 0, (LPARAM)&dbcgs); + switch(dbcgs.pValue->type) + { + case DBVT_DELETED: + continue; + break; + case DBVT_BYTE: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); + id += _id; + } + break; + case DBVT_WORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); + id += _id; + } + break; + case DBVT_DWORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); + id += _id; + } + break; + case DBVT_ASCIIZ: + { + id += dbcgs.pValue->pszVal; + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + } + break; + case DBVT_UTF8: + { + char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); + if(tmp[0]) + id += tmp; + mir_free(tmp); + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + } + break; + case DBVT_BLOB: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + case DBVT_WCHAR: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + } + id += " contact_id "; + ZeroMemory(&dbv, sizeof(dbv)); + ZeroMemory(&dbcgs, sizeof(dbcgs)); + dbcgs.pValue = &dbv; + dbcgs.szModule = proto; + dbcgs.szSetting = uid; + CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs); + switch(dbcgs.pValue->type) + { + case DBVT_DELETED: + continue; + break; + case DBVT_BYTE: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); + id += _id; + } + break; + case DBVT_WORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); + id += _id; + } + break; + case DBVT_DWORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); + id += _id; + } + break; + case DBVT_ASCIIZ: + { + id += dbcgs.pValue->pszVal; + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + } + break; + case DBVT_UTF8: + { + char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); + if(tmp[0]) + id += tmp; + mir_free(tmp); + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + } + break; + case DBVT_BLOB: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + case DBVT_WCHAR: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + } + std::string::size_type p1 = key.find("-----BEGIN PGP PUBLIC KEY BLOCK-----"); + if(p1 == std::string::npos) + continue; + p1 += strlen("-----BEGIN PGP PUBLIC KEY BLOCK-----"); + p1 ++; + id += '\n'; + key.insert(p1, id); + file<szModuleName, PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0); + DBVARIANT dbv = {0}; + DBCONTACTGETSETTING dbcgs = {0}; + dbcgs.pValue = &dbv; + dbcgs.szModule = accs[i]->szModuleName; + dbcgs.szSetting = uid; + CallService(MS_DB_CONTACT_GETSETTING, 0, (LPARAM)&dbcgs); + std::string id; + switch(dbcgs.pValue->type) + { + case DBVT_DELETED: + continue; + break; + case DBVT_BYTE: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); + id += _id; + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_WORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); + id += _id; + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_DWORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); + id += _id; + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_ASCIIZ: + { + id += dbcgs.pValue->pszVal; + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_UTF8: + { + char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); + if(tmp[0]) + id += tmp; + mir_free(tmp); + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + if(id == login) + acc = accs[i]->szModuleName; + } + break; + case DBVT_BLOB: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + case DBVT_WCHAR: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + } + } + if(acc.length()) + { + const char * uid = (const char*)CallProtoService(acc.c_str(), PS_GETCAPS, (WPARAM)PFLAG_UNIQUEIDSETTING, 0); + for(HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, (LPARAM)acc.c_str()); hContact; hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, (LPARAM)acc.c_str())) + { + DBVARIANT dbv = {0}; + DBCONTACTGETSETTING dbcgs = {0}; + dbcgs.pValue = &dbv; + dbcgs.szModule = acc.c_str(); + dbcgs.szSetting = uid; + CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs); + std::string id; + bool found = false; + switch(dbcgs.pValue->type) + { + case DBVT_DELETED: + continue; + break; + case DBVT_BYTE: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->bVal); + id += _id; + if(id == contact_id) + found = true; + } + break; + case DBVT_WORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->wVal); + id += _id; + if(id == contact_id) + found = true; + } + break; + case DBVT_DWORD: + { + char _id[64]; + mir_snprintf(_id, 63, "%d", dbcgs.pValue->dVal); + id += _id; + if(id == contact_id) + found = true; + } + break; + case DBVT_ASCIIZ: + { + id += dbcgs.pValue->pszVal; + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + if(id == contact_id) + found = true; + } + break; + case DBVT_UTF8: + { + char *tmp = mir_utf8decodeA(dbcgs.pValue->pszVal); + if(tmp[0]) + id += tmp; + mir_free(tmp); + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + if(id == contact_id) + found = true; + } + break; + case DBVT_BLOB: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + case DBVT_WCHAR: + //TODO + CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)&dbv); + break; + } + if(found) + { + wstring cmd; + TCHAR tmp2[MAX_PATH] = {0}; + TCHAR *ptmp; + string output; + DWORD exitcode; + { + HANDLE hcnt = hContact; + ptmp = UniGetContactSettingUtf(NULL, szGPGModuleName, "szHomePath", _T("")); + _tcscpy(tmp2, ptmp); + mir_free(ptmp); + _tcscat(tmp2, _T("\\")); + _tcscat(tmp2, _T("temporary_exported.asc")); + DeleteFile(tmp2); + wfstream f(tmp2, std::ios::out); + f< output.find("<", s)) + s2 = output.find("<", s); + if(s2 != string::npos) + { + tmp2 = new char [output.substr(s,s2-s-1).length()+1]; + strcpy(tmp2, output.substr(s,s2-s-1).c_str()); + mir_utf8decode(tmp2, 0); + if(hContact) + { + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainName", output.substr(s,s2-s-1).c_str()); + } + mir_free(tmp2); + if((s = output.find(")", s2)) == string::npos) + s = output.find(">", s2); + else if(s > output.find(">", s2)) + s = output.find(">", s2); + s2++; + if(output[s] == ')') + { + tmp2 = new char [output.substr(s2,s-s2).length()+1]; + strcpy(tmp2, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp2, 0); + if(hContact) + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyComment", output.substr(s2,s-s2).c_str()); + mir_free(tmp2); + s+=3; + s2 = output.find(">", s); + tmp2 = new char [output.substr(s,s2-s).length()+1]; + strcpy(tmp2, output.substr(s,s2-s).c_str()); + mir_utf8decode(tmp2, 0); + if(hContact) + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s,s2-s).c_str()); + mir_free(tmp2); + } + else + { + tmp2 = new char [output.substr(s2,s-s2).length()+1]; + strcpy(tmp2, output.substr(s2,s-s2).c_str()); + mir_utf8decode(tmp2, 0); + if(hContact) + DBWriteContactSettingString(hContact, szGPGModuleName, "KeyMainEmail", output.substr(s2,s-s2).c_str()); + mir_free(tmp2); + } + } + DBWriteContactSettingByte(hContact, szGPGModuleName, "GPGEncryption", 1); + DBWriteContactSettingTString(hContact, szGPGModuleName, "GPGPubKey", toUTF16(key).c_str()); + } + DeleteFile(tmp2); + break; + } + } + } + key.clear(); + } + } + if(file.is_open()) + file.close(); + char msg[512]; + mir_snprintf(msg, 511, "we have succesfully processed %d keys", processed_keys); + MessageBoxA(NULL, msg, Translate("Keys import result"), MB_OK); + return 0; +} \ No newline at end of file diff --git a/plugins/New_GPG/src/utilities.h b/plugins/New_GPG/src/utilities.h new file mode 100755 index 0000000000..30e9f68bb2 --- /dev/null +++ b/plugins/New_GPG/src/utilities.h @@ -0,0 +1,104 @@ +// Copyright © 2010-2012 sss +// +// 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 UTILITIES_H +#define UTILITIES_H +TCHAR* __stdcall UniGetContactSettingUtf(HANDLE hContact, const char *szModule,const char* szSetting, TCHAR* szDef); +char* __stdcall UniGetContactSettingUtf(HANDLE hContact, const char *szModule,const char* szSetting, char* szDef); +void GetFilePath(TCHAR *WindowTittle, char *szSetting, TCHAR *szExt, TCHAR *szExtDesc); +TCHAR *GetFilePath(TCHAR *WindowTittle, TCHAR *szExt, TCHAR *szExtDesc, bool save_file = false); +void GetFolderPath(TCHAR *WindowTittle, char *szSetting); + +void storeOutput(HANDLE ahandle, string *output); + +int ComboBoxAddStringUtf(HWND hCombo, const TCHAR *szString, DWORD data); +bool isContactSecured(HANDLE hContact); +bool isContactHaveKey(HANDLE hContact); +bool isTabsrmmUsed(); +bool isGPGKeyExist(); +bool isGPGValid(); +const bool StriStr(const char *str, const char *substr); +string toUTF8(wstring str); +wstring toUTF16(string str); +string get_random(int length); +string time_str(); + +struct db_event : public DBEVENTINFO +{ +public: + db_event(char* msg) + { + eventType = EVENTTYPE_MESSAGE; + flags = 0; + timestamp = 0; + szModule = 0; + cbSize = 0; + cbBlob = strlen(msg)+1; + pBlob = (PBYTE)msg; + } + db_event(char* msg, DWORD time) + { + cbBlob = strlen(msg)+1; + pBlob = (PBYTE)msg; + eventType = EVENTTYPE_MESSAGE; + flags = 0; + timestamp = time; + szModule = 0; + cbSize = 0; + } + db_event(char* msg, DWORD time, int type) + { + cbBlob = strlen(msg)+1; + pBlob = (PBYTE)msg; + if(type) + eventType = type; + else + eventType = EVENTTYPE_MESSAGE; + flags = 0; + timestamp = time; + szModule = 0; + cbSize = 0; + } + db_event(char* msg, int type) + { + cbBlob = strlen(msg)+1; + pBlob = (PBYTE)msg; + flags = 0; + if(type) + eventType = type; + else + eventType = EVENTTYPE_MESSAGE; + timestamp = 0; + szModule = 0; + cbSize = 0; + } + db_event(char* msg, DWORD time, int type, DWORD _flags) + { + cbBlob = strlen(msg)+1; + pBlob = (PBYTE)msg; + if(type) + eventType = type; + else + eventType = EVENTTYPE_MESSAGE; + flags = _flags; + timestamp = time; + szModule = 0; + cbSize = 0; + } +}; +void HistoryLog(HANDLE, db_event); + +#endif -- cgit v1.2.3