From af7e438cfe8ce85e1da234318ed1584e89d952cc Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Fri, 29 Jun 2012 05:38:03 +0000 Subject: only add some plugins and protocols, not adapted See please maybe not all need us git-svn-id: http://svn.miranda-ng.org/main/trunk@678 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/AutoShutdown/common.h | 93 + plugins/AutoShutdown/cpuusage.c | 257 + plugins/AutoShutdown/cpuusage.h | 24 + plugins/AutoShutdown/docs/Info_Src.txt | 31 + plugins/AutoShutdown/docs/License_Appendix.txt | 64 + plugins/AutoShutdown/docs/Shutdown-Developer.txt | 49 + plugins/AutoShutdown/docs/Shutdown-License.txt | 278 + plugins/AutoShutdown/docs/Shutdown-Readme.txt | 329 + plugins/AutoShutdown/docs/Shutdown-Translation.txt | 240 + plugins/AutoShutdown/docs/countdown.wav | Bin 0 -> 654 bytes plugins/AutoShutdown/frame.c | 644 ++ plugins/AutoShutdown/frame.h | 28 + plugins/AutoShutdown/m_shutdown.h | 196 + plugins/AutoShutdown/main.c | 192 + plugins/AutoShutdown/options.c | 189 + plugins/AutoShutdown/options.h | 24 + plugins/AutoShutdown/res/Thumbs.db | Bin 0 -> 6144 bytes plugins/AutoShutdown/res/active.ico | Bin 0 -> 1406 bytes plugins/AutoShutdown/res/header.ico | Bin 0 -> 2238 bytes plugins/AutoShutdown/res/inactive.ico | Bin 0 -> 1406 bytes plugins/AutoShutdown/resource.h | 58 + plugins/AutoShutdown/resource.rc | 253 + plugins/AutoShutdown/settingsdlg.c | 512 + plugins/AutoShutdown/settingsdlg.h | 30 + plugins/AutoShutdown/shutdown.def | 11 + plugins/AutoShutdown/shutdown.dep | 394 + plugins/AutoShutdown/shutdown.dsp | 451 + plugins/AutoShutdown/shutdown.dsw | 29 + plugins/AutoShutdown/shutdown.mak | 435 + plugins/AutoShutdown/shutdownsvc.c | 624 ++ plugins/AutoShutdown/shutdownsvc.h | 29 + plugins/AutoShutdown/utils.c | 458 + plugins/AutoShutdown/utils.h | 48 + plugins/AutoShutdown/version.h | 40 + plugins/AutoShutdown/version.rc | 51 + plugins/AutoShutdown/watcher.c | 408 + plugins/AutoShutdown/watcher.h | 29 + plugins/AvatarHistory/AvatarDlg.cpp | 621 ++ plugins/AvatarHistory/AvatarHistory.cpp | 999 ++ plugins/AvatarHistory/AvatarHistory.h | 109 + plugins/AvatarHistory/AvatarHistory.rc | 236 + plugins/AvatarHistory/AvatarHistory.vcxproj | 564 ++ .../AvatarHistory/AvatarHistory.vcxproj.filters | 82 + plugins/AvatarHistory/AvatarOverlay.ico | Bin 0 -> 1150 bytes plugins/AvatarHistory/Docs/avatarhist.png | Bin 0 -> 25934 bytes .../AvatarHistory/Docs/avatarhist_changelog.txt | 78 + plugins/AvatarHistory/Docs/avatarhist_readme.txt | 29 + plugins/AvatarHistory/Docs/avatarhist_version.txt | 1 + plugins/AvatarHistory/Docs/langpack_avatarhist.txt | 114 + plugins/AvatarHistory/history.ico | Bin 0 -> 1150 bytes plugins/AvatarHistory/icolib.cpp | 135 + plugins/AvatarHistory/options.cpp | 234 + plugins/AvatarHistory/popup.cpp | 279 + plugins/AvatarHistory/popup.h | 53 + plugins/AvatarHistory/resource.h | 88 + plugins/ExternalAPI/m_HTTPServer.h | 12 + plugins/ExternalAPI/m_autoreplacer.h | 39 + plugins/ExternalAPI/m_avatarhist.h | 56 + plugins/ExternalAPI/m_ftpfile.h | 119 + plugins/ExternalAPI/m_hddinfo.h | 6 + plugins/ExternalAPI/m_mucc.h | 189 + plugins/ExternalAPI/m_sendss.h | 66 + plugins/FTPFileYM/common.h | 129 + plugins/FTPFileYM/curl/curl.h | 1919 ++++ plugins/FTPFileYM/curl/curlbuild.h | 584 ++ plugins/FTPFileYM/curl/curlrules.h | 249 + plugins/FTPFileYM/curl/curlver.h | 70 + plugins/FTPFileYM/curl/easy.h | 103 + plugins/FTPFileYM/curl/mprintf.h | 82 + plugins/FTPFileYM/curl/multi.h | 346 + plugins/FTPFileYM/curl/stdcheaders.h | 34 + plugins/FTPFileYM/curl/typecheck-gcc.h | 551 + plugins/FTPFileYM/curl/types.h | 1 + plugins/FTPFileYM/dbentry.cpp | 169 + plugins/FTPFileYM/dbentry.h | 51 + plugins/FTPFileYM/deletetimer.cpp | 73 + plugins/FTPFileYM/deletetimer.h | 47 + plugins/FTPFileYM/dialog.cpp | 456 + plugins/FTPFileYM/dialog.h | 84 + plugins/FTPFileYM/docs/ftpfile_licence.txt | 340 + plugins/FTPFileYM/docs/ftpfile_readme.txt | 135 + plugins/FTPFileYM/docs/ftpfile_translate.txt | 103 + plugins/FTPFileYM/ftpfile.cpp | 634 ++ plugins/FTPFileYM/ftpfile.rc | 317 + plugins/FTPFileYM/ftpfile_10.vcxproj | 435 + plugins/FTPFileYM/ftpfile_10.vcxproj.filters | 175 + plugins/FTPFileYM/icons/clear.ico | Bin 0 -> 1150 bytes plugins/FTPFileYM/icons/clipboard.ico | Bin 0 -> 1150 bytes plugins/FTPFileYM/icons/delete.ico | Bin 0 -> 2550 bytes plugins/FTPFileYM/icons/ftp0.ico | Bin 0 -> 1150 bytes plugins/FTPFileYM/icons/ftp1.ico | Bin 0 -> 1150 bytes plugins/FTPFileYM/icons/ftp2.ico | Bin 0 -> 1150 bytes plugins/FTPFileYM/icons/ftp3.ico | Bin 0 -> 1150 bytes plugins/FTPFileYM/icons/ftp4.ico | Bin 0 -> 1150 bytes plugins/FTPFileYM/icons/menu.ico | Bin 0 -> 1150 bytes plugins/FTPFileYM/icons/pause.ico | Bin 0 -> 1150 bytes plugins/FTPFileYM/icons/resume.ico | Bin 0 -> 1150 bytes plugins/FTPFileYM/job_delete.cpp | 124 + plugins/FTPFileYM/job_delete.h | 50 + plugins/FTPFileYM/job_generic.cpp | 255 + plugins/FTPFileYM/job_generic.h | 109 + plugins/FTPFileYM/job_packer.cpp | 354 + plugins/FTPFileYM/job_packer.h | 63 + plugins/FTPFileYM/job_upload.cpp | 551 + plugins/FTPFileYM/job_upload.h | 84 + plugins/FTPFileYM/lib/libcurl.dll | Bin 0 -> 1048064 bytes plugins/FTPFileYM/lib/libcurl64.dll | Bin 0 -> 1196032 bytes plugins/FTPFileYM/libcurl.cpp | 73 + plugins/FTPFileYM/libcurl.h | 69 + plugins/FTPFileYM/manager.cpp | 449 + plugins/FTPFileYM/manager.h | 88 + plugins/FTPFileYM/mir_db.cpp | 198 + plugins/FTPFileYM/mir_db.h | 57 + plugins/FTPFileYM/options.cpp | 310 + plugins/FTPFileYM/options.h | 69 + plugins/FTPFileYM/resource.h | 101 + plugins/FTPFileYM/serverlist.cpp | 113 + plugins/FTPFileYM/serverlist.h | 79 + plugins/FTPFileYM/utils.cpp | 237 + plugins/FTPFileYM/utils.h | 71 + plugins/FTPFileYM/version.h | 4 + plugins/FTPFileYM/version.rc | 37 + plugins/FTPFileYM/zip/crypt.h | 131 + plugins/FTPFileYM/zip/ioapi.c | 235 + plugins/FTPFileYM/zip/ioapi.h | 200 + plugins/FTPFileYM/zip/zconf.h | 416 + plugins/FTPFileYM/zip/zip.c | 2004 ++++ plugins/FTPFileYM/zip/zip.h | 362 + plugins/FTPFileYM/zip/zlib.h | 1605 +++ plugins/SendScreenshotPlus/CSend.cpp | 416 + plugins/SendScreenshotPlus/CSend.h | 113 + plugins/SendScreenshotPlus/CSendEmail.cpp | 221 + plugins/SendScreenshotPlus/CSendEmail.h | 63 + plugins/SendScreenshotPlus/CSendFTPFile.cpp | 99 + plugins/SendScreenshotPlus/CSendFTPFile.h | 59 + plugins/SendScreenshotPlus/CSendFile.cpp | 53 + plugins/SendScreenshotPlus/CSendFile.h | 55 + plugins/SendScreenshotPlus/CSendHTTPServer.cpp | 143 + plugins/SendScreenshotPlus/CSendHTTPServer.h | 67 + plugins/SendScreenshotPlus/CSendImageShack.cpp | 299 + plugins/SendScreenshotPlus/CSendImageShack.h | 77 + plugins/SendScreenshotPlus/Main.cpp | 406 + plugins/SendScreenshotPlus/Main.h | 65 + plugins/SendScreenshotPlus/SendSS_9.vcproj | 621 ++ plugins/SendScreenshotPlus/UAboutForm.cpp | 212 + plugins/SendScreenshotPlus/UAboutForm.h | 69 + plugins/SendScreenshotPlus/UMainForm.cpp | 1180 +++ plugins/SendScreenshotPlus/UMainForm.h | 157 + plugins/SendScreenshotPlus/Utils.cpp | 579 ++ plugins/SendScreenshotPlus/Utils.h | 81 + plugins/SendScreenshotPlus/ctrl_button.cpp | 699 ++ plugins/SendScreenshotPlus/ctrl_button.h | 43 + plugins/SendScreenshotPlus/dlg_msgbox.cpp | 854 ++ plugins/SendScreenshotPlus/dlg_msgbox.h | 108 + plugins/SendScreenshotPlus/global.h | 196 + plugins/SendScreenshotPlus/mir_icolib.cpp | 382 + plugins/SendScreenshotPlus/mir_icolib.h | 139 + plugins/SendScreenshotPlus/mir_string.cpp | 179 + plugins/SendScreenshotPlus/mir_string.h | 129 + plugins/SendScreenshotPlus/res/UEditForm_nvr_1.bmp | Bin 0 -> 12342 bytes plugins/SendScreenshotPlus/res/UEditForm_nvr_2.bmp | Bin 0 -> 596 bytes plugins/SendScreenshotPlus/res/credits.txt | 10 + plugins/SendScreenshotPlus/res/license.txt | 15 + .../SendScreenshotPlus/res/overlay_disabled.ico | Bin 0 -> 1150 bytes plugins/SendScreenshotPlus/res/overlay_enabled.ico | Bin 0 -> 1150 bytes plugins/SendScreenshotPlus/res/ssArrow_Left.ico | Bin 0 -> 6830 bytes plugins/SendScreenshotPlus/res/ssArrow_Right.ico | Bin 0 -> 6830 bytes plugins/SendScreenshotPlus/res/ssCamera_1.ico | Bin 0 -> 6830 bytes plugins/SendScreenshotPlus/res/ssCamera_2.ico | Bin 0 -> 2550 bytes plugins/SendScreenshotPlus/res/ssDefault.ico | Bin 0 -> 1406 bytes plugins/SendScreenshotPlus/res/ssDelOff.ico | Bin 0 -> 6830 bytes plugins/SendScreenshotPlus/res/ssDelOn.ico | Bin 0 -> 6830 bytes plugins/SendScreenshotPlus/res/ssDeskOff.ico | Bin 0 -> 6830 bytes plugins/SendScreenshotPlus/res/ssDeskOn.ico | Bin 0 -> 6830 bytes plugins/SendScreenshotPlus/res/ssMonitor.ico | Bin 0 -> 6830 bytes plugins/SendScreenshotPlus/res/ssOpen.ico | Bin 0 -> 5430 bytes plugins/SendScreenshotPlus/res/ssTarget.ico | Bin 0 -> 766 bytes plugins/SendScreenshotPlus/res/sshelp.ico | Bin 0 -> 2550 bytes plugins/SendScreenshotPlus/resource.h | 102 + plugins/SendScreenshotPlus/resource.rc | 274 + plugins/SendScreenshotPlus/resource_6.rc | 2 + plugins/SendScreenshotPlus/sdk/DevKey.h | 3 + plugins/SendScreenshotPlus/sdk/icons.h | 112 + plugins/SendScreenshotPlus/version.h | 45 + plugins/SendScreenshotPlus/version.rc | 38 + plugins/ShlExt/clean.bat | 1 + plugins/ShlExt/docs/HowToBuild.txt | 22 + plugins/ShlExt/docs/shlext release notes.txt | 344 + plugins/ShlExt/inc/README.txt | 92 + plugins/ShlExt/inc/m_addcontact.inc | 54 + plugins/ShlExt/inc/m_api.pas | 75 + plugins/ShlExt/inc/m_awaymsg.inc | 40 + plugins/ShlExt/inc/m_clc.inc | 284 + plugins/ShlExt/inc/m_clist.inc | 641 ++ plugins/ShlExt/inc/m_clui.inc | 215 + plugins/ShlExt/inc/m_contacts.inc | 90 + plugins/ShlExt/inc/m_database.inc | 654 ++ plugins/ShlExt/inc/m_email.inc | 39 + plugins/ShlExt/inc/m_file.inc | 66 + plugins/ShlExt/inc/m_findadd.inc | 38 + plugins/ShlExt/inc/m_globaldefs.pas | 99 + plugins/ShlExt/inc/m_globaldefs.ppu | Bin 0 -> 8913 bytes plugins/ShlExt/inc/m_helpers.inc | 613 ++ plugins/ShlExt/inc/m_history.inc | 37 + plugins/ShlExt/inc/m_icq.inc | 191 + plugins/ShlExt/inc/m_ignore.inc | 74 + plugins/ShlExt/inc/m_langpack.inc | 82 + plugins/ShlExt/inc/m_message.inc | 57 + plugins/ShlExt/inc/m_netlib.inc | 713 ++ plugins/ShlExt/inc/m_options.inc | 109 + plugins/ShlExt/inc/m_plugins.inc | 70 + plugins/ShlExt/inc/m_popup.inc | 222 + plugins/ShlExt/inc/m_protocols.inc | 180 + plugins/ShlExt/inc/m_protomod.inc | 105 + plugins/ShlExt/inc/m_protosvc.inc | 753 ++ plugins/ShlExt/inc/m_skin.inc | 120 + plugins/ShlExt/inc/m_system.inc | 170 + plugins/ShlExt/inc/m_url.inc | 39 + plugins/ShlExt/inc/m_userinfo.inc | 84 + plugins/ShlExt/inc/m_utils.inc | 279 + plugins/ShlExt/inc/m_v8.inc | 62 + plugins/ShlExt/inc/newpluginapi.inc | 94 + plugins/ShlExt/inc/statusmodes.inc | 54 + plugins/ShlExt/inc/testdll.dpr | 60 + plugins/ShlExt/make.bat | 9 + plugins/ShlExt/resource.h | 13 + plugins/ShlExt/shlc.inc | 168 + plugins/ShlExt/shlcom.pas | 2383 +++++ plugins/ShlExt/shldlgs.rc | 93 + plugins/ShlExt/shldlgs.res | Bin 0 -> 2616 bytes plugins/ShlExt/shlext.dpr | 379 + plugins/ShlExt/shlicons.pas | 162 + plugins/ShlExt/shlipc.pas | 369 + plugins/SmartAutoReplier/ActionsHandler.cpp | 31 + plugins/SmartAutoReplier/ActionsHandler.h | 30 + plugins/SmartAutoReplier/AggressiveOptimize.h | 59 + plugins/SmartAutoReplier/Crc32Static.cpp | 139 + plugins/SmartAutoReplier/Crc32Static.h | 33 + plugins/SmartAutoReplier/CrushLog.cpp | 165 + plugins/SmartAutoReplier/CrushLog.h | 54 + plugins/SmartAutoReplier/GUI/AddRuleDlg.cpp | 219 + plugins/SmartAutoReplier/GUI/AddRuleDlg.h | 67 + plugins/SmartAutoReplier/GUI/EditReplyDlg.cpp | 88 + plugins/SmartAutoReplier/GUI/EditReplyDlg.h | 55 + plugins/SmartAutoReplier/GUI/OptionsDlg.cpp | 528 + plugins/SmartAutoReplier/GUI/OptionsDlg.h | 119 + plugins/SmartAutoReplier/GUI/SelectUserDlg.cpp | 109 + plugins/SmartAutoReplier/GUI/SelectUserDlg.h | 58 + plugins/SmartAutoReplier/GUI/SettingsDlgHolder.cpp | 207 + plugins/SmartAutoReplier/GUI/SettingsDlgHolder.h | 69 + plugins/SmartAutoReplier/Interfaces/ISettings.h | 34 + plugins/SmartAutoReplier/Interfaces/ISingletone.h | 35 + plugins/SmartAutoReplier/LuaBridge.cpp | 127 + plugins/SmartAutoReplier/LuaBridge.h | 96 + plugins/SmartAutoReplier/LuaScript.cpp | 215 + plugins/SmartAutoReplier/LuaScript.h | 68 + plugins/SmartAutoReplier/MessagesHandler.cpp | 469 + plugins/SmartAutoReplier/MessagesHandler.h | 72 + plugins/SmartAutoReplier/ModeMessHandler.cpp | 119 + plugins/SmartAutoReplier/ModeMessHandler.h | 34 + plugins/SmartAutoReplier/RuleItem.h | 47 + plugins/SmartAutoReplier/RulesStorage.cpp | 536 + plugins/SmartAutoReplier/RulesStorage.h | 63 + plugins/SmartAutoReplier/SAR.cpp | 462 + plugins/SmartAutoReplier/SAR.rc | 274 + plugins/SmartAutoReplier/SAR.sln | 25 + plugins/SmartAutoReplier/SAR.vcxproj | 189 + plugins/SmartAutoReplier/SAR.vcxproj.filters | 77 + plugins/SmartAutoReplier/SarLuaScript.cpp | 358 + plugins/SmartAutoReplier/SarLuaScript.h | 57 + plugins/SmartAutoReplier/ScriptsReader.cpp | 175 + plugins/SmartAutoReplier/ScriptsReader.h | 57 + plugins/SmartAutoReplier/SettingsHandler.cpp | 204 + plugins/SmartAutoReplier/SettingsHandler.h | 96 + plugins/SmartAutoReplier/comfunc.cpp | 74 + plugins/SmartAutoReplier/comfunc.h | 26 + plugins/SmartAutoReplier/comlogging.h | 42 + plugins/SmartAutoReplier/luainc.h | 31 + plugins/SmartAutoReplier/lualib/ReadMe.txt | 37 + plugins/SmartAutoReplier/lualib/lapi.c | 922 ++ plugins/SmartAutoReplier/lualib/lapi.h | 16 + plugins/SmartAutoReplier/lualib/lauxlib.c | 591 ++ plugins/SmartAutoReplier/lualib/lauxlib.h | 145 + plugins/SmartAutoReplier/lualib/lbaselib.c | 674 ++ plugins/SmartAutoReplier/lualib/lcode.c | 714 ++ plugins/SmartAutoReplier/lualib/lcode.h | 74 + plugins/SmartAutoReplier/lualib/ldblib.c | 299 + plugins/SmartAutoReplier/lualib/ldebug.c | 585 ++ plugins/SmartAutoReplier/lualib/ldebug.h | 31 + plugins/SmartAutoReplier/lualib/ldo.c | 458 + plugins/SmartAutoReplier/lualib/ldo.h | 60 + plugins/SmartAutoReplier/lualib/ldump.c | 170 + plugins/SmartAutoReplier/lualib/lfunc.c | 135 + plugins/SmartAutoReplier/lualib/lfunc.h | 25 + plugins/SmartAutoReplier/lualib/lgc.c | 493 + plugins/SmartAutoReplier/lualib/lgc.h | 25 + plugins/SmartAutoReplier/lualib/liolib.c | 750 ++ plugins/SmartAutoReplier/lualib/llex.c | 417 + plugins/SmartAutoReplier/lualib/llex.h | 75 + plugins/SmartAutoReplier/lualib/llimits.h | 185 + plugins/SmartAutoReplier/lualib/lmathlib.c | 246 + plugins/SmartAutoReplier/lualib/lmem.c | 91 + plugins/SmartAutoReplier/lualib/lmem.h | 44 + plugins/SmartAutoReplier/lualib/loadlib.c | 205 + plugins/SmartAutoReplier/lualib/lobject.c | 195 + plugins/SmartAutoReplier/lualib/lobject.h | 336 + plugins/SmartAutoReplier/lualib/lopcodes.c | 102 + plugins/SmartAutoReplier/lualib/lopcodes.h | 238 + plugins/SmartAutoReplier/lualib/lparser.c | 1329 +++ plugins/SmartAutoReplier/lualib/lparser.h | 71 + plugins/SmartAutoReplier/lualib/lstate.c | 220 + plugins/SmartAutoReplier/lualib/lstate.h | 195 + plugins/SmartAutoReplier/lualib/lstring.c | 102 + plugins/SmartAutoReplier/lualib/lstring.h | 33 + plugins/SmartAutoReplier/lualib/lstrlib.c | 770 ++ plugins/SmartAutoReplier/lualib/ltable.c | 509 + plugins/SmartAutoReplier/lualib/ltable.h | 31 + plugins/SmartAutoReplier/lualib/ltablib.c | 250 + plugins/SmartAutoReplier/lualib/ltests.c | 852 ++ plugins/SmartAutoReplier/lualib/ltm.c | 70 + plugins/SmartAutoReplier/lualib/ltm.h | 51 + plugins/SmartAutoReplier/lualib/lua.h | 391 + plugins/SmartAutoReplier/lualib/luainc.h | 12 + plugins/SmartAutoReplier/lualib/lualib.h | 56 + plugins/SmartAutoReplier/lualib/lualib.vcxproj | 138 + .../SmartAutoReplier/lualib/lualib.vcxproj.filters | 186 + plugins/SmartAutoReplier/lualib/lundump.c | 286 + plugins/SmartAutoReplier/lualib/lundump.h | 34 + plugins/SmartAutoReplier/lualib/lvm.c | 780 ++ plugins/SmartAutoReplier/lualib/lvm.h | 35 + plugins/SmartAutoReplier/lualib/lzio.c | 81 + plugins/SmartAutoReplier/lualib/lzio.h | 64 + plugins/SmartAutoReplier/lualib/targetver.h | 8 + plugins/SmartAutoReplier/resource.h | 52 + plugins/SmartAutoReplier/sar.ico | Bin 0 -> 318 bytes plugins/SmartAutoReplier/stdafx.cpp | 27 + plugins/SmartAutoReplier/stdafx.h | 74 + plugins/SmartAutoReplier/wtl/atlapp.h | 2035 ++++ plugins/SmartAutoReplier/wtl/atlcrack.h | 2384 +++++ plugins/SmartAutoReplier/wtl/atlctrls.h | 10041 +++++++++++++++++++ plugins/SmartAutoReplier/wtl/atlctrlw.h | 4157 ++++++++ plugins/SmartAutoReplier/wtl/atlctrlx.h | 5004 +++++++++ plugins/SmartAutoReplier/wtl/atlddx.h | 679 ++ plugins/SmartAutoReplier/wtl/atldlgs.h | 6403 ++++++++++++ plugins/SmartAutoReplier/wtl/atldwm.h | 461 + plugins/SmartAutoReplier/wtl/atlfind.h | 1032 ++ plugins/SmartAutoReplier/wtl/atlframe.h | 3688 +++++++ plugins/SmartAutoReplier/wtl/atlgdi.h | 3891 +++++++ plugins/SmartAutoReplier/wtl/atlmisc.h | 3817 +++++++ plugins/SmartAutoReplier/wtl/atlprint.h | 1109 ++ plugins/SmartAutoReplier/wtl/atlres.h | 263 + plugins/SmartAutoReplier/wtl/atlresce.h | 93 + plugins/SmartAutoReplier/wtl/atlribbon.h | 3446 +++++++ plugins/SmartAutoReplier/wtl/atlscrl.h | 2011 ++++ plugins/SmartAutoReplier/wtl/atlsplit.h | 917 ++ plugins/SmartAutoReplier/wtl/atltheme.h | 1218 +++ plugins/SmartAutoReplier/wtl/atluser.h | 1391 +++ plugins/SmartAutoReplier/wtl/atlwince.h | 2987 ++++++ plugins/SmartAutoReplier/wtl/atlwinx.h | 525 + plugins/XSoundNotify/DebugLogger.hpp | 91 + plugins/XSoundNotify/EventProcessor.cpp | 84 + plugins/XSoundNotify/EventProcessor.h | 27 + plugins/XSoundNotify/README | 1 + plugins/XSoundNotify/SettingsDialog.cpp | 124 + plugins/XSoundNotify/SettingsDialog.h | 60 + plugins/XSoundNotify/SoundNotifyData.cpp | 37 + plugins/XSoundNotify/SoundNotifyData.h | 33 + plugins/XSoundNotify/SoundNotifyDataStorage.cpp | 74 + plugins/XSoundNotify/SoundNotifyDataStorage.h | 34 + .../XSoundNotify/XSound Notify Miranda Plugin.sln | 20 + plugins/XSoundNotify/XSoundNotify.rc | Bin 0 -> 5494 bytes plugins/XSoundNotify/resource.h | Bin 0 -> 1556 bytes plugins/XSoundNotify/testplug.vcxproj | 167 + plugins/XSoundNotify/xsn_main.cpp | 122 + plugins/XSoundNotify/xsn_types.cpp | 32 + plugins/XSoundNotify/xsn_types.h | 33 + plugins/XSoundNotify/xsn_utils.cpp | 60 + plugins/XSoundNotify/xsn_utils.h | 18 + 378 files changed, 124761 insertions(+) create mode 100644 plugins/AutoShutdown/common.h create mode 100644 plugins/AutoShutdown/cpuusage.c create mode 100644 plugins/AutoShutdown/cpuusage.h create mode 100644 plugins/AutoShutdown/docs/Info_Src.txt create mode 100644 plugins/AutoShutdown/docs/License_Appendix.txt create mode 100644 plugins/AutoShutdown/docs/Shutdown-Developer.txt create mode 100644 plugins/AutoShutdown/docs/Shutdown-License.txt create mode 100644 plugins/AutoShutdown/docs/Shutdown-Readme.txt create mode 100644 plugins/AutoShutdown/docs/Shutdown-Translation.txt create mode 100644 plugins/AutoShutdown/docs/countdown.wav create mode 100644 plugins/AutoShutdown/frame.c create mode 100644 plugins/AutoShutdown/frame.h create mode 100644 plugins/AutoShutdown/m_shutdown.h create mode 100644 plugins/AutoShutdown/main.c create mode 100644 plugins/AutoShutdown/options.c create mode 100644 plugins/AutoShutdown/options.h create mode 100644 plugins/AutoShutdown/res/Thumbs.db create mode 100644 plugins/AutoShutdown/res/active.ico create mode 100644 plugins/AutoShutdown/res/header.ico create mode 100644 plugins/AutoShutdown/res/inactive.ico create mode 100644 plugins/AutoShutdown/resource.h create mode 100644 plugins/AutoShutdown/resource.rc create mode 100644 plugins/AutoShutdown/settingsdlg.c create mode 100644 plugins/AutoShutdown/settingsdlg.h create mode 100644 plugins/AutoShutdown/shutdown.def create mode 100644 plugins/AutoShutdown/shutdown.dep create mode 100644 plugins/AutoShutdown/shutdown.dsp create mode 100644 plugins/AutoShutdown/shutdown.dsw create mode 100644 plugins/AutoShutdown/shutdown.mak create mode 100644 plugins/AutoShutdown/shutdownsvc.c create mode 100644 plugins/AutoShutdown/shutdownsvc.h create mode 100644 plugins/AutoShutdown/utils.c create mode 100644 plugins/AutoShutdown/utils.h create mode 100644 plugins/AutoShutdown/version.h create mode 100644 plugins/AutoShutdown/version.rc create mode 100644 plugins/AutoShutdown/watcher.c create mode 100644 plugins/AutoShutdown/watcher.h create mode 100644 plugins/AvatarHistory/AvatarDlg.cpp create mode 100644 plugins/AvatarHistory/AvatarHistory.cpp create mode 100644 plugins/AvatarHistory/AvatarHistory.h create mode 100644 plugins/AvatarHistory/AvatarHistory.rc create mode 100644 plugins/AvatarHistory/AvatarHistory.vcxproj create mode 100644 plugins/AvatarHistory/AvatarHistory.vcxproj.filters create mode 100644 plugins/AvatarHistory/AvatarOverlay.ico create mode 100644 plugins/AvatarHistory/Docs/avatarhist.png create mode 100644 plugins/AvatarHistory/Docs/avatarhist_changelog.txt create mode 100644 plugins/AvatarHistory/Docs/avatarhist_readme.txt create mode 100644 plugins/AvatarHistory/Docs/avatarhist_version.txt create mode 100644 plugins/AvatarHistory/Docs/langpack_avatarhist.txt create mode 100644 plugins/AvatarHistory/history.ico create mode 100644 plugins/AvatarHistory/icolib.cpp create mode 100644 plugins/AvatarHistory/options.cpp create mode 100644 plugins/AvatarHistory/popup.cpp create mode 100644 plugins/AvatarHistory/popup.h create mode 100644 plugins/AvatarHistory/resource.h create mode 100644 plugins/ExternalAPI/m_autoreplacer.h create mode 100644 plugins/ExternalAPI/m_avatarhist.h create mode 100644 plugins/ExternalAPI/m_ftpfile.h create mode 100644 plugins/ExternalAPI/m_hddinfo.h create mode 100644 plugins/ExternalAPI/m_mucc.h create mode 100644 plugins/ExternalAPI/m_sendss.h create mode 100644 plugins/FTPFileYM/common.h create mode 100644 plugins/FTPFileYM/curl/curl.h create mode 100644 plugins/FTPFileYM/curl/curlbuild.h create mode 100644 plugins/FTPFileYM/curl/curlrules.h create mode 100644 plugins/FTPFileYM/curl/curlver.h create mode 100644 plugins/FTPFileYM/curl/easy.h create mode 100644 plugins/FTPFileYM/curl/mprintf.h create mode 100644 plugins/FTPFileYM/curl/multi.h create mode 100644 plugins/FTPFileYM/curl/stdcheaders.h create mode 100644 plugins/FTPFileYM/curl/typecheck-gcc.h create mode 100644 plugins/FTPFileYM/curl/types.h create mode 100644 plugins/FTPFileYM/dbentry.cpp create mode 100644 plugins/FTPFileYM/dbentry.h create mode 100644 plugins/FTPFileYM/deletetimer.cpp create mode 100644 plugins/FTPFileYM/deletetimer.h create mode 100644 plugins/FTPFileYM/dialog.cpp create mode 100644 plugins/FTPFileYM/dialog.h create mode 100644 plugins/FTPFileYM/docs/ftpfile_licence.txt create mode 100644 plugins/FTPFileYM/docs/ftpfile_readme.txt create mode 100644 plugins/FTPFileYM/docs/ftpfile_translate.txt create mode 100644 plugins/FTPFileYM/ftpfile.cpp create mode 100644 plugins/FTPFileYM/ftpfile.rc create mode 100644 plugins/FTPFileYM/ftpfile_10.vcxproj create mode 100644 plugins/FTPFileYM/ftpfile_10.vcxproj.filters create mode 100644 plugins/FTPFileYM/icons/clear.ico create mode 100644 plugins/FTPFileYM/icons/clipboard.ico create mode 100644 plugins/FTPFileYM/icons/delete.ico create mode 100644 plugins/FTPFileYM/icons/ftp0.ico create mode 100644 plugins/FTPFileYM/icons/ftp1.ico create mode 100644 plugins/FTPFileYM/icons/ftp2.ico create mode 100644 plugins/FTPFileYM/icons/ftp3.ico create mode 100644 plugins/FTPFileYM/icons/ftp4.ico create mode 100644 plugins/FTPFileYM/icons/menu.ico create mode 100644 plugins/FTPFileYM/icons/pause.ico create mode 100644 plugins/FTPFileYM/icons/resume.ico create mode 100644 plugins/FTPFileYM/job_delete.cpp create mode 100644 plugins/FTPFileYM/job_delete.h create mode 100644 plugins/FTPFileYM/job_generic.cpp create mode 100644 plugins/FTPFileYM/job_generic.h create mode 100644 plugins/FTPFileYM/job_packer.cpp create mode 100644 plugins/FTPFileYM/job_packer.h create mode 100644 plugins/FTPFileYM/job_upload.cpp create mode 100644 plugins/FTPFileYM/job_upload.h create mode 100644 plugins/FTPFileYM/lib/libcurl.dll create mode 100644 plugins/FTPFileYM/lib/libcurl64.dll create mode 100644 plugins/FTPFileYM/libcurl.cpp create mode 100644 plugins/FTPFileYM/libcurl.h create mode 100644 plugins/FTPFileYM/manager.cpp create mode 100644 plugins/FTPFileYM/manager.h create mode 100644 plugins/FTPFileYM/mir_db.cpp create mode 100644 plugins/FTPFileYM/mir_db.h create mode 100644 plugins/FTPFileYM/options.cpp create mode 100644 plugins/FTPFileYM/options.h create mode 100644 plugins/FTPFileYM/resource.h create mode 100644 plugins/FTPFileYM/serverlist.cpp create mode 100644 plugins/FTPFileYM/serverlist.h create mode 100644 plugins/FTPFileYM/utils.cpp create mode 100644 plugins/FTPFileYM/utils.h create mode 100644 plugins/FTPFileYM/version.h create mode 100644 plugins/FTPFileYM/version.rc create mode 100644 plugins/FTPFileYM/zip/crypt.h create mode 100644 plugins/FTPFileYM/zip/ioapi.c create mode 100644 plugins/FTPFileYM/zip/ioapi.h create mode 100644 plugins/FTPFileYM/zip/zconf.h create mode 100644 plugins/FTPFileYM/zip/zip.c create mode 100644 plugins/FTPFileYM/zip/zip.h create mode 100644 plugins/FTPFileYM/zip/zlib.h create mode 100644 plugins/SendScreenshotPlus/CSend.cpp create mode 100644 plugins/SendScreenshotPlus/CSend.h create mode 100644 plugins/SendScreenshotPlus/CSendEmail.cpp create mode 100644 plugins/SendScreenshotPlus/CSendEmail.h create mode 100644 plugins/SendScreenshotPlus/CSendFTPFile.cpp create mode 100644 plugins/SendScreenshotPlus/CSendFTPFile.h create mode 100644 plugins/SendScreenshotPlus/CSendFile.cpp create mode 100644 plugins/SendScreenshotPlus/CSendFile.h create mode 100644 plugins/SendScreenshotPlus/CSendHTTPServer.cpp create mode 100644 plugins/SendScreenshotPlus/CSendHTTPServer.h create mode 100644 plugins/SendScreenshotPlus/CSendImageShack.cpp create mode 100644 plugins/SendScreenshotPlus/CSendImageShack.h create mode 100644 plugins/SendScreenshotPlus/Main.cpp create mode 100644 plugins/SendScreenshotPlus/Main.h create mode 100644 plugins/SendScreenshotPlus/SendSS_9.vcproj create mode 100644 plugins/SendScreenshotPlus/UAboutForm.cpp create mode 100644 plugins/SendScreenshotPlus/UAboutForm.h create mode 100644 plugins/SendScreenshotPlus/UMainForm.cpp create mode 100644 plugins/SendScreenshotPlus/UMainForm.h create mode 100644 plugins/SendScreenshotPlus/Utils.cpp create mode 100644 plugins/SendScreenshotPlus/Utils.h create mode 100644 plugins/SendScreenshotPlus/ctrl_button.cpp create mode 100644 plugins/SendScreenshotPlus/ctrl_button.h create mode 100644 plugins/SendScreenshotPlus/dlg_msgbox.cpp create mode 100644 plugins/SendScreenshotPlus/dlg_msgbox.h create mode 100644 plugins/SendScreenshotPlus/global.h create mode 100644 plugins/SendScreenshotPlus/mir_icolib.cpp create mode 100644 plugins/SendScreenshotPlus/mir_icolib.h create mode 100644 plugins/SendScreenshotPlus/mir_string.cpp create mode 100644 plugins/SendScreenshotPlus/mir_string.h create mode 100644 plugins/SendScreenshotPlus/res/UEditForm_nvr_1.bmp create mode 100644 plugins/SendScreenshotPlus/res/UEditForm_nvr_2.bmp create mode 100644 plugins/SendScreenshotPlus/res/credits.txt create mode 100644 plugins/SendScreenshotPlus/res/license.txt create mode 100644 plugins/SendScreenshotPlus/res/overlay_disabled.ico create mode 100644 plugins/SendScreenshotPlus/res/overlay_enabled.ico create mode 100644 plugins/SendScreenshotPlus/res/ssArrow_Left.ico create mode 100644 plugins/SendScreenshotPlus/res/ssArrow_Right.ico create mode 100644 plugins/SendScreenshotPlus/res/ssCamera_1.ico create mode 100644 plugins/SendScreenshotPlus/res/ssCamera_2.ico create mode 100644 plugins/SendScreenshotPlus/res/ssDefault.ico create mode 100644 plugins/SendScreenshotPlus/res/ssDelOff.ico create mode 100644 plugins/SendScreenshotPlus/res/ssDelOn.ico create mode 100644 plugins/SendScreenshotPlus/res/ssDeskOff.ico create mode 100644 plugins/SendScreenshotPlus/res/ssDeskOn.ico create mode 100644 plugins/SendScreenshotPlus/res/ssMonitor.ico create mode 100644 plugins/SendScreenshotPlus/res/ssOpen.ico create mode 100644 plugins/SendScreenshotPlus/res/ssTarget.ico create mode 100644 plugins/SendScreenshotPlus/res/sshelp.ico create mode 100644 plugins/SendScreenshotPlus/resource.h create mode 100644 plugins/SendScreenshotPlus/resource.rc create mode 100644 plugins/SendScreenshotPlus/resource_6.rc create mode 100644 plugins/SendScreenshotPlus/sdk/DevKey.h create mode 100644 plugins/SendScreenshotPlus/sdk/icons.h create mode 100644 plugins/SendScreenshotPlus/version.h create mode 100644 plugins/SendScreenshotPlus/version.rc create mode 100644 plugins/ShlExt/clean.bat create mode 100644 plugins/ShlExt/docs/HowToBuild.txt create mode 100644 plugins/ShlExt/docs/shlext release notes.txt create mode 100644 plugins/ShlExt/inc/README.txt create mode 100644 plugins/ShlExt/inc/m_addcontact.inc create mode 100644 plugins/ShlExt/inc/m_api.pas create mode 100644 plugins/ShlExt/inc/m_awaymsg.inc create mode 100644 plugins/ShlExt/inc/m_clc.inc create mode 100644 plugins/ShlExt/inc/m_clist.inc create mode 100644 plugins/ShlExt/inc/m_clui.inc create mode 100644 plugins/ShlExt/inc/m_contacts.inc create mode 100644 plugins/ShlExt/inc/m_database.inc create mode 100644 plugins/ShlExt/inc/m_email.inc create mode 100644 plugins/ShlExt/inc/m_file.inc create mode 100644 plugins/ShlExt/inc/m_findadd.inc create mode 100644 plugins/ShlExt/inc/m_globaldefs.pas create mode 100644 plugins/ShlExt/inc/m_globaldefs.ppu create mode 100644 plugins/ShlExt/inc/m_helpers.inc create mode 100644 plugins/ShlExt/inc/m_history.inc create mode 100644 plugins/ShlExt/inc/m_icq.inc create mode 100644 plugins/ShlExt/inc/m_ignore.inc create mode 100644 plugins/ShlExt/inc/m_langpack.inc create mode 100644 plugins/ShlExt/inc/m_message.inc create mode 100644 plugins/ShlExt/inc/m_netlib.inc create mode 100644 plugins/ShlExt/inc/m_options.inc create mode 100644 plugins/ShlExt/inc/m_plugins.inc create mode 100644 plugins/ShlExt/inc/m_popup.inc create mode 100644 plugins/ShlExt/inc/m_protocols.inc create mode 100644 plugins/ShlExt/inc/m_protomod.inc create mode 100644 plugins/ShlExt/inc/m_protosvc.inc create mode 100644 plugins/ShlExt/inc/m_skin.inc create mode 100644 plugins/ShlExt/inc/m_system.inc create mode 100644 plugins/ShlExt/inc/m_url.inc create mode 100644 plugins/ShlExt/inc/m_userinfo.inc create mode 100644 plugins/ShlExt/inc/m_utils.inc create mode 100644 plugins/ShlExt/inc/m_v8.inc create mode 100644 plugins/ShlExt/inc/newpluginapi.inc create mode 100644 plugins/ShlExt/inc/statusmodes.inc create mode 100644 plugins/ShlExt/inc/testdll.dpr create mode 100644 plugins/ShlExt/make.bat create mode 100644 plugins/ShlExt/resource.h create mode 100644 plugins/ShlExt/shlc.inc create mode 100644 plugins/ShlExt/shlcom.pas create mode 100644 plugins/ShlExt/shldlgs.rc create mode 100644 plugins/ShlExt/shldlgs.res create mode 100644 plugins/ShlExt/shlext.dpr create mode 100644 plugins/ShlExt/shlicons.pas create mode 100644 plugins/ShlExt/shlipc.pas create mode 100644 plugins/SmartAutoReplier/ActionsHandler.cpp create mode 100644 plugins/SmartAutoReplier/ActionsHandler.h create mode 100644 plugins/SmartAutoReplier/AggressiveOptimize.h create mode 100644 plugins/SmartAutoReplier/Crc32Static.cpp create mode 100644 plugins/SmartAutoReplier/Crc32Static.h create mode 100644 plugins/SmartAutoReplier/CrushLog.cpp create mode 100644 plugins/SmartAutoReplier/CrushLog.h create mode 100644 plugins/SmartAutoReplier/GUI/AddRuleDlg.cpp create mode 100644 plugins/SmartAutoReplier/GUI/AddRuleDlg.h create mode 100644 plugins/SmartAutoReplier/GUI/EditReplyDlg.cpp create mode 100644 plugins/SmartAutoReplier/GUI/EditReplyDlg.h create mode 100644 plugins/SmartAutoReplier/GUI/OptionsDlg.cpp create mode 100644 plugins/SmartAutoReplier/GUI/OptionsDlg.h create mode 100644 plugins/SmartAutoReplier/GUI/SelectUserDlg.cpp create mode 100644 plugins/SmartAutoReplier/GUI/SelectUserDlg.h create mode 100644 plugins/SmartAutoReplier/GUI/SettingsDlgHolder.cpp create mode 100644 plugins/SmartAutoReplier/GUI/SettingsDlgHolder.h create mode 100644 plugins/SmartAutoReplier/Interfaces/ISettings.h create mode 100644 plugins/SmartAutoReplier/Interfaces/ISingletone.h create mode 100644 plugins/SmartAutoReplier/LuaBridge.cpp create mode 100644 plugins/SmartAutoReplier/LuaBridge.h create mode 100644 plugins/SmartAutoReplier/LuaScript.cpp create mode 100644 plugins/SmartAutoReplier/LuaScript.h create mode 100644 plugins/SmartAutoReplier/MessagesHandler.cpp create mode 100644 plugins/SmartAutoReplier/MessagesHandler.h create mode 100644 plugins/SmartAutoReplier/ModeMessHandler.cpp create mode 100644 plugins/SmartAutoReplier/ModeMessHandler.h create mode 100644 plugins/SmartAutoReplier/RuleItem.h create mode 100644 plugins/SmartAutoReplier/RulesStorage.cpp create mode 100644 plugins/SmartAutoReplier/RulesStorage.h create mode 100644 plugins/SmartAutoReplier/SAR.cpp create mode 100644 plugins/SmartAutoReplier/SAR.rc create mode 100644 plugins/SmartAutoReplier/SAR.sln create mode 100644 plugins/SmartAutoReplier/SAR.vcxproj create mode 100644 plugins/SmartAutoReplier/SAR.vcxproj.filters create mode 100644 plugins/SmartAutoReplier/SarLuaScript.cpp create mode 100644 plugins/SmartAutoReplier/SarLuaScript.h create mode 100644 plugins/SmartAutoReplier/ScriptsReader.cpp create mode 100644 plugins/SmartAutoReplier/ScriptsReader.h create mode 100644 plugins/SmartAutoReplier/SettingsHandler.cpp create mode 100644 plugins/SmartAutoReplier/SettingsHandler.h create mode 100644 plugins/SmartAutoReplier/comfunc.cpp create mode 100644 plugins/SmartAutoReplier/comfunc.h create mode 100644 plugins/SmartAutoReplier/comlogging.h create mode 100644 plugins/SmartAutoReplier/luainc.h create mode 100644 plugins/SmartAutoReplier/lualib/ReadMe.txt create mode 100644 plugins/SmartAutoReplier/lualib/lapi.c create mode 100644 plugins/SmartAutoReplier/lualib/lapi.h create mode 100644 plugins/SmartAutoReplier/lualib/lauxlib.c create mode 100644 plugins/SmartAutoReplier/lualib/lauxlib.h create mode 100644 plugins/SmartAutoReplier/lualib/lbaselib.c create mode 100644 plugins/SmartAutoReplier/lualib/lcode.c create mode 100644 plugins/SmartAutoReplier/lualib/lcode.h create mode 100644 plugins/SmartAutoReplier/lualib/ldblib.c create mode 100644 plugins/SmartAutoReplier/lualib/ldebug.c create mode 100644 plugins/SmartAutoReplier/lualib/ldebug.h create mode 100644 plugins/SmartAutoReplier/lualib/ldo.c create mode 100644 plugins/SmartAutoReplier/lualib/ldo.h create mode 100644 plugins/SmartAutoReplier/lualib/ldump.c create mode 100644 plugins/SmartAutoReplier/lualib/lfunc.c create mode 100644 plugins/SmartAutoReplier/lualib/lfunc.h create mode 100644 plugins/SmartAutoReplier/lualib/lgc.c create mode 100644 plugins/SmartAutoReplier/lualib/lgc.h create mode 100644 plugins/SmartAutoReplier/lualib/liolib.c create mode 100644 plugins/SmartAutoReplier/lualib/llex.c create mode 100644 plugins/SmartAutoReplier/lualib/llex.h create mode 100644 plugins/SmartAutoReplier/lualib/llimits.h create mode 100644 plugins/SmartAutoReplier/lualib/lmathlib.c create mode 100644 plugins/SmartAutoReplier/lualib/lmem.c create mode 100644 plugins/SmartAutoReplier/lualib/lmem.h create mode 100644 plugins/SmartAutoReplier/lualib/loadlib.c create mode 100644 plugins/SmartAutoReplier/lualib/lobject.c create mode 100644 plugins/SmartAutoReplier/lualib/lobject.h create mode 100644 plugins/SmartAutoReplier/lualib/lopcodes.c create mode 100644 plugins/SmartAutoReplier/lualib/lopcodes.h create mode 100644 plugins/SmartAutoReplier/lualib/lparser.c create mode 100644 plugins/SmartAutoReplier/lualib/lparser.h create mode 100644 plugins/SmartAutoReplier/lualib/lstate.c create mode 100644 plugins/SmartAutoReplier/lualib/lstate.h create mode 100644 plugins/SmartAutoReplier/lualib/lstring.c create mode 100644 plugins/SmartAutoReplier/lualib/lstring.h create mode 100644 plugins/SmartAutoReplier/lualib/lstrlib.c create mode 100644 plugins/SmartAutoReplier/lualib/ltable.c create mode 100644 plugins/SmartAutoReplier/lualib/ltable.h create mode 100644 plugins/SmartAutoReplier/lualib/ltablib.c create mode 100644 plugins/SmartAutoReplier/lualib/ltests.c create mode 100644 plugins/SmartAutoReplier/lualib/ltm.c create mode 100644 plugins/SmartAutoReplier/lualib/ltm.h create mode 100644 plugins/SmartAutoReplier/lualib/lua.h create mode 100644 plugins/SmartAutoReplier/lualib/luainc.h create mode 100644 plugins/SmartAutoReplier/lualib/lualib.h create mode 100644 plugins/SmartAutoReplier/lualib/lualib.vcxproj create mode 100644 plugins/SmartAutoReplier/lualib/lualib.vcxproj.filters create mode 100644 plugins/SmartAutoReplier/lualib/lundump.c create mode 100644 plugins/SmartAutoReplier/lualib/lundump.h create mode 100644 plugins/SmartAutoReplier/lualib/lvm.c create mode 100644 plugins/SmartAutoReplier/lualib/lvm.h create mode 100644 plugins/SmartAutoReplier/lualib/lzio.c create mode 100644 plugins/SmartAutoReplier/lualib/lzio.h create mode 100644 plugins/SmartAutoReplier/lualib/targetver.h create mode 100644 plugins/SmartAutoReplier/resource.h create mode 100644 plugins/SmartAutoReplier/sar.ico create mode 100644 plugins/SmartAutoReplier/stdafx.cpp create mode 100644 plugins/SmartAutoReplier/stdafx.h create mode 100644 plugins/SmartAutoReplier/wtl/atlapp.h create mode 100644 plugins/SmartAutoReplier/wtl/atlcrack.h create mode 100644 plugins/SmartAutoReplier/wtl/atlctrls.h create mode 100644 plugins/SmartAutoReplier/wtl/atlctrlw.h create mode 100644 plugins/SmartAutoReplier/wtl/atlctrlx.h create mode 100644 plugins/SmartAutoReplier/wtl/atlddx.h create mode 100644 plugins/SmartAutoReplier/wtl/atldlgs.h create mode 100644 plugins/SmartAutoReplier/wtl/atldwm.h create mode 100644 plugins/SmartAutoReplier/wtl/atlfind.h create mode 100644 plugins/SmartAutoReplier/wtl/atlframe.h create mode 100644 plugins/SmartAutoReplier/wtl/atlgdi.h create mode 100644 plugins/SmartAutoReplier/wtl/atlmisc.h create mode 100644 plugins/SmartAutoReplier/wtl/atlprint.h create mode 100644 plugins/SmartAutoReplier/wtl/atlres.h create mode 100644 plugins/SmartAutoReplier/wtl/atlresce.h create mode 100644 plugins/SmartAutoReplier/wtl/atlribbon.h create mode 100644 plugins/SmartAutoReplier/wtl/atlscrl.h create mode 100644 plugins/SmartAutoReplier/wtl/atlsplit.h create mode 100644 plugins/SmartAutoReplier/wtl/atltheme.h create mode 100644 plugins/SmartAutoReplier/wtl/atluser.h create mode 100644 plugins/SmartAutoReplier/wtl/atlwince.h create mode 100644 plugins/SmartAutoReplier/wtl/atlwinx.h create mode 100644 plugins/XSoundNotify/DebugLogger.hpp create mode 100644 plugins/XSoundNotify/EventProcessor.cpp create mode 100644 plugins/XSoundNotify/EventProcessor.h create mode 100644 plugins/XSoundNotify/README create mode 100644 plugins/XSoundNotify/SettingsDialog.cpp create mode 100644 plugins/XSoundNotify/SettingsDialog.h create mode 100644 plugins/XSoundNotify/SoundNotifyData.cpp create mode 100644 plugins/XSoundNotify/SoundNotifyData.h create mode 100644 plugins/XSoundNotify/SoundNotifyDataStorage.cpp create mode 100644 plugins/XSoundNotify/SoundNotifyDataStorage.h create mode 100644 plugins/XSoundNotify/XSound Notify Miranda Plugin.sln create mode 100644 plugins/XSoundNotify/XSoundNotify.rc create mode 100644 plugins/XSoundNotify/resource.h create mode 100644 plugins/XSoundNotify/testplug.vcxproj create mode 100644 plugins/XSoundNotify/xsn_main.cpp create mode 100644 plugins/XSoundNotify/xsn_types.cpp create mode 100644 plugins/XSoundNotify/xsn_types.h create mode 100644 plugins/XSoundNotify/xsn_utils.cpp create mode 100644 plugins/XSoundNotify/xsn_utils.h (limited to 'plugins') diff --git a/plugins/AutoShutdown/common.h b/plugins/AutoShutdown/common.h new file mode 100644 index 0000000000..eec97b0873 --- /dev/null +++ b/plugins/AutoShutdown/common.h @@ -0,0 +1,93 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include /* for mir_sntprintf() */ +#include /* for mktime(),time() */ +#include /* for _itow() */ +#include + +#define _WIN32_WINNT 0x0700 +#define __RPCASYNC_H__ /* VC6 shows warning there */ +#include +#pragma warning(disable:4201) /* nonstandard extension used : nameless struct/union */ +#include +#pragma warning(default:4201) /* nonstandard extension used : nameless struct/union */ +#include + +/* WinXP+: shutdown reason codes */ +#if defined(EWX_RESTARTAPPS) /* new MS Platform SDK */ + #include +#else + #define SHTDN_REASON_MAJOR_OTHER 0x00000000 + #define SHTDN_REASON_MINOR_OTHER 0x00000000 + #define SHTDN_REASON_FLAG_PLANNED 0x80000000 +#endif + +/* RAS */ +#undef WINVER +#define WINVER 0x400 /* prevent INVALID_BUFFER error */ +#include /* for RasEnumConnections(), RasHangUp() */ +#include /* error codes for RAS */ + +#define MIRANDA_VER 0x0702 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "m_shutdown.h" +#include "cpuusage.h" +#include "frame.h" +#include "options.h" +#include "settingsdlg.h" +#include "shutdownsvc.h" +#include "utils.h" +#include "watcher.h" +#include "resource.h" diff --git a/plugins/AutoShutdown/cpuusage.c b/plugins/AutoShutdown/cpuusage.c new file mode 100644 index 0000000000..1270fe02ec --- /dev/null +++ b/plugins/AutoShutdown/cpuusage.c @@ -0,0 +1,257 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "common.h" + +/************************* Stat Switch ********************************/ + +#define Li2Double(x) ((double)((x).HighPart)*4.294967296E9+(double)((x).LowPart)) + +static BOOL WinNT_PerfStatsSwitch(TCHAR *pszServiceName,BOOL fDisable) +{ + HKEY hKeyServices,hKeyService,hKeyPerf; + DWORD dwData,dwDataSize; + BOOL fSwitched=FALSE; + /* Win2000+ */ + if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("System\\CurrentControlSet\\Services"),0,KEY_QUERY_VALUE|KEY_SET_VALUE,&hKeyServices)) { + if(!RegOpenKeyEx(hKeyServices,pszServiceName,0,KEY_QUERY_VALUE|KEY_SET_VALUE,&hKeyService)) { + if(!RegOpenKeyEx(hKeyService,_T("Performance"),0,KEY_QUERY_VALUE|KEY_SET_VALUE,&hKeyPerf)) { + dwDataSize=sizeof(DWORD); + if(!RegQueryValueEx(hKeyPerf,_T("Disable Performance Counters"),NULL,NULL,(BYTE*)&dwData,&dwDataSize)) + if((dwData!=0)!=fDisable) + fSwitched=!RegSetValueEx(hKeyPerf,_T("Disable Performance Counters"),0,REG_DWORD,(BYTE*)&fDisable,dwDataSize); + RegCloseKey(hKeyPerf); + } + RegCloseKey(hKeyService); + } + RegCloseKey(hKeyServices); + } + return fSwitched; +} + +#if !defined(_UNICODE) +static void Win9x_PerfStatsSwitch(HKEY hKey,char *pszAction,char *pszName) +{ + DWORD dwData,dwSize; + dwSize=sizeof(dwData); + if(!RegOpenKeyExA(hKey,pszAction,0,KEY_QUERY_VALUE,&hKey)) { + /* a simple query does the trick (data and size must not be NULL!) */ + RegQueryValueExA(hKey,pszName,NULL,NULL,(BYTE*)&dwData,&dwSize); + RegCloseKey(hKey); + } +} +#endif + +/************************* Poll Thread ********************************/ + +struct CpuUsageThreadParams { + DWORD dwDelayMillis; + CPUUSAGEAVAILPROC pfnDataAvailProc; + LPARAM lParam; + HANDLE hFirstEvent; + DWORD *pidThread; +}; + +static BOOL CallBackAndWait(struct CpuUsageThreadParams *param,BYTE nCpuUsage) +{ + if(param->hFirstEvent!=NULL) { + /* return value for PollCpuUsage() */ + *param->pidThread=GetCurrentThreadId(); + SetEvent(param->hFirstEvent); + param->hFirstEvent=NULL; + /* lower priority after first call */ + SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_IDLE); + } + if(!param->pfnDataAvailProc(nCpuUsage,param->lParam)) return FALSE; + SleepEx(param->dwDelayMillis,TRUE); + return !Miranda_Terminated(); +} + +#if !defined(_UNICODE) +static void Win9x_PollThread(struct CpuUsageThreadParams *param) +{ + HKEY hKeyStats,hKeyData; + DWORD dwBufferSize,dwData; + + if(!RegOpenKeyExA(HKEY_DYN_DATA,"PerfStats",0,KEY_QUERY_VALUE,&hKeyStats)) { + /* start query */ + /* not needed for kernel + * Win9x_PerfStatsSwitch(hKeyStats,"StartSrv","KERNEL"); */ + Win9x_PerfStatsSwitch(hKeyStats,"StartStat","KERNEL\\CPUUsage"); + /* retrieve cpu usage */ + if(!RegOpenKeyExA(hKeyStats,"StatData",0,KEY_QUERY_VALUE,&hKeyData)) { + dwBufferSize=sizeof(dwData); + while(!RegQueryValueExA(hKeyData,"KERNEL\\CPUUsage",NULL,NULL,(BYTE*)&dwData,&dwBufferSize)) { + dwBufferSize=sizeof(dwData); + if(!CallBackAndWait(param,(BYTE)dwData)) break; + } + RegCloseKey(hKeyData); + } + /* stop query */ + Win9x_PerfStatsSwitch(hKeyStats,"StopStat","KERNEL\\CPUUsage"); + /* not needed for kernel + * Win9x_PerfStatsSwitch(hKeyStats,"StopSrv","KERNEL"); */ + RegCloseKey(hKeyStats); + } + /* return error for PollCpuUsage() if never succeeded */ + if(param->hFirstEvent!=NULL) SetEvent(param->hFirstEvent); + mir_free(param); +} +#endif /* !_UNICODE */ + +static void WinNT_PollThread(struct CpuUsageThreadParams *param) +{ + DWORD dwBufferSize=0,dwCount; + BYTE *pBuffer=NULL; + PERF_DATA_BLOCK *pPerfData=NULL; + LONG res,lCount; + PERF_OBJECT_TYPE *pPerfObj; + PERF_COUNTER_DEFINITION *pPerfCounter; + PERF_INSTANCE_DEFINITION *pPerfInstance; + PERF_COUNTER_BLOCK *pPerfCounterBlock; + DWORD dwObjectId,dwCounterId; + WCHAR wszValueName[11],*pwszInstanceName; + BYTE nCpuUsage; + BOOL fSwitched,fFound,fIsFirst=FALSE; + LARGE_INTEGER liPrevCounterValue={0},liCurrentCounterValue={0},liPrevPerfTime100nSec={0}; + + /* init */ + if(IsWinVer2000Plus()) { /* Win2000+: */ + dwObjectId=238; /*'Processor' object */ + dwCounterId=6; /* '% processor time' counter */ + pwszInstanceName=L"_Total"; /* '_Total' instance */ + } else { /* WinNT4: */ + dwObjectId=2; /* 'System' object */ + dwCounterId=240; /* '% Total processor time' counter */ + pwszInstanceName=NULL; + } + _itow(dwObjectId,wszValueName,10); + fSwitched=WinNT_PerfStatsSwitch(_T("PerfOS"),FALSE); + + /* poll */ + for(;;) { + /* retrieve data for given object */ + res=RegQueryValueExW(HKEY_PERFORMANCE_DATA,wszValueName,NULL,NULL,(BYTE*)pPerfData,&dwBufferSize); + while(!pBuffer || res==ERROR_MORE_DATA) { + pBuffer=(BYTE*)mir_realloc(pPerfData,dwBufferSize+=256); + if(!pBuffer) break; + pPerfData=(PERF_DATA_BLOCK*)pBuffer; + res=RegQueryValueExW(HKEY_PERFORMANCE_DATA,wszValueName,NULL,NULL,pBuffer,&dwBufferSize); + } + if(res!=ERROR_SUCCESS) break; + + /* find object in data */ + fFound=FALSE; + /* first object */ + pPerfObj=(PERF_OBJECT_TYPE*)((BYTE*)pPerfData+pPerfData->HeaderLength); + for(dwCount=0;dwCountNumObjectTypes;++dwCount) { + if(pPerfObj->ObjectNameTitleIndex==dwObjectId) { + /* find counter in object data */ + /* first counter */ + pPerfCounter=(PERF_COUNTER_DEFINITION*)((BYTE*)pPerfObj+pPerfObj->HeaderLength); + for(dwCount=0;dwCount<(pPerfObj->NumCounters);++dwCount) { + if(pPerfCounter->CounterNameTitleIndex==dwCounterId) { + /* find instance in counter data */ + if(pPerfObj->NumInstances==PERF_NO_INSTANCES) { + pPerfCounterBlock=(PERF_COUNTER_BLOCK*)((BYTE*)pPerfObj+pPerfObj->DefinitionLength); + liCurrentCounterValue=*(LARGE_INTEGER*)((BYTE*)pPerfCounterBlock+pPerfCounter->CounterOffset); + fFound=TRUE; + } + else { + /* first instance */ + pPerfInstance=(PERF_INSTANCE_DEFINITION*)((BYTE*)pPerfObj+pPerfObj->DefinitionLength); + for(lCount=0;lCount<(pPerfObj->NumInstances);++lCount) { + pPerfCounterBlock=(PERF_COUNTER_BLOCK*)((BYTE*)pPerfInstance+pPerfInstance->ByteLength); + if(!lstrcmpiW(pwszInstanceName,(WCHAR*)((BYTE*)pPerfInstance+pPerfInstance->NameOffset)) || !pwszInstanceName) { + liCurrentCounterValue=*(LARGE_INTEGER*)((BYTE*)pPerfCounterBlock+pPerfCounter->CounterOffset); + fFound=TRUE; + break; + } + /* next instance */ + pPerfInstance=(PPERF_INSTANCE_DEFINITION)((BYTE*)pPerfCounterBlock+pPerfCounterBlock->ByteLength); + } + } + break; + } + /* next counter */ + pPerfCounter=(PERF_COUNTER_DEFINITION*)((BYTE*)pPerfCounter+pPerfCounter->ByteLength); + } + break; + } + /* next object */ + pPerfObj=(PERF_OBJECT_TYPE*)((BYTE*)pPerfObj+pPerfObj->TotalByteLength); + } + if(!fFound) break; + + /* calc val from data, we need two samplings + * counter type: PERF_100NSEC_TIMER_INV + * calc: time base=100Ns, value=100*(1-(data_diff)/(100NsTime_diff)) */ + if(!fIsFirst) { + nCpuUsage=(BYTE)((1.0-(Li2Double(liCurrentCounterValue)-Li2Double(liPrevCounterValue))/(Li2Double(pPerfData->PerfTime100nSec)-Li2Double(liPrevPerfTime100nSec)))*100.0+0.5); + if(!CallBackAndWait(param,nCpuUsage)) break; + } + else fIsFirst=FALSE; + /* store current sampling for next */ + CopyMemory(&liPrevCounterValue,&liCurrentCounterValue,sizeof(LARGE_INTEGER)); + CopyMemory(&liPrevPerfTime100nSec,&pPerfData->PerfTime100nSec,sizeof(LARGE_INTEGER)); + } + + /* uninit */ + if(pPerfData) mir_free(pPerfData); + if(fSwitched) WinNT_PerfStatsSwitch(_T("PerfOS"),TRUE); + + /* return error for PollCpuUsage() if never succeeded */ + if(param->hFirstEvent!=NULL) SetEvent(param->hFirstEvent); + mir_free(param); +} + +/************************* Start Thread *******************************/ + +// returns poll thread id on success +DWORD PollCpuUsage(CPUUSAGEAVAILPROC pfnDataAvailProc,LPARAM lParam,DWORD dwDelayMillis) +{ + struct CpuUsageThreadParams *param; + DWORD idThread=0; + HANDLE hFirstEvent; + + /* init params */ + param=(struct CpuUsageThreadParams*)mir_alloc(sizeof(struct CpuUsageThreadParams)); + if(param==NULL) return FALSE; + param->dwDelayMillis=dwDelayMillis; + param->pfnDataAvailProc=pfnDataAvailProc; + param->lParam=lParam; + param->pidThread=&idThread; + param->hFirstEvent=hFirstEvent=CreateEvent(NULL,FALSE,FALSE,NULL); + if(hFirstEvent==NULL) { + mir_free(param); + return 0; + } + /* start thread */ +#if defined(_UNICODE) + if(mir_forkthread(WinNT_PollThread,param)!=-1) +#else + if(mir_forkthread(IsWinVerNT()?WinNT_PollThread:Win9x_PollThread,param)!=-1) +#endif + WaitForSingleObject(hFirstEvent,INFINITE); /* wait for first success */ + else mir_free(param); /* thread not started */ + CloseHandle(hFirstEvent); + return idThread; +} diff --git a/plugins/AutoShutdown/cpuusage.h b/plugins/AutoShutdown/cpuusage.h new file mode 100644 index 0000000000..681a2c8213 --- /dev/null +++ b/plugins/AutoShutdown/cpuusage.h @@ -0,0 +1,24 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* Start Thread */ +typedef BOOL (CALLBACK* CPUUSAGEAVAILPROC)(BYTE nCpuUsage,LPARAM lParam); +DWORD PollCpuUsage(CPUUSAGEAVAILPROC pfnDataAvailProc,LPARAM lParam,DWORD dwDelayMillis); diff --git a/plugins/AutoShutdown/docs/Info_Src.txt b/plugins/AutoShutdown/docs/Info_Src.txt new file mode 100644 index 0000000000..2b61a98f37 --- /dev/null +++ b/plugins/AutoShutdown/docs/Info_Src.txt @@ -0,0 +1,31 @@ + +AutoShutdown 1.4.0.1 for Miranda IM 0.7+ +------------------------------------------------------------------------ + Source Code + +Reminder: +'AutoShutdown' is released under the terms of the GNU General Public License. +See 'Shutdown-License.txt' for more details. +'AutoShutdown' is copyright 2004-2007 by H. Herkenrath. + +Please notify me of any changes that improve +'AutoShutdown' or add new features. +If you have any questions on the code, feel free +to contact me at my email address. + + H. Herkenrath (hrathh at users.sourceforge.net) + + +Notes +------------------------------------------------------------------------ +The following files need to be changed to bump the version number: + +Info_Src.txt (1 place) +version.h (4 places) +m_shutdown.h (1 place) +m_shutdown.inc (1 place) +docs\Shutdown-Readme.txt (3 places) +docs\Shutdown-Translation.txt (2 or 3 places) +docs\Shutdown-Developer.txt (1 place) + + diff --git a/plugins/AutoShutdown/docs/License_Appendix.txt b/plugins/AutoShutdown/docs/License_Appendix.txt new file mode 100644 index 0000000000..c590c3f5fb --- /dev/null +++ b/plugins/AutoShutdown/docs/License_Appendix.txt @@ -0,0 +1,64 @@ + +Excecpt of GNU General Public License (Appendix): + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/plugins/AutoShutdown/docs/Shutdown-Developer.txt b/plugins/AutoShutdown/docs/Shutdown-Developer.txt new file mode 100644 index 0000000000..9b15e2b09b --- /dev/null +++ b/plugins/AutoShutdown/docs/Shutdown-Developer.txt @@ -0,0 +1,49 @@ + +AutoShutdown 1.4.0.2 for Miranda IM 0.7+ +------------------------------------------------------------------------ + Developer Information + + Contents: ------------------------------- + | Translation, Services/Events, + | Debug Symbols, Coding Language, Rebase Info + +Translation +----------------- + The translation string listing can be found in + 'Shutdown-Translation.txt'. + +Services/Events +----------------- + For more information about which service functions are offered by + 'AutoShutdown' and about how they can be used by your plugin, + please refer to 'm_shutdown.h'. + If you would like to use Delphi/Pascal please refer to 'm_shutdown.inc'. + + Feel free to redirect any questions or extension ideas to me via e-mail: + hrathh at users.sourceforge.net + +Debug Symbols +----------------- + Debug symbols are also available for debugging purposes. + Copy the PDB-files in the SDK-zip into the same directory as the + corresponding DLL-files. + + To debug crashes the supplied MAP-file file might be helpful. + +Coding Language +----------------- + 'AutoShutdown' was written using Microsoft Visual C++ 6.0 SP6 + and the Microsoft Platform SDK shipped along with it. + +Rebase Info +----------------- + 'AutoShutdown' has set its base address to: + 0x11070000 + + Please avoid using this base address for your plugins because it will + slightly slow down startup of Miranda IM. + + With Microsoft Visual C++ the Base Address can be configured at: + 'Project' -> 'Settings' -> 'Linker' -> 'Output' -> 'Base Address' + +H. Herkenrath (hrathh at users.sourceforge.net) diff --git a/plugins/AutoShutdown/docs/Shutdown-License.txt b/plugins/AutoShutdown/docs/Shutdown-License.txt new file mode 100644 index 0000000000..a726a52df1 --- /dev/null +++ b/plugins/AutoShutdown/docs/Shutdown-License.txt @@ -0,0 +1,278 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. diff --git a/plugins/AutoShutdown/docs/Shutdown-Readme.txt b/plugins/AutoShutdown/docs/Shutdown-Readme.txt new file mode 100644 index 0000000000..59524f620f --- /dev/null +++ b/plugins/AutoShutdown/docs/Shutdown-Readme.txt @@ -0,0 +1,329 @@ + +AutoShutdown 1.4.0.2 +------------------------------------------------------------------------ + Plugin for Miranda IM 0.7 and + + + Plugin Info: ---------------------------- + | Version: 1.4.0.2 + | Filename: shutdown.dll + | Author: H. Herkenrath (hrathh at users.sourceforge.net) + | Description: Adds the possibility to shutdown Miranda IM + | or the computer after at a specified time. + + Contents: ------------------------------- + | Features, Requirements, Usage, Installation, + | Bugs and Wishes, To-Do List, Version History, + | Thanks, Translation, License and Copyright + +Features +---------------------- + + Shutdown Miranda IM or your computer after a specified time, + when receiving a special message or when all file transfers are completed + + Offers the following shutdown possibilities: + Logoff, Restart, Shutdown, Standby mode, Hibernate mode, Lock workstation, + Hang up dialup connections, Close Miranda IM, Set Miranda offine + + The available shutdown possibilities are only shown if they + are supported on your system + + The available shutdown events are only shown if you have + protocols or plugins installed that support the features + + Displays a confirmation dialog which is shown for 30 seconds + to cancel the process + + Plays a sound on confirmation dialog + + Displays the countdown in a special window below contact list + (this feature needs a MultiWindow enabled Contact List plugin) + + Plays a sound when the confirmation dialog is displayed + + No data gets lost on shutdown especially no unread messages + + Allows you to pause the shutdown countdown + + If Miranda is closed while automatic shutdown is running it will + show a dialog on next start of Miranda IM where it can be selected + to start automatic shutdown again + + Provides shutdown services for other plugins + + Full Unicode support + + Automatic installation of all files, just unzip into Plugins directory + + Supported plugins/tools: + MultiWindow Contact Lists (frames and hotkeys), Hotkey Plugins, + Magnetic Windows, Snapping Windows, TopToolBar, AutoReplacer, + Trigger Plugin (http://www.pboon.nl/projects.htm), HDD Info, + Weather Protocol + +Requirements +---------------------- + -> Miranda IM 0.7+: + Miranda IM is needed in version 0.7 or later. + + -> Optional: Weather Protocol 0.3.3.17+: + If you would like to use the thunderstorm shutdown feature, + you need to have Weather Protocol installed, version 0.3.3.17 or later. + + -> Optional: HDD Info 0.1.2.0+: + If you would like to use the harddrive overheat shutdown feature, + you need to have the HDD Info plugin installed, version 0.1.2.0 or later. + + -> Optional: Trigger Plugin 0.2.0.69+: + If you would like to use the Trigger feature, + you need to have the Trigger plugin installed, version 0.2.0.69 or later. + +Usage +---------------------- + AutoShutdown can be activated via the main menu: + 'Main Menu' -> 'Automatic Shutdown' + + The options to use 'Hibernate mode' and 'Lock workstation' + are only available if your system supports it. + All other options are only available if they are enabled on your system. + + Enabling 'Hibernate mode' on Windows ME/2000 and later: + 'Control Panel' -> 'Power Options' -> 'Hibernate' + To enable the Hibernate feature go to the Control Panel, + double-click Power Options, and then click the Hibernate tab. + Click to select the Enable Hibernate Support check box. + +Installation +---------------------- + Find 'miranda32.exe' on your computer. + + Just copy all the contents of the zip-file as they are into the 'Plugins' + subdirectory in the Miranda IM folder. + 'AutoShutdown' will detect the files and move them into the appropriate + directories on it's first run. + + You can also do all the installation by hand, if you want to: + + Main Plugin: Copy the file 'shutdown.dll' into the 'Plugins' subdirectory + in the Miranda IM folder. + + The Unicode version of the plugin will only work on Windows NT/2000/XP, + Windows Server 2000, Windows Vista or later with an installed + Unicode version of Miranda IM. + To use it on Windows 95/98/Me, please download the ANSI version of the plugin. + + Documentation: The txt-files should be moved along with the SDK-zip into the + 'Docs' directory in the Miranda IM folder. + + Sounds: The wav-files should be moved into the 'Sounds' + directory. They will get recognized automatically and be added to the sounds list. + + That's it! + +Bugs and Wishes +---------------------- + Feel free to mail me your wishes about 'AutoShutdown' and tell + me all the bugs you may find: hrathh at users.sourceforge.net + +To-Do List (random ideas) +---------------------- + ? Design some icons for the shutdown types (shutdown, reboot, etc.)...anyone? + ? Ddd possibility to shutdown on status change of specific users + ? Support Alarms Plugin API (m_alarms.h): + This would replace countdown frame, showing the shutdown countdown + on the Alarms frame instead (don't know if this is a good idea, not yet possible) + ? Show system tray icon when automatic shutdown is enabled (not needed, bad looking) + ? Add possibility to set Miranda to a specific status instead of offline + (really shutdown related?) + ? Start a specified application on event (really shutdown related?) + +Version History +---------------------- + 1.4.0.2 - minor fixes + 1.4.0.1 - ensure correct threshold values for cpuusage + - uses langpack locale for combobox sorting + - fixed: fontservice items were registered too early + - fixed: unicode problem with tray menu item + - fixed: settings dialog did not show up with parent + - added v0.8 support + - minor other improvements + 1.4.0.0 - Added possibility to shutdown when computer finishes + a busy task (high cpu usage) + - Support for AutoReplacer in message editbox + - Fixed minor issue with reactivating on miranda startup + - Really fixed shutdown on message in unicode build + - Updated new miranda headers, use of mir_forkthread + - Fixed automatic installation routine, now works again + - Bug-Fix: countdown hours (and higher) were converted wrongly + - Fixes for Win9x and WinNT4 + - Adjustments for hung apps + - Tweak: support for ENDSESSION_CLOSEAPP in Windows Vista + - Code reorganization + - Minor Vista and robustness tweaks + - Improved FontService and IcoLib support (core built-in) + 1.3.1.1 - Tweaks for blind users + - Minor speed-up for frame drawing when resized + - Cleanups + - workaround for frames not drawing when previously hidden + 1.3.1.0 - Added FontService support + - Added HDD Info overheat shutdown + - Updated Trigger plugin support (0.2) + - Updated TopToolBar support to latest version (0.7.3) + - Fixed 'lock workstation' on WinNT4 + - Marquee on progress + - Minor fixes and improvements + - Minor updates for new Miranda + 1.3.0.8 - Bug-Fix: Check for unicode core was wrong + - Some other minor changes + 1.3.0.7 - Improvements to OKTOEXIT handling + - Bug-Fix: Daylight saving time was ignored in time conversion + 1.3.0.6 - Reduced ANSI file size (corrected compiler settings) + - Minor internal tweaks + - Bug-Fix: Confirmation countdown in options was not displayed correctly + - Included debug symbols (PDB) into SDK package + - Adjusted db settings + 1.3.0.5 - Minor internal tweaks + - Fixed crash on start when Trigger plugin installed + 1.3.0.4 - Minor improvements and some internal changes to the countdown frame + - Finally fully fixed the dialup shutdown problem + - Added: Now also adds Close Miranda and Set Miranda offline as + actions for the trigger plugin (was requested) + 1.3.0.3 - Bug-Fix: Another try to fix the 'hangup dialup connections' freeze + 1.3.0.2 - Bug-Fix: 'hang up dialup connection' freezed Miranda sometimes + 1.3.0.1 - Fix: On some rare situations Miranda was not shutdown correctly + - Fix: Frame was not shown correctly on clist_modern + - Fixed mw_clist hotkey + - Some minor improvements + - Added shutdown event + - Fixed minor workstation locked issue + - Fixed 'sec' not shown correctly on frame (bug in WinAPI) + - Made 'hang up dialup connections' code more robust + - Bug-Fix: countdown values were not saved + - Fixed: shutdown dates in past were sometimes not recognized correctly + 1.3.0.0 - Make use of FORCEIFHUNG flag instead of FORCE whenever it is possible + - Shutdown at [hh:mm] and [yy-mm-dd] instead of Shutdown only at [hh:mm] + (also making use of calendar common control) + - New shutdown type: set status to offline + - Make use of ME_IDLE_CHANGED to shutdown on idle + - Added 'Thunder Shutdown' functionality + - Now making use of marquee mode of progressbar of time countdown is to + long to be displayed + - Added: Hotkey support for toggling automatic shutdown on/off + - Added: IcoLib support + - Updated: DBEditor++ support + - Added: Support for Trigger plugin (shutdown actions) + - Added: Unicode support + - Added: Functionality of Thunder Shutdown plugin (see option page) + - Removed: AgressiveOptimize.h to make it work on all systems + - Improved: New service functions + - Added: Shows countdown frame in normal window when frames are not available + - Added: Hotkey support for hotkey services (toggle) + - Improved: Now makes use of StrFromTimeInterval, BroadcastSystemMessage + - Improved: Made file transfer shutdown logic more robust + - Imroved dialogs look and feel + - Cleaned up and revisited code + 1.2.0.4 - Changed time control to use windows default control + - Fix: The icon on the countdown frame was sqeezed a bit + - Improved shutdown dialog layout + - Some small string improvements/changes (see Shutdown-Translation.txt') + - Some other minor code changes and improvements + 1.2.0.3 - 'Shutdown on file transfer' and 'Shutdown on message receival' + are now only enabled if plugins and protocols are installed that + support file transfer and/or instant messaging features + - Some other minor changes + 1.2.0.2 - Fix: Shutdown on message receival only worked when + message dialog was closed (Thanks to Hurricane and Foo) + - Fix: Sound option dialog sometimes crashed + when selecting a different countdown sound file (Thanks to Rex) + - Minor string improvements (see 'Shutdown-Translation.txt') + - Some small internal improvements + 1.2.0.1 - Fix: TopToolBar button showed wrong behaviour if + dialog was already opened + 1.2.0.0 - Add: New shutdown type 'Hang up dialup connections' + - Fix: Combo box did not remember last option correctly + - Some other small fixes/changes/improvents + 1.1.3.1 - Fix: Tabulator did not work correctly on settings dialog + - Fix: Some problems with the 'last exit remembering' + - Fix: 'Cancel' button was not default button on shutdown dialog + - Some other minor fixes/improvements + 1.1.3.0 - Improved: Sending of WM_ENDSESSION + - Add: If Miranda is closed and automatic shutdown is running + it will remember it and shows on next Miranda start a message box + where the user can select to start automatic shutdown again + - Add: When no option is selected it does no longer allow the + user to click on OK + - Fix: Time input control sometimes got hidden when editing hours + - Some other minor improvements/fixes + 1.1.2.0 - Fix: The shutdown on file transfer completion feature + did not always work correctly, especially with ICQ file transfers + - Fix: If the default sound file isn't installed it doesn't + anylonger give out the windows default sound by default + - Add: If Miranda is closed and automatic shutdown is running + it will remember it and start on next Miranda start again + 1.1.1.1 - Fix: Shutdown on specific time sometimes did not work correctly + and crashed Miranda on opening the 30s confirmation window + 1.1.1.0 - Fix: Default time was sometimes not detected correctly + - Improved: Shutdown/Restart is now faster due to improved + sending of WM_ENDSESSION + - Improved: When the countdown is paused it shows a blinking text + - Change: Context menu can now also be opened via left click + - Change: Shutdown on message receival now checks for + if the message contains the specified text instead of checking for + exactly the same content + - Change: 'Cancel Countdown' in context menu now only stops the countdown + instead of stopping all shutdown causes + - Change: When using shutdown at time feature the countdown display will + show the time instead of the countdown (Suggested by Rootgar) + - Change: The context menu now show a different text instead of being + checked when the countdown is paused + - Added/Changed some strings (see 'Shutdown-Translation.txt') + - Some other minor changes/improvements + 1.1.0.0 - Add: Possibility to shut down when all file transfers are finished + - Add: Possibility to shut down on message receival + - Add: WM_ENDSESSION now gets send to all applications manually on + shutdown/restart to prevent data loss + - Add: Now containing default sound file boundled with zip + - Add: Possibility to pause/unpause the countdown via right click on it + - Fix: Shutdown/Restart was not shown on Windows 2000/XP + - Fix: Updated link on plugin options page + - Fix: Countdown got updated one second after reactivating clist + - Change: Sound now gets played repeatedly on 30s shutdown dialog + - Change: Now 'Cancel' is the default button on 30s shutdown dialog + - Improved/Added some strings (please see 'Shutdown-Translation.txt') + - Some other minor improvements + 1.0.0.0 - Initial release + +Thanks +---------------------- + * To Corsario (Angelo Luiz Tartari) for the first idea of a shutdown plugin + * To Dennys for the first idea of rebooting via message ('dReboot' plugin) + * To noname for the thunderstorm shutdown feature + * To Marek 'tusz' Tusiewicz for the sound file and testing + * To Rootgar and Tigerix for their bug reports and suggestions + +Translation +---------------------- + Translation strings can be found in 'Shutdown-Translation.txt'. + +License and Copyright +---------------------- + 'AutoShutdown' is released under the terms of the GNU General Public License. + See 'Shutdown-License.txt' for more details. + + Copyright (c) 2004-2007 by H. Herkenrath. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. + 2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + 3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + 4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +H. Herkenrath (hrathh at users.sourceforge.net) diff --git a/plugins/AutoShutdown/docs/Shutdown-Translation.txt b/plugins/AutoShutdown/docs/Shutdown-Translation.txt new file mode 100644 index 0000000000..3ff9b29186 --- /dev/null +++ b/plugins/AutoShutdown/docs/Shutdown-Translation.txt @@ -0,0 +1,240 @@ + +AutoShutdown 1.4.0.2 for Miranda IM 0.7+ +------------------------------------------------------------------------ + Translator Information + + Contents: ------------------------------- + | General Info, String Listing + +General Info +----------------------------- + 'AutoShutdown' can be translated with the Miranda IM + language files. + + Place the following strings listed in the following section in a + file called 'langpack_.txt' in the Miranda IM directory. + Then you can translate them into your language. + + If you need more info about Miranda IM language files visit: + http://miranda.svn.sourceforge.net/viewvc/*checkout*/miranda/trunk/miranda/i18n/readme.txt + +String Listing +----------------------------- + +; --- Plugin: AutoShutdown 1.4.0.2 (German) --- + +; Translation by hrathh +; Please report any mistakes or missing strings in here. + +[AutoShutdown] +Automatisches Beenden +[Adds the possibility to shutdown the computer when a specified event occurs.] +Dieses Plugin ermцglicht es den Computer bei Eintreten festgelegter Ereignisse zu Beenden. +[AutoShutdown Plugin] +AutoShutdown-Plugin +[The AutoShutdown plugin can not be loaded. It requires Miranda IM %hs or later.] +Das AutoShutdown-Plugin kann nicht geladen werden. Es benцtigt Miranda IM %hs oder neuer. + +; Menu Item +[Automatic &shutdown...] +Automatisches &Beenden... +[Stop automatic &shutdown] +Automatisches &Beenden abbrechen +; TopToolBar Button +[Start/Stop automatic shutdown] +Automatisches Beenden de-/aktivieren +[Start automatic shutdown] +Automatisches Beenden aktivieren +[Stop automatic shutdown] +Automatisches Beenden deaktivieren + +; Sound +;[Alerts] +[Automatic Shutdown Countdown] +Countdown beim Automatischen Beenden +; Hotkey +[Toggle Automatic Shutdown] +Automatisches Beenden ein-/ausschalten + +; Icons +[Active] +Aktiviert +[Inactive] +Deaktiviert +[Header] +Illustration +; Fonts and Colors +[Countdown on Frame] +Countdown im Rahmen +[Background] +Hintergrund +[Progress Bar] +Fortschrittsbalken + +; Settings Dialog +[Automatic Shutdown] +Automatisches Beenden +[Select the automatic shutdown event] +Ein Ereignis zum automatischen Beenden wдhlen +[Shutdown at &specific time] +Beenden zur festgelegten &Zeit +[Shutdown a&t:] +Durchfьhren u&m: +[Shutdown i&n:] +Durchfьhren i&n: +[Second(s)] +Sekunden(n) +[Minute(s)] +Minute(n) +[Hour(s)] +Stunde(n) +[Day(s)] +Tage(n) +[Week(s)] +Woche(n) +[Month(s)] +Monat(en) +[Shutdown when a &message is received containing the following text:] +Beenden, wenn eine &Nachricht eingeht, die den folgenden Text enthдlt: +[Shutdown when all &file transfers are finished] +Beenden, wenn alle &Dateiьbertragungen abgeschlossen sind +[Shutdown when &prozessor usage drops below:] +Beenden, wenn die &Prozessorauslastung unter folgenden Wert fдllt: +[(current: %u%%)] +(aktuell: %u%%) +;[%] +[Shutdown when Miranda IM becomes &idle] +Beenden, wenn Miranda IM im &Idle-Modus ist +[Configure] +Konfigurieren +[Shutdown when all contacts are &offline] +Beenden, wenn alle Kontakte &offline sind +[&Action:] +&Vorgang: +[Close Miranda IM] +Miranda IM schlieЯen +[Sets all Miranda IM protocols to offline and closes Miranda IM.] +Setzt alle Netzwerkprotokolle auf "Offline" und beendet Miranda IM. +[Set Miranda IM offline] +Miranda IM offline schalten +[Sets all Miranda IM protocols to offline.] +Setzt alle Protokolle von Miranda IM auf Offline. +[Log off user] +Benutzer abmelden +[Logs the current Windows user off so that another user can log in.] +Meldet den aktuellen Benutzer von Windows ab, sodass sich ein anderer Benutzer anmelden kann. +[Restart computer] +Computer neu starten +[Shuts down Windows and then restarts Windows.] +Beendet die Windows-Sitzung und Windows und startet dann Windows erneut. +[Shutdown computer] +Computer herunterfahren +[Closes all running programs and shuts down Windows to a point at which it is safe to turn off the power.] +Beendet die Windows-Sitzung und fдhrt den Computer herunter. Der Computer wird ausgeschaltet. +[Standby mode] +Standby-Modus +[Saves the current Windows session in memory and sets the system to suspend mode.] +Behдlt die Windows-Sitzung bei, speichert die Daten im Arbeitsspeicher und schaltet den Computer in den Energiesparmodus. +[Hibernate mode] +Ruhezustand +[Saves the current Windows session on harddisc, so that the power can be turned off.] +Speichert die Windows-Sitzung auf der Festplatte, sodass der Computer ausgeschaltet werden kann. +[Lock workstation] +Arbeitsplatz verriegeln +[Locks the computer. To unlock the computer, you must log in.] +Verriegelt den Computer gegen Zugriff. Um den Computer wieder zu entriegeln mьssen Sie sich erneut anmelden. +[Hang up dialup connections] +DFЬ-Verbindungen trennen +[Sets all protocols to offline and closes all RAS connections.] +Setzt alle Netzwerkprotokolle auf "Offline" und trennt alle aktiven DFЬ-Netzwerkverbindungen. + +; Options +[Shutdown] +Beenden +[&Show confirmation dialog before shutdown] +&Bestдtigungsfenster vor dem Beenden anzeigen +[&Countdown starts at:] +&Countdown beginnt bei: +[seconds] +Sekunden +[Shutdown Events] +Ereignisse +[&Activate automatic shutdown with the same settings again if Miranda IM was closed with automatic shutdown enabled] +&Automatisches Beenden mit den gleichen Einstellungen erneut aktivieren, wenn Miranda IM beendet wurde wдhrend es aktiviert war +[&Ignore hidden or temporary contacts when watching for all contacts being offline] +&Versteckte und temporдre Kontakte beim Prьfen auf Offline Status ignorieren +[Critical Shutdown Events] +Kritische Ereignisse +[&Thunderstorm warning is issued (Weather)] +Gewitterwarnung wird ausgegeben (Wetter) +[&Harddrive overheats (HDD Info)] +&Festplatte ьberhitzt (HDD Info) + +; Trigger Plugin +[Shutdown: Close Miranda IM] +Herunterfahren: Miranda IM schlieЯen +[Shutdown: Set Miranda IM offline] +Herunterfahren: Miranda IM offline schalten +[Shutdown: Log off user] +Herunterfahren: Abmelden +[Shutdown: Restart computer] +Herunterfahren: Neustart +[Shutdown: Shutdown computer] +Herunterfahren: Computer ausschalten +[Shutdown: Standby mode] +Herunterfahren: Standby-Modus +[Shutdown: Hibernate mode] +Herunterfahren: Ruhezustand +[Shutdown: Lock workstation] +Herunterfahren: Arbeitsplatz verriegeln +[Shutdown: Hang up dialup connections] +Herunterfahren: DFЬ-verbindungen trennen + +; Shutdown Dialog +;[Automatic Shutdown] +[Miranda IM is going to be automatically closed in %i second(s).] +Miranda IM wird in %i Sekunde(n) automatisch geschlossen. +[You will be logged off automatically in %i second(s).] +Der Benutzer wird in %i Sekunde(n) automatisch abgemeldet. +[The computer will automatically be restarted in %i second(s).] +Der Computer wird in %i Sekunde(n) automatisch neu gestartet. +[The computer will automatically be set to standby mode in %i second(s).] +Der Computer wird in %i Sekunde(n) automatisch in den Stanby-Modus geschaltet. +[The computer will automatically be set to hibernate mode in %i second(s).] +Der Computer wird in %i Sekunde(n) automatisch in den Ruhezustand geschaltet. +[The workstation will automatically get locked in %i second(s).] +Der Arbeitsplatz wird in %i Sekunde(n) automatisch verriegelt. +[The computer will automatically be shut down in %i second(s).] +Der Computer wird in %i Sekunde(n) automatisch heruntergefahren. +[All dialup connections will be closed in %i second(s).] +Alle aktiven DFЬ-Netzwerkverbindungen werden in %i Sekunde(n) automatisch getrennt. +[Unsaved data in open applications except Miranda IM might get lost.] +Ungespeicherte Daten in geцffneten Anwendungen auЯer Miranda IM kцnnten verloren gehen. +[Please click "Cancel" if you would like to abort the process.] +Bitte auf "Abbrechen" klicken, wenn der Vorgang nicht durchgefьhrt werden soll. +[&Now!] +&Sofort! + +; Countdown Frame +[Time left:] +Verbleibend: +[Shutdown at:] +Beenden um: +[Paused] +Pause +[&Cancel Countdown] +Countdown &abbrechen +[&Pause Countdown] +Countdown &pausieren +[&Unpause Countdown] +Countdown &fortsetzen + +; Error +[Automatic Shutdown Error] +Fehler beim Automatischen Beenden +[The shutdown process failed!\nReason: %s] +Der Beendevorgang konnte nicht gestartet werden!\nGrund: %s + +; --- + +H. Herkenrath (hrathh at users.sourceforge.net) diff --git a/plugins/AutoShutdown/docs/countdown.wav b/plugins/AutoShutdown/docs/countdown.wav new file mode 100644 index 0000000000..45baa854bb Binary files /dev/null and b/plugins/AutoShutdown/docs/countdown.wav differ diff --git a/plugins/AutoShutdown/frame.c b/plugins/AutoShutdown/frame.c new file mode 100644 index 0000000000..f9266b1906 --- /dev/null +++ b/plugins/AutoShutdown/frame.c @@ -0,0 +1,644 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "common.h" + +/* Show Frame */ +extern HINSTANCE hInst; +static HWND hwndCountdownFrame; +static WORD hFrame; +/* Misc */ +static HANDLE hHookModulesLoaded; + +/************************* Helpers ************************************/ + +#define FRAMEELEMENT_BAR 1 +#define FRAMEELEMENT_BKGRND 2 +#define FRAMEELEMENT_TEXT 3 +static COLORREF GetDefaultColor(BYTE id) +{ + switch(id) { + case FRAMEELEMENT_BAR: + return RGB(250,0,0); /* same color as used on header icon */ + case FRAMEELEMENT_BKGRND: + return (COLORREF)DBGetContactSettingDword(NULL,"CLC","BkColour",CLCDEFAULT_BKCOLOUR); + case FRAMEELEMENT_TEXT: + return GetSysColor(COLOR_WINDOWTEXT); + } + return 0; /* never happens */ +} + +static LOGFONT* GetDefaultFont(LOGFONT *lf) +{ + NONCLIENTMETRICS ncm; + ZeroMemory(&ncm,sizeof(ncm)); + ncm.cbSize=sizeof(ncm); + if(SystemParametersInfo(SPI_GETNONCLIENTMETRICS,ncm.cbSize,&ncm,0)) { + *lf=ncm.lfStatusFont; + return lf; + } + return (LOGFONT*)NULL; +} + +static HICON SetFrameTitleIcon(WORD hFrame,HICON hNewIcon) +{ + HICON hPrevIcon; + hPrevIcon=(HICON)CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS,MAKEWPARAM(FO_ICON,hFrame),0); + CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,MAKEWPARAM(FO_ICON,hFrame),(LPARAM)hNewIcon); + if((int)hPrevIcon==-1) return (HICON)NULL; + return hPrevIcon; +} + +static LRESULT CALLBACK ProgressBarSubclassProc(HWND hwndProgress,UINT msg,WPARAM wParam,LPARAM lParam) +{ + switch(msg) { + case WM_ERASEBKGND: + return TRUE; + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + return SendMessage(GetParent(hwndProgress),msg,wParam,lParam); + } + return CallWindowProc((WNDPROC)GetWindowLong(hwndProgress,GWL_USERDATA),hwndProgress,msg,wParam,lParam); +} + +/************************* Window Class *******************************/ + +#define COUNTDOWNFRAME_CLASS _T("AutoShutdownCountdown") + +/* Data */ +struct CountdownFrameWndData { /* sizeof=57, max cbClsExtra=40 on Win32 */ + time_t countdown,settingLastTime; + HANDLE hHookColorsChanged,hHookFontsChanged,hHookIconsChanged; + HANDLE hwndIcon,hwndProgress,hwndDesc,hwndTime,hwndToolTip; + HBRUSH hbrBackground; + COLORREF clrBackground,clrText; + HFONT hFont; + WORD fTimeFlags; + BYTE flags; +}; + +/* Flags */ +#define FWPDF_PAUSED 0x01 +#define FWPDF_PAUSEDSHOWN 0x02 +#define FWPDF_COUNTDOWNINVALID 0x04 +#define FWPDF_TIMEISCLIPPED 0x08 + +/* Menu Items */ +#define MENUITEM_STOPCOUNTDOWN 1 +#define MENUITEM_PAUSECOUNTDOWN 2 + +/* Messages */ +#define M_REFRESH_COLORS (WM_USER+0) +#define M_REFRESH_ICONS (WM_USER+1) +#define M_REFRESH_FONTS (WM_USER+2) +#define M_SET_COUNTDOWN (WM_USER+3) +#define M_UPDATE_COUNTDOWN (WM_USER+4) +#define M_CHECK_CLIPPED (WM_USER+5) +#define M_CLOSE_COUNTDOWN (WM_USER+6) +#define M_PAUSE_COUNTDOWN (WM_USER+7) + +static LRESULT CALLBACK FrameWndProc(HWND hwndFrame,UINT msg,WPARAM wParam,LPARAM lParam) +{ + struct CountdownFrameWndData *dat=(struct CountdownFrameWndData*)GetWindowLong(hwndFrame,GWL_USERDATA); + + switch(msg) { + case WM_NCCREATE: /* init window data */ + dat=(struct CountdownFrameWndData*)mir_calloc(sizeof(*dat)); + SetWindowLong(hwndFrame,GWL_USERDATA,(LONG)dat); + if(dat==NULL) return FALSE; /* creation failed */ + dat->fTimeFlags=*(WORD*)((CREATESTRUCT*)lParam)->lpCreateParams; + dat->flags=FWPDF_COUNTDOWNINVALID; + break; + case WM_CREATE: /* create childs */ + { CREATESTRUCT *params=(CREATESTRUCT*)lParam; + dat->hwndIcon=CreateWindowEx(WS_EX_NOPARENTNOTIFY, + _T("Static"), + NULL, + WS_CHILD|WS_VISIBLE|SS_ICON|SS_CENTERIMAGE|SS_NOTIFY, + 3, 0, + GetSystemMetrics(SM_CXICON), + GetSystemMetrics(SM_CYICON), + hwndFrame, + NULL, + params->hInstance, + NULL); + dat->hwndProgress=CreateWindowEx(WS_EX_NOPARENTNOTIFY, + PROGRESS_CLASS, + (dat->fTimeFlags&SDWTF_ST_TIME)?TranslateT("Shutdown at:"):TranslateT("Time left:"), + WS_CHILD|WS_VISIBLE|PBS_SMOOTH, + GetSystemMetrics(SM_CXICON)+5, + 5, 90, + (GetSystemMetrics(SM_CXICON)/2)-5, + hwndFrame, + NULL, + params->hInstance, + NULL); + if(dat->hwndProgress==NULL) return -1; /* creation failed, calls WM_DESTROY */ + SendMessage(dat->hwndProgress,PBM_SETSTEP,(WPARAM)1,0); + SetWindowLong(dat->hwndProgress,GWL_USERDATA,SetWindowLong(dat->hwndProgress,GWL_WNDPROC,(LONG)ProgressBarSubclassProc)); + dat->hwndDesc=CreateWindowEx(WS_EX_NOPARENTNOTIFY, + _T("Static"), + (dat->fTimeFlags&SDWTF_ST_TIME)?TranslateT("Shutdown at:"):TranslateT("Time left:"), + WS_CHILD|WS_VISIBLE|SS_LEFTNOWORDWRAP|SS_NOTIFY, + GetSystemMetrics(SM_CXICON)+5, + (GetSystemMetrics(SM_CXICON)/2), + 75, + (GetSystemMetrics(SM_CXICON)/2), + hwndFrame, + NULL, + params->hInstance, + NULL); + dat->hwndTime=CreateWindowEx(WS_EX_NOPARENTNOTIFY, + _T("Static"), + NULL, /* hh:mm:ss */ + WS_CHILD|WS_VISIBLE|SS_RIGHT|SS_NOTIFY|SS_ENDELLIPSIS, + (GetSystemMetrics(SM_CXICON)+80), + (GetSystemMetrics(SM_CXICON)/2), + 35, + (GetSystemMetrics(SM_CXICON)/2), + hwndFrame, + NULL, + params->hInstance, + NULL); + if(dat->hwndTime==NULL) return -1; /* creation failed, calls WM_DESTROY */ + /* create tooltips */ + if(IsWinVer98Plus() || IsWinVer2000Plus()) { + TTTOOLINFO ti; + dat->hwndToolTip=CreateWindowEx(WS_EX_TOPMOST, + TOOLTIPS_CLASS, + NULL, + WS_POPUP|TTS_ALWAYSTIP|TTS_NOPREFIX, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + hwndFrame, + NULL, + params->hInstance, + NULL); + if(dat->hwndToolTip!=NULL) { + SetWindowPos(dat->hwndToolTip,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE); + ZeroMemory(&ti,sizeof(ti)); + ti.cbSize=sizeof(ti); + ti.hwnd=hwndFrame; + ti.uFlags=TTF_IDISHWND|TTF_SUBCLASS|TTF_TRANSPARENT; + ti.lpszText=LPSTR_TEXTCALLBACK; /* commctl 4.70+ */ + ti.uId=(UINT)dat->hwndTime; /* in-place tooltip */ + SendMessage(dat->hwndToolTip,TTM_ADDTOOL,0,(LPARAM)&ti); + ti.uFlags&=~TTF_TRANSPARENT; + ti.uId=(UINT)dat->hwndProgress; + SendMessage(dat->hwndToolTip,TTM_ADDTOOL,0,(LPARAM)&ti); + if(dat->hwndDesc!=NULL) { + ti.uId=(UINT)dat->hwndDesc; + SendMessage(dat->hwndToolTip,TTM_ADDTOOL,0,(LPARAM)&ti); + } + if(dat->hwndIcon!=NULL) { + ti.uId=(UINT)dat->hwndIcon; + SendMessage(dat->hwndToolTip,TTM_ADDTOOL,0,(LPARAM)&ti); + } + } + } + /* init layout */ + dat->hHookColorsChanged=HookEventMessage(ME_COLOUR_RELOAD,hwndFrame,M_REFRESH_COLORS); + dat->hHookFontsChanged=HookEventMessage(ME_FONT_RELOAD,hwndFrame,M_REFRESH_FONTS); + dat->hHookIconsChanged=HookEventMessage(ME_SKIN2_ICONSCHANGED,hwndFrame,M_REFRESH_ICONS); + SendMessage(hwndFrame,M_REFRESH_COLORS,0,0); + SendMessage(hwndFrame,M_REFRESH_FONTS,0,0); + SendMessage(hwndFrame,M_REFRESH_ICONS,0,0); + SendMessage(hwndFrame,M_SET_COUNTDOWN,0,0); + SendMessage(hwndFrame,M_UPDATE_COUNTDOWN,0,0); + if(!SetTimer(hwndFrame,1,1000,NULL)) return -1; /* creation failed, calls WM_DESTROY */ + return 0; + } + case WM_DESTROY: + { HICON hIcon; + if(dat==NULL) return 0; + UnhookEvent(dat->hHookColorsChanged); + UnhookEvent(dat->hHookFontsChanged); + UnhookEvent(dat->hHookIconsChanged); + /* other childs are destroyed automatically */ + if(dat->hwndToolTip!=NULL) DestroyWindow(dat->hwndToolTip); + hIcon=(HICON)SendMessage(dat->hwndIcon,STM_SETIMAGE,IMAGE_ICON,(LPARAM)NULL); + IcoLib_ReleaseIcon(hIcon); /* does NULL check */ + break; + } + case WM_NCDESTROY: + if(dat==NULL) return 0; + if(dat->hFont!=NULL) DeleteObject(dat->hFont); + if(dat->hbrBackground!=NULL) DeleteObject(dat->hbrBackground); + mir_free(dat); + SetWindowLong(hwndFrame,GWL_USERDATA,(LONG)NULL); + break; + case WM_SIZE: + { RECT rc; + LONG width,height; + HDWP hdwp; + UINT defflg=SWP_NOZORDER|SWP_NOOWNERZORDER|SWP_NOACTIVATE; + SetRect(&rc,0,0,LOWORD(lParam),HIWORD(lParam)); /* width,height */ + /* workaround: reduce flickering of frame in clist */ + InvalidateRect(hwndFrame,&rc,FALSE); + hdwp=BeginDeferWindowPos(3); + /* progress */ + width=rc.right-GetSystemMetrics(SM_CXICON)-10; + height=rc.bottom-(GetSystemMetrics(SM_CYICON)/2)-5; + hdwp=DeferWindowPos(hdwp,dat->hwndProgress,NULL,0,0,width,height,SWP_NOMOVE|defflg); + /* desc */ + if(dat->hwndDesc!=NULL) hdwp=DeferWindowPos(hdwp,dat->hwndDesc,NULL,GetSystemMetrics(SM_CXICON)+5,5+height,0,0,SWP_NOSIZE|defflg); + /* time */ + hdwp=DeferWindowPos(hdwp,dat->hwndTime,NULL,GetSystemMetrics(SM_CXICON)+85,5+height,width-80,(GetSystemMetrics(SM_CXICON)/2),defflg); + EndDeferWindowPos(hdwp); + PostMessage(hwndFrame,M_CHECK_CLIPPED,0,0); + return 0; + } + case M_REFRESH_COLORS: + { COLORREF clrBar; + if(FontService_GetColor(TranslateT("Automatic Shutdown"),TranslateT("Progress Bar"),&clrBar)) + clrBar=GetDefaultColor(FRAMEELEMENT_BAR); + if(FontService_GetColor(TranslateT("Automatic Shutdown"),TranslateT("Background"),&dat->clrBackground)) + dat->clrBackground=GetDefaultColor(FRAMEELEMENT_BKGRND); + if(dat->hbrBackground!=NULL) DeleteObject(dat->hbrBackground); + dat->hbrBackground=CreateSolidBrush(dat->clrBackground); + SendMessage(dat->hwndProgress,PBM_SETBARCOLOR,0,(LPARAM)clrBar); + SendMessage(dat->hwndProgress,PBM_SETBKCOLOR,0,(LPARAM)dat->clrBackground); + InvalidateRect(hwndFrame,NULL,TRUE); + return 0; + } + case M_REFRESH_ICONS: + if(dat->hwndIcon!=NULL) + IcoLib_ReleaseIcon((HICON)SendMessage(dat->hwndIcon,STM_SETIMAGE,IMAGE_ICON,(LPARAM)IcoLib_GetIcon("AutoShutdown_Header"))); + if(hFrame) /* refresh frame title icon */ + IcoLib_ReleaseIcon(SetFrameTitleIcon(hFrame,IcoLib_GetIcon("AutoShutdown_Active"))); + return 0; + case M_REFRESH_FONTS: + { LOGFONT lf; + if(!FontService_GetFont(TranslateT("Automatic Shutdown"),TranslateT("Countdown on Frame"),&dat->clrText,&lf)) { + if(dat->hFont!=NULL) DeleteObject(dat->hFont); + dat->hFont=CreateFontIndirect(&lf); + } + else { + dat->clrText=GetDefaultColor(FRAMEELEMENT_TEXT); + if(GetDefaultFont(&lf)!=NULL) { + if(dat->hFont!=NULL) DeleteObject(dat->hFont); + dat->hFont=CreateFontIndirect(&lf); + } + } + if(dat->hwndDesc!=NULL) + SendMessage(dat->hwndDesc,WM_SETFONT,(WPARAM)dat->hFont,FALSE); + SendMessage(dat->hwndTime,WM_SETFONT,(WPARAM)dat->hFont,FALSE); + InvalidateRect(hwndFrame,NULL,FALSE); + return 0; + } + case WM_SYSCOLORCHANGE: + SendMessage(hwndFrame,M_REFRESH_COLORS,0,0); + break; + case WM_SETTINGCHANGE: /* colors depend on windows settings */ + SendMessage(hwndFrame,M_REFRESH_COLORS,0,0); + SendMessage(hwndFrame,M_REFRESH_FONTS,0,0); + SendMessage(hwndFrame,M_UPDATE_COUNTDOWN,0,0); + RedrawWindow(hwndFrame,NULL,NULL,RDW_INVALIDATE|RDW_ALLCHILDREN|RDW_ERASE); + break; + case WM_TIMECHANGE: /* windows system clock changed */ + SendMessage(hwndFrame,M_SET_COUNTDOWN,0,0); + PostMessage(hwndFrame,M_UPDATE_COUNTDOWN,0,0); + break; + case WM_CTLCOLORDLG: + case WM_CTLCOLORSTATIC: + SetTextColor((HDC)wParam,dat->clrText); + SetBkColor((HDC)wParam,dat->clrBackground); + return (BOOL)dat->hbrBackground; + case WM_ERASEBKGND: + { RECT rc; + if(dat->hbrBackground!=NULL && GetClientRect(hwndFrame,&rc)) { + FillRect((HDC)wParam,&rc,dat->hbrBackground); + return TRUE; + } + return FALSE; + } + case M_SET_COUNTDOWN: + if(dat->fTimeFlags&SDWTF_ST_TIME) { + dat->settingLastTime=(time_t)DBGetContactSettingDword(NULL,"AutoShutdown","TimeStamp",SETTING_TIMESTAMP_DEFAULT); + dat->countdown=time(NULL); + if(dat->settingLastTime>dat->countdown) dat->countdown=dat->settingLastTime-dat->countdown; + else dat->countdown=0; + } + else if(dat->flags&FWPDF_COUNTDOWNINVALID) { + dat->countdown=(time_t)DBGetContactSettingDword(NULL,"AutoShutdown","Countdown",SETTING_COUNTDOWN_DEFAULT); + dat->countdown*=(time_t)DBGetContactSettingDword(NULL,"AutoShutdown","CountdownUnit",SETTING_COUNTDOWNUNIT_DEFAULT); + } + dat->flags&=~FWPDF_COUNTDOWNINVALID; + /* commctl 4.70+, Win95: 1-100 will work fine (wrap around) */ + SendMessage(dat->hwndProgress,PBM_SETRANGE32,(WPARAM)0,(LPARAM)dat->countdown); + return 0; + case WM_TIMER: + if(dat==NULL) return 0; + if(dat->countdown!=0 && !(dat->flags&FWPDF_COUNTDOWNINVALID) && !(dat->flags&FWPDF_PAUSED)) { + dat->countdown--; + PostMessage(dat->hwndProgress,PBM_STEPIT,0,0); + } + if(IsWindowVisible(hwndFrame)) PostMessage(hwndFrame,M_UPDATE_COUNTDOWN,0,0); + if(dat->countdown==0) { + SendMessage(hwndFrame,M_CLOSE_COUNTDOWN,0,0); + ServiceShutdown(0,TRUE); + ServiceStopWatcher(0,0); + } + return 0; + case WM_SHOWWINDOW: + /* the text is kept unchanged while hidden */ + if((BOOL)wParam) SendMessage(hwndFrame,M_UPDATE_COUNTDOWN,0,0); + break; + case M_UPDATE_COUNTDOWN: + if(dat->flags&FWPDF_PAUSED && !(dat->flags&FWPDF_PAUSEDSHOWN)) { + SetWindowText(dat->hwndTime,TranslateT("Paused")); + dat->flags|=FWPDF_PAUSEDSHOWN; + } + else { + TCHAR szOutput[256]; + if(dat->fTimeFlags&SDWTF_ST_TIME) + GetFormatedDateTime(szOutput,SIZEOF(szOutput),dat->settingLastTime,TRUE); + else GetFormatedCountdown(szOutput,SIZEOF(szOutput),dat->countdown); + SetWindowText(dat->hwndTime,szOutput); + PostMessage(hwndFrame,M_CHECK_CLIPPED,0,0); + /* update tooltip text (if shown) */ + if(dat->hwndToolTip!=NULL && !(dat->flags&FWPDF_PAUSED)) { + TTTOOLINFO ti; + ti.cbSize=sizeof(ti); + if(SendMessage(dat->hwndToolTip,TTM_GETCURRENTTOOL,0,(LPARAM)&ti) && (HWND)ti.uId!=dat->hwndIcon) + SendMessage(dat->hwndToolTip,TTM_UPDATE,0,0); + } else dat->flags&=~FWPDF_PAUSEDSHOWN; + } + return 0; + case M_CLOSE_COUNTDOWN: + KillTimer(hwndFrame,1); + dat->countdown=0; + dat->flags&=~FWPDF_PAUSED; + SendMessage(hwndFrame,M_UPDATE_COUNTDOWN,0,0); + dat->flags|=FWPDF_COUNTDOWNINVALID; + /* step up to upper range */ + SendMessage(dat->hwndProgress,PBM_SETPOS,SendMessage(dat->hwndProgress,PBM_GETRANGE,FALSE,0),0); + SetWindowLong(dat->hwndProgress,GWL_STYLE,GetWindowLong(dat->hwndProgress,GWL_STYLE)|PBM_SETMARQUEE); + SendMessage(dat->hwndProgress,PBM_SETMARQUEE,TRUE,10); /* marquee for rest of time */ + return 0; + case M_PAUSE_COUNTDOWN: + if(dat->flags&FWPDF_PAUSED) { + /* unpause */ + dat->flags&=~(FWPDF_PAUSED|FWPDF_PAUSEDSHOWN); + SendMessage(hwndFrame,M_SET_COUNTDOWN,0,0); + SendMessage(dat->hwndProgress,PBM_SETSTATE,PBST_NORMAL,0); /* WinVista+ */ + } + else { + /* pause */ + dat->flags|=FWPDF_PAUSED; + SendMessage(dat->hwndProgress,PBM_SETSTATE,PBST_PAUSED,0); /* WinVista+ */ + } + SendMessage(hwndFrame,M_UPDATE_COUNTDOWN,0,0); + return 0; + case WM_CONTEXTMENU: + { HMENU hContextMenu; + POINT pt; + if(dat->flags&FWPDF_COUNTDOWNINVALID) return 0; + POINTSTOPOINT(pt,MAKEPOINTS(lParam)); + if(pt.x==-1 && pt.y==-1) { /* invoked by keyboard */ + RECT rc; + /* position in middle above rect */ + if(!GetWindowRect(hwndFrame, &rc)) return 0; + pt.x=rc.left+((int)(rc.right-rc.left)/2); + pt.y=rc.top+((int)(rc.bottom-rc.top)/2); + } + hContextMenu=CreatePopupMenu(); + if(hContextMenu!=NULL) { + AppendMenu(hContextMenu,MF_STRING,MENUITEM_PAUSECOUNTDOWN,(dat->flags&FWPDF_PAUSED)?TranslateT("&Unpause Countdown"):TranslateT("&Pause Countdown")); + SetMenuDefaultItem(hContextMenu,MENUITEM_PAUSECOUNTDOWN,FALSE); + AppendMenu(hContextMenu,MF_STRING,MENUITEM_STOPCOUNTDOWN,TranslateT("&Cancel Countdown")); + TrackPopupMenuEx(hContextMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_HORPOSANIMATION|TPM_VERPOSANIMATION|TPM_RIGHTBUTTON,pt.x,pt.y,hwndFrame,NULL); + DestroyMenu(hContextMenu); + } + return 0; + } + case WM_LBUTTONDBLCLK: + if(!(dat->flags&FWPDF_COUNTDOWNINVALID)) + SendMessage(hwndFrame,M_PAUSE_COUNTDOWN,0,0); + return 0; + case WM_COMMAND: + switch(LOWORD(wParam)) { + case MENUITEM_STOPCOUNTDOWN: + /* close only countdown window when other watcher types running */ + if(dat->fTimeFlags&~(SDWTF_SPECIFICTIME|SDWTF_ST_MASK)) + CloseCountdownFrame(); /* something else is running */ + else ServiceStopWatcher(0,0); /* calls CloseCountdownFrame() */ + return 0; + case MENUITEM_PAUSECOUNTDOWN: + SendMessage(hwndFrame,M_PAUSE_COUNTDOWN,0,0); + return 0; + } + break; + case M_CHECK_CLIPPED: /* for in-place tooltip on dat->hwndTime */ + { RECT rc; + HDC hdc; + SIZE size; + HFONT hFontPrev=NULL; + TCHAR szOutput[256]; + dat->flags&=~FWPDF_TIMEISCLIPPED; + if(GetWindowText(dat->hwndTime,szOutput,SIZEOF(szOutput)-1)) + if(GetClientRect(dat->hwndTime,&rc)) { + hdc=GetDC(dat->hwndTime); + if(hdc!=NULL) { + if(dat->hFont!=NULL) + hFontPrev=SelectObject(hdc,dat->hFont); + if(GetTextExtentPoint32(hdc,szOutput,lstrlen(szOutput),&size)) + if(size.cx>=(rc.right-rc.left)) + dat->flags&=FWPDF_TIMEISCLIPPED; + if(dat->hFont!=NULL) + SelectObject(hdc,hFontPrev); + ReleaseDC(dat->hwndTime,hdc); + } + } + return 0; + } + case WM_NOTIFY: + if(((NMHDR*)lParam)->hwndFrom==dat->hwndToolTip) + switch(((NMHDR*)lParam)->code) { + case TTN_SHOW: /* 'in-place' tooltip on dat->hwndTime */ + if(dat->flags&FWPDF_TIMEISCLIPPED && (HWND)wParam==dat->hwndTime && IsWinVer2000Plus()) { + RECT rc; + if(GetWindowRect(dat->hwndTime,&rc)) { + SetWindowLong(dat->hwndToolTip,GWL_STYLE,GetWindowLong(dat->hwndToolTip,GWL_STYLE)|TTS_NOANIMATE); + SetWindowLong(dat->hwndToolTip,GWL_EXSTYLE,GetWindowLong(dat->hwndToolTip,GWL_EXSTYLE)|WS_EX_TRANSPARENT); + SendMessage(dat->hwndToolTip,TTM_ADJUSTRECT,TRUE,(LPARAM)&rc); + SetWindowPos(dat->hwndToolTip,NULL,rc.left,rc.top,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); + return TRUE; /* self-defined position */ + } + } + SetWindowLong(dat->hwndToolTip,GWL_STYLE,GetWindowLong(dat->hwndToolTip,GWL_STYLE)&(~TTS_NOANIMATE)); + SetWindowLong(dat->hwndToolTip,GWL_EXSTYLE,GetWindowLong(dat->hwndToolTip,GWL_EXSTYLE)&(~WS_EX_TRANSPARENT)); + return 0; + case TTN_POP: + /* workaround #5: frame does not get redrawn after + * in-place tooltip hidden on dat->hwndTime */ + RedrawWindow(hwndCountdownFrame,NULL,NULL,RDW_INVALIDATE|RDW_ALLCHILDREN|RDW_ERASE); + return 0; + case TTN_NEEDTEXT: + { NMTTDISPINFO *ttdi=(NMTTDISPINFO*)lParam; + if(dat->flags&FWPDF_TIMEISCLIPPED && (HWND)wParam==dat->hwndTime) { + if(GetWindowText(dat->hwndTime,ttdi->szText,SIZEOF(ttdi->szText)-1)) + ttdi->lpszText=ttdi->szText; + } + else if((HWND)wParam==dat->hwndIcon) + ttdi->lpszText=TranslateT("Automatic Shutdown"); + else { + TCHAR szTime[SIZEOF(ttdi->szText)]; + if(dat->fTimeFlags&SDWTF_ST_TIME) + GetFormatedDateTime(szTime,SIZEOF(szTime),dat->settingLastTime,FALSE); + else GetFormatedCountdown(szTime,SIZEOF(szTime),dat->countdown); + mir_sntprintf(ttdi->szText,SIZEOF(ttdi->szText),_T("%s %s"),(dat->fTimeFlags&SDWTF_ST_TIME)?TranslateT("Shutdown at:"):TranslateT("Time left:"),szTime); + ttdi->lpszText=ttdi->szText; + } + return 0; + } + } + break; + } + return DefWindowProc(hwndFrame,msg,wParam,lParam); +} + +/************************* Show Frame *********************************/ + +void ShowCountdownFrame(WORD fTimeFlags) +{ + hwndCountdownFrame=CreateWindowEx(WS_EX_CONTROLPARENT|WS_EX_NOPARENTNOTIFY|WS_EX_TRANSPARENT, + COUNTDOWNFRAME_CLASS, + NULL, + WS_CHILD|WS_TABSTOP, + 0, 0, + GetSystemMetrics(SM_CXICON)+103, + GetSystemMetrics(SM_CYICON)+2, + (HWND)CallService(MS_CLUI_GETHWND,0,0), + NULL, + hInst, + &fTimeFlags); + if(hwndCountdownFrame==NULL) return; + + if(ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) { + CLISTFrame clf; + ZeroMemory(&clf,sizeof(clf)); + clf.cbSize=sizeof(clf); + clf.hIcon=IcoLib_GetIcon("AutoShutdown_Active"); /* CListFrames does not make a copy */ + clf.align=alBottom; + clf.height=GetSystemMetrics(SM_CYICON); + clf.Flags=F_VISIBLE|F_SHOWTBTIP|F_NOBORDER|F_SKINNED; + clf.name=Translate("AutoShutdown"); + clf.TBname=Translate("Automatic Shutdown"); + clf.hWnd=hwndCountdownFrame; + hFrame=(WORD)CallService(MS_CLIST_FRAMES_ADDFRAME,(WPARAM)&clf,0); + if(hFrame) { + ShowWindow(hwndCountdownFrame,SW_SHOW); + CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,MAKEWPARAM(FO_TBTIPNAME,hFrame),(LPARAM)clf.name); + /* HACKS TO FIX CLUI FRAMES: + * *** why is CLUIFrames is horribly buggy??! *** date: sept 2005, nothing changed until sept 2006 + * workaround #1: MS_CLIST_FRAMES_REMOVEFRAME does not finish with destroy cycle (clist_modern, clist_nicer crashes) */ + SendMessage((HWND)CallService(MS_CLUI_GETHWND,0,0),WM_SIZE,0,0); + /* workaround #2: drawing glitch after adding a frame (frame positioned wrongly when hidden) */ + CallService(MS_CLIST_FRAMES_UPDATEFRAME,hFrame,FU_FMPOS|FU_FMREDRAW); + /* workaround #3: MS_CLIST_FRAMES_SETFRAMEOPTIONS does cause redrawing problems */ + if(!(CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS,MAKEWPARAM(FO_FLAGS,hFrame),0)&F_VISIBLE)) + CallService(MS_CLIST_FRAMES_SHFRAME,hFrame,0); + /* workaround #4: MS_CLIST_FRAMES_SHFRAME does cause redrawing problems when frame was hidden */ + RedrawWindow(hwndCountdownFrame,NULL,NULL,RDW_INVALIDATE|RDW_ALLCHILDREN|RDW_ERASE); + /* workaround #5: for in-place tooltip TTN_POP + * workaround #6 and #7: see CloseCountdownFrame() */ + } + } +} + +void CloseCountdownFrame(void) +{ + if(hwndCountdownFrame!=NULL) { + SendMessage(hwndCountdownFrame,M_CLOSE_COUNTDOWN,0,0); + if(hFrame) { + IcoLib_ReleaseIcon(SetFrameTitleIcon(hFrame,NULL)); + /* HACKS TO FIX CLUIFrames: + * workaround #6: MS_CLIST_FRAMES_REMOVEFRAME does not finish with + * destroy cycle (clist_modern, clist_nicer crashes) */ + CallService(MS_CLIST_FRAMES_SETFRAMEOPTIONS,MAKEWPARAM(FO_FLAGS,hFrame),(LPARAM)CallService(MS_CLIST_FRAMES_GETFRAMEOPTIONS,MAKEWPARAM(FO_FLAGS,hFrame),0)&(~F_VISIBLE)); + #if !defined(_DEBUG) + /* workaround #7: MS_CLIST_FRAMES_REMOVEFRAME crashes after two calls + * clist_nicer crashes after some calls (bug in it) */ + CallService(MS_CLIST_FRAMES_REMOVEFRAME,hFrame,0); + #endif + } + else DestroyWindow(hwndCountdownFrame); + hwndCountdownFrame=NULL; + hFrame=0; + } + +} + +/************************* Misc ***************************************/ + +static int FrameModulesLoaded(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + if(ServiceExists(MS_CLIST_FRAMES_ADDFRAME)) { + LOGFONT lf; + COLORREF clr; + HMODULE hUxThemeDLL; + BOOL (WINAPI *pfnIsThemeActive)(VOID); + /* built-in font module is not available before this hook */ + clr=GetDefaultColor(FRAMEELEMENT_TEXT); + FontService_RegisterFont("AutoShutdown","CountdownFont",TranslateT("Automatic Shutdown"),TranslateT("Countdown on Frame"),0,FALSE,GetDefaultFont(&lf),clr); + clr=GetDefaultColor(FRAMEELEMENT_BKGRND); + FontService_RegisterColor("AutoShutdown","BkgColor",TranslateT("Automatic Shutdown"),TranslateT("Background"),clr); + /* progressbar color can only be changed in windows classic theme */ + /* FIXME: should be registered/unregistered on WM_THEMECHANGED/ME_OPT_INITIALISE msg, + * currently not possible as no such font service exists */ + hUxThemeDLL=LoadLibraryA("UXTHEME"); /* all ascii */ + *(PROC*)&pfnIsThemeActive=(hUxThemeDLL!=NULL)?GetProcAddress(hUxThemeDLL,"IsThemeActive"):NULL; + if(pfnIsThemeActive==NULL || !pfnIsThemeActive()) { + /* progressbar color can only be changed with classic theme */ + clr=GetDefaultColor(FRAMEELEMENT_BAR); + FontService_RegisterColor("AutoShutdown","ProgressColor",TranslateT("Automatic Shutdown"),TranslateT("Progress Bar"),clr); + } + if(hUxThemeDLL!=NULL) FreeLibrary(hUxThemeDLL); + } + return 0; +} + +int InitFrame(void) +{ + WNDCLASSEX wcx; + ZeroMemory(&wcx,sizeof(wcx)); + wcx.cbSize =sizeof(wcx); + wcx.style =CS_DBLCLKS|CS_PARENTDC; + wcx.lpfnWndProc =FrameWndProc; + wcx.hInstance =hInst; + wcx.hCursor =(HCURSOR)LoadImage(NULL,IDC_ARROW,IMAGE_CURSOR,0,0,LR_SHARED); + wcx.lpszClassName =COUNTDOWNFRAME_CLASS; + if(!RegisterClassEx(&wcx)) return 1; + + hwndCountdownFrame=NULL; + hHookModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,FrameModulesLoaded); + return 0; +} + +void UninitFrame(void) +{ + /* frame closed by UninitWatcher() */ + UnregisterClass(COUNTDOWNFRAME_CLASS,hInst); /* fails if window still exists */ + UnhookEvent(hHookModulesLoaded); +} diff --git a/plugins/AutoShutdown/frame.h b/plugins/AutoShutdown/frame.h new file mode 100644 index 0000000000..1b0bffdafd --- /dev/null +++ b/plugins/AutoShutdown/frame.h @@ -0,0 +1,28 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* Show Frame */ +void ShowCountdownFrame(WORD fTimeFlags); +void CloseCountdownFrame(void); + +/* Misc */ +int InitFrame(void); +void UninitFrame(void); \ No newline at end of file diff --git a/plugins/AutoShutdown/m_shutdown.h b/plugins/AutoShutdown/m_shutdown.h new file mode 100644 index 0000000000..87e25e8851 --- /dev/null +++ b/plugins/AutoShutdown/m_shutdown.h @@ -0,0 +1,196 @@ +/* + +'AutoShutdown'-Plugin for +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright (C) 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef M_SHUTDOWN_H__ +#define M_SHUTDOWN_H__ + +#if defined (_MSC_VER) && (_MSC_VER >= 1020) + #pragma once +#endif + +/* + AutoShutdown v1.4.0.2 +*/ + +/* interface id */ +#if !defined(MIID_SHUTDOWN) + #define MIID_SHUTDOWN {0x142982a8,0x88cf,0x4c65,{0x87,0x21,0x6d,0xe2,0x7d,0x5c,0xe7,0xb5}} +#endif + +/******************************************************************/ +/************************* SERVICES *******************************/ +/******************************************************************/ + +/* Show settings dialog v1.3.0.0+ +Shows the dialog by which the shutdown watcher can be started. +If the dialog is already opened this brings it to foreground. + wParam=lParam=0 +Returns 0 on success, nonzero otherwise. +*/ +#define MS_AUTOSHUTDOWN_SHOWSETTINGSDIALOG "AutoShutdown/ShowSettingsDialog" + +/* Initiate shutdown process v1.3.0.0+ +Initiates the shutdown process for a given shutdown type. +If another shutdown process is already pending it will return error. +Associated events: ME_AUTOSHUTDOWN_OKTOSHUTDOWN, ME_AUTOSHUTDOWN_SHUTDOWN + wParam=shutdownType + lParam=(LPARAM)(BOOL)fShowConfirmDlg (whether to show the warning dialog or not) +Returns 0 on success, nonzero otherwise. +*/ +#define MS_AUTOSHUTDOWN_SHUTDOWN "AutoShutdown/Shutdown" + +/* shutdown types */ +#define SDSDT_CLOSEMIRANDA 1 // close miranda process +#define SDSDT_SETMIRANDAOFFLINE 2 // set all protocols to offline +#define SDSDT_LOGOFF 3 // logoff from Windows +#define SDSDT_REBOOT 4 // reboot computer +#define SDSDT_SHUTDOWN 5 // shutdown Windows and power off +#define SDSDT_STANDBY 6 // standby mode +#define SDSDT_HIBERNATE 7 // hibernate mode +#define SDSDT_LOCKWORKSTATION 8 // lock the workstation +#define SDSDT_CLOSERASCONNECTIONS 9 // close all dialup connections +#define SDSDT_MAX 9 + +/* Get shutdown type description v1.4.0.0+ +Gets a textual description of the given shutdown type. + wParam=shutdownType + lParam=flags (see GSTDF_* below) +Returns a static buffer of the description of the given shutdown type. +It does not need to be freed in any way. +The returned text is already translated. +Returns a pointer to a string on success, NULL on error. +*/ +#define MS_AUTOSHUTDOWN_GETTYPEDESCRIPTION "AutoShutdown/GetTypeDescription" + +#define GSTDF_LONGDESC 0x0001 // returns a long description +#define GSTDF_UNICODE 0x0002 // returns a Unicode string +#define GSTDF_UNTRANSLATED 0x0004 // returns an untranslated string +#if defined(_UNICODE) + #define GSTDF_TCHAR GSTDF_UNICODE // will return WCHAR* +#else + #define GSTDF_TCHAR 0 // will return char*, as usual +#endif + +/* Check if shutdown type is enabled v1.4.0.0+ +Tests if a specific shutdown type is activated and its use is possible +on the system. For example hibernate and stand-by modes are not available on +older versions of Windows (needs Windows ME/2000+). +Shutdown might also be prohibited by security restrictions. +This services checks it all. +However, there is no need to call this before calling MS_AUTOSHUTDOWN_SHUTDOWN. +MS_AUTOSHUTDOWN_SHUTDOWN will fail if the given shutdown type is not enabled. + wParam=shutdownType + lParam=0 +Returns TRUE if the given shutdown type is enabled, FALSE otherwise. +*/ +#define MS_AUTOSHUTDOWN_ISTYPEENABLED "AutoShutdown/IsTypeEnabled" + +/* Start shutdown watcher v1.4.0.0+ +Starts the watcher using the last settings specified on the dialog +shown by MS_AUTOSHUTDOWN_SHOWSETTINGSDIALOG. +Call MS_AUTOSHUTDOWN_SHOWSETTINGSDIALOG instead to offer +options about what watcher to use. +Associated event: ME_AUTOSHUTDOWN_WATCHERCHANGED + wParam=lParam=0 +Returns 0 on success, nonzero otherwise. +*/ +#define MS_AUTOSHUTDOWN_STARTWATCHER "AutoShutdown/StartWatcher" + +/* Stop shutdown watcher v1.4.0.0+ +Stops the currently running watcher. +If the watcher is not running, it returns error. +Associated event: ME_AUTOSHUTDOWN_WATCHERCHANGED + wParam=lParam=0 +Returns 0 on success, nonzero otherwise. +*/ +#define MS_AUTOSHUTDOWN_STOPWATCHER "AutoShutdown/StopWatcher" + +/* Check if watcher is running v1.4.0.0+ +Checks if the watcher is currently active or not. + wParam=lParam=0 +Returns TRUE if the watcher is enabled, FALSE otherwise. +*/ +#define MS_AUTOSHUTDOWN_ISWATCHERENABLED "AutoShutdown/IsWatcherEnabled" + +/******************************************************************/ +/************************** EVENTS ********************************/ +/******************************************************************/ + +/* Disallow shutdown process (event) v1.3.0.0+ +Gets fired when MS_AUTOSHUTDOWN_SHUTDOWN is called. +Parmeters are the same as specified at the call to MS_AUTOSHUTDOWN_SHUTDOWN. + wParam=shutdownType + lParam=(LPARAM)(BOOL)fShowConfirmDlg +Return 0 to allow shutdown, 1 to disallow. +*/ +#define ME_AUTOSHUTDOWN_OKTOSHUTDOWN "AutoShutdown/OkToShutdown" + +/* Shutdown process started (event) v1.3.0.1+ +Gets fired when ME_AUTOSHUTDOWN_OKTOSHUTDOWN was confirmed. +Parmeters are the same as specified at the call +to MS_AUTOSHUTDOWN_SHUTDOWN. + wParam=shutdownType + lParam=(LPARAM)(BOOL)fShowConfirmDlg +Unused, return always 0 here. +*/ +#define ME_AUTOSHUTDOWN_SHUTDOWN "AutoShutdown/ShutdownEvent" + +/* Watcher changed (event) v1.3.0.0+ +Fired when MS_AUTOSHUTDOWN_STARTWATCHER or MS_AUTOSHUTDOWN_STOPWATCHER +is called. + wParam=(WPARAM)(BOOL)fIsStarted (whether whe watcher is running now) + lParam=0 +Unused, return always 0 here. +*/ +#define ME_AUTOSHUTDOWN_WATCHERCHANGED "AutoShutdown/Watcher/Changed" + + +#ifndef SHUTDOWN_NOSETTINGS +#define SETTING_REMEMBERONRESTART_DEFAULT 0 // SDROR_RUNNING +#define SETTING_SHOWCONFIRMDLG_DEFAULT 1 +#define SETTING_CONFIRMDLGCOUNTDOWN_DEFAULT 30 // seconds +#define SETTING_WEATHERSHUTDOWN_DEFAULT 0 +#define SETTING_HDDOVERHEATSHUTDOWN_DEFAULT 1 +#define SETTING_SMARTOFFLINECHECK_DEFAULT 1 + +#define SETTING_SHUTDOWNTYPE_DEFAULT SDSDT_SHUTDOWN +#define SETTING_WATCHERFLAGS_DEFAULT (SDWTF_SPECIFICTIME|SDWTF_ST_COUNTDOWN) +#define SETTING_COUNTDOWN_DEFAULT 30 +#define SETTING_COUNTDOWNUNIT_DEFAULT 60 // x times countdown seconds +#define SETTING_TIMESTAMP_DEFAULT (DWORD)(time(NULL)+(SETTING_COUNTDOWN_DEFAULT*SETTING_COUNTDOWNUNIT_DEFAULT)) +#define SETTING_CPUUSAGETHRESHOLD_DEFAULT 90 // percent + +#define SDWTF_SPECIFICTIME 0x0001 +#define SDWTF_ST_TIME 0x0002 +#define SDWTF_ST_COUNTDOWN 0x0004 +#define SDWTF_ST_MASK 0x0006 /* bitmask for SDWTF_ST_* bits */ +#define SDWTF_MESSAGE 0x0008 +#define SDWTF_FILETRANSFER 0x0010 +#define SDWTF_IDLE 0x0020 +#define SDWTF_STATUS 0x0040 +#define SDWTF_CPUUSAGE 0x0080 +#define SDWTF_MASK 0x00FF /* bitmask for all SDWTF_* bits */ + +#define SDROR_RUNNING 3 +#endif + +#endif // M_SHUTDOWN_H diff --git a/plugins/AutoShutdown/main.c b/plugins/AutoShutdown/main.c new file mode 100644 index 0000000000..d4f9a63480 --- /dev/null +++ b/plugins/AutoShutdown/main.c @@ -0,0 +1,192 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "common.h" +#include "version.h" + +HINSTANCE hInst; +PLUGINLINK *pluginLink; +struct MM_INTERFACE mmi; +static HANDLE hHookModulesLoaded; +HANDLE hActiveIcon,hInactiveIcon; + +PLUGININFOEX pluginInfo={ + sizeof(PLUGININFOEX), + "AutoShutdown", + PLUGIN_VERSION, +#if defined(_DEBUG) + "Development build not intended for release. ("__DATE__")", +#else + "Adds the possibility to shutdown the computer when a specified event occurs.", /* autotranslated */ +#endif + "H. Herkenrath", + PLUGIN_EMAIL, /* @ will be set later */ + "© 2004-2007 H. Herkenrath", + PLUGIN_WEBSITE, + UNICODE_AWARE, + 0, +#if defined(_UNICODE) + // {9DE24579-5C5C-49aa-80E8-4D38E4344E63} + {0x9de24579,0x5c5c,0x49aa,{0x80,0xe8,0x4d,0x38,0xe4,0x34,0x4e,0x63}}, +#else + // {7C0DD208-94D8-4283-879A-E6F86135B826} + {0x7c0dd208,0x94d8,0x4283,{0x87,0x9a,0xe6,0xf8,0x61,0x35,0xb8,0x26}} +#endif +}; +static const MUUID interfaces[]={MIID_SHUTDOWN,MIID_LAST}; + +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,void *pReserved) +{ + UNREFERENCED_PARAMETER(pReserved); + if(fdwReason==DLL_PROCESS_ATTACH) + /* Do not call this function from a DLL that is linked to the static C run-time library (CRT). + * The static CRT requires DLL_THREAD_ATTACH and DLL_THREAD_DETATCH notifications to function properly. */ + DisableThreadLibraryCalls(hInst=hinstDLL); + return TRUE; +} + +static void InstallFile(const TCHAR *pszFileName,const TCHAR *pszDestSubDir) +{ + TCHAR szFileFrom[MAX_PATH+1],szFileTo[MAX_PATH+1],*p; + HANDLE hFile; + + if(!GetModuleFileName(hInst,szFileFrom,SIZEOF(szFileFrom)-lstrlen(pszFileName))) + return; + p=_tcsrchr(szFileFrom,_T('\\')); + if(p!=NULL) *(++p)=0; + lstrcat(szFileFrom,pszFileName); /* buffer safe */ + + hFile=CreateFile(szFileFrom,0,FILE_SHARE_READ,0,OPEN_EXISTING,0,0); + if(hFile==INVALID_HANDLE_VALUE) return; + CloseHandle(hFile); + + if(!GetModuleFileName(NULL,szFileTo,SIZEOF(szFileTo)-lstrlen(pszDestSubDir)-lstrlen(pszFileName))) + return; + p=_tcsrchr(szFileTo,_T('\\')); + if(p!=NULL) *(++p)=0; + lstrcat(szFileTo,pszDestSubDir); /* buffer safe */ + CreateDirectory(szFileTo,NULL); + lstrcat(szFileTo,pszFileName); /* buffer safe */ + + if(!MoveFile(szFileFrom,szFileTo) && GetLastError()==ERROR_ALREADY_EXISTS) { + DeleteFile(szFileTo); + MoveFile(szFileFrom,szFileTo); + } +} + +static int ShutdownModulesLoaded(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + if(ServiceExists("DBEditorpp/RegisterSingleModule")) + CallService("DBEditorpp/RegisterSingleModule",(WPARAM)"AutoShutdown",0); + /* merged thundershutdown plugin */ + if(GetModuleHandleA("tshutdown.dll")) { + DBWriteContactSettingByte(NULL,"PluginDisable","tshutdown.dll",1); + DBWriteContactSettingByte(NULL,"AutoShutdown","WeatherShutdown",1); + } + return 0; +} + +#ifdef __cplusplus +extern "C" { +#endif + +__declspec(dllexport) const PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) +{ + if(mirandaVersioncode) { + case PSN_APPLY: + DBWriteContactSettingByte(NULL,"AutoShutdown","ShowConfirmDlg",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_SHOWCONFIRMDLG)!=0)); + DBWriteContactSettingWord(NULL,"AutoShutdown","ConfirmDlgCountdown",(WORD)GetDlgItemInt(hwndDlg,IDC_EDIT_CONFIRMDLGCOUNTDOWN,NULL,FALSE)); + DBWriteContactSettingByte(NULL,"AutoShutdown","RememberOnRestart",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_REMEMBERONRESTART)!=0)); + DBWriteContactSettingByte(NULL,"AutoShutdown","SmartOfflineCheck",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_SMARTOFFLINECHECK)!=0)); + if(IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHECK_WEATHER))) + DBWriteContactSettingByte(NULL,"AutoShutdown","WeatherShutdown",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_WEATHER)!=0)); + if(IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHECK_HDDOVERHEAT))) + DBWriteContactSettingByte(NULL,"AutoShutdown","HddOverheatShutdown",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_HDDOVERHEAT)!=0)); + return TRUE; + } + break; + } + return FALSE; +} + +static int ShutdownOptInit(WPARAM wParam,LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp; + UNREFERENCED_PARAMETER(lParam); + ZeroMemory(&odp,sizeof(odp)); + odp.cbSize=sizeof(odp); + odp.hInstance=hInst; + odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPT_SHUTDOWN); + odp.position=900000002; + odp.ptszGroup=_T("Events"); /* autotranslated */ + odp.ptszTitle=_T("Automatic Shutdown"); /* autotranslated */ + odp.ptszTab=_T("Automatic Shutdown"); /* autotranslated, can be made a tab */ + odp.flags=ODPF_BOLDGROUPS|ODPF_EXPERTONLY|ODPF_TCHAR; + odp.pfnDlgProc=ShutdownOptDlgProc; + CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); + return 0; +} + +/************************* Trigger ************************************/ + +static int __stdcall ActionProc(DWORD idAction,REPORTINFO *ri,int shutdownType) +{ + UNREFERENCED_PARAMETER(ri); + if(idAction&ACT_PERFORM) ServiceShutdown(shutdownType,TRUE); + return 0; +} +#define ActionProcJmp(shutdownType) { return ActionProc(id,ri,shutdownType); } + +static int CloseActionProc(DWORD id,REPORTINFO *ri) ActionProcJmp(SDSDT_CLOSEMIRANDA) +static int SetOfflineActionProc(DWORD id,REPORTINFO *ri) ActionProcJmp(SDSDT_SETMIRANDAOFFLINE) +static int LogoffActionProc(DWORD id,REPORTINFO *ri) ActionProcJmp(SDSDT_LOGOFF) +static int RebootActionProc(DWORD id,REPORTINFO *ri) ActionProcJmp(SDSDT_REBOOT) +static int ShutdownActionProc(DWORD id,REPORTINFO *ri) ActionProcJmp(SDSDT_SHUTDOWN) +static int StandbyActionProc(DWORD id,REPORTINFO *ri) ActionProcJmp(SDSDT_STANDBY) +static int HibernateActionProc(DWORD id,REPORTINFO *ri) ActionProcJmp(SDSDT_HIBERNATE) +static int LockActionProc(DWORD id,REPORTINFO *ri) ActionProcJmp(SDSDT_LOCKWORKSTATION) +static int HangupActionProc(DWORD id,REPORTINFO *ri) ActionProcJmp(SDSDT_CLOSERASCONNECTIONS) + +static int TriggerRegisterActions(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + /* new trigger API (0.2.0.69+) */ + if(ServiceExists(MS_TRIGGER_REGISTERCONDITION)) { + ACTIONREGISTER ar; + BYTE shutdownType; + char *pszDesc,szName[138]; + ACTIONFUNCTION actionFunctions[SDSDT_MAX]={CloseActionProc,SetOfflineActionProc,LogoffActionProc, + RebootActionProc,ShutdownActionProc,StandbyActionProc, + HibernateActionProc,LockActionProc,HangupActionProc}; + ZeroMemory(&ar,sizeof(ar)); + ar.cbSize=sizeof(ar); + ar.flags=ARF_TCHAR|ARF_FUNCTION; + ar.pszName=szName; + for(shutdownType=1;shutdownType<=SDSDT_MAX;++shutdownType) + if(ServiceIsTypeEnabled(shutdownType,0)) { + pszDesc=(char*)ServiceGetTypeDescription(shutdownType,GSTDF_UNTRANSLATED); + if(pszDesc!=NULL) { + mir_snprintf(szName,sizeof(szName),"Shutdown: %s",pszDesc); /* autotranslated */ + ar.actionFunction=actionFunctions[shutdownType-1]; + CallService(MS_TRIGGER_REGISTERACTION,0,(LPARAM)&ar); + } + } + } + return 0; +} + +/************************* Misc ***************************************/ + +void InitOptions(void) +{ + /* Option Page */ + hHookOptInit=HookEvent(ME_OPT_INITIALISE,ShutdownOptInit); + /* Trigger */ + hHookModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,TriggerRegisterActions); +} + +void UninitOptions(void) +{ + /* Option Page */ + UnhookEvent(hHookOptInit); + /* Trigger */ + UnhookEvent(hHookModulesLoaded); +} diff --git a/plugins/AutoShutdown/options.h b/plugins/AutoShutdown/options.h new file mode 100644 index 0000000000..8b8e63f04f --- /dev/null +++ b/plugins/AutoShutdown/options.h @@ -0,0 +1,24 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* Misc */ +void InitOptions(void); +void UninitOptions(void); diff --git a/plugins/AutoShutdown/res/Thumbs.db b/plugins/AutoShutdown/res/Thumbs.db new file mode 100644 index 0000000000..28fd3e08f0 Binary files /dev/null and b/plugins/AutoShutdown/res/Thumbs.db differ diff --git a/plugins/AutoShutdown/res/active.ico b/plugins/AutoShutdown/res/active.ico new file mode 100644 index 0000000000..83d1be2388 Binary files /dev/null and b/plugins/AutoShutdown/res/active.ico differ diff --git a/plugins/AutoShutdown/res/header.ico b/plugins/AutoShutdown/res/header.ico new file mode 100644 index 0000000000..4a31e98104 Binary files /dev/null and b/plugins/AutoShutdown/res/header.ico differ diff --git a/plugins/AutoShutdown/res/inactive.ico b/plugins/AutoShutdown/res/inactive.ico new file mode 100644 index 0000000000..6c69a4d40a Binary files /dev/null and b/plugins/AutoShutdown/res/inactive.ico differ diff --git a/plugins/AutoShutdown/resource.h b/plugins/AutoShutdown/resource.h new file mode 100644 index 0000000000..4d8370f00a --- /dev/null +++ b/plugins/AutoShutdown/resource.h @@ -0,0 +1,58 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resource.rc +// +#define IDI_ACTIVE 101 +#define IDI_INACTIVE 102 +#define IDI_HEADER 103 +#define IDD_SETTINGS 104 +#define IDD_SHUTDOWNNOW 105 +#define IDD_OPT_SHUTDOWN 106 +#define IDC_ICON_HEADER 1001 +#define IDC_TEXT_HEADER 1002 +#define IDC_TEXT_HEADERDESC 1003 +#define IDC_RECT_HEADER 1004 +#define IDC_RADIO_STTIME 1005 +#define IDC_RADIO_STCOUNTDOWN 1006 +#define IDC_CHECK_SPECIFICTIME 1007 +#define IDC_TIME_TIMESTAMP 1008 +#define IDC_DATE_TIMESTAMP 1009 +#define IDC_EDIT_COUNTDOWN 1010 +#define IDC_SPIN_COUNTDOWN 1011 +#define IDC_COMBO_COUNTDOWNUNIT 1012 +#define IDC_COMBO_SHUTDOWNTYPE 1013 +#define IDC_TEXT_SHUTDOWNTYPE 1014 +#define IDC_TEXT_SECONDS 1015 +#define IDC_CHECK_FILETRANSFER 1016 +#define IDC_CHECK_IDLE 1017 +#define IDC_URL_IDLE 1018 +#define IDC_CHECK_MESSAGE 1019 +#define IDC_EDIT_MESSAGE 1020 +#define IDC_CHECK_STATUS 1021 +#define IDC_CHECK_CPUUSAGE 1022 +#define IDC_TEXT_CURRENTCPU 1023 +#define IDC_EDIT_CPUUSAGE 1024 +#define IDC_SPIN_CPUUSAGE 1025 +#define IDC_TEXT_PERCENT 1026 +#define IDC_BUTTON_SHUTDOWNNOW 1027 +#define IDC_TEXT_UNSAVEDWARNING 1028 +#define IDC_CHECK_SHOWCONFIRMDLG 1029 +#define IDC_TEXT_COUNTDOWNSTARTS 1030 +#define IDC_EDIT_CONFIRMDLGCOUNTDOWN 1031 +#define IDC_SPIN_CONFIRMDLGCOUNTDOWN 1032 +#define IDC_CHECK_REMEMBERONRESTART 1033 +#define IDC_CHECK_SMARTOFFLINECHECK 1034 +#define IDC_CHECK_WEATHER 1035 +#define IDC_CHECK_HDDOVERHEAT 1036 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 107 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1037 +#define _APS_NEXT_SYMED_VALUE 2001 +#endif +#endif diff --git a/plugins/AutoShutdown/resource.rc b/plugins/AutoShutdown/resource.rc new file mode 100644 index 0000000000..a9bac86713 --- /dev/null +++ b/plugins/AutoShutdown/resource.rc @@ -0,0 +1,253 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include +#include + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Englisch (GB) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE MOVEABLE PURE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE MOVEABLE PURE +BEGIN + "#include \r\n" + "#include \r\n" + "\0" +END + +3 TEXTINCLUDE MOVEABLE PURE +BEGIN + "#include ""version.rc""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPT_SHUTDOWN DIALOGEX 0, 0, 201, 190 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "Shutdown",IDC_STATIC,3,1,196,45 + CONTROL "&Show confirmation dialog before shutdown", + IDC_CHECK_SHOWCONFIRMDLG,"Button",BS_AUTOCHECKBOX | + WS_GROUP | WS_TABSTOP,12,14,182,10 + LTEXT "&Countdown starts at:",IDC_TEXT_COUNTDOWNSTARTS,24,29, + 79,8 + EDITTEXT IDC_EDIT_CONFIRMDLGCOUNTDOWN,109,27,32,12,ES_AUTOHSCROLL | + ES_NUMBER + CONTROL "",IDC_SPIN_CONFIRMDLGCOUNTDOWN,"msctls_updown32", + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK | + WS_TABSTOP,137,27,9,11 + LTEXT "seconds",IDC_TEXT_SECONDS,146,29,48,8,NOT WS_GROUP + GROUPBOX "Shutdown Events",IDC_STATIC,3,51,196,66,WS_GROUP + CONTROL "&Activate automatic shutdown with the same settings again if Miranda IM was closed with automatic shutdown enabled", + IDC_CHECK_REMEMBERONRESTART,"Button",BS_AUTOCHECKBOX | + BS_TOP | BS_MULTILINE | WS_TABSTOP,12,64,182,27 + CONTROL "&Ignore hidden or temporary contacts when watching for all contacts being offline", + IDC_CHECK_SMARTOFFLINECHECK,"Button",BS_AUTOCHECKBOX | + BS_TOP | BS_MULTILINE | WS_TABSTOP,12,93,182,20 + GROUPBOX "Critical Shutdown Events",IDC_STATIC,3,123,196,66 + LTEXT "Automatically shutdown the computer and turn the power off when one of the following occurs:", + IDC_STATIC,12,135,182,18,SS_NOPREFIX + CONTROL "&Thunderstorm warning is issued (Weather)", + IDC_CHECK_WEATHER,"Button",BS_AUTOCHECKBOX | BS_TOP | + WS_DISABLED | WS_TABSTOP,12,157,182,11 + CONTROL "&Harddrive overheats (HDD Info)",IDC_CHECK_HDDOVERHEAT, + "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,12, + 172,182,10 +END + +IDD_SETTINGS DIALOGEX 0, 0, 239, 286 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | + WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Automatic Shutdown" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "",IDC_RECT_HEADER,0,0,243,25,NOT WS_GROUP + ICON "",IDC_ICON_HEADER,7,3,20,20,SS_CENTERIMAGE | WS_GROUP, + WS_EX_TRANSPARENT + LTEXT "Automatic Shutdown",IDC_TEXT_HEADER,34,4,201,8, + SS_NOPREFIX,WS_EX_TRANSPARENT + LTEXT "Select the automatic shutdown event", + IDC_TEXT_HEADERDESC,43,12,192,8,SS_NOPREFIX, + WS_EX_TRANSPARENT + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,25,243,1 + CONTROL "Shutdown at &specific time",IDC_CHECK_SPECIFICTIME, + "Button",BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,13,35, + 212,10 + CONTROL "Shutdown a&t:",IDC_RADIO_STTIME,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,25,49,68,8 + CONTROL "",IDC_TIME_TIMESTAMP,"SysDateTimePick32",DTS_UPDOWN | + WS_TABSTOP | 0x8,95,47,62,13 + CONTROL "",IDC_DATE_TIMESTAMP,"SysDateTimePick32",WS_TABSTOP,159, + 47,66,13 + CONTROL "Shutdown i&n:",IDC_RADIO_STCOUNTDOWN,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,25,64,68,8 + EDITTEXT IDC_EDIT_COUNTDOWN,95,62,62,13,ES_AUTOHSCROLL | + ES_NUMBER + CONTROL "",IDC_SPIN_COUNTDOWN,"msctls_updown32",UDS_WRAP | + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,146,62,12, + 14 + COMBOBOX IDC_COMBO_COUNTDOWNUNIT,159,62,66,114,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + CONTROL "Shutdown when a &message is received containing the following text:", + IDC_CHECK_MESSAGE,"Button",BS_AUTOCHECKBOX | BS_TOP | + BS_MULTILINE | WS_GROUP | WS_TABSTOP,13,78,211,18 + EDITTEXT IDC_EDIT_MESSAGE,25,96,199,21,ES_MULTILINE | + ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL + CONTROL "Shutdown when Miranda IM becomes &idle",IDC_CHECK_IDLE, + "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | + WS_GROUP | WS_TABSTOP,13,123,164,9 + CONTROL "Configure",IDC_URL_IDLE,"Hyperlink",WS_TABSTOP,179,124, + 46,9 + CONTROL "Shutdown when &prozessor usage drops below:", + IDC_CHECK_CPUUSAGE,"Button",BS_AUTOCHECKBOX | BS_TOP | + BS_MULTILINE | WS_GROUP | WS_TABSTOP,13,139,159,22 + EDITTEXT IDC_EDIT_CPUUSAGE,179,140,32,13,ES_AUTOHSCROLL | + ES_NUMBER + CONTROL "",IDC_SPIN_CPUUSAGE,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | + UDS_NOTHOUSANDS | UDS_HOTTRACK,205,140,11,14 + LTEXT "%",IDC_TEXT_PERCENT,215,140,15,13,SS_NOPREFIX | + SS_CENTERIMAGE | NOT WS_GROUP + LTEXT "(current: 0%)",IDC_TEXT_CURRENTCPU,179,154,60,8, + SS_NOPREFIX | NOT WS_GROUP + CONTROL "Shutdown when all contacts are &offline", + IDC_CHECK_STATUS,"Button",BS_AUTOCHECKBOX | BS_TOP | + WS_GROUP | WS_TABSTOP,13,162,211,9 + CONTROL "Shutdown when all &file transfers are finished", + IDC_CHECK_FILETRANSFER,"Button",BS_AUTOCHECKBOX | BS_TOP | + WS_GROUP | WS_TABSTOP,13,177,211,10 + LTEXT "&Action:",IDC_STATIC,15,199,209,8 + COMBOBOX IDC_COMBO_SHUTDOWNTYPE,14,209,210,103,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "",IDC_TEXT_SHUTDOWNTYPE,15,225,208,25,NOT WS_GROUP + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,258,245,1 + DEFPUSHBUTTON "OK",IDOK,123,266,50,14,WS_GROUP + PUSHBUTTON "Cancel",IDCANCEL,179,266,50,14 +END + +IDD_SHUTDOWNNOW DIALOGEX 0, 0, 204, 98 +STYLE DS_MODALFRAME | DS_NOIDLEMSG | DS_SETFOREGROUND | DS_FIXEDSYS | + DS_NOFAILCREATE | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +EXSTYLE WS_EX_TOPMOST +CAPTION "Automatic Shutdown" +FONT 8, "MS Shell Dlg" +BEGIN + ICON "",IDC_ICON_HEADER,6,7,20,20,SS_CENTERIMAGE | WS_GROUP, + WS_EX_TRANSPARENT + LTEXT "",IDC_TEXT_HEADER,34,8,162,18,SS_NOPREFIX | NOT + WS_GROUP + LTEXT "Unsaved data in open applications except Miranda IM might get lost.", + IDC_TEXT_UNSAVEDWARNING,33,31,161,17,SS_NOPREFIX | NOT + WS_VISIBLE + LTEXT "Please click ""Cancel"" if you would like to abort the process.", + IDC_STATIC,33,49,161,17,SS_NOPREFIX + PUSHBUTTON "&Now!",IDC_BUTTON_SHUTDOWNNOW,32,75,67,14,WS_GROUP + DEFPUSHBUTTON "Cancel",IDCANCEL,103,75,68,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_OPT_SHUTDOWN, DIALOG + BEGIN + VERTGUIDE, 3 + VERTGUIDE, 12 + VERTGUIDE, 194 + VERTGUIDE, 199 + HORZGUIDE, 27 + HORZGUIDE, 39 + END + + IDD_SETTINGS, DIALOG + BEGIN + VERTGUIDE, 13 + VERTGUIDE, 25 + VERTGUIDE, 95 + VERTGUIDE, 159 + VERTGUIDE, 179 + VERTGUIDE, 224 + HORZGUIDE, 266 + HORZGUIDE, 280 + END + + IDD_SHUTDOWNNOW, DIALOG + BEGIN + VERTGUIDE, 34 + VERTGUIDE, 196 + HORZGUIDE, 8 + HORZGUIDE, 31 + HORZGUIDE, 75 + HORZGUIDE, 89 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ACTIVE ICON DISCARDABLE "res/active.ico" +IDI_HEADER ICON DISCARDABLE "res/header.ico" +IDI_INACTIVE ICON DISCARDABLE "res/inactive.ico" +#endif // Englisch (GB) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "version.rc" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/AutoShutdown/settingsdlg.c b/plugins/AutoShutdown/settingsdlg.c new file mode 100644 index 0000000000..03f514d61b --- /dev/null +++ b/plugins/AutoShutdown/settingsdlg.c @@ -0,0 +1,512 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "common.h" + +/* Menu Item */ +static HANDLE hServiceMenuCommand; +/* Toolbar Button */ +static HANDLE hHookToolbarLoaded; +/* Services */ +static HANDLE hServiceShowDlg; +static HWND hwndSettingsDlg; +extern HINSTANCE hInst; + +/************************* Dialog *************************************/ + +static void EnableDlgItem(HWND hwndDlg,int idCtrl,BOOL fEnable) +{ + hwndDlg=GetDlgItem(hwndDlg,idCtrl); + if(hwndDlg!=NULL && IsWindowEnabled(hwndDlg)!=fEnable) + EnableWindow(hwndDlg,fEnable); +} + +static BOOL CALLBACK DisplayCpuUsageProc(BYTE nCpuUsage,LPARAM lParam) +{ + TCHAR str[64]; + /* dialog closed? */ + if(!IsWindow((HWND)lParam)) return FALSE; /* stop poll thread */ + mir_sntprintf(str,SIZEOF(str),TranslateT("(current: %u%%)"),nCpuUsage); + SetWindowText((HWND)lParam,str); + return TRUE; +} + +static BOOL AnyProtoHasCaps(DWORD caps1) +{ + int nProtoCount,i; + PROTOCOLDESCRIPTOR **protos; + if(!CallService(MS_PROTO_ENUMPROTOCOLS,(WPARAM)&nProtoCount,(LPARAM)&protos)) + for(i=0;itype==PROTOTYPE_PROTOCOL) + if(CallProtoService(protos[i]->szName,PS_GETCAPS,(WPARAM)PFLAGNUM_1,0)&caps1) + return TRUE; /* CALLSERVICE_NOTFOUND also handled gracefully */ + return FALSE; +} + +#define M_ENABLE_SUBCTLS (WM_APP+111) +#define M_UPDATE_SHUTDOWNDESC (WM_APP+112) +#define M_CHECK_DATETIME (WM_APP+113) +static BOOL CALLBACK SettingsDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) +{ + switch(msg) { + case WM_INITDIALOG: + { LCID locale; + hwndSettingsDlg=hwndDlg; + TranslateDialogDefault(hwndDlg); + locale=CallService(MS_LANGPACK_GETLOCALE,0,0); + SendDlgItemMessage(hwndDlg,IDC_ICON_HEADER,STM_SETIMAGE,IMAGE_ICON,(LPARAM)IcoLib_GetIcon("AutoShutdown_Header")); + { HFONT hBoldFont; + LOGFONT lf; + if(GetObject((HFONT)SendDlgItemMessage(hwndDlg,IDC_TEXT_HEADER,WM_GETFONT,0,0),sizeof(lf),&lf)) { + lf.lfWeight=FW_BOLD; + hBoldFont=CreateFontIndirect(&lf); + } else hBoldFont=NULL; + SendDlgItemMessage(hwndDlg,IDC_TEXT_HEADER,WM_SETFONT,(WPARAM)hBoldFont,FALSE); + } + /* read-in watcher flags */ + { WORD watcherType; + watcherType=DBGetContactSettingWord(NULL,"AutoShutdown","WatcherFlags",SETTING_WATCHERFLAGS_DEFAULT); + CheckRadioButton(hwndDlg,IDC_RADIO_STTIME,IDC_RADIO_STCOUNTDOWN,(watcherType&SDWTF_ST_TIME)?IDC_RADIO_STTIME:IDC_RADIO_STCOUNTDOWN); + CheckDlgButton(hwndDlg,IDC_CHECK_SPECIFICTIME,(watcherType&SDWTF_SPECIFICTIME)!=0); + CheckDlgButton(hwndDlg,IDC_CHECK_MESSAGE,(watcherType&SDWTF_MESSAGE)!=0); + CheckDlgButton(hwndDlg,IDC_CHECK_FILETRANSFER,(watcherType&SDWTF_FILETRANSFER)!=0); + CheckDlgButton(hwndDlg,IDC_CHECK_IDLE,(watcherType&SDWTF_IDLE)!=0); + CheckDlgButton(hwndDlg,IDC_CHECK_STATUS,(watcherType&SDWTF_STATUS)!=0); + CheckDlgButton(hwndDlg,IDC_CHECK_CPUUSAGE,(watcherType&SDWTF_CPUUSAGE)!=0); + } + /* read-in countdown val */ + { SYSTEMTIME st; + if(!TimeStampToSystemTime((time_t)DBGetContactSettingDword(NULL,"AutoShutdown","TimeStamp",SETTING_TIMESTAMP_DEFAULT),&st)) + GetLocalTime(&st); + DateTime_SetSystemtime(GetDlgItem(hwndDlg,IDC_TIME_TIMESTAMP),GDT_VALID,&st); + DateTime_SetSystemtime(GetDlgItem(hwndDlg,IDC_DATE_TIMESTAMP),GDT_VALID,&st); + SendMessage(hwndDlg,M_CHECK_DATETIME,0,0); + } + { DWORD setting; + setting=DBGetContactSettingDword(NULL,"AutoShutdown","Countdown",SETTING_COUNTDOWN_DEFAULT); + if(setting<1) setting=SETTING_COUNTDOWN_DEFAULT; + SendDlgItemMessage(hwndDlg,IDC_SPIN_COUNTDOWN,UDM_SETRANGE,0,MAKELPARAM(UD_MAXVAL,1)); + SendDlgItemMessage(hwndDlg,IDC_EDIT_COUNTDOWN,EM_SETLIMITTEXT,(WPARAM)10,0); + SendDlgItemMessage(hwndDlg,IDC_SPIN_COUNTDOWN,UDM_SETPOS,0,MAKELPARAM(setting,0)); + SetDlgItemInt(hwndDlg,IDC_EDIT_COUNTDOWN,setting,FALSE); + } + { HWND hwndCombo; + DWORD lastUnit; + int i,index; + const DWORD unitValues[]={1,60,60*60,60*60*24,60*60*24*7,60*60*24*31}; + const TCHAR *unitNames[]={_T("Second(s)"),_T("Minute(s)"),_T("Hour(s)"), + _T("Day(s)"),_T("Week(s)"),_T("Month(s)")}; + hwndCombo=GetDlgItem(hwndDlg,IDC_COMBO_COUNTDOWNUNIT); + lastUnit=DBGetContactSettingDword(NULL,"AutoShutdown","CountdownUnit",SETTING_COUNTDOWNUNIT_DEFAULT); + SendMessage(hwndCombo,CB_SETLOCALE,(WPARAM)locale,0); /* sort order */ + SendMessage(hwndCombo,CB_INITSTORAGE,SIZEOF(unitNames),SIZEOF(unitNames)*16); /* approx. */ + for(i=0;iidFrom) { + case IDC_TIME_TIMESTAMP: + case IDC_DATE_TIMESTAMP: + switch(((NMHDR*)lParam)->code) { + case DTN_CLOSEUP: + case NM_KILLFOCUS: + PostMessage(hwndDlg,M_CHECK_DATETIME,0,0); + return TRUE; + } + } + break; + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_CHECK_MESSAGE: + case IDC_CHECK_FILETRANSFER: + case IDC_CHECK_IDLE: + case IDC_CHECK_CPUUSAGE: + case IDC_CHECK_STATUS: + case IDC_CHECK_SPECIFICTIME: + case IDC_RADIO_STTIME: + case IDC_RADIO_STCOUNTDOWN: + SendMessage(hwndDlg,M_ENABLE_SUBCTLS,0,0); + return TRUE; + case IDC_EDIT_COUNTDOWN: + if(HIWORD(wParam)==EN_KILLFOCUS) { + if((int)GetDlgItemInt(hwndDlg,IDC_EDIT_COUNTDOWN,NULL,TRUE)<1) { + SendDlgItemMessage(hwndDlg,IDC_SPIN_COUNTDOWN,UDM_SETPOS,0,MAKELPARAM(1,0)); + SetDlgItemInt(hwndDlg,IDC_EDIT_COUNTDOWN,1,FALSE); + } + return TRUE; + } + break; + case IDC_EDIT_CPUUSAGE: + if(HIWORD(wParam)==EN_KILLFOCUS) { + WORD val; + val=(WORD)GetDlgItemInt(hwndDlg,IDC_EDIT_CPUUSAGE,NULL,FALSE); + if(val<1) val=1; + else if(val>100) val=100; + SendDlgItemMessage(hwndDlg,IDC_SPIN_CPUUSAGE,UDM_SETPOS,0,MAKELPARAM(val,0)); + SetDlgItemInt(hwndDlg,IDC_EDIT_CPUUSAGE,val,FALSE); + return TRUE; + } + break; + case IDC_URL_IDLE: + { OPENOPTIONSDIALOG ood; + ood.cbSize=sizeof(ood); + ood.pszGroup="Status"; /* autotranslated */ + ood.pszPage="Idle"; /* autotranslated */ + ood.pszTab=NULL; + CallService(MS_OPT_OPENOPTIONS,0,(LPARAM)&ood); + return TRUE; + } + case IDC_COMBO_SHUTDOWNTYPE: + if(HIWORD(wParam)==CBN_SELCHANGE) + SendMessage(hwndDlg,M_UPDATE_SHUTDOWNDESC,0,lParam); + return TRUE; + case IDOK: /* save settings and start watcher */ + ShowWindow(hwndDlg,SW_HIDE); + /* message text */ + { HWND hwndEdit=GetDlgItem(hwndDlg,IDC_EDIT_MESSAGE); + int len=GetWindowTextLength(hwndEdit)+1; + TCHAR *pszText=(TCHAR*)mir_alloc(len*sizeof(TCHAR)); + if(pszText!=NULL && GetWindowText(hwndEdit,pszText,len+1)) { + TrimString(pszText); + DBWriteContactSettingTString(NULL,"AutoShutdown","Message",pszText); + } + mir_free(pszText); /* does NULL check */ + } + /* timestamp */ + { SYSTEMTIME st; + time_t timestamp; + DateTime_GetSystemtime(GetDlgItem(hwndDlg,IDC_TIME_TIMESTAMP),&st); /* time gets synchronized */ + if(!SystemTimeToTimeStamp(&st,×tamp)) + timestamp=time(NULL); + DBWriteContactSettingDword(NULL,"AutoShutdown","TimeStamp",(DWORD)timestamp); + } + /* shutdown type */ + { int index; + index=SendDlgItemMessage(hwndDlg,IDC_COMBO_SHUTDOWNTYPE,CB_GETCURSEL,0,0); + if(index!=LB_ERR) DBWriteContactSettingByte(NULL,"AutoShutdown","ShutdownType",(BYTE)SendDlgItemMessage(hwndDlg,IDC_COMBO_SHUTDOWNTYPE,CB_GETITEMDATA,(WPARAM)index,0)); + index=SendDlgItemMessage(hwndDlg,IDC_COMBO_COUNTDOWNUNIT,CB_GETCURSEL,0,0); + if(index!=LB_ERR) DBWriteContactSettingDword(NULL,"AutoShutdown","CountdownUnit",(DWORD)SendDlgItemMessage(hwndDlg,IDC_COMBO_COUNTDOWNUNIT,CB_GETITEMDATA,(WPARAM)index,0)); + DBWriteContactSettingDword(NULL,"AutoShutdown","Countdown",(DWORD)GetDlgItemInt(hwndDlg,IDC_EDIT_COUNTDOWN,NULL,FALSE)); + DBWriteContactSettingByte(NULL,"AutoShutdown","CpuUsageThreshold",(BYTE)GetDlgItemInt(hwndDlg,IDC_EDIT_CPUUSAGE,NULL,FALSE)); + } + /* watcher type */ + { WORD watcherType; + watcherType=(WORD)(IsDlgButtonChecked(hwndDlg,IDC_RADIO_STTIME)?SDWTF_ST_TIME:SDWTF_ST_COUNTDOWN); + if(IsDlgButtonChecked(hwndDlg,IDC_CHECK_SPECIFICTIME)) watcherType|=SDWTF_SPECIFICTIME; + if(IsDlgButtonChecked(hwndDlg,IDC_CHECK_MESSAGE)) watcherType|=SDWTF_MESSAGE; + if(IsDlgButtonChecked(hwndDlg,IDC_CHECK_FILETRANSFER)) watcherType|=SDWTF_FILETRANSFER; + if(IsDlgButtonChecked(hwndDlg,IDC_CHECK_IDLE)) watcherType|=SDWTF_IDLE; + if(IsDlgButtonChecked(hwndDlg,IDC_CHECK_STATUS)) watcherType|=SDWTF_STATUS; + if(IsDlgButtonChecked(hwndDlg,IDC_CHECK_CPUUSAGE)) watcherType|=SDWTF_CPUUSAGE; + DBWriteContactSettingWord(NULL,"AutoShutdown","WatcherFlags",watcherType); + ServiceStartWatcher(0,watcherType); + } + /* fall through */ + case IDCANCEL: /* WM_CLOSE */ + DestroyWindow(hwndDlg); + return TRUE; + } + break; + } + CallSnappingWindowProc(hwndDlg,msg,wParam,lParam); /* Snapping Windows plugin */ + return FALSE; +} + +/************************* Services ***********************************/ + +static int ServiceShowSettingsDialog(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + if(hwndSettingsDlg!=NULL) { /* already opened, bring to front */ + SetForegroundWindow(hwndSettingsDlg); + return 0; + } + return (CreateDialog(hInst,MAKEINTRESOURCE(IDD_SETTINGS),NULL,SettingsDlgProc)==NULL); +} + +/************************* Toolbar ************************************/ + +static WORD hToolbarButton; + +static int ToolbarLoaded(WPARAM wParam,LPARAM lParam) +{ + TTBButtonV2 ttbb; + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + + ZeroMemory(&ttbb,sizeof(ttbb)); + ttbb.cbSize=sizeof(ttbb); + /* toptoolbar offers icolib support */ + ttbb.hIconUp=(HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_ACTIVE),IMAGE_ICON,0,0,0); + ttbb.hIconDn=(HICON)LoadImage(hInst,MAKEINTRESOURCE(IDI_INACTIVE),IMAGE_ICON,0,0,0); + ttbb.pszServiceUp=ttbb.pszServiceDown="AutoShutdown/MenuCommand"; + ttbb.dwFlags=TTBBF_VISIBLE|TTBBF_SHOWTOOLTIP; + ttbb.name=Translate("Start/Stop automatic shutdown"); + + hToolbarButton=(WORD)CallService(MS_TTB_ADDBUTTON,(WPARAM)&ttbb,0); + if(ttbb.hIconUp!=NULL) DestroyIcon(ttbb.hIconUp); + if(ttbb.hIconDn!=NULL) DestroyIcon(ttbb.hIconDn); + return 0; +} + +void SetShutdownToolbarButton(BOOL fActive) +{ + if(hToolbarButton) { + CallService(MS_TTB_SETBUTTONSTATE,hToolbarButton,fActive?TTBST_PUSHED:TTBST_RELEASED); + CallService(MS_TTB_SETBUTTONOPTIONS,MAKEWPARAM(TTBO_TIPNAME,hToolbarButton),(LPARAM)(fActive?Translate("Sdop automatic shutdown"):Translate("Start automatic shutdown"))); + } +} + +/************************* Menu Item **********************************/ + +static HANDLE hMainMenuItem,hTrayMenuItem; +extern HANDLE hActiveIcon,hInactiveIcon; + +void SetShutdownMenuItem(BOOL fActive) +{ + CLISTMENUITEM cmi; + ZeroMemory(&cmi,sizeof(cmi)); + cmi.cbSize=sizeof(cmi); + + /* main menu */ + cmi.position=2001090000; + cmi.icolibItem=fActive?hActiveIcon:hInactiveIcon; + cmi.ptszName=fActive?_T("Stop automatic &shutdown"):_T("Automatic &shutdown..."); /* autotranslated */ + cmi.pszService="AutoShutdown/MenuCommand"; + cmi.flags=CMIF_TCHAR|CMIF_ICONFROMICOLIB; + if(hMainMenuItem!=NULL) { + cmi.flags|=CMIM_NAME|CMIM_ICON; + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hMainMenuItem,(LPARAM)&cmi); + } + else hMainMenuItem=(HANDLE)CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&cmi); + + /* tray menu */ + cmi.position=899999; + if(hTrayMenuItem!=NULL) { + cmi.flags|=CMIM_NAME|CMIM_ICON; + CallService(MS_CLIST_MODIFYMENUITEM,(WPARAM)hTrayMenuItem,(LPARAM)&cmi); + } + else hTrayMenuItem=(HANDLE)CallService(MS_CLIST_ADDTRAYMENUITEM,0,(LPARAM)&cmi); + + IcoLib_ReleaseIcon(cmi.hIcon); +} + +static int MenuItemCommand(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + /* toggle between StopWatcher and ShowSettingsDdialog */ + if(ServiceIsWatcherEnabled(0,0)) + ServiceStopWatcher(0,0); + else + ServiceShowSettingsDialog(0,0); + return 0; +} + +/************************* Misc ***************************************/ + +void InitSettingsDlg(void) +{ + /* Menu Item */ + hServiceMenuCommand=CreateServiceFunction("AutoShutdown/MenuCommand",MenuItemCommand); + hMainMenuItem=hTrayMenuItem=NULL; + SetShutdownMenuItem(FALSE); + /* Toolbar Item */ + hToolbarButton=0; + hHookToolbarLoaded=HookEvent(ME_TTB_MODULELOADED,ToolbarLoaded); /* no service to check for */ + /* Hotkey */ + SkinAddNewHotkey("AutoShutdown_Toggle",Translate("Main"),Translate("Toggle Automatic Shutdown"),'T',HOTKEYF_CONTROL|HOTKEYF_SHIFT,"AutoShutdown/MenuCommand"); + /* Services */ + hwndSettingsDlg=NULL; + hServiceShowDlg=CreateServiceFunction(MS_AUTOSHUTDOWN_SHOWSETTINGSDIALOG,ServiceShowSettingsDialog); +} + +void UninitSettingsDlg(void) +{ + /* Toolbar Item */ + UnhookEvent(hHookToolbarLoaded); + /* Menu Item */ + DestroyServiceFunction(hServiceMenuCommand); + /* Services */ + DestroyServiceFunction(hServiceShowDlg); +} + diff --git a/plugins/AutoShutdown/settingsdlg.h b/plugins/AutoShutdown/settingsdlg.h new file mode 100644 index 0000000000..2f7bf8ea84 --- /dev/null +++ b/plugins/AutoShutdown/settingsdlg.h @@ -0,0 +1,30 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* Menu Item */ +void SetShutdownMenuItem(BOOL fActive); + +/* Toolbar Button */ +void SetShutdownToolbarButton(BOOL fActive); + +/* Misc */ +void InitSettingsDlg(void); +void UninitSettingsDlg(void); diff --git a/plugins/AutoShutdown/shutdown.def b/plugins/AutoShutdown/shutdown.def new file mode 100644 index 0000000000..09d13e6c16 --- /dev/null +++ b/plugins/AutoShutdown/shutdown.def @@ -0,0 +1,11 @@ +LIBRARY shutdown BASE=0x11070000 +SECTIONS + ; obfuscated email address + .rdata READ WRITE +EXPORTS + MirandaPluginInfo PRIVATE + Load PRIVATE + Unload PRIVATE + ; v0.8 support + MirandaPluginInfoEx PRIVATE + MirandaPluginInterfaces PRIVATE diff --git a/plugins/AutoShutdown/shutdown.dep b/plugins/AutoShutdown/shutdown.dep new file mode 100644 index 0000000000..ec15869669 --- /dev/null +++ b/plugins/AutoShutdown/shutdown.dep @@ -0,0 +1,394 @@ +# Microsoft Developer Studio erstellte Abhдngigkeitsdatei, einbezogen von shutdown.mak + +.\cpuusage.c : \ + ".\common.h"\ + ".\cpuusage.h"\ + ".\frame.h"\ + ".\include\m_autoreplacer.h"\ + ".\include\m_button.h"\ + ".\include\m_clc.h"\ + ".\include\m_clist.h"\ + ".\include\m_clistint.h"\ + ".\include\m_clui.h"\ + ".\include\m_cluiframes.h"\ + ".\include\m_database.h"\ + ".\include\m_file.h"\ + ".\include\m_fontservice.h"\ + ".\include\m_genmenu.h"\ + ".\include\m_hddinfo.h"\ + ".\include\m_hotkey.h"\ + ".\include\m_hotkeysplus.h"\ + ".\include\m_hotkeysservice.h"\ + ".\include\m_icolib.h"\ + ".\include\m_idle.h"\ + ".\include\m_langpack.h"\ + ".\include\m_magneticwindows.h"\ + ".\include\m_message.h"\ + ".\include\m_mwclc.h"\ + ".\include\m_options.h"\ + ".\include\m_plugins.h"\ + ".\include\m_protocols.h"\ + ".\include\m_protosvc.h"\ + ".\include\m_skin.h"\ + ".\include\m_snappingwindows.h"\ + ".\include\m_system.h"\ + ".\include\m_toptoolbar.h"\ + ".\include\m_trigger.h"\ + ".\include\m_utils.h"\ + ".\include\m_weather.h"\ + ".\include\newpluginapi.h"\ + ".\include\statusmodes.h"\ + ".\include\win2k.h"\ + ".\m_shutdown.h"\ + ".\options.h"\ + ".\settingsdlg.h"\ + ".\shutdownsvc.h"\ + ".\utils.h"\ + ".\watcher.h"\ + "e:\vc98\include\basetsd.h"\ + + +.\frame.c : \ + ".\common.h"\ + ".\cpuusage.h"\ + ".\frame.h"\ + ".\include\m_autoreplacer.h"\ + ".\include\m_button.h"\ + ".\include\m_clc.h"\ + ".\include\m_clist.h"\ + ".\include\m_clistint.h"\ + ".\include\m_clui.h"\ + ".\include\m_cluiframes.h"\ + ".\include\m_database.h"\ + ".\include\m_file.h"\ + ".\include\m_fontservice.h"\ + ".\include\m_genmenu.h"\ + ".\include\m_hddinfo.h"\ + ".\include\m_hotkey.h"\ + ".\include\m_hotkeysplus.h"\ + ".\include\m_hotkeysservice.h"\ + ".\include\m_icolib.h"\ + ".\include\m_idle.h"\ + ".\include\m_langpack.h"\ + ".\include\m_magneticwindows.h"\ + ".\include\m_message.h"\ + ".\include\m_mwclc.h"\ + ".\include\m_options.h"\ + ".\include\m_plugins.h"\ + ".\include\m_protocols.h"\ + ".\include\m_protosvc.h"\ + ".\include\m_skin.h"\ + ".\include\m_snappingwindows.h"\ + ".\include\m_system.h"\ + ".\include\m_toptoolbar.h"\ + ".\include\m_trigger.h"\ + ".\include\m_utils.h"\ + ".\include\m_weather.h"\ + ".\include\newpluginapi.h"\ + ".\include\statusmodes.h"\ + ".\include\win2k.h"\ + ".\m_shutdown.h"\ + ".\options.h"\ + ".\settingsdlg.h"\ + ".\shutdownsvc.h"\ + ".\utils.h"\ + ".\watcher.h"\ + "e:\vc98\include\basetsd.h"\ + + +.\main.c : \ + ".\common.h"\ + ".\cpuusage.h"\ + ".\frame.h"\ + ".\include\m_autoreplacer.h"\ + ".\include\m_button.h"\ + ".\include\m_clc.h"\ + ".\include\m_clist.h"\ + ".\include\m_clistint.h"\ + ".\include\m_clui.h"\ + ".\include\m_cluiframes.h"\ + ".\include\m_database.h"\ + ".\include\m_file.h"\ + ".\include\m_fontservice.h"\ + ".\include\m_genmenu.h"\ + ".\include\m_hddinfo.h"\ + ".\include\m_hotkey.h"\ + ".\include\m_hotkeysplus.h"\ + ".\include\m_hotkeysservice.h"\ + ".\include\m_icolib.h"\ + ".\include\m_idle.h"\ + ".\include\m_langpack.h"\ + ".\include\m_magneticwindows.h"\ + ".\include\m_message.h"\ + ".\include\m_mwclc.h"\ + ".\include\m_options.h"\ + ".\include\m_plugins.h"\ + ".\include\m_protocols.h"\ + ".\include\m_protosvc.h"\ + ".\include\m_skin.h"\ + ".\include\m_snappingwindows.h"\ + ".\include\m_system.h"\ + ".\include\m_toptoolbar.h"\ + ".\include\m_trigger.h"\ + ".\include\m_utils.h"\ + ".\include\m_weather.h"\ + ".\include\newpluginapi.h"\ + ".\include\statusmodes.h"\ + ".\include\win2k.h"\ + ".\m_shutdown.h"\ + ".\options.h"\ + ".\settingsdlg.h"\ + ".\shutdownsvc.h"\ + ".\utils.h"\ + ".\version.h"\ + ".\watcher.h"\ + "e:\vc98\include\basetsd.h"\ + + +.\options.c : \ + ".\common.h"\ + ".\cpuusage.h"\ + ".\frame.h"\ + ".\include\m_autoreplacer.h"\ + ".\include\m_button.h"\ + ".\include\m_clc.h"\ + ".\include\m_clist.h"\ + ".\include\m_clistint.h"\ + ".\include\m_clui.h"\ + ".\include\m_cluiframes.h"\ + ".\include\m_database.h"\ + ".\include\m_file.h"\ + ".\include\m_fontservice.h"\ + ".\include\m_genmenu.h"\ + ".\include\m_hddinfo.h"\ + ".\include\m_hotkey.h"\ + ".\include\m_hotkeysplus.h"\ + ".\include\m_hotkeysservice.h"\ + ".\include\m_icolib.h"\ + ".\include\m_idle.h"\ + ".\include\m_langpack.h"\ + ".\include\m_magneticwindows.h"\ + ".\include\m_message.h"\ + ".\include\m_mwclc.h"\ + ".\include\m_options.h"\ + ".\include\m_plugins.h"\ + ".\include\m_protocols.h"\ + ".\include\m_protosvc.h"\ + ".\include\m_skin.h"\ + ".\include\m_snappingwindows.h"\ + ".\include\m_system.h"\ + ".\include\m_toptoolbar.h"\ + ".\include\m_trigger.h"\ + ".\include\m_utils.h"\ + ".\include\m_weather.h"\ + ".\include\newpluginapi.h"\ + ".\include\statusmodes.h"\ + ".\include\win2k.h"\ + ".\m_shutdown.h"\ + ".\options.h"\ + ".\settingsdlg.h"\ + ".\shutdownsvc.h"\ + ".\utils.h"\ + ".\watcher.h"\ + "e:\vc98\include\basetsd.h"\ + + +.\settingsdlg.c : \ + ".\common.h"\ + ".\cpuusage.h"\ + ".\frame.h"\ + ".\include\m_autoreplacer.h"\ + ".\include\m_button.h"\ + ".\include\m_clc.h"\ + ".\include\m_clist.h"\ + ".\include\m_clistint.h"\ + ".\include\m_clui.h"\ + ".\include\m_cluiframes.h"\ + ".\include\m_database.h"\ + ".\include\m_file.h"\ + ".\include\m_fontservice.h"\ + ".\include\m_genmenu.h"\ + ".\include\m_hddinfo.h"\ + ".\include\m_hotkey.h"\ + ".\include\m_hotkeysplus.h"\ + ".\include\m_hotkeysservice.h"\ + ".\include\m_icolib.h"\ + ".\include\m_idle.h"\ + ".\include\m_langpack.h"\ + ".\include\m_magneticwindows.h"\ + ".\include\m_message.h"\ + ".\include\m_mwclc.h"\ + ".\include\m_options.h"\ + ".\include\m_plugins.h"\ + ".\include\m_protocols.h"\ + ".\include\m_protosvc.h"\ + ".\include\m_skin.h"\ + ".\include\m_snappingwindows.h"\ + ".\include\m_system.h"\ + ".\include\m_toptoolbar.h"\ + ".\include\m_trigger.h"\ + ".\include\m_utils.h"\ + ".\include\m_weather.h"\ + ".\include\newpluginapi.h"\ + ".\include\statusmodes.h"\ + ".\include\win2k.h"\ + ".\m_shutdown.h"\ + ".\options.h"\ + ".\settingsdlg.h"\ + ".\shutdownsvc.h"\ + ".\utils.h"\ + ".\watcher.h"\ + "e:\vc98\include\basetsd.h"\ + + +.\shutdownsvc.c : \ + ".\common.h"\ + ".\cpuusage.h"\ + ".\frame.h"\ + ".\include\m_autoreplacer.h"\ + ".\include\m_button.h"\ + ".\include\m_clc.h"\ + ".\include\m_clist.h"\ + ".\include\m_clistint.h"\ + ".\include\m_clui.h"\ + ".\include\m_cluiframes.h"\ + ".\include\m_database.h"\ + ".\include\m_file.h"\ + ".\include\m_fontservice.h"\ + ".\include\m_genmenu.h"\ + ".\include\m_hddinfo.h"\ + ".\include\m_hotkey.h"\ + ".\include\m_hotkeysplus.h"\ + ".\include\m_hotkeysservice.h"\ + ".\include\m_icolib.h"\ + ".\include\m_idle.h"\ + ".\include\m_langpack.h"\ + ".\include\m_magneticwindows.h"\ + ".\include\m_message.h"\ + ".\include\m_mwclc.h"\ + ".\include\m_options.h"\ + ".\include\m_plugins.h"\ + ".\include\m_protocols.h"\ + ".\include\m_protosvc.h"\ + ".\include\m_skin.h"\ + ".\include\m_snappingwindows.h"\ + ".\include\m_system.h"\ + ".\include\m_toptoolbar.h"\ + ".\include\m_trigger.h"\ + ".\include\m_utils.h"\ + ".\include\m_weather.h"\ + ".\include\newpluginapi.h"\ + ".\include\statusmodes.h"\ + ".\include\win2k.h"\ + ".\m_shutdown.h"\ + ".\options.h"\ + ".\settingsdlg.h"\ + ".\shutdownsvc.h"\ + ".\utils.h"\ + ".\watcher.h"\ + "e:\vc98\include\basetsd.h"\ + + +.\utils.c : \ + ".\common.h"\ + ".\cpuusage.h"\ + ".\frame.h"\ + ".\include\m_autoreplacer.h"\ + ".\include\m_button.h"\ + ".\include\m_clc.h"\ + ".\include\m_clist.h"\ + ".\include\m_clistint.h"\ + ".\include\m_clui.h"\ + ".\include\m_cluiframes.h"\ + ".\include\m_database.h"\ + ".\include\m_file.h"\ + ".\include\m_fontservice.h"\ + ".\include\m_genmenu.h"\ + ".\include\m_hddinfo.h"\ + ".\include\m_hotkey.h"\ + ".\include\m_hotkeysplus.h"\ + ".\include\m_hotkeysservice.h"\ + ".\include\m_icolib.h"\ + ".\include\m_idle.h"\ + ".\include\m_langpack.h"\ + ".\include\m_magneticwindows.h"\ + ".\include\m_message.h"\ + ".\include\m_mwclc.h"\ + ".\include\m_options.h"\ + ".\include\m_plugins.h"\ + ".\include\m_protocols.h"\ + ".\include\m_protosvc.h"\ + ".\include\m_skin.h"\ + ".\include\m_snappingwindows.h"\ + ".\include\m_system.h"\ + ".\include\m_toptoolbar.h"\ + ".\include\m_trigger.h"\ + ".\include\m_utils.h"\ + ".\include\m_weather.h"\ + ".\include\newpluginapi.h"\ + ".\include\statusmodes.h"\ + ".\include\win2k.h"\ + ".\m_shutdown.h"\ + ".\options.h"\ + ".\settingsdlg.h"\ + ".\shutdownsvc.h"\ + ".\utils.h"\ + ".\watcher.h"\ + "e:\vc98\include\basetsd.h"\ + + +.\watcher.c : \ + ".\common.h"\ + ".\cpuusage.h"\ + ".\frame.h"\ + ".\include\m_autoreplacer.h"\ + ".\include\m_button.h"\ + ".\include\m_clc.h"\ + ".\include\m_clist.h"\ + ".\include\m_clistint.h"\ + ".\include\m_clui.h"\ + ".\include\m_cluiframes.h"\ + ".\include\m_database.h"\ + ".\include\m_file.h"\ + ".\include\m_fontservice.h"\ + ".\include\m_genmenu.h"\ + ".\include\m_hddinfo.h"\ + ".\include\m_hotkey.h"\ + ".\include\m_hotkeysplus.h"\ + ".\include\m_hotkeysservice.h"\ + ".\include\m_icolib.h"\ + ".\include\m_idle.h"\ + ".\include\m_langpack.h"\ + ".\include\m_magneticwindows.h"\ + ".\include\m_message.h"\ + ".\include\m_mwclc.h"\ + ".\include\m_options.h"\ + ".\include\m_plugins.h"\ + ".\include\m_protocols.h"\ + ".\include\m_protosvc.h"\ + ".\include\m_skin.h"\ + ".\include\m_snappingwindows.h"\ + ".\include\m_system.h"\ + ".\include\m_toptoolbar.h"\ + ".\include\m_trigger.h"\ + ".\include\m_utils.h"\ + ".\include\m_weather.h"\ + ".\include\newpluginapi.h"\ + ".\include\statusmodes.h"\ + ".\include\win2k.h"\ + ".\m_shutdown.h"\ + ".\options.h"\ + ".\settingsdlg.h"\ + ".\shutdownsvc.h"\ + ".\utils.h"\ + ".\watcher.h"\ + "e:\vc98\include\basetsd.h"\ + + +.\resource.rc : \ + ".\include\m_utils.h"\ + ".\res\active.ico"\ + ".\res\header.ico"\ + ".\res\inactive.ico"\ + ".\version.rc"\ + diff --git a/plugins/AutoShutdown/shutdown.dsp b/plugins/AutoShutdown/shutdown.dsp new file mode 100644 index 0000000000..52d65badfa --- /dev/null +++ b/plugins/AutoShutdown/shutdown.dsp @@ -0,0 +1,451 @@ +# Microsoft Developer Studio Project File - Name="shutdown" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** NICHT BEARBEITEN ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=shutdown - Win32 Release +!MESSAGE Dies ist kein gьltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE +!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und fьhren Sie den Befehl +!MESSAGE +!MESSAGE NMAKE /f "shutdown.mak". +!MESSAGE +!MESSAGE Sie kцnnen beim Ausfьhren von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "shutdown.mak" CFG="shutdown - Win32 Release" +!MESSAGE +!MESSAGE Fьr die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "shutdown - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE "shutdown - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE "shutdown - Win32 Release Unicode" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE "shutdown - Win32 Debug Unicode" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "shutdown - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "release/ANSI" +# PROP BASE Intermediate_Dir "temp/Release/ANSI" +# PROP BASE Target_Dir "release/ANSI" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "temp/Release/ANSI" +# PROP Intermediate_Dir "temp/Release/ANSI" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "release/ANSI" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SHUTDOWN_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W4 /GX /O2 /I ".\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "STRICT" /D "SHUTDOWN_EXPORTS" /U "NO_STRICT" /FR /FD /opt:nowin98 /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +# SUBTRACT MTL /mktyplib203 /Oicf +# ADD BASE RSC /l 0x1009 /d "NDEBUG" +# ADD RSC /l 0x409 /i ".\include" /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib comctl32.lib gdi32.lib user32.lib shell32.lib advapi32.lib /nologo /base:"0x11070000" /dll /pdb:"./release/ANSI/shutdown.pdb" /map:"release/ANSI/shutdown.map" /debug /machine:I386 /nodefaultlib:"uuid.lib" /nodefaultlib:"OLDNAMES" /def:"shutdown.def" /out:"./release/ANSI/shutdown.dll" /mapinfo:lines /opt:nowin98 /ignore:4078 /RELEASE +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "shutdown - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "temp/Debug/ANSI" +# PROP BASE Intermediate_Dir "temp/Debug/ANSI" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "temp/Debug/ANSI" +# PROP Intermediate_Dir "temp/Debug/ANSI" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SHUTDOWN_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W4 /Gm /Gi /GR /GX /ZI /Od /I ".\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "STRICT" /D "SHUTDOWN_EXPORTS" /U "NO_STRICT" /FR /FD /GZ /c +# SUBTRACT CPP /WX /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# SUBTRACT MTL /Oicf +# ADD BASE RSC /l 0x1009 /d "_DEBUG" +# ADD RSC /l 0x409 /i ".\include" /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib comctl32.lib gdi32.lib user32.lib shell32.lib advapi32.lib /nologo /base:"0x11070000" /dll /pdb:"D:/Miranda IM/ANSI/Plugins/shutdown.pdb" /map /debug /machine:I386 /nodefaultlib:"uuid.lib" /nodefaultlib:"OLDNAMES" /def:"shutdown.def" /out:"D:/Miranda IM/ANSI/Plugins/shutdown.dll" /pdbtype:sept +# SUBTRACT LINK32 /verbose /pdb:none + +!ELSEIF "$(CFG)" == "shutdown - Win32 Release Unicode" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "release/Unicode" +# PROP BASE Intermediate_Dir "temp/Release/Unicode" +# PROP BASE Target_Dir "release/Unicode" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "temp/Release/Unicode" +# PROP Intermediate_Dir "temp/Release/Unicode" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "release/Unicode" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SHUTDOWN_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W4 /GX /O2 /I ".\include" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "STRICT" /D "SHUTDOWN_EXPORTS" /U "_MBCS" /U "NO_STRICT" /FR /FD /opt:nowin98 /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +# SUBTRACT MTL /mktyplib203 /Oicf +# ADD BASE RSC /l 0x1009 /d "NDEBUG" /d "_UNICODE" /d "UNICODE" +# ADD RSC /l 0x409 /i ".\include" /d "NDEBUG" /d "_UNICODE" /d "UNICODE" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib comctl32.lib gdi32.lib user32.lib shell32.lib advapi32.lib /nologo /base:"0x11070000" /dll /pdb:"./release/Unicode/shutdown.pdb" /map:"release/Unicode/shutdown.map" /debug /machine:I386 /nodefaultlib:"uuid.lib" /nodefaultlib:"OLDNAMES" /def:"shutdown.def" /out:"./release/Unicode/shutdown.dll" /mapinfo:lines /opt:nowin98 /ignore:4078 /RELEASE +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "shutdown - Win32 Debug Unicode" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "temp/Debug/Unicode" +# PROP BASE Intermediate_Dir "temp/Debug/Unicode" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "temp/Debug/Unicode" +# PROP Intermediate_Dir "temp/Debug/Unicode" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SHUTDOWN_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W4 /Gm /Gi /GR /GX /ZI /Od /I ".\include" /D "_DEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "STRICT" /D "SHUTDOWN_EXPORTS" /U "_MBCS" /U "NO_STRICT" /FR /FD /GZ /c +# SUBTRACT CPP /WX /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# SUBTRACT MTL /Oicf +# ADD BASE RSC /l 0x1009 /d "_DEBUG" /d "_UNICODE" /d "UNICODE" +# ADD RSC /l 0x409 /i ".\include" /d "_DEBUG" /d "_UNICODE" /d "UNICODE" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib comctl32.lib gdi32.lib user32.lib shell32.lib advapi32.lib /nologo /base:"0x11070000" /dll /pdb:"D:/Miranda IM/Unicode/Plugins/shutdown.pdb" /map /debug /machine:I386 /nodefaultlib:"uuid.lib" /nodefaultlib:"OLDNAMES" /def:"shutdown.def" /out:"D:/Miranda IM/Unicode/Plugins/shutdown.dll" /pdbtype:sept +# SUBTRACT LINK32 /pdb:none /nodefaultlib + +!ENDIF + +# Begin Target + +# Name "shutdown - Win32 Release" +# Name "shutdown - Win32 Debug" +# Name "shutdown - Win32 Release Unicode" +# Name "shutdown - Win32 Debug Unicode" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\cpuusage.c +# End Source File +# Begin Source File + +SOURCE=.\frame.c +# End Source File +# Begin Source File + +SOURCE=.\main.c +# End Source File +# Begin Source File + +SOURCE=.\options.c +# End Source File +# Begin Source File + +SOURCE=.\settingsdlg.c +# End Source File +# Begin Source File + +SOURCE=.\shutdownsvc.c +# End Source File +# Begin Source File + +SOURCE=.\utils.c +# End Source File +# Begin Source File + +SOURCE=.\watcher.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\common.h +# End Source File +# Begin Source File + +SOURCE=.\cpuusage.h +# End Source File +# Begin Source File + +SOURCE=.\frame.h +# End Source File +# Begin Source File + +SOURCE=.\m_shutdown.h +# End Source File +# Begin Source File + +SOURCE=.\options.h +# End Source File +# Begin Source File + +SOURCE=.\settingsdlg.h +# End Source File +# Begin Source File + +SOURCE=.\shutdownsvc.h +# End Source File +# Begin Source File + +SOURCE=.\utils.h +# End Source File +# Begin Source File + +SOURCE=.\watcher.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\res\active.ico +# End Source File +# Begin Source File + +SOURCE=.\res\header.ico +# End Source File +# Begin Source File + +SOURCE=.\res\inactive.ico +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\version.h +# End Source File +# End Group +# Begin Group "Documentation" + +# PROP Default_Filter "txt" +# Begin Source File + +SOURCE=.\Extensions\countdown.wav +# End Source File +# Begin Source File + +SOURCE=.\m_shutdown.inc +# End Source File +# Begin Source File + +SOURCE=".\docs\Shutdown-Developer.txt" +# End Source File +# Begin Source File + +SOURCE=".\docs\Shutdown-License.txt" +# End Source File +# Begin Source File + +SOURCE=".\docs\Shutdown-Readme.txt" +# End Source File +# Begin Source File + +SOURCE=".\docs\Shutdown-Translation.txt" +# End Source File +# End Group +# Begin Group "SDK" + +# PROP Default_Filter "*.h" +# Begin Source File + +SOURCE=.\include\m_autoreplacer.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_button.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_clc.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_clist.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_clistint.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_clui.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_cluiframes.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_database.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_file.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_fontservice.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_genmenu.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_hddinfo.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_hotkey.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_hotkeysplus.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_hotkeysservice.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_icolib.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_idle.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_langpack.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_magneticwindows.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_message.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_mwclc.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_options.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_plugins.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_protocols.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_protomod.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_protosvc.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_skin.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_snappingwindows.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_system.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_toptoolbar.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_trigger.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_updater.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_utils.h +# End Source File +# Begin Source File + +SOURCE=.\include\m_weather.h +# End Source File +# Begin Source File + +SOURCE=.\include\newpluginapi.h +# End Source File +# Begin Source File + +SOURCE=.\include\statusmodes.h +# End Source File +# Begin Source File + +SOURCE=.\include\win2k.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\Info_Src.txt +# End Source File +# Begin Source File + +SOURCE=.\License_Appendix.txt +# End Source File +# End Target +# End Project diff --git a/plugins/AutoShutdown/shutdown.dsw b/plugins/AutoShutdown/shutdown.dsw new file mode 100644 index 0000000000..b5435be4b4 --- /dev/null +++ b/plugins/AutoShutdown/shutdown.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELЦSCHT WERDEN! + +############################################################################### + +Project: "shutdown"=".\shutdown.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/plugins/AutoShutdown/shutdown.mak b/plugins/AutoShutdown/shutdown.mak new file mode 100644 index 0000000000..daaa0217de --- /dev/null +++ b/plugins/AutoShutdown/shutdown.mak @@ -0,0 +1,435 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on shutdown.dsp +!IF "$(CFG)" == "" +CFG=shutdown - Win32 Release +!MESSAGE Keine Konfiguration angegeben. shutdown - Win32 Release wird als Standard verwendet. +!ENDIF + +!IF "$(CFG)" != "shutdown - Win32 Release" && "$(CFG)" != "shutdown - Win32 Debug" && "$(CFG)" != "shutdown - Win32 Release Unicode" && "$(CFG)" != "shutdown - Win32 Debug Unicode" +!MESSAGE UngЃltige Konfiguration "$(CFG)" angegeben. +!MESSAGE Sie k”nnen beim AusfЃhren von NMAKE eine Konfiguration angeben +!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: +!MESSAGE +!MESSAGE NMAKE /f "shutdown.mak" CFG="shutdown - Win32 Release" +!MESSAGE +!MESSAGE FЃr die Konfiguration stehen zur Auswahl: +!MESSAGE +!MESSAGE "shutdown - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE "shutdown - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE "shutdown - Win32 Release Unicode" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE "shutdown - Win32 Debug Unicode" (basierend auf "Win32 (x86) Dynamic-Link Library") +!MESSAGE +!ERROR Eine ungЃltige Konfiguration wurde angegeben. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "shutdown - Win32 Release" + +OUTDIR=.\temp/Release/ANSI +INTDIR=.\temp/Release/ANSI +# Begin Custom Macros +OutDir=.\temp/Release/ANSI +# End Custom Macros + +ALL : ".\release\ANSI\shutdown.dll" "$(OUTDIR)\shutdown.bsc" + + +CLEAN : + -@erase "$(INTDIR)\cpuusage.obj" + -@erase "$(INTDIR)\cpuusage.sbr" + -@erase "$(INTDIR)\frame.obj" + -@erase "$(INTDIR)\frame.sbr" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\main.sbr" + -@erase "$(INTDIR)\options.obj" + -@erase "$(INTDIR)\options.sbr" + -@erase "$(INTDIR)\resource.res" + -@erase "$(INTDIR)\settingsdlg.obj" + -@erase "$(INTDIR)\settingsdlg.sbr" + -@erase "$(INTDIR)\shutdownsvc.obj" + -@erase "$(INTDIR)\shutdownsvc.sbr" + -@erase "$(INTDIR)\utils.obj" + -@erase "$(INTDIR)\utils.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\watcher.obj" + -@erase "$(INTDIR)\watcher.sbr" + -@erase "$(OUTDIR)\shutdown.bsc" + -@erase "$(OUTDIR)\shutdown.exp" + -@erase ".\release\ANSI\shutdown.dll" + -@erase ".\release\ANSI\shutdown.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /MD /W4 /GX /O2 /I ".\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "STRICT" /D "SHUTDOWN_EXPORTS" /U "NO_STRICT" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /opt:nowin98 /c +MTL_PROJ=/nologo /D "NDEBUG" /win32 +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /i ".\include" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\shutdown.bsc" +BSC32_SBRS= \ + "$(INTDIR)\cpuusage.sbr" \ + "$(INTDIR)\frame.sbr" \ + "$(INTDIR)\main.sbr" \ + "$(INTDIR)\options.sbr" \ + "$(INTDIR)\settingsdlg.sbr" \ + "$(INTDIR)\shutdownsvc.sbr" \ + "$(INTDIR)\utils.sbr" \ + "$(INTDIR)\watcher.sbr" + +"$(OUTDIR)\shutdown.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib comctl32.lib gdi32.lib user32.lib shell32.lib advapi32.lib /nologo /base:"0x11070000" /dll /incremental:no /pdb:"./release/ANSI/shutdown.pdb" /debug /machine:I386 /nodefaultlib:"uuid.lib" /nodefaultlib:"OLDNAMES" /def:"shutdown.def" /out:"./release/ANSI/shutdown.dll" /implib:"$(OUTDIR)\shutdown.lib" /opt:nowin98 /ignore:4078 /RELEASE +LINK32_OBJS= \ + "$(INTDIR)\cpuusage.obj" \ + "$(INTDIR)\frame.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\options.obj" \ + "$(INTDIR)\settingsdlg.obj" \ + "$(INTDIR)\shutdownsvc.obj" \ + "$(INTDIR)\utils.obj" \ + "$(INTDIR)\watcher.obj" \ + "$(INTDIR)\resource.res" + +".\release\ANSI\shutdown.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "shutdown - Win32 Debug" + +OUTDIR=.\temp/Debug/ANSI +INTDIR=.\temp/Debug/ANSI +# Begin Custom Macros +OutDir=.\temp/Debug/ANSI +# End Custom Macros + +ALL : "..\Miranda IM\ANSI\Plugins\shutdown.dll" "$(OUTDIR)\shutdown.bsc" + + +CLEAN : + -@erase "$(INTDIR)\cpuusage.obj" + -@erase "$(INTDIR)\cpuusage.sbr" + -@erase "$(INTDIR)\frame.obj" + -@erase "$(INTDIR)\frame.sbr" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\main.sbr" + -@erase "$(INTDIR)\options.obj" + -@erase "$(INTDIR)\options.sbr" + -@erase "$(INTDIR)\resource.res" + -@erase "$(INTDIR)\settingsdlg.obj" + -@erase "$(INTDIR)\settingsdlg.sbr" + -@erase "$(INTDIR)\shutdownsvc.obj" + -@erase "$(INTDIR)\shutdownsvc.sbr" + -@erase "$(INTDIR)\utils.obj" + -@erase "$(INTDIR)\utils.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(INTDIR)\watcher.obj" + -@erase "$(INTDIR)\watcher.sbr" + -@erase "$(OUTDIR)\shutdown.bsc" + -@erase "$(OUTDIR)\shutdown.exp" + -@erase "$(OUTDIR)\shutdown.map" + -@erase "..\Miranda IM\ANSI\Plugins\shutdown.dll" + -@erase "..\Miranda IM\ANSI\Plugins\shutdown.ilk" + -@erase "..\Miranda IM\ANSI\Plugins\shutdown.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /MTd /W4 /Gm /Gi /GR /GX /ZI /Od /I ".\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "STRICT" /D "SHUTDOWN_EXPORTS" /U "NO_STRICT" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /i ".\include" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\shutdown.bsc" +BSC32_SBRS= \ + "$(INTDIR)\cpuusage.sbr" \ + "$(INTDIR)\frame.sbr" \ + "$(INTDIR)\main.sbr" \ + "$(INTDIR)\options.sbr" \ + "$(INTDIR)\settingsdlg.sbr" \ + "$(INTDIR)\shutdownsvc.sbr" \ + "$(INTDIR)\utils.sbr" \ + "$(INTDIR)\watcher.sbr" + +"$(OUTDIR)\shutdown.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib comctl32.lib gdi32.lib user32.lib shell32.lib advapi32.lib /nologo /base:"0x11070000" /dll /incremental:yes /pdb:"C:/Dokumente und Einstellungen/bib-nutzer/Desktop/Miranda IM/ANSI/Plugins/shutdown.pdb" /map:"$(INTDIR)\shutdown.map" /debug /machine:I386 /nodefaultlib:"uuid.lib" /nodefaultlib:"OLDNAMES" /def:"shutdown.def" /out:"C:/Dokumente und Einstellungen/bib-nutzer/Desktop/Miranda IM/ANSI/Plugins/shutdown.dll" /implib:"$(OUTDIR)\shutdown.lib" /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\cpuusage.obj" \ + "$(INTDIR)\frame.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\options.obj" \ + "$(INTDIR)\settingsdlg.obj" \ + "$(INTDIR)\shutdownsvc.obj" \ + "$(INTDIR)\utils.obj" \ + "$(INTDIR)\watcher.obj" \ + "$(INTDIR)\resource.res" + +"..\Miranda IM\ANSI\Plugins\shutdown.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "shutdown - Win32 Release Unicode" + +OUTDIR=.\temp/Release/Unicode +INTDIR=.\temp/Release/Unicode +# Begin Custom Macros +OutDir=.\temp/Release/Unicode +# End Custom Macros + +ALL : ".\release\Unicode\shutdown.dll" "$(OUTDIR)\shutdown.bsc" + + +CLEAN : + -@erase "$(INTDIR)\cpuusage.obj" + -@erase "$(INTDIR)\cpuusage.sbr" + -@erase "$(INTDIR)\frame.obj" + -@erase "$(INTDIR)\frame.sbr" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\main.sbr" + -@erase "$(INTDIR)\options.obj" + -@erase "$(INTDIR)\options.sbr" + -@erase "$(INTDIR)\resource.res" + -@erase "$(INTDIR)\settingsdlg.obj" + -@erase "$(INTDIR)\settingsdlg.sbr" + -@erase "$(INTDIR)\shutdownsvc.obj" + -@erase "$(INTDIR)\shutdownsvc.sbr" + -@erase "$(INTDIR)\utils.obj" + -@erase "$(INTDIR)\utils.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\watcher.obj" + -@erase "$(INTDIR)\watcher.sbr" + -@erase "$(OUTDIR)\shutdown.bsc" + -@erase "$(OUTDIR)\shutdown.exp" + -@erase ".\release\Unicode\shutdown.dll" + -@erase ".\release\Unicode\shutdown.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /MD /W4 /GX /O2 /I ".\include" /D "NDEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "STRICT" /D "SHUTDOWN_EXPORTS" /U "_MBCS" /U "NO_STRICT" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\shutdown.pch" /YX"common.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /opt:nowin98 /c +MTL_PROJ=/nologo /D "NDEBUG" /win32 +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /i ".\include" /d "NDEBUG" /d "_UNICODE" /d "UNICODE" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\shutdown.bsc" +BSC32_SBRS= \ + "$(INTDIR)\cpuusage.sbr" \ + "$(INTDIR)\frame.sbr" \ + "$(INTDIR)\main.sbr" \ + "$(INTDIR)\options.sbr" \ + "$(INTDIR)\settingsdlg.sbr" \ + "$(INTDIR)\shutdownsvc.sbr" \ + "$(INTDIR)\utils.sbr" \ + "$(INTDIR)\watcher.sbr" + +"$(OUTDIR)\shutdown.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib comctl32.lib gdi32.lib user32.lib shell32.lib advapi32.lib /nologo /base:"0x11070000" /dll /incremental:no /pdb:"./release/Unicode/shutdown.pdb" /debug /machine:I386 /nodefaultlib:"uuid.lib" /nodefaultlib:"OLDNAMES" /def:"shutdown.def" /out:"./release/Unicode/shutdown.dll" /implib:"$(OUTDIR)\shutdown.lib" /opt:nowin98 /ignore:4078 /RELEASE +LINK32_OBJS= \ + "$(INTDIR)\cpuusage.obj" \ + "$(INTDIR)\frame.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\options.obj" \ + "$(INTDIR)\settingsdlg.obj" \ + "$(INTDIR)\shutdownsvc.obj" \ + "$(INTDIR)\utils.obj" \ + "$(INTDIR)\watcher.obj" \ + "$(INTDIR)\resource.res" + +".\release\Unicode\shutdown.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "shutdown - Win32 Debug Unicode" + +OUTDIR=.\temp/Debug/Unicode +INTDIR=.\temp/Debug/Unicode +# Begin Custom Macros +OutDir=.\temp/Debug/Unicode +# End Custom Macros + +ALL : "..\Miranda IM\Unicode\Plugins\shutdown.dll" "$(OUTDIR)\shutdown.bsc" + + +CLEAN : + -@erase "$(INTDIR)\cpuusage.obj" + -@erase "$(INTDIR)\cpuusage.sbr" + -@erase "$(INTDIR)\frame.obj" + -@erase "$(INTDIR)\frame.sbr" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\main.sbr" + -@erase "$(INTDIR)\options.obj" + -@erase "$(INTDIR)\options.sbr" + -@erase "$(INTDIR)\resource.res" + -@erase "$(INTDIR)\settingsdlg.obj" + -@erase "$(INTDIR)\settingsdlg.sbr" + -@erase "$(INTDIR)\shutdownsvc.obj" + -@erase "$(INTDIR)\shutdownsvc.sbr" + -@erase "$(INTDIR)\utils.obj" + -@erase "$(INTDIR)\utils.sbr" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(INTDIR)\watcher.obj" + -@erase "$(INTDIR)\watcher.sbr" + -@erase "$(OUTDIR)\shutdown.bsc" + -@erase "$(OUTDIR)\shutdown.exp" + -@erase "$(OUTDIR)\shutdown.map" + -@erase "..\Miranda IM\Unicode\Plugins\shutdown.dll" + -@erase "..\Miranda IM\Unicode\Plugins\shutdown.ilk" + -@erase "..\Miranda IM\Unicode\Plugins\shutdown.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /MTd /W4 /Gm /Gi /GR /GX /ZI /Od /I ".\include" /D "_DEBUG" /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "STRICT" /D "SHUTDOWN_EXPORTS" /U "_MBCS" /U "NO_STRICT" /FR"$(INTDIR)\\" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\resource.res" /i ".\include" /d "_DEBUG" /d "_UNICODE" /d "UNICODE" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\shutdown.bsc" +BSC32_SBRS= \ + "$(INTDIR)\cpuusage.sbr" \ + "$(INTDIR)\frame.sbr" \ + "$(INTDIR)\main.sbr" \ + "$(INTDIR)\options.sbr" \ + "$(INTDIR)\settingsdlg.sbr" \ + "$(INTDIR)\shutdownsvc.sbr" \ + "$(INTDIR)\utils.sbr" \ + "$(INTDIR)\watcher.sbr" + +"$(OUTDIR)\shutdown.bsc" : "$(OUTDIR)" $(BSC32_SBRS) + $(BSC32) @<< + $(BSC32_FLAGS) $(BSC32_SBRS) +<< + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib comctl32.lib gdi32.lib user32.lib shell32.lib advapi32.lib /nologo /base:"0x11070000" /dll /incremental:yes /pdb:"C:/Dokumente und Einstellungen/bib-nutzer/Desktop/Miranda IM/Unicode/Plugins/shutdown.pdb" /map:"$(INTDIR)\shutdown.map" /debug /machine:I386 /nodefaultlib:"uuid.lib" /nodefaultlib:"OLDNAMES" /def:"shutdown.def" /out:"C:/Dokumente und Einstellungen/bib-nutzer/Desktop/Miranda IM/Unicode/Plugins/shutdown.dll" /implib:"$(OUTDIR)\shutdown.lib" /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\cpuusage.obj" \ + "$(INTDIR)\frame.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\options.obj" \ + "$(INTDIR)\settingsdlg.obj" \ + "$(INTDIR)\shutdownsvc.obj" \ + "$(INTDIR)\utils.obj" \ + "$(INTDIR)\watcher.obj" \ + "$(INTDIR)\resource.res" + +"..\Miranda IM\Unicode\Plugins\shutdown.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("shutdown.dep") +!INCLUDE "shutdown.dep" +!ELSE +!MESSAGE Warning: cannot find "shutdown.dep" +!ENDIF +!ENDIF + + +!IF "$(CFG)" == "shutdown - Win32 Release" || "$(CFG)" == "shutdown - Win32 Debug" || "$(CFG)" == "shutdown - Win32 Release Unicode" || "$(CFG)" == "shutdown - Win32 Debug Unicode" +SOURCE=.\cpuusage.c + +"$(INTDIR)\cpuusage.obj" "$(INTDIR)\cpuusage.sbr" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\frame.c + +"$(INTDIR)\frame.obj" "$(INTDIR)\frame.sbr" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\main.c + +"$(INTDIR)\main.obj" "$(INTDIR)\main.sbr" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\options.c + +"$(INTDIR)\options.obj" "$(INTDIR)\options.sbr" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\settingsdlg.c + +"$(INTDIR)\settingsdlg.obj" "$(INTDIR)\settingsdlg.sbr" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\shutdownsvc.c + +"$(INTDIR)\shutdownsvc.obj" "$(INTDIR)\shutdownsvc.sbr" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\utils.c + +"$(INTDIR)\utils.obj" "$(INTDIR)\utils.sbr" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\watcher.c + +"$(INTDIR)\watcher.obj" "$(INTDIR)\watcher.sbr" : $(SOURCE) "$(INTDIR)" + + +SOURCE=.\resource.rc + +"$(INTDIR)\resource.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + + +!ENDIF + diff --git a/plugins/AutoShutdown/shutdownsvc.c b/plugins/AutoShutdown/shutdownsvc.c new file mode 100644 index 0000000000..2b519cc512 --- /dev/null +++ b/plugins/AutoShutdown/shutdownsvc.c @@ -0,0 +1,624 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "common.h" + +/* Shutdown Dialog */ +static HWND hwndShutdownDlg; +extern HINSTANCE hInst; +/* Services */ +static HANDLE hEventOkToShutdown,hEventShutdown; +static HANDLE hServiceShutdown,hServiceIsTypeEnabled,hServiceGetTypeDesc; + +/************************* Utils **************************************/ + +static BOOL WinNT_SetPrivilege(TCHAR *pszPrivName,BOOL bEnable) +{ + BOOL bReturn=FALSE; + HANDLE hToken; + TOKEN_PRIVILEGES tkp; + /* get a token for this process */ + if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken)) { + tkp.PrivilegeCount=1; /* one privilege is to set */ + /* get the LUID for the shutdown privilege */ + if(LookupPrivilegeValue(NULL,pszPrivName,&tkp.Privileges[0].Luid)) { + tkp.Privileges[0].Attributes=bEnable?SE_PRIVILEGE_ENABLED:0; + /* get the shutdown privilege for this process */ + bReturn=AdjustTokenPrivileges(hToken,FALSE,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0); + } + CloseHandle(hToken); + } + return bReturn; +} + +static void BroadcastEndSession(DWORD dwRecipients,LPARAM lParam) +{ + LONG (WINAPI *pfnBroadcastSystemMessage)(DWORD,DWORD*,UINT,WPARAM,LPARAM); +#if defined(_UNICODE) + *(PROC*)&pfnBroadcastSystemMessage=GetProcAddress(GetModuleHandleA("USER32"),"BroadcastSystemMessageW"); +#else + *(PROC*)&pfnBroadcastSystemMessage=GetProcAddress(GetModuleHandleA("USER32"),"BroadcastSystemMessageA"); + if(!pfnBroadcastSystemMessage) /* Win95 has undecorated API */ + *(PROC*)&pfnBroadcastSystemMessage=GetProcAddress(GetModuleHandleA("USER32"),"BroadcastSystemMessage"); +#endif + if(pfnBroadcastSystemMessage) + pfnBroadcastSystemMessage(BSF_FORCEIFHUNG,&dwRecipients,WM_ENDSESSION,TRUE,lParam); +} + +static BOOL WinNT_IsWorkStationLocked(void) +{ + HDESK hDesk; + TCHAR szName[8]; + DWORD cbName; + BOOL bLocked; + hDesk=OpenInputDesktop(0,FALSE,DESKTOP_READOBJECTS); + if(hDesk==NULL) return TRUE; + bLocked=(!GetUserObjectInformation(hDesk,UOI_NAME,szName,SIZEOF(szName),&cbName) || lstrcmpi(szName,_T("default"))!=0); + CloseDesktop(hDesk); + return bLocked; +} + +#if !defined(_UNICODE) +static void Win9x_TerminateExplorer(void) +{ + HANDLE hProcess; + DWORD idProcess; + if(GetWindowThreadProcessId(GetDesktopWindow(),&idProcess)) { + hProcess=OpenProcess(PROCESS_TERMINATE,FALSE,idProcess); + if(hProcess!=NULL) { + TerminateProcess(hProcess,0); + CloseHandle(hProcess); + } + } +} +#endif + +/************************* Workers ************************************/ + +static BOOL IsShutdownTypeEnabled(BYTE shutdownType) +{ + BOOL bReturn=FALSE; + switch(shutdownType) { + case SDSDT_HIBERNATE: + case SDSDT_STANDBY: + { HMODULE hPowerDLL=LoadLibraryA("POWRPROF"); /* all ascii */ + if(hPowerDLL!=NULL) { + BOOLEAN (STDAPICALLTYPE *pfnIsPwrModeAllowed)(void); + *(PROC*)&pfnIsPwrModeAllowed=GetProcAddress(hPowerDLL,(shutdownType==SDSDT_HIBERNATE)?"IsPwrHibernateAllowed":"IsPwrSuspendAllowed"); + if(pfnIsPwrModeAllowed) bReturn=pfnIsPwrModeAllowed()!=0; + FreeLibrary(hPowerDLL); + } + } + /* test privilege */ + if(bReturn && IsWinVerNT()) { + bReturn=WinNT_SetPrivilege(SE_SHUTDOWN_NAME,TRUE); + if(bReturn) WinNT_SetPrivilege(SE_SHUTDOWN_NAME,FALSE); + } + break; + case SDSDT_LOGOFF: + { HKEY hKey; + DWORD dwSetting,dwSize; + /* NoLogOff is BINARY on Win9x/ME and DWORD on Win2000+ */ + bReturn=TRUE; + if(RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"),0,KEY_QUERY_VALUE,&hKey)==ERROR_SUCCESS) { + dwSize=sizeof(dwSetting); + if(RegQueryValueEx(hKey,_T("NoLogOff"),0,NULL,(void*)&dwSetting,&dwSize)==ERROR_SUCCESS) + if(dwSetting) bReturn=FALSE; + RegCloseKey(hKey); + } + } + break; + case SDSDT_LOCKWORKSTATION: + { void (WINAPI *pfnLockWorkStation)(void); + *(PROC*)&pfnLockWorkStation=GetProcAddress(GetModuleHandleA("USER32"),"LockWorkStation"); + if(pfnLockWorkStation) { + HKEY hKey; + DWORD dwSize,dwSetting; + /* DisableLockWorkstation is DWORD on Win2000+ */ + bReturn=TRUE; + if(RegOpenKeyEx(HKEY_CURRENT_USER,_T("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"),0,KEY_QUERY_VALUE,&hKey)==ERROR_SUCCESS) { + dwSize=sizeof(dwSetting); + if(!RegQueryValueEx(hKey,_T("DisableLockWorkstation"),0,NULL,(void*)&dwSetting,&dwSize)) + if(dwSetting) bReturn=FALSE; + RegCloseKey(hKey); + } + } + else if(IsWinVerNT()) /* for WinNT4 */ + bReturn=SearchPath(NULL,_T("LOGIN.SCR"),NULL,0,NULL,NULL)!=0; + } + break; + case SDSDT_CLOSERASCONNECTIONS: + /* check if RAS installed/available */ + bReturn=SearchPath(NULL,_T("RASAPI32"),_T(".DLL"),0,NULL,NULL)!=0; + break; + case SDSDT_SETMIRANDAOFFLINE: + case SDSDT_CLOSEMIRANDA: + bReturn=TRUE; /* always possible */ + break; + case SDSDT_REBOOT: + case SDSDT_SHUTDOWN: + /* test privileges */ + if(IsWinVerNT()) { + bReturn=WinNT_SetPrivilege(SE_SHUTDOWN_NAME,TRUE); + if(bReturn) WinNT_SetPrivilege(SE_SHUTDOWN_NAME,FALSE); + } + else bReturn=TRUE; + break; + } + return bReturn; +} + +static DWORD ShutdownNow(BYTE shutdownType) +{ + DWORD dwErrCode=ERROR_SUCCESS; + switch(shutdownType) { + case SDSDT_CLOSEMIRANDA: + if(!Miranda_Terminated()) { + /* waiting for short until ready (but not too long...) */ + DWORD dwLastTickCount=GetTickCount(); + while(!CallService(MS_SYSTEM_OKTOEXIT,0,0)) { + /* infinite loop protection (max 5 sec) */ + if(GetTickCount()-dwLastTickCount>=5000) { /* wraparound works */ + OutputDebugStringA("Timeout (5 sec)\n"); /* tell others, all ascii */ + break; + } + SleepEx(1000,TRUE); + if(Miranda_Terminated()) break; /* someone else did it */ + OutputDebugStringA("Not ready to exit. Waiting...\n"); /* tell others, all ascii */ + } + /* shutdown service must be called from main thread anyway */ + if(!DestroyWindow((HWND)CallService(MS_CLUI_GETHWND,0,0))) + dwErrCode=GetLastError(); + } + break; + case SDSDT_SETMIRANDAOFFLINE: + /* set global status mode to offline (is remembered by Miranda on exit) */ + CallService(MS_CLIST_SETSTATUSMODE,(WPARAM)ID_STATUS_OFFLINE,(LPARAM)NULL); + break; + case SDSDT_STANDBY: + case SDSDT_HIBERNATE: + WinNT_SetPrivilege(SE_SHUTDOWN_NAME,TRUE); + if(!SetSystemPowerState(shutdownType==SDSDT_STANDBY,TRUE)) + dwErrCode=GetLastError(); + WinNT_SetPrivilege(SE_SHUTDOWN_NAME,FALSE); + break; + case SDSDT_LOCKWORKSTATION: + { BOOL (WINAPI *pfnLockWorkStation)(void); + *(PROC*)&pfnLockWorkStation=GetProcAddress(GetModuleHandleA("USER32"),"LockWorkStation"); + if(pfnLockWorkStation!=NULL) /* Win2000+ */ + if(!pfnLockWorkStation() && !WinNT_IsWorkStationLocked()) + dwErrCode=GetLastError(); + else if(IsWinVerNT()) { /* WinNT4 */ + HKEY hKey; + /* start LOGON.SCR screensaver (locks workstation on NT4) */ + if(!SearchPath(NULL,_T("LOGIN.SCR"),NULL,0,NULL,NULL)) { + if(RegCreateKeyEx(HKEY_CURRENT_USER,_T("Control Panel\\Desktop"),0,NULL,REG_OPTION_VOLATILE,KEY_QUERY_VALUE|KEY_SET_VALUE,NULL,&hKey,NULL)==ERROR_SUCCESS) { + TCHAR szScreenSaveActive[2],szScreenSaverIsSecure[2],szScrnsaveExe[MAX_PATH]; + DWORD dwSize; + /* save old settings */ + dwSize=sizeof(szScreenSaveActive); /* in bytes */ + ZeroMemory(&szScreenSaveActive,dwSize); + RegQueryValueEx(hKey,_T("ScreenSaveActive"),0,NULL,(void*)szScreenSaveActive,&dwSize); + dwSize=sizeof(szScreenSaverIsSecure); /* in bytes */ + ZeroMemory(&szScreenSaverIsSecure, dwSize); + RegQueryValueEx(hKey,_T("ScreenSaverIsSecure"),0,NULL,(void*)szScreenSaverIsSecure,&dwSize); + dwSize=sizeof(szScrnsaveExe); /* in bytes */ + ZeroMemory(&szScrnsaveExe,dwSize); + RegQueryValueEx(hKey,_T("SCRNSAVE.EXE"),0,NULL,(void*)szScrnsaveExe,&dwSize); + /* set LOGON.SCR data */ + if(!RegSetValueEx(hKey,_T("ScreenSaveActive"),0,REG_SZ,(void*)_T("1"),2) && + !RegSetValueEx(hKey,_T("ScreenSaverIsSecure"),0,REG_SZ,(void*)"1",2) && + !RegSetValueEx(hKey,_T("SCRNSAVE.EXE"),0,REG_SZ,(void*)_T("LOGIN.SCR"),10)) + SendMessage(GetForegroundWindow(),WM_SYSCOMMAND,SC_SCREENSAVE,0); + else dwErrCode=GetLastError(); + /* restore old settings */ + RegSetValueEx(hKey,_T("ScreenSaveActive"),0,REG_SZ,(void*)szScreenSaveActive,(lstrlen(szScreenSaveActive)+1)*sizeof(TCHAR)); + RegSetValueEx(hKey,_T("ScreenSaverIsSecure"),0,REG_SZ,(void*)szScreenSaverIsSecure,(lstrlen(szScreenSaverIsSecure)+1)*sizeof(TCHAR)); + RegSetValueEx(hKey,_T("SCRNSAVE.EXE"),0,REG_SZ,(void*)szScrnsaveExe,(lstrlen(szScrnsaveExe)+1)*sizeof(TCHAR)); + RegCloseKey(hKey); + } else dwErrCode=GetLastError(); + } else dwErrCode=GetLastError(); + } else dwErrCode=GetLastError(); + } + break; + case SDSDT_CLOSERASCONNECTIONS: + ShutdownNow(SDSDT_SETMIRANDAOFFLINE); /* set Miranda offline */ + /* hang up all ras connections */ + { HMODULE hRasApiDLL=LoadLibrary(_T("RASAPI32")); /* all ascii */ + if(hRasApiDLL!=NULL) { + DWORD (APIENTRY *pfnRasEnumConnections)(RASCONN*,DWORD*,DWORD*); + DWORD (APIENTRY *pfnRasHangUp)(HRASCONN); + DWORD (APIENTRY *pfnRasGetConnectStatus)(HRASCONN,RASCONNSTATUS*); + #if defined(_UNICODE) + *(PROC*)&pfnRasEnumConnections=GetProcAddress(hRasApiDLL,"RasEnumConnectionsW"); + *(PROC*)&pfnRasHangUp=GetProcAddress(hRasApiDLL,"RasHangUpW"); + *(PROC*)&pfnRasGetConnectStatus=GetProcAddress(hRasApiDLL,"RasGetConnectStatusW"); + #else + *(PROC*)&pfnRasEnumConnections=GetProcAddress(hRasApiDLL,"RasEnumConnectionsA"); + *(PROC*)&pfnRasHangUp=GetProcAddress(hRasApiDLL,"RasHangUpA"); + *(PROC*)&pfnRasGetConnectStatus=GetProcAddress(hRasApiDLL,"RasGetConnectStatusA"); + #endif + if(pfnRasEnumConnections && pfnRasGetConnectStatus && pfnRasHangUp) { + RASCONN *paConn; + RASCONN *paConnBuf; + DWORD dwConnSize,dwConnItems,dwRetries; + RASCONNSTATUS rcs; + DWORD dw,dwLastTickCount; + + dwConnSize=sizeof(RASCONN); + dwConnItems=0; + paConn=(RASCONN*)mir_alloc(dwConnSize); + dwErrCode=ERROR_NOT_ENOUGH_MEMORY; + if(paConn!=NULL) + for(dwRetries=5;dwRetries!=0;dwRetries--) { /* prevent infinite loop (rare) */ + ZeroMemory(paConn,dwConnSize); + paConn[0].dwSize=sizeof(RASCONN); + dwErrCode=pfnRasEnumConnections(paConn,&dwConnSize,&dwConnItems); + if(dwErrCode!=ERROR_BUFFER_TOO_SMALL) break; + paConnBuf=(RASCONN*)mir_realloc(paConn,dwConnSize); + if(paConnBuf!=NULL) { + mir_free(paConn); + paConn=NULL; + dwErrCode=ERROR_NOT_ENOUGH_MEMORY; + break; + } + paConn=paConnBuf; + } + if(dwErrCode==ERROR_SUCCESS || dwErrCode==ERROR_BUFFER_TOO_SMALL) { + for(dw=0;dw3000) break; /* wraparound works */ + } + } + mir_free(paConn); /* does NULL check */ + } else dwErrCode=GetLastError(); + FreeLibrary(hRasApiDLL); + } else dwErrCode=GetLastError(); + } + /* set Miranda to offline again, to remain offline with reconnection plugins */ + ShutdownNow(SDSDT_SETMIRANDAOFFLINE); + break; + case SDSDT_REBOOT: + case SDSDT_SHUTDOWN: + if(GetSystemMetrics(SM_SHUTTINGDOWN)) { /* Win2000+, 0 on error */ + dwErrCode=ERROR_SHUTDOWN_IN_PROGRESS; + break; + } + /* WinNT4/2000/XP */ + { BOOL (WINAPI *pfnInitiateSystemShutdownEx)(const TCHAR*,const TCHAR*,DWORD,BOOL,BOOL,DWORD); + BOOL (WINAPI *pfnInitiateSystemShutdown)(const TCHAR*,const TCHAR*,DWORD,BOOL,BOOL); + #if defined(_UNICODE) + *(PROC*)&pfnInitiateSystemShutdownEx=GetProcAddress(GetModuleHandleA("ADVAPI32"),"InitiateSystemShutdownExW"); + *(PROC*)&pfnInitiateSystemShutdown=GetProcAddress(GetModuleHandleA("ADVAPI32"),"InitiateSystemShutdownW"); + #else + *(PROC*)&pfnInitiateSystemShutdownEx=GetProcAddress(GetModuleHandleA("ADVAPI32"),"InitiateSystemShutdownExA"); + *(PROC*)&pfnInitiateSystemShutdown=GetProcAddress(GetModuleHandleA("ADVAPI32"),"InitiateSystemShutdownA"); + #endif + if(pfnInitiateSystemShutdownEx!=NULL || pfnInitiateSystemShutdown!=NULL) { + WinNT_SetPrivilege(SE_SHUTDOWN_NAME,TRUE); + + /* does not send out WM_ENDSESSION messages, so we do it manually to + * give the applications the chance to save their data */ + WinNT_SetPrivilege(SE_TCB_NAME,TRUE); /* for BSM_ALLDESKTOPS */ + BroadcastEndSession(BSM_APPLICATIONS|BSM_ALLDESKTOPS,ENDSESSION_CLOSEAPP); /* app should close itself */ + WinNT_SetPrivilege(SE_TCB_NAME,FALSE); + + if(pfnInitiateSystemShutdownEx!=NULL) { + if(!pfnInitiateSystemShutdownEx(NULL,TranslateT("AutoShutdown"),0,TRUE,shutdownType==SDSDT_REBOOT,SHTDN_REASON_MAJOR_OTHER|SHTDN_REASON_MINOR_OTHER|SHTDN_REASON_FLAG_PLANNED)) + dwErrCode=GetLastError(); + } else if(!pfnInitiateSystemShutdown(NULL,TranslateT("AutoShutdown"),0,TRUE,shutdownType==SDSDT_REBOOT)) + dwErrCode=GetLastError(); + + /* cleanly close Miranda */ + if(!dwErrCode) ShutdownNow(SDSDT_CLOSEMIRANDA); + break; + } + } + /* fall through for Win9x */ + case SDSDT_LOGOFF: + { UINT flags; + switch(shutdownType) { + case SDSDT_LOGOFF: flags=EWX_LOGOFF; break; + case SDSDT_REBOOT: flags=EWX_REBOOT; break; + default: flags=EWX_SHUTDOWN|EWX_POWEROFF; + } + if(shutdownType==SDSDT_LOGOFF && IsWinVer2000Plus() && !WinNT_IsWorkStationLocked()) + flags|=EWX_FORCEIFHUNG; /* only considered for WM_ENDSESSION messages */ + else flags|=EWX_FORCE; /* must be used when workstation locked */ + + if(flags&EWX_FORCE) { + /* EWX_FORCE does not send out WM_ENDSESSION messages, so we do it + * manually to give the applications the chance to save their data */ + BroadcastEndSession(BSM_APPLICATIONS,(shutdownType==SDSDT_LOGOFF)?ENDSESSION_LOGOFF:0); + + /* Windows Me/98/95 (msdn): Because of the design of the shell, + * calling ExitWindowsEx with EWX_FORCE fails to completely log off + * the user (the system terminates the applications and displays the + * Enter Windows Password dialog box, however, the user's desktop remains.) + * To log off the user forcibly, terminate the Explorer process before calling + * ExitWindowsEx with EWX_LOGOFF and EWX_FORCE. */ + #if !defined(_UNICODE) + if(shutdownType==SDSDT_LOGOFF && !IsWinVerNT()) Win9x_TerminateExplorer(); + #endif + } + if(!ExitWindowsEx(flags,SHTDN_REASON_MAJOR_OTHER|SHTDN_REASON_MINOR_OTHER|SHTDN_REASON_FLAG_PLANNED)) + dwErrCode=GetLastError(); + /* cleanly close Miranda */ + if(!dwErrCode) ShutdownNow(SDSDT_CLOSEMIRANDA); + } + break; + } + return dwErrCode; +} + +/************************* Shutdown Dialog ****************************/ + +#define M_START_SHUTDOWN (WM_APP+111) +#define M_UPDATE_COUNTDOWN (WM_APP+112) +static BOOL CALLBACK ShutdownDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) +{ + BYTE shutdownType=(BYTE)GetWindowLong(hwndDlg,DWL_USER); + WORD countdown=(WORD)GetWindowLong(GetDlgItem(hwndDlg,IDC_TEXT_HEADER),GWL_USERDATA); + static BOOL (WINAPI *pfnLockSetForegroundWindow)(UINT); + + switch(msg) { + case WM_INITDIALOG: + hwndShutdownDlg=hwndDlg; + SetWindowLong(hwndDlg,DWL_USER,(LONG)lParam); + TranslateDialogDefault(hwndDlg); + + if(lParam==SDSDT_SHUTDOWN || lParam==SDSDT_REBOOT || lParam==SDSDT_LOGOFF) + ShowWindow(GetDlgItem(hwndDlg,IDC_TEXT_UNSAVEDWARNING),SW_SHOW); + SendDlgItemMessage(hwndDlg,IDC_ICON_HEADER,STM_SETIMAGE,IMAGE_ICON,(LPARAM)IcoLib_GetIcon("AutoShutdown_Header")); + { HFONT hBoldFont; + LOGFONT lf; + if(GetObject((HFONT)SendDlgItemMessage(hwndDlg,IDC_TEXT_HEADER,WM_GETFONT,0,0),sizeof(lf),&lf)) { + lf.lfWeight=FW_BOLD; + hBoldFont=CreateFontIndirect(&lf); + } + else hBoldFont=NULL; + SendDlgItemMessage(hwndDlg,IDC_TEXT_HEADER,WM_SETFONT,(WPARAM)hBoldFont,FALSE); + SetWindowLong(GetDlgItem(hwndDlg,IDC_TEXT_HEADER),GWL_USERDATA,(LONG)hBoldFont); + } + { WORD countdown=DBGetContactSettingWord(NULL,"AutoShutdown","ConfirmDlgCountdown",SETTING_CONFIRMDLGCOUNTDOWN_DEFAULT); + if(countdown<3) countdown=SETTING_CONFIRMDLGCOUNTDOWN_DEFAULT; + SetWindowLong(GetDlgItem(hwndDlg,IDC_TEXT_HEADER),GWL_USERDATA,countdown); + SendMessage(hwndDlg,M_UPDATE_COUNTDOWN,0,countdown); + } + SkinPlaySound("AutoShutdown_Countdown"); + if(!SetTimer(hwndDlg,1,1000,NULL)) PostMessage(hwndDlg,M_START_SHUTDOWN,0,0); + Utils_RestoreWindowPositionNoSize(hwndDlg,NULL,"AutoShutdown","ConfirmDlg_"); + + /* disallow foreground window changes (WinMe/2000+) */ + SetForegroundWindow(hwndDlg); + *(PROC*)&pfnLockSetForegroundWindow=GetProcAddress(GetModuleHandleA("USER32"),"LockSetForegroundWindow"); + if(pfnLockSetForegroundWindow!=NULL) + pfnLockSetForegroundWindow(LSFW_LOCK); + + SendMessage(hwndDlg,WM_NEXTDLGCTL,(WPARAM)GetDlgItem(hwndDlg,IDCANCEL),TRUE); + return FALSE; /* focus set on cancel */ + case WM_DESTROY: + { HFONT hFont; + HICON hIcon; + hwndShutdownDlg=NULL; + ShowWindow(hwndDlg,SW_HIDE); + /* reallow foreground window changes (WinMe/2000+) */ + if(pfnLockSetForegroundWindow) pfnLockSetForegroundWindow(LSFW_UNLOCK); + Utils_SaveWindowPosition(hwndDlg,NULL,"AutoShutdown","ConfirmDlg_"); + hIcon=(HICON)SendDlgItemMessage(hwndDlg,IDC_ICON_HEADER,STM_SETIMAGE,IMAGE_ICON,(LPARAM)NULL); + IcoLib_ReleaseIcon(hIcon); /* does NULL check */ + hFont=(HFONT)SendDlgItemMessage(hwndDlg,IDC_TEXT_HEADER,WM_GETFONT,0,0); + SendDlgItemMessage(hwndDlg,IDC_TEXT_HEADER,WM_SETFONT,(WPARAM)NULL,FALSE); /* no return value */ + if(hFont!=NULL) DeleteObject(hFont); + return TRUE; + } + case M_START_SHUTDOWN: + if(IsWindowEnabled(GetDlgItem(hwndDlg,IDC_BUTTON_SHUTDOWNNOW))) { + DWORD dwErrCode; + EnableWindow(GetDlgItem(hwndDlg,IDC_BUTTON_SHUTDOWNNOW),FALSE); + ShowWindow(hwndDlg,SW_HIDE); /* get rid of the dialog immediately */ + dwErrCode=ShutdownNow(shutdownType); + if(dwErrCode!=ERROR_SUCCESS) { + char *pszErr; + pszErr=GetWinErrorDescription(dwErrCode); + ShowInfoMessage(NIIF_ERROR,Translate("Automatic Shutdown Error"),Translate("The shutdown process failed!\nReason: %s"),(pszErr!=NULL)?pszErr:Translate("Unknown")); + if(pszErr!=NULL) LocalFree(pszErr); + } + DestroyWindow(hwndDlg); + } + return TRUE; + case WM_TIMER: + if(countdown) { + --countdown; + SetWindowLong(GetDlgItem(hwndDlg,IDC_TEXT_HEADER),GWL_USERDATA,countdown); + if(countdown==27 || countdown==24 || countdown==21 || countdown==19 || + countdown==17 || countdown==15 || countdown==13 || countdown==11 || + countdown<=10) + SkinPlaySound("AutoShutdown_Countdown"); + } + else KillTimer(hwndDlg,wParam); /* countdown finished */ + PostMessage(hwndDlg,M_UPDATE_COUNTDOWN,0,countdown); + return TRUE; + case M_UPDATE_COUNTDOWN: /* lParam=(WORD)countdown */ + { TCHAR szText[256]; + TCHAR *desc[]={_T("Miranda IM is going to be automatically closed in %u second(s)."), + _T("All Miranda IM protocols are going to be set to offline in %u second(s)."), + _T("You will be logged off automatically in %u second(s)."), + _T("The computer will automatically be restarted in %u second(s)."), + _T("The computer will automatically be set to standby mode in %u second(s)."), + _T("The computer will automatically be set to hibernate mode in %u second(s)."), + _T("The workstation will automatically get locked in %u second(s)."), + _T("All dialup connections will be closed in %u second(s)."), + _T("The computer will automatically be shut down in %u second(s).")}; + mir_sntprintf(szText,SIZEOF(szText),TranslateTS(desc[shutdownType-1]),lParam); + SetDlgItemText(hwndDlg,IDC_TEXT_HEADER,szText); + /* countdown finished */ + if(!lParam) PostMessage(hwndDlg,M_START_SHUTDOWN,0,0); + return TRUE; + } + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_BUTTON_SHUTDOWNNOW: + KillTimer(hwndDlg,1); + SetWindowLong(GetDlgItem(hwndDlg,IDC_TEXT_HEADER),GWL_USERDATA,0); + SendMessage(hwndDlg,M_UPDATE_COUNTDOWN,0,(LONG)0); + PostMessage(hwndDlg,M_START_SHUTDOWN,0,0); + return TRUE; + case IDCANCEL: /* WM_CLOSE */ + if(countdown) { + KillTimer(hwndDlg,1); + DestroyWindow(hwndDlg); + } + return TRUE; + } + break; + } + return FALSE; +} + +/************************* Services ***********************************/ + +int ServiceShutdown(WPARAM wParam,LPARAM lParam) +{ + /* passing 0 as wParam is only to be used internally, undocumented */ + if(!wParam) wParam=DBGetContactSettingByte(NULL,"AutoShutdown","ShutdownType",SETTING_SHUTDOWNTYPE_DEFAULT); + if(!IsShutdownTypeEnabled((BYTE)wParam)) return 1; /* does shutdownType range check */ + if((BOOL)lParam && hwndShutdownDlg!=NULL) return 2; + + /* ask others if allowed */ + if(NotifyEventHooks(hEventOkToShutdown,wParam,lParam)) { + OutputDebugStringA("automatic shutdown denied by event hook\n"); /* all ascii */ + return 3; + } + /* tell others */ + NotifyEventHooks(hEventShutdown,wParam,lParam); + /* show dialog */ + if(lParam && DBGetContactSettingByte(NULL,"AutoShutdown","ShowConfirmDlg",SETTING_SHOWCONFIRMDLG_DEFAULT)) + if(CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_SHUTDOWNNOW),NULL,ShutdownDlgProc,(LPARAM)(BYTE)wParam)!=NULL) + return 0; + /* show error */ + { DWORD dwErrCode; + dwErrCode=ShutdownNow((BYTE)wParam); + if(dwErrCode!=ERROR_SUCCESS) { + char *pszErr; + pszErr=GetWinErrorDescription(dwErrCode); + ShowInfoMessage(NIIF_ERROR,Translate("Automatic Shutdown Error"),Translate("Inititiating the shutdown process failed!\nReason: %s"),(pszErr!=NULL)?pszErr:Translate("Unknown")); + if(pszErr!=NULL) LocalFree(pszErr); + return 4; + } + } + return 0; +} + +int ServiceIsTypeEnabled(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + return IsShutdownTypeEnabled((BYTE)wParam); /* does shutdownType range check */ +} + +int ServiceGetTypeDescription(WPARAM wParam,LPARAM lParam) +{ + TCHAR *pszDesc; + const TCHAR *apszShort[]={_T("Close Miranda IM"),_T("Set Miranda IM offline"),_T("Log off user"), + _T("Restart computer"),_T("Shutdown computer"),_T("Standby mode"),_T("Hibernate mode"), + _T("Lock workstation"),_T("Hang up dialup connections"),_T("Close Miranda IM"), + _T("Set Miranda IM offline"),_T("Log off user"),_T("Restart computer"),_T("Shutdown computer"), + _T("Standby mode"),_T("Hibernate mode"),_T("Lock workstation"),_T("Hang up dialup connections")}; + const TCHAR *apszLong[]={_T("Sets all Miranda IM protocols to offline and closes Miranda IM."), + _T("Sets all Miranda IM protocols to offline."), + _T("Logs the current Windows user off so that another user can log in."), + _T("Shuts down Windows and then restarts Windows."), + _T("Closes all running programs and shuts down Windows to a point at which it is safe to turn off the power."), + _T("Saves the current Windows session in memory and sets the system to suspend mode."), + _T("Saves the current Windows session on harddisc, so that the power can be turned off."), + _T("Locks the computer. To unlock the computer, you must log in."), + _T("Sets all protocols to offline and closes all RAS connections.")}; + /* shutdownType range check */ + if(!wParam || (BYTE)wParam>SDSDT_MAX) return (int)NULL; + /* select description */ + pszDesc=(TCHAR*)((lParam&GSTDF_LONGDESC)?apszLong:apszShort)[wParam-1]; + if(!(lParam&GSTDF_UNTRANSLATED)) pszDesc=TranslateTS(pszDesc); + /* convert as needed */ + #if defined(_UNICODE) + if(!(lParam&GSTDF_UNICODE)) { + static char szConvBuf[128]; + char *buf=u2a(pszDesc); + if(buf==NULL) return (int)NULL; + lstrcpynA(szConvBuf,buf,sizeof(szConvBuf)); + mir_free(buf); + return (int)szConvBuf; + } + #else + if(lParam&GSTDF_UNICODE) { + static WCHAR szConvBuf[128]; + WCHAR *buf=a2u(pszDesc); + if(buf==NULL) return (int)NULL; + lstrcpynW(szConvBuf,buf,SIZEOF(szConvBuf)); + mir_free(buf); + return (int)szConvBuf; + } + #endif + return (int)pszDesc; +} + +/************************* Misc ***************************************/ + +void InitShutdownSvc(void) +{ + /* Shutdown Dialog */ + hwndShutdownDlg=NULL; + SkinAddNewSoundBundled("AutoShutdown_Countdown",Translate("Alerts"),Translate("Automatic Shutdown Countdown"),"Sounds\\","countdown.wav"); + /* Services */ + hEventOkToShutdown=CreateHookableEvent(ME_AUTOSHUTDOWN_OKTOSHUTDOWN); + hEventShutdown=CreateHookableEvent(ME_AUTOSHUTDOWN_SHUTDOWN); + hServiceShutdown=CreateServiceFunction(MS_AUTOSHUTDOWN_SHUTDOWN,ServiceShutdown); + hServiceIsTypeEnabled=CreateServiceFunction(MS_AUTOSHUTDOWN_ISTYPEENABLED,ServiceIsTypeEnabled); + hServiceGetTypeDesc=CreateServiceFunction(MS_AUTOSHUTDOWN_GETTYPEDESCRIPTION,ServiceGetTypeDescription); +} + +void UninitShutdownSvc(void) +{ + /* Shutdown Dialog */ + if(hwndShutdownDlg!=NULL) DestroyWindow(hwndShutdownDlg); + /* Services */ + DestroyServiceFunction(hServiceShutdown); + DestroyServiceFunction(hServiceIsTypeEnabled); + DestroyServiceFunction(hServiceGetTypeDesc); + DestroyHookableEvent(hEventOkToShutdown); + DestroyHookableEvent(hEventShutdown); +} diff --git a/plugins/AutoShutdown/shutdownsvc.h b/plugins/AutoShutdown/shutdownsvc.h new file mode 100644 index 0000000000..412db18ee6 --- /dev/null +++ b/plugins/AutoShutdown/shutdownsvc.h @@ -0,0 +1,29 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* Services */ +int ServiceShutdown(WPARAM wParam,LPARAM lParam); +int ServiceIsTypeEnabled(WPARAM wParam,LPARAM lParam); +int ServiceGetTypeDescription(WPARAM wParam,LPARAM lParam); + +/* Misc */ +void InitShutdownSvc(void); +void UninitShutdownSvc(void); diff --git a/plugins/AutoShutdown/utils.c b/plugins/AutoShutdown/utils.c new file mode 100644 index 0000000000..b9bbddbc01 --- /dev/null +++ b/plugins/AutoShutdown/utils.c @@ -0,0 +1,458 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "common.h" + +/************************* String *********************************/ + +// mir_free() the return value +#if !defined(_UNICODE) +WCHAR* a2u(const char *pszAnsi) +{ + int codepage,cch; + WCHAR *psz; + + if(pszAnsi==NULL) return NULL; + codepage=CallService(MS_LANGPACK_GETCODEPAGE,0,0); + cch=MultiByteToWideChar(codepage,0,pszAnsi,-1,NULL,0); + if(!cch) return NULL; + + psz=(WCHAR*)mir_alloc(cch*sizeof(WCHAR)); + if(psz!=NULL && !MultiByteToWideChar(codepage,0,pszAnsi,-1,psz,cch)) { + mir_free(psz); + return NULL; + } + return psz; +} +#endif + +// mir_free() the return value +#if defined(_UNICODE) +char* u2a(const WCHAR *pszUnicode) +{ + int codepage,cch; + char *psz; + DWORD flags; + + if(pszUnicode==NULL) return NULL; + codepage=CallService(MS_LANGPACK_GETCODEPAGE,0,0); + /* without WC_COMPOSITECHECK some characters might get out strange (see MS blog) */ + cch=WideCharToMultiByte(codepage,flags=WC_COMPOSITECHECK,pszUnicode,-1,NULL,0,NULL,NULL); + if(!cch) cch=WideCharToMultiByte(codepage,flags=0,pszUnicode,-1,NULL,0,NULL,NULL); + if(!cch) return NULL; + + psz=(char*)mir_alloc(cch); + if(psz!=NULL && !WideCharToMultiByte(codepage,flags,pszUnicode,-1,psz,cch,NULL,NULL)){ + mir_free(psz); + return NULL; + } + return psz; +} +#endif + +void TrimString(TCHAR *pszStr) +{ + int i; + TCHAR *psz,szChars[]=_T(" \r\n\t"); + for(i=0;ilpszCaption); /* does NULL check */ + mir_free((char*)mbp->lpszText); /* does NULL check */ + mir_free(mbp); +} + +void ShowInfoMessage(BYTE flags,const char *pszTitle,const char *pszTextFmt,...) +{ + char szText[256]; /* max for systray */ + MSGBOXPARAMSA *mbp; + + va_list va; + va_start(va,pszTextFmt); + mir_vsnprintf(szText,SIZEOF(szText),pszTextFmt,va); + va_end(va); + + if(ServiceExists(MS_CLIST_SYSTRAY_NOTIFY)) { + MIRANDASYSTRAYNOTIFY msn; + msn.cbSize=sizeof(msn); + msn.szProto=NULL; + msn.szInfoTitle=(char*)pszTitle; + msn.szInfo=(char*)szText; + msn.uTimeout=30000; /* max timeout */ + msn.dwInfoFlags=flags; + if(!CallServiceSync(MS_CLIST_SYSTRAY_NOTIFY,0,(LPARAM)&msn)) + return; /* success */ + } + + mbp=(MSGBOXPARAMSA*)mir_calloc(sizeof(*mbp)); + if(mbp==NULL) return; + mbp->cbSize=sizeof(*mbp); + mbp->lpszCaption=mir_strdup(pszTitle); + mbp->lpszText=mir_strdup(szText); + mbp->dwStyle=MB_OK|MB_SETFOREGROUND|MB_TASKMODAL; + mbp->dwLanguageId=LANGIDFROMLCID((LCID)CallService(MS_LANGPACK_GETLOCALE,0,0)); + switch(flags&NIIF_ICON_MASK) { + case NIIF_INFO: mbp->dwStyle|=MB_ICONINFORMATION; break; + case NIIF_WARNING: mbp->dwStyle|=MB_ICONWARNING; break; + case NIIF_ERROR: mbp->dwStyle|=MB_ICONERROR; + } + mir_forkthread(MessageBoxIndirectFree,mbp); +} + +// LocalFree() the return value +char* GetWinErrorDescription(DWORD dwLastError) +{ + char *buf=NULL; + DWORD flags=FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM; + if(!FormatMessageA(flags,NULL,dwLastError,LANGIDFROMLCID((LCID)CallService(MS_LANGPACK_GETLOCALE,0,0)),(char*)&buf,0,NULL)) + if(GetLastError()==ERROR_RESOURCE_LANG_NOT_FOUND) + FormatMessageA(flags,NULL,dwLastError,0,(char*)&buf,0,NULL); + return buf; +} + +/************************* Time ***********************************/ + +BOOL SystemTimeToTimeStamp(SYSTEMTIME *st,time_t *timestamp) +{ + struct tm ts; + ts.tm_isdst=-1; /* daylight saving time (-1=compute) */ + ts.tm_sec=st->wSecond; /* 0-59 */ + ts.tm_min=st->wMinute; /* 0-59 */ + ts.tm_hour=st->wHour; /* 0-23 */ + ts.tm_mday=st->wDay; /* 1-31 */ + ts.tm_wday=st->wDayOfWeek; /* 0-6 (Sun-Sat) */ + ts.tm_mon=st->wMonth-1; /* 0-11 (Jan-Dec) */ + ts.tm_year=st->wYear-1900; /* current year minus 1900 */ + ts.tm_yday=0; /* 0-365 (Jan1=0) */ + *timestamp=mktime(&ts); + return (*timestamp!=-1); +} + +BOOL TimeStampToSystemTime(time_t timestamp,SYSTEMTIME *st) +{ + struct tm *ts; + ts=localtime(×tamp); /* statically alloced, local time correction */ + if(ts==NULL) return FALSE; + st->wMilliseconds=0; /* 0-999 (not given in tm) */ + st->wSecond=(WORD)ts->tm_sec; /* 0-59 */ + st->wMinute=(WORD)ts->tm_min; /* 0-59 */ + st->wHour=(WORD)ts->tm_hour; /* 0-23 */ + st->wDay=(WORD)ts->tm_mday; /* 1-31 */ + st->wDayOfWeek=(WORD)ts->tm_wday; /* 0-6 (Sun-Sat) */ + st->wMonth=(WORD)(ts->tm_mon+1); /* 1-12 (Jan-Dec) */ + st->wYear=(WORD)(ts->tm_year+1900); /* 1601-30827 */ + return TRUE; +} + +BOOL GetFormatedCountdown(TCHAR *pszOut,int nSize,time_t countdown) +{ + static BOOL fInited=FALSE; + static int (WINAPI *pfnStrFromTimeInterval)(TCHAR*,UINT,DWORD,int); + #if defined(_UNICODE) + static int (WINAPI *pfnGetDurationFormat)(LCID,DWORD,const SYSTEMTIME*,double,WCHAR*,WCHAR*,int); + #endif + /* Init */ + if(!fInited) { + #if defined(_UNICODE) + *(PROC*)&pfnGetDurationFormat=GetProcAddress(GetModuleHandleA("KERNEL32"),"GetDurationFormat"); + if(pfnGetDurationFormat==NULL) { + #endif + HMODULE hShlwDLL=LoadLibraryA("SHLWAPI"); /* all ascii */ + #if defined(_UNICODE) + *(PROC*)&pfnStrFromTimeInterval=GetProcAddress(hShlwDLL,"StrFromTimeIntervalW"); + #else + *(PROC*)&pfnStrFromTimeInterval=GetProcAddress(hShlwDLL,"StrFromTimeIntervalA"); + #endif + #if defined(_UNICODE) + } + #endif + fInited=TRUE; + } + /* WinVista */ + #if defined(_UNICODE) + if(pfnGetDurationFormat!=NULL) { + SYSTEMTIME st; + LCID locale; + locale=(LCID)CallService(MS_LANGPACK_GETLOCALE,0,0); + if(TimeStampToSystemTime(countdown,&st)) + if(pfnGetDurationFormat(locale,0,&st,0,NULL,pszOut,nSize)) + return TRUE; + return FALSE; + } + #endif + /* Win9x/NT/XP */ + if(pfnStrFromTimeInterval!=NULL) + return pfnStrFromTimeInterval(pszOut,nSize,(countdown>(MAXDWORD/1000))?MAXDWORD:(countdown*1000),10)!=0; + return FALSE; +} + +BOOL GetFormatedDateTime(TCHAR *pszOut,int nSize,time_t timestamp,BOOL fShowDateEvenToday) +{ + SYSTEMTIME st,stNow; + LCID locale; + locale=(LCID)CallService(MS_LANGPACK_GETLOCALE,0,0); + GetLocalTime(&stNow); + TimeStampToSystemTime(timestamp,&st); + /* today: no need to show the date */ + if(!fShowDateEvenToday && st.wDay==stNow.wDay && st.wMonth==stNow.wMonth && st.wYear==stNow.wYear) + return GetTimeFormat(locale,((st.wSecond==0)?TIME_NOSECONDS:0)|TIME_FORCE24HOURFORMAT,&st,NULL,pszOut,nSize)!=0; + /* show both date and time */ + { TCHAR szDate[128],szTime[128]; + if(!GetTimeFormat(locale,((st.wSecond==0)?TIME_NOSECONDS:0)|TIME_FORCE24HOURFORMAT,&st,NULL,szTime,SIZEOF(szTime))) + return FALSE; + if(!GetDateFormat(locale,DATE_SHORTDATE,&st,NULL,szDate,SIZEOF(szDate))) + return FALSE; + mir_sntprintf(pszOut,nSize,_T("%s %s"),szTime,szDate); + return TRUE; + } +} + +/************************* Fonts & Colors *************************/ + +int FontService_RegisterFont(const char *pszDbModule,const char *pszDbName,const TCHAR *pszSection,const TCHAR *pszDescription,int position,BOOL bAllowEffects,LOGFONT *plfDefault,COLORREF clrDefault) +{ + FontIDT fid; + ZeroMemory(&fid,sizeof(fid)); + fid.cbSize=sizeof(fid); + lstrcpynA(fid.dbSettingsGroup,pszDbModule,sizeof(fid.dbSettingsGroup)); /* buffer safe */ + lstrcpynA(fid.prefix,pszDbName,sizeof(fid.prefix)); /* buffer safe */ + lstrcpyn(fid.group,pszSection,SIZEOF(fid.group)); /* buffer safe */ + lstrcpyn(fid.name,pszDescription,SIZEOF(fid.name)); /* buffer safe */ + fid.flags=FIDF_ALLOWREREGISTER; + if(bAllowEffects) fid.flags|=FIDF_ALLOWEFFECTS; + fid.order=position; + if(plfDefault!=NULL) { + fid.flags|=FIDF_DEFAULTVALID; + fid.deffontsettings.colour=clrDefault; + fid.deffontsettings.size=(char)plfDefault->lfHeight; + if(plfDefault->lfItalic) fid.deffontsettings.style|=DBFONTF_ITALIC; + if(plfDefault->lfWeight!=FW_NORMAL) fid.deffontsettings.style|=DBFONTF_BOLD; + if(plfDefault->lfUnderline) fid.deffontsettings.style|=DBFONTF_UNDERLINE; + if(plfDefault->lfStrikeOut) fid.deffontsettings.style|=DBFONTF_STRIKEOUT; + fid.deffontsettings.charset=plfDefault->lfCharSet; + lstrcpyn(fid.deffontsettings.szFace,plfDefault->lfFaceName,SIZEOF(fid.deffontsettings.szFace)); /* buffer safe */ + } + return CallService(MS_FONT_REGISTERT,(WPARAM)&fid,(LPARAM)&fid); +} + +int FontService_GetFont(const TCHAR *pszSection,const TCHAR *pszDescription,COLORREF *pclr,LOGFONT *plf) +{ + FontIDT fid; + fid.cbSize=sizeof(fid); + lstrcpyn(fid.group,pszSection,SIZEOF(fid.group)); /* buffer sfae */ + lstrcpyn(fid.name,pszDescription,SIZEOF(fid.name)); /* buffer safe */ + *pclr=(COLORREF)CallService(MS_FONT_GETT,(WPARAM)&fid,(LPARAM)plf); /* uses fallback font on error */ + return (int)*pclr==-1; +} + +int FontService_RegisterColor(const char *pszDbModule,const char *pszDbName,const TCHAR *pszSection,const TCHAR *pszDescription,COLORREF clrDefault) +{ + ColourIDT cid; + ZeroMemory(&cid,sizeof(cid)); + cid.cbSize=sizeof(cid); + cid.defcolour=clrDefault; + lstrcpynA(cid.dbSettingsGroup,pszDbModule,sizeof(cid.dbSettingsGroup)); /* buffer safe */ + lstrcpynA(cid.setting,pszDbName,sizeof(cid.setting)); /* buffer safe */ + lstrcpyn(cid.group,pszSection,SIZEOF(cid.group)); /* buffer safe */ + lstrcpyn(cid.name,pszDescription,SIZEOF(cid.name)); /* buffer safe */ + return CallService(MS_COLOUR_REGISTERT,(WPARAM)&cid,0); +} + +int FontService_GetColor(const TCHAR *pszSection,const TCHAR *pszDescription,COLORREF *pclr) +{ + ColourIDT cid; + ZeroMemory(&cid,sizeof(cid)); + cid.cbSize=sizeof(cid); + lstrcpyn(cid.group,pszSection,sizeof(cid.group)); /* buffer safe */ + lstrcpyn(cid.name,pszDescription,sizeof(cid.name)); /* buffer safe */ + *pclr=(COLORREF)CallService(MS_COLOUR_GETT,(WPARAM)&cid,0); + return (int)*pclr==-1; +} + +/************************* Skin ***********************************/ + +HANDLE IcoLib_AddIconRes(const char *pszDbName,const TCHAR *pszSection,const TCHAR *pszDesc,HINSTANCE hInst,WORD idRes,BOOL fLarge) +{ + SKINICONDESC sid; + TCHAR szFileName[MAX_PATH]; + sid.cbSize=sizeof(SKINICONDESC); + sid.pszName=(char*)pszDbName; + sid.ptszSection=(TCHAR*)pszSection; + sid.ptszDescription=(TCHAR*)pszDesc; + sid.ptszDefaultFile=szFileName; + sid.iDefaultIndex=-idRes; + sid.cx=GetSystemMetrics(fLarge?SM_CXICON:SM_CXSMICON); + sid.cy=GetSystemMetrics(fLarge?SM_CYICON:SM_CYSMICON); + sid.hDefaultIcon=NULL; + sid.flags=SIDF_SORTED|SIDF_ALL_TCHAR; + if(!GetModuleFileName(hInst,szFileName,SIZEOF(szFileName))) + return NULL; + return (HANDLE)CallService(MS_SKIN2_ADDICON,0,(LPARAM)&sid); +} + +HICON IcoLib_GetIcon(const char *pszDbName) +{ + return (HICON)CallService(MS_SKIN2_GETICON,0,(LPARAM)pszDbName); +} + +int IcoLib_ReleaseIcon(HICON hIcon) +{ + return CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon,0); +} + +int SkinAddNewSoundBundled(const char *pszDbName,const char *pszSection,const char *pszDesc,const char *pszSubDir,const char *pszDefaultFile) +{ + SKINSOUNDDESCEX ssd; + char szFile[MAX_PATH],*p; + HANDLE hFile; + + ssd.cbSize=sizeof(ssd); + ssd.pszName=pszDbName; + ssd.pszSection=pszSection; + ssd.pszDescription=pszDesc; + ssd.pszDefaultFile=NULL; + if(GetModuleFileNameA(NULL,szFile,SIZEOF(szFile)-lstrlenA(pszSubDir)-lstrlenA(pszDefaultFile))) { + p=strrchr(szFile,'\\'); + if(p!=NULL) *(++p)=0; + lstrcatA(lstrcatA(szFile,pszSubDir),pszDefaultFile); /* buffer safe */ + /* check if sound file exist */ + hFile=CreateFileA(szFile,0,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); + if(hFile!=INVALID_HANDLE_VALUE) { + ssd.pszDefaultFile=szFile; /* MS_UTILS_PATHTORELATIVET called automatically */ + CloseHandle(hFile); + } + } + return CallService(MS_SKIN_ADDNEWSOUND,0,(LPARAM)&ssd); +} + +/* workaround for 'Hotkey Service' plugin because it has needs an event catcher */ +static char szHotkeyService[MAXMODULELABELLENGTH]; +static int moduleId,itemId; +static int HotkeysServiceHotkeyPressed(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + if(((THKSEvent*)wParam)->moduleId==moduleId && ((THKSEvent*)wParam)->itemId==LOWORD(itemId)) + CallService(szHotkeyService,0,0); + return 0; +} + +/* defines for 'Hotkey Manager' */ +#define HK_ACT_OVERWRITE 0 +#define HKF_GLOBAL 0x00000001 +#define HKF_WPARNUM 0x00000008 +#define HKF_HEX 0x00000200 +#define HKF_LCURRENT 0x00001000 +#define HKT_SERVICE 2 +typedef struct { + void *reserved1; + void *reserved2; + int hotkey; + WCHAR* descr; + DWORD flags; + ATOM reserved3; + DWORD _type; + char* service; + WPARAM wparam; + LPARAM lparam; +} HOTKEYREC; +#define MS_HK_ADDHOTKEY "HotKey/AddHotkey" + +int SkinAddNewHotkey(const char *pszDbName,const char *pszSection,const char *pszDescription,UINT vk,UINT hotkeyfModifiers,const char *pszServiceName) +{ + if(ServiceExists(MS_SKIN_ADDHOTKEY)) { /* clist_mw, clist_modern */ + SKINHOTKEYDESCEX shd; + ZeroMemory(&shd,sizeof(shd)); + shd.cbSize=sizeof(shd); + shd.pszName=(char*)pszDbName; + shd.pszDescription=(char*)pszDescription; + shd.pszSection=(char*)pszSection; + shd.pszService=(char*)pszServiceName; + shd.DefHotKey=MAKEWORD(vk,hotkeyfModifiers); + CallService(MS_SKIN_ADDHOTKEY,0,(LPARAM)&shd); + /* no return */ + } + if(ServiceExists(MS_HOTKEYSPLUS_ADDKEY)) /* 'Hotkeys Plus' */ + return CallService(MS_HOTKEYSPLUS_ADDKEY,(WPARAM)pszServiceName,(LPARAM)pszDescription); + if(ServiceExists(HKS_REGISTERFUNCTION)) { /* mHotKey */ + KEYHASH kh; + kh.isShift=(hotkeyfModifiers&HOTKEYF_SHIFT)!=0; + kh.isCtrl=(hotkeyfModifiers&HOTKEYF_CONTROL)!=0; + kh.isAlt=(hotkeyfModifiers&HOTKEYF_ALT)!=0; + kh.vkCode=vk; + return !CallService(HKS_REGISTERFUNCTION,(WPARAM)&kh,(LPARAM)pszServiceName); + } + if(ServiceExists(MS_HK_ADDHOTKEY)) { /* 'Hotkey Manager' */ + HOTKEYREC hkr; + ZeroMemory(&hkr,sizeof(hkr)); + hkr.hotkey=(int)MAKEWORD(vk,hotkeyfModifiers); + #if defined(_UNICODE) + hkr.descr=(WCHAR*)pszDescription; + #else + hkr.descr=(WCHAR*)a2u(pszDescription); + #endif + hkr.flags=HKF_GLOBAL|HKF_WPARNUM|HKF_LCURRENT|HKF_HEX; + hkr._type=HKT_SERVICE; + hkr.service=(char*)pszServiceName; + CallService(MS_HK_ADDHOTKEY,(WPARAM)&hkr,HK_ACT_OVERWRITE); + #if !defined(_UNICODE) + mir_free(hkr.descr); + #endif + return 0; + } + if(ServiceExists(MS_HKS_REGISTER_ITEM)) { /* 'Hotkeys Service' */ + THKSItem item; + ZeroMemory(&item,sizeof(item)); + item.name=(char*)pszSection; + item.itemType=HKS_ITEM_MODULE; + item.owner=LOWORD(CallService(MS_HKS_REGISTER_ITEM,(WPARAM)&item,0)); + item.name=(char*)pszDescription; + item.itemType=HKS_ITEM_ACTION; + item.hotkey.key=(WORD)vk; + item.hotkey.modifiers=MOD_GLOBAL; + if(hotkeyfModifiers&HOTKEYF_ALT) item.hotkey.modifiers|=MOD_ALT; + if(hotkeyfModifiers&HOTKEYF_CONTROL) item.hotkey.modifiers|=MOD_CONTROL; + if(hotkeyfModifiers&HOTKEYF_SHIFT) item.hotkey.modifiers|=MOD_SHIFT; + if(hotkeyfModifiers&HOTKEYF_EXT) item.hotkey.modifiers|=MOD_WIN; + /* no possibility to specify a service to call, + * all processing needs to be done in the plugins */ + moduleId=item.owner; + mir_snprintf(szHotkeyService,sizeof(szHotkeyService),"%s",pszServiceName); // only allows for one hotkey as a whole + HookEvent(ME_HKS_KEY_PRESSED,HotkeysServiceHotkeyPressed); + itemId=CallService(MS_HKS_REGISTER_ITEM,(WPARAM)&item,0); + return HIWORD(itemId); + } + return 1; +} diff --git a/plugins/AutoShutdown/utils.h b/plugins/AutoShutdown/utils.h new file mode 100644 index 0000000000..98b4825ec0 --- /dev/null +++ b/plugins/AutoShutdown/utils.h @@ -0,0 +1,48 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* String */ +WCHAR *a2u(const char *pszAnsi); +char *u2a(const WCHAR *pszUnicode); +void TrimString(TCHAR *pszStr); + +/* Error Output */ +void ShowInfoMessage(BYTE flags,const char *pszTitle,const char *pszTextFmt,...); +char* GetWinErrorDescription(DWORD dwLastError); + +/* Time */ +BOOL SystemTimeToTimeStamp(SYSTEMTIME *st,time_t *timestamp); +BOOL TimeStampToSystemTime(time_t timestamp,SYSTEMTIME *st); +BOOL GetFormatedCountdown(TCHAR *pszOut,int nSize,time_t countdown); +BOOL GetFormatedDateTime(TCHAR *pszOut,int nSize,time_t timestamp,BOOL fShowDateEvenToday); + +/* Fonts & Colors */ +int FontService_RegisterFont(const char *pszDbModule,const char *pszDbName,const TCHAR *pszSection,const TCHAR *pszDescription,int position,BOOL bAllowEffects,LOGFONT *plfDefault,COLORREF clrDefault); +int FontService_GetFont(const TCHAR *pszSection,const TCHAR *pszDescription,COLORREF *pclr,LOGFONT *plf); +int FontService_RegisterColor(const char *pszDbModule,const char *pszDbName,const TCHAR *pszSection,const TCHAR *pszDescription,COLORREF clrDefault); +int FontService_GetColor(const TCHAR *pszSection,const TCHAR *pszDescription,COLORREF *pclr); + +/* Skin */ +HANDLE IcoLib_AddIconRes(const char *pszDbName,const TCHAR *pszSection,const TCHAR *pszDesc,HINSTANCE hInst,WORD idRes,BOOL fLarge); +HICON IcoLib_GetIcon(const char *pszDbName); +int IcoLib_ReleaseIcon(HICON hIcon); +int SkinAddNewSoundBundled(const char *pszDbName,const char *pszSection,const char *pszDesc,const char *pszSubDir,const char *pszDefaultFile); +int SkinAddNewHotkey(const char *pszDbName,const char* pszSection,const char *pszDescription,UINT vk,UINT hotkeyfModifiers,const char *pszServiceName); diff --git a/plugins/AutoShutdown/version.h b/plugins/AutoShutdown/version.h new file mode 100644 index 0000000000..cba1fe2c93 --- /dev/null +++ b/plugins/AutoShutdown/version.h @@ -0,0 +1,40 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#define NEEDED_MIRANDA_VERSION PLUGIN_MAKE_VERSION(0,7,0,16) +#define NEEDED_MIRANDA_VERSION_STR "0.7 alpha build #16" +#define PLUGIN_VERSION PLUGIN_MAKE_VERSION(1,4,0,2) +#define FILE_VERSION 1,4,0,2 + +#if defined(_DEBUG) + #define FILE_VERSION_STR "1.4.0.3 alpha" +#else + #define FILE_VERSION_STR "1.4.0.2" +#endif + +#define PLUGIN_EMAIL "hrathh users.sourceforge.net" +#define PLUGIN_EMAIL_ATT_POS 7 /* position of the @-sign in the email adress above */ + +#if defined(_UNICODE) + #define PLUGIN_WEBSITE "http://addons.miranda-im.org/details.php?action=viewfile&id=3056" +#else + #define PLUGIN_WEBSITE "http://addons.miranda-im.org/details.php?action=viewfile&id=1086" +#endif diff --git a/plugins/AutoShutdown/version.rc b/plugins/AutoShutdown/version.rc new file mode 100644 index 0000000000..97f35498c3 --- /dev/null +++ b/plugins/AutoShutdown/version.rc @@ -0,0 +1,51 @@ +#ifndef _MAC + +#include "version.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION FILE_VERSION + PRODUCTVERSION FILE_VERSION + FILEFLAGSMASK 0x0L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", "Licensed under the terms of the GNU General Public License" + VALUE "FileDescription", "AutoShutdown Plugin for Miranda IM" + VALUE "FileVersion", FILE_VERSION_STR +#ifdef _UNICODE + VALUE "InternalName", "AutoShutdown (Unicode)" +#else + VALUE "InternalName", "AutoShutdown" +#endif + VALUE "LegalCopyright", "Copyright © 2004-2007 H. Herkenrath" + VALUE "OriginalFilename", "shutdown.dll" + VALUE "ProductName", "Automatic Shutdown" + VALUE "ProductVersion", FILE_VERSION_STR + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +#endif // !_MAC + + + + diff --git a/plugins/AutoShutdown/watcher.c b/plugins/AutoShutdown/watcher.c new file mode 100644 index 0000000000..75a2881e98 --- /dev/null +++ b/plugins/AutoShutdown/watcher.c @@ -0,0 +1,408 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "common.h" + +/* Msg Shutdown */ +static HANDLE hHookEventAdded; +/* Transfer Shutdown */ +static HANDLE hHookProtoAck; +/* Idle Shutdown */ +static HANDLE hHookIdleChanged; +/* Status Shutdown */ +static HANDLE hHookSettingChanged; +/* Weather Shutdown */ +static HANDLE hHookWeatherUpdated; +/* Overheat Shutdown */ +static HANDLE hHookHddOverheat; +/* Services */ +static HANDLE hServiceStartWatcher,hServiceStopWatcher,hServiceIsEnabled; +static HANDLE hEventWatcherChanged; +/* Misc */ +static HANDLE hHookModulesLoaded; + +/************************* Shared *************************************/ + +static WORD currentWatcherType; + +static void __stdcall MainThreadMapping(HANDLE *phDoneEvent) +{ + ServiceShutdown(0,TRUE); /* ensure main thread (for cpu usage shutdown) */ + ServiceStopWatcher(0,0); + if(*phDoneEvent!=NULL) SetEvent(*phDoneEvent); +} + +static void __inline ShutdownAndStopWatcher(void) +{ + HANDLE hDoneEvent; + hDoneEvent=CreateEvent(NULL,FALSE,FALSE,NULL); + if(CallFunctionAsync(MainThreadMapping,&hDoneEvent)) + if(hDoneEvent!=NULL) WaitForSingleObject(hDoneEvent,INFINITE); + if(hDoneEvent!=NULL) CloseHandle(hDoneEvent); +} + +/************************* Msg Shutdown *******************************/ + +// ppBlob might get reallocated, must have been allocated using mir_alloc() +static TCHAR* GetMessageText(BYTE **ppBlob,DWORD *pcbBlob) +{ +#if defined(_UNICODE) + DWORD cb; + (*ppBlob)[*pcbBlob]=0; + cb=lstrlenA((char*)*ppBlob); + /* use Unicode data if present */ + if(*pcbBlob>(cb+3)) { + (*ppBlob)[*pcbBlob-1]=0; + return (WCHAR*)&(*ppBlob)[cb]; + } + /* no Unicode data present, convert from ANSI */ + { int len; + BYTE *buf; + len=MultiByteToWideChar(CP_ACP,0,(char*)*ppBlob,-1,NULL,0); + if(!len) return NULL; + buf=(BYTE*)mir_realloc(*ppBlob,(*pcbBlob)+(len*sizeof(WCHAR))); + if(buf==NULL) return NULL; + *pcbBlob+=len*sizeof(WCHAR); + *ppBlob=buf; + buf=&(*ppBlob)[cb]; + MultiByteToWideChar(CP_ACP,0,(char*)*ppBlob,-1,(WCHAR*)buf,len); + ((WCHAR*)buf)[len-1]=0; + return (WCHAR*)buf; + } +#else + (*ppBlob)[*pcbBlob]=0; + return (char*)*ppBlob; +#endif +} + +static int MsgEventAdded(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + if(currentWatcherType&SDWTF_MESSAGE) { + DBEVENTINFO dbe; + dbe.cbSize=sizeof(dbe); + dbe.cbBlob=(DWORD)CallService(MS_DB_EVENT_GETBLOBSIZE,(WPARAM)lParam,0); + dbe.pBlob=(BYTE*)mir_alloc(dbe.cbBlob+2); /* ensure term zero */ + if(dbe.pBlob==NULL) return 0; + if(!CallService(MS_DB_EVENT_GET,(WPARAM)lParam,(LPARAM)&dbe)) + if(dbe.eventType==EVENTTYPE_MESSAGE && !(dbe.flags&DBEF_SENT)) { + DBVARIANT dbv; + TCHAR *pszMsg; + if(!DBGetContactSettingTString(NULL,"AutoShutdown","Message",&dbv)) { + TrimString(dbv.ptszVal); + pszMsg=GetMessageText(&dbe.pBlob,&dbe.cbBlob); + if(pszMsg!=NULL && _tcsstr(pszMsg,dbv.ptszVal)!=NULL) + ShutdownAndStopWatcher(); /* msg with specified text recvd */ + mir_free(dbv.ptszVal); /* does NULL check */ + } + } + mir_free(dbe.pBlob); + } + return 0; +} + +/************************* Transfer Shutdown **************************/ + +static HANDLE *transfers; +static int nTransfersCount; + +static int ProtoAck(WPARAM wParam,LPARAM lParam) +{ + ACKDATA *ack=(ACKDATA*)lParam; + UNREFERENCED_PARAMETER(wParam); + if(ack->type==ACKTYPE_FILE) + switch(ack->result) { + case ACKRESULT_DATA: + { int i; + for(i=0;ihProcess) + break; /* already in list */ + /* insert into list */ + { HANDLE *buf=(HANDLE*)mir_realloc(transfers,(nTransfersCount+1)*sizeof(HANDLE)); if(buf!=NULL) { + transfers=buf; + transfers[nTransfersCount]=ack->hProcess; + ++nTransfersCount; + } + } + break; + } + case ACKRESULT_SUCCESS: + case ACKRESULT_FAILED: + case ACKRESULT_DENIED: + { int i; + for(i=0;ihProcess) { + /* remove from list */ + HANDLE *buf; + if(i<(nTransfersCount-1)) + MoveMemory(&transfers[i],&transfers[i+1],(nTransfersCount-i-1)*sizeof(HANDLE)); + --nTransfersCount; + buf=(HANDLE*)mir_realloc(transfers,nTransfersCount*sizeof(HANDLE)); + if(buf!=NULL) transfers=buf; + else if(!nTransfersCount) transfers=NULL; + /* stop watcher */ + if(!nTransfersCount && (currentWatcherType&SDWTF_FILETRANSFER)) + ShutdownAndStopWatcher(); + break; + } + break; + } + } + return 0; +} + +/************************* Idle Shutdown ******************************/ + +static int IdleChanged(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + if(currentWatcherType&SDWTF_IDLE && lParam&IDF_ISIDLE) + ShutdownAndStopWatcher(); + return 0; +} + +/************************* Status Shutdown ****************************/ + +static BOOL CheckAllContactsOffline(void) +{ + BOOL fSmartCheck,fAllOffline=TRUE; /* tentatively */ + HANDLE hContact; + char *pszProto; + fSmartCheck=DBGetContactSettingByte(NULL,"AutoShutdown","SmartOfflineCheck",SETTING_SMARTOFFLINECHECK_DEFAULT); + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + while(hContact!=NULL) { + pszProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); + if(pszProto!=NULL && CallProtoService(pszProto,PS_GETSTATUS,0,0)!=ID_STATUS_OFFLINE) + if(DBGetContactSettingByte(hContact,pszProto,"ChatRoom",0)) continue; + if(DBGetContactSettingWord(hContact,pszProto,"Status",0)!=ID_STATUS_OFFLINE) { + if(fSmartCheck) { + if(DBGetContactSettingByte(hContact,"CList","Hidden",0)) continue; + if(DBGetContactSettingByte(hContact,"CList","NotOnList",0)) continue; + } + fAllOffline=FALSE; + break; + } + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0); + } + return fAllOffline; +} + +static int StatusSettingChanged(WPARAM wParam,LPARAM lParam) +{ + if(currentWatcherType&SDWTF_STATUS) { + DBCONTACTWRITESETTING *dbcws=(DBCONTACTWRITESETTING*)lParam; + if((HANDLE)wParam!=NULL && dbcws->value.wVal==ID_STATUS_OFFLINE && !lstrcmpA(dbcws->szSetting,"Status")) { + char *pszProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,wParam,0); + if(pszProto!=NULL && !lstrcmpA(dbcws->szModule,pszProto)) + if(CheckAllContactsOffline()) + ShutdownAndStopWatcher(); + } + } + return 0; +} + +/************************* Cpu Shutdown *******************************/ + +static DWORD idCpuUsageThread; + +static BOOL CALLBACK CpuUsageWatcherProc(BYTE nCpuUsage,LPARAM lParam) +{ + static BYTE nTimesBelow=0; /* only one watcher thread */ + /* terminated? */ + if(idCpuUsageThread!=GetCurrentThreadId()) { + nTimesBelow=0; + return FALSE; /* stop poll thread */ + } + /* ignore random peaks */ + if(nCpuUsage<(BYTE)lParam) ++nTimesBelow; + else nTimesBelow=0; + if(nTimesBelow==3) { + nTimesBelow=0; + ShutdownAndStopWatcher(); + return FALSE; /* stop poll thread */ + } + return TRUE; +} + +/************************* Weather Shutdown ***************************/ + +static int WeatherUpdated(WPARAM wParam,LPARAM lParam) +{ + char *pszProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,wParam,0); + if((BOOL)lParam && pszProto!=NULL && CallProtoService(pszProto,PS_GETSTATUS,0,0)==THUNDER) + if(DBGetContactSettingByte(NULL,"AutoShutdown","WeatherShutdown",SETTING_WEATHERSHUTDOWN_DEFAULT)) + ServiceShutdown(SDSDT_SHUTDOWN,TRUE); + return 0; +} + +/************************* Overheat Shutdown **************************/ + +static int HddOverheat(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + if(DBGetContactSettingByte(NULL,"AutoShutdown","HddOverheatShutdown",SETTING_HDDOVERHEATSHUTDOWN_DEFAULT)) + ServiceShutdown(SDSDT_SHUTDOWN,TRUE); + return 0; +} + +/************************* Services ***********************************/ + +int ServiceStartWatcher(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + + /* passing watcherType as lParam is only to be used internally, undocumented */ + if(lParam==0) lParam=(LPARAM)DBGetContactSettingWord(NULL,"AutoShutdown","WatcherFlags",0); + + if(!(lParam&SDWTF_MASK)) return 1; /* invalid flags or empty? */ + if(lParam&SDWTF_SPECIFICTIME && !(lParam&SDWTF_ST_MASK)) return 2; /* no specific time choice? */ + if(currentWatcherType==(WORD)lParam) return 3; + + if(currentWatcherType!=0) { + /* Time Shutdown */ + CloseCountdownFrame(); /* fails if not opened */ + /* Cpu Shutdown */ + idCpuUsageThread=0; + } + SetShutdownMenuItem(TRUE); + SetShutdownToolbarButton(TRUE); + currentWatcherType=(WORD)lParam; + NotifyEventHooks(hEventWatcherChanged,TRUE,0); + + /* Time Shutdown */ + if(currentWatcherType&SDWTF_SPECIFICTIME) + ShowCountdownFrame(currentWatcherType); /* after modules loaded */ + /* Cpu Shutdown */ + if(currentWatcherType&SDWTF_CPUUSAGE) + idCpuUsageThread=PollCpuUsage(CpuUsageWatcherProc,(LPARAM)DBGetContactSettingRangedByte(NULL,"AutoShutdown","CpuUsageThreshold",SETTING_CPUUSAGETHRESHOLD_DEFAULT,1,100),1500); + /* Transfer Shutdown */ + if(currentWatcherType&SDWTF_FILETRANSFER && !nTransfersCount) + ShutdownAndStopWatcher(); + /* Status Shutdown */ + if(currentWatcherType&SDWTF_STATUS && CheckAllContactsOffline()) + ShutdownAndStopWatcher(); + return 0; +} + +int ServiceStopWatcher(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + if(currentWatcherType==0) return 1; + + /* Time Shutdown */ + if(currentWatcherType&SDWTF_SPECIFICTIME) + CloseCountdownFrame(); + /* Cpu Shutdown */ + idCpuUsageThread=0; + + currentWatcherType=0; + SetShutdownMenuItem(FALSE); + SetShutdownToolbarButton(FALSE); + NotifyEventHooks(hEventWatcherChanged,FALSE,0); + return 0; +} + +int ServiceIsWatcherEnabled(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + return currentWatcherType!=0; +} + +/************************* Misc ***********************************/ + +static int WatcherModulesLoaded(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + + /* Weather Shutdown */ + if(ServiceExists(MS_WEATHER_UPDATE)) + hHookWeatherUpdated=HookEvent(ME_WEATHER_UPDATED,WeatherUpdated); + /* Overheat Shutdown */ + if(ServiceExists(MS_SYSINFO_HDDTEMP)) + hHookHddOverheat=HookEvent(ME_SYSINFO_HDDOVERHEAT,HddOverheat); + + /* restore watcher if it was running on last exit */ + if(DBGetContactSettingByte(NULL,"AutoShutdown","RememberOnRestart",0)==SDROR_RUNNING) { + DBWriteContactSettingByte(NULL,"AutoShutdown","RememberOnRestart",1); + ServiceStartWatcher(0,0); /* after modules loaded */ + } + return 0; +} + +void InitWatcher(void) +{ + /* Shared */ + currentWatcherType=0; + /* Message Shutdown */ + hHookEventAdded=HookEvent(ME_DB_EVENT_ADDED,MsgEventAdded); + /* Status Shutdown*/ + hHookSettingChanged=HookEvent(ME_DB_CONTACT_SETTINGCHANGED,StatusSettingChanged); + /* Idle Shutdown */ + hHookIdleChanged=HookEvent(ME_IDLE_CHANGED,IdleChanged); + /* Transfer Shutdown */ + transfers=NULL; + nTransfersCount=0; + hHookProtoAck=HookEvent(ME_PROTO_ACK,ProtoAck); + /* Weather Shutdown */ + hHookWeatherUpdated=NULL; + /* Overheat Shutdown */ + hHookHddOverheat=NULL; + /* Services */ + hEventWatcherChanged=CreateHookableEvent(ME_AUTOSHUTDOWN_WATCHERCHANGED); + hServiceStartWatcher=CreateServiceFunction(MS_AUTOSHUTDOWN_STARTWATCHER,ServiceStartWatcher); + hServiceStopWatcher=CreateServiceFunction(MS_AUTOSHUTDOWN_STOPWATCHER,ServiceStopWatcher); + hServiceIsEnabled=CreateServiceFunction(MS_AUTOSHUTDOWN_ISWATCHERENABLED,ServiceIsWatcherEnabled); + /* Misc */ + hHookModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,WatcherModulesLoaded); +} + +void UninitWatcher(void) +{ + /* remember watcher if running */ + if(!ServiceStopWatcher(0,0)) + if(DBGetContactSettingByte(NULL,"AutoShutdown","RememberOnRestart",SETTING_REMEMBERONRESTART_DEFAULT)) + DBWriteContactSettingByte(NULL,"AutoShutdown","RememberOnRestart",SDROR_RUNNING); + + /* Message Shutdown */ + UnhookEvent(hHookEventAdded); + /* Status Shutdown*/ + UnhookEvent(hHookSettingChanged); + /* Idle Shutdown */ + UnhookEvent(hHookIdleChanged); + /* Transfer Shutdown */ + UnhookEvent(hHookProtoAck); + mir_free(transfers); /* does NULL check */ + /* Weather Shutdown */ + UnhookEvent(hHookWeatherUpdated); /* does NULL check */ + /* Overheat Shutdown */ + UnhookEvent(hHookHddOverheat); /* does NULL check */ + /* Services */ + DestroyServiceFunction(hServiceStartWatcher); + DestroyServiceFunction(hServiceStopWatcher); + DestroyServiceFunction(hServiceIsEnabled); + DestroyHookableEvent(hEventWatcherChanged); + /* Misc */ + UnhookEvent(hHookModulesLoaded); +} diff --git a/plugins/AutoShutdown/watcher.h b/plugins/AutoShutdown/watcher.h new file mode 100644 index 0000000000..20f4e431c3 --- /dev/null +++ b/plugins/AutoShutdown/watcher.h @@ -0,0 +1,29 @@ +/* + +'AutoShutdown'-Plugin for Miranda IM + +Copyright 2004-2007 H. Herkenrath + +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 (Shutdown-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +/* Services */ +int ServiceStartWatcher(WPARAM wParam,LPARAM lParam); +int ServiceStopWatcher(WPARAM wParam,LPARAM lParam); +int ServiceIsWatcherEnabled(WPARAM wParam,LPARAM lParam); + +/* Misc */ +void InitWatcher(void); +void UninitWatcher(void); diff --git a/plugins/AvatarHistory/AvatarDlg.cpp b/plugins/AvatarHistory/AvatarDlg.cpp new file mode 100644 index 0000000000..4abe154016 --- /dev/null +++ b/plugins/AvatarHistory/AvatarDlg.cpp @@ -0,0 +1,621 @@ +/* +Avatar History Plugin + Copyright (C) 2006 Matthew Wild - Email: mwild1@gmail.com + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "AvatarHistory.h" + +extern HINSTANCE hInst; +HANDLE hMenu = NULL; +DWORD WINAPI AvatarDialogThread(LPVOID param); +static INT_PTR CALLBACK AvatarDlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam); +int ShowSaveDialog(HWND hwnd, TCHAR* fn,HANDLE hContact = NULL); + +BOOL ProtocolEnabled(const char *proto); +int FillAvatarListFromDB(HWND list, HANDLE hContact); +int FillAvatarListFromFolder(HWND list, HANDLE hContact); +int CleanupAvatarPic(HWND hwnd); +BOOL UpdateAvatarPic(HWND hwnd); +TCHAR* GetCurrentSelFile(HWND list); +TCHAR * GetContactFolder(TCHAR *fn, HANDLE hContact); +BOOL ResolveShortcut(TCHAR *shortcut, TCHAR *file); + +static INT_PTR ShowDialogSvc(WPARAM wParam, LPARAM lParam); +extern HANDLE hServices[]; +extern HANDLE hHooks[]; + +struct AvatarDialogData +{ + HANDLE hContact; + TCHAR fn[MAX_PATH]; + HWND parent; +}; + + +class ListEntry +{ +public: + ListEntry() + { + dbe = NULL; + filename = NULL; + filelink = NULL; + } + + ~ListEntry() + { + mir_free(filename); + mir_free(filelink); + } + + HANDLE dbe; + TCHAR *filename; + TCHAR *filelink; +}; + +int OpenAvatarDialog(HANDLE hContact, char* fn) +{ + HWND hAvatarWindow = WindowList_Find(hAvatarWindowsList, hContact); + if (hAvatarWindow) + { + SetForegroundWindow(hAvatarWindow); + SetFocus(hAvatarWindow); + return 0; + } + + DWORD dwId; + struct AvatarDialogData *avdlg = (struct AvatarDialogData*)malloc(sizeof(struct AvatarDialogData)); + ZeroMemory(avdlg, sizeof(struct AvatarDialogData)); + avdlg->hContact = hContact; + if (fn == NULL) + { + avdlg->fn[0] = _T('\0'); + } + else + { +#ifdef _UNICODE + MultiByteToWideChar(CP_ACP, 0, fn, -1, avdlg->fn, MAX_REGS(avdlg->fn)); +#else + lstrcpyn(avdlg->fn, fn, sizeof(avdlg->fn)); +#endif + } + + CloseHandle(CreateThread(NULL, 0, AvatarDialogThread, (LPVOID)avdlg, 0, &dwId)); + return 0; +} + +DWORD WINAPI AvatarDialogThread(LPVOID param) +{ + struct AvatarDialogData* data = (struct AvatarDialogData*)param; + DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_AVATARDLG), data->parent, AvatarDlgProc, (LPARAM)param); + return 0; +} + +void EnableDisableControls(HWND hwnd) +{ + HWND list = GetDlgItem(hwnd, IDC_AVATARLIST); + + int cursel = SendMessage(list, LB_GETCURSEL, 0, 0); + int count = SendMessage(list, LB_GETCOUNT, 0, 0); + + if (cursel == LB_ERR) + { + EnableWindow(GetDlgItem(hwnd, IDC_BACK), count > 0); + EnableWindow(GetDlgItem(hwnd, IDC_NEXT), count > 0); + } + else + { + EnableWindow(GetDlgItem(hwnd, IDC_BACK), cursel > 0); + EnableWindow(GetDlgItem(hwnd, IDC_NEXT), cursel < count-1); + } +} + +static INT_PTR CALLBACK AvatarDlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) + { + case WM_INITDIALOG: + { + AvatarDialogData *data = (struct AvatarDialogData*) lParam; + SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) createDefaultOverlayedIcon(TRUE)); + SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) createDefaultOverlayedIcon(FALSE)); + if (db_byte_get(NULL, MODULE_NAME, "LogToHistory", AVH_DEF_LOGTOHISTORY)) + FillAvatarListFromDB(GetDlgItem(hwnd, IDC_AVATARLIST), data->hContact); + else if (opts.log_per_contact_folders) + FillAvatarListFromFolder(GetDlgItem(hwnd, IDC_AVATARLIST), data->hContact); + TCHAR *displayName = (TCHAR*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM) data->hContact,GCDNF_TCHAR); + if(displayName) + { + TCHAR title[MAX_PATH]; + mir_sntprintf(title,MAX_PATH,TranslateT("Avatar History for %s"),displayName); + SetWindowText(hwnd,title); + } + + SetWindowLongPtr(hwnd, GWLP_USERDATA, (ULONG_PTR)data->hContact); + UpdateAvatarPic(hwnd); + CheckDlgButton(hwnd, IDC_LOGUSER, (UINT)db_byte_get(data->hContact, MODULE_NAME, "LogToDisk", BST_INDETERMINATE)); + CheckDlgButton(hwnd, IDC_POPUPUSER, (UINT)db_byte_get(data->hContact, MODULE_NAME, "AvatarPopups", BST_INDETERMINATE)); + CheckDlgButton(hwnd, IDC_HISTORYUSER, (UINT)db_byte_get(data->hContact, MODULE_NAME, "LogToHistory", BST_INDETERMINATE)); + ShowWindow(GetDlgItem(hwnd, IDC_OPENFOLDER), opts.log_per_contact_folders ? SW_SHOW : SW_HIDE); + Utils_RestoreWindowPositionNoSize(hwnd,NULL,MODULE_NAME,"AvatarHistoryDialog"); + WindowList_Add(hAvatarWindowsList,hwnd,data->hContact); + TranslateDialogDefault(hwnd); + EnableDisableControls(hwnd); + free(data); + data = NULL; + break; + } + case WM_CLOSE: + { + CleanupAvatarPic(hwnd); + EndDialog(hwnd, 0); + return TRUE; + } + case WM_DESTROY: + { + Utils_SaveWindowPosition(hwnd,NULL,MODULE_NAME,"AvatarHistoryDialog"); + WindowList_Remove(hAvatarWindowsList,hwnd); + DestroyIcon((HICON)SendMessage(hwnd, WM_SETICON, ICON_BIG, 0)); + DestroyIcon((HICON)SendMessage(hwnd, WM_SETICON, ICON_SMALL, 0)); + HWND list = GetDlgItem(hwnd, IDC_AVATARLIST); + int count = SendMessage(list, LB_GETCOUNT, 0, 0); + for(int i = 0; i < count; i++) + delete (ListEntry *) SendMessage(list, LB_GETITEMDATA, i, 0); + break; + } + case WM_CONTEXTMENU: + { + HWND list = GetDlgItem(hwnd, IDC_AVATARLIST); + HWND pic = GetDlgItem(hwnd, IDC_AVATAR); + int pos; + + if ((HANDLE) wParam == list) + { + POINT p; + p.x = LOWORD(lParam); + p.y = HIWORD(lParam); + + ScreenToClient(list, &p); + + pos = SendMessage(list, LB_ITEMFROMPOINT, 0, MAKELONG(p.x, p.y)); + if (HIWORD(pos)) + break; + pos = LOWORD(pos); + + int count = SendMessage(list, LB_GETCOUNT, 0, 0); + if (pos >= count) + break; + + SendMessage(list, LB_SETCURSEL, pos, 0); + EnableDisableControls(hwnd); + } + else if ((HANDLE) wParam == pic) + { + pos = SendMessage(list, LB_GETCURSEL, 0, 0); + if (pos == LB_ERR) + break; + } + else + break; + + HMENU menu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1)); + HMENU submenu = GetSubMenu(menu, 0); + TranslateMenu(submenu); + + if (!UpdateAvatarPic(hwnd)) + { + RemoveMenu(submenu, 2, MF_BYPOSITION); + RemoveMenu(submenu, 0, MF_BYPOSITION); + } + + POINT p; + p.x = LOWORD(lParam); + p.y = HIWORD(lParam); + int ret = TrackPopupMenu(submenu, TPM_TOPALIGN|TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_RETURNCMD, p.x, p.y, 0, list, NULL); + DestroyMenu(menu); + + switch(ret) + { + case ID_AVATARLISTPOPUP_SAVEAS: + { + HANDLE hContact = (HANDLE) GetWindowLongPtr(hwnd, GWLP_USERDATA); + ListEntry *le = (ListEntry*) SendMessage(list, LB_GETITEMDATA, pos, 0); + ShowSaveDialog(hwnd, le->filename, hContact); + break; + } + case ID_AVATARLISTPOPUP_DELETE: + { + ListEntry *le = (ListEntry*) SendMessage(list, LB_GETITEMDATA, pos, 0); + + BOOL blDelete; + + if(le->dbe) + blDelete = MessageBox(hwnd, TranslateT("Are you sure you wish to delete this history entry?\nOnly the entry in history will be deleted, bitmap file will be kept!"), + TranslateT("Delete avatar log?"), MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2|MB_SETFOREGROUND|MB_TOPMOST) == IDYES; + else + blDelete = MessageBox(hwnd, TranslateT("Are you sure you wish to delete this avatar shortcut?\nOnly shortcut will be deleted, bitmap file will be kept!"), + TranslateT("Delete avatar log?"), MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2|MB_SETFOREGROUND|MB_TOPMOST) == IDYES; + + if (blDelete) + { + HANDLE hContact = (HANDLE) GetWindowLongPtr(hwnd, GWLP_USERDATA); + + if(le->dbe) + CallService(MS_DB_EVENT_DELETE, (WPARAM) hContact, (LPARAM) le->dbe); + else + DeleteFile(le->filelink); + + delete le; + + SendMessage(list, LB_DELETESTRING, pos, 0); + + int count = SendMessage(list, LB_GETCOUNT, 0, 0); + if (count > 0) + { + if (pos >= count) + pos = count -1; + SendMessage(list, LB_SETCURSEL, pos, 0); + } + + UpdateAvatarPic(hwnd); + EnableDisableControls(hwnd); + } + break; + } + case ID_AVATARLISTPOPUP_DELETE_BOTH: + { + ListEntry *le = (ListEntry*) SendMessage(list, LB_GETITEMDATA, pos, 0); + + BOOL blDelete; + + if(le->dbe) + blDelete = MessageBox(hwnd, TranslateT("Are you sure you wish to delete this archived avatar?\nThis will delete the history entry and the bitmap file.\nWARNING:This can affect more than one entry in history!"), + TranslateT("Delete avatar?"), MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2|MB_SETFOREGROUND|MB_TOPMOST) == IDYES; + else + blDelete = MessageBox(hwnd, TranslateT("Are you sure you wish to delete this archived avatar?\nThis will delete the shortcut and the bitmap file.\nWARNING:This can affect more than one shortcut!"), + TranslateT("Delete avatar?"), MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2|MB_SETFOREGROUND|MB_TOPMOST) == IDYES; + + if (blDelete) + { + HANDLE hContact = (HANDLE) GetWindowLongPtr(hwnd, GWLP_USERDATA); + + DeleteFile(le->filename); + + if(le->dbe) + CallService(MS_DB_EVENT_DELETE, (WPARAM) hContact, (LPARAM) le->dbe); + else + DeleteFile(le->filelink); + + delete le; + + SendMessage(list, LB_DELETESTRING, pos, 0); + + int count = SendMessage(list, LB_GETCOUNT, 0, 0); + if (count > 0) + { + if (pos >= count) + pos = count -1; + SendMessage(list, LB_SETCURSEL, pos, 0); + } + + UpdateAvatarPic(hwnd); + EnableDisableControls(hwnd); + } + break; + } + } + break; + } + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case IDOK: + if(HIWORD(wParam) == BN_CLICKED) + { + HANDLE hContact = (HANDLE) GetWindowLongPtr(hwnd, GWLP_USERDATA); + + db_byte_set(hContact, MODULE_NAME, "AvatarPopups", (BYTE) IsDlgButtonChecked(hwnd, IDC_POPUPUSER)); + db_byte_set(hContact, MODULE_NAME, "LogToDisk", (BYTE) IsDlgButtonChecked(hwnd, IDC_LOGUSER)); + db_byte_set(hContact, MODULE_NAME, "LogToHistory", (BYTE) IsDlgButtonChecked(hwnd, IDC_HISTORYUSER)); + + CleanupAvatarPic(hwnd); + EndDialog(hwnd, 0); + return TRUE; + } + break; + case IDC_AVATARLIST: + if(HIWORD(wParam) == LBN_SELCHANGE) + { + UpdateAvatarPic(hwnd); + EnableDisableControls(hwnd); + return TRUE; + } + break; + case IDC_OPENFOLDER: + if(HIWORD(wParam) == BN_CLICKED) + { + if (opts.log_per_contact_folders) + { + TCHAR avfolder[MAX_PATH]; + HANDLE hContact = (HANDLE)GetWindowLongPtr(hwnd, GWLP_USERDATA); + GetContactFolder(avfolder, hContact); + ShellExecute(NULL, db_byte_get(NULL, MODULE_NAME, "OpenFolderMethod", 0) ? _T("explore") : _T("open"), avfolder, NULL, NULL, SW_SHOWNORMAL); + return TRUE; + } + } + break; + case IDC_NEXT: + if(HIWORD(wParam) == BN_CLICKED) + { + HWND list = GetDlgItem(hwnd, IDC_AVATARLIST); + SendMessage(list, LB_SETCURSEL, SendMessage(list, LB_GETCURSEL, 0, 0) +1, 0); + UpdateAvatarPic(hwnd); + EnableDisableControls(hwnd); + return TRUE; + } + break; + case IDC_BACK: + if(HIWORD(wParam) == BN_CLICKED) + { + HWND list = GetDlgItem(hwnd, IDC_AVATARLIST); + int cursel = SendMessage(list, LB_GETCURSEL, 0, 0); + if (cursel == LB_ERR) + SendMessage(list, LB_SETCURSEL, SendMessage(list, LB_GETCOUNT, 0, 0) -1, 0); + else + SendMessage(list, LB_SETCURSEL, cursel -1, 0); + UpdateAvatarPic(hwnd); + EnableDisableControls(hwnd); + return TRUE; + } + break; + } + break; + } + } + return FALSE; +} + + + +int FillAvatarListFromFolder(HWND list, HANDLE hContact) +{ + int max_pos = 0; + TCHAR dir[MAX_PATH], path[MAX_PATH], lnk[MAX_PATH]; + WIN32_FIND_DATA finddata; + + GetContactFolder(dir, hContact); + mir_sntprintf(path, MAX_PATH, _T("%s\\*.lnk"), dir); + + HANDLE hFind = FindFirstFile(path, &finddata); + if (hFind == INVALID_HANDLE_VALUE) + return 0; + + do + { + if(finddata.cFileName[0] != '.') + { + mir_sntprintf(lnk, MAX_PATH, _T("%s\\%s"), dir, finddata.cFileName); + if (ResolveShortcut(lnk, path)) + { + // Add to list + ListEntry *le = new ListEntry(); + le->filename = mir_tstrdup(path); + le->filelink = mir_tstrdup(lnk); + + TCHAR *p = _tcschr(finddata.cFileName, _T('.')); + if (p != NULL) + p[0] = _T('\0'); + max_pos = SendMessage(list, LB_ADDSTRING, 0, (LPARAM) finddata.cFileName); + SendMessage(list, LB_SETITEMDATA, max_pos, (LPARAM) le); + } + } + } while(FindNextFile(hFind, &finddata)); + FindClose(hFind); + SendMessage(list, LB_SETCURSEL, max_pos, 0); // Set to first item + return 0; +} + + + +int FillAvatarListFromDB(HWND list, HANDLE hContact) +{ + int max_pos = 0; + BYTE blob[2048]; + HANDLE dbe = (HANDLE) CallService(MS_DB_EVENT_FINDFIRST, (WPARAM) hContact, 0); + while(dbe != NULL) + { + DBEVENTINFO dbei = {0}; + dbei.cbSize = sizeof(dbei); + dbei.cbBlob = sizeof(blob); + dbei.pBlob = blob; + if (CallService(MS_DB_EVENT_GET, (WPARAM) dbe, (LPARAM) &dbei) == 0 + && dbei.eventType == EVENTTYPE_AVATAR_CHANGE) + { + + // Get last char from blob + int i = dbei.cbBlob - 2; + for(; i >= 0 && dbei.pBlob[i] != 0; i--) ; + + if (i != (int) dbei.cbBlob - 2 && i >= 0) + { + // Oki, found one + + // Get time + TCHAR date[64]; + DBTIMETOSTRINGT tts = {0}; + tts.szFormat = _T("d s"); + tts.szDest = date; + tts.cbDest = sizeof(date); + CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM) dbei.timestamp, (LPARAM) &tts); + + // Get file in disk + char path[MAX_PATH] = ""; + CallService(MS_UTILS_PATHTOABSOLUTE,(WPARAM) (char *) &dbei.pBlob[i+1],(LPARAM)path); + TCHAR *filename = mir_a2t(path); + + // Add to list + ListEntry *le = new ListEntry(); + le->dbe = dbe; + le->filename = filename; + + max_pos = SendMessage(list,LB_ADDSTRING, 0, (LPARAM) date); + SendMessage(list, LB_SETITEMDATA, max_pos, (LPARAM) le); + } + } + + dbe = (HANDLE) CallService(MS_DB_EVENT_FINDNEXT, (WPARAM) dbe, 0); + } + + SendMessage(list, LB_SETCURSEL, max_pos, 0); // Set to first item + return 0; +} + +BOOL UpdateAvatarPic(HWND hwnd) +{ + HWND hwndpic = GetDlgItem(hwnd, IDC_AVATAR); + if (!hwnd || !hwndpic) + return -1; + + HWND list = GetDlgItem(hwnd, IDC_AVATARLIST); + TCHAR *filename = GetCurrentSelFile(list); + if(!filename) + { + SetDlgItemText(hwnd,IDC_AVATARPATH,TranslateT("avatar path is null.")); + return 0; + } + SetDlgItemText(hwnd,IDC_AVATARPATH,filename); + + HBITMAP avpic = (HBITMAP) CallService(MS_IMG_LOAD, (WPARAM) filename, IMGL_TCHAR); + + BOOL found_image = (avpic != NULL); + + avpic = (HBITMAP)SendMessage(hwndpic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)avpic); + if (avpic) + DeleteObject(avpic); + + return found_image; +} + +int CleanupAvatarPic(HWND hwnd) +{ + HWND hwndpic = GetDlgItem(hwnd, IDC_AVATAR); + if (!hwnd || !hwndpic) + return -1; + + HBITMAP avpic = (HBITMAP)SendMessage(hwndpic, STM_GETIMAGE, 0, 0); + if(avpic) + DeleteObject(avpic); + return 0; +} + +int PreBuildContactMenu(WPARAM wParam,LPARAM lParam) +{ + CLISTMENUITEM clmi = {0}; + clmi.cbSize = sizeof(clmi); + clmi.flags = CMIM_FLAGS; + + char *proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); + if (!ProtocolEnabled(proto)) + clmi.flags |= CMIF_HIDDEN; + + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) hMenu, (LPARAM) &clmi); + + return 0; +} + +void InitMenuItem() +{ + CLISTMENUITEM mi = {0}; + + hServices[2] = CreateServiceFunction(MS_AVATARHISTORY_SHOWDIALOG, ShowDialogSvc); + + mi.cbSize = sizeof(mi); + mi.ptszName = LPGENT("View Avatar History"); + mi.flags = CMIF_TCHAR; + mi.position = 1000090010; + mi.hIcon = createDefaultOverlayedIcon(FALSE); + mi.pszService = MS_AVATARHISTORY_SHOWDIALOG; + hMenu = (HANDLE)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); + DestroyIcon(mi.hIcon); +} + +static INT_PTR ShowDialogSvc(WPARAM wParam, LPARAM lParam) +{ + OpenAvatarDialog((HANDLE)wParam, (char*)lParam); + return 0; +} + +TCHAR* GetCurrentSelFile(HWND list) +{ + int cursel = SendMessage(list, LB_GETCURSEL, 0, 0); + if (cursel > -1) + return ((ListEntry*) SendMessage(list, LB_GETITEMDATA, cursel, 0))->filename; + else + return NULL; +} + +int ShowSaveDialog(HWND hwnd, TCHAR* fn, HANDLE hContact) +{ + TCHAR filter[MAX_PATH]; + TCHAR file[MAX_PATH]; + OPENFILENAME ofn; + ZeroMemory(&ofn, sizeof(OPENFILENAME)); + DBVARIANT dbvInitDir = {0}; + bool ret = (DBGetContactSettingTString(hContact,MODULE_NAME,"SavedAvatarFolder",&dbvInitDir)== 0); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwnd; + ofn.hInstance = hInst; + + CallService(MS_UTILS_GETBITMAPFILTERSTRINGST, MAX_PATH, (LPARAM)filter); + ofn.lpstrFilter = filter; + + ofn.nFilterIndex = 1; + lstrcpyn(file, _tcsrchr(fn, '\\')+1, sizeof(file)); + ofn.lpstrFile = file; + + TCHAR *displayName = (TCHAR*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME,(WPARAM)hContact,GCDNF_TCHAR); + if(displayName) + { + TCHAR title[MAX_PATH]; + mir_sntprintf(title,sizeof(title),TranslateT("Save Avatar for %s"),displayName); + ofn.lpstrTitle = title; + } + else + { + ofn.lpstrTitle = TranslateT("Save Avatar"); + } + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_DONTADDTORECENT; + ofn.lpstrDefExt = _tcsrchr(fn, '.')+1; + if(ret) + { + ofn.lpstrInitialDir = dbvInitDir.ptszVal; + DBFreeVariant(&dbvInitDir); + } + else + { + ofn.lpstrInitialDir = _T("."); + } + if(GetSaveFileName(&ofn)) + { + CopyFile(fn, file, FALSE); + DBWriteContactSettingTString(hContact,MODULE_NAME,"SavedAvatarFolder",file); + } + return 0; +} diff --git a/plugins/AvatarHistory/AvatarHistory.cpp b/plugins/AvatarHistory/AvatarHistory.cpp new file mode 100644 index 0000000000..8dca674f77 --- /dev/null +++ b/plugins/AvatarHistory/AvatarHistory.cpp @@ -0,0 +1,999 @@ +/* +Avatar History Plugin +--------- + + This plugin uses the event provided by Avatar Service to + automatically back up contacts' avatars when they change. + Copyright (C) 2006 Matthew Wild - Email: mwild1@gmail.com + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ +#include "AvatarHistory.h" + +HINSTANCE hInst; +PLUGINLINK *pluginLink; +DWORD mirVer; + +HANDLE hHooks[6] = {0}; +HANDLE hServices[3] = {0}; + +HANDLE hFolder = NULL; + +char *metacontacts_proto = NULL; + +TCHAR profilePath[MAX_PATH]; // database profile path (read at startup only) +TCHAR basedir[MAX_PATH]; +MM_INTERFACE mmi; +UTF8_INTERFACE utfi; +int hLangpack = 0; +HANDLE hAvatarWindowsList = NULL; + +static int ModulesLoaded(WPARAM wParam, LPARAM lParam); +static int PreShutdown(WPARAM wParam, LPARAM lParam); +static int AvatarChanged(WPARAM wParam, LPARAM lParam); +int OptInit(WPARAM wParam,LPARAM lParam); + +TCHAR * GetHistoryFolder(TCHAR *fn); +TCHAR * GetProtocolFolder(TCHAR *fn, char *proto); +TCHAR * GetOldStyleAvatarName(TCHAR *fn, HANDLE hContact); + +void InitMenuItem(); + +void * GetHistoryEventText(HANDLE hContact, HANDLE hDbEvent, DBEVENTINFO *dbe, int format); + +// Services +static INT_PTR IsEnabled(WPARAM wParam, LPARAM lParam); +static INT_PTR GetCachedAvatar(WPARAM wParam, LPARAM lParam); +TCHAR * GetCachedAvatar(char *proto, TCHAR *hash); +BOOL CreateShortcut(TCHAR *file, TCHAR *shortcut); + + + +PLUGININFOEX pluginInfo={ + sizeof(PLUGININFOEX), +#ifdef _WIN64 + "Avatar History (x64)", +#elif _UNICODE + "Avatar History (Unicode)", +#else + "Avatar History (Ansi)", +#endif + PLUGIN_MAKE_VERSION(0,0,3,3), + "This plugin keeps backups of all your contacts' avatar changes and/or shows popups", + "Matthew Wild (MattJ), Ricardo Pescuma Domenecci", + "mwild1@gmail.com", + "В© 2006-2012 Matthew Wild, Ricardo Pescuma Domenecci", + "http://pescuma.org/miranda/avatarhist", + UNICODE_AWARE, + 0, //doesn't replace anything built-in +#ifdef _WIN64 + { 0xe04702a2, 0x379, 0x4c69, { 0xbf, 0x8a, 0x84, 0xd5, 0xd0, 0xc9, 0x19, 0xcc } } // {E04702A2-0379-4C69-BF8A-84D5D0C919CC} +#elif _UNICODE + { 0xdbe8c990, 0x7aa0, 0x458d, { 0xba, 0xb7, 0x33, 0xeb, 0x7, 0x23, 0x8e, 0x71 } } // {DBE8C990-7AA0-458d-BAB7-33EB07238E71} +#else + { 0x4079923c, 0x8aa1, 0x4a2e, { 0x95, 0x8b, 0x9d, 0xc, 0xd0, 0xe8, 0x2e, 0xb2 } } // {4079923C-8AA1-4a2e-958B-9D0CD0E82EB2} +#endif +}; + +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInst = hinstDLL; + return TRUE; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + if(mirandaVersion < PLUGIN_MAKE_VERSION(0,9,50,3)) + { + MessageBox(NULL,_T("AvatarHistory requires Miranda IM 0.9.50 or later."),_T("Avatar History"),MB_OK); + return NULL; + } + mirVer = mirandaVersion; + return &pluginInfo; +} + +static const MUUID interfaces[] = { MIID_AVATAR_CHANGE_LOGGER, MIID_AVATAR_CHANGE_NOTIFIER, MIID_LAST }; +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +static INT_PTR CALLBACK FirstRunDlgProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + switch(uMsg) + { + case WM_INITDIALOG: + { + SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) createDefaultOverlayedIcon(TRUE)); + SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) createDefaultOverlayedIcon(FALSE)); + TranslateDialogDefault(hwnd); + + CheckDlgButton(hwnd, IDC_MIR_PROTO, BST_CHECKED); + break; + } + case WM_COMMAND: + { + switch(LOWORD(wParam)) + { + case IDOK: + { + int ret = 0; + + if (IsDlgButtonChecked(hwnd, IDC_MIR_SAME)) + ret = IDC_MIR_SAME; + else if (IsDlgButtonChecked(hwnd, IDC_MIR_PROTO)) + ret = IDC_MIR_PROTO; + else if (IsDlgButtonChecked(hwnd, IDC_MIR_SHORT)) + ret = IDC_MIR_SHORT; + else if (IsDlgButtonChecked(hwnd, IDC_SHORT)) + ret = IDC_SHORT; + else if (IsDlgButtonChecked(hwnd, IDC_DUP)) + ret = IDC_DUP; + + EndDialog(hwnd, ret); + return TRUE; + } + } + break; + } + case WM_CLOSE: + { + EndDialog(hwnd, 0); + return TRUE; + } + } + + return FALSE; +} + +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) +{ + pluginLink=link; + + if(mir_getMMI(&mmi)) + { + MessageBox(NULL,_T("Avatar History"),_T("Miranda Memory manager not initialized, plugin cannot load.\nPlease update Miranda IM to the latest version."),MB_OK | MB_TOPMOST); + return 1; + } + if(mir_getUTFI(&utfi)) + { + MessageBox(NULL,_T("Avatar History"),_T("Miranda UTF8 interface not initialized, plugin cannot load.\nPlease update Miranda IM to the latest version."),MB_OK | MB_TOPMOST); + return 1; + } + mir_getLP(&pluginInfo); + + // Is first run? + if (DBGetContactSettingByte(NULL, MODULE_NAME, "FirstRun", 1)) + { + // Show dialog + int ret = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_FIRST_RUN), NULL, FirstRunDlgProc, 0); + if (ret == 0) + return -1; + + // Write settings + + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogToDisk", 1); + + if (ret == IDC_MIR_SAME) + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogKeepSameFolder", 1); + else + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogKeepSameFolder", 0); + + if (ret == IDC_MIR_SHORT || ret == IDC_SHORT || ret == IDC_DUP) + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogPerContactFolders", 1); + else + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogPerContactFolders", 0); + + if (ret == IDC_DUP) + DBWriteContactSettingByte(NULL, MODULE_NAME, "StoreAsHash", 0); + else + DBWriteContactSettingByte(NULL, MODULE_NAME, "StoreAsHash", 1); + + if (ret == IDC_MIR_SAME || ret == IDC_MIR_PROTO || ret == IDC_MIR_SHORT) + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogToHistory", 1); + else + DBWriteContactSettingByte(NULL, MODULE_NAME, "LogToHistory", 0); + + DBWriteContactSettingByte(NULL, MODULE_NAME, "FirstRun", 0); + } + + LoadOptions(); + + hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED,ModulesLoaded); + hHooks[1] = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown); + hHooks[3] = HookEvent(ME_OPT_INITIALISE, OptInit); + hHooks[4] = HookEvent(ME_SKIN2_ICONSCHANGED, IcoLibIconsChanged); + hHooks[5] = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PreBuildContactMenu); + + hServices[0] = CreateServiceFunction(MS_AVATARHISTORY_ENABLED, IsEnabled); + hServices[1] = CreateServiceFunction(MS_AVATARHISTORY_GET_CACHED_AVATAR, GetCachedAvatar); + + if(CallService(MS_DB_GETPROFILEPATHT, MAX_PATH, (LPARAM)profilePath) != 0) + _tcscpy(profilePath, _T(".")); // Failed, use current dir + + SkinAddNewSoundExT("avatar_changed",LPGENT("Avatar History"),LPGENT("Contact changed avatar")); + SkinAddNewSoundExT("avatar_removed",LPGENT("Avatar History"),LPGENT("Contact removed avatar")); + + hAvatarWindowsList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); + + SetupIcoLib(); + InitMenuItem(); + + return 0; +} + +static int ModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + mir_sntprintf(basedir, MAX_REGS(basedir), _T("%s\\Avatars History"), profilePath); + + hFolder = FoldersRegisterCustomPathT(LPGEN("Avatars"), LPGEN("Avatar History"), + PROFILE_PATHT _T("\\") CURRENT_PROFILET _T("\\Avatars History")); + InitPopups(); + + if (ServiceExists(MS_MC_GETPROTOCOLNAME)) + metacontacts_proto = (char *) CallService(MS_MC_GETPROTOCOLNAME, 0, 0); + + // updater plugin support + if(ServiceExists(MS_UPDATE_REGISTER)) + { + Update upd = {0}; + char szCurrentVersion[30]; + + upd.cbSize = sizeof(upd); + upd.szComponentName = pluginInfo.shortName; + + upd.szUpdateURL = UPDATER_AUTOREGISTER; + + upd.szBetaVersionURL = "http://code.google.com/p/pescuma/downloads/list?q=label:Plugin-AVH"; + upd.szBetaChangelogURL = "http://code.google.com/p/pescuma/source/list"; +#ifdef _WIN64 + upd.pbBetaVersionPrefix = (BYTE *) "Avatar History (x64) "; + upd.szBetaUpdateURL = "http://pescuma.googlecode.com/files/avatarhistW.%VERSION%-x64.zip"; +#elif _UNICODE + upd.pbBetaVersionPrefix = (BYTE *) "Avatar History (Unicode) "; + upd.szBetaUpdateURL = "http://pescuma.googlecode.com/files/avatarhistW.%VERSION%.zip"; +#else + upd.pbBetaVersionPrefix = (BYTE *) "Avatar History (ANSI) "; + upd.szBetaUpdateURL = "http://pescuma.googlecode.com/files/avatarhist.%VERSION%.zip"; +#endif + upd.cpbBetaVersionPrefix = (int) strlen((char *)upd.pbBetaVersionPrefix); + + upd.pbVersion = (BYTE *)CreateVersionStringPluginEx(&pluginInfo, szCurrentVersion); + upd.cpbVersion = (int) strlen((char *)upd.pbVersion); + + CallService(MS_UPDATE_REGISTER, 0, (LPARAM)&upd); + } + + if (DBGetContactSettingByte(NULL, MODULE_NAME, "LogToHistory", AVH_DEF_LOGTOHISTORY)) + { + char *templates[] = { "Avatar change\nchanged his/her avatar", + "Avatar removal\nremoved his/her avatar" }; + HICON hIcon = createDefaultOverlayedIcon(FALSE); + HistoryEvents_RegisterWithTemplates(MODULE_NAME, "avatarchange", "Avatar change", EVENTTYPE_AVATAR_CHANGE, hIcon, + HISTORYEVENTS_FORMAT_CHAR | HISTORYEVENTS_FORMAT_WCHAR | HISTORYEVENTS_FORMAT_RICH_TEXT, + HISTORYEVENTS_FLAG_SHOW_IM_SRMM | HISTORYEVENTS_FLAG_EXPECT_CONTACT_NAME_BEFORE, + GetHistoryEventText, templates, MAX_REGS(templates)); + DestroyIcon(hIcon); + } + + hHooks[2] = HookEvent(ME_AV_CONTACTAVATARCHANGED, AvatarChanged); + + return 0; +} + +static int PreShutdown(WPARAM wParam, LPARAM lParam) +{ + int i; + + for (i = 0; i < MAX_REGS(hHooks); i++) + UnhookEvent(hHooks[i]); + + for (i = 0; i < MAX_REGS(hServices); i++) + DestroyServiceFunction(hServices[i]); + + WindowList_Broadcast(hAvatarWindowsList,WM_CLOSE,0,0); + + return 0; +} + +BOOL ProtocolEnabled(const char *proto) +{ + if (proto == NULL) + return FALSE; + + char setting[256]; + mir_snprintf(setting, sizeof(setting), "%sEnabled", proto); + return (BOOL) DBGetContactSettingByte(NULL, MODULE_NAME, setting, TRUE); +} + + +BOOL ContactEnabled(HANDLE hContact, char *setting, int def) +{ + if (hContact == NULL) + return FALSE; + + char *proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); + if (!ProtocolEnabled(proto)) + return FALSE; + + BYTE globpref = db_byte_get(NULL, MODULE_NAME, setting, def); + BYTE userpref = db_byte_get(hContact, MODULE_NAME, setting, BST_INDETERMINATE); + + return (globpref && userpref == BST_INDETERMINATE) || userpref == BST_CHECKED; +} + +// Returns true if the unicode buffer only contains 7-bit characters. +BOOL IsUnicodeAscii(const WCHAR * pBuffer, int nSize) +{ + BOOL bResult = TRUE; + int nIndex; + + for (nIndex = 0; nIndex < nSize; nIndex++) { + if (pBuffer[nIndex] > 0x7F) { + bResult = FALSE; + break; + } + } + return bResult; +} + +void ConvertToFilename(TCHAR *str, size_t size) { + for(size_t i = 0; i < size && str[i] != '\0'; i++) { + switch(str[i]) { + case '/': + case '\\': + case ':': + case '*': + case '?': + case '"': + case '<': + case '>': + case '|': + //case '.': + str[i] = '_'; + } + } +} + +void ErrorExit(HANDLE hContact,LPTSTR lpszFunction) +{ + // Retrieve the system error message for the last-error code + + LPVOID lpMsgBuf; + LPVOID lpDisplayBuf; + DWORD dw = GetLastError(); + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dw, + MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), + (LPTSTR) &lpMsgBuf, + 0, NULL ); + + // Display the error message and exit the process + + lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, + (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); + StringCchPrintf((LPTSTR)lpDisplayBuf, + LocalSize(lpDisplayBuf) / sizeof(TCHAR), + TEXT("%s failed with error %d: %s"), + lpszFunction, dw, lpMsgBuf); + ShowDebugPopup(hContact,TEXT("Error"), (LPCTSTR)lpDisplayBuf); + + LocalFree(lpMsgBuf); + LocalFree(lpDisplayBuf); +} + +#ifdef _UNICODE + +#define CS "%S" + +#else + +#define CS "%s" + +#endif + + +TCHAR * GetExtension(TCHAR *file) +{ + if(file == NULL) return _T(""); + TCHAR *ext = _tcsrchr(file, _T('.')); + if (ext != NULL) + ext++; + else + ext = _T(""); + + return ext; +} + + +void CreateOldStyleShortcut(HANDLE hContact, TCHAR *history_filename) +{ + TCHAR shortcut[MAX_PATH] = _T(""); + + GetOldStyleAvatarName(shortcut, hContact); + + mir_sntprintf(shortcut, MAX_REGS(shortcut), _T("%s.%s.lnk"), shortcut, + GetExtension(history_filename)); + + if (!CreateShortcut(history_filename, shortcut)) + { + ShowPopup(hContact, _T("Avatar History: Unable to create shortcut"), shortcut); + } + else + { + ShowDebugPopup(hContact, _T("AVH Debug: Shortcut created successfully"), shortcut); + } +} + + +BOOL CopyImageFile(TCHAR *old_file, TCHAR *new_file) +{ + TCHAR *ext = GetExtension(old_file); + mir_sntprintf(new_file, MAX_PATH, _T("%s.%s"), new_file, ext); + + BOOL ret = CopyFile(old_file, new_file, TRUE); + if(!ret) + ErrorExit(NULL,_T("CopyImageFile")); + return !ret; +} + +// fired when the contacts avatar changes +// wParam = hContact +// lParam = struct avatarCacheEntry *cacheEntry +// the event CAN pass a NULL pointer in lParam which means that the avatar has changed, +// but is no longer valid (happens, when a contact removes his avatar, for example). +// DONT DESTROY the bitmap handle passed in the struct avatarCacheEntry * +// +// It is also possible that this event passes 0 as wParam (hContact), in which case, +// a protocol picture (pseudo - avatar) has been changed. +static int AvatarChanged(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + CONTACTAVATARCHANGEDNOTIFICATION* avatar = (CONTACTAVATARCHANGEDNOTIFICATION*)lParam; + + if (hContact == NULL) + { + ShowDebugPopup(NULL, _T("AVH Debug"), _T("Invalid contact/avatar... skipping")); + return 0; + } + + char *proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, wParam, 0); + if (proto == NULL) + { + ShowDebugPopup(hContact, _T("AVH Debug"), _T("Invalid protocol... skipping")); + return 0; + } + else if (metacontacts_proto != NULL && strcmp(metacontacts_proto, proto) == 0) + { + ShowDebugPopup(hContact, _T("AVH Debug"), _T("Ignoring metacontacts notification")); + return 0; + } + + DBVARIANT dbvOldHash = {0}; + bool ret = (DBGetContactSettingTString(hContact,MODULE_NAME,"AvatarHash",&dbvOldHash) == 0); + + if (avatar == NULL) + { + if (!ret || !_tcscmp(dbvOldHash.ptszVal, _T("-"))) + { + //avoid duplicate "removed avatar" notifications + //do not notify on an empty profile + ShowDebugPopup(hContact, _T("AVH Debug"), _T("Removed avatar, no avatar before...skipping")); + DBFreeVariant(&dbvOldHash); + return 0; + } + SkinPlaySound("avatar_removed"); + + // Is a flash avatar or avs could not load it + DBWriteContactSettingTString(hContact, MODULE_NAME, "AvatarHash", _T("-")); + + if (ContactEnabled(hContact, "AvatarPopups", AVH_DEF_AVPOPUPS) && opts.popup_show_removed) + ShowPopup(hContact, NULL, opts.popup_removed); + + if (ContactEnabled(hContact, "LogToHistory", AVH_DEF_LOGTOHISTORY)) + HistoryEvents_AddToHistorySimple(hContact, EVENTTYPE_AVATAR_CHANGE, 1, DBEF_READ); + } + else + { + if(ret && !_tcscmp(dbvOldHash.ptszVal, avatar->hash)) + { + // same avatar hash, skipping + ShowDebugPopup(hContact, _T("AVH Debug"), _T("Hashes are the same... skipping")); + DBFreeVariant(&dbvOldHash); + return 0; + } + SkinPlaySound("avatar_changed"); + DBWriteContactSettingTString(hContact, "AvatarHistory", "AvatarHash", avatar->hash); + + TCHAR history_filename[MAX_PATH] = _T(""); + + if (ContactEnabled(hContact, "LogToDisk", AVH_DEF_LOGTODISK)) + { + if (!opts.log_store_as_hash) + { + if (opts.log_per_contact_folders) + { + GetOldStyleAvatarName(history_filename, hContact); + if (CopyImageFile(avatar->filename, history_filename)) + ShowPopup(hContact, _T("Avatar History: Unable to save avatar"), history_filename); + else + ShowDebugPopup(hContact, _T("AVH Debug: File copied successfully"), history_filename); + + if (ServiceExists(MS_MC_GETMETACONTACT)) + { + HANDLE hMetaContact = (HANDLE) CallService(MS_MC_GETMETACONTACT, wParam, 0); + + if (hMetaContact != NULL && ContactEnabled(hMetaContact, "LogToDisk", AVH_DEF_LOGTOHISTORY)) + { + TCHAR filename[MAX_PATH] = _T(""); + + GetOldStyleAvatarName(filename, hMetaContact); + if (CopyImageFile(avatar->filename, filename)) + ShowPopup(hContact, _T("Avatar History: Unable to save avatar"), filename); + else + ShowDebugPopup(hContact, _T("AVH Debug: File copied successfully"), filename); + } + } + } + } + else + { + // See if we already have the avatar + TCHAR hash[128]; + lstrcpyn(hash, avatar->hash, sizeof(hash)); + ConvertToFilename(hash, sizeof(hash)); + + TCHAR *file = GetCachedAvatar(proto, hash); + + if (file != NULL) + { + lstrcpyn(history_filename, file, MAX_REGS(history_filename)); + mir_free(file); + } + else + { + if (opts.log_keep_same_folder) + GetHistoryFolder(history_filename); + else + GetProtocolFolder(history_filename, proto); + + mir_sntprintf(history_filename, MAX_REGS(history_filename), + _T("%s\\%s"), history_filename, hash); + + if (CopyImageFile(avatar->filename, history_filename)) + ShowPopup(hContact, _T("Avatar History: Unable to save avatar"), history_filename); + else + ShowDebugPopup(hContact, _T("AVH Debug: File copied successfully"), history_filename); + } + + if (opts.log_per_contact_folders) + { + CreateOldStyleShortcut(hContact, history_filename); + + if (ServiceExists(MS_MC_GETMETACONTACT)) + { + HANDLE hMetaContact = (HANDLE) CallService(MS_MC_GETMETACONTACT, wParam, 0); + + if (hMetaContact != NULL && ContactEnabled(hMetaContact, "LogToDisk", AVH_DEF_LOGTOHISTORY)) + CreateOldStyleShortcut(hMetaContact, history_filename); + } + } + } + } + + + if (ContactEnabled(hContact, "AvatarPopups", AVH_DEF_AVPOPUPS) && opts.popup_show_changed) + ShowPopup(hContact, NULL, opts.popup_changed); + + if (ContactEnabled(hContact, "LogToHistory", AVH_DEF_LOGTOHISTORY)) + { + TCHAR rel_path[MAX_PATH] = _T(""); + CallService(MS_UTILS_PATHTORELATIVET,(WPARAM)history_filename,(LPARAM)rel_path); +#ifdef _UNICODE + char *blob = mir_utf8encodeT(rel_path); + int flags = DBEF_READ | DBEF_UTF; +#else + char *blob = mir_strdup(rel_path); + int flags = DBEF_READ; +#endif + HistoryEvents_AddToHistoryEx(hContact, EVENTTYPE_AVATAR_CHANGE, 0, NULL, 0, (PBYTE) blob, (int) strlen(blob) + 1, flags); + } + } + + return 0; +} + +extern "C" int __declspec(dllexport) Unload(void) +{ + return 0; +} + + +static INT_PTR IsEnabled(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE) wParam; + return ContactEnabled(hContact, "LogToDisk", AVH_DEF_LOGTODISK) + || ContactEnabled(hContact, "AvatarPopups", AVH_DEF_AVPOPUPS) + || ContactEnabled(hContact, "LogToHistory", AVH_DEF_LOGTOHISTORY); +} + + +/* +Get cached avatar + +wParam: (char *) protocol name +lParam: (TCHAR *) hash +return: (TCHAR *) NULL if none is found or the path to the avatar. You need to free this string + with mir_free. +*/ +static INT_PTR GetCachedAvatar(WPARAM wParam, LPARAM lParam) +{ + TCHAR hash[128]; + lstrcpyn(hash, (TCHAR *) lParam, sizeof(hash)); + ConvertToFilename(hash, sizeof(hash)); + return (INT_PTR) GetCachedAvatar((char *) wParam, hash); +} + +TCHAR * GetCachedAvatar(char *proto, TCHAR *hash) +{ + TCHAR *ret = NULL; + TCHAR file[1024] = _T(""); + TCHAR search[1024] = _T(""); + if (opts.log_keep_same_folder) + GetHistoryFolder(file); + else + GetProtocolFolder(file, proto); + + mir_sntprintf(search, MAX_REGS(search), _T("%s\\%s.*"), file, hash); + + WIN32_FIND_DATA finddata; + HANDLE hFind = FindFirstFile(search, &finddata); + if (hFind == INVALID_HANDLE_VALUE) + return NULL; + + do + { + size_t len = lstrlen(finddata.cFileName); + if (len > 4 + && (!lstrcmpi(&finddata.cFileName[len-4], _T(".png")) + || !lstrcmpi(&finddata.cFileName[len-4], _T(".bmp")) + || !lstrcmpi(&finddata.cFileName[len-4], _T(".gif")) + || !lstrcmpi(&finddata.cFileName[len-4], _T(".jpg")) + || !lstrcmpi(&finddata.cFileName[len-5], _T(".jpeg")))) + { + mir_sntprintf(file, MAX_REGS(file), _T("%s\\%s"), file, finddata.cFileName); + ret = mir_tstrdup(file); + break; + } + } while(FindNextFile(hFind, &finddata)); + FindClose(hFind); + + return ret; +} + + +int GetUIDFromHContact(HANDLE contact, TCHAR* uinout, size_t uinout_len) +{ + CONTACTINFO cinfo; + + ZeroMemory(&cinfo,sizeof(CONTACTINFO)); + cinfo.cbSize = sizeof(CONTACTINFO); + cinfo.hContact = contact; + cinfo.dwFlag = CNF_UNIQUEID | CNF_TCHAR; + + bool found = true; + if(CallService(MS_CONTACT_GETCONTACTINFO,0,(LPARAM)&cinfo)==0) + { + if(cinfo.type == CNFT_ASCIIZ) + { + lstrcpyn(uinout, cinfo.pszVal, uinout_len); + // It is up to us to free the string + // The catch? We need to use Miranda's free(), not our CRT's :) + mir_free(cinfo.pszVal); + } + else if(cinfo.type == CNFT_DWORD) + { + _itot(cinfo.dVal,uinout,10); + } + else if(cinfo.type == CNFT_WORD) + { + _itot(cinfo.wVal,uinout,10); + } + else found = false; + } + else found = false; + + if (!found) + { + lstrcpyn(uinout, TranslateT("Unknown UIN"),uinout_len); + } + return 0; +} + + +TCHAR * GetHistoryFolder(TCHAR *fn) +{ + if (fn == NULL) return NULL; + FoldersGetCustomPathT(hFolder, fn, MAX_PATH, basedir); + if(!CreateDirectory(fn, NULL)) + ErrorExit(NULL,_T("GetHistoryFolder")); + + return fn; +} + + +TCHAR * GetProtocolFolder(TCHAR *fn, char *proto) +{ + GetHistoryFolder(fn); + + if (proto == NULL) + proto = Translate("Unknown Protocol"); + + mir_sntprintf(fn, MAX_PATH, _T("%s\\") _T(CS), fn, proto); + if(!CreateDirectory(fn, NULL)) + ErrorExit(NULL,_T("CreateDirectory")); + + return fn; +} + + +TCHAR * GetContactFolder(TCHAR *fn, HANDLE hContact) +{ + TCHAR uin[MAX_PATH]; + + char *proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM) hContact, 0); + GetProtocolFolder(fn, proto); + + GetUIDFromHContact(hContact, uin, MAX_REGS(uin)); + mir_sntprintf(fn, MAX_PATH, _T("%s\\%s"), fn, uin); + if(!CreateDirectory(fn, NULL)) + ErrorExit(hContact,_T("CreateDirectory")); + ConvertToFilename(uin, sizeof(uin)); //added so that weather id's like "yw/CI0000" work + +#ifdef DBGPOPUPS + TCHAR log[1024]; + mir_sntprintf(log, MAX_REGS(log), _T("Path: %s\nProto: ") _T(CS) _T("\nUIN: %s"), fn, proto, uin); + ShowPopup(hContact, _T("AVH Debug: GetContactFolder"), log); +#endif + + return fn; +} + +TCHAR * GetOldStyleAvatarName(TCHAR *fn, HANDLE hContact) +{ + GetContactFolder(fn, hContact); + + SYSTEMTIME curtime; + GetLocalTime(&curtime); + mir_sntprintf(fn, MAX_PATH, + _T("%s\\%04d-%02d-%02d %02dh%02dm%02ds"), fn, + curtime.wYear, curtime.wMonth, curtime.wDay, + curtime.wHour, curtime.wMinute, curtime.wSecond); + ShowDebugPopup(hContact,_T("AVH Debug: GetOldStyleAvatarName"),fn); + return fn; +} + +BOOL CreateShortcut(TCHAR *file, TCHAR *shortcut) +{ + CoInitialize(NULL); + + IShellLink* psl = NULL; + + HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &psl); + + if (SUCCEEDED(hr)) + { + psl->SetPath(file); + + IPersistFile* ppf = NULL; + hr = psl->QueryInterface(IID_IPersistFile, (void **) &ppf); + + if (SUCCEEDED(hr)) + { +#ifdef _UNICODE + hr = ppf->Save(shortcut, TRUE); +#else + WCHAR tmp[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, shortcut, -1, tmp, MAX_PATH); + hr = ppf->Save(tmp, TRUE); +#endif + ppf->Release(); + } + + psl->Release(); + } + + if(FAILED(hr)) + ErrorExit(NULL,_T("CreateShortcut")); + return SUCCEEDED(hr); +} + + +BOOL ResolveShortcut(TCHAR *shortcut, TCHAR *file) +{ + CoInitialize(NULL); + + IShellLink* psl = NULL; + + HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &psl); + + if (SUCCEEDED(hr)) + { + IPersistFile* ppf = NULL; + hr = psl->QueryInterface(IID_IPersistFile, (void **) &ppf); + + if (SUCCEEDED(hr)) + { +#ifdef _UNICODE + hr = ppf->Load(shortcut, STGM_READ); +#else + WCHAR tmp[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, shortcut, -1, tmp, MAX_PATH); + hr = ppf->Load(tmp, STGM_READ); +#endif + + if (SUCCEEDED(hr)) + { + hr = psl->Resolve(NULL, SLR_UPDATE); + + if (SUCCEEDED(hr)) + { + WIN32_FIND_DATA wfd; + hr = psl->GetPath(file, MAX_PATH, &wfd, SLGP_RAWPATH); + } + } + + ppf->Release(); + } + psl->Release(); + } + + if(FAILED(hr)) + ErrorExit(NULL,_T("CreateShortcut")); + return SUCCEEDED(hr); +} + + +template +void ConvertToRTF(Buffer *buffer, T *line) +{ + buffer->append("{\\uc1 ", 6); + + for (; *line; line++) + { + if (*line == (T)'\r' && line[1] == (T)'\n') { + buffer->append("\\line ", 6); + line++; + } + else if (*line == (T)'\n') { + buffer->append("\\line ", 6); + } + else if (*line == (T)'\t') { + buffer->append("\\tab ", 5); + } + else if (*line == (T)'\\' || *line == (T)'{' || *line == (T)'}') { + buffer->append('\\'); + buffer->append((char) *line); + } + else if (*line < 128) { + buffer->append((char) *line); + } + else + buffer->appendPrintf("\\u%d ?", *line); + } + + buffer->append('}'); +} + + +void GetRTFFor(Buffer *buffer, HBITMAP hBitmap) +{ + BITMAP bmp; + GetObject(hBitmap, sizeof(bmp), &bmp); + + DWORD dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8); + BYTE *p = (BYTE *) malloc(dwLen); + if (p == NULL) + return; + + dwLen = GetBitmapBits(hBitmap, dwLen, p); + + buffer->appendPrintf("{\\pict\\wbitmap0\\wbmbitspixel%u\\wbmplanes%u\\wbmwidthbytes%u\\picw%u\\pich%u ", + bmp.bmBitsPixel, bmp.bmPlanes, bmp.bmWidthBytes, bmp.bmWidth, bmp.bmHeight); + + for (DWORD i = 0; i < dwLen; i++) + buffer->appendPrintf("%02X", p[i]); + + buffer->append('}'); + + +/* + BITMAPINFOHEADER bih = { 0 }; + HDC hdc = GetDC(NULL); + GetDIBits(hdc, hBitmap, 0, bmp.bmHeight, p, (BITMAPINFO *) & bih, DIB_RGB_COLORS); + + buffer->appendPrintf("{\\pict\\wbitmap0\\wbmbitspixel%u\\wbmplanes%u\\wbmwidthbytes%u\\picw%u\\pich%u ", + bmp.bmBitsPixel, bmp.bmPlanes, bmp.bmWidthBytes, bmp.bmWidth, bmp.bmHeight); + + DWORD i; + for (i = 0; i < sizeof(BITMAPINFOHEADER); i++) + buffer->appendPrintf("%02X", ((PBYTE) & bih)[i]); + + for (i = 0; i < dwLen; i++) + buffer->appendPrintf("%02X", p[i]); + + buffer->append('}'); +*/ + + free(p); +} + + +void * GetHistoryEventText(HANDLE hContact, HANDLE hDbEvent, DBEVENTINFO *dbe, int format) +{ + void *ret; + + if (format & HISTORYEVENTS_FORMAT_CHAR) + { + ret = DbGetEventTextA(dbe, CP_ACP); + } + else if (format & HISTORYEVENTS_FORMAT_WCHAR) + { + ret = DbGetEventTextW(dbe, CP_ACP); + } + else if (format & HISTORYEVENTS_FORMAT_RICH_TEXT) + { + Buffer buffer; + + TCHAR *tmp = DbGetEventTextT(dbe, CP_ACP); + ConvertToRTF(&buffer, tmp); + mir_free(tmp); + + // Load the image + size_t i; + for(i = dbe->cbBlob-2; i > 0 && dbe->pBlob[i] != 0; i--) ; + i++; + + if (dbe->pBlob[i] != 0) + { + TCHAR absFile[MAX_PATH] = _T(""); + CallService(MS_UTILS_PATHTOABSOLUTET,(WPARAM) &dbe->pBlob[i], (LPARAM)absFile); + if(absFile != NULL) + { + HBITMAP hBmp = (HBITMAP) CallService(MS_IMG_LOAD, (WPARAM) absFile, IMGL_TCHAR); + + if (hBmp != NULL) + { + buffer.append("\\line ", 7); + GetRTFFor(&buffer, hBmp); + DeleteObject(hBmp); + } + } + } + + buffer.append(' '); + buffer.pack(); + ret = buffer.detach(); + } + + return ret; +} + diff --git a/plugins/AvatarHistory/AvatarHistory.h b/plugins/AvatarHistory/AvatarHistory.h new file mode 100644 index 0000000000..25ec454de2 --- /dev/null +++ b/plugins/AvatarHistory/AvatarHistory.h @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include //for ImageList_* +#include +#include +#include + + +#define MIRANDA_VER 0x0900 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Globals +extern HINSTANCE hInst; +extern HANDLE hMenu; +extern DWORD mirVer; +extern HANDLE hAvatarWindowsList; + +#include "resource.h" +#include "m_avatarhist.h" + +#include "../utils/mir_buffer.h" + +#include "../historyevents/m_historyevents.h" + +#define MODULE_NAME "AvatarHistory" + +#define AVH_DEF_POPUPFG 0 +#define AVH_DEF_POPUPBG 0x2DB6FF +#define AVH_DEF_AVPOPUPS 0 +#define AVH_DEF_LOGTODISK 1 +#define AVH_DEF_LOGKEEPSAMEFOLDER 0 +#define AVH_DEF_LOGOLDSTYLE 0 +#define AVH_DEF_LOGTOHISTORY 1 +#define AVH_DEF_DEFPOPUPS 0 +#define AVH_DEF_SHOWMENU 1 + +#define DEFAULT_TEMPLATE_REMOVED LPGENT("removed his/her avatar") +#define DEFAULT_TEMPLATE_CHANGED LPGENT("changed his/her avatar") + +void LoadOptions(); + + // from icolib.cpp +void SetupIcoLib(); + +HICON createDefaultOverlayedIcon(BOOL big); +HICON createProtoOverlayedIcon(HANDLE hContact); + +int PreBuildContactMenu(WPARAM wParam,LPARAM lParam); +int IcoLibIconsChanged(WPARAM wParam,LPARAM lParam); + +int OpenAvatarDialog(HANDLE hContact, char* fn); + +#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) ) + +#define POPUP_ACTION_DONOTHING 0 +#define POPUP_ACTION_CLOSEPOPUP 1 +#define POPUP_ACTION_OPENAVATARHISTORY 2 +#define POPUP_ACTION_OPENHISTORY 3 + +#define POPUP_DELAY_DEFAULT 0 +#define POPUP_DELAY_CUSTOM 1 +#define POPUP_DELAY_PERMANENT 2 + + +struct Options { + // Log + BOOL log_per_contact_folders; + BOOL log_keep_same_folder; + BOOL log_store_as_hash; + + // Popup + BOOL popup_show_changed; + TCHAR popup_changed[1024]; + BOOL popup_show_removed; + TCHAR popup_removed[1024]; + WORD popup_delay_type; + WORD popup_timeout; + BYTE popup_use_win_colors; + BYTE popup_use_default_colors; + COLORREF popup_bkg_color; + COLORREF popup_text_color; + WORD popup_left_click_action; + WORD popup_right_click_action; +}; + +extern Options opts; + + +#include "popup.h" diff --git a/plugins/AvatarHistory/AvatarHistory.rc b/plugins/AvatarHistory/AvatarHistory.rc new file mode 100644 index 0000000000..c9da3d1e39 --- /dev/null +++ b/plugins/AvatarHistory/AvatarHistory.rc @@ -0,0 +1,236 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1252) + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU +BEGIN + POPUP "Avatar List Popup" + BEGIN + MENUITEM "Save As...", ID_AVATARLISTPOPUP_SAVEAS + MENUITEM "Delete this entry", ID_AVATARLISTPOPUP_DELETE + MENUITEM "Delete this entry and the bitmap file", ID_AVATARLISTPOPUP_DELETE_BOTH + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_AVATARDLG DIALOGEX 0, 0, 216, 195 +STYLE DS_SETFONT | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Avatar History" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + LISTBOX IDC_AVATARLIST,7,7,110,74,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + CONTROL "",IDC_AVATAR,"Static",SS_BITMAP | SS_NOTIFY | SS_CENTERIMAGE | SS_REALSIZEIMAGE | SS_SUNKEN,125,7,84,74 + LTEXT "Static",IDC_AVATARPATH,7,105,204,26 + PUSHBUTTON "Open Folder",IDC_OPENFOLDER,6,81,49,14 + PUSHBUTTON "<",IDC_BACK,138,82,31,10,BS_CENTER | BS_VCENTER + PUSHBUTTON ">",IDC_NEXT,172,82,31,10,BS_CENTER | BS_VCENTER + CONTROL "Store this user's old avatars in disk",IDC_LOGUSER, + "Button",BS_AUTO3STATE | WS_TABSTOP,7,135,202,10 + CONTROL "Log this user's avatars changes to history",IDC_HISTORYUSER, + "Button",BS_AUTO3STATE | WS_TABSTOP,7,147,202,10 + CONTROL "Show popups for this user",IDC_POPUPUSER,"Button",BS_AUTO3STATE | WS_TABSTOP,7,159,202,10 + DEFPUSHBUTTON "OK",IDOK,73,169,50,14 +END + +IDD_OPTIONS DIALOGEX 0, 0, 314, 173 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Protocols",IDC_PROTOCOLS_G,3,3,308,157 + LTEXT "Enable tracking for these protocols:",IDC_PROTOCOLS_L,13,17,157,11 + CONTROL "List1",IDC_PROTOCOLS,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SORTASCENDING | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,12,31,158,119 + LTEXT "MetaContacts have special handling: the info is always copied from subcontacts (notifications from a meta are ignored)",IDC_STATIC,181,31,124,119 +END + +IDD_POPUPS DIALOGEX 0, 0, 314, 235 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "Show popup when a contact change his avatar",IDC_POPUPS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,3,308,12 + GROUPBOX "Colours",IDC_COLOURS_G,3,25,158,75 + CONTROL "",IDC_BGCOLOR,"ColourPicker",WS_TABSTOP,12,37,34,14 + LTEXT "Background colour",IDC_BGCOLOR_L,55,41,89,8 + CONTROL "",IDC_TEXTCOLOR,"ColourPicker",WS_TABSTOP,12,55,34,14 + LTEXT "Text colour",IDC_TEXTCOLOR_L,55,59,89,8 + CONTROL "Use Windows colours",IDC_WINCOLORS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,74,132,10 + CONTROL "Use default colours",IDC_DEFAULTCOLORS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,84,132,10 + GROUPBOX "Delay",IDC_DELAY_G,166,25,145,75 + CONTROL "From popup plugin",IDC_DELAYFROMPU,"Button",BS_AUTORADIOBUTTON | WS_GROUP,174,38,131,10 + CONTROL "Custom",IDC_DELAYCUSTOM,"Button",BS_AUTORADIOBUTTON,174,52,131,10 + CONTROL "Permanent",IDC_DELAYPERMANENT,"Button",BS_AUTORADIOBUTTON,174,82,131,10 + EDITTEXT IDC_DELAY,208,65,31,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "Spin1",IDC_DELAY_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,239,67,11,11 + GROUPBOX "Actions",IDC_ACTIONS_G,3,103,308,47 + RTEXT "On right click:",IDC_RIGHT_ACTION_L,13,118,131,9 + COMBOBOX IDC_RIGHT_ACTION,149,116,156,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "On left click:",IDC_LEFT_ACTION_L,13,132,131,9 + COMBOBOX IDC_LEFT_ACTION,149,132,156,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Track",IDC_TRACK_G,3,153,308,47 + CONTROL "Avatar change:",IDC_CHANGED_L,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,166,89,10 + EDITTEXT IDC_CHANGED,105,166,200,13,ES_AUTOHSCROLL + CONTROL "Avatar removal:",IDC_REMOVED_L,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,183,89,10 + EDITTEXT IDC_REMOVED,105,183,200,13,ES_AUTOHSCROLL + PUSHBUTTON "Preview",IDC_PREV,132,206,50,14 +END + +IDD_FIRST_RUN DIALOGEX 0, 0, 451, 253 +STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Avatar History: Select how to store history avatars" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + LTEXT "Please select how the avatar history should be stored. This setting can NOT be changed in future, because it would cause all previous history to be lost.",IDC_STATIC,15,7,416,23 + CONTROL "Store history in miranda history and all history avatars in same folder",IDC_MIR_SAME, + "Button",BS_AUTORADIOBUTTON | WS_GROUP,15,32,416,11 + CONTROL "Store history in miranda history and history avatars in per protocol folders",IDC_MIR_PROTO, + "Button",BS_AUTORADIOBUTTON,15,66,416,11 + CONTROL "Store history in miranda history and history avatars in per contact folders using shortcuts",IDC_MIR_SHORT, + "Button",BS_AUTORADIOBUTTON,15,99,416,11 + CONTROL "Store history avatars in per contact folders using shortcuts",IDC_SHORT, + "Button",BS_AUTORADIOBUTTON,15,140,416,11 + CONTROL "Store history avatars in per contact folders",IDC_DUP, + "Button",BS_AUTORADIOBUTTON,15,181,416,11 + LTEXT "History is stored inside miranda db. It can be seen by History++ or Avatar History internal viewer.",IDC_STATIC,15,44,416,10 + LTEXT "All avatars are stored as \\Avatars History\\",IDC_STATIC,15,54,416,10 + LTEXT "History is stored inside miranda db. It can be seen by History++ or Avatar History internal viewer.",IDC_STATIC,15,77,416,10 + LTEXT "All avatars are stored as \\Avatars History\\\\",IDC_STATIC,15,87,416,10 + LTEXT "History is stored inside miranda db. It can be seen by History++ or Avatar History internal viewer.",IDC_STATIC,15,110,416,10 + LTEXT "All avatars are stored as \\Avatars History\\\\ and have a shortcut per history entry in \\Avatars History\\\\\\",IDC_STATIC,15,120,416,18 + LTEXT "History is stored only in disk. It can be seen by Avatar History internal viewer.",IDC_STATIC,15,151,416,10 + LTEXT "All avatars are stored as \\Avatars History\\\\ and have a shortcut per history entry in \\Avatars History\\\\\\",IDC_STATIC,15,161,416,18 + LTEXT "History is stored only in disk. It can be seen by Avatar History internal viewer.",IDC_STATIC,15,192,416,10 + LTEXT "All avatars are stored as \\Avatars History\\\\\\ (the same image can be stored lot of times)",IDC_STATIC,15,203,416,18 + DEFPUSHBUTTON "OK",IDOK,151,232,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_AVATARDLG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 209 + VERTGUIDE, 203 + TOPMARGIN, 7 + BOTTOMMARGIN, 159 + END + + IDD_OPTIONS, DIALOG + BEGIN + LEFTMARGIN, 3 + RIGHTMARGIN, 311 + TOPMARGIN, 3 + BOTTOMMARGIN, 171 + HORZGUIDE, 150 + END + + IDD_POPUPS, DIALOG + BEGIN + LEFTMARGIN, 3 + RIGHTMARGIN, 311 + VERTGUIDE, 12 + VERTGUIDE, 144 + VERTGUIDE, 174 + VERTGUIDE, 305 + TOPMARGIN, 3 + BOTTOMMARGIN, 225 + END + + IDD_FIRST_RUN, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 443 + VERTGUIDE, 15 + VERTGUIDE, 431 + TOPMARGIN, 7 + BOTTOMMARGIN, 246 + END +END +#endif // APSTUDIO_INVOKED + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (United Kingdom) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (United Kingdom) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/AvatarHistory/AvatarHistory.vcxproj b/plugins/AvatarHistory/AvatarHistory.vcxproj new file mode 100644 index 0000000000..e5b0fb0b25 --- /dev/null +++ b/plugins/AvatarHistory/AvatarHistory.vcxproj @@ -0,0 +1,564 @@ +п»ї + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + Unicode Debug + Win32 + + + Unicode Debug + x64 + + + Unicode Release + Win32 + + + Unicode Release + x64 + + + + + + + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + Unicode + + + DynamicLibrary + false + MultiByte + + + DynamicLibrary + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + avatarhistW + $(SolutionDir)$(Platform)\$(Configuration)\Plugins\ + $(SolutionDir)obj\$(Platform)\$(Configuration)\ + + + true + avatarhistW + $(SolutionDir)$(Platform)\$(Configuration)\Plugins\ + $(SolutionDir)obj\$(Platform)\$(Configuration)\ + + + true + avatarhistW + $(SolutionDir)$(Platform)\$(Configuration)\Plugins\ + $(SolutionDir)obj\$(Platform)\$(Configuration)\ + + + true + avatarhistW + $(SolutionDir)$(Platform)\$(Configuration)\Plugins\ + $(SolutionDir)obj\$(Platform)\$(Configuration)\ + + + false + avatarhistW + $(SolutionDir)$(Platform)\$(Configuration)\Plugins\ + $(SolutionDir)obj\$(Platform)\$(Configuration)\ + + + false + avatarhistW + $(SolutionDir)$(Platform)\$(Configuration)\Plugins\ + $(SolutionDir)obj\$(Platform)\$(Configuration)\ + + + false + avatarhistW + $(SolutionDir)$(Platform)\$(Configuration)\Plugins\ + $(SolutionDir)obj\$(Platform)\$(Configuration)\ + + + false + avatarhistW + $(SolutionDir)obj\$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\Plugins\ + + + + MultiThreadedDebug + Default + false + Disabled + true + Level3 + true + EditAndContinue + ../../include;sdk;%(AdditionalIncludeDirectories) + DBGPOPUPS;WIN32;_DEBUG;_WINDOWS;_USRDLL;AvatarHistory_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + AvatarHistory.h + + + true + _DEBUG;%(PreprocessorDefinitions) + .\Debug\AvatarHistory.tlb + true + Win32 + + + 0x0809 + _DEBUG;%(PreprocessorDefinitions) + + + true + $(IntDir)$(TargetName).bsc + + + true + true + true + Console + .\Debug\avatarhist.lib + comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName).pdb + + + if not exist "$(OutputPath)Docs\" mkdir "$(OutputPath)Docs\" +copy "$(ProjectDir)Docs\*.*" "$(OutputPath)Docs\" + + + Preparing Release + + + + + MultiThreadedDebug + Default + false + Disabled + true + Level3 + ProgramDatabase + ../../include;sdk;%(AdditionalIncludeDirectories) + DBGPOPUPS;_WIN64;_DEBUG;_WINDOWS;_USRDLL;AvatarHistory_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + AvatarHistory.h + + + true + _DEBUG;%(PreprocessorDefinitions) + .\Debug\AvatarHistory.tlb + true + + + 0x0809 + _DEBUG;%(PreprocessorDefinitions) + + + true + $(IntDir)$(TargetName).bsc + + + true + true + true + Console + .\Debug\avatarhist.lib + comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName).pdb + + + if not exist "$(OutputPath)Docs\" mkdir "$(OutputPath)Docs\" +copy "$(ProjectDir)Docs\*.*" "$(OutputPath)Docs\" + + + Preparing Release + + + + + MultiThreadedDebug + Default + false + Disabled + true + Level3 + true + EditAndContinue + ../../include;sdk;%(AdditionalIncludeDirectories) + DBGPOPUPS;WIN32;_DEBUG;_WINDOWS;_UNICODE;UNICODE;_USRDLL;AvatarHistory_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + AvatarHistory.h + + + true + _DEBUG;%(PreprocessorDefinitions) + .\Unicode_Debug\AvatarHistory.tlb + true + Win32 + + + 0x0809 + _DEBUG;%(PreprocessorDefinitions) + + + true + $(IntDir)$(TargetName).bsc + + + true + true + true + Console + comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName).pdb + + + if not exist "$(OutputPath)Docs\" mkdir "$(OutputPath)Docs\" +copy "$(ProjectDir)Docs\*.*" "$(OutputPath)Docs\" + + + Preparing Release + + + + + MultiThreadedDebug + Default + false + Disabled + true + Level3 + ProgramDatabase + ../../include;sdk;%(AdditionalIncludeDirectories) + DBGPOPUPS;_WIN64;_DEBUG;_WINDOWS;_UNICODE;UNICODE;_USRDLL;AvatarHistory_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + AvatarHistory.h + + + true + _DEBUG;%(PreprocessorDefinitions) + .\Unicode_Debug\AvatarHistory.tlb + true + + + 0x0809 + _DEBUG;%(PreprocessorDefinitions) + + + true + $(IntDir)$(TargetName).bsc + + + true + true + true + Console + comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName).pdb + + + if not exist "$(OutputPath)Docs\" mkdir "$(OutputPath)Docs\" +copy "$(ProjectDir)Docs\*.*" "$(OutputPath)Docs\" + + + Preparing Release + + + + + MultiThreadedDLL + OnlyExplicitInline + true + true + MinSpace + true + Level3 + ../../include;sdk;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;AvatarHistory_EXPORTS;%(PreprocessorDefinitions) + false + AvatarHistory.h + + + true + NDEBUG;%(PreprocessorDefinitions) + .\Release\AvatarHistory.tlb + true + Win32 + + + 0x0809 + NDEBUG;%(PreprocessorDefinitions) + + + true + $(IntDir)$(TargetName).bsc + + + true + true + Console + false + comctl32.lib;%(AdditionalDependencies) + false + $(OutDir)$(TargetName).pdb + + + if not exist "$(OutputPath)Docs\" mkdir "$(OutputPath)Docs\" +copy "$(ProjectDir)Docs\*.*" "$(OutputPath)Docs\" + + + Preparing Release + + + + + MultiThreadedDLL + OnlyExplicitInline + true + true + MinSpace + true + Level3 + ../../include;sdk;%(AdditionalIncludeDirectories) + _WIN64;NDEBUG;_WINDOWS;_USRDLL;AvatarHistory_EXPORTS;%(PreprocessorDefinitions) + false + AvatarHistory.h + + + true + NDEBUG;%(PreprocessorDefinitions) + .\Release\AvatarHistory.tlb + true + + + 0x0809 + NDEBUG;%(PreprocessorDefinitions) + + + true + $(IntDir)$(TargetName).bsc + + + true + true + Console + false + .\Release\avatarhist.lib + comctl32.lib;%(AdditionalDependencies) + false + $(OutDir)$(TargetName).pdb + + + if not exist "$(OutputPath)Docs\" mkdir "$(OutputPath)Docs\" +copy "$(ProjectDir)Docs\*.*" "$(OutputPath)Docs\" + + + Preparing Release + + + + + MultiThreadedDLL + OnlyExplicitInline + true + true + MinSpace + true + Level3 + ../../include;sdk;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_UNICODE;UNICODE;_USRDLL;AvatarHistory_EXPORTS;%(PreprocessorDefinitions) + false + AvatarHistory.h + + + true + NDEBUG;%(PreprocessorDefinitions) + .\Unicode_Release\AvatarHistory.tlb + true + Win32 + + + 0x0809 + NDEBUG;%(PreprocessorDefinitions) + + + true + $(IntDir)$(TargetName).bsc + + + true + true + Console + false + comctl32.lib;%(AdditionalDependencies) + false + $(OutDir)$(TargetName).pdb + + + if not exist "$(OutputPath)Docs\" mkdir "$(OutputPath)Docs\" +copy "$(ProjectDir)Docs\*.*" "$(OutputPath)Docs\" + + + Preparing Release + + + + + MultiThreadedDLL + OnlyExplicitInline + true + true + MinSpace + true + Level3 + ../../include;sdk;%(AdditionalIncludeDirectories) + _WIN64;NDEBUG;_WINDOWS;_UNICODE;UNICODE;_USRDLL;AvatarHistory_EXPORTS;%(PreprocessorDefinitions) + false + AvatarHistory.h + + + true + NDEBUG;%(PreprocessorDefinitions) + .\Unicode_Release\AvatarHistory.tlb + true + + + 0x0809 + NDEBUG;%(PreprocessorDefinitions) + + + true + $(IntDir)$(TargetName).bsc + + + true + true + Console + false + comctl32.lib;%(AdditionalDependencies) + $(OutDir)$(TargetName).pdb + false + + + if not exist "$(OutputPath)Docs\" mkdir "$(OutputPath)Docs\" +copy "$(ProjectDir)Docs\*.*" "$(OutputPath)Docs\" + + + Preparing Release + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/AvatarHistory/AvatarHistory.vcxproj.filters b/plugins/AvatarHistory/AvatarHistory.vcxproj.filters new file mode 100644 index 0000000000..b405a21122 --- /dev/null +++ b/plugins/AvatarHistory/AvatarHistory.vcxproj.filters @@ -0,0 +1,82 @@ +п»ї + + + + {82b52cc9-91bf-46bb-b045-52e8df41b13d} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {e28f6fa3-76df-4c8d-8454-ee929e07f290} + h;hpp;hxx;hm;inl + + + {6ad471fb-470c-4466-b817-ec90cb51260c} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + {72021e6b-0e9b-4cf3-b35f-db87ed4f6541} + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Docs + + + Docs + + + Docs + + + Docs + + + \ No newline at end of file diff --git a/plugins/AvatarHistory/AvatarOverlay.ico b/plugins/AvatarHistory/AvatarOverlay.ico new file mode 100644 index 0000000000..63557bad99 Binary files /dev/null and b/plugins/AvatarHistory/AvatarOverlay.ico differ diff --git a/plugins/AvatarHistory/Docs/avatarhist.png b/plugins/AvatarHistory/Docs/avatarhist.png new file mode 100644 index 0000000000..e9619f63a0 Binary files /dev/null and b/plugins/AvatarHistory/Docs/avatarhist.png differ diff --git a/plugins/AvatarHistory/Docs/avatarhist_changelog.txt b/plugins/AvatarHistory/Docs/avatarhist_changelog.txt new file mode 100644 index 0000000000..8689c4b656 --- /dev/null +++ b/plugins/AvatarHistory/Docs/avatarhist_changelog.txt @@ -0,0 +1,78 @@ +Avatar History + +Changelog: + +. 0.0.3.3 ++ Added Updater support + +. 0.0.3.2 +-Show contact display name in save dialog +-Added hidden debug setting: +Add BYTE "Debug" in "AvatarHistory" module to show debug popups. +ATTENTION: This is only recommended for advanced users to find problems, +in normal usage they tend to become annoying +-Fixed popups for removed avatars +-Updated m_folders.h +-Allow plugin to load in Miranda 0.9.50 + + +. 0.0.3.1 ++ Show Contact Name in Avatar History dialog title ++ Show picture path in avatar history dialog ++ support for WindowList +* fixed some issues reported by borkra ++ updated m_folders.h +* fixed duplicate avatar notifications (thanks xaos) + +. 0.0.3.0 +THIS REQUIRES MIRANDA IM 0.10 ALPHA #3 OR ABOVE!! + + added x64 version + + improved unicode support + + added sounds + + added more debug information + * save position of avatar history dialog + ! fixed crash with empty avatar history + * BMP files are not converted to PNG any more + * fixed Updater support + + +. 0.0.2.10 + * Fix for get event text + +. 0.0.2.9 + + Depends on history events to add events to history + +. 0.0.2.8 + * Fix for radios in first run dialog + +. 0.0.2.7 + + Added first run dialog and option to store avatars as version 1 + * Changed to stop using avs services and use freeiamge services (requires miranda 0.7 #28) + +. 0.0.2.6 + * Changed to always use online proto icon as base for popup icon + +. 0.0.2.5 + + Added support for Miranda 0.8 + +. 0.0.2.4 + * Try to fix blank images + +. 0.0.2.3 + + Hide contact menu item for disabled protocols + + Create shortcuts for metacontacts if it is a enabled protocol + +. 0.0.2.2 + * Bug fixes (thanks borkra) + + Use shortcuts in avatar history dialog when history log is disabled (thanks Let) + + Option to delete only the entry or it and the avatar image + * Moved default place of menu entry to bellow View History + * Using default Miranda icon for History if possible + * Using icon based on avs for overlay + * Small changes in options dialog + +. 0.0.2.0 + * Changed to store avatars in a proto dir (lost compatibility with old version) + * Changes in options and avatar dialog + + Keep only one copy of an image (even if contact switchs back to it) + + Updater support \ No newline at end of file diff --git a/plugins/AvatarHistory/Docs/avatarhist_readme.txt b/plugins/AvatarHistory/Docs/avatarhist_readme.txt new file mode 100644 index 0000000000..b07d99ee40 --- /dev/null +++ b/plugins/AvatarHistory/Docs/avatarhist_readme.txt @@ -0,0 +1,29 @@ +Avatar History plugin +----------------------------------- + +CAUTION: THIS IS AN BETA STAGE PLUGIN. IT CAN DO VERY BAD THINGS. USE AT YOUR OWN RISK. + +This plugins keep a history of contact avatars. It stores the files on the disk and uses miranda history to keep track of then. + +This plugin is really made by MattJ, I'm only doing some changes to allow better handling of the avatars. + +If you want to import the old history to new format, you can use the Avatar History Importer plugin by TioDuke. It will import old avatars to new format, allowing to keep only one copy of each avatar (but new avatars may appear duplicated, because the hash function used by the importer may not be the same as the one used by the protocol). It can be downloaded at: +Avatar History Importer Ansi Dll: http://pescuma.mirandaim.ru/miranda/avh_imp.zip +Avatar History Importer Unicode Dll: http://pescuma.mirandaim.ru/miranda/avh_impW.zip +Avatar History Importer Source: http://pescuma.mirandaim.ru/miranda/avh_imp_src.zip + +To user the importer, you should: +1. Backup your profile and the old avatar history folder +2. Install the new version of Avatar History +3. Start miranda with all protocols offline +4. Setup Avatar History options (some are better if set once and not changed anymore). You will need 'Show expert options' checkbox enabled +5. Finish miranda and install Avatar History Importer +6. Start miranda with all protocols offline +7. A messagebox will appear, telling that the importer will run. Wait until the importer ended messagebox. +8. Enjoy ;) + +Now all avatars are stored in per protocol folders. This is done to allow avoiding duplicated avatars. (If you enable 'Keep all in same folder' there will be only one folder for all protocols - this may help in case you have more than one instance of the same proto). The relation avatar <-> contact and the avatar history dialog is created from info from the contact history (and not using the files in HD). Since some people like to see the images in contacts folders, there is the option 'Also create per contact folders with shortcuts'. This option will create the contact folders (as previous version) and will create shortcuts inside it to the avatar stored in the protocol folder (if 2 avatars are the same, there will be 2 shortcuts but only one avatar in disk). Importer will use this option too when importing, but you must set it before importing everything. + +This plugin needs Avatar Service and Miranda 0.7 to be able to work. To log events to history it needs History Events plugin. + +To report bugs/make suggestions, go to the forum thread: http://forums.miranda-im.org/showthread.php?t=9118 diff --git a/plugins/AvatarHistory/Docs/avatarhist_version.txt b/plugins/AvatarHistory/Docs/avatarhist_version.txt new file mode 100644 index 0000000000..7ed8590d76 --- /dev/null +++ b/plugins/AvatarHistory/Docs/avatarhist_version.txt @@ -0,0 +1 @@ +Avatar History 0.0.2.10 \ No newline at end of file diff --git a/plugins/AvatarHistory/Docs/langpack_avatarhist.txt b/plugins/AvatarHistory/Docs/langpack_avatarhist.txt new file mode 100644 index 0000000000..2bad91ae78 --- /dev/null +++ b/plugins/AvatarHistory/Docs/langpack_avatarhist.txt @@ -0,0 +1,114 @@ +; Avatar History +; Author: MattJ and Pescuma + +[Avatar History] + +; Menu + +[View Avatar History] + +; Custom folders + +[Avatars] + +; Options + +[History] +[Avatar] + +[ Logging options ] +[Store old avatars on disk] +[Also create per contact folders with shortcuts] +[Log avatar changes to history] + +[ History templates ] +[Avatar change:] +[Track when contacts remove their avatars too] +[Avatar removal:] + +[ Protocols ] +[Enable tracking for these protocols:] +[Keep all in same folder] + +[Popups] +[Avatar Change] + +[Show popup when a contact change his avatar] + +[ Colours ] +[Background colour] +[Text colour] +[Use Windows colours] +[Use default colours] + +[ Delay ] +[From popup plugin] +[Custom] +[Permanent] + +[ Actions ] +[On right click:] +[On left click:] +[Do nothing] +[Close popup] +[Show avatar history] +[Show contact history] + +[Preview] + + +; Test popup + +[Test Contact] +[Test description] + + +; First run dialog + +[Avatar History: Select how to store history avatars] +[Please select how the avatar history should be stored. This setting can NOT be changed in future, because it would cause all previous history to be lost.] +[Store history in miranda history and all history avatars in same folder] +[History is stored inside miranda db. It can be seen by History++ or Avatar History internal viewer.] +[All avatars are stored as \\Avatars History\\] +[Store history in miranda history and history avatars in per protocol folders] +[All avatars are stored as \\Avatars History\\\\] +[Store history in miranda history and history avatars in per contact folders using shortcuts] +[All avatars are stored as \\Avatars History\\\\ and have a shortcut per history entry in \\Avatars History\\\\\\] +[Store history avatars in per contact folders using shortcut] +[History is stored only in disk. It can be seen by Avatar History internal viewer.] +[All avatars are stored as \\Avatars History\\\\ and have a shortcut per history entry in \\Avatars History\\\\\\] +[Store history avatars in per contact folders] +[All avatars are stored as \\Avatars History\\\\\\ (the same image can be stored lot of times)] +[OK] + +; Avatar dialog + +[Open Folder] +[Save] +[Delete] +[<] +[>] +[Store this user's old avatars in disk] +[Log this user's avatars changes to history] +[Show popups for this user] +[OK] +[Save As...] +[Delete this entry] +[Delete this entry and the bitmap file] + + +; Others + +[Please select an avatar from the list] +[No avatar selected] + +[Delete avatar log?] +[Are you sure you wish to delete this history entry?\nOnly the entry in history will be deleted, bitmap file will be kept!] +[Are you sure you wish to delete this avatar shortcut?\nOnly shortcut will be deleted, bitmap file will be kept!] + +[Delete avatar?] +[Are you sure you wish to delete this archived avatar?\nThis will delete the history entry and the bitmap file.\nWARNING:This can affect more than one entry in history!] +[Are you sure you wish to delete this archived avatar?\nThis will delete the shortcut and the bitmap file.\nWARNING:This can affect more than one shortcut!] + +[Unknown Protocol] +[Unknown UIN] diff --git a/plugins/AvatarHistory/history.ico b/plugins/AvatarHistory/history.ico new file mode 100644 index 0000000000..4b56c86221 Binary files /dev/null and b/plugins/AvatarHistory/history.ico differ diff --git a/plugins/AvatarHistory/icolib.cpp b/plugins/AvatarHistory/icolib.cpp new file mode 100644 index 0000000000..b8e54b0807 --- /dev/null +++ b/plugins/AvatarHistory/icolib.cpp @@ -0,0 +1,135 @@ +#include "AvatarHistory.h" + +enum IconIndex +{ + I_HISTORY, + I_OVERLAY +}; + +typedef struct +{ + TCHAR* szDescr; + char* szName; + int defIconID; + BOOL core; +} IconStruct; + +static IconStruct iconList[] = +{ + { LPGENT("History"), "core_main_10", IDI_AVATARHIST, TRUE }, + { LPGENT("Avatar Overlay"), "avh_overlay", IDI_AVATAROVERLAY, FALSE } +}; + +extern HANDLE hHooks[]; + +static HICON LoadIconEx(IconIndex i) +{ + HICON hIcon; + + if (hHooks[4]) + hIcon = (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)iconList[(int)i].szName); + else + hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(iconList[(int)i].defIconID), + IMAGE_ICON, 0, 0, 0); + + return hIcon; +} + + +static void ReleaseIconEx(HICON hIcon) +{ + if (hHooks[4]) + CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0); + else + DestroyIcon(hIcon); +} + +static void IcoLibUpdateMenus() +{ + CLISTMENUITEM mi = {0}; + + mi.cbSize = sizeof(mi); + mi.flags = CMIM_FLAGS | CMIM_ICON; + mi.hIcon = createDefaultOverlayedIcon(FALSE); + CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )hMenu, ( LPARAM )&mi ); + DestroyIcon(mi.hIcon); +} + +int IcoLibIconsChanged(WPARAM wParam, LPARAM lParam) +{ + IcoLibUpdateMenus(); + return 0; +} + +void SetupIcoLib() +{ + if (hHooks[4]) + { + SKINICONDESC sid = {0}; + TCHAR path[MAX_PATH]; + + GetModuleFileName(hInst, path, sizeof(path)); + + sid.cbSize = SKINICONDESC_SIZE; + sid.ptszSection = LPGENT("Avatar History"); + sid.ptszDefaultFile = path; + sid.flags = SIDF_ALL_TCHAR; + + for (unsigned i = 0; i < MAX_REGS(iconList); i++) + { + if (!iconList[i].core) + { + sid.ptszDescription = iconList[i].szDescr; + sid.pszName = iconList[i].szName; + sid.iDefaultIndex = -iconList[i].defIconID; + CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); + } + } + } + IcoLibUpdateMenus(); +} + +static HICON getOverlayedIcon(HICON icon, HICON overlay, BOOL big) +{ + HIMAGELIST il = ImageList_Create( + GetSystemMetrics(big?SM_CXICON:SM_CXSMICON), + GetSystemMetrics(big?SM_CYICON:SM_CYSMICON), + ILC_COLOR32|ILC_MASK, 2, 2); + ImageList_AddIcon(il, icon); + ImageList_AddIcon(il, overlay); + HIMAGELIST newImage = ImageList_Merge(il,0,il,1,0,0); + ImageList_Destroy(il); + HICON hIcon = ImageList_GetIcon(newImage, 0, 0); + ImageList_Destroy(newImage); + return hIcon; // the result should be destroyed by DestroyIcon() +} + + +HICON createDefaultOverlayedIcon(BOOL big) +{ + HICON icon0 = LoadIconEx(I_HISTORY); + HICON icon1 = LoadIconEx(I_OVERLAY); + + HICON resIcon = getOverlayedIcon(icon0, icon1, FALSE); + + ReleaseIconEx(icon0); + ReleaseIconEx(icon1); + + return resIcon; +} + + +HICON createProtoOverlayedIcon(HANDLE hContact) +{ + HICON icon1 = LoadIconEx(I_OVERLAY); + + char *szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + HICON icon0 = LoadSkinnedProtoIcon(szProto, ID_STATUS_ONLINE); + + HICON resIcon = getOverlayedIcon(icon0, icon1, FALSE); + + ReleaseIconEx(icon1); + CallService(MS_SKIN2_RELEASEICON, (WPARAM)icon0, 0); + + return resIcon; +} diff --git a/plugins/AvatarHistory/options.cpp b/plugins/AvatarHistory/options.cpp new file mode 100644 index 0000000000..2d1a75116a --- /dev/null +++ b/plugins/AvatarHistory/options.cpp @@ -0,0 +1,234 @@ +/* +Avatar History Plugin + Copyright (C) 2006 Matthew Wild - Email: mwild1@gmail.com + + 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "AvatarHistory.h" +#include "../utils/mir_options.h" + + + +// Prototypes ///////////////////////////////////////////////////////////////////////////////////// + +Options opts; + + +static INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +static INT_PTR CALLBACK PopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + + +static OptPageControl optionsControls[] = { + { NULL, CONTROL_PROTOCOL_LIST, IDC_PROTOCOLS, "%sEnabled", TRUE } +}; + + +static OptPageControl popupsControls[] = { + { NULL, CONTROL_CHECKBOX, IDC_POPUPS, "AvatarPopups", AVH_DEF_AVPOPUPS }, + { &opts.popup_bkg_color, CONTROL_COLOR, IDC_BGCOLOR, "PopupsBgColor", AVH_DEF_POPUPBG }, + { &opts.popup_text_color, CONTROL_COLOR, IDC_TEXTCOLOR, "PopupsTextColor", AVH_DEF_POPUPFG }, + { &opts.popup_use_win_colors, CONTROL_CHECKBOX, IDC_WINCOLORS, "PopupsWinColors", FALSE }, + { &opts.popup_use_default_colors, CONTROL_CHECKBOX, IDC_DEFAULTCOLORS, "PopupsDefaultColors", AVH_DEF_DEFPOPUPS }, + { &opts.popup_delay_type, CONTROL_RADIO, IDC_DELAYFROMPU, "PopupsDelayType", POPUP_DELAY_DEFAULT, POPUP_DELAY_DEFAULT }, + { NULL, CONTROL_RADIO, IDC_DELAYCUSTOM, "PopupsDelayType", POPUP_DELAY_DEFAULT, POPUP_DELAY_CUSTOM }, + { NULL, CONTROL_RADIO, IDC_DELAYPERMANENT, "PopupsDelayType", POPUP_DELAY_DEFAULT, POPUP_DELAY_PERMANENT }, + { &opts.popup_timeout, CONTROL_SPIN, IDC_DELAY, "PopupsTimeout", 10, IDC_DELAY_SPIN, (WORD) 1, (WORD) 255 }, + { &opts.popup_right_click_action, CONTROL_COMBO, IDC_RIGHT_ACTION, "PopupsRightClick", POPUP_ACTION_CLOSEPOPUP }, + { &opts.popup_left_click_action, CONTROL_COMBO, IDC_LEFT_ACTION, "PopupsLeftClick", POPUP_ACTION_OPENAVATARHISTORY }, + { &opts.popup_show_changed, CONTROL_CHECKBOX, IDC_CHANGED_L, "PopupsShowChanged", TRUE }, + { &opts.popup_changed, CONTROL_TEXT, IDC_CHANGED, "PopupsTextChanged", (ULONG_PTR) DEFAULT_TEMPLATE_CHANGED }, + { &opts.popup_show_removed, CONTROL_CHECKBOX, IDC_REMOVED_L, "PopupsShowRemoved", TRUE }, + { &opts.popup_removed, CONTROL_TEXT, IDC_REMOVED, "PopupsTextRemoved", (ULONG_PTR) DEFAULT_TEMPLATE_REMOVED } +}; + +static UINT popupsExpertControls[] = { + IDC_COLOURS_G, IDC_BGCOLOR, IDC_BGCOLOR_L, IDC_TEXTCOLOR, IDC_TEXTCOLOR_L, IDC_WINCOLORS, IDC_DEFAULTCOLORS, + IDC_DELAY_G, IDC_DELAYFROMPU, IDC_DELAYCUSTOM, IDC_DELAYPERMANENT, IDC_DELAY, IDC_DELAY_SPIN, + IDC_ACTIONS_G, IDC_RIGHT_ACTION_L, IDC_RIGHT_ACTION, IDC_LEFT_ACTION_L, IDC_LEFT_ACTION, + IDC_PREV +}; + + +// Functions ////////////////////////////////////////////////////////////////////////////////////// + + +int OptInit(WPARAM wParam,LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp; + + ZeroMemory(&odp,sizeof(odp)); + odp.cbSize=sizeof(odp); + odp.position=0; + odp.hInstance=hInst; + odp.ptszGroup = LPGENT("History"); // group to put your item under + odp.ptszTitle = LPGENT("Avatar"); // name of the item + odp.pfnDlgProc = OptionsDlgProc; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR | ODPF_EXPERTONLY; + CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); + + if(ServiceExists(MS_POPUP_ADDPOPUPT)) + { + ZeroMemory(&odp,sizeof(odp)); + odp.cbSize=sizeof(odp); + odp.position=0; + odp.hInstance=hInst; + odp.ptszGroup = LPGENT("Popups"); + odp.ptszTitle = LPGENT("Avatar Change"); + odp.pfnDlgProc = PopupsDlgProc; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_POPUPS); + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; + odp.expertOnlyControls = popupsExpertControls; + odp.nExpertOnlyControls = MAX_REGS(popupsExpertControls); + odp.nIDBottomSimpleControl = IDC_POPUPS; + odp.nIDRightSimpleControl = IDC_POPUPS; + CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp); + } + + return 0; +} + + +void LoadOptions() +{ + LoadOpts(optionsControls, MAX_REGS(optionsControls), MODULE_NAME); + LoadOpts(popupsControls, MAX_REGS(popupsControls), MODULE_NAME); + + opts.log_per_contact_folders = DBGetContactSettingByte(NULL, MODULE_NAME, "LogPerContactFolders", 0); + opts.log_keep_same_folder = DBGetContactSettingByte(NULL, MODULE_NAME, "LogKeepSameFolder", 0); + opts.log_store_as_hash = DBGetContactSettingByte(NULL, MODULE_NAME, "StoreAsHash", 1); +} + + +static INT_PTR CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + return SaveOptsDlgProc(optionsControls, MAX_REGS(optionsControls), MODULE_NAME, hwndDlg, msg, wParam, lParam); +} + + +static void PopupsEnableDisableCtrls(HWND hwndDlg) +{ + BOOL enabled = IsDlgButtonChecked(hwndDlg, IDC_POPUPS); + + EnableWindow(GetDlgItem(hwndDlg, IDC_COLOURS_G), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_BGCOLOR_L), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTCOLOR_L), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELAY_G), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELAYFROMPU), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELAYCUSTOM), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELAYPERMANENT), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_ACTIONS_G), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_RIGHT_ACTION_L), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_RIGHT_ACTION), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_LEFT_ACTION_L), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_LEFT_ACTION), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_PREV), enabled); + + EnableWindow(GetDlgItem(hwndDlg, IDC_BGCOLOR), enabled && + !IsDlgButtonChecked(hwndDlg, IDC_WINCOLORS) && + !IsDlgButtonChecked(hwndDlg, IDC_DEFAULTCOLORS)); + EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTCOLOR), enabled && + !IsDlgButtonChecked(hwndDlg, IDC_WINCOLORS) && + !IsDlgButtonChecked(hwndDlg, IDC_DEFAULTCOLORS)); + EnableWindow(GetDlgItem(hwndDlg, IDC_DEFAULTCOLORS), enabled && + !IsDlgButtonChecked(hwndDlg, IDC_WINCOLORS)); + EnableWindow(GetDlgItem(hwndDlg, IDC_WINCOLORS), enabled && + !IsDlgButtonChecked(hwndDlg, IDC_DEFAULTCOLORS)); + + EnableWindow(GetDlgItem(hwndDlg, IDC_DELAY), enabled && + IsDlgButtonChecked(hwndDlg, IDC_DELAYCUSTOM)); + + EnableWindow(GetDlgItem(hwndDlg, IDC_CHANGED_L), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVED_L), enabled); + EnableWindow(GetDlgItem(hwndDlg, IDC_CHANGED), enabled && + IsDlgButtonChecked(hwndDlg, IDC_CHANGED_L)); + EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVED), enabled && + IsDlgButtonChecked(hwndDlg, IDC_REMOVED_L)); + +} + + +static INT_PTR CALLBACK PopupsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + { + SendDlgItemMessage(hwndDlg, IDC_RIGHT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Do nothing")); + SendDlgItemMessage(hwndDlg, IDC_RIGHT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Close popup")); + SendDlgItemMessage(hwndDlg, IDC_RIGHT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Show avatar history")); + SendDlgItemMessage(hwndDlg, IDC_RIGHT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Show contact history")); + + SendDlgItemMessage(hwndDlg, IDC_LEFT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Do nothing")); + SendDlgItemMessage(hwndDlg, IDC_LEFT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Close popup")); + SendDlgItemMessage(hwndDlg, IDC_LEFT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Show avatar history")); + SendDlgItemMessage(hwndDlg, IDC_LEFT_ACTION, CB_ADDSTRING, 0, (LPARAM) TranslateT("Show contact history")); + + // Needs to be called here in this case + BOOL ret = SaveOptsDlgProc(popupsControls, MAX_REGS(popupsControls), MODULE_NAME, hwndDlg, msg, wParam, lParam); + + PopupsEnableDisableCtrls(hwndDlg); + + return ret; + } + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDC_POPUPS: + case IDC_WINCOLORS: + case IDC_DEFAULTCOLORS: + case IDC_DELAYFROMPU: + case IDC_DELAYPERMANENT: + case IDC_DELAYCUSTOM: + case IDC_CHANGED_L: + case IDC_REMOVED_L: + { + if (HIWORD(wParam) == BN_CLICKED) + PopupsEnableDisableCtrls(hwndDlg); + + break; + } + case IDC_PREV: + { + Options op = opts; + + if (IsDlgButtonChecked(hwndDlg, IDC_DELAYFROMPU)) + op.popup_delay_type = POPUP_DELAY_DEFAULT; + else if (IsDlgButtonChecked(hwndDlg, IDC_DELAYCUSTOM)) + op.popup_delay_type = POPUP_DELAY_CUSTOM; + else if (IsDlgButtonChecked(hwndDlg, IDC_DELAYPERMANENT)) + op.popup_delay_type = POPUP_DELAY_PERMANENT; + + op.popup_timeout = GetDlgItemInt(hwndDlg,IDC_DELAY, NULL, FALSE); + op.popup_bkg_color = SendDlgItemMessage(hwndDlg,IDC_BGCOLOR,CPM_GETCOLOUR,0,0); + op.popup_text_color = SendDlgItemMessage(hwndDlg,IDC_TEXTCOLOR,CPM_GETCOLOUR,0,0); + op.popup_use_win_colors = IsDlgButtonChecked(hwndDlg, IDC_WINCOLORS) != 0; + op.popup_use_default_colors = IsDlgButtonChecked(hwndDlg, IDC_DEFAULTCOLORS) != 0; + + HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST,0,0); + ShowTestPopup(hContact,TranslateT("Test Contact"), TranslateT("Test description"), &op); + + break; + } + } + break; + } + } + + return SaveOptsDlgProc(popupsControls, MAX_REGS(popupsControls), MODULE_NAME, hwndDlg, msg, wParam, lParam); +} diff --git a/plugins/AvatarHistory/popup.cpp b/plugins/AvatarHistory/popup.cpp new file mode 100644 index 0000000000..dc03ee783d --- /dev/null +++ b/plugins/AvatarHistory/popup.cpp @@ -0,0 +1,279 @@ +/* +Copyright (C) 2005 Ricardo Pescuma Domenecci + +This is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this file; see the file license.txt. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + + +#include "AvatarHistory.h" + + + +// Prototypes ///////////////////////////////////////////////////////////////////////////////////// + +#define WMU_ACTION (WM_USER + 1) + + +LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +HWND hPopupWindow = NULL; + + +static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); +static LRESULT CALLBACK DumbPopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); + + + +// Functions ////////////////////////////////////////////////////////////////////////////////////// + + +// Initializations needed by popups +void InitPopups() +{ + // window needed for popup commands + hPopupWindow = CreateWindowEx(WS_EX_TOOLWINDOW, _T("static"), _T(MODULE_NAME) _T("_PopupWindow"), + 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, HWND_DESKTOP, + NULL, hInst, NULL); + SetWindowLong(hPopupWindow, GWLP_WNDPROC, (LONG_PTR)PopupWndProc); +} + + +// Deinitializations needed by popups +void DeInitPopups() +{ +} + + +// Show an error popup +void ShowErrPopup(const TCHAR *description, const TCHAR *title) +{ + ShowPopupEx(NULL, title == NULL ? _T(MODULE_NAME) _T(" Error") : title, description, + NULL, POPUP_TYPE_ERROR, NULL); +} + + +void ShowTestPopup(HANDLE hContact,const TCHAR *title, const TCHAR *description, const Options *op) +{ + ShowPopupEx(hContact, title, description, NULL, POPUP_TYPE_TEST, op); +} + + +void ShowPopup(HANDLE hContact, const TCHAR *title, const TCHAR *description) +{ + ShowPopupEx(hContact, title, description, hContact, POPUP_TYPE_NORMAL, &opts); +} + +void ShowDebugPopup(HANDLE hContact, const TCHAR *title, const TCHAR *description) +{ + if(DBGetContactSettingByte(NULL,MODULE_NAME,"Debug",0)) + { + ShowPopup(hContact,title,description); + } +} + +typedef struct +{ + void* plugin_data; + HICON hIcon; +} +PopupDataType; + +// Show an popup +void ShowPopupEx(HANDLE hContact, const TCHAR *title, const TCHAR *description, + void *plugin_data, int type, const Options *op) +{ + if(ServiceExists(MS_POPUP_ADDPOPUPT)) + { + // Make popup + POPUPDATAT ppd = {0}; + + ppd.lchContact = hContact; + ppd.lchIcon = createProtoOverlayedIcon(hContact); + + ppd.PluginData = mir_alloc(sizeof(PopupDataType)); + ((PopupDataType*)ppd.PluginData)->plugin_data = plugin_data; + ((PopupDataType*)ppd.PluginData)->hIcon = ppd.lchIcon; + + if (title != NULL) + lstrcpyn(ppd.lptzContactName, title, MAX_REGS(ppd.lptzContactName)); + else if (hContact != NULL) + lstrcpyn(ppd.lptzContactName, (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR | GCDNF_NOCACHE), + MAX_REGS(ppd.lptzContactName)); + + if (description != NULL) + lstrcpyn(ppd.lptzText, description, MAX_REGS(ppd.lptzText)); + + if (type == POPUP_TYPE_NORMAL || type == POPUP_TYPE_TEST) + { + if (op->popup_use_default_colors) + { + ppd.colorBack = 0; + ppd.colorText = 0; + } + else if (op->popup_use_win_colors) + { + ppd.colorBack = GetSysColor(COLOR_BTNFACE); + ppd.colorText = GetSysColor(COLOR_WINDOWTEXT); + } + else + { + ppd.colorBack = op->popup_bkg_color; + ppd.colorText = op->popup_text_color; + } + } + else // if (type == POPUP_TYPE_ERROR) + { + ppd.colorBack = RGB(200,0,0); + ppd.colorText = RGB(255,255,255); + } + + if (type == POPUP_TYPE_NORMAL) + { + ppd.PluginWindowProc = PopupDlgProc; + } + else // if (type == POPUP_TYPE_TEST || type == POPUP_TYPE_ERROR) + { + ppd.PluginWindowProc = DumbPopupDlgProc; + } + + if (type == POPUP_TYPE_NORMAL || type == POPUP_TYPE_TEST) + { + switch (op->popup_delay_type) + { + case POPUP_DELAY_CUSTOM: + ppd.iSeconds = opts.popup_timeout; + break; + + case POPUP_DELAY_PERMANENT: + ppd.iSeconds = -1; + break; + + case POPUP_DELAY_DEFAULT: + default: + ppd.iSeconds = 0; + break; + } + } + else // if (type == POPUP_TYPE_ERROR) + { + ppd.iSeconds = 0; + } + + // Now that every field has been filled, we want to see the popup. + PUAddPopUpT(&ppd); + } + else + { + MessageBox(NULL, description, title ? title : (TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR), + MB_OK); + } + +} + + +// Handle to the hidden windows to handle actions for popup clicks +// wParam has the number of MOTD in case of WMU_SHOW_MOTD_DETAILS +LRESULT CALLBACK PopupWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if (uMsg == WMU_ACTION) + { + if (lParam == POPUP_ACTION_OPENAVATARHISTORY) + { + CallService("AvatarHistory/ShowDialog", wParam, 0); + } + else if (lParam == POPUP_ACTION_OPENHISTORY) + { + CallService(MS_HISTORY_SHOWCONTACTHISTORY, wParam, 0); + } + } + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + + +// Handle to popup events +static LRESULT CALLBACK PopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) { + case WM_COMMAND: + { + PopupDataType* popup = (PopupDataType*)PUGetPluginData(hWnd); + PostMessage(hPopupWindow, WMU_ACTION, (WPARAM)popup->plugin_data, opts.popup_left_click_action); + + if (opts.popup_left_click_action != POPUP_ACTION_DONOTHING) + PUDeletePopUp(hWnd); + + return TRUE; + } + + case WM_CONTEXTMENU: + { + PopupDataType* popup = (PopupDataType*)PUGetPluginData(hWnd); + PostMessage(hPopupWindow, WMU_ACTION, (WPARAM)popup->plugin_data, opts.popup_right_click_action); + + if (opts.popup_right_click_action != POPUP_ACTION_DONOTHING) + PUDeletePopUp(hWnd); + + return TRUE; + } + + case UM_FREEPLUGINDATA: + { + PopupDataType* popup = (PopupDataType*)PUGetPluginData(hWnd); + if ((INT_PTR)popup != CALLSERVICE_NOTFOUND) + { + DestroyIcon(popup->hIcon); + mir_free(popup); + } + return FALSE; //the return value is ignored + } + } + + return DefWindowProc(hWnd, message, wParam, lParam); +} + + +// Handle to popup events +static LRESULT CALLBACK DumbPopupDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch(message) { + case WM_COMMAND: + { + PUDeletePopUp(hWnd); + return TRUE; + } + + case WM_CONTEXTMENU: + { + PUDeletePopUp(hWnd); + return TRUE; + } + + case UM_FREEPLUGINDATA: + { + PopupDataType* popup = (PopupDataType*)PUGetPluginData(hWnd); + if ((INT_PTR)popup != CALLSERVICE_NOTFOUND) + { + DestroyIcon(popup->hIcon); + mir_free(popup); + } + return FALSE; //the return value is ignored + } + } + + return DefWindowProc(hWnd, message, wParam, lParam); +} + + diff --git a/plugins/AvatarHistory/popup.h b/plugins/AvatarHistory/popup.h new file mode 100644 index 0000000000..2944ba0895 --- /dev/null +++ b/plugins/AvatarHistory/popup.h @@ -0,0 +1,53 @@ +/* +Copyright (C) 2005 Ricardo Pescuma Domenecci + +This is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this file; see the file license.txt. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + + +#ifndef __POPUP_H__ +# define __POPUP_H__ + +#include + + +// Initializations needed by popups +void InitPopups(); + +// Deinitializations needed by popups +void DeInitPopups(); + + +#define POPUP_TYPE_NORMAL 0 +#define POPUP_TYPE_TEST 1 +#define POPUP_TYPE_ERROR 2 + +// Show an popup +void ShowPopup(HANDLE hContact, const TCHAR *title, const TCHAR *description); +void ShowDebugPopup(HANDLE hContact, const TCHAR *title, const TCHAR *description); + +// Show an test +void ShowTestPopup(HANDLE hContact,const TCHAR *title, const TCHAR *description, const Options *op); + +// Show an error popup +void ShowErrPopup(const char *description, const char *title = NULL); + +void ShowPopupEx(HANDLE hContact, const TCHAR *title, const TCHAR *description, + void *plugin_data, int type, const Options *op); + + + +#endif // __POPUP_H__ diff --git a/plugins/AvatarHistory/resource.h b/plugins/AvatarHistory/resource.h new file mode 100644 index 0000000000..9ec6008167 --- /dev/null +++ b/plugins/AvatarHistory/resource.h @@ -0,0 +1,88 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by AvatarHistory.rc +// +#define IDD_OPTIONS_OLD 101 +#define IDC_POPUPBG 102 +#define IDD_AVATARDLG 102 +#define IDC_POPUPFG 103 +#define IDI_AVATARHIST 104 +#define IDI_NEWAVATAR 105 +#define IDI_AVATAROVERLAY 106 +#define IDR_MENU1 108 +#define IDD_FIRST_RUN 109 +#define IDD_OPTIONS 119 +#define IDD_POPUPS 120 +#define IDC_CUSTOM1 1000 +#define IDC_AVATARPOPUPS 1001 +#define IDC_DELAY 1001 +#define IDC_LOGTODISK 1002 +#define IDC_WINCOLORS 1002 +#define IDC_LOGTOHISTORY 1003 +#define IDC_DEFAULTCOLORS 1003 +#define IDC_BGCOLOR 1004 +#define IDC_DEFPOPUPS 1005 +#define IDC_TEXTCOLOR 1005 +#define IDC_PREV 1006 +#define IDC_AVATAR 1007 +#define IDC_DELAYFROMPU 1007 +#define IDC_AVATARLIST 1008 +#define IDC_DELAYCUSTOM 1008 +#define IDC_SAVE 1009 +#define IDC_DELAYPERMANENT 1009 +#define IDC_DELETE 1010 +#define IDC_NEXT 1011 +#define IDC_BACK 1012 +#define IDC_LOGUSER 1013 +#define IDC_POPUPUSER 1014 +#define IDC_OPENFOLDER 1015 +#define IDC_PUFGTEXT 1016 +#define IDC_HISTORYUSER 1016 +#define IDC_PUBGTEXT 1017 +#define IDC_SHOWMENU 1019 +#define IDC_LOGGING_G 1020 +#define IDC_SAME_FOLDER 1021 +#define IDC_RIGHT_ACTION 1022 +#define IDC_MIR_SAME 1022 +#define IDC_LEFT_ACTION 1023 +#define IDC_MIR_PROTO 1023 +#define IDC_AVATARPATH 1023 +#define IDC_MIR_SHORT 1024 +#define IDC_SHORT 1025 +#define IDC_DUP 1026 +#define IDC_PROTOCOLS 1041 +#define IDC_CHANGED 1058 +#define IDC_REMOVED 1059 +#define IDC_POPUPS 1060 +#define IDC_DELAY_SPIN 1061 +#define IDC_LOG_DISK 1061 +#define IDC_LOG_HISTORY 1062 +#define IDC_TRACK_G 1063 +#define IDC_CHANGED_L 1064 +#define IDC_REMOVED_L 1065 +#define IDC_PROTOCOLS_G 1066 +#define IDC_PROTOCOLS_L 1067 +#define IDC_TRACK_CHANGE 1068 +#define IDC_COLOURS_G 1068 +#define IDC_OLD_STYLE 1068 +#define IDC_TRACK_REMOVE 1069 +#define IDC_BGCOLOR_L 1069 +#define IDC_TEXTCOLOR_L 1070 +#define IDC_DELAY_G 1071 +#define IDC_ACTIONS_G 1072 +#define IDC_RIGHT_ACTION_L 1073 +#define IDC_LEFT_ACTION_L 1074 +#define ID_AVATARLISTPOPUP_SAVEAS 40001 +#define ID_AVATARLISTPOPUP_DELETE 40002 +#define ID_AVATARLISTPOPUP_DELETE_BOTH 40003 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 110 +#define _APS_NEXT_COMMAND_VALUE 40004 +#define _APS_NEXT_CONTROL_VALUE 1025 +#define _APS_NEXT_SYMED_VALUE 103 +#endif +#endif diff --git a/plugins/ExternalAPI/m_HTTPServer.h b/plugins/ExternalAPI/m_HTTPServer.h index 6cb6549ee0..c8de071838 100644 --- a/plugins/ExternalAPI/m_HTTPServer.h +++ b/plugins/ExternalAPI/m_HTTPServer.h @@ -100,6 +100,18 @@ typedef struct { #define MS_HTTP_GET_ALL_SHARES "HTTPServer/GetAllShares" +///////////////////////////////////////////// +//// Service MS_HTTP_GET_LINK ///// +///////////////////////////////////////////// +// +// wParam = (char*)pszSrvPath; +// lParam = 0 +// Return URL Link on success, 0 on failure +// Return pointer must be mir_free by caller +// +// Return the URL link to the pszSrvPath + +#define MS_HTTP_GET_LINK "HTTPServer/GetLink" #endif diff --git a/plugins/ExternalAPI/m_autoreplacer.h b/plugins/ExternalAPI/m_autoreplacer.h new file mode 100644 index 0000000000..57271a7163 --- /dev/null +++ b/plugins/ExternalAPI/m_autoreplacer.h @@ -0,0 +1,39 @@ +/* + AutoReplacer plugin + by Angelo Luiz Tartari +*/ + +#ifndef M_AUTOREPLACER_H +#define M_AUTOREPLACER_H + +/* + Adds a window handle to AutoReplacer. + This handle must belong to any window based on a editbox (editbox, richtext, TMemo, TEdit, TMaskEdit, etc.). + After adding a handle, AutoReplacer will automatically work on this window. + wParam = 0 + lParam = (LPARAM)(HWND)hwnd + Returns: 0 on success, -1 if hwnd is invalid, 1 on error. + Example: + if(ServiceExists(MS_AUTOREPLACER_ADDWINHANDLE)) + autoreplacer_AddWinHandle(GetDlgItem(hwndDlg, IDC_EDIT1)); +*/ +#define MS_AUTOREPLACER_ADDWINHANDLE "AutoReplacer/AddWinHandle" +static int __inline autoreplacer_AddWinHandle(HWND hwnd) { + return (int)CallService(MS_AUTOREPLACER_ADDWINHANDLE, (WPARAM)0, (LPARAM)hwnd); +} + +/* + Removes a window handle from AutoReplacer's list. + wParam = 0 + lParam = (LPARAM)(HWND)hwnd + Returns: 0 on success, -1 if hwnd is invalid, 1 if hwnd wasn't found. + Example: + if(ServiceExists(MS_AUTOREPLACER_REMWINHANDLE)) + autoreplacer_RemWinHandle(GetDlgItem(hwndDlg, IDC_EDIT1)); +*/ +#define MS_AUTOREPLACER_REMWINHANDLE "AutoReplacer/RemWinHandle" +static int __inline autoreplacer_RemWinHandle(HWND hwnd) { + return (int)CallService(MS_AUTOREPLACER_REMWINHANDLE, (WPARAM)0, (LPARAM)hwnd); +} + +#endif \ No newline at end of file diff --git a/plugins/ExternalAPI/m_avatarhist.h b/plugins/ExternalAPI/m_avatarhist.h new file mode 100644 index 0000000000..6f1e5c8ebd --- /dev/null +++ b/plugins/ExternalAPI/m_avatarhist.h @@ -0,0 +1,56 @@ +/* +Copyright (C) 2006 MattJ, Ricardo Pescuma Domenecci + +This is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this file; see the file license.txt. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + + +#ifndef __M_AVATARHISTORY_H__ +# define __M_AVATARHISTORY_H__ + + +#define MIID_AVATAR_CHANGE_LOGGER { 0x95e3f3d3, 0x9678, 0x4561, { 0x96, 0xf8, 0x95, 0x88, 0x33, 0x7b, 0x86, 0x68 } } +#define MIID_AVATAR_CHANGE_NOTIFIER { 0x91af9298, 0x8570, 0x4063, { 0xbf, 0x2f, 0xca, 0x68, 0xd0, 0xe3, 0xb3, 0x6a } } + + +#define EVENTTYPE_AVATAR_CHANGE 9003 + + +/* +Return TRUE is Avatar History is enabled for this contact + +wParam: hContact +lParam: ignored +*/ +#define MS_AVATARHISTORY_ENABLED "AvatarHistory/IsEnabled" + + +/* +Get cached avatar + +wParam: (char *) protocol name +lParam: (TCHAR *) hash +return: (TCHAR *) NULL if none is found or the path to the avatar. You need to free this string + with mir_free. +*/ +#define MS_AVATARHISTORY_GET_CACHED_AVATAR "AvatarHistory/GetCachedAvatar" + + +#define MS_AVATARHISTORY_SHOWDIALOG "AvatarHistory/ShowDialog" + + + +#endif // __M_AVATARHISTORY_H__ diff --git a/plugins/ExternalAPI/m_ftpfile.h b/plugins/ExternalAPI/m_ftpfile.h new file mode 100644 index 0000000000..6575fd9e3b --- /dev/null +++ b/plugins/ExternalAPI/m_ftpfile.h @@ -0,0 +1,119 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +This is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. + +This 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this file; see the file license.txt. If +not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. +*/ + + +#ifndef __M_FTP_FILE_H__ +#define __M_FTP_FILE_H__ + +#define FNUM_DEFAULT 0 // user's default FTP server +#define FNUM_FTP1 1 // first FTP server in setting +#define FNUM_FTP2 2 // second... +#define FNUM_FTP3 3 +#define FNUM_FTP4 4 +#define FNUM_FTP5 5 + +#define FMODE_RAWFILE 1 // Object list contains path(s) to file(s) which will be uploaded as they are +#define FMODE_ZIPFILE 2 // ... path(s) to file(s) which will be zipped and uploaded as one ZIP file +#define FMODE_ZIPFOLDER 4 // ... path to folder which will be zipped and uploaded as one ZIP file (objectCount == 1) + +#define FUPL_UNICODE 1 // Object list contains WCHAR* paths + +#if defined _UNICODE || defined UNICODE +#define FUPL_TCHAR FUPL_UNICODE +#else +#define FUPL_TCHAR 0 +#endif + +typedef struct +{ + int cbSize; // size of the structure + HANDLE hContact; // contact handle, can be NULL + BYTE ftpNum; // number of the FTP server which will be used for upload, can be one of FNUM_* values + BYTE mode; // upload mode, can be one of FMODE_* values + DWORD flags; // bitwise OR of the FUPL_* flags above + + union { + TCHAR **pstzObjects; // pointer to the array of the object(s) to upload, content is determined by MODE value + char **pszObjects; + wchar_t **pswzObjects; + }; + + int objectCount; // number of items in Object list +} FTPUPLOAD; + +// +// Send file(s) or folder in selected mode to the FTP server +// wParam = (WPARAM)0; not used +// lParam = (LPARAM)(FTPUPLOAD*)&ftpu; pointer to FTPUPLOAD +// returns 0 if upload started with no errors, nonzero otherwise +// +#define MS_FTPFILE_UPLOAD "FTPFile/Upload" + +__inline static INT_PTR FTPFileUploadA(HANDLE hContact, BYTE ftpNum, BYTE mode, char **pszObjects, int objCount) +{ + FTPUPLOAD ftpu = {0}; + ftpu.cbSize = sizeof(ftpu); + ftpu.hContact = hContact; + ftpu.ftpNum = ftpNum; + ftpu.mode = mode; + ftpu.pszObjects = pszObjects; + ftpu.objectCount = objCount; + return CallService(MS_FTPFILE_UPLOAD, (WPARAM)0, (LPARAM)&ftpu); +} + +__inline static INT_PTR FTPFileUploadW(HANDLE hContact, BYTE ftpNum, BYTE mode, wchar_t **pswzObjects, int objCount) +{ + FTPUPLOAD ftpu = {0}; + ftpu.cbSize = sizeof(ftpu); + ftpu.hContact = hContact; + ftpu.ftpNum = ftpNum; + ftpu.mode = mode; + ftpu.flags = FUPL_UNICODE; + ftpu.pswzObjects = pswzObjects; + ftpu.objectCount = objCount; + return CallService(MS_FTPFILE_UPLOAD, (WPARAM)0, (LPARAM)&ftpu); +} + +#if defined _UNICODE || defined UNICODE +#define FTPFileUpload FTPFileUploadW +#else +#define FTPFileUpload FTPFileUploadA +#endif + +// +// Show a simple file manager +// wParam = (WPARAM)0; not used +// lParam = (LPARAM)0; not used +// returns 0 always +// +#define MS_FTPFILE_SHOWMANAGER "FTPFile/ShowManager" + +__inline static INT_PTR FTPFileShowManager() +{ + return CallService(MS_FTPFILE_SHOWMANAGER, (WPARAM)0, (LPARAM)0); +} + +// +// OBSOLOTE SERVICE (used by Send Screenshot plugin) +// Do NOT use it! +// +#define MS_FTPFILE_SHAREFILE "FTPFile/ShareFiles" + +#endif \ No newline at end of file diff --git a/plugins/ExternalAPI/m_hddinfo.h b/plugins/ExternalAPI/m_hddinfo.h new file mode 100644 index 0000000000..3f529ec1ff --- /dev/null +++ b/plugins/ExternalAPI/m_hddinfo.h @@ -0,0 +1,6 @@ +#define MS_SYSINFO_HDDTEMP "SysInfo/HddTemp" + // checks current hdd temperature +#define MS_SYSINFO_CUSTPOP "SysInfo/CustomPopup" + //shows special custom popup +#define ME_SYSINFO_HDDOVERHEAT "SysInfo/HddOverheat" + // happens if one ot the drives has current temperature higher than set as normal diff --git a/plugins/ExternalAPI/m_mucc.h b/plugins/ExternalAPI/m_mucc.h new file mode 100644 index 0000000000..44fc7dd2f1 --- /dev/null +++ b/plugins/ExternalAPI/m_mucc.h @@ -0,0 +1,189 @@ +/* + +MUCC Group Chat GUI Plugin for Miranda IM +Copyright (C) 2004 Piotr Piastucki + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef M_MUCC_INCLUDED +#define M_MUCC_INCLUDED + +#define MUCC_WINDOW_CHATROOM 1 +#define MUCC_WINDOW_CHATLIST 2 + +#define MUCC_WF_BOLD 0x0001 //enable the 'bold' button +#define MUCC_WF_ITALIC 0x0002 //enable the 'italics' button +#define MUCC_WF_UNDERLINE 0x0004 //enable the 'underline' button +#define MUCC_WF_COLOR 0x0008 //enable the 'foreground color' button +#define MUCC_WF_BKGCOLOR 0x0010 //enable the 'background color' button +#define MUCC_WF_TYPNOTIF 0x0020 //enable typing notifications + +typedef struct { + int cbSize; + int iType; //Window type, MUCW_CHATROOM or MUCW_CHATLIST + DWORD dwFlags; //Window look & feel flags + const char *pszModule; //Identifier of the module owning the window + const char *pszModuleName; //Name of the module as displayed to the user + const char *pszID; //Unique identifier of the chat room + const char *pszName; //Name of the chat room + const char *pszUID; //Identifier of the user + const char *pszNick; //Nick name used by the user in the chat room + const char *pszStatusbarText; //Optional text to set in the statusbar +} MUCCWINDOW; + +#define MS_MUCC_NEW_WINDOW "MUCC/NewWindow" + +typedef struct { + const char *pszID; //Unique identifier of the group or the chat room + const char *pszName; //Name of the group or the chat room + const char *pszNick; //Name of the user + const char *pszText; //Text, usage depends on type of event + int iCount; //Number of users in the chat room + DWORD dwFlags; //Item flags +} MUCCQUERYITEM; + +typedef struct { + int cbSize; + int iType; //Query type, one of MUCC_EVENT_QUERY_* values + const char *pszModule; //Name of the module + const char *pszParent; //Parent of groups or the group chat rooms belong to + int iItemsNum; //Number of items pItems iws pointing to + MUCCQUERYITEM *pItems; //Pointer to array of result items + DWORD dwFlags; //Item flags + int iPage; //Number of page in room list + int iLastPage; //1 if the group has any child or there is a next page in room list, 0 otherwise +} MUCCQUERYRESULT; + +#define MS_MUCC_QUERY_RESULT "MUCC/QueryResult" + +/* + * The following fields must be set for all events: + * cbSize - size of the structure + * pszModule - module name + * iType - event type (id) + */ +/* + * Incoming messages + */ +#define MUCC_EVENT_MESSAGE 0x0001 +/* pszID - room ID + * pszUID - user UID (login etc.) + * pszNick - user nick (i.e. the name to be displayed) + * pszText - message + * iFont - font index + * iFontSize - font size + * color - text color + * dwFlags - flags + * time - time + * bIsMe - TRUE if this is an outgoing message, FALSE otherwise + */ +#define MUCC_EVENT_STATUS 0x0002 +/* pszID - room ID + * pszUID - user UID (login etc.) + * pszNick - user nick (i.e. the name to be displayed) + * pszText - unused + * dwData - status + * dwFlags + * bIsMe + */ +#define MUCC_EVENT_INVITATION 0x0003 +/* +*/ +#define MUCC_EVENT_ERROR 0x0004 + +#define MUCC_EVENT_TOPIC 0x0005 +/* pszID + * pszText + */ +#define MUCC_EVENT_ROOM_INFO 0x0006 + +/* + * Incoming & outgoing messages + */ +#define MUCC_EVENT_JOIN 0x0080 +#define MUCC_EVENT_LEAVE 0x0081 +/* + * Outgoing messages + */ +#define MUCC_EVENT_INVITE 0x0102 +#define MUCC_EVENT_START_PRIV 0x0103 +#define MUCC_EVENT_REGISTER_NICK 0x0105 +#define MUCC_EVENT_REMOVE_NICK 0x0106 +#define MUCC_EVENT_REGISTER_ROOM 0x0107 +#define MUCC_EVENT_REMOVE_ROOM 0x0108 +#define MUCC_EVENT_KICK_BAN 0x0109 +#define MUCC_EVENT_SET_USER_ROLE 0x010A +#define MUCC_EVENT_UNBAN 0x010B +/* + * Queries + */ +#define MUCC_EVENT_QUERY_GROUPS 0x0120 +#define MUCC_EVENT_QUERY_ROOMS 0x0121 +#define MUCC_EVENT_QUERY_USER_ROOMS 0x0122 +#define MUCC_EVENT_QUERY_USER_NICKS 0x0123 +#define MUCC_EVENT_QUERY_SEARCH 0x0124 +#define MUCC_EVENT_QUERY_CONTACTS 0x0130 +#define MUCC_EVENT_QUERY_USERS 0x0131 +/* + Event flags +*/ +#define MUCC_EF_FONT_BOLD 0x000100 // Bold font flag (MUCC_EVENT_MESSAGE) +#define MUCC_EF_FONT_ITALIC 0x000200 // Italic font flag (MUCC_EVENT_MESSAGE) +#define MUCC_EF_FONT_UNDERLINE 0x000400 // Underlined font flags (MUCC_EVENT_MESSAGE) +/* +#define MUCC_EF_FONT_NAME 0x000800 +#define MUCC_EF_FONT_SIZE 0x001000 +#define MUCC_EF_FONT_COLOR 0x002000 +*/ +#define MUCC_EF_ROOM_PUBLIC 0x000001 +#define MUCC_EF_ROOM_NICKNAMES 0x000002 +#define MUCC_EF_ROOM_PERMANENT 0x000004 +#define MUCC_EF_ROOM_MEMBERS_ONLY 0x000008 +#define MUCC_EF_ROOM_MODERATED 0x000020 +#define MUCC_EF_ROOM_OFFICIAL 0x000040 +#define MUCC_EF_ROOM_NAME 0x100000 + +#define MUCC_EF_USER_OWNER 0x000001 +#define MUCC_EF_USER_ADMIN 0x000002 +#define MUCC_EF_USER_REGISTERED 0x000004 +#define MUCC_EF_USER_MEMBER 0x000008 +#define MUCC_EF_USER_MODERATOR 0x000010 +#define MUCC_EF_USER_BANNED 0x000020 +#define MUCC_EF_USER_GLOBALOWNER 0x000040 + +typedef struct { + int cbSize; + int iType; // Event type, one of MUCC_EVENT_* values + DWORD dwFlags; // Event flags - MUCC_EF_* + int iFont; // Text font index + int iFontSize; // Text font size + COLORREF color; // Text color + const char *pszModule; // Name of the module + const char *pszID; // Unique identifier of the chat room corresponding to the event, + const char *pszName; // Name of the chat room visible to the user + const char *pszUID; // User identifier, usage depends on type of event + const char *pszNick; // Nick, usage depends on type of event + const char *pszText; // Text, usage depends on type of event + DWORD dwData; // DWORD data e.g. status + BOOL bIsMe; // TRUE if the event is related to the user + time_t time; // Time of the event +} MUCCEVENT; + +#define MS_MUCC_EVENT "MUCC/Event" +#define ME_MUCC_EVENT "MUCC/OutgoingEvent" + +#endif + diff --git a/plugins/ExternalAPI/m_sendss.h b/plugins/ExternalAPI/m_sendss.h new file mode 100644 index 0000000000..90cc84d421 --- /dev/null +++ b/plugins/ExternalAPI/m_sendss.h @@ -0,0 +1,66 @@ +//This file is part of Send Screenshot a Miranda IM plugin +//Copyright (c) 2004-2006 Sйrgio Vieira Rolanski +// +//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 _M_SENDSS_H_ +#define _M_SENDSS_H_ + +////////////////////////////////////////////////////////////////////////////// +// Open the main capture dialog, but does not capture anything +// wParam = contact handle +// lParam = 0 +// Returns zero on success +// -1 if was not possibly to create capture window +#define MS_SENDSS_OPENDIALOG "SendSS/OpenCaptureDialog" + +////////////////////////////////////////////////////////////////////////////// +// Send an image to imageshack.us +// wParam = (char*)filename +// lParam = (HANDLE)contact (can be null) +// v0.8.0.0+ +// Returns always 0 (if lParam != 0) +// Returns (char*)URL or error message if lParam = 0. caller must mir_free the pointer +#define MS_SENDSS_SEND2IMAGESHACK "SendSS/Send2ImageShack" + +////////////////////////////////////////////////////////////////////////////// +// 1. Send a screenshot of the desktop to the selected contact +// wParam = contact handle +// lParam = 0 +// 2. Open the capture dialog in take screenshot only mode (it will not be sent) +// wParam = 0 +// lParam = anything but 0 +// Returns: +// zero on success +// -1 if was not possibly to create capture window +#define MS_SENDSS_SENDDESKTOP "SendSS/SendDesktop" + +////////////////////////////////////////////////////////////////////////////// +// Edit a in-memory bitmap on the edit window +// wParam = (SENDSSCB) callback function address to call when editing is done +// lParam = (HBITMAP) bitmap handle, a copy is made so the calling function can free this handle after the service function returns +// Returns: +// Zero on success +// -1 if could not create the edit window +// -2 if was not possible to alocate needed memory +#define MS_SENDSS_EDITBITMAP "SendSS/EditBitmap" + +// The parameter passed is the bitmap handle +// the called function must free this handle when it's not needed anymore +// Don't do much processing on the called function or you will lock miranda up +typedef void (__stdcall *SENDSSCB)(LPVOID); + +#endif + diff --git a/plugins/FTPFileYM/common.h b/plugins/FTPFileYM/common.h new file mode 100644 index 0000000000..d8d3ec56b4 --- /dev/null +++ b/plugins/FTPFileYM/common.h @@ -0,0 +1,129 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows XP or later. +#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later. +#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE. +#endif + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _DEBUG +#define _CRTDBG_MAP_ALLOC +#include +#endif + +#include +#include +using namespace std; + +#define MIRANDA_VER 0x0700 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "curl/curl.h" +#include "sys/stat.h" + +#include "mir_db.h" +#include "libcurl.h" + +#include "resource.h" +#include "docs/m_ftpfile.h" +#include "sdk/m_updater.h" +#include "sdk/m_msg_buttonsbar.h" + +#if defined _WIN64 +#define MIID_FTPFILE { 0x6453cf27, 0xd111, 0x41f4, { 0xbe, 0xf5, 0xa8, 0xd8, 0x68, 0x8e, 0x44, 0xc6 } } +#elif defined _UNICODE +#define MIID_FTPFILE { 0x9502e511, 0x7e5d, 0x49a1, {0x8b, 0xa5, 0xb1, 0xae, 0xe7, 0xf, 0xa5, 0xbf } } +#else +#define MIID_FTPFILE { 0x64f80ef4, 0x856e, 0x4f27, { 0xb2, 0xa6, 0x47, 0x4a, 0x1, 0xff, 0x69, 0x83 } } +#endif + +#ifndef SIZEOF +#define SIZEOF(s) (sizeof(s) / sizeof((s)[0])) +#endif + +#ifndef FREE +#define FREE(X) if (X) { mir_free(X); X = NULL; } +#endif + +#ifdef _DEBUG +#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__) +#else +#define DEBUG_CLIENTBLOCK +#endif + +#ifdef _DEBUG +#define new DEBUG_CLIENTBLOCK +#endif + +#define MS_FTPFILE_SHAREFILE "FTPFile/ShareFiles" +#define MS_FTPFILE_CONTACTMENU "FTPFile/ContactMenu" +#define MS_FTPFILE_MAINMENU "FTPFile/MainMenu" + +#define MODULE "FTPFile" +#define MODULE_FILES "FTPFile_Files" + +#define SOUND_UPCOMPLETE "ftpfile_upcomplete" +#define SOUND_CANCEL "ftpfile_cancel" + +extern HINSTANCE hInst; \ No newline at end of file diff --git a/plugins/FTPFileYM/curl/curl.h b/plugins/FTPFileYM/curl/curl.h new file mode 100644 index 0000000000..973fdcc49d --- /dev/null +++ b/plugins/FTPFileYM/curl/curl.h @@ -0,0 +1,1919 @@ +#ifndef __CURL_CURL_H +#define __CURL_CURL_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: curl.h,v 1.390 2009-08-11 14:07:08 patrickm Exp $ + ***************************************************************************/ + +/* + * If you have libcurl problems, all docs and details are found here: + * http://curl.haxx.se/libcurl/ + * + * curl-library mailing list subscription and unsubscription web interface: + * http://cool.haxx.se/mailman/listinfo/curl-library/ + */ + +#include "curlver.h" /* libcurl version defines */ +#include "curl/curlbuild.h" /* libcurl build definitions */ +#include "curlrules.h" /* libcurl rules enforcement */ + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && \ + !defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#include +#include + +/* The include stuff here below is mainly for time_t! */ +#include +#include + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__GNUC__) && \ + !defined(__CYGWIN__) || defined(__MINGW32__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +#include +#include +#endif +#else + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on system that are known to + require it! */ +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ + defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ + defined(ANDROID) +#include +#endif + +#ifndef _WIN32_WCE +#include +#endif +#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) +#include +#endif +#include +#endif + +#ifdef __BEOS__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void CURL; + +/* + * Decorate exportable functions for Win32 and Symbian OS DLL linking. + * This avoids using a .def file for building libcurl.dll. + */ +#if (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) && \ + !defined(CURL_STATICLIB) +#if defined(BUILDING_LIBCURL) +#define CURL_EXTERN __declspec(dllexport) +#else +#define CURL_EXTERN __declspec(dllimport) +#endif +#else + +#ifdef CURL_HIDDEN_SYMBOLS +/* + * This definition is used to make external definitions visible in the + * shared library when symbols are hidden by default. It makes no + * difference when compiling applications whether this is set or not, + * only when compiling the library. + */ +#define CURL_EXTERN CURL_EXTERN_SYMBOL +#else +#define CURL_EXTERN +#endif +#endif + +#ifndef curl_socket_typedef +/* socket typedef */ +#ifdef WIN32 +typedef SOCKET curl_socket_t; +#define CURL_SOCKET_BAD INVALID_SOCKET +#else +typedef int curl_socket_t; +#define CURL_SOCKET_BAD -1 +#endif +#define curl_socket_typedef +#endif /* curl_socket_typedef */ + +struct curl_httppost { + struct curl_httppost *next; /* next entry in the list */ + char *name; /* pointer to allocated name */ + long namelength; /* length of name length */ + char *contents; /* pointer to allocated data contents */ + long contentslength; /* length of contents field */ + char *buffer; /* pointer to allocated buffer contents */ + long bufferlength; /* length of buffer field */ + char *contenttype; /* Content-Type */ + struct curl_slist* contentheader; /* list of extra headers for this form */ + struct curl_httppost *more; /* if one field name has more than one + file, this link should link to following + files */ + long flags; /* as defined below */ +#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */ +#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */ +#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer + do not free in formfree */ +#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer + do not free in formfree */ +#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */ +#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */ +#define HTTPPOST_CALLBACK (1<<6) /* upload file contents by using the + regular read callback to get the data + and pass the given pointer as custom + pointer */ + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ + void *userp; /* custom pointer used for + HTTPPOST_CALLBACK posts */ +}; + +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + +#ifndef CURL_MAX_WRITE_SIZE + /* Tests have proven that 20K is a very bad buffer size for uploads on + Windows, while 16K for some odd reason performed a lot better. + We do the ifndef check to allow this value to easier be changed at build + time for those who feel adventurous. */ +#define CURL_MAX_WRITE_SIZE 16384 +#endif +/* This is a magic return code for the write callback that, when returned, + will signal libcurl to pause receiving on the current transfer. */ +#define CURL_WRITEFUNC_PAUSE 0x10000001 +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + +/* These are the return codes for the seek callbacks */ +#define CURL_SEEKFUNC_OK 0 +#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ +#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so + libcurl might try other means instead */ +typedef int (*curl_seek_callback)(void *instream, + curl_off_t offset, + int origin); /* 'whence' */ + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +/* This is a return code for the read callback that, when returned, will + signal libcurl to pause sending data on the current transfer. */ +#define CURL_READFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_LAST /* never use */ +} curlsocktype; + +typedef int (*curl_sockopt_callback)(void *clientp, + curl_socket_t curlfd, + curlsocktype purpose); + +struct curl_sockaddr { + int family; + int socktype; + int protocol; + unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it + turned really ugly and painful on the systems that + lack this type */ + struct sockaddr addr; +}; + +typedef curl_socket_t +(*curl_opensocket_callback)(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address); + +#ifndef CURL_NO_OLDIES + /* not used since 7.10.8, will be removed in a future release */ +typedef int (*curl_passwd_callback)(void *clientp, + const char *prompt, + char *buffer, + int buflen); +#endif + +typedef enum { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} curlioerr; + +typedef enum { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} curliocmd; + +typedef curlioerr (*curl_ioctl_callback)(CURL *handle, + int cmd, + void *clientp); + +/* + * The following typedef's are signatures of malloc, free, realloc, strdup and + * calloc respectively. Function pointers of these types can be passed to the + * curl_global_init_mem() function to set user defined memory management + * callback routines. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); + +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userptr); /* whatever the user please */ + +/* All possible error codes from all sorts of curl functions. Future versions + may return other values, stay prepared. + + Always add new return codes last. Never *EVER* remove any. The return + codes must remain the same! + */ + +typedef enum { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_OBSOLETE4, /* 4 - NOT USED */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_OBSOLETE10, /* 10 - NOT USED */ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_OBSOLETE12, /* 12 - NOT USED */ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_OBSOLETE16, /* 16 - NOT USED */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_TELNET_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ + CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint + wasn't verified fine */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ + CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized transfer encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURLE_AGAIN, /* 81 - socket is not ready for send/recv, + wait till it's ready and try again (Added + in 7.18.2) */ + CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or + wrong format (Added in 7.19.0) */ + CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in + 7.19.0) */ + CURL_LAST /* never use! */ +} CURLcode; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ + +/* The following were added in 7.17.1 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.17.0 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* noone should be using this! */ +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 +#define CURLE_URL_MALFORMAT_USER CURLE_OBSOLETE4 + +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED + +/* The following were added earlier */ + +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT + +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED + +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME + +/* This was the error code 50 in 7.7.3 and a few earlier versions, this + is no longer used by libcurl but is instead #defined here only to not + make programs break */ +#define CURLE_ALREADY_COMPLETE 99999 + +#endif /*!CURL_NO_OLDIES*/ + +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ + void *ssl_ctx, /* actually an + OpenSSL SSL_CTX */ + void *userptr); + +typedef enum { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already + in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} curl_proxytype; /* this enum was added in 7.10 */ + +#define CURLAUTH_NONE 0 /* nothing */ +#define CURLAUTH_BASIC (1<<0) /* Basic (default) */ +#define CURLAUTH_DIGEST (1<<1) /* Digest */ +#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */ +#define CURLAUTH_NTLM (1<<3) /* NTLM */ +#define CURLAUTH_DIGEST_IE (1<<4) /* Digest with IE flavour */ +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) /* all fine types set */ +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURL_ERROR_SIZE 256 + +struct curl_khkey { + const char *key; /* points to a zero-terminated string encoded with base64 + if len is zero, otherwise to the "raw" data */ + size_t len; + enum type { + CURLKHTYPE_UNKNOWN, + CURLKHTYPE_RSA1, + CURLKHTYPE_RSA, + CURLKHTYPE_DSS + } keytype; +}; + +/* this is the set of return values expected from the curl_sshkeycallback + callback */ +enum curl_khstat { + CURLKHSTAT_FINE_ADD_TO_FILE, + CURLKHSTAT_FINE, + CURLKHSTAT_REJECT, /* reject the connection, return an error */ + CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so + this causes a CURLE_DEFER error but otherwise the + connection will be left intact etc */ + CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ +}; + +/* this is the set of status codes pass in to the callback */ +enum curl_khmatch { + CURLKHMATCH_OK, /* match */ + CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ + CURLKHMATCH_MISSING, /* no matching host/key found */ + CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ +}; + +typedef int + (*curl_sshkeycallback) (CURL *easy, /* easy handle */ + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch, /* libcurl's view on the keys */ + void *clientp); /* custom pointer passed from app */ + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +#define CURLFTPSSL_NONE CURLUSESSL_NONE +#define CURLFTPSSL_TRY CURLUSESSL_TRY +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL +#define CURLFTPSSL_ALL CURLUSESSL_ALL +#define CURLFTPSSL_LAST CURLUSESSL_LAST +#define curl_ftpssl curl_usessl +#endif /*!CURL_NO_OLDIES*/ + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +typedef enum { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} curl_ftpccc; + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +typedef enum { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} curl_ftpauth; + +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +typedef enum { + CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ + CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD + again if MKD succeeded, for SFTP this does + similar magic */ + CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD + again even if MKD failed! */ + CURLFTP_CREATE_DIR_LAST /* not an option, never use */ +} curl_ftpcreatedir; + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +typedef enum { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} curl_ftpmethod; + +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +#define CURLPROTO_HTTP (1<<0) +#define CURLPROTO_HTTPS (1<<1) +#define CURLPROTO_FTP (1<<2) +#define CURLPROTO_FTPS (1<<3) +#define CURLPROTO_SCP (1<<4) +#define CURLPROTO_SFTP (1<<5) +#define CURLPROTO_TELNET (1<<6) +#define CURLPROTO_LDAP (1<<7) +#define CURLPROTO_LDAPS (1<<8) +#define CURLPROTO_DICT (1<<9) +#define CURLPROTO_FILE (1<<10) +#define CURLPROTO_TFTP (1<<11) +#define CURLPROTO_ALL (~0) /* enable everything */ + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +/* name is uppercase CURLOPT_, + type is one of the defined CURLOPTTYPE_ + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif + +#ifdef CURL_ISOCPP +#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLOPT_/**/name = type + number +#endif + +/* + * This macro-mania below setups the CURLOPT_[what] enum, to be used with + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] + * word. + */ + +typedef enum { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(FILE, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, OBJECTPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, OBJECTPOINT, 4), + + /* "name:password" to use when fetching. */ + CINIT(USERPWD, OBJECTPOINT, 5), + + /* "name:password" to use with proxy. */ + CINIT(PROXYUSERPWD, OBJECTPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, OBJECTPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(INFILE, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. If this is not used, error messages go to stderr instead: */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was successful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referrer page (needed by some CGIs) */ + CINIT(REFERER, OBJECTPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, OBJECTPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, OBJECTPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, OBJECTPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind */ + CINIT(HTTPHEADER, OBJECTPOINT, 23), + + /* This points to a linked list of post entries, struct curl_httppost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, OBJECTPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, OBJECTPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, OBJECTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(WRITEHEADER, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, OBJECTPOINT, 31), + + /* What version to specifically try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, OBJECTPOINT, 36), + + /* HTTP request, for odd commands like DELETE, TRACE and others */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, OBJECTPOINT, 39), + + /* Pass a pointer to string of the output using full variable-replacement + as described elsewhere. */ + CINIT(WRITEINFO, OBJECTPOINT, 40), + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* return bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the progress callback */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), + + /* We want the referrer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, OBJECTPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, OBJECTPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, OBJECTPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + /* What policy to use when closing connections when the cache is filled + up */ + CINIT(CLOSEPOLICY, LONG, 72), + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, OBJECTPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, OBJECTPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects + are OK within this time, then fine... This only aborts the connect + phase. [Only works on unix-style/SIGALRM operating systems] */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, OBJECTPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specifically switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, OBJECTPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, OBJECTPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, OBJECTPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, OBJECTPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* To become OBSOLETE soon */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands */ + CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, OBJECTPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. */ + CINIT(ENCODING, OBJECTPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentially send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specifically switch on or off the FTP engine's use of the EPRT command ( it + also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx + in second argument. The function must be matching the + curl_ssl_ctx_callback proto. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server. + In 7.19.4 we introduced the convenience enums for this option using the + CURLFTP_CREATE_DIR prefix. + */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, OBJECTPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise + CURLFTPSSL_CONTROL - SSL for the control connection or fail + CURLFTPSSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, OBJECTPOINT, 134), + + /* feed cookies into cookie engine */ + CINIT(COOKIELIST, OBJECTPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the application even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Set the behaviour of POST when redirecting. Values must be set to one + of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ + CINIT(POSTREDIR, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ + CINIT(PROXY_TRANSFER_MODE, LONG, 166), + + /* Callback function for seeking in the input stream */ + CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), + CINIT(SEEKDATA, OBJECTPOINT, 168), + + /* CRL file */ + CINIT(CRLFILE, OBJECTPOINT, 169), + + /* Issuer certificate */ + CINIT(ISSUERCERT, OBJECTPOINT, 170), + + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + + /* Collect certificate chain info and allow it to get retrievable with + CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only + working with OpenSSL-powered builds. */ + CINIT(CERTINFO, LONG, 172), + + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, OBJECTPOINT, 173), + CINIT(PASSWORD, OBJECTPOINT, 174), + + /* "name" and "pwd" to use with Proxy when fetching. */ + CINIT(PROXYUSERNAME, OBJECTPOINT, 175), + CINIT(PROXYPASSWORD, OBJECTPOINT, 176), + + /* Comma separated list of hostnames defining no-proxy zones. These should + match both hostnames directly, and hostnames within a domain. For + example, local.com will match local.com and www.local.com, but NOT + notlocal.com or www.notlocal.com. For compatibility with other + implementations of this, .local.com will be considered to be the same as + local.com. A single * is the only valid wildcard, and effectively + disables the use of proxy. */ + CINIT(NOPROXY, OBJECTPOINT, 177), + + /* block size for TFTP transfers */ + CINIT(TFTP_BLKSIZE, LONG, 178), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + CINIT(PROTOCOLS, LONG, 181), + + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. Defaults + to all protocols except FILE and SCP. */ + CINIT(REDIR_PROTOCOLS, LONG, 182), + + /* set the SSH knownhost file name to use */ + CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183), + + /* set the SSH host key callback, must point to a curl_sshkeycallback + function */ + CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + + /* set the SSH host key callback custom pointer */ + CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2011 */ + +/* This was added in version 7.19.1 */ +#define CURLOPT_POST301 CURLOPT_POSTREDIR + +/* These are scheduled to disappear by 2009 */ + +/* The following were added in 7.17.0 */ +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_FTPAPPEND CURLOPT_APPEND +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL + +/* The following were added earlier */ + +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */ + + /* three convenient "aliases" that follow the name scheme better */ +#define CURLOPT_WRITEDATA CURLOPT_FILE +#define CURLOPT_READDATA CURLOPT_INFILE +#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +}; + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +}; + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + + CURL_SSLVERSION_LAST /* never use, keep last */ +}; + +/* symbols to use with CURLOPT_POSTREDIR. + CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that + CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */ + +#define CURL_REDIR_GET_ALL 0 +#define CURL_REDIR_POST_301 1 +#define CURL_REDIR_POST_302 2 +#define CURL_REDIR_POST_ALL (CURL_REDIR_POST_301|CURL_REDIR_POST_302) + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + + +/* curl_strequal() and curl_strnequal() are subject for removal in a future + libcurl, see lib/README.curlx for details */ +CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); +CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); + +/* name is uppercase CURLFORM_ */ +#ifdef CFINIT +#undef CFINIT +#endif + +#ifdef CURL_ISOCPP +#define CFINIT(name) CURLFORM_ ## name +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define CFINIT(name) CURLFORM_/**/name +#endif + +typedef enum { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CFINIT(STREAM), + + CURLFORM_LASTENTRY /* the last unused */ +} CURLformoption; + +#undef CFINIT /* done */ + +/* structure to be used as parameter for CURLFORM_ARRAY */ +struct curl_forms { + CURLformoption option; + const char *value; +}; + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +typedef enum { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} CURLFORMcode; + +/* + * NAME curl_formadd() + * + * DESCRIPTION + * + * Pretty advanced function for building multi-part formposts. Each invoke + * adds one part that together construct a full post. Then use + * CURLOPT_HTTPPOST to send it off to libcurl. + */ +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...); + +/* + * callback function for curl_formget() + * The void *arg pointer will be the one passed as second argument to + * curl_formget(). + * The character buffer passed to it must not be freed. + * Should return the buffer length passed to it as the argument "len" on + * success. + */ +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, size_t len); + +/* + * NAME curl_formget() + * + * DESCRIPTION + * + * Serialize a curl_httppost struct built with curl_formadd(). + * Accepts a void pointer as second argument which will be passed to + * the curl_formget_callback function. + * Returns 0 on success. + */ +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append); +/* + * NAME curl_formfree() + * + * DESCRIPTION + * + * Free a multipart formpost previously built with curl_formadd(). + */ +CURL_EXTERN void curl_formfree(struct curl_httppost *form); + +/* + * NAME curl_getenv() + * + * DESCRIPTION + * + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is + * complete. DEPRECATED - see lib/README.curlx + */ +CURL_EXTERN char *curl_getenv(const char *variable); + +/* + * NAME curl_version() + * + * DESCRIPTION + * + * Returns a static ascii string of the libcurl version. + */ +CURL_EXTERN char *curl_version(void); + +/* + * NAME curl_easy_escape() + * + * DESCRIPTION + * + * Escapes URL strings (converts all letters consider illegal in URLs to their + * %XX versions). This function returns a new allocated string or NULL if an + * error occurred. + */ +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + + +/* + * NAME curl_easy_unescape() + * + * DESCRIPTION + * + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit + * versions). This function returns a new allocated string or NULL if an error + * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. + */ +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); + +/* + * NAME curl_free() + * + * DESCRIPTION + * + * Provided for de-allocation in the same translation unit that did the + * allocation. Added in libcurl 7.10 + */ +CURL_EXTERN void curl_free(void *p); + +/* + * NAME curl_global_init() + * + * DESCRIPTION + * + * curl_global_init() should be invoked exactly once for each application that + * uses libcurl and before any call of other libcurl functions. + * + * This function is not thread-safe! + */ +CURL_EXTERN CURLcode curl_global_init(long flags); + +/* + * NAME curl_global_init_mem() + * + * DESCRIPTION + * + * curl_global_init() or curl_global_init_mem() should be invoked exactly once + * for each application that uses libcurl. This function can be used to + * initialize libcurl and set user defined memory management callback + * functions. Users can implement memory management routines to check for + * memory leaks, check for mis-use of the curl library etc. User registered + * callback routines with be invoked by this library instead of the system + * memory management routines like malloc, free etc. + */ +CURL_EXTERN CURLcode curl_global_init_mem(long flags, + curl_malloc_callback m, + curl_free_callback f, + curl_realloc_callback r, + curl_strdup_callback s, + curl_calloc_callback c); + +/* + * NAME curl_global_cleanup() + * + * DESCRIPTION + * + * curl_global_cleanup() should be invoked exactly once for each application + * that uses libcurl + */ +CURL_EXTERN void curl_global_cleanup(void); + +/* linked-list structure for the CURLOPT_QUOTE option (and other) */ +struct curl_slist { + char *data; + struct curl_slist *next; +}; + +/* + * NAME curl_slist_append() + * + * DESCRIPTION + * + * Appends a string to a linked list. If no list exists, it will be created + * first. Returns the new list, after appending. + */ +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, + const char *); + +/* + * NAME curl_slist_free_all() + * + * DESCRIPTION + * + * free a previously built curl_slist. + */ +CURL_EXTERN void curl_slist_free_all(struct curl_slist *); + +/* + * NAME curl_getdate() + * + * DESCRIPTION + * + * Returns the time, in seconds since 1 Jan 1970 of the time string given in + * the first argument. The time argument in the second parameter is unused + * and should be set to NULL. + */ +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); + +/* info about the certificate chain, only for OpenSSL builds. Asked + for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ +struct curl_certinfo { + int num_of_certs; /* number of certificates with information */ + struct curl_slist **certinfo; /* for each index in this array, there's a + linked list with textual information in the + format "name: value" */ +}; + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_SLIST + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + /* Fill in new entries below here! */ + + CURLINFO_LASTONE = 35 +} CURLINFO; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_WIN32 (1<<1) +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_NOTHING 0 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL + + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different data locks for a single share */ +typedef enum { + CURL_LOCK_DATA_NONE = 0, + /* CURL_LOCK_DATA_SHARE is used internally to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_LAST +} curl_lock_data; + +/* Different lock access types */ +typedef enum { + CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ + CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ + CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ + CURL_LOCK_ACCESS_LAST /* never use */ +} curl_lock_access; + +typedef void (*curl_lock_function)(CURL *handle, + curl_lock_data data, + curl_lock_access locktype, + void *userptr); +typedef void (*curl_unlock_function)(CURL *handle, + curl_lock_data data, + void *userptr); + +typedef void CURLSH; + +typedef enum { + CURLSHE_OK, /* all is fine */ + CURLSHE_BAD_OPTION, /* 1 */ + CURLSHE_IN_USE, /* 2 */ + CURLSHE_INVALID, /* 3 */ + CURLSHE_NOMEM, /* out of memory */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ + CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ + CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ + CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock + callback functions */ + CURLSHOPT_LAST /* never use */ +} CURLSHoption; + +CURL_EXTERN CURLSH *curl_share_init(void); +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); + +/**************************************************************************** + * Structures for querying information about the curl library at runtime. + */ + +typedef enum { + CURLVERSION_FIRST, + CURLVERSION_SECOND, + CURLVERSION_THIRD, + CURLVERSION_FOURTH, + CURLVERSION_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basically all programs ever that want to get version information. It is + meant to be a built-in version number for what kind of struct the caller + expects. If the struct ever changes, we redefine the NOW to another enum + from above. */ +#define CURLVERSION_NOW CURLVERSION_FOURTH + +typedef struct { + CURLversion age; /* age of the returned struct */ + const char *version; /* LIBCURL_VERSION */ + unsigned int version_num; /* LIBCURL_VERSION_NUM */ + const char *host; /* OS/host/cpu/machine when configured */ + int features; /* bitmask, see defines below */ + const char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used anymore, always 0 */ + const char *libz_version; /* human readable string */ + /* protocols is terminated by an entry with a NULL protoname */ + const char * const *protocols; + + /* The fields below this were added in CURLVERSION_SECOND */ + const char *ares; + int ares_num; + + /* This field was added in CURLVERSION_THIRD */ + const char *libidn; + + /* These field were added in CURLVERSION_FOURTH */ + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; + + const char *libssh_version; /* human readable string */ + +} curl_version_info_data; + +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */ +#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */ +#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */ +#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */ +#define CURL_VERSION_CONV (1<<12) /* character conversions supported */ +#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */ + +/* + * NAME curl_version_info() + * + * DESCRIPTION + * + * This function returns a pointer to a static copy of the version info + * struct. See above. + */ +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); + +/* + * NAME curl_easy_strerror() + * + * DESCRIPTION + * + * The curl_easy_strerror function may be used to turn a CURLcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_easy_strerror(CURLcode); + +/* + * NAME curl_share_strerror() + * + * DESCRIPTION + * + * The curl_share_strerror function may be used to turn a CURLSHcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_share_strerror(CURLSHcode); + +/* + * NAME curl_easy_pause() + * + * DESCRIPTION + * + * The curl_easy_pause function pauses or unpauses transfers. Select the new + * state by setting the bitmask, use the convenience defines below. + * + */ +CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); + +#define CURLPAUSE_RECV (1<<0) +#define CURLPAUSE_RECV_CONT (0) + +#define CURLPAUSE_SEND (1<<2) +#define CURLPAUSE_SEND_CONT (0) + +#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) +#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) + +#ifdef __cplusplus +} +#endif + +/* unfortunately, the easy.h and multi.h include files need options and info + stuff before they can be included! */ +#include "easy.h" /* nothing in curl is fun without the easy stuff */ +#include "multi.h" + +/* the typechecker doesn't work in C++ (yet) */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ + !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) +#include "typecheck-gcc.h" +#else +#if defined(__STDC__) && (__STDC__ >= 1) +/* This preprocessor magic that replaces a call with the exact same call is + only done to make sure application authors pass exactly three arguments + to these functions. */ +#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) +#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) +#endif /* __STDC__ >= 1 */ +#endif /* gcc >= 4.3 && !__cplusplus */ + +#endif /* __CURL_CURL_H */ diff --git a/plugins/FTPFileYM/curl/curlbuild.h b/plugins/FTPFileYM/curl/curlbuild.h new file mode 100644 index 0000000000..9cb347323e --- /dev/null +++ b/plugins/FTPFileYM/curl/curlbuild.h @@ -0,0 +1,584 @@ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: curlbuild.h.dist,v 1.28 2009-05-12 01:57:54 yangtse Exp $ + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * See file include/curl/curlbuild.h.in, run configure, and forget + * that this file exists it is only used for non-configure systems. + * But you can keep reading if you want ;-) + * + */ + +/* ================================================================ */ +/* NOTES FOR NON-CONFIGURE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/ + * + * Try to keep one section per platform, compiler and architecture, + * otherwise, if an existing section is reused for a different one and + * later on the original is adjusted, probably the piggybacking one can + * be adversely changed. + * + * In order to differentiate between platforms/compilers/architectures + * use only compiler built in predefined preprocessor symbols. + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * For any given platform/compiler curl_off_t must be typedef'ed to a + * 64-bit wide signed integral data type. The width of this data type + * must remain constant and independant of any possible large file + * support settings. + * + * As an exception to the above, curl_off_t shall be typedef'ed to a + * 32-bit wide signed integral data type if there is no 64-bit type. + * + * As a general rule, curl_off_t shall not be mapped to off_t. This + * rule shall only be violated if off_t is the only 64-bit data type + * available and the size of off_t is independant of large file support + * settings. Keep your build on the safe side avoiding an off_t gating. + * If you have a 64-bit off_t then take for sure that another 64-bit + * data type exists, dig deeper and you will find it. + * + * NOTE 3: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.dist or + * at file include/curl/curlbuild.h, this is due to the following reason: + * file include/curl/curlbuild.h.dist is renamed to include/curl/curlbuild.h + * when the libcurl source code distribution archive file is created. + * + * File include/curl/curlbuild.h.dist is not included in the distribution + * archive. File include/curl/curlbuild.h is not present in the CVS tree. + * + * The distributed include/curl/curlbuild.h file is only intended to be used + * on systems which can not run the also distributed configure script. + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + * If you check out from CVS on a non-configure platform, you must run the + * appropriate buildconf* script to set up curlbuild.h and other local files. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR NON-CONFIGURE SYSTEMS ONLY */ +/* ================================================================ */ + +#if defined(__DJGPP__) || defined(__GO32__) +# if defined(__DJGPP__) && (__DJGPP__ > 1) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__SALFORDC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__BORLANDC__) +# if (__BORLANDC__ < 0x520) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__TURBOC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__WATCOMC__) +# if defined(__386__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__POCC__) +# if (__POCC__ < 280) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# elif defined(_MSC_VER) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__LCC__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__SYMBIAN32__) +# if defined(__EABI__) /* Treat all ARM compilers equally */ +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__CW32__) +# pragma longlong on +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__VC32__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__MWERKS__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(_WIN32_WCE) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__MINGW32__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__VMS) +# if defined(__alpha) || defined(__ia64) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__OS400__) +# if defined(__ILEC400__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__MVS__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# define CURL_SIZEOF_LONG 4 +# elif defined(_LP64) +# define CURL_SIZEOF_LONG 8 +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__370__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# define CURL_SIZEOF_LONG 4 +# elif defined(_LP64) +# define CURL_SIZEOF_LONG 8 +# endif +# if defined(_LONG_LONG) +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# else +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(TPF) +# define CURL_SIZEOF_LONG 8 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* ===================================== */ +/* KEEP MSVC THE PENULTIMATE ENTRY */ +/* ===================================== */ + +#elif defined(_MSC_VER) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T __int64 +# define CURL_FORMAT_CURL_OFF_T "I64d" +# define CURL_FORMAT_CURL_OFF_TU "I64u" +# define CURL_FORMAT_OFF_T "%I64d" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T i64 +# define CURL_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 4 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T int +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* ===================================== */ +/* KEEP GENERIC GCC THE LAST ENTRY */ +/* ===================================== */ + +#elif defined(__GNUC__) +# if defined(__i386__) || defined(__ppc__) +# define CURL_SIZEOF_LONG 4 +# define CURL_TYPEOF_CURL_OFF_T long long +# define CURL_FORMAT_CURL_OFF_T "lld" +# define CURL_FORMAT_CURL_OFF_TU "llu" +# define CURL_FORMAT_OFF_T "%lld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T LL +# define CURL_SUFFIX_CURL_OFF_TU ULL +# elif defined(__x86_64__) || defined(__ppc64__) +# define CURL_SIZEOF_LONG 8 +# define CURL_TYPEOF_CURL_OFF_T long +# define CURL_FORMAT_CURL_OFF_T "ld" +# define CURL_FORMAT_CURL_OFF_TU "lu" +# define CURL_FORMAT_OFF_T "%ld" +# define CURL_SIZEOF_CURL_OFF_T 8 +# define CURL_SUFFIX_CURL_OFF_T L +# define CURL_SUFFIX_CURL_OFF_TU UL +# endif +# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURL_SIZEOF_CURL_SOCKLEN_T 4 +# define CURL_PULL_SYS_TYPES_H 1 +# define CURL_PULL_SYS_SOCKET_H 1 + +#else +# error "Unknown non-configure build target!" + Error Compilation_aborted_Unknown_non_configure_build_target +#endif + +/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */ +/* sys/types.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */ +/* sys/socket.h is required here to properly make type definitions below. */ +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Data type definition of curl_socklen_t. */ + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T + typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; +#endif + +/* Data type definition of curl_off_t. */ + +#ifdef CURL_TYPEOF_CURL_OFF_T + typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; +#endif + +#endif /* __CURL_CURLBUILD_H */ diff --git a/plugins/FTPFileYM/curl/curlrules.h b/plugins/FTPFileYM/curl/curlrules.h new file mode 100644 index 0000000000..44018737d9 --- /dev/null +++ b/plugins/FTPFileYM/curl/curlrules.h @@ -0,0 +1,249 @@ +#ifndef __CURL_CURLRULES_H +#define __CURL_CURLRULES_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: curlrules.h,v 1.6 2009-04-29 15:15:38 yangtse Exp $ + ***************************************************************************/ + +/* ================================================================ */ +/* COMPILE TIME SANITY CHECKS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * All checks done in this file are intentionally placed in a public + * header file which is pulled by curl/curl.h when an application is + * being built using an already built libcurl library. Additionally + * this file is also included and used when building the library. + * + * If compilation fails on this file it is certainly sure that the + * problem is elsewhere. It could be a problem in the curlbuild.h + * header file, or simply that you are using different compilation + * settings than those used to build the library. + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * Do not deactivate any check, these are done to make sure that the + * library is properly built and used. + * + * You can find further help on the libcurl development mailing list: + * http://cool.haxx.se/mailman/listinfo/curl-library/ + * + * NOTE 2 + * ------ + * + * Some of the following compile time checks are based on the fact + * that the dimension of a constant array can not be a negative one. + * In this way if the compile time verification fails, the compilation + * will fail issuing an error. The error description wording is compiler + * dependant but it will be quite similar to one of the following: + * + * "negative subscript or subscript is too large" + * "array must have at least one element" + * "-1 is an illegal array size" + * "size of array is negative" + * + * If you are building an application which tries to use an already + * built libcurl library and you are getting this kind of errors on + * this file, it is a clear indication that there is a mismatch between + * how the library was built and how you are trying to use it for your + * application. Your already compiled or binary library provider is the + * only one who can give you the details you need to properly use it. + */ + +/* + * Verify that some macros are actually defined. + */ + +#ifndef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing +#endif + +#ifndef CURL_FORMAT_OFF_T +# error "CURL_FORMAT_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing +#endif + +/* + * Macros private to this header file. + */ + +#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1 + +#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 + +/* + * Verify that the size previously defined and expected for long + * is the same as the one reported by sizeof() at compile time. + */ + +typedef char + __curl_rule_01__ + [CurlchkszEQ(long, CURL_SIZEOF_LONG)]; + +/* + * Verify that the size previously defined and expected for + * curl_off_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_02__ + [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)]; + +/* + * Verify at compile time that the size of curl_off_t as reported + * by sizeof() is greater or equal than the one reported for long + * for the current compilation. + */ + +typedef char + __curl_rule_03__ + [CurlchkszGE(curl_off_t, long)]; + +/* + * Verify that the size previously defined and expected for + * curl_socklen_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_04__ + [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)]; + +/* + * Verify at compile time that the size of curl_socklen_t as reported + * by sizeof() is greater or equal than the one reported for int for + * the current compilation. + */ + +typedef char + __curl_rule_05__ + [CurlchkszGE(curl_socklen_t, int)]; + +/* ================================================================ */ +/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ +/* ================================================================ */ + +/* + * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow + * these to be visible and exported by the external libcurl interface API, + * while also making them visible to the library internals, simply including + * setup.h, without actually needing to include curl.h internally. + * If some day this section would grow big enough, all this should be moved + * to its own header file. + */ + +/* + * Figure out if we can use the ## preprocessor operator, which is supported + * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ + * or __cplusplus so we need to carefully check for them too. + */ + +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ + defined(__ILEC400__) + /* This compiler is believed to have an ISO compatible preprocessor */ +#define CURL_ISOCPP +#else + /* This compiler is believed NOT to have an ISO compatible preprocessor */ +#undef CURL_ISOCPP +#endif + +/* + * Macros for minimum-width signed and unsigned curl_off_t integer constants. + */ + +#ifdef CURL_ISOCPP +# define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val ## Suffix +#else +# define __CURL_OFF_T_C_HELPER2(Val,Suffix) Val/**/Suffix +#endif +#define __CURL_OFF_T_C_HELPER1(Val,Suffix) __CURL_OFF_T_C_HELPER2(Val,Suffix) +#define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_T) +#define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HELPER1(Val,CURL_SUFFIX_CURL_OFF_TU) + +/* + * Get rid of macros private to this header file. + */ + +#undef CurlchkszEQ +#undef CurlchkszGE + +/* + * Get rid of macros not intended to exist beyond this point. + */ + +#undef CURL_PULL_WS2TCPIP_H +#undef CURL_PULL_SYS_TYPES_H +#undef CURL_PULL_SYS_SOCKET_H +#undef CURL_PULL_STDINT_H +#undef CURL_PULL_INTTYPES_H + +#undef CURL_TYPEOF_CURL_SOCKLEN_T +#undef CURL_TYPEOF_CURL_OFF_T + +#endif /* __CURL_CURLRULES_H */ diff --git a/plugins/FTPFileYM/curl/curlver.h b/plugins/FTPFileYM/curl/curlver.h new file mode 100644 index 0000000000..177f6cbd8d --- /dev/null +++ b/plugins/FTPFileYM/curl/curlver.h @@ -0,0 +1,70 @@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: curlver.h,v 1.47 2009-05-18 07:58:00 bagder Exp $ + ***************************************************************************/ + +/* This header file contains nothing but libcurl version info, generated by + a script at release-time. This was made its own header file in 7.11.2 */ + +/* This is the global package copyright */ +#define LIBCURL_COPYRIGHT "1996 - 2009 Daniel Stenberg, ." + +/* This is the version number of the libcurl package from which this header + file origins: */ +#define LIBCURL_VERSION "7.19.6" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 +#define LIBCURL_VERSION_MINOR 19 +#define LIBCURL_VERSION_PATCH 6 + +/* This is the numeric version of the libcurl version number, meant for easier + parsing and comparions by programs. The LIBCURL_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. +*/ +#define LIBCURL_VERSION_NUM 0x071306 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in CVS, as the timestamp is properly set in the + * tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + */ +#define LIBCURL_TIMESTAMP "Wed Aug 12 08:59:35 UTC 2009" + +#endif /* __CURL_CURLVER_H */ diff --git a/plugins/FTPFileYM/curl/easy.h b/plugins/FTPFileYM/curl/easy.h new file mode 100644 index 0000000000..40449c3ec8 --- /dev/null +++ b/plugins/FTPFileYM/curl/easy.h @@ -0,0 +1,103 @@ +#ifndef __CURL_EASY_H +#define __CURL_EASY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: easy.h,v 1.14 2008-05-12 21:43:28 bagder Exp $ + ***************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN CURL *curl_easy_init(void); +CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); +CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); +CURL_EXTERN void curl_easy_cleanup(CURL *curl); + +/* + * NAME curl_easy_getinfo() + * + * DESCRIPTION + * + * Request internal information from the curl session with this function. The + * third argument MUST be a pointer to a long, a pointer to a char * or a + * pointer to a double (as the documentation describes elsewhere). The data + * pointed to will be filled in accordingly and can be relied upon only if the + * function returns CURLE_OK. This function is intended to get used *AFTER* a + * performed transfer, all results from this function are undefined until the + * transfer is completed. + */ +CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); + + +/* + * NAME curl_easy_duphandle() + * + * DESCRIPTION + * + * Creates a new curl session handle with the same options set for the handle + * passed in. Duplicating a handle could only be a matter of cloning data and + * options, internal state info and things like persistant connections cannot + * be transfered. It is useful in multithreaded applications when you can run + * curl_easy_duphandle() for each new thread to avoid a series of identical + * curl_easy_setopt() invokes in every thread. + */ +CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl); + +/* + * NAME curl_easy_reset() + * + * DESCRIPTION + * + * Re-initializes a CURL handle to the default values. This puts back the + * handle to the same state as it was in when it was just created. + * + * It does keep: live connections, the Session ID cache, the DNS cache and the + * cookies. + */ +CURL_EXTERN void curl_easy_reset(CURL *curl); + +/* + * NAME curl_easy_recv() + * + * DESCRIPTION + * + * Receives data from the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, + size_t *n); + +/* + * NAME curl_easy_send() + * + * DESCRIPTION + * + * Sends data over the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, + size_t buflen, size_t *n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/plugins/FTPFileYM/curl/mprintf.h b/plugins/FTPFileYM/curl/mprintf.h new file mode 100644 index 0000000000..d7202de170 --- /dev/null +++ b/plugins/FTPFileYM/curl/mprintf.h @@ -0,0 +1,82 @@ +#ifndef __CURL_MPRINTF_H +#define __CURL_MPRINTF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: mprintf.h,v 1.16 2008-05-20 10:21:50 patrickm Exp $ + ***************************************************************************/ + +#include +#include /* needed for FILE */ + +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN int curl_mprintf(const char *format, ...); +CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); +CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); +CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, + const char *format, ...); +CURL_EXTERN int curl_mvprintf(const char *format, va_list args); +CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); +CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); +CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, + const char *format, va_list args); +CURL_EXTERN char *curl_maprintf(const char *format, ...); +CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); + +#ifdef _MPRINTF_REPLACE +# undef printf +# undef fprintf +# undef sprintf +# undef vsprintf +# undef snprintf +# undef vprintf +# undef vfprintf +# undef vsnprintf +# undef aprintf +# undef vaprintf +# define printf curl_mprintf +# define fprintf curl_mfprintf +#ifdef CURLDEBUG +/* When built with CURLDEBUG we define away the sprintf() functions since we + don't want internal code to be using them */ +# define sprintf sprintf_was_used +# define vsprintf vsprintf_was_used +#else +# define sprintf curl_msprintf +# define vsprintf curl_mvsprintf +#endif +# define snprintf curl_msnprintf +# define vprintf curl_mvprintf +# define vfprintf curl_mvfprintf +# define vsnprintf curl_mvsnprintf +# define aprintf curl_maprintf +# define vaprintf curl_mvaprintf +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __CURL_MPRINTF_H */ diff --git a/plugins/FTPFileYM/curl/multi.h b/plugins/FTPFileYM/curl/multi.h new file mode 100644 index 0000000000..153f7721c9 --- /dev/null +++ b/plugins/FTPFileYM/curl/multi.h @@ -0,0 +1,346 @@ +#ifndef __CURL_MULTI_H +#define __CURL_MULTI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: multi.h,v 1.45 2008-05-20 10:21:50 patrickm Exp $ + ***************************************************************************/ +/* + This is an "external" header file. Don't give away any internals here! + + GOALS + + o Enable a "pull" interface. The application that uses libcurl decides where + and when to ask libcurl to get/send data. + + o Enable multiple simultaneous transfers in the same thread without making it + complicated for the application. + + o Enable the application to select() on its own file descriptors and curl's + file descriptors simultaneous easily. + +*/ + +/* + * This header file should not really need to include "curl.h" since curl.h + * itself includes this file and we expect user applications to do #include + * without the need for especially including multi.h. + * + * For some reason we added this include here at one point, and rather than to + * break existing (wrongly written) libcurl applications, we leave it as-is + * but with this warning attached. + */ +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void CURLM; + +typedef enum { + CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or + curl_multi_socket*() soon */ + CURLM_OK, + CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ + CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ + CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ + CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ + CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ + CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ + CURLM_LAST +} CURLMcode; + +/* just to make code nicer when using curl_multi_socket() you can now check + for CURLM_CALL_MULTI_SOCKET too in the same style it works for + curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ +#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM + +typedef enum { + CURLMSG_NONE, /* first, not used */ + CURLMSG_DONE, /* This easy handle has completed. 'result' contains + the CURLcode of the transfer */ + CURLMSG_LAST /* last, not used */ +} CURLMSG; + +struct CURLMsg { + CURLMSG msg; /* what this message means */ + CURL *easy_handle; /* the handle it concerns */ + union { + void *whatever; /* message-specific data */ + CURLcode result; /* return code for transfer */ + } data; +}; +typedef struct CURLMsg CURLMsg; + +/* + * Name: curl_multi_init() + * + * Desc: inititalize multi-style curl usage + * + * Returns: a new CURLM handle to use in all 'curl_multi' functions. + */ +CURL_EXTERN CURLM *curl_multi_init(void); + +/* + * Name: curl_multi_add_handle() + * + * Desc: add a standard curl handle to the multi stack + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_remove_handle() + * + * Desc: removes a curl handle from the multi stack again + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_fdset() + * + * Desc: Ask curl for its fd_set sets. The app can use these to select() or + * poll() on. We want curl_multi_perform() called as soon as one of + * them are ready. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); + + /* + * Name: curl_multi_perform() + * + * Desc: When the app thinks there's data available for curl it calls this + * function to read/write whatever there is right now. This returns + * as soon as the reads and writes are done. This function does not + * require that there actually is data available for reading or that + * data can be written, it can be called just in case. It returns + * the number of handles that still transfer data in the second + * argument's integer-pointer. + * + * Returns: CURLMcode type, general multi error code. *NOTE* that this only + * returns errors etc regarding the whole multi stack. There might + * still have occurred problems on invidual transfers even when this + * returns OK. + */ +CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, + int *running_handles); + + /* + * Name: curl_multi_cleanup() + * + * Desc: Cleans up and removes a whole multi stack. It does not free or + * touch any individual easy handles in any way. We need to define + * in what state those handles will be if this function is called + * in the middle of a transfer. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); + +/* + * Name: curl_multi_info_read() + * + * Desc: Ask the multi handle if there's any messages/informationals from + * the individual transfers. Messages include informationals such as + * error code from the transfer or just the fact that a transfer is + * completed. More details on these should be written down as well. + * + * Repeated calls to this function will return a new struct each + * time, until a special "end of msgs" struct is returned as a signal + * that there is no more to get at this point. + * + * The data the returned pointer points to will not survive calling + * curl_multi_cleanup(). + * + * The 'CURLMsg' struct is meant to be very simple and only contain + * very basic informations. If more involved information is wanted, + * we will provide the particular "transfer handle" in that struct + * and that should/could/would be used in subsequent + * curl_easy_getinfo() calls (or similar). The point being that we + * must never expose complex structs to applications, as then we'll + * undoubtably get backwards compatibility problems in the future. + * + * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out + * of structs. It also writes the number of messages left in the + * queue (after this read) in the integer the second argument points + * to. + */ +CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, + int *msgs_in_queue); + +/* + * Name: curl_multi_strerror() + * + * Desc: The curl_multi_strerror function may be used to turn a CURLMcode + * value into the equivalent human readable error string. This is + * useful for printing meaningful error messages. + * + * Returns: A pointer to a zero-terminated error message. + */ +CURL_EXTERN const char *curl_multi_strerror(CURLMcode); + +/* + * Name: curl_multi_socket() and + * curl_multi_socket_all() + * + * Desc: An alternative version of curl_multi_perform() that allows the + * application to pass in one of the file descriptors that have been + * detected to have "action" on them and let libcurl perform. + * See man page for details. + */ +#define CURL_POLL_NONE 0 +#define CURL_POLL_IN 1 +#define CURL_POLL_OUT 2 +#define CURL_POLL_INOUT 3 +#define CURL_POLL_REMOVE 4 + +#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD + +#define CURL_CSELECT_IN 0x01 +#define CURL_CSELECT_OUT 0x02 +#define CURL_CSELECT_ERR 0x04 + +typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* see above */ + void *userp, /* private callback + pointer */ + void *socketp); /* private socket + pointer */ +/* + * Name: curl_multi_timer_callback + * + * Desc: Called by libcurl whenever the library detects a change in the + * maximum number of milliseconds the app is allowed to wait before + * curl_multi_socket() or curl_multi_perform() must be called + * (to allow libcurl's timed events to take place). + * + * Returns: The callback should return zero. + */ +typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp); /* private callback + pointer */ + +CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, + curl_socket_t s, + int ev_bitmask, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); + +#ifndef CURL_ALLOW_OLD_MULTI_SOCKET +/* This macro below was added in 7.16.3 to push users who recompile to use + the new curl_multi_socket_action() instead of the old curl_multi_socket() +*/ +#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) +#endif + +/* + * Name: curl_multi_timeout() + * + * Desc: Returns the maximum number of milliseconds the app is allowed to + * wait before curl_multi_socket() or curl_multi_perform() must be + * called (to allow libcurl's timed events to take place). + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, + long *milliseconds); + +#undef CINIT /* re-using the same name as in curl.h */ + +#ifdef CURL_ISOCPP +#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLMOPT_/**/name = type + number +#endif + +typedef enum { + /* This is the socket callback function pointer */ + CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), + + /* This is the argument passed to the socket callback */ + CINIT(SOCKETDATA, OBJECTPOINT, 2), + + /* set to 1 to enable pipelining for this multi handle */ + CINIT(PIPELINING, LONG, 3), + + /* This is the timer callback function pointer */ + CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), + + /* This is the argument passed to the timer callback */ + CINIT(TIMERDATA, OBJECTPOINT, 5), + + /* maximum number of entries in the connection cache */ + CINIT(MAXCONNECTS, LONG, 6), + + CURLMOPT_LASTENTRY /* the last unused */ +} CURLMoption; + + +/* + * Name: curl_multi_setopt() + * + * Desc: Sets options for the multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, + CURLMoption option, ...); + + +/* + * Name: curl_multi_assign() + * + * Desc: This function sets an association in the multi handle between the + * given socket and a private pointer of the application. This is + * (only) useful for curl_multi_socket uses. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, + curl_socket_t sockfd, void *sockp); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/plugins/FTPFileYM/curl/stdcheaders.h b/plugins/FTPFileYM/curl/stdcheaders.h new file mode 100644 index 0000000000..f739d7f9aa --- /dev/null +++ b/plugins/FTPFileYM/curl/stdcheaders.h @@ -0,0 +1,34 @@ +#ifndef __STDC_HEADERS_H +#define __STDC_HEADERS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: stdcheaders.h,v 1.9 2009-05-18 12:25:45 yangtse Exp $ + ***************************************************************************/ + +#include + +size_t fread (void *, size_t, size_t, FILE *); +size_t fwrite (const void *, size_t, size_t, FILE *); + +int strcasecmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); + +#endif diff --git a/plugins/FTPFileYM/curl/typecheck-gcc.h b/plugins/FTPFileYM/curl/typecheck-gcc.h new file mode 100644 index 0000000000..9788305819 --- /dev/null +++ b/plugins/FTPFileYM/curl/typecheck-gcc.h @@ -0,0 +1,551 @@ +#ifndef __CURL_TYPECHECK_GCC_H +#define __CURL_TYPECHECK_GCC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * $Id: typecheck-gcc.h,v 1.9 2009-01-25 23:26:31 bagder Exp $ + ***************************************************************************/ + +/* wraps curl_easy_setopt() with typechecking */ + +/* To add a new kind of warning, add an + * if(_curl_is_sometype_option(_curl_opt) && ! _curl_is_sometype(value)) + * _curl_easy_setopt_err_sometype(); + * block and define _curl_is_sometype_option, _curl_is_sometype and + * _curl_easy_setopt_err_sometype below + * + * To add an option that uses the same type as an existing option, you'll just + * need to extend the appropriate _curl_*_option macro + */ +#define curl_easy_setopt(handle, option, value) \ +__extension__ ({ \ + __typeof__ (option) _curl_opt = option; \ + if (__builtin_constant_p(_curl_opt)) { \ + if (_curl_is_long_option(_curl_opt) && !_curl_is_long(value)) \ + _curl_easy_setopt_err_long(); \ + if (_curl_is_off_t_option(_curl_opt) && !_curl_is_off_t(value)) \ + _curl_easy_setopt_err_curl_off_t(); \ + if (_curl_is_string_option(_curl_opt) && !_curl_is_string(value)) \ + _curl_easy_setopt_err_string(); \ + if (_curl_is_write_cb_option(_curl_opt) && !_curl_is_write_cb(value)) \ + _curl_easy_setopt_err_write_callback(); \ + if ((_curl_opt) == CURLOPT_READFUNCTION && !_curl_is_read_cb(value)) \ + _curl_easy_setopt_err_read_cb(); \ + if ((_curl_opt) == CURLOPT_IOCTLFUNCTION && !_curl_is_ioctl_cb(value)) \ + _curl_easy_setopt_err_ioctl_cb(); \ + if ((_curl_opt) == CURLOPT_SOCKOPTFUNCTION && !_curl_is_sockopt_cb(value))\ + _curl_easy_setopt_err_sockopt_cb(); \ + if ((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION && \ + !_curl_is_opensocket_cb(value)) \ + _curl_easy_setopt_err_opensocket_cb(); \ + if ((_curl_opt) == CURLOPT_PROGRESSFUNCTION && \ + !_curl_is_progress_cb(value)) \ + _curl_easy_setopt_err_progress_cb(); \ + if ((_curl_opt) == CURLOPT_DEBUGFUNCTION && !_curl_is_debug_cb(value)) \ + _curl_easy_setopt_err_debug_cb(); \ + if ((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION && \ + !_curl_is_ssl_ctx_cb(value)) \ + _curl_easy_setopt_err_ssl_ctx_cb(); \ + if (_curl_is_conv_cb_option(_curl_opt) && !_curl_is_conv_cb(value)) \ + _curl_easy_setopt_err_conv_cb(); \ + if ((_curl_opt) == CURLOPT_SEEKFUNCTION && !_curl_is_seek_cb(value)) \ + _curl_easy_setopt_err_seek_cb(); \ + if (_curl_is_cb_data_option(_curl_opt) && !_curl_is_cb_data(value)) \ + _curl_easy_setopt_err_cb_data(); \ + if ((_curl_opt) == CURLOPT_ERRORBUFFER && !_curl_is_error_buffer(value)) \ + _curl_easy_setopt_err_error_buffer(); \ + if ((_curl_opt) == CURLOPT_STDERR && !_curl_is_FILE(value)) \ + _curl_easy_setopt_err_FILE(); \ + if (_curl_is_postfields_option(_curl_opt) && !_curl_is_postfields(value)) \ + _curl_easy_setopt_err_postfields(); \ + if ((_curl_opt) == CURLOPT_HTTPPOST && \ + !_curl_is_arr((value), struct curl_httppost)) \ + _curl_easy_setopt_err_curl_httpost(); \ + if (_curl_is_slist_option(_curl_opt) && \ + !_curl_is_arr((value), struct curl_slist)) \ + _curl_easy_setopt_err_curl_slist(); \ + if ((_curl_opt) == CURLOPT_SHARE && !_curl_is_ptr((value), CURLSH)) \ + _curl_easy_setopt_err_CURLSH(); \ + } \ + curl_easy_setopt(handle, _curl_opt, value); \ +}) + +/* wraps curl_easy_getinfo() with typechecking */ +/* FIXME: don't allow const pointers */ +#define curl_easy_getinfo(handle, info, arg) \ +__extension__ ({ \ + __typeof__ (info) _curl_info = info; \ + if (__builtin_constant_p(_curl_info)) { \ + if (_curl_is_string_info(_curl_info) && !_curl_is_arr((arg), char *)) \ + _curl_easy_getinfo_err_string(); \ + if (_curl_is_long_info(_curl_info) && !_curl_is_arr((arg), long)) \ + _curl_easy_getinfo_err_long(); \ + if (_curl_is_double_info(_curl_info) && !_curl_is_arr((arg), double)) \ + _curl_easy_getinfo_err_double(); \ + if (_curl_is_slist_info(_curl_info) && \ + !_curl_is_arr((arg), struct curl_slist *)) \ + _curl_easy_getinfo_err_curl_slist(); \ + } \ + curl_easy_getinfo(handle, _curl_info, arg); \ +}) + +/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), + * for now just make sure that the functions are called with three + * arguments + */ +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) + + +/* the actual warnings, triggered by calling the _curl_easy_setopt_err* + * functions */ + +/* To define a new warning, use _CURL_WARNING(identifier, "message") */ +#define _CURL_WARNING(id, message) \ + static void __attribute__((warning(message))) __attribute__((unused)) \ + __attribute__((noinline)) id(void) { __asm__(""); } + +_CURL_WARNING(_curl_easy_setopt_err_long, + "curl_easy_setopt expects a long argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, + "curl_easy_setopt expects a curl_off_t argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_string, + "curl_easy_setopt expects a string (char* or char[]) argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_write_callback, + "curl_easy_setopt expects a curl_write_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_read_cb, + "curl_easy_setopt expects a curl_read_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, + "curl_easy_setopt expects a curl_ioctl_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, + "curl_easy_setopt expects a curl_sockopt_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, + "curl_easy_setopt expects a curl_opensocket_callback argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_progress_cb, + "curl_easy_setopt expects a curl_progress_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_debug_cb, + "curl_easy_setopt expects a curl_debug_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, + "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_conv_cb, + "curl_easy_setopt expects a curl_conv_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_seek_cb, + "curl_easy_setopt expects a curl_seek_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_cb_data, + "curl_easy_setopt expects a private data pointer as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_error_buffer, + "curl_easy_setopt expects a char buffer of CURL_ERROR_SIZE as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_FILE, + "curl_easy_setopt expects a FILE* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_postfields, + "curl_easy_setopt expects a void* or char* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, + "curl_easy_setopt expects a struct curl_httppost* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_slist, + "curl_easy_setopt expects a struct curl_slist* argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_CURLSH, + "curl_easy_setopt expects a CURLSH* argument for this option") + +_CURL_WARNING(_curl_easy_getinfo_err_string, + "curl_easy_getinfo expects a pointer to char * for this info") +_CURL_WARNING(_curl_easy_getinfo_err_long, + "curl_easy_getinfo expects a pointer to long for this info") +_CURL_WARNING(_curl_easy_getinfo_err_double, + "curl_easy_getinfo expects a pointer to double for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, + "curl_easy_getinfo expects a pointer to struct curl_slist * for this info") + +/* groups of curl_easy_setops options that take the same type of argument */ + +/* To add a new option to one of the groups, just add + * (option) == CURLOPT_SOMETHING + * to the or-expression. If the option takes a long or curl_off_t, you don't + * have to do anything + */ + +/* evaluates to true if option takes a long argument */ +#define _curl_is_long_option(option) \ + (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) + +#define _curl_is_off_t_option(option) \ + ((option) > CURLOPTTYPE_OFF_T) + +/* evaluates to true if option takes a char* argument */ +#define _curl_is_string_option(option) \ + ((option) == CURLOPT_URL || \ + (option) == CURLOPT_PROXY || \ + (option) == CURLOPT_INTERFACE || \ + (option) == CURLOPT_NETRC_FILE || \ + (option) == CURLOPT_USERPWD || \ + (option) == CURLOPT_USERNAME || \ + (option) == CURLOPT_PASSWORD || \ + (option) == CURLOPT_PROXYUSERPWD || \ + (option) == CURLOPT_PROXYUSERNAME || \ + (option) == CURLOPT_PROXYPASSWORD || \ + (option) == CURLOPT_NOPROXY || \ + (option) == CURLOPT_ENCODING || \ + (option) == CURLOPT_REFERER || \ + (option) == CURLOPT_USERAGENT || \ + (option) == CURLOPT_COOKIE || \ + (option) == CURLOPT_COOKIEFILE || \ + (option) == CURLOPT_COOKIEJAR || \ + (option) == CURLOPT_COOKIELIST || \ + (option) == CURLOPT_FTPPORT || \ + (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ + (option) == CURLOPT_FTP_ACCOUNT || \ + (option) == CURLOPT_RANGE || \ + (option) == CURLOPT_CUSTOMREQUEST || \ + (option) == CURLOPT_SSLCERT || \ + (option) == CURLOPT_SSLCERTTYPE || \ + (option) == CURLOPT_SSLKEY || \ + (option) == CURLOPT_SSLKEYTYPE || \ + (option) == CURLOPT_KEYPASSWD || \ + (option) == CURLOPT_SSLENGINE || \ + (option) == CURLOPT_CAINFO || \ + (option) == CURLOPT_CAPATH || \ + (option) == CURLOPT_RANDOM_FILE || \ + (option) == CURLOPT_EGDSOCKET || \ + (option) == CURLOPT_SSL_CIPHER_LIST || \ + (option) == CURLOPT_KRBLEVEL || \ + (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ + (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ + (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ + (option) == CURLOPT_CRLFILE || \ + (option) == CURLOPT_ISSUERCERT || \ + 0) + +/* evaluates to true if option takes a curl_write_callback argument */ +#define _curl_is_write_cb_option(option) \ + ((option) == CURLOPT_HEADERFUNCTION || \ + (option) == CURLOPT_WRITEFUNCTION) + +/* evaluates to true if option takes a curl_conv_callback argument */ +#define _curl_is_conv_cb_option(option) \ + ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) + +/* evaluates to true if option takes a data argument to pass to a callback */ +#define _curl_is_cb_data_option(option) \ + ((option) == CURLOPT_WRITEDATA || \ + (option) == CURLOPT_READDATA || \ + (option) == CURLOPT_IOCTLDATA || \ + (option) == CURLOPT_SOCKOPTDATA || \ + (option) == CURLOPT_OPENSOCKETDATA || \ + (option) == CURLOPT_PROGRESSDATA || \ + (option) == CURLOPT_WRITEHEADER || \ + (option) == CURLOPT_DEBUGDATA || \ + (option) == CURLOPT_SSL_CTX_DATA || \ + (option) == CURLOPT_SEEKDATA || \ + (option) == CURLOPT_PRIVATE || \ + 0) + +/* evaluates to true if option takes a POST data argument (void* or char*) */ +#define _curl_is_postfields_option(option) \ + ((option) == CURLOPT_POSTFIELDS || \ + (option) == CURLOPT_COPYPOSTFIELDS || \ + 0) + +/* evaluates to true if option takes a struct curl_slist * argument */ +#define _curl_is_slist_option(option) \ + ((option) == CURLOPT_HTTPHEADER || \ + (option) == CURLOPT_HTTP200ALIASES || \ + (option) == CURLOPT_QUOTE || \ + (option) == CURLOPT_POSTQUOTE || \ + (option) == CURLOPT_PREQUOTE || \ + (option) == CURLOPT_TELNETOPTIONS || \ + 0) + +/* groups of curl_easy_getinfo infos that take the same type of argument */ + +/* evaluates to true if info expects a pointer to char * argument */ +#define _curl_is_string_info(info) \ + (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) + +/* evaluates to true if info expects a pointer to long argument */ +#define _curl_is_long_info(info) \ + (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) + +/* evaluates to true if info expects a pointer to double argument */ +#define _curl_is_double_info(info) \ + (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) + +/* true if info expects a pointer to struct curl_slist * argument */ +#define _curl_is_slist_info(info) \ + (CURLINFO_SLIST < (info)) + + +/* typecheck helpers -- check whether given expression has requested type*/ + +/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, + * otherwise define a new macro. Search for __builtin_types_compatible_p + * in the GCC manual. + * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is + * the actual expression passed to the curl_easy_setopt macro. This + * means that you can only apply the sizeof and __typeof__ operators, no + * == or whatsoever. + */ + +/* XXX: should evaluate to true iff expr is a pointer */ +#define _curl_is_any_ptr(expr) \ + (sizeof(expr) == sizeof(void*)) + +/* evaluates to true if expr is NULL */ +/* XXX: must not evaluate expr, so this check is not accurate */ +#define _curl_is_NULL(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) + +/* evaluates to true if expr is type*, const type* or NULL */ +#define _curl_is_ptr(expr, type) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), type *) || \ + __builtin_types_compatible_p(__typeof__(expr), const type *)) + +/* evaluates to true if expr is one of type[], type*, NULL or const type* */ +#define _curl_is_arr(expr, type) \ + (_curl_is_ptr((expr), type) || \ + __builtin_types_compatible_p(__typeof__(expr), type [])) + +/* evaluates to true if expr is a string */ +#define _curl_is_string(expr) \ + (_curl_is_arr((expr), char) || \ + _curl_is_arr((expr), signed char) || \ + _curl_is_arr((expr), unsigned char)) + +/* evaluates to true if expr is a long (no matter the signedness) + * XXX: for now, int is also accepted (and therefore short and char, which + * are promoted to int when passed to a variadic function) */ +#define _curl_is_long(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), long) || \ + __builtin_types_compatible_p(__typeof__(expr), signed long) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ + __builtin_types_compatible_p(__typeof__(expr), int) || \ + __builtin_types_compatible_p(__typeof__(expr), signed int) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ + __builtin_types_compatible_p(__typeof__(expr), short) || \ + __builtin_types_compatible_p(__typeof__(expr), signed short) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ + __builtin_types_compatible_p(__typeof__(expr), char) || \ + __builtin_types_compatible_p(__typeof__(expr), signed char) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned char)) + +/* evaluates to true if expr is of type curl_off_t */ +#define _curl_is_off_t(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) + +/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ +/* XXX: also check size of an char[] array? */ +#define _curl_is_error_buffer(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), char *) || \ + __builtin_types_compatible_p(__typeof__(expr), char[])) + +/* evaluates to true if expr is of type (const) void* or (const) FILE* */ +#if 0 +#define _curl_is_cb_data(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_ptr((expr), FILE)) +#else /* be less strict */ +#define _curl_is_cb_data(expr) \ + _curl_is_any_ptr(expr) +#endif + +/* evaluates to true if expr is of type FILE* */ +#define _curl_is_FILE(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), FILE *)) + +/* evaluates to true if expr can be passed as POST data (void* or char*) */ +#define _curl_is_postfields(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_arr((expr), char)) + +/* FIXME: the whole callback checking is messy... + * The idea is to tolerate char vs. void and const vs. not const + * pointers in arguments at least + */ +/* helper: __builtin_types_compatible_p distinguishes between functions and + * function pointers, hide it */ +#define _curl_callback_compatible(func, type) \ + (__builtin_types_compatible_p(__typeof__(func), type) || \ + __builtin_types_compatible_p(__typeof__(func), type*)) + +/* evaluates to true if expr is of type curl_read_callback or "similar" */ +#define _curl_is_read_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \ + _curl_callback_compatible((expr), _curl_read_callback1) || \ + _curl_callback_compatible((expr), _curl_read_callback2) || \ + _curl_callback_compatible((expr), _curl_read_callback3) || \ + _curl_callback_compatible((expr), _curl_read_callback4) || \ + _curl_callback_compatible((expr), _curl_read_callback5) || \ + _curl_callback_compatible((expr), _curl_read_callback6)) +typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*); +typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*); +typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*); +typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*); +typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*); +typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*); + +/* evaluates to true if expr is of type curl_write_callback or "similar" */ +#define _curl_is_write_cb(expr) \ + (_curl_is_read_cb(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \ + _curl_callback_compatible((expr), _curl_write_callback1) || \ + _curl_callback_compatible((expr), _curl_write_callback2) || \ + _curl_callback_compatible((expr), _curl_write_callback3) || \ + _curl_callback_compatible((expr), _curl_write_callback4) || \ + _curl_callback_compatible((expr), _curl_write_callback5) || \ + _curl_callback_compatible((expr), _curl_write_callback6)) +typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*); +typedef size_t (_curl_write_callback2)(const char *, size_t, size_t, + const void*); +typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*); +typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*); +typedef size_t (_curl_write_callback5)(const void *, size_t, size_t, + const void*); +typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*); + +/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ +#define _curl_is_ioctl_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback4)) +typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*); +typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*); +typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*); +typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*); + +/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ +#define _curl_is_sockopt_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback2)) +typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); +typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t, + curlsocktype); + +/* evaluates to true if expr is of type curl_opensocket_callback or "similar" */ +#define _curl_is_opensocket_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\ + _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback4)) +typedef curl_socket_t (_curl_opensocket_callback1) + (void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback2) + (void *, curlsocktype, const struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback3) + (const void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (_curl_opensocket_callback4) + (const void *, curlsocktype, const struct curl_sockaddr *); + +/* evaluates to true if expr is of type curl_progress_callback or "similar" */ +#define _curl_is_progress_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \ + _curl_callback_compatible((expr), _curl_progress_callback1) || \ + _curl_callback_compatible((expr), _curl_progress_callback2)) +typedef int (_curl_progress_callback1)(void *, + double, double, double, double); +typedef int (_curl_progress_callback2)(const void *, + double, double, double, double); + +/* evaluates to true if expr is of type curl_debug_callback or "similar" */ +#define _curl_is_debug_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \ + _curl_callback_compatible((expr), _curl_debug_callback1) || \ + _curl_callback_compatible((expr), _curl_debug_callback2) || \ + _curl_callback_compatible((expr), _curl_debug_callback3) || \ + _curl_callback_compatible((expr), _curl_debug_callback4)) +typedef int (_curl_debug_callback1) (CURL *, + curl_infotype, char *, size_t, void *); +typedef int (_curl_debug_callback2) (CURL *, + curl_infotype, char *, size_t, const void *); +typedef int (_curl_debug_callback3) (CURL *, + curl_infotype, const char *, size_t, void *); +typedef int (_curl_debug_callback4) (CURL *, + curl_infotype, const char *, size_t, const void *); + +/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ +/* this is getting even messier... */ +#define _curl_is_ssl_ctx_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) +typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *); +typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *); +typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *); +#ifdef HEADER_SSL_H +/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX + * this will of course break if we're included before OpenSSL headers... + */ +typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); +typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); +typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, const void *); +#else +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; +#endif + +/* evaluates to true if expr is of type curl_conv_callback or "similar" */ +#define _curl_is_conv_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \ + _curl_callback_compatible((expr), _curl_conv_callback1) || \ + _curl_callback_compatible((expr), _curl_conv_callback2) || \ + _curl_callback_compatible((expr), _curl_conv_callback3) || \ + _curl_callback_compatible((expr), _curl_conv_callback4)) +typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); +typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); +typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); +typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); + +/* evaluates to true if expr is of type curl_seek_callback or "similar" */ +#define _curl_is_seek_cb(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \ + _curl_callback_compatible((expr), _curl_seek_callback1) || \ + _curl_callback_compatible((expr), _curl_seek_callback2)) +typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); +typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); + + +#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/plugins/FTPFileYM/curl/types.h b/plugins/FTPFileYM/curl/types.h new file mode 100644 index 0000000000..d37d6ae9e1 --- /dev/null +++ b/plugins/FTPFileYM/curl/types.h @@ -0,0 +1 @@ +/* not used */ diff --git a/plugins/FTPFileYM/dbentry.cpp b/plugins/FTPFileYM/dbentry.cpp new file mode 100644 index 0000000000..cb11af1944 --- /dev/null +++ b/plugins/FTPFileYM/dbentry.cpp @@ -0,0 +1,169 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "dbentry.h" +#include "options.h" + +int DBEntry::entryID; +Mutex DBEntry::mutexDB; + +DBEntry::DBEntry() +{ } + +DBEntry::DBEntry(DBEntry *entry) +{ + this->fileID = entry->fileID; + this->iFtpNum = entry->iFtpNum; + strcpy(this->szFileName, entry->szFileName); +} + +DBEntry *DBEntry::getFirts() +{ + entryID = 0; + DBEntry *entry = new DBEntry(); + return getNext(entry); +} + +DBEntry *DBEntry::getNext(DBEntry *entry) +{ + char szValue[256]; + int count = DB::getDword(0, MODULE_FILES, "NextFileID", 0); + + for (; entryID < count; entryID++) + { + int ftpNum = DB::getByteF(0, MODULE_FILES, "Ftp%d", entryID, -1); + if (ftpNum != -1) + { + if (!DB::getAStringF(0, MODULE_FILES, "Filename%d", entryID, szValue)) + { + entry->fileID = entryID; + entry->iFtpNum = ftpNum; + strcpy(entry->szFileName, szValue); + entry->deleteTS = DB::getDwordF(0, MODULE_FILES, "DeleteTS%d", entryID, 0); + entryID++; + return entry; + } + } + } + + delete entry; + return NULL; +} + +void DBEntry::cleanupDB() +{ + int count = 0; + + DBEntry *entry = getFirts(); + while (entry != NULL) + { + DB::setByteF(0, MODULE_FILES, "Ftp%d", count, entry->iFtpNum); + DB::setAStringF(0, MODULE_FILES, "Filename%d", count, entry->szFileName); + if (entry->deleteTS != 0) + DB::setDwordF(0, MODULE_FILES, "DeleteTS%d", count, entry->deleteTS); + + count++; + entry = getNext(entry); + } + + DB::setDword(0, MODULE_FILES, "NextFileID", count); +} + +DBEntry *DBEntry::get(int fileID) +{ + char szValue[256]; + DBEntry *entry = new DBEntry(); + + int ftpNum = DB::getByteF(0, MODULE_FILES, "Ftp%d", fileID, -1); + if (ftpNum != -1) + { + if (!DB::getAStringF(0, MODULE_FILES, "Filename%d", fileID, szValue)) + { + entry->fileID = fileID; + entry->iFtpNum = ftpNum; + strcpy(entry->szFileName, szValue); + entry->deleteTS = DB::getDwordF(0, MODULE_FILES, "DeleteTS%d", fileID, 0); + return entry; + } + } + + return NULL; +} + +void DBEntry::remove(int fileID) +{ + DB::deleteSettingF(0, MODULE_FILES, "Ftp%d", fileID); + DB::deleteSettingF(0, MODULE_FILES, "Filename%d", fileID); + DB::deleteSettingF(0, MODULE_FILES, "DeleteTS%d", fileID); +} + +bool DBEntry::entryExists(GenericJob *job) +{ + Lock *lock = new Lock(mutexDB); + + DBEntry *entry = getFirts(); + while (entry != NULL) + { + if (entry->iFtpNum == job->iFtpNum && !strcmp(entry->szFileName, job->szSafeFileName)) + { + delete lock; + return true; + } + entry = getNext(entry); + } + + delete lock; + return false; +} + +void DBEntry::add(GenericJob *job) +{ + if (entryExists(job)) + return; + + Lock *lock = new Lock(mutexDB); + int id = DB::getDword(0, MODULE_FILES, "NextFileID", 0); + DB::setByteF(0, MODULE_FILES, "Ftp%d", id, job->iFtpNum); + DB::setAStringF(0, MODULE_FILES, "Filename%d", id, job->szSafeFileName); + + if (job->tab->iOptAutoDelete != -1) + { + time_t deleteTS = time(NULL); + deleteTS += (job->tab->iOptAutoDelete * 60); + DB::setDwordF(0, MODULE_FILES, "DeleteTS%d", id, deleteTS); + } + + DB::setDword(0, MODULE_FILES, "NextFileID", id + 1); + job->fileID = id; + + delete lock; +} + +void DBEntry::setDeleteTS(GenericJob *job) +{ + if (job->tab->iOptAutoDelete != -1) + { + time_t deleteTS = time(NULL); + deleteTS += (job->tab->iOptAutoDelete * 60); + DB::setDwordF(0, MODULE_FILES, "DeleteTS%d", job->fileID, deleteTS); + } + else + { + DB::deleteSettingF(0, MODULE_FILES, "DeleteTS%d", job->fileID); + } +} \ No newline at end of file diff --git a/plugins/FTPFileYM/dbentry.h b/plugins/FTPFileYM/dbentry.h new file mode 100644 index 0000000000..27ad865559 --- /dev/null +++ b/plugins/FTPFileYM/dbentry.h @@ -0,0 +1,51 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "common.h" +#include "job_upload.h" +#include "utils.h" + +class DBEntry +{ +private: + static int entryID; + static bool entryExists(GenericJob *job); + +public: + int fileID; + int iFtpNum; + char szFileName[256]; + DWORD deleteTS; + + static Mutex mutexDB; + + DBEntry(); + DBEntry(DBEntry *entry); + + static DBEntry *getFirts(); + static DBEntry *getNext(DBEntry *entry); + static void cleanupDB(); + + static DBEntry *get(int fileID); + static void remove(int fileID); + + static void add(GenericJob *job); + static void setDeleteTS(GenericJob *job); +}; diff --git a/plugins/FTPFileYM/deletetimer.cpp b/plugins/FTPFileYM/deletetimer.cpp new file mode 100644 index 0000000000..480a0a9c3b --- /dev/null +++ b/plugins/FTPFileYM/deletetimer.cpp @@ -0,0 +1,73 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "deletetimer.h" +#include "dbentry.h" +#include "job_delete.h" + +DeleteTimer *DeleteTimer::instance = NULL; +DeleteTimer &deleteTimer = DeleteTimer::getInstance(); + +extern Options &opt; + +void DeleteTimer::init() +{ + timerId = 0; + if (opt.bAutoDelete) + this->start(); +} + +void DeleteTimer::deinit() +{ + this->stop(); + delete this; +} + +void DeleteTimer::start() +{ + if (!timerId) + timerId = SetTimer(NULL, 0, 1000 * 60 * 5, (TIMERPROC)AutoDeleteTimerProc); +} + +void DeleteTimer::stop() +{ + if (timerId) + { + KillTimer(NULL, timerId); + timerId = 0; + } +} + +void CALLBACK DeleteTimer::AutoDeleteTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) +{ + Lock *lock = new Lock(DBEntry::mutexDB); + + DBEntry *entry = DBEntry::getFirts(); + while (entry != NULL) + { + if (entry->deleteTS > 0 && entry->deleteTS < time(NULL)) + { + DeleteJob *job = new DeleteJob(new DBEntry(entry), NULL); + job->start(); + } + + entry = DBEntry::getNext(entry); + } + + delete lock; +} \ No newline at end of file diff --git a/plugins/FTPFileYM/deletetimer.h b/plugins/FTPFileYM/deletetimer.h new file mode 100644 index 0000000000..9fbe478c9d --- /dev/null +++ b/plugins/FTPFileYM/deletetimer.h @@ -0,0 +1,47 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "common.h" +#include "options.h" + +class DeleteTimer +{ +private: + static DeleteTimer *instance; + UINT timerId; + + DeleteTimer() { }; + ~DeleteTimer() { instance = NULL; }; + + static void CALLBACK AutoDeleteTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime); + +public: + static DeleteTimer &getInstance() + { + if (!instance) + instance = new DeleteTimer(); + return *instance; + }; + + void init(); + void deinit(); + void start(); + void stop(); +}; \ No newline at end of file diff --git a/plugins/FTPFileYM/dialog.cpp b/plugins/FTPFileYM/dialog.cpp new file mode 100644 index 0000000000..9cef156189 --- /dev/null +++ b/plugins/FTPFileYM/dialog.cpp @@ -0,0 +1,456 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "dialog.h" +#include "dbentry.h" +#include "options.h" +#include "job_upload.h" +#include "job_packer.h" + +UploadDialog *UploadDialog::instance = NULL; +UploadDialog *uDlg = NULL; + +Mutex UploadDialog::mutexTabs; +WNDPROC UploadDialog::oldTabControlProc; + +extern Options &opt; +extern BOOL (WINAPI *MyEnableThemeDialogTexture)(HANDLE, DWORD); + +UploadDialog::UploadDialog() +{ + this->hwnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DLG_UPLOAD), 0, UploadDlgProc); + this->hwndTabs = GetDlgItem(this->hwnd, IDC_TAB); + MyEnableThemeDialogTexture(this->hwnd, ETDT_ENABLETAB); + + MONITORINFO mi = {0}; + mi.cbSize = sizeof(mi); + HMONITOR hMonitor = MonitorFromWindow(this->hwnd, MONITOR_DEFAULTTONEAREST); + GetMonitorInfo(hMonitor, &mi); + + RECT rc; + GetWindowRect(this->hwnd, &rc); + rc.left = mi.rcWork.left + ((mi.rcWork.right - mi.rcWork.left) - (rc.right-rc.left)) / 2; + rc.top = mi.rcWork.top + ((mi.rcWork.bottom - mi.rcWork.top) - (rc.bottom-rc.top)) / 2; + SetWindowPos(this->hwnd, 0, rc.left, rc.top, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE); +} + +UploadDialog::~UploadDialog() +{ + if (this->hwnd) + { + ShowWindow(this->hwnd, SW_HIDE); + SendMessage(this->hwnd, WMU_DESTROY, 0, 0); + } + + instance = NULL; + uDlg = NULL; +} + +void UploadDialog::selectTab(int index) +{ + if (tabs[index] != NULL) + tabs[index]->select(); +} + +void UploadDialog::show() +{ + ShowWindow(this->hwnd, SW_SHOWNORMAL); +} + +UploadDialog::Tab::Tab(GenericJob *Job) +:job(Job),bOptCloseDlg(opt.bCloseDlg),bOptCopyLink(opt.bCopyLink),bOptAutosend(opt.bAutosend),iOptAutoDelete(-1) +{ + if (opt.bAutoDelete) + this->iOptAutoDelete = Utils::getDeleteTimeMin(); + + this->stzSpeed[0] = 0; + this->stzComplet[0] = 0; + this->stzRemain[0] = 0; + + TCHAR buff[256]; + TCITEM tab = {0}; + tab.mask = TCIF_TEXT; + tab.pszText = Utils::getTextFragment(job->stzFileName, 20, buff); + TabCtrl_InsertItem(uDlg->hwndTabs, uDlg->tabs.size(), &tab); + + Lock *lock = new Lock(mutexTabs); + uDlg->tabs.push_back(this); + delete lock; + + this->select(); +} + +UploadDialog::Tab::~Tab() +{ + Lock *lock = new Lock(mutexTabs); + TabCtrl_DeleteItem(uDlg->hwndTabs, this->index()); + uDlg->tabs.erase(uDlg->tabs.begin() + this->index()); + delete lock; + + if (this->job->isCompleted()) + delete this->job; + + if (uDlg->tabs.size() == 0) + delete uDlg; + else + uDlg->selectTab(0); +} + +int UploadDialog::Tab::index() +{ + for (UINT i = 0; i < uDlg->tabs.size(); i++) + { + if (uDlg->tabs[i] == this) + return i; + } + + return -1; +} + +void UploadDialog::Tab::select() +{ + TabCtrl_SetCurSel(uDlg->hwndTabs, this->index()); + + Lock *lock = new Lock(mutexTabs); + uDlg->activeTab = this->index(); + delete lock; + + this->job->refreshTab(true); + InvalidateRect(uDlg->hwnd, NULL, TRUE); +} + +void UploadDialog::Tab::labelCompleted() +{ + TCHAR buff[64], buff2[256]; + mir_sntprintf(buff2, SIZEOF(buff2), _T("* %s"), Utils::getTextFragment(this->job->stzFileName, 20, buff)); + + TCITEM tab = {0}; + tab.mask = TCIF_TEXT; + tab.pszText = buff2; + TabCtrl_SetItem(uDlg->hwndTabs, this->index(), &tab); +} + +INT_PTR CALLBACK UploadDialog::TabControlProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDOWN: + { + POINT pt; + GetCursorPos(&pt); + ScreenToClient(uDlg->hwndTabs, &pt); + + TCHITTESTINFO tch; + tch.pt = pt; + tch.flags = 0; + int index = TabCtrl_HitTest(uDlg->hwndTabs, &tch); + + if (index != -1) + uDlg->tabs[index]->job->closeTab(); + } + break; + } + + return CallWindowProc(UploadDialog::oldTabControlProc, hwnd, msg, wParam, lParam); +} + +INT_PTR CALLBACK UploadDialog::UploadDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)Utils::loadIconEx("main")); + + UploadDialog::oldTabControlProc = (WNDPROC)SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_TAB), GWLP_WNDPROC, (LONG_PTR)TabControlProc); + + LOGFONT logFont = {0}; + HFONT hFont = (HFONT)SendMessage(GetDlgItem(hwndDlg, IDC_ST_FILE), WM_GETFONT, 0, 0); + GetObject(hFont, sizeof(logFont), &logFont); + logFont.lfWeight = FW_BOLD; + hFont = CreateFontIndirect(&logFont); + SendMessage(GetDlgItem(hwndDlg, IDC_ST_CONTACT), WM_SETFONT, (WPARAM)hFont, 0); + SendMessage(GetDlgItem(hwndDlg, IDC_ST_FILE), WM_SETFONT, (WPARAM)hFont, 0); + SendMessage(GetDlgItem(hwndDlg, IDC_ST_SERVER), WM_SETFONT, (WPARAM)hFont, 0); + SendMessage(GetDlgItem(hwndDlg, IDC_ST_SPEED), WM_SETFONT, (WPARAM)hFont, 0); + SendMessage(GetDlgItem(hwndDlg, IDC_ST_COMPLETED), WM_SETFONT, (WPARAM)hFont, 0); + SendMessage(GetDlgItem(hwndDlg, IDC_ST_REMAIN), WM_SETFONT, (WPARAM)hFont, 0); + + logFont.lfHeight -= 4; + hFont = CreateFontIndirect(&logFont); + SendMessage(GetDlgItem(hwndDlg, IDC_UP_CONTACT), WM_SETFONT, (WPARAM)hFont, 0); + + SendDlgItemMessage(hwndDlg, IDC_BTN_PROTO, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BTN_PROTO, BUTTONADDTOOLTIP, (WPARAM)TranslateT("User Info"), BATF_TCHAR); + + SendDlgItemMessage(hwndDlg, IDC_BTN_PAUSE, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BTN_PAUSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("pause")); + SendDlgItemMessage(hwndDlg, IDC_BTN_PAUSE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Pause"), BATF_TCHAR); + + SendDlgItemMessage(hwndDlg, IDC_BTN_CLIPBOARD, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BTN_CLIPBOARD, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("clipboard")); + SendDlgItemMessage(hwndDlg, IDC_BTN_CLIPBOARD, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Copy Link to Clipboard"), BATF_TCHAR); + + SendDlgItemMessage(hwndDlg, IDC_BTN_DOWNLOAD, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BTN_DOWNLOAD, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_EVENT_URL)); + SendDlgItemMessage(hwndDlg, IDC_BTN_DOWNLOAD, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open in Browser"), BATF_TCHAR); + + SendDlgItemMessage(hwndDlg, IDC_BTN_FILEMANAGER, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BTN_FILEMANAGER, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("main")); + SendDlgItemMessage(hwndDlg, IDC_BTN_FILEMANAGER, BUTTONADDTOOLTIP, (WPARAM)TranslateT("FTP File Manager"), BATF_TCHAR); + + SendDlgItemMessage(hwndDlg, IDC_BTN_OPTIONS, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BTN_OPTIONS, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_OPTIONS)); + SendDlgItemMessage(hwndDlg, IDC_BTN_OPTIONS, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Options"), BATF_TCHAR); + + SendDlgItemMessage(hwndDlg, IDC_BTN_CLOSE, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BTN_CLOSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_DELETE)); + SendDlgItemMessage(hwndDlg, IDC_BTN_CLOSE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Close"), BATF_TCHAR); + + break; + } + case WM_MEASUREITEM: + { + return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); + } + case WM_DRAWITEM: + { + return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); + } + case WM_COMMAND: + { + HANDLE hContact = uDlg->tabs[uDlg->activeTab]->job->hContact; + if (hContact != NULL) + { + if (CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam),MPCF_CONTACTMENU), (LPARAM)hContact)) + break; + } + + if (HIWORD(wParam) == BN_CLICKED) + { + switch (LOWORD(wParam)) + { + case IDC_BTN_PROTO: + { + if (hContact != NULL) + { + RECT rc; + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)hContact, 0); + GetWindowRect((HWND)lParam, &rc); + TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); + DestroyMenu(hMenu); + } + + break; + } + case IDC_BTN_PAUSE: + { + uDlg->tabs[uDlg->activeTab]->job->pauseHandler(); + return TRUE; + } + case IDC_BTN_CLIPBOARD: + { + UploadJob *job = (UploadJob *)uDlg->tabs[uDlg->activeTab]->job; + Utils::copyToClipboard(job->szFileLink); + return TRUE; + } + case IDC_BTN_DOWNLOAD: + { + UploadJob *job = (UploadJob *)uDlg->tabs[uDlg->activeTab]->job; + ShellExecuteA(NULL, "open", job->szFileLink, NULL, NULL, SW_SHOWNORMAL); + return TRUE; + } + case IDC_BTN_FILEMANAGER: + { + CallService(MS_FTPFILE_SHOWMANAGER, 0, 0); + return TRUE; + } + case IDC_BTN_OPTIONS: + { + Tab *tab = uDlg->tabs[uDlg->activeTab]; + + POINT pt; + GetCursorPos(&pt); + SetForegroundWindow(uDlg->hwndTabs); + + HMENU hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU_UPLOAD)); + if (hMenu) + { + HMENU hPopupMenu = GetSubMenu(hMenu, 0); + CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM)hPopupMenu, 0); + CheckMenuItem(hPopupMenu, IDM_CLOSEDLG, MF_BYCOMMAND | tab->bOptCloseDlg ? MF_CHECKED : 0); + CheckMenuItem(hPopupMenu, IDM_COPYLINK, MF_BYCOMMAND | tab->bOptCopyLink ? MF_CHECKED : 0); + CheckMenuItem(hPopupMenu, IDM_AUTOSEND, MF_BYCOMMAND | tab->bOptAutosend ? MF_CHECKED : 0); + + HMENU hTimeMenu = GetSubMenu(hPopupMenu, 3); + CheckMenuItem(hTimeMenu, IDM_DISABLED, MF_BYCOMMAND | (tab->iOptAutoDelete == -1) ? MF_CHECKED : MF_UNCHECKED); + + int times[10] = {5, 15, 30, 1 * 60, 2 * 60, 5 * 60, 10 * 60, 1 * 24 * 60, 2 * 24 * 60, 7 * 24 * 60}; + bool bChecked = (tab->iOptAutoDelete == -1) ? true : false; + TCHAR buff[256]; + + for (int i = 0; i < SIZEOF(times); i++) + { + if (i == 3 || i == 7) + AppendMenu(hTimeMenu, MF_SEPARATOR, 0, 0); + + if (i < 3) + mir_sntprintf(buff, SIZEOF(buff), TranslateT("%d minutes"), times[i]); + else if (i < 7) + mir_sntprintf(buff, SIZEOF(buff), TranslateT("%d hours"), times[i] / 60); + else + mir_sntprintf(buff, SIZEOF(buff), TranslateT("%d days"), times[i] / 60 / 24); + + UINT check = MF_UNCHECKED; + if (!bChecked && tab->iOptAutoDelete == times[i]) + { + check = MF_CHECKED; + bChecked = true; + } + + AppendMenu(hTimeMenu, MF_STRING | check, times[i], buff); + } + + if (opt.bAutoDelete) + { + switch (opt.timeRange) + { + case Options::TR_MINUTES: mir_sntprintf(buff, SIZEOF(buff), TranslateT("%d minutes"), opt.iDeleteTime); break; + case Options::TR_HOURS: mir_sntprintf(buff, SIZEOF(buff), TranslateT("%d hours"), opt.iDeleteTime); break; + case Options::TR_DAYS: mir_sntprintf(buff, SIZEOF(buff), TranslateT("%d days"), opt.iDeleteTime); break; + } + + AppendMenu(hTimeMenu, MF_SEPARATOR, 0, 0); + AppendMenu(hTimeMenu, MF_STRING | bChecked ? MF_UNCHECKED : MF_CHECKED, IDM_CUSTOM, buff); + } + + int command = TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_RETURNCMD, pt.x, pt.y, 0, uDlg->hwndTabs, NULL); + switch (command) + { + case IDM_CLOSEDLG: + tab->bOptCloseDlg = !tab->bOptCloseDlg; break; + case IDM_COPYLINK: + tab->bOptCopyLink = !tab->bOptCopyLink; break; + case IDM_AUTOSEND: + tab->bOptAutosend = !tab->bOptAutosend; break; + case IDM_DISABLED: + tab->iOptAutoDelete = -1; break; + case IDM_CUSTOM: + switch (opt.timeRange) + { + case Options::TR_MINUTES: tab->iOptAutoDelete = opt.iDeleteTime; break; + case Options::TR_HOURS: tab->iOptAutoDelete = opt.iDeleteTime * 60; break; + case Options::TR_DAYS: tab->iOptAutoDelete = opt.iDeleteTime * 60 * 24; break; + } + break; + default: + tab->iOptAutoDelete = command; + break; + } + + if (command && ((UploadJob *)tab->job)->isCompleted()) + DBEntry::setDeleteTS(tab->job); + + DestroyMenu(hMenu); + } + return TRUE; + } + case IDC_BTN_CLOSE: + { + uDlg->tabs[uDlg->activeTab]->job->closeTab(); + return TRUE; + } + } + } + break; + } + case WM_NOTIFY: + { + switch (((LPNMHDR)lParam)->code) + { + case TCN_SELCHANGE: + { + uDlg->selectTab(TabCtrl_GetCurSel(uDlg->hwndTabs)); + break; + } + case TTN_GETDISPINFO: + { + LPNMTTDISPINFO pInfo = (LPNMTTDISPINFO)lParam; + + POINT pt; + GetCursorPos(&pt); + ScreenToClient(hwndDlg, &pt); + + UINT i; RECT rc; + for (i = 0; i < uDlg->tabs.size(); i++) + { + if (uDlg->tabs[i] != NULL) + { + TabCtrl_GetItemRect(uDlg->hwndTabs, i, &rc); + if (PtInRect(&rc, pt)) break; + } + } + + if (i < uDlg->tabs.size()) + { + uDlg->tabs[i]->job->createToolTip(); + HWND hToolTip = TabCtrl_GetToolTips(uDlg->hwndTabs); + SendMessage(hToolTip, TTM_SETMAXTIPWIDTH, 0, (LPARAM)500); + pInfo->lpszText = uDlg->stzToolTipText; + } + + break; + } + } + break; + } + case WM_CLOSE: + { + for (UINT i = 0; i < uDlg->tabs.size(); i++) + uDlg->tabs[i]->job->pause(); + + int result = IDYES; + if (!Miranda_Terminated() && UploadJob::iRunningJobCount > 0) + result = Utils::msgBox(TranslateT("Do you really want to cancel all running jobs?"), MB_YESNO | MB_ICONQUESTION); + + if (result == IDYES) + { + SkinPlaySound(SOUND_CANCEL); + size_t count = uDlg->tabs.size(); + for (UINT i = 0; i < count; i++) + uDlg->tabs[0]->job->closeAllTabs(); + } + else + { + for (UINT i = 0; i < uDlg->tabs.size(); i++) + uDlg->tabs[i]->job->resume(); + } + + break; + } + case WMU_DESTROY: + { + DestroyWindow(hwndDlg); + break; + } + } + + return FALSE; +} \ No newline at end of file diff --git a/plugins/FTPFileYM/dialog.h b/plugins/FTPFileYM/dialog.h new file mode 100644 index 0000000000..1c1cd38ff8 --- /dev/null +++ b/plugins/FTPFileYM/dialog.h @@ -0,0 +1,84 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "common.h" +#include "utils.h" + +#define WMU_DESTROY (WM_USER + 1) +#define IDM_CUSTOM 41000 + +class UploadDialog +{ + friend class GenericJob; + friend class UploadJob; + friend class PackerJob; + +private: + static UploadDialog *instance; + static Mutex mutexTabs; + static WNDPROC oldTabControlProc; + TCHAR stzToolTipText[1024]; + + UploadDialog(); + +public: + class Tab + { + public: + GenericJob *job; + + bool bOptCloseDlg; + bool bOptCopyLink; + bool bOptAutosend; + int iOptAutoDelete; + + TCHAR stzSpeed[64]; + TCHAR stzComplet[64]; + TCHAR stzRemain[64]; + + Tab(GenericJob *Job); + ~Tab(); + + int index(); + void select(); + void labelCompleted(); + }; + + HWND hwnd; + HWND hwndTabs; + int activeTab; + + vector tabs; + + ~UploadDialog(); + + static UploadDialog *getInstance() + { + if (!instance) + instance = new UploadDialog(); + return instance; + }; + + void selectTab(int index); + void show(); + + static INT_PTR CALLBACK TabControlProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK UploadDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +}; \ No newline at end of file diff --git a/plugins/FTPFileYM/docs/ftpfile_licence.txt b/plugins/FTPFileYM/docs/ftpfile_licence.txt new file mode 100644 index 0000000000..7f1161073d --- /dev/null +++ b/plugins/FTPFileYM/docs/ftpfile_licence.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/plugins/FTPFileYM/docs/ftpfile_readme.txt b/plugins/FTPFileYM/docs/ftpfile_readme.txt new file mode 100644 index 0000000000..971d3d18ab --- /dev/null +++ b/plugins/FTPFileYM/docs/ftpfile_readme.txt @@ -0,0 +1,135 @@ +*********** +FTP File YM +*********** + +Description +=========== +Plugin uploads files to the FTP server. + +Main features +============= +- FTPS (FTP+SSL) and SFTP (FTP via SSH) support +- support for zipping files before upload +- support for sending folders +- tabs support in upload dialog +- possibility to set 5 different FTP servers +- simple file manager for deleting uploaded files from FTP +- added Pause/Resume and Cancel buttons in upload dialog +- customizable menu entries + +!!! Requirements !!! +==================== +Libcurl.dll has to be in Miranda root folder. + + +Changelog +========= + +--- 0.4.0.3 --- +* x64 portability changes +! fixed multiple same files in file manager + +--- 0.4.0.2 --- ++ possibility to enter archive file name ++ check if file exists on server + +--- 0.4.0.1 --- +! restored backward compatibility with Send Screenshot + +--- 0.4.0.0 --- ++ added zipping support ++ added support for sending folders +* many other changes and improvements +* plugin completely rewritted to C++ + +--- 0.3.0.4 --- +* redesigned buttons in file manager +! fixed multiple same files in file manager +! another fixes for SFTP + +--- 0.3.0.3 --- ++ added hidden option ('LocalIP', string format) for set IP address used in PORT command +! fixed file deleting via SFTP +! fixed upload dialog refreshing + +--- 0.3.0.2 --- +! some FTP connection fixes + +--- 0.3.0.1 --- +! fixed 100% CPU load in file manager +! some other minor fixes + +--- 0.3.0.0 --- ++ implemented libcurl library ++ added FTPS (FTP+SSL) and SFTP (FTP via SSH) support + +--- 0.2.2.1 --- ++ auto deletion function can be adjusted in options menu in upload dialog +! some fixes for file manager + +--- 0.2.2.0 --- ++ automatic deletion of file after defined time ++ added send button to tabsrmm button bar ++ added server info to upload dialog +! fixed 'Command after upload' function + +--- 0.2.1.0 --- ++ simple file manager for deleting uploaded files from FTP + +--- 0.2.0.1 --- ++ ability to close tab by double click or middle button click +* changed upload dialog layout +! fixed selection of new tab after tab is closed + +--- 0.2.0.0 --- +* plugin was completely rewritten ++ added tabs support + +--- 0.1.0.3 --- +! disabled menu entries for non IM contacts + +--- 0.1.0.2 --- +! fixed possible crash in options + +--- 0.1.0.1 --- ++ added options for better customize of contact menu items (original patch by jarvis) ++ added check of minimal Miranda version (0.7+) +! fixed percentual indicator for large files + +--- 0.1.0.0 --- ++ first FL version + +--- 0.0.2.5 --- ++ option for remove national characters from filename ++ updater support +* increased number of FTP servers to 5 +* visual changes in upload dialog +! fixed 100% CPU load when upload process is paused +! fixed compatibility with clist_classic and clist_mw +! fixed compatibility with scriver and srmm + +--- 0.0.2.4 --- ++ added Cancel All and Stop/Resume buttons ++ restored service function for other plugins (sendSS) - see m_ftpfile.h +! fixed some minor bugs + +--- 0.0.2.3 --- ++ added Ansi version +! fixed crash on sending multiple files + +--- 0.0.2.2 --- ++ added possibility to set 3 different FTP server ++ full Unicode support +* menu entry redesigned + +Symbols used in changelog: + = new / * = changed / ! = fixed + + +Author +====== +original plugin by Joel Jonsson (thx!) +mod by yaho -> YM + +ICQ: 356344824 +email: yaho@miranda-easy.net +www: www.miranda-easy.net \ No newline at end of file diff --git a/plugins/FTPFileYM/docs/ftpfile_translate.txt b/plugins/FTPFileYM/docs/ftpfile_translate.txt new file mode 100644 index 0000000000..ee987f182f --- /dev/null +++ b/plugins/FTPFileYM/docs/ftpfile_translate.txt @@ -0,0 +1,103 @@ +;FTP File YM +;============= + +;Main +;------ +[FTP File] + +;Open file dialog +;------------------ +[FTP File - Select files] + +;Error messages +;---------------- +[FTP File Error] +[Aborting file upload...] +[Error occurred when opening local file.\nAborting file upload...] +[Error occurred when initializing libcurl.\nAborting file upload...] +[You have to fill FTP server setting before upload file.] +[FTP error occurred.\n%s] + +;Upload dialog +;--------------- +[Upload manager - %d file(s)] +[Sending for:] +[Upload info] +[File:] +[Speed:] +[Completed:] +[Remaining:] +[Download url:] +[Copy link to clipboard] +[Options] +[Close] +[Automatically delete file after...] +[Disabled] + +;File manager +;--------------- +[FTP File manager] +[Select all] +[Deselect all] +[Delete from FTP] +[Delete from list] +[Copy link] +[Download file] + +;Dialogs +;--------------- +[Enter file name] +[File exists - %s] +[File with the same name alredy exists on the server.] +[How to procced?] +[Rename] +[Overwrite] +[Copy URL] +[Cancel] + +;Sounds +;-------- +[File upload complete] +[Upload canceled] + +;Icons +;-------- +[Send file] +[Clipboard] +[FTP Server %d] + +;Options page - Accounts +;----------------------- +[Accounts] +[FTP account] +[Account name] +[Default FTP server] +[Protocol] +[FTP (Standard)] +[FTP+SSL (Explicit)] +[FTP+SSL (Implicit)] +[SFTP (Secure FTP ove SSH)] +[Host name] +[Port] +[Use passive mode] +[User] +[Password] +[Command after upload] +[Directory on server] +[URL] + +;Options page - Advanced +;----------------------- +[Advanced] +[File download link] +[Copy download link to message log] +[Autosend download link to contact] +[Menu items] +[Use submenu (restart required)] +[Hide inactive accounts] +[Other] +[ZIP support] +[Enter archive name manually] +[Compression level:] +[Close dialog after upload finishes] +[Automatically delete file from FTP server after (experimental):] diff --git a/plugins/FTPFileYM/ftpfile.cpp b/plugins/FTPFileYM/ftpfile.cpp new file mode 100644 index 0000000000..0bcac128cb --- /dev/null +++ b/plugins/FTPFileYM/ftpfile.cpp @@ -0,0 +1,634 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "common.h" +#include "deletetimer.h" +#include "dbentry.h" +#include "dialog.h" +#include "libcurl.h" +#include "manager.h" +#include "options.h" +#include "job_delete.h" +#include "job_packer.h" +#include "job_upload.h" +#include "version.h" + +HINSTANCE hInst; +PLUGINLINK *pluginLink; +MM_INTERFACE mmi = {0}; + +HANDLE hModulesLoaded, hEventPreShutdown, hOptionsInit, hPrebuildContactMenu, hTabsrmmButtonPressed; +HANDLE hServiceUpload, hServiceShowManager, hServiceContactMenu, hServiceMainMenu, hServiceShareFile; +HGENMENU hMenu, hMainMenu, hSubMenu[ServerList::FTP_COUNT], hMainSubMenu[ServerList::FTP_COUNT]; + +extern UploadDialog *uDlg; +extern Manager *manDlg; + +extern DeleteTimer &deleteTimer; +extern ServerList &ftpList; +extern Options &opt; +extern LibCurl &curl; + +BOOL (WINAPI *MyEnableThemeDialogTexture)(HANDLE, DWORD) = 0; +int PrebuildContactMenu(WPARAM wParam, LPARAM lParam); +void PrebuildMainMenu(); +int TabsrmmButtonPressed(WPARAM wParam, LPARAM lParam); +int UploadFile(HANDLE hContact, int iFtpNum, UploadJob::EMode mode); + +static PLUGININFOEX pluginInfoEx = +{ + sizeof(PLUGININFOEX), +#ifdef _WIN64 + "FTP File YM x64", +#else + "FTP File YM", +#endif + __VERSION_DWORD, + "FTP a file to a server and send the URL to your friend. Supported automatic zipping before upload and encryption via SFTP and FTPS.", + "yaho", + "yaho@miranda-easy.net", + "Copyright © 2007-2010 Jan Holub", + "http://miranda-easy.net/mods.php", + UNICODE_AWARE, + 0, + MIID_FTPFILE +}; + +//------------ BASIC STAFF ------------// + +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + hInst = hinstDLL; + return TRUE; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + if (mirandaVersion < PLUGIN_MAKE_VERSION(0, 8, 0, 0)) + return NULL; + + return &pluginInfoEx; +} + +static const MUUID interfaces[] = {MIID_FTPFILE, MIID_LAST}; +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + +//------------ INIT FUNCTIONS ------------// + +struct _tag_iconList +{ + char *szDescr; + char *szName; + int defIconID; +} +static const iconList[6] = +{ + { "Send file", "main", IDI_MENU }, + { "Clipboard", "clipboard", IDI_CLIPBOARD }, + { "Pause", "pause", IDI_PAUSE }, + { "Resume", "resume", IDI_RESUME }, + { "Delete from list", "clear", IDI_CLEAR }, + { "Delete from FTP", "delete", IDI_DELETE } +}; + +static HANDLE hIconlibItem[ServerList::FTP_COUNT + SIZEOF(iconList)]; + +static void InitIcolib() +{ + TCHAR stzFile[MAX_PATH]; + char szSettingName[100]; + char szDesc[100]; + + SKINICONDESC sid = {0}; + sid.cbSize = sizeof(sid); + sid.cx = sid.cy = 16; + sid.ptszDefaultFile = stzFile; + sid.pszSection = MODULE; + sid.pszDescription = szDesc; + sid.pszName = szSettingName; + sid.flags = SIDF_PATH_TCHAR; + + GetModuleFileName(hInst, stzFile, MAX_PATH); + + for (int i = 0; i < ServerList::FTP_COUNT; i++) + { + mir_snprintf(szDesc, sizeof(szDesc), Translate("FTP Server %d"), i + 1); + mir_snprintf(szSettingName, sizeof(szSettingName), "%s_ftp%d", MODULE, i); + sid.iDefaultIndex = -(IDI_FTP0 + i); + hIconlibItem[i] = (HANDLE)CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); + } + + for (int i = 0; i < SIZEOF(iconList); i++) + { + mir_snprintf(szSettingName, sizeof(szSettingName), "%s_%s", MODULE, iconList[i].szName); + sid.pszDescription = Translate(iconList[i].szDescr); + sid.iDefaultIndex = -(iconList[i].defIconID); + hIconlibItem[i + ServerList::FTP_COUNT] = (HANDLE)CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); + } +} + +void InitMenuItems() +{ + CLISTMENUITEM mi = {0}; + CLISTMENUITEM mi2 = {0}; + TCHAR stzName[256]; + + mi.cbSize = sizeof(mi); + mi.flags = CMIF_ROOTPOPUP | CMIF_ICONFROMICOLIB | CMIF_TCHAR; + mi.icolibItem = hIconlibItem[ServerList::FTP_COUNT]; + mi.position = 3000090001; + mi.ptszName = LPGENT("FTP File"); + + hMainMenu = (HGENMENU)CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi); + if (opt.bUseSubmenu) hMenu = (HGENMENU)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); + + memset(&mi, 0, sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.ptszName = stzName; + + mi2.cbSize = sizeof(mi2); + mi2.flags = CMIF_CHILDPOPUP | CMIF_ROOTHANDLE | CMIF_TCHAR; + mi2.pszService = MS_FTPFILE_CONTACTMENU; + + for (int i = 0; i < ServerList::FTP_COUNT; i++) + { + if (DB::getStringF(0, MODULE, "Name%d", i, stzName)) + mir_sntprintf(stzName, SIZEOF(stzName), TranslateT("FTP Server %d"), i + 1); + + mi.flags = CMIF_ICONFROMICOLIB | CMIF_TCHAR; + mi.hParentMenu = 0; + if (opt.bUseSubmenu) + { + mi.flags |= CMIF_CHILDPOPUP | CMIF_ROOTHANDLE; + mi.hParentMenu = hMenu; + } + + mi.icolibItem = hIconlibItem[i]; + mi.popupPosition = i + 1000; + hSubMenu[i] = (HGENMENU)CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); + + mi.flags |= CMIF_CHILDPOPUP | CMIF_ROOTHANDLE; + mi.hParentMenu = hMainMenu; + hMainSubMenu[i] = (HGENMENU)CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi); + + mi2.hParentMenu = hSubMenu[i]; + mi2.pszService = MS_FTPFILE_CONTACTMENU; + mi2.popupPosition = mi2.position = i + UploadJob::FTP_RAWFILE; + mi2.ptszName = TranslateT("Upload file(s)"); + CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi2); + + mi2.pszService = MS_FTPFILE_MAINMENU; + mi2.hParentMenu = hMainSubMenu[i]; + CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi2); + + mi2.hParentMenu = hSubMenu[i]; + mi2.pszService = MS_FTPFILE_CONTACTMENU; + mi2.popupPosition = i + UploadJob::FTP_ZIPFILE; + mi2.ptszName = TranslateT("Zip and upload file(s)"); + CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi2); + + mi2.pszService = MS_FTPFILE_MAINMENU; + mi2.hParentMenu = hMainSubMenu[i]; + CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi2); + + mi2.hParentMenu = hSubMenu[i]; + mi2.pszService = MS_FTPFILE_CONTACTMENU; + mi2.popupPosition = i + UploadJob::FTP_ZIPFOLDER; + mi2.ptszName = TranslateT("Zip and upload folder"); + CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi2); + + mi2.pszService = MS_FTPFILE_MAINMENU; + mi2.hParentMenu = hMainSubMenu[i]; + CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi2); + } + + memset(&mi, 0, sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.flags = CMIF_ICONFROMICOLIB | CMIF_CHILDPOPUP | CMIF_ROOTHANDLE | CMIF_TCHAR; + mi.icolibItem = hIconlibItem[ServerList::FTP_COUNT]; + mi.position = 3000090001; + mi.ptszName = LPGENT("FTP File manager"); + mi.pszService = MS_FTPFILE_SHOWMANAGER; + mi.hParentMenu = hMainMenu; + CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi); + + PrebuildMainMenu(); + + hPrebuildContactMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu); +} + +void InitHotkeys() +{ + HOTKEYDESC hk = {0}; + hk.cbSize = sizeof(hk); + hk.pszDescription = LPGEN("Show FTPFile manager"); + hk.pszName = LPGEN("FTP_ShowManager"); + hk.pszSection = MODULE; + hk.pszService = MS_FTPFILE_SHOWMANAGER; + CallService(MS_HOTKEY_REGISTER, 0, (LPARAM)&hk); +} + +void InitUpdater() +{ +#ifndef _WIN64 + if (ServiceExists(MS_UPDATE_REGISTER)) + { + Update update = {0}; + char szVersion[16]; + update.cbSize = sizeof(Update); + update.szComponentName = pluginInfoEx.shortName; + update.pbVersion = (BYTE *)CreateVersionString(pluginInfoEx.version, szVersion); + update.cpbVersion = (int)strlen((char *)update.pbVersion); + +#ifdef _UNICODE + update.szUpdateURL = "http://miranda-easy.net/addons/updater/ftpfile-ym.zip"; +#else + update.szUpdateURL = "http://miranda-easy.net/addons/updater/ftpfile-ym_ansi.zip"; +#endif + update.szVersionURL = "http://miranda-easy.net/addons/updater/ftpfile_version.txt"; + update.pbVersionPrefix = (BYTE *)"FTP File YM "; + update.cpbVersionPrefix = (int)strlen((char *)update.pbVersionPrefix); + CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); + } +#endif +} + +void InitTabsrmmButton() +{ + if (ServiceExists(MS_BB_ADDBUTTON)) + { + BBButton btn = {0}; + btn.cbSize = sizeof(btn); + btn.dwButtonID = 1; + btn.pszModuleName = MODULE; + btn.dwDefPos = 105; + btn.hIcon = hIconlibItem[ServerList::FTP_COUNT]; + btn.bbbFlags = BBBF_ISARROWBUTTON | BBBF_ISIMBUTTON | BBBF_ISLSIDEBUTTON | BBBF_CANBEHIDDEN; + btn.ptszTooltip = TranslateT("FTP File"); + CallService(MS_BB_ADDBUTTON, 0, (LPARAM)&btn); + hTabsrmmButtonPressed = HookEvent(ME_MSG_BUTTONPRESSED, TabsrmmButtonPressed); + } +} + +//------------ MENU & BUTTON HANDLERS ------------// + +int PrebuildContactMenu(WPARAM wParam, LPARAM lParam) +{ + bool bIsContact = false; + + char *szProto = DB::getProto((HANDLE)wParam); + if (szProto) bIsContact = (CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_IM) ? true : false; + + bool bHideRoot = opt.bHideInactive; + for (int i = 0; i < ServerList::FTP_COUNT; i++) + { + if (ftpList[i]->bEnabled) + bHideRoot = false; + } + + CLISTMENUITEM mi = {0}; + mi.cbSize = sizeof(mi); + mi.flags = CMIM_FLAGS; + + if (opt.bUseSubmenu) + { + if (!bIsContact || bHideRoot) mi.flags |= CMIF_HIDDEN; + else mi.flags &= ~CMIF_HIDDEN; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMenu, (LPARAM)&mi); + } + + for (int i = 0; i < ServerList::FTP_COUNT; i++) + { + mi.flags = CMIM_FLAGS; + if (!bIsContact) + { + mi.flags |= CMIF_HIDDEN; + } + else if (!ftpList[i]->bEnabled) + { + mi.flags |= opt.bHideInactive ? CMIF_HIDDEN : CMIF_GRAYED; + } + + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hSubMenu[i], (LPARAM)&mi); + } + + return 0; +} + +void PrebuildMainMenu() +{ + CLISTMENUITEM mi = {0}; + mi.cbSize = sizeof(mi); + + for (int i = 0; i < ServerList::FTP_COUNT; i++) + { + mi.flags = CMIM_FLAGS; + if (!ftpList[i]->bEnabled) + mi.flags |= opt.bHideInactive ? CMIF_HIDDEN : CMIF_GRAYED; + + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hMainSubMenu[i], (LPARAM)&mi); + } +} + +int TabsrmmButtonPressed(WPARAM wParam, LPARAM lParam) +{ + CustomButtonClickData *cbc = (CustomButtonClickData *)lParam; + HANDLE hContact = (HANDLE)wParam; + + if (!strcmp(cbc->pszModule, MODULE) && cbc->dwButtonId == 1 && hContact) + { + if (cbc->flags == BBCF_ARROWCLICKED) + { + HMENU hMenu = CreatePopupMenu(); + if (hMenu) + { + int iCount = 0; + for (UINT i = 0; i < ServerList::FTP_COUNT; i++) + { + if (ftpList[i]->bEnabled) + { + HMENU hModeMenu = CreatePopupMenu(); + AppendMenu(hModeMenu, MF_STRING, i + UploadJob::FTP_RAWFILE, TranslateT("Upload file")); + AppendMenu(hModeMenu, MF_STRING, i + UploadJob::FTP_ZIPFILE, TranslateT("Zip and upload file")); + AppendMenu(hModeMenu, MF_STRING, i + UploadJob::FTP_ZIPFOLDER, TranslateT("Zip and upload folder")); + AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT_PTR)hModeMenu, ftpList[i]->stzName); + DestroyMenu(hModeMenu); + iCount++; + } + } + + if (iCount != 0) + { + POINT pt; + GetCursorPos(&pt); + HWND hwndBtn = WindowFromPoint(pt); + if (hwndBtn) + { + RECT rc; + GetWindowRect(hwndBtn, &rc); + SetForegroundWindow(cbc->hwndFrom); + int selected = TrackPopupMenu(hMenu, TPM_RETURNCMD, rc.left, rc.bottom, 0, cbc->hwndFrom, 0); + if (selected != 0) + { + int ftpNum = selected & (1|2|4); + int mode = selected & (UploadJob::FTP_RAWFILE | UploadJob::FTP_ZIPFILE | UploadJob::FTP_ZIPFOLDER); + UploadFile(hContact, ftpNum, (UploadJob::EMode)mode); + } + } + } + + DestroyMenu(hMenu); + } + } + else + { + UploadFile(hContact, 0, UploadJob::FTP_RAWFILE); + } + } + + return 0; +} + +int UploadFile(HANDLE hContact, int iFtpNum, GenericJob::EMode mode, void **objects, int objCount, DWORD flags) +{ + if (!ftpList[iFtpNum]->isValid()) + { + Utils::msgBox(TranslateT("You have to fill FTP server setting before upload a file."), MB_OK | MB_ICONERROR); + return 1; + } + + GenericJob *job; + if (mode == GenericJob::FTP_RAWFILE) + job = new UploadJob(hContact, iFtpNum, mode); + else + job = new PackerJob(hContact, iFtpNum, mode); + + int result; + if (objects != NULL) + result = job->getFiles(objects, objCount, flags); + else + result = job->getFiles(); + + if (result != 0) + { + uDlg = UploadDialog::getInstance(); + if (!uDlg->hwnd || !uDlg->hwndTabs) + { + Utils::msgBox(TranslateT("Error has occurred while trying to create a dialog!"), MB_OK | MB_ICONERROR); + delete uDlg; + return 1; + } + + job->addToUploadDlg(); + uDlg->show(); + } + else + { + delete job; + return 1; + } + + return 0; +} + +int UploadFile(HANDLE hContact, int iFtpNum, GenericJob::EMode mode) +{ + return UploadFile(hContact, iFtpNum, mode, NULL, 0, 0); +} + +//------------ MIRANDA SERVICES ------------// + +INT_PTR UploadService(WPARAM wParam, LPARAM lParam) +{ + FTPUPLOAD* ftpu = (FTPUPLOAD *)lParam; + if (ftpu == NULL || ftpu->cbSize != sizeof(FTPUPLOAD)) + return 1; + + int ftpNum = (ftpu->ftpNum == FNUM_DEFAULT) ? opt.defaultFTP : ftpu->ftpNum - 1; + int mode = (ftpu->mode * GenericJob::FTP_RAWFILE); + + UploadFile(ftpu->hContact, ftpNum, (GenericJob::EMode)mode, (void**)ftpu->pstzObjects, ftpu->objectCount, ftpu->flags); + return 0; +} + +INT_PTR ShareFileService(WPARAM wParam, LPARAM lParam) +{ + if (!wParam || !lParam) + return 1; + + FTPUPLOAD ftpu = {0}; + ftpu.cbSize = sizeof(ftpu); + ftpu.ftpNum = FNUM_DEFAULT; + ftpu.mode = FMODE_RAWFILE; + ftpu.hContact = (HANDLE)wParam; + + char *szFile = (char *)mir_alloc(1024 * sizeof(char)); + ZeroMemory(szFile, 1024); + strcpy(szFile, (char *)lParam); + + char *ptr, buff[256]; + if (szFile[strlen(szFile) + 1]) + { + ptr = szFile + strlen(szFile) + 1; + while (ptr[0]) + { + ftpu.pszObjects = (char **)mir_realloc(ftpu.pszObjects, (ftpu.objectCount + 1) * sizeof(char *)); + mir_snprintf(buff, MAX_PATH, "%s\\%s", szFile, ptr); + ftpu.pszObjects[ftpu.objectCount++] = mir_strdup(buff); + ptr += strlen(ptr) + 1; + } + } + else + { + ftpu.pszObjects = (char **)mir_alloc(sizeof(char *)); + ftpu.pszObjects[0] = mir_strdup(szFile); + ftpu.objectCount = 1; + } + + CallService(MS_FTPFILE_UPLOAD, 0, (LPARAM)&ftpu); + + for (int i = 0; i < ftpu.objectCount; i++) + FREE(ftpu.pszObjects[i]); + + FREE(ftpu.pszObjects); + FREE(szFile); + + return 0; +} + +INT_PTR ShowManagerService(WPARAM wParam, LPARAM lParam) +{ + manDlg = Manager::getInstance(); + manDlg->init(); + return 0; +} + +INT_PTR ContactMenuService(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + int ftpNum = lParam & (1|2|4); + int mode = lParam & (UploadJob::FTP_RAWFILE | UploadJob::FTP_ZIPFILE | UploadJob::FTP_ZIPFOLDER); + return UploadFile(hContact, ftpNum, (UploadJob::EMode)mode); +} + +INT_PTR MainMenuService(WPARAM wParam, LPARAM lParam) +{ + int ftpNum = wParam & (1|2|4); + int mode = wParam & (UploadJob::FTP_RAWFILE | UploadJob::FTP_ZIPFILE | UploadJob::FTP_ZIPFOLDER); + return UploadFile(0, ftpNum, (UploadJob::EMode)mode); +} + +//------------ START & EXIT STUFF ------------// + +int ModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + InitIcolib(); + InitMenuItems(); + InitHotkeys(); + InitUpdater(); + InitTabsrmmButton(); + + SkinAddNewSoundEx(SOUND_UPCOMPLETE, Translate("FTP File"), Translate("File upload complete")); + SkinAddNewSoundEx(SOUND_CANCEL, Translate("FTP File"), Translate("Upload canceled")); + + curl.global_init(CURL_GLOBAL_ALL); + + return 0; +} + +int Shutdown(WPARAM wParam, LPARAM lParam) +{ + deleteTimer.deinit(); + + if (manDlg) delete manDlg; + if (uDlg) SendMessage(uDlg->hwnd, WM_CLOSE, 0, 0); + + UploadJob::jobDone.release(); + DeleteJob::jobDone.release(); + DBEntry::cleanupDB(); + + curl.global_cleanup(); + + ftpList.deinit(); + opt.deinit(); + curl.deinit(); + + return 0; +} + +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) +{ + pluginLink = link; + + if (!curl.init()) + { + Utils::msgBox(TranslateT("FTP File YM won't be loaded because libcurl.dll is missing or wrong version!"), MB_OK | MB_ICONERROR); + return 1; + } + +#ifdef _DEBUG + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); +#endif + + mir_getMMI(&mmi); + + CoInitialize(NULL); + + hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); + hEventPreShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, Shutdown); + hOptionsInit = HookEvent(ME_OPT_INITIALISE, Options::InitOptions); + + hServiceUpload = CreateServiceFunction(MS_FTPFILE_UPLOAD, UploadService); + hServiceShowManager = CreateServiceFunction(MS_FTPFILE_SHOWMANAGER, ShowManagerService); + hServiceContactMenu = CreateServiceFunction(MS_FTPFILE_CONTACTMENU, ContactMenuService); + hServiceMainMenu = CreateServiceFunction(MS_FTPFILE_MAINMENU, MainMenuService); + hServiceShareFile = CreateServiceFunction(MS_FTPFILE_SHAREFILE, ShareFileService); + + if (IsWinVerXPPlus()) + { + HMODULE hUxTheme = GetModuleHandle(_T("uxtheme.dll")); + if (hUxTheme) + MyEnableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture"); + } + + opt.loadOptions(); + deleteTimer.init(); + ftpList.init(); + + return 0; +} + +extern "C" int __declspec(dllexport) Unload(void) +{ + UnhookEvent(hModulesLoaded); + UnhookEvent(hEventPreShutdown); + UnhookEvent(hOptionsInit); + UnhookEvent(hPrebuildContactMenu); + UnhookEvent(hTabsrmmButtonPressed); + + DestroyServiceFunction(hServiceUpload); + DestroyServiceFunction(hServiceShowManager); + DestroyServiceFunction(hServiceContactMenu); + DestroyServiceFunction(hServiceMainMenu); + DestroyServiceFunction(hServiceShareFile); + + return 0; +} \ No newline at end of file diff --git a/plugins/FTPFileYM/ftpfile.rc b/plugins/FTPFileYM/ftpfile.rc new file mode 100644 index 0000000000..c1cd9e3a96 --- /dev/null +++ b/plugins/FTPFileYM/ftpfile.rc @@ -0,0 +1,317 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1250) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPT_FTPFILE DIALOGEX 0, 0, 268, 230 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "FTP account",IDC_STATIC,7,5,254,220 + RTEXT "Host name",IDC_STATIC,14,70,89,8 + RTEXT "User",IDC_STATIC,14,129,89,8 + RTEXT "Password",IDC_STATIC,14,148,89,8 + RTEXT "URL",IDC_STATIC,14,207,89,8 + RTEXT "Directory on server",IDC_STATIC,14,189,89,8 + EDITTEXT IDC_SERVER,109,68,140,12,ES_AUTOHSCROLL + EDITTEXT IDC_USER,109,127,140,12,ES_AUTOHSCROLL + EDITTEXT IDC_PASSWORD,109,146,140,12,ES_PASSWORD | ES_AUTOHSCROLL + EDITTEXT IDC_DIR,109,186,140,12,ES_AUTOHSCROLL + EDITTEXT IDC_URL,109,205,140,12,ES_AUTOHSCROLL + RTEXT "Port",IDC_STATIC,14,88,89,8 + EDITTEXT IDC_PORT,109,86,140,12,ES_AUTOHSCROLL | ES_NUMBER + RTEXT "Command after upload",IDC_STATIC,14,172,89,8 + EDITTEXT IDC_CHMOD,109,170,140,12,ES_AUTOHSCROLL + CONTROL "Use passive mode",IDC_PASSIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,110,104,142,10 + COMBOBOX IDC_FTPLIST,109,16,125,28,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + RTEXT "Account name",IDC_STATIC,14,18,89,8,0,WS_EX_RIGHT + CONTROL "",IDC_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,241,18,11,10 + COMBOBOX IDC_PROTOLIST,109,50,125,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "Protocol",IDC_STATIC,14,53,89,8 + CONTROL "Default FTP server",IDC_DEFAULT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,109,33,140,10 +END + +IDD_OPT_ADVANCED DIALOGEX 0, 0, 265, 225 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "File download link",IDC_STATIC,5,12,254,42 + CONTROL "Close dialog after upload is completed",IDC_CLOSEDLG, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,163,236,10 + CONTROL "Copy download link to message log",IDC_URL_COPYTOML, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,38,236,10 + CONTROL "Autosend download link to contact",IDC_URL_AUTOSEND, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,24,236,10 + GROUPBOX "Menu items",IDC_STATIC,5,58,254,42 + CONTROL "Use submenu (restart required)",IDC_USESUBMENU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,69,236,10 + CONTROL "Hide inactive accounts",IDC_HIDEINACTIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,84,236,10 + GROUPBOX "Other",IDC_STATIC,5,152,254,60 + CONTROL "Automatically delete file from FTP server after (experimental):",IDC_AUTODELETE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,177,237,10 + EDITTEXT IDC_DELETETIME,27,192,38,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_DELETETIME_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,57,187,11,14 + COMBOBOX IDC_RANGE,71,192,75,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "ZIP support",IDC_STATIC,5,104,254,44 + CONTROL "Enter archive name manually",IDC_SETZIPNAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,115,240,10 + LTEXT "Compression level:",IDC_STATIC,24,131,82,8 + EDITTEXT IDC_LEVEL,108,130,38,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_LEVEL_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,135,125,11,14 +END + +IDD_DLG_UPLOAD DIALOGEX 0, 0, 285, 148 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Upload File Manager" +FONT 8, "Tahoma", 400, 0, 0xEE +BEGIN + CONTROL "",IDC_TAB,"SysTabControl32",TCS_TOOLTIPS | WS_TABSTOP,3,3,279,142 + LTEXT "",IDC_STATIC,3,134,277,10,SS_SUNKEN + LTEXT "File:",IDC_ST_FILE,21,46,55,8 + LTEXT "Completed:",IDC_ST_COMPLETED,21,85,55,8 + LTEXT "Speed:",IDC_ST_SPEED,21,72,55,8 + LTEXT "Remaining:",IDC_ST_REMAIN,21,98,55,8 + GROUPBOX "Summary",IDC_STATIC,11,35,260,79 + LTEXT "",IDC_UP_FILE,84,46,180,8 + CONTROL "",IDC_PB_UPLOAD,"msctls_progress32",PBS_SMOOTH | WS_BORDER,11,119,236,10 + LTEXT "",IDC_UP_SPEED,84,72,180,8 + LTEXT "",IDC_UP_COMPLETED,84,85,180,8 + LTEXT "To:",IDC_ST_CONTACT,17,22,19,8 + LTEXT "Nick",IDC_UP_CONTACT,55,18,158,17,SS_CENTERIMAGE + LTEXT "",IDC_UP_REMAIN,84,98,180,8 + CONTROL "Close",IDC_BTN_CLOSE,"MButtonClass",WS_TABSTOP,253,20,16,14 + CONTROL "Clipboard",IDC_BTN_CLIPBOARD,"MButtonClass",NOT WS_VISIBLE | WS_TABSTOP,251,96,16,14 + EDITTEXT IDC_ED_URL,20,97,210,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_VISIBLE + CONTROL "Options",IDC_BTN_OPTIONS,"MButtonClass",WS_TABSTOP,237,20,16,14 + CONTROL "Pause",IDC_BTN_PAUSE,"MButtonClass",WS_TABSTOP,253,117,16,14 + CONTROL "File Manager",IDC_BTN_FILEMANAGER,"MButtonClass",WS_TABSTOP,221,20,16,14 + LTEXT "Server:",IDC_ST_SERVER,21,59,55,8 + LTEXT "",IDC_UP_SERVER,84,59,180,8 + CONTROL "User info",IDC_BTN_PROTO,"MButtonClass",WS_TABSTOP,38,20,16,14 + LTEXT "UPLOADING...",IDC_STATUSBAR,11,135,267,8 + CONTROL "Open in Browser",IDC_BTN_DOWNLOAD,"MButtonClass",NOT WS_VISIBLE | WS_TABSTOP,235,96,16,14 +END + +IDD_DLG_MANAGER DIALOGEX 0, 0, 214, 215 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "FTP File Manager" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_FILELIST,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | TVS_INFOTIP | WS_BORDER | WS_HSCROLL | WS_TABSTOP,6,6,201,189 + CONTROL "Select All",IDC_BTN_SELECTALL,"MButtonClass",WS_TABSTOP,6,198,16,14 + CONTROL "Deselect All",IDC_BTN_DESELECTALL,"MButtonClass",WS_TABSTOP,22,198,16,14 + CONTROL "Delete from list",IDC_BTN_DELETEFROMLIST,"MButtonClass",WS_TABSTOP,44,198,16,14 + CONTROL "Delete from FTP",IDC_BTN_DELETE,"MButtonClass",WS_TABSTOP,60,198,16,14 + CONTROL "Close",IDC_BTN_CLOSE,"MButtonClass",WS_TABSTOP,191,198,16,14 +END + +IDD_DLG_NAME DIALOGEX 0, 0, 165, 52 +STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Enter file name" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + PUSHBUTTON "OK",IDOK,24,31,50,14 + PUSHBUTTON "Cancel",IDCANCEL,90,31,50,14 + EDITTEXT IDC_NAME,7,8,151,14,ES_AUTOHSCROLL +END + +IDD_DLG_FILEEXISTS DIALOGEX 0, 0, 220, 76 +STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION +CAPTION "File exists" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Rename",IDC_RENAME,35,38,65,14 + PUSHBUTTON "Overwrite",IDC_OVERWRITE,119,38,65,14 + CTEXT "File with the same name already exists on the server.",IDC_HEADER,4,9,211,8 + CTEXT "How to proceed?",IDC_STATIC,4,20,211,8 + PUSHBUTTON "Cancel",IDC_CANCEL,119,56,65,14 + PUSHBUTTON "Copy URL",IDC_COPYURL,35,56,65,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OPT_FTPFILE, DIALOG + BEGIN + BOTTOMMARGIN, 223 + END + + IDD_OPT_ADVANCED, DIALOG + BEGIN + BOTTOMMARGIN, 212 + END + + IDD_DLG_UPLOAD, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 278 + TOPMARGIN, 7 + BOTTOMMARGIN, 141 + END + + IDD_DLG_MANAGER, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 207 + TOPMARGIN, 7 + BOTTOMMARGIN, 194 + END + + IDD_DLG_NAME, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 158 + TOPMARGIN, 7 + BOTTOMMARGIN, 45 + END + + IDD_DLG_FILEEXISTS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 213 + TOPMARGIN, 7 + BOTTOMMARGIN, 69 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU_UPLOAD MENU +BEGIN + POPUP "" + BEGIN + MENUITEM "Autosend download link to contact", IDM_AUTOSEND + MENUITEM "Copy download link to message log", IDM_COPYLINK + MENUITEM "Close dialog after upload finishes", IDM_CLOSEDLG + POPUP "Automatically delete file after..." + BEGIN + MENUITEM "Disabled", IDM_DISABLED + MENUITEM SEPARATOR + END + END +END + +IDR_MENU_MANAGER MENU +BEGIN + POPUP "" + BEGIN + MENUITEM "Delete from List", IDM_DELETEFROMLIST + MENUITEM "Delete from FTP", IDM_DELETEFROMFTP + MENUITEM SEPARATOR + MENUITEM "Copy Link", IDM_COPYLINK + MENUITEM "Open in Browser", IDM_DOWNLOAD + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_PAUSE ICON "icons\\pause.ico" +IDI_FTP0 ICON "icons\\ftp0.ico" +IDI_FTP1 ICON "icons\\ftp1.ico" +IDI_FTP2 ICON "icons\\ftp2.ico" +IDI_FTP3 ICON "icons\\ftp3.ico" +IDI_FTP4 ICON "icons\\ftp4.ico" +IDI_MENU ICON "icons\\menu.ico" +IDI_CLIPBOARD ICON "icons\\clipboard.ico" +IDI_RESUME ICON "icons\\resume.ico" +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Czech resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) +#ifdef _WIN32 +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +#pragma code_page(1250) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_CLEAR ICON "icons\\clear.ico" +IDI_DELETE ICON "icons\\delete.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Czech resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/FTPFileYM/ftpfile_10.vcxproj b/plugins/FTPFileYM/ftpfile_10.vcxproj new file mode 100644 index 0000000000..b50cdd5535 --- /dev/null +++ b/plugins/FTPFileYM/ftpfile_10.vcxproj @@ -0,0 +1,435 @@ +п»ї + + + + Debug Unicode + Win32 + + + Debug Unicode + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release Unicode + Win32 + + + Release Unicode + x64 + + + Release + Win32 + + + Release + x64 + + + + ftpfile + {73482497-9F57-4819-A9AB-5D841A9F072D} + ftpfile + Win32Proj + + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + MultiByte + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + MultiByte + true + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)64\ + $(Configuration)64\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)64\ + $(Configuration)64\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + $(SolutionDir)$(Configuration)64\ + $(Configuration)64\ + false + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)64\ + $(Configuration)64\ + true + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + Disabled + ..\..\include;curl;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + common.h + Level3 + EditAndContinue + + + wininet.lib;uxtheme.lib;comctl32.lib;zlib.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + lib;%(AdditionalLibraryDirectories) + true + Windows + MachineX86 + + + + + X64 + + + Disabled + ..\..\include;curl;%(AdditionalIncludeDirectories) + _WIN64;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + common.h + Level3 + false + ProgramDatabase + + + wininet.lib;uxtheme.lib;comctl32.lib;zlib.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + lib;%(AdditionalLibraryDirectories) + true + Windows + MachineX64 + + + + + Full + true + ..\..\include;curl;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + + + wininet.lib;uxtheme.lib;comctl32.lib;zlib.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + lib;%(AdditionalLibraryDirectories) + false + %(IgnoreSpecificDefaultLibraries) + true + Windows + true + true + true + MachineX86 + + + + + X64 + + + Full + true + ..\..\include;curl;%(AdditionalIncludeDirectories) + _WIN64;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + wininet.lib;uxtheme.lib;comctl32.lib;zlib.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + lib;%(AdditionalLibraryDirectories) + false + %(IgnoreSpecificDefaultLibraries) + true + Windows + true + true + true + MachineX64 + + + + + Full + true + ..\..\include;curl;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + false + ProgramDatabase + + + wininet.lib;uxtheme.lib;comctl32.lib;zlib.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + lib;%(AdditionalLibraryDirectories) + false + %(IgnoreSpecificDefaultLibraries) + true + Windows + true + true + true + MachineX86 + + + + + X64 + + + Full + true + ..\..\include;curl;%(AdditionalIncludeDirectories) + _WIN64;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + false + ProgramDatabase + + + wininet.lib;uxtheme.lib;comctl32.lib;zlib.lib;%(AdditionalDependencies) + $(OutDir)$(ProjectName).dll + lib;%(AdditionalLibraryDirectories) + false + %(IgnoreSpecificDefaultLibraries) + true + Windows + true + true + true + MachineX64 + + + + + Disabled + ..\..\include;curl;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + common.h + Level3 + EditAndContinue + + + wininet.lib;uxtheme.lib;comctl32.lib;zlib.lib;%(AdditionalDependencies) + d:\Development\TEST\miranda-im-v0.9.3-unicode\plugins\ftpfile.dll + lib;%(AdditionalLibraryDirectories) + %(DelayLoadDLLs) + true + Windows + MachineX86 + + + + + X64 + + + Disabled + ..\..\include;curl;%(AdditionalIncludeDirectories) + _WIN64;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + common.h + Level3 + ProgramDatabase + + + wininet.lib;uxtheme.lib;comctl32.lib;zlib.lib;%(AdditionalDependencies) + d:\Development\YMP\4.6\Light\Miranda IM\plugins\ftpfile.dll + lib;%(AdditionalLibraryDirectories) + %(DelayLoadDLLs) + true + Windows + MachineX64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/FTPFileYM/ftpfile_10.vcxproj.filters b/plugins/FTPFileYM/ftpfile_10.vcxproj.filters new file mode 100644 index 0000000000..7f21cc8ad4 --- /dev/null +++ b/plugins/FTPFileYM/ftpfile_10.vcxproj.filters @@ -0,0 +1,175 @@ +п»ї + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {b3e7dfba-6dac-490c-b597-8001819c9a39} + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {e450d857-86aa-4ad4-b63c-3a21362402c8} + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files\zip + + + Source Files\zip + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files\zip + + + Header Files\zip + + + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + Resource Files + + + + + Resource Files + + + Resource Files + + + \ No newline at end of file diff --git a/plugins/FTPFileYM/icons/clear.ico b/plugins/FTPFileYM/icons/clear.ico new file mode 100644 index 0000000000..8fd6c2a936 Binary files /dev/null and b/plugins/FTPFileYM/icons/clear.ico differ diff --git a/plugins/FTPFileYM/icons/clipboard.ico b/plugins/FTPFileYM/icons/clipboard.ico new file mode 100644 index 0000000000..d0e80b0e7e Binary files /dev/null and b/plugins/FTPFileYM/icons/clipboard.ico differ diff --git a/plugins/FTPFileYM/icons/delete.ico b/plugins/FTPFileYM/icons/delete.ico new file mode 100644 index 0000000000..26058006a0 Binary files /dev/null and b/plugins/FTPFileYM/icons/delete.ico differ diff --git a/plugins/FTPFileYM/icons/ftp0.ico b/plugins/FTPFileYM/icons/ftp0.ico new file mode 100644 index 0000000000..2a10ab1ad9 Binary files /dev/null and b/plugins/FTPFileYM/icons/ftp0.ico differ diff --git a/plugins/FTPFileYM/icons/ftp1.ico b/plugins/FTPFileYM/icons/ftp1.ico new file mode 100644 index 0000000000..6ab8b4a2f3 Binary files /dev/null and b/plugins/FTPFileYM/icons/ftp1.ico differ diff --git a/plugins/FTPFileYM/icons/ftp2.ico b/plugins/FTPFileYM/icons/ftp2.ico new file mode 100644 index 0000000000..cda6827a5e Binary files /dev/null and b/plugins/FTPFileYM/icons/ftp2.ico differ diff --git a/plugins/FTPFileYM/icons/ftp3.ico b/plugins/FTPFileYM/icons/ftp3.ico new file mode 100644 index 0000000000..ed2eea3582 Binary files /dev/null and b/plugins/FTPFileYM/icons/ftp3.ico differ diff --git a/plugins/FTPFileYM/icons/ftp4.ico b/plugins/FTPFileYM/icons/ftp4.ico new file mode 100644 index 0000000000..69965d998a Binary files /dev/null and b/plugins/FTPFileYM/icons/ftp4.ico differ diff --git a/plugins/FTPFileYM/icons/menu.ico b/plugins/FTPFileYM/icons/menu.ico new file mode 100644 index 0000000000..ae0e211a7f Binary files /dev/null and b/plugins/FTPFileYM/icons/menu.ico differ diff --git a/plugins/FTPFileYM/icons/pause.ico b/plugins/FTPFileYM/icons/pause.ico new file mode 100644 index 0000000000..c3ed4fa12b Binary files /dev/null and b/plugins/FTPFileYM/icons/pause.ico differ diff --git a/plugins/FTPFileYM/icons/resume.ico b/plugins/FTPFileYM/icons/resume.ico new file mode 100644 index 0000000000..01451a7319 Binary files /dev/null and b/plugins/FTPFileYM/icons/resume.ico differ diff --git a/plugins/FTPFileYM/job_delete.cpp b/plugins/FTPFileYM/job_delete.cpp new file mode 100644 index 0000000000..f7d2c7c64b --- /dev/null +++ b/plugins/FTPFileYM/job_delete.cpp @@ -0,0 +1,124 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "common.h" +#include "job_delete.h" + +Event DeleteJob::jobDone; +Mutex DeleteJob::mutexJobCount; +int DeleteJob::iRunningJobCount = 0; + +extern ServerList &ftpList; +extern Manager *manDlg; +extern LibCurl &curl; + +DeleteJob::DeleteJob(DBEntry *_entry, Manager::TreeItem *_item) +:entry(_entry),treeItem(_item),ftp(ftpList[entry->iFtpNum]) +{ } + +DeleteJob::~DeleteJob() +{ + delete this->entry; +} + +void DeleteJob::waitingThread(void *arg) +{ + DeleteJob *job = (DeleteJob *)arg; + + while(!Miranda_Terminated()) + { + Lock *lock = new Lock(mutexJobCount); + if (iRunningJobCount < MAX_RUNNING_JOBS) + { + iRunningJobCount++; + delete lock; + job->run(); + delete job; + + Lock *lock = new Lock(mutexJobCount); + iRunningJobCount--; + delete lock; + + jobDone.release(); + return; + } + + delete lock; + jobDone.wait(); + } + + delete job; +} + +void DeleteJob::start() +{ + mir_forkthread(&DeleteJob::waitingThread, this); +} + +void DeleteJob::run() +{ + char szError[1024]; + + CURL *hCurl = curl.easy_init(); + if (hCurl) + { + struct curl_slist *headerList = NULL; + headerList = curl.slist_append(headerList, getDelFileString()); + + Utils::curlSetOpt(hCurl, this->ftp, getDelUrlString(), headerList, szError); + + int result = curl.easy_perform(hCurl); + if (result == CURLE_OK) + { + if (manDlg != NULL && this->treeItem) + this->treeItem->remove(); + else + DBEntry::remove(entry->fileID); + } + else if (manDlg != NULL && this->treeItem) + { + TCHAR *error = mir_a2t(szError); + _tcscpy(this->treeItem->stzToolTip, error); + this->treeItem->setState(Manager::TreeItem::_ERROR()); + FREE(error); + } + + curl.slist_free_all(headerList); + curl.easy_cleanup(hCurl); + } +} + +char *DeleteJob::getDelFileString() +{ + if (ftp->ftpProto == ServerList::FTP::FT_SSH) + mir_snprintf(buff, sizeof(buff), "rm \"%s/%s\"", ftp->szDir, entry->szFileName); + else + mir_snprintf(buff, sizeof(buff), "DELE %s", entry->szFileName); + + return buff; +} + +char *DeleteJob::getDelUrlString() +{ + if (ftp->szDir[0] && ftp->ftpProto != ServerList::FTP::FT_SSH) + mir_snprintf(buff, sizeof(buff), "%s%s/%s/", ftp->getProtoString(), ftp->szServer, ftp->szDir); + else + mir_snprintf(buff, sizeof(buff), "%s%s/", ftp->getProtoString(), ftp->szServer); + + return buff; +} \ No newline at end of file diff --git a/plugins/FTPFileYM/job_delete.h b/plugins/FTPFileYM/job_delete.h new file mode 100644 index 0000000000..a2da7c5d24 --- /dev/null +++ b/plugins/FTPFileYM/job_delete.h @@ -0,0 +1,50 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "dbentry.h" +#include "manager.h" + +class DeleteJob +{ +private: + static const int MAX_RUNNING_JOBS = 2; + + DBEntry *entry; + Manager::TreeItem *treeItem; + ServerList::FTP *ftp; + char buff[256]; + + static Mutex mutexJobCount; + static int iRunningJobCount; + + char *getDelFileString(); + char *getDelUrlString(); + + static void waitingThread(void *arg); + void run(); + +public: + static Event jobDone; + + DeleteJob(DBEntry *entry, Manager::TreeItem *item); + ~DeleteJob(); + + void start(); +}; diff --git a/plugins/FTPFileYM/job_generic.cpp b/plugins/FTPFileYM/job_generic.cpp new file mode 100644 index 0000000000..2a126b2190 --- /dev/null +++ b/plugins/FTPFileYM/job_generic.cpp @@ -0,0 +1,255 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "job_generic.h" +#include "dbentry.h" +#include "utils.h" + +extern UploadDialog *uDlg; +extern ServerList &ftpList; + +GenericJob::GenericJob(HANDLE _hContact, int _iFtpNum, EMode _mode) +:hContact(_hContact),iFtpNum(_iFtpNum),mode(_mode),status(STATUS_CREATED),ftp(ftpList[iFtpNum]) +{ + this->stzFilePath[0] = 0; + this->stzFileName[0] = 0; + this->szSafeFileName[0] = 0; +} + +GenericJob::GenericJob(GenericJob *job) +:hContact(job->hContact),iFtpNum(job->iFtpNum),mode(job->mode),status(job->status),ftp(job->ftp),tab(job->tab) +{ + _tcscpy(this->stzFilePath, job->stzFilePath); + _tcscpy(this->stzFileName, job->stzFileName); + strcpy(this->szSafeFileName, job->szSafeFileName); +} + +GenericJob::~GenericJob() +{ + for (UINT i = 0; i < this->files.size(); i++) + mir_free(this->files[i]); +} + +int GenericJob::openFileDialog() +{ + OPENFILENAME ofn = {0}; + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = 0; + ofn.lpstrFilter = _T("All Files (*.*)\0*.*\0"); + ofn.nFilterIndex = 1; + ofn.lpstrFile = this->stzFilePath; + ofn.lpstrTitle = TranslateT("FTP File - Select files"); + ofn.nMaxFile = SIZEOF(this->stzFilePath); + ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_NOCHANGEDIR; + return GetOpenFileName(&ofn); +} + +int GenericJob::openFolderDialog() +{ + BROWSEINFO bi = {0}; + bi.lpszTitle = TranslateT("FTP File - Select a folder"); + bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_NONEWFOLDERBUTTON | BIF_DONTGOBELOWDOMAIN; + LPITEMIDLIST pidl = SHBrowseForFolder(&bi); + if (pidl != 0) + { + SHGetPathFromIDList(pidl, this->stzFilePath); + CoTaskMemFree(pidl); + return 1; + } + + return 0; +} + +void GenericJob::getFilesFromOpenDialog() +{ + TCHAR stzFile[MAX_PATH]; + + size_t length = _tcslen(this->stzFilePath); + if (this->stzFilePath[0] && this->stzFilePath[length+1]) // multiple files + { + TCHAR *ptr = this->stzFilePath + length + 1; + while (ptr[0]) + { + mir_sntprintf(stzFile, MAX_PATH, _T("%s\\%s"), this->stzFilePath, ptr); + this->addFile(stzFile); + ptr += _tcslen(ptr) + 1; + } + } + else + { + this->addFile(this->stzFilePath); + } +} + +int GenericJob::getFilesFromFolder(TCHAR *stzFolder) +{ + TCHAR stzFile[MAX_PATH], stzDirSave[MAX_PATH]; + + GetCurrentDirectory(MAX_PATH, stzDirSave); + if (!SetCurrentDirectory(stzFolder)) + { + Utils::msgBox(TranslateT("Folder not found!"), MB_OK | MB_ICONERROR); + return 0; + } + + WIN32_FIND_DATA ffd; + HANDLE hFind = FindFirstFile(_T("*.*"), &ffd); + while (hFind != INVALID_HANDLE_VALUE) + { + if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + mir_sntprintf(stzFile, MAX_PATH, _T("%s\\%s"), stzFolder, ffd.cFileName); + this->addFile(stzFile); + } + + if (!FindNextFile(hFind, &ffd)) + break; + } + + FindClose(hFind); + SetCurrentDirectory(stzDirSave); + + if (this->files.size() == 0) + { + Utils::msgBox(TranslateT("The selected folder does not contain any files.\nFTP File sends files only from the selected folder, not from subfolders."), MB_OK | MB_ICONERROR); + return 0; + } + + return 1; +} + +int GenericJob::getFiles() +{ + if (this->mode == FTP_ZIPFOLDER) + { + if (!openFolderDialog()) return 0; + return getFilesFromFolder(this->stzFilePath); + } + else + { + if (!openFileDialog()) return 0; + getFilesFromOpenDialog(); + } + + return 1; +} + +int GenericJob::getFiles(void **objects, int objCount, DWORD flags) +{ + if (this->mode == FTP_ZIPFOLDER) + { + TCHAR *folder; + if (flags & FUPL_UNICODE) + folder = mir_u2t((wchar_t *)objects[0]); + else + folder = mir_a2t((char *)objects[0]); + + int result = getFilesFromFolder(folder); + FREE(folder); + return result; + } + else + { + for (int i = 0; i < objCount; i++) + { + TCHAR *fileName; + if (flags & FUPL_UNICODE) + fileName = mir_u2t((wchar_t *)objects[i]); + else + fileName = mir_a2t((char *)objects[i]); + + addFile(fileName); + FREE(fileName); + } + } + + return (this->files.size() == 0) ? 0 : 1; +} + +void GenericJob::addFile(TCHAR *fileName) +{ + TCHAR *buff = mir_tstrdup(fileName); + this->files.push_back(buff); +} + +void GenericJob::setStatus(EStatus status) +{ + this->status = status; + this->refreshTab(true); +} + +bool GenericJob::isCompleted() +{ + return this->status == STATUS_COMPLETED; +} + +bool GenericJob::isPaused() +{ + return this->status == STATUS_PAUSED; +} + +bool GenericJob::isWaitting() +{ + return this->status == STATUS_WAITING; +} + +bool GenericJob::isCanceled() +{ + return this->status == STATUS_CANCELED; +} + +bool GenericJob::isConnecting() +{ + return (this->status == STATUS_CONNECTING || this->status == STATUS_CREATED); +} + +TCHAR *GenericJob::getStatusString() +{ + switch (this->status) + { + case STATUS_CANCELED: return TranslateT("CANCELED"); + case STATUS_COMPLETED: return TranslateT("COMPLETED"); + case STATUS_CONNECTING: return TranslateT("CONNECTING..."); + case STATUS_CREATED: return TranslateT("CREATED"); + case STATUS_PACKING: return TranslateT("PACKING..."); + case STATUS_PAUSED: return TranslateT("PAUSED"); + case STATUS_UPLOADING: return TranslateT("UPLOADING..."); + case STATUS_WAITING: return TranslateT("WAITING..."); + default: return TranslateT("UNKNOWN"); + } +} + +void GenericJob::refreshTab(bool bTabChanged) +{ + if (bTabChanged) + { + if (this->hContact != NULL) + { + SendDlgItemMessage(uDlg->hwnd, IDC_BTN_PROTO, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedProtoIcon(DB::getProto(this->hContact), ID_STATUS_ONLINE)); + SetDlgItemText(uDlg->hwnd, IDC_UP_CONTACT, (TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)this->hContact, GCDNF_TCHAR)); + } + else + { + SendDlgItemMessage(uDlg->hwnd, IDC_BTN_PROTO, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("main")); + SetDlgItemTextA(uDlg->hwnd, IDC_UP_CONTACT, this->ftp->szServer); + } + + SetDlgItemText(uDlg->hwnd, IDC_UP_FILE, this->stzFileName); + SetDlgItemTextA(uDlg->hwnd, IDC_UP_SERVER, this->ftp->szServer); + } +} \ No newline at end of file diff --git a/plugins/FTPFileYM/job_generic.h b/plugins/FTPFileYM/job_generic.h new file mode 100644 index 0000000000..618d891a82 --- /dev/null +++ b/plugins/FTPFileYM/job_generic.h @@ -0,0 +1,109 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "common.h" +#include "dialog.h" +#include "serverlist.h" + +class Event +{ +private: + HANDLE handle; + +public: + Event() { handle = CreateEvent (0, FALSE, FALSE, 0); } + ~Event() { CloseHandle (handle); } + + operator HANDLE () { return handle; } + + void release() { SetEvent(handle); } + void wait() { WaitForSingleObject(handle, INFINITE); } +}; + +class GenericJob +{ +private: + int openFileDialog(); + int openFolderDialog(); + void getFilesFromOpenDialog(); + int getFilesFromFolder(TCHAR *stzFolder); + void addFile(TCHAR *fileName); + +public: + enum EMode + { + FTP_RAWFILE = 8, + FTP_ZIPFILE = 16, + FTP_ZIPFOLDER = 32 + }; + + enum EStatus + { + STATUS_CREATED = 0, + STATUS_WAITING, + STATUS_CONNECTING, + STATUS_UPLOADING, + STATUS_PACKING, + STATUS_PAUSED, + STATUS_CANCELED, + STATUS_COMPLETED + }; + + HANDLE hContact; + int iFtpNum, fileID; + ServerList::FTP *ftp; + TCHAR stzFilePath[1024]; + TCHAR stzFileName[64]; + char szSafeFileName[64]; + EMode mode; + EStatus status; + + UploadDialog::Tab *tab; + vector files; + TCHAR * operator[] (int i) const { return files[i];} + + GenericJob(HANDLE hContact, int iFtpNum, EMode mode); + GenericJob(GenericJob *job); + virtual ~GenericJob(); + + int getFiles(); + int getFiles(void **objects, int objCount, DWORD flags); + void setStatus(EStatus status); + + bool isCompleted(); + bool isPaused(); + bool isWaitting(); + bool isConnecting(); + bool isCanceled(); + + TCHAR *getStatusString(); + + virtual void start() = 0; + virtual void pause() = 0; + virtual void resume() = 0; + virtual void cancel() = 0; + virtual void addToUploadDlg() = 0; + virtual void pauseHandler() = 0; + + virtual void refreshTab(bool bTabChanged); + virtual void closeTab() = 0; + virtual void closeAllTabs() = 0; + virtual void createToolTip() = 0; +}; diff --git a/plugins/FTPFileYM/job_packer.cpp b/plugins/FTPFileYM/job_packer.cpp new file mode 100644 index 0000000000..4d5c9ce4d5 --- /dev/null +++ b/plugins/FTPFileYM/job_packer.cpp @@ -0,0 +1,354 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "job_packer.h" +#include "job_upload.h" +#include "dialog.h" +#include "options.h" +#include "utils.h" + +Event PackerJob::jobDone; +Mutex PackerJob::mutexJobCount; +int PackerJob::iRunningJobCount = 0; + +extern UploadDialog *uDlg; +extern Options &opt; + +PackerJob::PackerJob(HANDLE _hContact, int _iFtpNum, EMode _mode) +:GenericJob(_hContact, _iFtpNum, _mode),uiFileSize(0),uiReaded(0),lastUpdateTick(0) +{ } + +void PackerJob::getZipFilePath() +{ + TCHAR buff[256], stzFileName[256] = {0}; + TCHAR *pch; + + if (this->files.size() == 1) + { + _tcscpy(stzFileName, Utils::getFileNameFromPath(this->files[0])); + pch = _tcsrchr(stzFileName, '.'); + if (pch) *pch = 0; + } + else + { + _tcscpy(buff, this->files[0]); + pch = _tcsrchr(buff, '\\'); + if (pch) + { + *pch = 0; + pch = _tcsrchr(buff, '\\'); + if (pch) _tcscpy(stzFileName, pch + 1); + } + } + + if (_tcslen(stzFileName) == 0) + _tcscpy(stzFileName, _T("archive")); + + GetTempPath(SIZEOF(buff), buff); + + mir_sntprintf(this->stzFilePath, SIZEOF(this->stzFilePath), _T("%s%s.zip"), buff, stzFileName); + _tcscpy(this->stzFileName, Utils::getFileNameFromPath(this->stzFilePath)); + + if (opt.bSetZipName) + Utils::setFileNameDlg(this->stzFileName); +} + +void PackerJob::addToUploadDlg() +{ + this->getZipFilePath(); + + UploadDialog::Tab *newTab = new UploadDialog::Tab(this); + this->tab = newTab; + this->start(); +} + +void PackerJob::waitingThread(void *arg) +{ + PackerJob *job = (PackerJob *)arg; + + while(!Miranda_Terminated()) + { + Lock *lock = new Lock(mutexJobCount); + if (iRunningJobCount < MAX_RUNNING_JOBS) + { + iRunningJobCount++; + delete lock; + job->pack(); + delete job; + + Lock *lock = new Lock(mutexJobCount); + iRunningJobCount--; + delete lock; + + jobDone.release(); + return; + } + + delete lock; + jobDone.wait(); + job->status = GenericJob::STATUS_WAITING; + } +} + +void PackerJob::start() +{ + mir_forkthread(&PackerJob::waitingThread, this); +} + +void PackerJob::pack() +{ + struct _stat fileInfo; + for (UINT i = 0; i < this->files.size(); i++) + { + if (_tstat(this->files[i], &fileInfo) == 0) + this->uiFileSize += (UINT64)fileInfo.st_size; + } + + this->setStatus(STATUS_PACKING); + this->startTS = time(NULL); + + int res = this->createZipFile(); + if (res == ZIP_OK) + { + UploadJob *ujob = new UploadJob(this); + ujob->tab->job = ujob; + ujob->start(); + } + else + { + if (res == ZIP_ERRNO) + { + Utils::msgBox(TranslateT("Error occured when zipping the file(s)."), MB_OK | MB_ICONERROR); + delete this->tab; + } + + DeleteFile(this->stzFilePath); + } +} + +int PackerJob::createZipFile() +{ + int result = ZIP_ERRNO; + + char *filePath = mir_t2a(this->stzFilePath); + zipFile zf = zipOpen2(filePath, 0, NULL, NULL); + FREE(filePath); + + if (zf != NULL) + { + result = ZIP_OK; + + int size_buf = 65536; + void *buff = (void *)mir_alloc(size_buf); + + for (UINT i = 0; i < this->files.size(); i++) + { + int size_read; + zip_fileinfo zi; + + zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour = 0; + zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0; + zi.dosDate = 0; + zi.internal_fa = 0; + zi.external_fa = 0; + + getFileTime(this->files[i], &zi.tmz_date, &zi.dosDate); + + char *file = mir_t2a(Utils::getFileNameFromPath(this->files[i])); + int err = zipOpenNewFileInZip(zf, file, &zi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, opt.iCompressionLevel); + FREE(file); + + if (err == ZIP_OK) + { + FILE *fin = _tfopen(this->files[i], _T("rb")); + if (fin) + { + do + { + if (this->isCanceled()) + { + fclose(fin); + result = STATUS_CANCELED; + goto Cleanup; + } + + err = ZIP_OK; + size_read = (int)fread(buff, 1, size_buf, fin); + if (size_read < size_buf && feof(fin) == 0) + { + fclose(fin); + result = ZIP_ERRNO; + goto Cleanup; + } + + if (size_read > 0) + { + err = zipWriteInFileInZip(zf, buff, size_read); + this->uiReaded += size_read; + } + + this->updateStats(); + } + while ((err == ZIP_OK) && (size_read > 0)); + fclose(fin); + } + else + { + err = ZIP_ERRNO; + } + + err = zipCloseFileInZip(zf); + if (err < 0) + { + result = ZIP_ERRNO; + goto Cleanup; + } + } + else + { + result = ZIP_ERRNO; + break; + } + } + +Cleanup: + zipClose(zf, NULL); + FREE(buff); + } + + return result; +} + +uLong PackerJob::getFileTime(TCHAR *file, tm_zip *tmzip, uLong *dt) +{ + FILETIME ftLocal; + HANDLE hFind; + WIN32_FIND_DATA ff32; + + hFind = FindFirstFile(file, &ff32); + if (hFind != INVALID_HANDLE_VALUE) + { + FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal); + FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0); + FindClose(hFind); + return 1; + } + + return 0; +} + +void PackerJob::updateStats() +{ + DWORD dwNewTick = GetTickCount(); + if (this->uiReaded && (time(NULL) > this->startTS) && (dwNewTick > this->lastUpdateTick + 100)) + { + this->lastUpdateTick = dwNewTick; + + double speed = ((double)this->uiReaded / 1024)/(time(NULL) - this->startTS); + mir_sntprintf(this->tab->stzSpeed, SIZEOF(this->tab->stzSpeed), _T("%0.1f kB/s"), speed); + + double perc = this->uiFileSize ? ((double)this->uiReaded / this->uiFileSize) * 100 : 0; + mir_sntprintf(this->tab->stzComplet, SIZEOF(this->tab->stzComplet), _T("%0.1f%% (%d kB/%d kB)"), perc, (int)this->uiReaded/1024, (int)this->uiFileSize/1024); + + TCHAR buff[256]; + long s = (this->uiFileSize - this->uiReaded) / (long)(speed * 1024); + int d = (s / 60 / 60 / 24); + int h = (s - d * 60 * 60 * 24) / 60 / 60; + int m = (s - d * 60 * 60 * 24 - h * 60 * 60) / 60; + s = s - (d * 24 * 60 * 60) - (h * 60 * 60) - (m * 60); + + if (d > 0) mir_sntprintf(buff, SIZEOF(buff), _T("%dd %02d:%02d:%02d"), d, h, m, s); + else mir_sntprintf(buff, SIZEOF(buff), _T("%02d:%02d:%02d"), h, m, s); + mir_sntprintf(this->tab->stzRemain, SIZEOF(this->tab->stzRemain), _T("%s (%d kB/%d kB)"), buff, (this->uiFileSize - this->uiReaded)/1024, this->uiFileSize/1024); + + this->refreshTab(false); + } +} + +void PackerJob::refreshTab(bool bTabChanged) +{ + if (uDlg->activeTab == this->tab->index()) + { + GenericJob::refreshTab(bTabChanged); + + SetDlgItemText(uDlg->hwnd, IDC_UP_SPEED, this->tab->stzSpeed); + SetDlgItemText(uDlg->hwnd, IDC_UP_COMPLETED, this->tab->stzComplet); + SetDlgItemText(uDlg->hwnd, IDC_UP_REMAIN, this->tab->stzRemain); + + SendDlgItemMessage(uDlg->hwnd, IDC_PB_UPLOAD, PBM_SETRANGE32, 0, (LPARAM)this->uiFileSize); + SendDlgItemMessage(uDlg->hwnd, IDC_PB_UPLOAD, PBM_SETPOS, (WPARAM)this->uiReaded, 0); + + if (bTabChanged) + { + SetDlgItemText(uDlg->hwnd, IDC_STATUSBAR, TranslateT("PACKING...")); + EnableWindow(GetDlgItem(uDlg->hwnd, IDC_BTN_PAUSE), FALSE); + } + } +} + +bool PackerJob::isCanceled() +{ + return this->status == STATUS_CANCELED; +} + +void PackerJob::pauseHandler() +{ + /* Not implemented */ +} + +void PackerJob::pause() +{ + /* Not implemented */ +} + +void PackerJob::resume() +{ + /* Not implemented */ +} + +void PackerJob::cancel() +{ + this->setStatus(STATUS_CANCELED); +} + +void PackerJob::closeTab() +{ + if (Utils::msgBox(TranslateT("Do you really want to cancel this upload?"), MB_YESNO | MB_ICONQUESTION) == IDYES) + { + this->cancel(); + delete this->tab; + } +} + +void PackerJob::closeAllTabs() +{ + this->cancel(); + delete this->tab; +} + +void PackerJob::createToolTip() +{ + TCHAR *server = mir_a2t(this->ftp->szServer); + mir_sntprintf(uDlg->stzToolTipText, SIZEOF(uDlg->stzToolTipText), + TranslateT("Status: %s\r\nFile: %s\r\nServer: %s"), + this->getStatusString(), + this->stzFileName, + server); + + FREE(server); +} \ No newline at end of file diff --git a/plugins/FTPFileYM/job_packer.h b/plugins/FTPFileYM/job_packer.h new file mode 100644 index 0000000000..5d6857f24b --- /dev/null +++ b/plugins/FTPFileYM/job_packer.h @@ -0,0 +1,63 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "common.h" +#include "job_generic.h" +#include "zip/zip.h" + +class PackerJob: public GenericJob +{ +private: + static const int MAX_RUNNING_JOBS = 1; + + UINT64 uiFileSize; + UINT64 uiReaded; + time_t startTS; + time_t lastUpdateTick; + + static Event jobDone; + static Mutex mutexJobCount; + static int iRunningJobCount; + + static void waitingThread(void *arg); + static uLong getFileTime(TCHAR *file, tm_zip *tmzip, uLong *dt); + + void pack(); + void getZipFilePath(); + int createZipFile(); + void updateStats(); + bool isCanceled(); + +public: + PackerJob(HANDLE hContact, int iFtpNum, EMode mode); + virtual ~PackerJob() {}; + + virtual void start(); + virtual void pause(); + virtual void resume(); + virtual void cancel(); + virtual void addToUploadDlg(); + virtual void pauseHandler(); + + virtual void refreshTab(bool bTabChanged); + virtual void closeTab(); + virtual void closeAllTabs(); + virtual void createToolTip(); +}; \ No newline at end of file diff --git a/plugins/FTPFileYM/job_upload.cpp b/plugins/FTPFileYM/job_upload.cpp new file mode 100644 index 0000000000..36b4e628b5 --- /dev/null +++ b/plugins/FTPFileYM/job_upload.cpp @@ -0,0 +1,551 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "job_upload.h" +#include "dbentry.h" +#include "job_packer.h" + +Event UploadJob::jobDone; +Mutex UploadJob::mutexJobCount; +int UploadJob::iRunningJobCount = 0; + +extern UploadDialog *uDlg; +extern ServerList &ftpList; +extern LibCurl &curl; + +UploadJob::UploadJob(HANDLE _hContact, int _iFtpNum, EMode _mode) +:GenericJob(_hContact, _iFtpNum, _mode),fp(NULL) +{ + this->szFileLink[0] = 0; +} + +UploadJob::UploadJob(UploadJob *job) +:GenericJob(job),fp(NULL),uiSent(0),uiTotalSent(0),uiFileSize(0) +{ + strcpy(this->szFileLink, job->szFileLink); + for (int i = 0; i < SIZEOF(this->lastSpeed); i++) + this->lastSpeed[i] = 0; +} + +UploadJob::UploadJob(PackerJob *job) +:GenericJob(job),fp(NULL),uiSent(0),uiTotalSent(0),uiFileSize(0) +{ + for (int i = 0; i < SIZEOF(this->lastSpeed); i++) + this->lastSpeed[i] = 0; + + Utils::makeSafeString(job->stzFileName, this->szSafeFileName); + this->status = STATUS_CREATED; +} + +UploadJob::~UploadJob() +{ + if (this->fp) + fclose(this->fp); + + if (this->mode != FTP_RAWFILE) + DeleteFile(this->stzFilePath); +} + +void UploadJob::addToUploadDlg() +{ + for (UINT i = 0; i < this->files.size(); i++) + { + UploadJob *jobCopy = new UploadJob(this); + _tcscpy(jobCopy->stzFilePath, this->files[i]); + _tcscpy(jobCopy->stzFileName, Utils::getFileNameFromPath(jobCopy->stzFilePath)); + Utils::makeSafeString(jobCopy->stzFileName, jobCopy->szSafeFileName); + + UploadDialog::Tab *newTab = new UploadDialog::Tab(jobCopy); + jobCopy->tab = newTab; + jobCopy->start(); + } + + delete this; +} + +void UploadJob::autoSend() +{ + if (this->hContact != NULL) + { + char *szProto = DB::getProto(this->hContact); + if (szProto) + { + DBEVENTINFO dbei = {0}; + dbei.cbSize = sizeof(dbei); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.flags = DBEF_SENT; + dbei.szModule = szProto; + dbei.timestamp = (DWORD)time(NULL); + dbei.cbBlob = (DWORD)strlen(this->szFileLink) + 1; + dbei.pBlob = (PBYTE)this->szFileLink; + CallService(MS_DB_EVENT_ADD, (WPARAM)this->hContact, (LPARAM)&dbei); + CallContactService(this->hContact, PSS_MESSAGE, 0, (LPARAM)this->szFileLink); + CallServiceSync(MS_MSG_SENDMESSAGE, (WPARAM)this->hContact, 0); + } + } +} + +void UploadJob::copyLinkToML() +{ + if (this->hContact != NULL) + { + char buff[256]; + mir_snprintf(buff, sizeof(buff), "%s\r\n", this->szFileLink); + CallServiceSync(MS_MSG_SENDMESSAGE, (WPARAM)this->hContact, (LPARAM)buff); + } +} + +void UploadJob::pause() +{ + if (!isCompleted()) + { + curl.easy_pause(this->hCurl, CURLPAUSE_SEND); + this->setStatus(STATUS_PAUSED); + } +} + +void UploadJob::pauseHandler() +{ + if (this->isPaused()) + { + this->resume(); + SendDlgItemMessage(uDlg->hwnd, IDC_BTN_PAUSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("pause")); + SendDlgItemMessage(uDlg->hwnd, IDC_BTN_PAUSE, BUTTONADDTOOLTIP, (WPARAM)Translate("Pause"), 0); + } + else + { + this->pause(); + SendDlgItemMessage(uDlg->hwnd, IDC_BTN_PAUSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("resume")); + SendDlgItemMessage(uDlg->hwnd, IDC_BTN_PAUSE, BUTTONADDTOOLTIP, (WPARAM)Translate("Resume"), 0); + } +} + +void UploadJob::resume() +{ + this->uiSent = 0; + this->startTS = time(NULL); + if (!isCompleted()) + { + curl.easy_pause(this->hCurl, CURLPAUSE_CONT); + this->setStatus(STATUS_UPLOADING); + } +} + +void UploadJob::cancel() +{ + this->setStatus(STATUS_CANCELED); + curl.easy_pause(this->hCurl, CURLPAUSE_CONT); +} + +void UploadJob::waitingThread(void *arg) +{ + UploadJob *job = (UploadJob *)arg; + + while (!Miranda_Terminated()) + { + Lock *lock = new Lock(mutexJobCount); + if (iRunningJobCount < MAX_RUNNING_JOBS) + { + iRunningJobCount++; + delete lock; + job->upload(); + + if (!job->isCompleted()) + delete job; + + Lock *lock = new Lock(mutexJobCount); + iRunningJobCount--; + delete lock; + + jobDone.release(); + return; + } + + delete lock; + jobDone.wait(); + job->status = GenericJob::STATUS_WAITING; + } + + delete job; +} + +void UploadJob::start() +{ + mir_forkthread(&UploadJob::waitingThread, this); +} + +char *UploadJob::getChmodString() +{ + if (ftp->ftpProto == ServerList::FTP::FT_SSH) + mir_snprintf(buff, sizeof(buff), "%s \"%s/%s\"", ftp->szChmod, ftp->szDir, this->szSafeFileName); + else + mir_snprintf(buff, sizeof(buff), "%s %s", ftp->szChmod, this->szSafeFileName); + + return buff; +} + +char *UploadJob::getDelFileString() +{ + if (ftp->ftpProto == ServerList::FTP::FT_SSH) + mir_snprintf(buff, sizeof(buff), "rm \"%s/%s\"", ftp->szDir, this->szSafeFileName); + else + mir_snprintf(buff, sizeof(buff), "DELE %s", this->szSafeFileName); + + return buff; +} + +char *UploadJob::getUrlString() +{ + if (ftp->szDir[0]) + mir_snprintf(buff, sizeof(buff), "%s%s/%s/%s", ftp->getProtoString(), ftp->szServer, ftp->szDir, this->szSafeFileName); + else + mir_snprintf(buff, sizeof(buff), "%s%s/%s", ftp->getProtoString(), ftp->szServer, this->szSafeFileName); + + return buff; +} + +char *UploadJob::getDelUrlString() +{ + if (ftp->szDir[0] && ftp->ftpProto != ServerList::FTP::FT_SSH) + mir_snprintf(buff, sizeof(buff), "%s%s/%s/", ftp->getProtoString(), ftp->szServer, ftp->szDir); + else + mir_snprintf(buff, sizeof(buff), "%s%s/", ftp->getProtoString(), ftp->szServer); + + return buff; +} + +CURL *UploadJob::curlInit(char *szUrl, struct curl_slist *headerList) +{ + this->hCurl = curl.easy_init(); + if (!hCurl) return NULL; + + Utils::curlSetOpt(this->hCurl, this->ftp, szUrl, headerList, this->szError); + + curl.easy_setopt(this->hCurl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)this->uiFileSize); + curl.easy_setopt(this->hCurl, CURLOPT_READDATA, this); + curl.easy_setopt(this->hCurl, CURLOPT_READFUNCTION, &UploadJob::ReadCallback); + //curl.easy_setopt(this->hCurl, CURLOPT_UPLOAD, 1L); + + return this->hCurl; +} + +bool UploadJob::fileExistsOnServer() +{ + int result = curl.easy_perform(hCurl); + return result != CURLE_REMOTE_FILE_NOT_FOUND; +} + +INT_PTR CALLBACK UploadJob::DlgProcFileExists(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + + TCHAR buff[256]; + TCHAR *fileName = mir_a2t((char *)lParam); + mir_sntprintf(buff, SIZEOF(buff), TranslateT("File exists - %s"), fileName); + SetWindowText(hwndDlg, buff); + FREE(fileName); + return TRUE; + } + case WM_COMMAND: + { + if (HIWORD(wParam) == BN_CLICKED) + EndDialog(hwndDlg, LOWORD(wParam)); + break; + } + } + + return FALSE; +} + +void UploadJob::upload() +{ + this->refreshTab(true); + + this->fp = _tfopen(this->stzFilePath, _T("rb")); + if (this->fp == NULL) + { + Utils::msgBox(TranslateT("Error occurred when opening local file.\nAborting file upload..."), MB_OK | MB_ICONERROR); + return; + } + + struct curl_slist *headerList = NULL; + if (this->ftp->szChmod[0]) + headerList = curl.slist_append(headerList, getChmodString()); + + struct _stat fileInfo; + _tstat(this->stzFilePath, &fileInfo); + this->uiFileSize = (UINT64)fileInfo.st_size; + + CURL *hCurl = this->curlInit(getUrlString(), headerList); + if (!hCurl) + { + Utils::msgBox(TranslateT("Error occurred when initializing libcurl.\nAborting file upload..."), MB_OK | MB_ICONERROR); + return; + } + + bool uploadFile = true; + if (fileExistsOnServer()) + { + int res = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_DLG_FILEEXISTS), 0, DlgProcFileExists, (LPARAM)this->szSafeFileName); + if (res == IDC_RENAME) + { + if (Utils::setFileNameDlgA(this->szSafeFileName) == true) + curl.easy_setopt(hCurl, CURLOPT_URL, getUrlString()); + } + else if (res == IDC_COPYURL) + { + uploadFile = false; + } + else if (res == IDC_CANCEL) + { + this->setStatus(STATUS_CANCELED); + delete this->tab; + return; + } + } + + if (uploadFile) + { + curl.easy_setopt(this->hCurl, CURLOPT_UPLOAD, 1L); + this->setStatus(STATUS_CONNECTING); + this->startTS = time(NULL); + + int result = curl.easy_perform(hCurl); + curl.slist_free_all(headerList); + curl.easy_cleanup(hCurl); + + if (result != CURLE_OK && result != CURLE_ABORTED_BY_CALLBACK) + { + char buff[256]; + mir_snprintf(buff, sizeof(buff), Translate("FTP error occurred.\n%s"), this->szError); + Utils::msgBoxA(buff, MB_OK | MB_ICONERROR); + } + + if (result > CURLE_OPERATION_TIMEDOUT) + { + struct curl_slist *headerList = NULL; + headerList = curl.slist_append(headerList, getDelFileString()); + + CURL *hCurl = curl.easy_init(); + if (hCurl) + { + Utils::curlSetOpt(hCurl, this->ftp, getDelUrlString(), headerList, this->szError); + curl.easy_perform(hCurl); + curl.slist_free_all(headerList); + curl.easy_cleanup(hCurl); + } + } + + if (result != CURLE_OK && result != CURLE_QUOTE_ERROR) + { + if (!this->isCanceled()) + { + this->setStatus(STATUS_CANCELED); + delete this->tab; + } + return; + } + + DBEntry::add(this); + SkinPlaySound(SOUND_UPCOMPLETE); + } + + this->setStatus(STATUS_COMPLETED); + + Utils::createFileDownloadLink(this->ftp->szUrl, this->szSafeFileName, this->szFileLink, sizeof(this->szFileLink)); + Utils::copyToClipboard(this->szFileLink); + + if (this->tab->bOptAutosend) + this->autoSend(); + else if (this->tab->bOptCopyLink) + this->copyLinkToML(); + + if (!this->tab->bOptCloseDlg) + { + this->tab->labelCompleted(); + this->tab->select(); + } + else + this->closeTab(); +} + +size_t UploadJob::ReadCallback(void *ptr, size_t size, size_t nmemb, void *arg) +{ + UploadJob *job = (UploadJob *)arg; + + if (job->uiTotalSent == 0) + job->status = UploadJob::STATUS_UPLOADING; + + if (job->isCanceled()) + return CURL_READFUNC_ABORT; + + size_t readed = fread(ptr, size, nmemb, job->fp); + job->uiSent += readed; + job->uiTotalSent += readed; + job->updateStats(); + + return readed; +} + +void UploadJob::updateStats() +{ + if (this->uiSent && (time(NULL) > this->startTS)) + { + double speed = ((double)this->uiSent / 1024)/(time(NULL) - this->startTS); + this->avgSpeed = speed; + for (int i = 0; i < SIZEOF(this->lastSpeed); i++) + { + this->avgSpeed += (this->lastSpeed[i] == 0 ? speed : this->lastSpeed[i]); + if (i < SIZEOF(this->lastSpeed) - 1) + this->lastSpeed[i + 1] = this->lastSpeed[i]; + } + + this->avgSpeed /= SIZEOF(this->lastSpeed) + 1; + this->lastSpeed[0] = speed; + + mir_sntprintf(this->tab->stzSpeed, SIZEOF(this->tab->stzSpeed), _T("%0.1f kB/s"), this->avgSpeed); + + double perc = this->uiFileSize ? ((double)this->uiTotalSent / this->uiFileSize) * 100 : 0; + mir_sntprintf(this->tab->stzComplet, SIZEOF(this->tab->stzComplet), _T("%0.1f%% (%d kB/%d kB)"), perc, (int)this->uiTotalSent/1024, (int)this->uiFileSize/1024); + + long s = (this->uiFileSize - this->uiTotalSent) / (long)(this->avgSpeed * 1024); + int d = (s / 60 / 60 / 24); + int h = (s - d * 60 * 60 * 24) / 60 / 60; + int m = (s - d * 60 * 60 * 24 - h * 60 * 60) / 60; + s = s - (d * 24 * 60 * 60) - (h * 60 * 60) - (m * 60); + + TCHAR buff[256]; + if (d > 0) mir_sntprintf(buff, SIZEOF(buff), _T("%dd %02d:%02d:%02d"), d, h, m, s); + else mir_sntprintf(buff, SIZEOF(buff), _T("%02d:%02d:%02d"), h, m, s); + mir_sntprintf(this->tab->stzRemain, SIZEOF(this->tab->stzRemain), _T("%s (%d kB/%d kB)"), buff, (this->uiFileSize - this->uiTotalSent)/1024, this->uiFileSize/1024); + + this->refreshTab(false); + } +} + +void UploadJob::refreshTab(bool bTabChanged) +{ + if (uDlg->activeTab == this->tab->index()) + { + GenericJob::refreshTab(bTabChanged); + + ShowWindow(GetDlgItem(uDlg->hwnd, IDC_BTN_CLIPBOARD), this->isCompleted() ? SW_SHOW : SW_HIDE); + ShowWindow(GetDlgItem(uDlg->hwnd, IDC_BTN_DOWNLOAD), this->isCompleted() ? SW_SHOW : SW_HIDE); + EnableWindow(GetDlgItem(uDlg->hwnd, IDC_BTN_PAUSE), !this->isCompleted() && !this->isConnecting()); + + if (this->isCompleted()) + SetDlgItemText(uDlg->hwnd, IDC_STATUSBAR, TranslateT("COMPLETED")); + else if (this->isConnecting()) + SetDlgItemText(uDlg->hwnd, IDC_STATUSBAR, TranslateT("CONNECTING...")); + else if (this->isPaused()) + SetDlgItemText(uDlg->hwnd, IDC_STATUSBAR, TranslateT("PAUSED")); + else if (this->isWaitting()) + SetDlgItemText(uDlg->hwnd, IDC_STATUSBAR, TranslateT("WAITTING...")); + else + SetDlgItemText(uDlg->hwnd, IDC_STATUSBAR, TranslateT("UPLOADING...")); + + if (bTabChanged) + { + if (this->isPaused()) + { + SendDlgItemMessage(uDlg->hwnd, IDC_BTN_PAUSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("resume")); + SendDlgItemMessage(uDlg->hwnd, IDC_BTN_PAUSE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Resume"), BATF_TCHAR); + } + else + { + SendDlgItemMessage(uDlg->hwnd, IDC_BTN_PAUSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("pause")); + SendDlgItemMessage(uDlg->hwnd, IDC_BTN_PAUSE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Pause"), BATF_TCHAR); + } + + ShowWindow(GetDlgItem(uDlg->hwnd, IDC_ST_REMAIN), !this->isCompleted() ? SW_SHOW : SW_HIDE); + ShowWindow(GetDlgItem(uDlg->hwnd, IDC_UP_COMPLETED), !this->isCompleted() ? SW_SHOW : SW_HIDE); + ShowWindow(GetDlgItem(uDlg->hwnd, IDC_UP_REMAIN), !this->isCompleted() ? SW_SHOW : SW_HIDE); + ShowWindow(GetDlgItem(uDlg->hwnd, IDC_ED_URL), this->isCompleted() ? SW_SHOW : SW_HIDE); + SetDlgItemText(uDlg->hwnd, IDC_ST_COMPLETED, this->isCompleted() ? TranslateT("Download link:") : TranslateT("Completed:")); + } + + if (this->isCompleted()) + { + SetDlgItemText(uDlg->hwnd, IDC_UP_SPEED, _T("")); + SetDlgItemText(uDlg->hwnd, IDC_UP_COMPLETED, _T("")); + SetDlgItemText(uDlg->hwnd, IDC_UP_REMAIN, _T("")); + + SetDlgItemTextA(uDlg->hwnd, IDC_ED_URL, this->szFileLink); + SendDlgItemMessage(uDlg->hwnd, IDC_PB_UPLOAD, PBM_SETRANGE32, 0, (LPARAM)100); + SendDlgItemMessage(uDlg->hwnd, IDC_PB_UPLOAD, PBM_SETPOS, (WPARAM)100, 0); + } + else + { + SetDlgItemText(uDlg->hwnd, IDC_UP_SPEED, this->tab->stzSpeed); + SetDlgItemText(uDlg->hwnd, IDC_UP_COMPLETED, this->tab->stzComplet); + SetDlgItemText(uDlg->hwnd, IDC_UP_REMAIN, this->tab->stzRemain); + + SendDlgItemMessage(uDlg->hwnd, IDC_PB_UPLOAD, PBM_SETRANGE32, 0, (LPARAM)this->uiFileSize); + SendDlgItemMessage(uDlg->hwnd, IDC_PB_UPLOAD, PBM_SETPOS, (WPARAM)this->uiTotalSent, 0); + } + } +} + +void UploadJob::closeTab() +{ + if (!this->isCompleted()) + { + this->pause(); + if (Utils::msgBox(TranslateT("Do you really want to cancel running upload?"), MB_YESNO | MB_ICONQUESTION) == IDNO) + { + this->resume(); + return; + } + + this->cancel(); + } + + delete this->tab; +} + +void UploadJob::closeAllTabs() +{ + if (!this->isCompleted()) + this->cancel(); + + delete this->tab; +} + +void UploadJob::createToolTip() +{ + TCHAR *server = mir_a2t(this->ftp->szServer); + mir_sntprintf(uDlg->stzToolTipText, SIZEOF(uDlg->stzToolTipText), + TranslateT("Status: %s\r\nFile: %s\r\nServer: %s"), + this->getStatusString(), + this->stzFileName, + server); + + if (this->tab->stzSpeed[0] && this->tab->stzComplet[0] && this->tab->stzRemain[0]) + mir_sntprintf(uDlg->stzToolTipText, SIZEOF(uDlg->stzToolTipText), + TranslateT("%s\r\nSpeed: %s\r\nCompleted: %s\r\nRemaining: %s"), + uDlg->stzToolTipText, + this->tab->stzSpeed, + this->tab->stzComplet, + this->tab->stzRemain); + + FREE(server); +} \ No newline at end of file diff --git a/plugins/FTPFileYM/job_upload.h b/plugins/FTPFileYM/job_upload.h new file mode 100644 index 0000000000..fa29e3c640 --- /dev/null +++ b/plugins/FTPFileYM/job_upload.h @@ -0,0 +1,84 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "common.h" +#include "job_generic.h" +#include "utils.h" + +class UploadJob: public GenericJob +{ + friend class UploadDialog; + +private: + static const int MAX_RUNNING_JOBS = 4; + + FILE *fp; + CURL *hCurl; + char szError[CURL_ERROR_SIZE]; + char buff[256]; + + UINT64 uiFileSize; + UINT64 uiTotalSent; + UINT64 uiSent; + time_t startTS; + double lastSpeed[10]; + double avgSpeed; + + static Mutex mutexJobCount; + static int iRunningJobCount; + + char *getChmodString(); + char *getDelFileString(); + char *getUrlString(); + char *getDelUrlString(); + void copyLinkToML(); + void autoSend(); + + CURL *curlInit(char *szUrl, struct curl_slist *headerList); + + static void waitingThread(void *arg); + static size_t ReadCallback(void *ptr, size_t size, size_t nmemb, void *arg); + static INT_PTR CALLBACK DlgProcFileExists(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + + bool fileExistsOnServer(); + void upload(); + void updateStats(); + +public: + char szFileLink[256]; + static Event jobDone; + + UploadJob(HANDLE _hContact, int _iFtpNum, EMode _mode); + UploadJob(UploadJob *job); + UploadJob(PackerJob *job); + virtual ~UploadJob(); + + virtual void start(); + virtual void pause(); + virtual void resume(); + virtual void cancel(); + virtual void addToUploadDlg(); + virtual void pauseHandler(); + + virtual void refreshTab(bool bTabChanged); + virtual void closeTab(); + virtual void closeAllTabs(); + virtual void createToolTip(); +}; \ No newline at end of file diff --git a/plugins/FTPFileYM/lib/libcurl.dll b/plugins/FTPFileYM/lib/libcurl.dll new file mode 100644 index 0000000000..0980b9a3e4 Binary files /dev/null and b/plugins/FTPFileYM/lib/libcurl.dll differ diff --git a/plugins/FTPFileYM/lib/libcurl64.dll b/plugins/FTPFileYM/lib/libcurl64.dll new file mode 100644 index 0000000000..4efba6f35f Binary files /dev/null and b/plugins/FTPFileYM/lib/libcurl64.dll differ diff --git a/plugins/FTPFileYM/libcurl.cpp b/plugins/FTPFileYM/libcurl.cpp new file mode 100644 index 0000000000..59f95b6de6 --- /dev/null +++ b/plugins/FTPFileYM/libcurl.cpp @@ -0,0 +1,73 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "libcurl.h" + +LibCurl *LibCurl::instance = NULL; +LibCurl &curl = LibCurl::getInstance(); + +BOOL LibCurl::init() +{ + HMODULE h = LoadLibrary(_T("libcurl.dll")); + if (h == NULL) + { + h = LoadLibrary(_T("plugins\\libcurl.dll")); + if (h == NULL) return FALSE; + } + + version_info = (_curl_version_info)GetProcAddress(h, "curl_version_info"); + if (version_info == NULL) + return FALSE; + + PVERSION_INFO info = version_info(CURLVERSION_NOW); + if (info == NULL) + return FALSE; + + if (info->version_num < PLUGIN_MAKE_VERSION(0, 7, 10, 0)) + return FALSE; + + if ((info->features & CURL_VERSION_SSL) == 0) + return FALSE; + + bool found = false; + for (int i = 0; info->protocols[i]; i++) + { + if (strcmp(info->protocols[i], "ftp") == 0) + found = true; + } + + if (!found) + return FALSE; + + global_init = (_curl_global_init) GetProcAddress(h, "curl_global_init"); + global_cleanup = (_curl_global_cleanup) GetProcAddress(h, "curl_global_cleanup"); + easy_init = (_curl_easy_init) GetProcAddress(h, "curl_easy_init"); + easy_cleanup = (_curl_easy_cleanup) GetProcAddress(h, "curl_easy_cleanup"); + easy_perform = (_curl_easy_perform) GetProcAddress(h, "curl_easy_perform"); + easy_pause = (_curl_easy_pause) GetProcAddress(h, "curl_easy_pause"); + easy_setopt = (_curl_easy_setopt) GetProcAddress(h, "curl_easy_setopt"); + slist_append = (_curl_slist_append) GetProcAddress(h, "curl_slist_append"); + slist_free_all = (_curl_slist_free_all) GetProcAddress(h, "curl_slist_free_all"); + + return TRUE; +} + +void LibCurl::deinit() +{ + delete this; +} \ No newline at end of file diff --git a/plugins/FTPFileYM/libcurl.h b/plugins/FTPFileYM/libcurl.h new file mode 100644 index 0000000000..4a8ba6b253 --- /dev/null +++ b/plugins/FTPFileYM/libcurl.h @@ -0,0 +1,69 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "common.h" + +class LibCurl +{ +private: + typedef CURL *PCURL; + typedef struct curl_slist *PCURL_SLIST; + typedef curl_version_info_data *PVERSION_INFO; + + typedef CURLcode (__cdecl * _curl_global_init) (long); + typedef void (__cdecl * _curl_global_cleanup) (void); + + typedef PCURL (__cdecl * _curl_easy_init) (void); + typedef void (__cdecl * _curl_easy_cleanup) (PCURL); + typedef CURLcode (__cdecl * _curl_easy_perform) (PCURL); + typedef CURLcode (__cdecl * _curl_easy_pause) (PCURL,int); + typedef CURLcode (__cdecl * _curl_easy_setopt) (PCURL,CURLoption,...); + + typedef PCURL_SLIST (__cdecl * _curl_slist_append) (PCURL_SLIST,LPCSTR); + typedef void (__cdecl * _curl_slist_free_all) (PCURL_SLIST); + + typedef PVERSION_INFO (__cdecl * _curl_version_info) (CURLversion); + + static LibCurl *instance; + LibCurl() { }; + ~LibCurl() { instance = NULL; }; + +public: + _curl_global_init global_init; + _curl_global_cleanup global_cleanup; + _curl_easy_init easy_init; + _curl_easy_cleanup easy_cleanup; + _curl_easy_perform easy_perform; + _curl_easy_pause easy_pause; + _curl_easy_setopt easy_setopt; + _curl_slist_append slist_append; + _curl_slist_free_all slist_free_all; + _curl_version_info version_info; + + static LibCurl &getInstance() + { + if (!instance) + instance = new LibCurl(); + return *instance; + }; + + BOOL init(); + void deinit(); +}; \ No newline at end of file diff --git a/plugins/FTPFileYM/manager.cpp b/plugins/FTPFileYM/manager.cpp new file mode 100644 index 0000000000..abf1ec3f0a --- /dev/null +++ b/plugins/FTPFileYM/manager.cpp @@ -0,0 +1,449 @@ +/* +FTP File plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "common.h" +#include "job_delete.h" +#include "manager.h" +#include "dbentry.h" +#include "options.h" +#include "utils.h" + +Manager *manDlg = NULL; +Manager *Manager::instance = NULL; + +extern Options &opt; +extern ServerList &ftpList; + +Manager::Manager() +{ } + +Manager::~Manager() +{ + for (UINT i = 0; i < this->rootItems.size(); i++) + delete this->rootItems[i]; + + for (UINT i = 0; i < this->items.size(); i++) + delete this->items[i]; + + ImageList_Destroy(this->himlStates); + DBEntry::cleanupDB(); + + instance = NULL; + manDlg = NULL; +} + +void Manager::init() +{ + if (opt.enabled != 0) + { + this->hwnd = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DLG_MANAGER), NULL, Manager::ManagerDlgProc); + this->hwndFileTree = GetDlgItem(this->hwnd, IDC_FILELIST); + this->initImageList(); + this->fillTree(); + this->show(); + } + else + { + Utils::msgBox(TranslateT("You have to fill and enable at least one FTP server in setting."), MB_OK); + delete this; + } +} + +void Manager::show() +{ + ShowWindow(this->hwnd, SW_SHOWNORMAL); + BringWindowToTop(this->hwnd); +} + +void Manager::initImageList() +{ + char buff[256]; + + this->himlStates = ImageList_Create(16, 16, IsWinVerXPPlus() ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, ServerList::FTP_COUNT + 4, 0); + ImageList_AddIcon(himlStates, LoadSkinnedIcon(SKINICON_OTHER_DELETE)); // image index 0 is useless for INDEXTOSTATEIMAGEMASK + ImageList_AddIcon(himlStates, LoadSkinnedIcon(SKINICON_OTHER_DELETE)); + ImageList_AddIcon(himlStates, LoadSkinnedIcon(SKINICON_OTHER_NOTICK)); + ImageList_AddIcon(himlStates, LoadSkinnedIcon(SKINICON_OTHER_TICK)); + + for (int i = 0; i < ServerList::FTP_COUNT; i++) + { + mir_snprintf(buff, sizeof(buff), "ftp%d", i); + ImageList_AddIcon(himlStates, Utils::loadIconEx(buff)); + } + + TreeView_SetImageList(this->hwndFileTree, himlStates, TVSIL_STATE); + TreeView_SetItemHeight(this->hwndFileTree, 18); +} + +void Manager::initRootItems() +{ + TVINSERTSTRUCT tvi = {0}; + tvi.hInsertAfter = TVI_LAST; + tvi.item.mask = TVIF_TEXT | TVIF_STATE; + tvi.item.stateMask = TVIS_STATEIMAGEMASK | TVIS_EXPANDED | TVIS_BOLD; + + for (UINT i = 0; i < ServerList::FTP_COUNT; i++) + { + if (ftpList[i]->bEnabled) + { + tvi.item.pszText = ftpList[i]->stzName; + tvi.item.state = INDEXTOSTATEIMAGEMASK(i + 4) | TVIS_EXPANDED | TVIS_BOLD; + HTREEITEM hItem = TreeView_InsertItem(this->hwndFileTree, &tvi); + this->AddRoot(hItem); + } + } +} + +void Manager::fillTree() +{ + initRootItems(); + + TVINSERTSTRUCT tvi = {0}; + tvi.hInsertAfter = TVI_LAST; + tvi.item.mask = TVIF_TEXT | TVIF_STATE; + tvi.item.stateMask = TVIS_STATEIMAGEMASK; + tvi.item.state = TreeItem::_UNCHECKED(); + + Lock *lock = new Lock(DBEntry::mutexDB); + + DBEntry *entry = DBEntry::getFirts(); + while (entry != NULL) + { + if ((UINT)entry->iFtpNum < this->rootItems.size()) + { + tvi.item.pszText = mir_a2t(entry->szFileName); + tvi.hParent = this->rootItems[entry->iFtpNum]->handle; + HTREEITEM hItem = TreeView_InsertItem(this->hwndFileTree, &tvi); + this->AddLeaf(hItem, tvi.hParent, entry->fileID); + FREE(tvi.item.pszText); + } + + entry = DBEntry::getNext(entry); + } + + delete lock; +} + +int Manager::indexOf(HTREEITEM handle) +{ + for (UINT i = 0; i < this->rootItems.size(); i++) + { + if (this->rootItems[i]->handle == handle) + return i; + } + + return -1; +} + +Manager::TreeItem *Manager::getItem(HTREEITEM handle) +{ + for (UINT i = 0; i < this->rootItems.size(); i++) + { + if (this->rootItems[i]->handle == handle) + return this->rootItems[i]; + } + + for (UINT i = 0; i < this->items.size(); i++) + { + if (this->items[i]->handle == handle) + return this->items[i]; + } + + return NULL; +} + +Manager::TreeItem::TreeItem(HTREEITEM _handle, HTREEITEM _parent, int _id) +:handle(_handle),parent(_parent),fileID(_id) +{ + stzToolTip[0] = 0; +} + +void Manager::TreeItem::setState(UINT state) +{ + TVITEM item = {0}; + item.mask = TVIF_HANDLE | TVIF_STATE; + item.stateMask = TVIS_STATEIMAGEMASK; + item.hItem = this->handle; + TreeView_GetItem(manDlg->hwndFileTree, &item); + + if (TreeItem::_GETSTATE(item.state) != 0) + { + item.state = state; + TreeView_SetItem(manDlg->hwndFileTree, &item); + } +} + +UINT Manager::TreeItem::getState() +{ + TVITEM item = {0}; + item.mask = TVIF_HANDLE | TVIF_STATE; + item.stateMask = TVIS_STATEIMAGEMASK; + item.hItem = this->handle; + TreeView_GetItem(manDlg->hwndFileTree, &item); + return TreeItem::_GETSTATE(item.state); +} + +void Manager::TreeItem::toggleState() +{ + TVITEM item = {0}; + item.mask = TVIF_HANDLE | TVIF_STATE; + item.stateMask = TVIS_STATEIMAGEMASK; + item.hItem = this->handle; + TreeView_GetItem(manDlg->hwndFileTree, &item); + + UINT state = TreeItem::_GETSTATE(item.state); + if (state == STATE_UNCHECKED) + item.state = TreeItem::_CHECKED(); + else if (state == STATE_CHECKED || state == STATE_ERROR) + item.state = TreeItem::_UNCHECKED(); + + TreeView_SetItem(manDlg->hwndFileTree, &item); +} + +void Manager::TreeItem::remove() +{ + TreeView_DeleteItem(manDlg->hwndFileTree, this->handle); + DBEntry::remove(this->fileID); +} + +bool Manager::TreeItem::isRoot() +{ + return (this->parent != NULL) ? false : true; +} + + +INT_PTR CALLBACK Manager::ManagerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)Utils::loadIconEx("main")); + SendDlgItemMessage(hwndDlg, IDC_BTN_SELECTALL, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BTN_SELECTALL, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_TICK)); + SendDlgItemMessage(hwndDlg, IDC_BTN_SELECTALL, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Select All"), BATF_TCHAR); + SendDlgItemMessage(hwndDlg, IDC_BTN_DESELECTALL, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BTN_DESELECTALL, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_NOTICK)); + SendDlgItemMessage(hwndDlg, IDC_BTN_DESELECTALL, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Clear All"), BATF_TCHAR); + SendDlgItemMessage(hwndDlg, IDC_BTN_DELETEFROMLIST, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BTN_DELETEFROMLIST, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("clear")); + SendDlgItemMessage(hwndDlg, IDC_BTN_DELETEFROMLIST, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Delete from List"), BATF_TCHAR); + SendDlgItemMessage(hwndDlg, IDC_BTN_DELETE, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BTN_DELETE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)Utils::loadIconEx("delete")); + SendDlgItemMessage(hwndDlg, IDC_BTN_DELETE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Delete from FTP"), BATF_TCHAR); + SendDlgItemMessage(hwndDlg, IDC_BTN_CLOSE, BUTTONSETASFLATBTN, 0, 0); + SendDlgItemMessage(hwndDlg, IDC_BTN_CLOSE, BM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadSkinnedIcon(SKINICON_OTHER_EXIT)); + SendDlgItemMessage(hwndDlg, IDC_BTN_CLOSE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Close"), BATF_TCHAR); + + return TRUE; + } + case WM_COMMAND: + { + if (HIWORD(wParam) == BN_CLICKED) + { + switch (LOWORD(wParam)) + { + case IDC_BTN_DELETE: + { + for (UINT i = 0; i < manDlg->items.size(); i++) + { + TreeItem *item = manDlg->items[i]; + if (item->getState() == STATE_CHECKED) + { + DeleteJob *job = new DeleteJob(DBEntry::get(item->fileID), item); + job->start(); + } + } + break; + } + case IDC_BTN_DELETEFROMLIST: + { + for (UINT i = 0; i < manDlg->items.size(); i++) + { + TreeItem *item = manDlg->items[i]; + if (item->getState() == STATE_CHECKED) + item->remove(); + } + break; + } + case IDC_BTN_SELECTALL: + case IDC_BTN_DESELECTALL: + { + UINT newState = (LOWORD(wParam) == IDC_BTN_SELECTALL) ? + TreeItem::_CHECKED() : TreeItem::_UNCHECKED(); + + for (UINT i = 0; i < manDlg->items.size(); i++) + manDlg->items[i]->setState(newState); + + break; + } + case IDC_BTN_CLOSE: + { + DestroyWindow(hwndDlg); + break; + } + } + } + + break; + } + case WM_NOTIFY: + { + if (((LPNMHDR)lParam)->idFrom == IDC_FILELIST) + { + switch(((LPNMHDR)lParam)->code) + { + case TVN_KEYDOWN: + if (((LPNMTVKEYDOWN)lParam)->wVKey != VK_SPACE) + break; + case NM_CLICK: + { + HTREEITEM hItem; + TVHITTESTINFO hti = {0}; + hti.pt.x = (short)LOWORD(GetMessagePos()); + hti.pt.y = (short)HIWORD(GetMessagePos()); + ScreenToClient(((LPNMHDR)lParam)->hwndFrom, &hti.pt); + if (TreeView_HitTest(((LPNMHDR)lParam)->hwndFrom, &hti) || ((LPNMHDR)lParam)->code == TVN_KEYDOWN) + { + if (((LPNMHDR)lParam)->code == TVN_KEYDOWN) + { + hti.flags |= TVHT_ONITEMSTATEICON; + hItem = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom); + } + else + { + hItem = hti.hItem; + } + + TreeItem *item = manDlg->getItem(hItem); + if (item && (hti.flags & TVHT_ONITEMSTATEICON)) + { + if (item->isRoot()) + { + for (UINT i = 0; i < manDlg->items.size(); i++) + { + if (manDlg->items[i]->parent == item->handle) + manDlg->items[i]->toggleState(); + } + } + else + { + item->toggleState(); + } + } + } + return TRUE; + } + case NM_RCLICK: + { + TVHITTESTINFO hti; + hti.pt.x = (short)LOWORD(GetMessagePos()); + hti.pt.y = (short)HIWORD(GetMessagePos()); + ScreenToClient(manDlg->hwndFileTree, &hti.pt); + if (TreeView_HitTest(manDlg->hwndFileTree, &hti)) + { + HTREEITEM hItem = hti.hItem; + TreeItem *item = manDlg->getItem(hItem); + if (item && !item->isRoot()) + { + POINT pt; + GetCursorPos(&pt); + SetForegroundWindow(hwndDlg); + HMENU hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU_MANAGER)); + if (hMenu) + { + HMENU hPopupMenu = GetSubMenu(hMenu, 0); + CallService(MS_LANGPACK_TRANSLATEMENU, (WPARAM)hPopupMenu, 0); + int command = TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN | TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL); + switch (command) + { + + case IDM_DELETEFROMLIST: + { + item->remove(); + break; + } + case IDM_DELETEFROMFTP: + { + DeleteJob *job = new DeleteJob(DBEntry::get(item->fileID), item); + job->start(); + break; + } + case IDM_COPYLINK: + case IDM_DOWNLOAD: + { + int ftpNum = manDlg->indexOf(item->parent); + if (ftpNum != -1) + { + char buff[256]; + + DBEntry *entry = DBEntry::get(item->fileID); + Utils::createFileDownloadLink(ftpList[ftpNum]->szUrl, entry->szFileName, buff, sizeof(buff)); + delete entry; + + if (command == IDM_COPYLINK) + Utils::copyToClipboard(buff); + else + ShellExecuteA(NULL, "open", buff, NULL, NULL, SW_SHOWNORMAL); + } + break; + } + } + DestroyMenu(hMenu); + } + } + } + return TRUE; + } + case TVN_GETINFOTIP: + { + NMTVGETINFOTIP *tvInfoTip = (NMTVGETINFOTIP *)lParam; + TreeItem *item = manDlg->getItem(tvInfoTip->hItem); + + if (item) + { + if (item->stzToolTip[0]) + { + _tcsncpy(tvInfoTip->pszText, item->stzToolTip, tvInfoTip->cchTextMax - 1); + tvInfoTip->pszText[tvInfoTip->cchTextMax - 1] = 0; + } + } + + return TRUE; + } + } + } + + break; + } + case WM_CLOSE: + { + DestroyWindow(hwndDlg); + return TRUE; + } + case WM_DESTROY: + { + delete manDlg; + return TRUE; + } + } + + return FALSE; +} \ No newline at end of file diff --git a/plugins/FTPFileYM/manager.h b/plugins/FTPFileYM/manager.h new file mode 100644 index 0000000000..ef5ba0ddb3 --- /dev/null +++ b/plugins/FTPFileYM/manager.h @@ -0,0 +1,88 @@ +/* +FTP File plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "common.h" + +class Manager +{ +private: + enum EState + { + STATE_ERROR = 1, + STATE_UNCHECKED, + STATE_CHECKED + }; + + static Manager *instance; + + HWND hwnd; + HWND hwndFileTree; + HIMAGELIST himlStates; + + Manager(); + + void show(); + void initRootItems(); + void initImageList(); + void fillTree(); + +public: + class TreeItem + { + public: + HTREEITEM handle; + HTREEITEM parent; + TCHAR stzToolTip[256]; + int fileID; + + TreeItem(HTREEITEM _handle, HTREEITEM _parent, int _id); + void setState(UINT state); + UINT getState(); + void toggleState(); + void remove(); + bool isRoot(); + + static UINT _GETSTATE(UINT s) { return ((s & TVIS_STATEIMAGEMASK) >> 12); } + static UINT _ERROR() { return INDEXTOSTATEIMAGEMASK(STATE_ERROR); } + static UINT _UNCHECKED() { return INDEXTOSTATEIMAGEMASK(STATE_UNCHECKED); } + static UINT _CHECKED() { return INDEXTOSTATEIMAGEMASK(STATE_CHECKED); } + }; + + vector rootItems; + vector items; + + ~Manager(); + + void AddRoot(HTREEITEM h) { rootItems.push_back(new TreeItem(h,NULL,0)); } + void AddLeaf(HTREEITEM h, HTREEITEM p, int id) { items.push_back(new TreeItem(h,p,id)); } + + static Manager *getInstance() + { + if (!instance) + instance = new Manager(); + return instance; + }; + + void init(); + int indexOf(HTREEITEM handle); + TreeItem *getItem(HTREEITEM handle); + + static INT_PTR CALLBACK ManagerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +}; diff --git a/plugins/FTPFileYM/mir_db.cpp b/plugins/FTPFileYM/mir_db.cpp new file mode 100644 index 0000000000..1a466f7863 --- /dev/null +++ b/plugins/FTPFileYM/mir_db.cpp @@ -0,0 +1,198 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "mir_db.h" + +int DB::setByte(HANDLE hContact, char *szModule, char *szSetting, int iValue) +{ + return DBWriteContactSettingByte(hContact, szModule, szSetting, iValue); +} + +int DB::setByteF(HANDLE hContact, char *szModule, char *szSetting, int id, int iValue) +{ + char formSet[256]; + mir_snprintf(formSet, sizeof(formSet), szSetting, id); + return setByte(hContact, szModule, formSet, iValue); +} + +int DB::setWord(HANDLE hContact, char *szModule, char *szSetting, int iValue) +{ + return DBWriteContactSettingWord(hContact, szModule, szSetting, iValue); +} + +int DB::setWordF(HANDLE hContact, char *szModule, char *szSetting, int id, int iValue) +{ + char formSet[256]; + mir_snprintf(formSet, sizeof(formSet), szSetting, id); + return setWord(hContact, szModule, formSet, iValue); +} + +int DB::setDword(HANDLE hContact, char *szModule, char *szSetting, int iValue) +{ + return DBWriteContactSettingDword(hContact, szModule, szSetting, iValue); +} + +int DB::setDwordF(HANDLE hContact, char *szModule, char *szSetting, int id, int iValue) +{ + char formSet[256]; + mir_snprintf(formSet, sizeof(formSet), szSetting, id); + return setDword(hContact, szModule, formSet, iValue); +} + +int DB::setAString(HANDLE hContact, char *szModule, char *szSetting, char *szValue) +{ + return DBWriteContactSettingString(hContact, szModule, szSetting, szValue); +} + +int DB::setAStringF(HANDLE hContact, char *szModule, char *szSetting, int id, char *szValue) +{ + char formSet[256]; + mir_snprintf(formSet, sizeof(formSet), szSetting, id); + return setAString(hContact, szModule, formSet, szValue); +} + +int DB::setString(HANDLE hContact, char *szModule, char *szSetting, TCHAR *stzValue) +{ + return DBWriteContactSettingTString(hContact, szModule, szSetting, stzValue); +} + +int DB::setStringF(HANDLE hContact, char *szModule, char *szSetting, int id, TCHAR *stzValue) +{ + char formSet[256]; + mir_snprintf(formSet, sizeof(formSet), szSetting, id); + return setString(hContact, szModule, formSet, stzValue); +} + +int DB::setCryptedString(HANDLE hContact, char *szModule, char *szSetting, char *szValue) +{ + char buff[256]; + strcpy(buff, szValue); + CallService(MS_DB_CRYPT_ENCODESTRING, (WPARAM)sizeof(buff), (LPARAM)buff); + return setAString(hContact, szModule, szSetting, buff); +} + +int DB::getByte(HANDLE hContact, char *szModule, char *szSetting, int iErrorValue) +{ + return DBGetContactSettingByte(hContact, szModule, szSetting, iErrorValue); +} + +int DB::getByteF(HANDLE hContact, char *szModule, char *szSetting, int id, int iErrorValue) +{ + char formSet[256]; + mir_snprintf(formSet, sizeof(formSet), szSetting, id); + return getByte(hContact, szModule, formSet, iErrorValue); +} + +int DB::getWord(HANDLE hContact, char *szModule, char *szSetting, int iErrorValue) +{ + return DBGetContactSettingWord(hContact, szModule, szSetting, iErrorValue); +} + +int DB::getWordF(HANDLE hContact, char *szModule, char *szSetting, int id, int iErrorValue) +{ + char formSet[256]; + mir_snprintf(formSet, sizeof(formSet), szSetting, id); + return getWord(hContact, szModule, formSet, iErrorValue); +} + +int DB::getDword(HANDLE hContact, char *szModule, char *szSetting, int iErrorValue) +{ + return DBGetContactSettingDword(hContact, szModule, szSetting, iErrorValue); +} + +int DB::getDwordF(HANDLE hContact, char *szModule, char *szSetting, int id, int iErrorValue) +{ + char formSet[256]; + mir_snprintf(formSet, sizeof(formSet), szSetting, id); + return getDword(hContact, szModule, formSet, iErrorValue); +} + +int DB::getAString(HANDLE hContact, char *szModule, char *szSetting, char *buff) +{ + DBVARIANT dbv; + if (!DBGetContactSettingString(hContact, szModule, szSetting, &dbv)) + { + strcpy(buff, dbv.pszVal); + DBFreeVariant(&dbv); + return 0; + } + + buff[0] = 0; + return 1; +} + +int DB::getAStringF(HANDLE hContact, char *szModule, char *szSetting, int id, char *buff) +{ + char formSet[256]; + mir_snprintf(formSet, sizeof(formSet), szSetting, id); + return getAString(hContact, szModule, formSet, buff); +} + +int DB::getString(HANDLE hContact, char *szModule, char *szSetting, TCHAR *buff) +{ + DBVARIANT dbv; + if (!DBGetContactSettingTString(hContact, szModule, szSetting, &dbv)) + { + _tcscpy(buff, dbv.ptszVal); + DBFreeVariant(&dbv); + return 0; + } + + buff[0] = 0; + return 1; +} + +int DB::getStringF(HANDLE hContact, char *szModule, char *szSetting, int id, TCHAR *buff) +{ + char formSet[256]; + mir_snprintf(formSet, sizeof(formSet), szSetting, id); + return getString(hContact, szModule, formSet, buff); +} + +int DB::getCryptedString(HANDLE hContact, char *szModule, char *szSetting, char *szValue) +{ + char buff[256]; + if (!getAString(hContact, szModule, szSetting, buff)) + { + CallService(MS_DB_CRYPT_DECODESTRING, (WPARAM)sizeof(buff), (LPARAM)buff); + strcpy(szValue, buff); + return 0; + } + + szValue[0] = 0; + return 1; +} + +int DB::deleteSetting(HANDLE hContact, char *szModule, char *szSetting) +{ + return DBDeleteContactSetting(hContact, szModule, szSetting); +} + +int DB::deleteSettingF(HANDLE hContact, char *szModule, char *szSetting, int id) +{ + char formSet[256]; + mir_snprintf(formSet, sizeof(formSet), szSetting, id); + return deleteSetting(hContact, szModule, formSet); +} + +char *DB::getProto(HANDLE hContact) +{ + char *szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + return ((INT_PTR)szProto != CALLSERVICE_NOTFOUND) ? szProto : NULL; +} + diff --git a/plugins/FTPFileYM/mir_db.h b/plugins/FTPFileYM/mir_db.h new file mode 100644 index 0000000000..df2004c86d --- /dev/null +++ b/plugins/FTPFileYM/mir_db.h @@ -0,0 +1,57 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "common.h" + +class DB +{ +public: + static int setByte(HANDLE hContact, char *szModule, char *szSetting, int iValue); + static int setByteF(HANDLE hContact, char *szModule, char *szSetting, int id, int iValue); + static int setWord(HANDLE hContact, char *szModule, char *szSetting, int iValue); + static int setWordF(HANDLE hContact, char *szModule, char *szSetting, int id, int iValue); + static int setDword(HANDLE hContact, char *szModule, char *szSetting, int iValue); + static int setDwordF(HANDLE hContact, char *szModule, char *szSetting, int id, int iValue); + + static int setAString(HANDLE hContact, char *szModule, char *szSetting, char *szValue); + static int setAStringF(HANDLE hContact, char *szModule, char *szSetting, int id, char *szValue); + static int setString(HANDLE hContact, char *szModule, char *szSetting, TCHAR *stzValue); + static int setStringF(HANDLE hContact, char *szModule, char *szSetting, int id, TCHAR *stzValue); + + static int getByte(HANDLE hContact, char *szModule, char *szSetting, int iErrorValue); + static int getByteF(HANDLE hContact, char *szModule, char *szSetting, int id, int iErrorValue = -1); + static int getWord(HANDLE hContact, char *szModule, char *szSetting, int iErrorValue = -1); + static int getWordF(HANDLE hContact, char *szModule, char *szSetting, int id, int iErrorValue = -1); + static int getDword(HANDLE hContact, char *szModule, char *szSetting, int iErrorValue = -1); + static int getDwordF(HANDLE hContact, char *szModule, char *szSetting, int id, int iErrorValue = -1); + + static int getAString(HANDLE hContact, char *szModule, char *szSetting, char *buff); + static int getAStringF(HANDLE hContact, char *szModule, char *szSetting, int id, char *buff); + static int getString(HANDLE hContact, char *szModule, char *szSetting, TCHAR *buff); + static int getStringF(HANDLE hContact, char *szModule, char *szSetting, int id, TCHAR *buff); + + static int setCryptedString(HANDLE hContact, char *szModule, char *szSetting, char *szValue); + static int getCryptedString(HANDLE hContact, char *szModule, char *szSetting, char *szValue); + + static int deleteSetting(HANDLE hContact, char *szModule, char *szSetting); + static int deleteSettingF(HANDLE hContact, char *szModule, char *szSetting, int id); + + static char *getProto(HANDLE hContact); +}; \ No newline at end of file diff --git a/plugins/FTPFileYM/options.cpp b/plugins/FTPFileYM/options.cpp new file mode 100644 index 0000000000..65700e1744 --- /dev/null +++ b/plugins/FTPFileYM/options.cpp @@ -0,0 +1,310 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "deletetimer.h" +#include "options.h" + +Options *Options::instance = NULL; +Options &opt = Options::getInstance(); + +extern DeleteTimer &deleteTimer; +extern ServerList &ftpList; + +extern void PrebuildMainMenu(); + +void Options::deinit() +{ + delete this; +} + +void Options::loadOptions() +{ + enabled = DB::getByte(0, MODULE, "Enabled", 0); + selected = DB::getByte(0, MODULE, "Selected", 0); + defaultFTP = DB::getByte(0, MODULE, "Default", 0); + bAutosend = DB::getByte(0, MODULE, "Autosend", 0) ? true : false; + bCloseDlg = DB::getByte(0, MODULE, "CloseDlg", 0) ? true : false; + bCopyLink = DB::getByte(0, MODULE, "CopyLink", 1) ? true : false; + bUseSubmenu = DB::getByte(0, MODULE, "UseSubmenu", 1) ? true : false; + bHideInactive = DB::getByte(0, MODULE, "HideInactive", 1) ? true : false; + bAutoDelete = DB::getByte(0, MODULE, "DeleteTimer", 0) ? true : false; + iDeleteTime = DB::getDword(0, MODULE, "AutoDeleteTime", 60); + timeRange = (ETimeRange)DB::getByte(0, MODULE, "TimeRange", TR_MINUTES); + iCompressionLevel = DB::getByte(0, MODULE, "CompressionLevel", 6); + bSetZipName = DB::getByte(0, MODULE, "SetZipName", 0) ? true : false; +} + +void Options::saveOptions() const +{ + DB::setByte(0, MODULE, "Autosend", bAutosend ? 1 : 0); + DB::setByte(0, MODULE, "CopyLink", bCopyLink ? 1 : 0); + DB::setByte(0, MODULE, "UseSubmenu", bUseSubmenu ? 1 : 0); + DB::setByte(0, MODULE, "HideInactive", bHideInactive ? 1 : 0); + DB::setByte(0, MODULE, "CloseDlg", bCloseDlg ? 1 : 0); + DB::setByte(0, MODULE, "DeleteTimer", bAutoDelete ? 1 : 0); + DB::setDword(0, MODULE, "AutoDeleteTime", iDeleteTime); + DB::setByte(0, MODULE, "TimeRange", (int)timeRange); + DB::setByte(0, MODULE, "CompressionLevel", iCompressionLevel); + DB::setByte(0, MODULE, "SetZipName", bSetZipName ? 1 : 0); +} + +void Options::enableItems(HWND hwndDlg, bool state) +{ + EnableWindow(GetDlgItem(hwndDlg, IDC_DEFAULT), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_PROTOLIST), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_SERVER), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_USER), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_PASSWORD), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_DIR), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_URL), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_PORT), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_CHMOD), state); + EnableWindow(GetDlgItem(hwndDlg, IDC_PASSIVE), state); +} + +INT_PTR CALLBACK Options::DlgProcOptsAccounts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + + for (int i = 0; i < ServerList::FTP_COUNT; i++) + ComboBox_AddString(GetDlgItem(hwndDlg, IDC_FTPLIST), ftpList[i]->stzName); + + ComboBox_SetCurSel(GetDlgItem(hwndDlg, IDC_FTPLIST), opt.selected); + CheckDlgButton(hwndDlg, IDC_DEFAULT, opt.selected == opt.defaultFTP); + + ServerList::FTP *ftp = ftpList.getSelected(); + ComboBox_AddString(GetDlgItem(hwndDlg, IDC_PROTOLIST), TranslateT("FTP (Standard)")); + ComboBox_AddString(GetDlgItem(hwndDlg, IDC_PROTOLIST), TranslateT("FTP+SSL (Explicit)")); + ComboBox_AddString(GetDlgItem(hwndDlg, IDC_PROTOLIST), TranslateT("FTP+SSL (Implicit)")); + ComboBox_AddString(GetDlgItem(hwndDlg, IDC_PROTOLIST), TranslateT("SFTP (Secure FTP over SSH)")); + ComboBox_SetCurSel(GetDlgItem(hwndDlg, IDC_PROTOLIST), ftp->ftpProto); + + SetDlgItemTextA(hwndDlg, IDC_SERVER, ftp->szServer); + SetDlgItemTextA(hwndDlg, IDC_USER, ftp->szUser); + SetDlgItemTextA(hwndDlg, IDC_PASSWORD, ftp->szPass); + SetDlgItemTextA(hwndDlg, IDC_DIR, ftp->szDir); + SetDlgItemTextA(hwndDlg, IDC_URL, ftp->szUrl); + SetDlgItemTextA(hwndDlg, IDC_CHMOD, ftp->szChmod); + SetDlgItemInt (hwndDlg, IDC_PORT, ftp->iPort, FALSE); + CheckDlgButton(hwndDlg, IDC_PASSIVE, ftp->bPassive); + + if (ftpList.getSelected()->bEnabled) + { + CheckDlgButton(hwndDlg, IDC_ENABLED, 1); + } + else + { + CheckDlgButton(hwndDlg, IDC_ENABLED, 0); + enableItems(hwndDlg, false); + } + + return TRUE; + } + case WM_COMMAND: + { + if (HIWORD(wParam) == BN_CLICKED) + { + if (LOWORD(wParam) == IDC_ENABLED) + enableItems(hwndDlg, IsDlgButtonChecked(hwndDlg, IDC_ENABLED) == BST_CHECKED ? true : false); + } + else if (HIWORD(wParam) == CBN_SELCHANGE) + { + if (LOWORD(wParam) == IDC_FTPLIST) + { + opt.selected = (BYTE)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_FTPLIST)); + CheckDlgButton(hwndDlg, IDC_DEFAULT, opt.selected == opt.defaultFTP); + + ServerList::FTP *ftp = ftpList.getSelected(); + SendDlgItemMessage(hwndDlg, IDC_PROTOLIST, CB_SETCURSEL, ftp->ftpProto, 0); + SetDlgItemTextA(hwndDlg, IDC_SERVER, ftp->szServer); + SetDlgItemTextA(hwndDlg, IDC_USER, ftp->szUser); + SetDlgItemTextA(hwndDlg, IDC_PASSWORD, ftp->szPass); + SetDlgItemTextA(hwndDlg, IDC_DIR, ftp->szDir); + SetDlgItemTextA(hwndDlg, IDC_URL, ftp->szUrl); + SetDlgItemTextA(hwndDlg, IDC_CHMOD, ftp->szChmod); + SetDlgItemInt (hwndDlg, IDC_PORT, ftp->iPort, FALSE); + CheckDlgButton(hwndDlg, IDC_PASSIVE, ftp->bPassive); + + if (ftpList.getSelected()->bEnabled) + { + CheckDlgButton(hwndDlg, IDC_ENABLED, 1); + enableItems(hwndDlg, true); + } + else + { + CheckDlgButton(hwndDlg, IDC_ENABLED, 0); + enableItems(hwndDlg, false); + } + } + else if (LOWORD(wParam) == IDC_PROTOLIST) + { + int sel = ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_PROTOLIST)); + switch (sel) + { + case ServerList::FTP::FT_STANDARD: + case ServerList::FTP::FT_SSL_EXPLICIT: SetDlgItemInt(hwndDlg, IDC_PORT, 21, FALSE); break; + case ServerList::FTP::FT_SSL_IMPLICIT: SetDlgItemInt(hwndDlg, IDC_PORT, 990, FALSE); break; + case ServerList::FTP::FT_SSH: SetDlgItemInt(hwndDlg, IDC_PORT, 22, FALSE); break; + } + } + } + + if (HIWORD(wParam)==BN_CLICKED || HIWORD(wParam)==EN_CHANGE || HIWORD(wParam)==CBN_SELCHANGE || HIWORD(wParam)==CBN_EDITCHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + return TRUE; + } + case WM_NOTIFY: + { + if (((LPNMHDR)lParam)->code == PSN_APPLY) + { + if (IsDlgButtonChecked(hwndDlg, IDC_ENABLED)) + opt.enabled |= (1 << opt.selected); + else + opt.enabled &= ~(1 << opt.selected); + + if (IsDlgButtonChecked(hwndDlg, IDC_DEFAULT)) + opt.defaultFTP = opt.selected; + + ServerList::FTP *ftp = ftpList.getSelected(); + GetDlgItemText(hwndDlg, IDC_FTPLIST, ftp->stzName, SIZEOF(ftp->stzName)); + GetDlgItemTextA(hwndDlg, IDC_SERVER, ftp->szServer, SIZEOF(ftp->szServer)); + GetDlgItemTextA(hwndDlg, IDC_USER, ftp->szUser, SIZEOF(ftp->szUser)); + GetDlgItemTextA(hwndDlg, IDC_PASSWORD, ftp->szPass, SIZEOF(ftp->szPass)); + GetDlgItemTextA(hwndDlg, IDC_DIR, ftp->szDir, SIZEOF(ftp->szDir)); + GetDlgItemTextA(hwndDlg, IDC_URL, ftp->szUrl, SIZEOF(ftp->szUrl)); + GetDlgItemTextA(hwndDlg, IDC_CHMOD, ftp->szChmod, SIZEOF(ftp->szChmod)); + + ftp->ftpProto = (ServerList::FTP::EProtoType)ComboBox_GetCurSel(GetDlgItem(hwndDlg, IDC_PROTOLIST)); + ftp->iPort = GetDlgItemInt(hwndDlg, IDC_PORT, 0, 0); + ftp->bPassive = IsDlgButtonChecked(hwndDlg, IDC_PASSIVE) ? true : false; + + ComboBox_DeleteString(GetDlgItem(hwndDlg, IDC_FTPLIST), opt.selected); + ComboBox_InsertString(GetDlgItem(hwndDlg, IDC_FTPLIST), opt.selected, ftp->stzName); + ComboBox_SetCurSel(GetDlgItem(hwndDlg, IDC_FTPLIST), opt.selected); + + ftpList.saveToDb(); + PrebuildMainMenu(); + } + return TRUE; + } + } + + return FALSE; +} + +INT_PTR CALLBACK Options::DlgProcOptsAdvanced(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + + CheckDlgButton(hwndDlg, IDC_URL_AUTOSEND, opt.bAutosend ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_URL_COPYTOML, opt.bCopyLink ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_USESUBMENU, opt.bUseSubmenu ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_HIDEINACTIVE, opt.bHideInactive ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_CLOSEDLG, opt.bCloseDlg ? 1 : 0); + CheckDlgButton(hwndDlg, IDC_AUTODELETE, opt.bAutoDelete ? 1 : 0); + + SendDlgItemMessage(hwndDlg, IDC_LEVEL_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(9, 0)); + SetDlgItemInt(hwndDlg, IDC_LEVEL, opt.iCompressionLevel, FALSE); + CheckDlgButton(hwndDlg, IDC_SETZIPNAME, opt.bSetZipName ? 1 : 0); + + SendDlgItemMessage(hwndDlg, IDC_DELETETIME_SPIN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(UD_MAXVAL, 1)); + SetDlgItemInt(hwndDlg, IDC_DELETETIME, opt.iDeleteTime, FALSE); + + SendDlgItemMessage(hwndDlg, IDC_RANGE, CB_ADDSTRING, 0, (LPARAM)TranslateT("minutes")); + SendDlgItemMessage(hwndDlg, IDC_RANGE, CB_ADDSTRING, 0, (LPARAM)TranslateT("hours")); + SendDlgItemMessage(hwndDlg, IDC_RANGE, CB_ADDSTRING, 0, (LPARAM)TranslateT("days")); + SendDlgItemMessage(hwndDlg, IDC_RANGE, CB_SETCURSEL, (int)opt.timeRange, 0); + + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETETIME), opt.bAutoDelete); + EnableWindow(GetDlgItem(hwndDlg, IDC_RANGE), opt.bAutoDelete); + + return TRUE; + } + case WM_COMMAND: + { + if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDC_AUTODELETE) + { + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETETIME), IsDlgButtonChecked(hwndDlg, IDC_AUTODELETE)); + EnableWindow(GetDlgItem(hwndDlg, IDC_RANGE), IsDlgButtonChecked(hwndDlg, IDC_AUTODELETE)); + } + + if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == EN_CHANGE) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + + return TRUE; + } + case WM_NOTIFY: + { + if(((LPNMHDR)lParam)->code == PSN_APPLY) + { + opt.bAutosend = IsDlgButtonChecked(hwndDlg, IDC_URL_AUTOSEND) ? true : false; + opt.bCopyLink = IsDlgButtonChecked(hwndDlg, IDC_URL_COPYTOML) ? true : false; + opt.bUseSubmenu = IsDlgButtonChecked(hwndDlg, IDC_USESUBMENU) ? true : false; + opt.bHideInactive = IsDlgButtonChecked(hwndDlg, IDC_HIDEINACTIVE) ? true : false; + opt.bCloseDlg = IsDlgButtonChecked(hwndDlg, IDC_CLOSEDLG) ? true : false; + opt.bAutoDelete = IsDlgButtonChecked(hwndDlg, IDC_AUTODELETE) ? true : false; + opt.iCompressionLevel = GetDlgItemInt(hwndDlg, IDC_LEVEL, 0, FALSE); + opt.bSetZipName = IsDlgButtonChecked(hwndDlg, IDC_SETZIPNAME) ? true : false; + opt.iDeleteTime = GetDlgItemInt(hwndDlg, IDC_DELETETIME, 0, FALSE); + opt.timeRange = (Options::ETimeRange)SendDlgItemMessage(hwndDlg, IDC_RANGE, CB_GETCURSEL, 0, 0); + opt.saveOptions(); + + if (opt.bAutoDelete) deleteTimer.start(); + else deleteTimer.stop(); + + PrebuildMainMenu(); + } + return TRUE; + } + } + + return FALSE; +} + +int Options::InitOptions(WPARAM wParam, LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = {0}; + + odp.cbSize = sizeof(odp); + odp.position = 100000000; + odp.hInstance = hInst; + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR; + odp.ptszTitle = LPGENT("FTP File"); + odp.ptszGroup = LPGENT("Services"); + + odp.ptszTab = LPGENT("Accounts"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_FTPFILE); + odp.pfnDlgProc = Options::DlgProcOptsAccounts; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); + + odp.ptszTab = LPGENT("Advanced"); + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_ADVANCED); + odp.pfnDlgProc = Options::DlgProcOptsAdvanced; + CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp); + + return 0; +} \ No newline at end of file diff --git a/plugins/FTPFileYM/options.h b/plugins/FTPFileYM/options.h new file mode 100644 index 0000000000..5def96e1e5 --- /dev/null +++ b/plugins/FTPFileYM/options.h @@ -0,0 +1,69 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "common.h" +#include "serverlist.h" + +class Options +{ +private: + static Options *instance; + + Options() { }; + ~Options() { instance = NULL; }; + +public: + enum ETimeRange + { + TR_MINUTES= 0, + TR_HOURS, + TR_DAYS + }; + + BYTE enabled; + BYTE selected; + BYTE defaultFTP; + bool bCloseDlg; + bool bCopyLink; + bool bAutosend; + bool bUseSubmenu; + bool bHideInactive; + bool bAutoDelete; + int iCompressionLevel; + bool bSetZipName; + int iDeleteTime; + ETimeRange timeRange; + + static Options &getInstance() + { + if (!instance) + instance = new Options(); + return *instance; + }; + + static void enableItems(HWND hwndDlg, bool state); + static int InitOptions(WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK DlgProcOptsAccounts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK DlgProcOptsAdvanced(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + + void deinit(); + void loadOptions(); + void saveOptions() const; +}; \ No newline at end of file diff --git a/plugins/FTPFileYM/resource.h b/plugins/FTPFileYM/resource.h new file mode 100644 index 0000000000..17a227010b --- /dev/null +++ b/plugins/FTPFileYM/resource.h @@ -0,0 +1,101 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by ftpfile.rc +// +#define IDD_DLG_UPLOAD 101 +#define IDD_OPT_FTPFILE 103 +#define IDD_OPT_ADVANCED 104 +#define IDR_MENU_UPLOAD 106 +#define IDI_PAUSE 110 +#define IDI_RESUME 111 +#define IDD_DLG_MANAGER 113 +#define IDR_MENU_MANAGER 115 +#define IDI_CLEAR 116 +#define IDI_DELETE 117 +#define IDD_DLG_NAME 118 +#define IDD_DLG_FILEEXISTS 119 +#define IDC_TAB 1001 +#define IDC_PB_UPLOAD 1002 +#define IDC_ST_FILE 1003 +#define IDC_ST_SPEED 1004 +#define IDC_ST_COMPLETED 1005 +#define IDC_ST_REMAIN 1006 +#define IDC_UP_FILE 1007 +#define IDC_UP_COMPLETED 1008 +#define IDC_UP_SPEED 1009 +#define IDC_UP_REMAIN 1010 +#define IDC_ST_CONTACT 1011 +#define IDC_BTN_CLOSE 1012 +#define IDC_BTN_CLIPBOARD 1013 +#define IDC_BTN_OPTIONS 1014 +#define IDC_UP_CONTACT 1015 +#define IDC_ED_URL 1016 +#define IDC_BTN_FILEMANAGER 1017 +#define IDC_BTN_PAUSE 1018 +#define IDC_ST_SERVER 1019 +#define IDC_UP_SERVER 1020 +#define IDC_SERVER 1021 +#define IDC_BTN_PROTO 1021 +#define IDC_USER 1022 +#define IDC_BTN_DOWNLOAD 1022 +#define IDC_PASSWORD 1023 +#define IDC_DIR 1024 +#define IDC_URL 1025 +#define IDC_PORT 1026 +#define IDC_CHMOD 1027 +#define IDC_URL_CLOSEDLG 1028 +#define IDC_CLOSEDLG 1028 +#define IDC_URL_COPYTOML 1029 +#define IDC_URL_AUTOSEND 1030 +#define IDC_FTPLIST 1031 +#define IDC_AUTODELETE 1031 +#define IDC_ENABLED 1032 +#define IDC_PASSIVE 1033 +#define IDC_USESUBMENU 1034 +#define IDC_HIDEINACTIVE 1035 +#define IDC_FILELIST 1040 +#define IDC_BTN_SELECTALL 1041 +#define IDC_BTN_DESELECTALL 1042 +#define IDC_BTN_DELETE 1043 +#define IDC_DELETETIME 1043 +#define IDC_BTN_DELETEFROMLIST 1044 +#define IDC_LEVEL 1044 +#define IDC_DELETETIME_SPIN 1045 +#define IDC_RANGE 1046 +#define IDC_PROTOLIST 1047 +#define IDC_LEVEL_SPIN 1047 +#define IDC_SETZIPNAME 1048 +#define IDC_NAME 1049 +#define IDC_STATUSBAR 1050 +#define IDC_DEFAULT 1052 +#define IDC_RENAME 1054 +#define IDC_OVERWRITE 1055 +#define IDC_CANCEL 1056 +#define IDC_HEADER 1057 +#define IDC_CANCEL2 1058 +#define IDC_COPYURL 1058 +#define IDI_FTP0 20000 +#define IDI_FTP1 20001 +#define IDI_FTP2 20002 +#define IDI_FTP3 20003 +#define IDI_FTP4 20004 +#define IDI_MENU 20010 +#define IDI_CLIPBOARD 20011 +#define IDM_COPYLINK 40001 +#define IDM_CLOSEDLG 40002 +#define IDM_AUTOSEND 40003 +#define IDM_DELETEFROMLIST 40016 +#define IDM_DELETEFROMFTP 40017 +#define IDM_DOWNLOAD 40019 +#define IDM_DISABLED 40043 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 119 +#define _APS_NEXT_COMMAND_VALUE 40044 +#define _APS_NEXT_CONTROL_VALUE 1058 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/FTPFileYM/serverlist.cpp b/plugins/FTPFileYM/serverlist.cpp new file mode 100644 index 0000000000..9d94c33b7c --- /dev/null +++ b/plugins/FTPFileYM/serverlist.cpp @@ -0,0 +1,113 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "serverlist.h" +#include "options.h" + +ServerList *ServerList::instance = NULL; +ServerList &ftpList = ServerList::getInstance(); + +extern Options &opt; + +void ServerList::init() +{ + for (int i = 0; i < FTP_COUNT; i++) + { + ServerList::FTP *ftp = new ServerList::FTP(i); + ftpList.add(ftp); + } +} + +void ServerList::deinit() +{ + for (UINT i = 0; i < ftpList.size(); i++) + delete ftpList[i]; + + delete this; +} + +void ServerList::saveToDb() const +{ + ServerList::FTP *ftp = ftpList.getSelected(); + char buff[256]; + + mir_snprintf(buff, sizeof(buff), "Password%d", opt.selected); + DB::setCryptedString(0, MODULE, buff, ftp->szPass); + + DB::setStringF(0, MODULE, "Name%d", opt.selected, ftp->stzName); + DB::setAStringF(0, MODULE, "Server%d", opt.selected, ftp->szServer); + DB::setAStringF(0, MODULE, "User%d", opt.selected, ftp->szUser); + DB::setAStringF(0, MODULE, "Url%d", opt.selected, ftp->szUrl); + DB::setAStringF(0, MODULE, "Dir%d", opt.selected, ftp->szDir); + DB::setAStringF(0, MODULE, "Chmod%d", opt.selected, ftp->szChmod); + DB::setWordF(0, MODULE, "FtpProto%d", opt.selected, ftp->ftpProto); + DB::setWordF(0, MODULE, "Port%d", opt.selected, ftp->iPort); + DB::setByteF(0, MODULE, "Passive%d", opt.selected, ftp->bPassive); + DB::setByte(0, MODULE, "Selected", opt.selected); + DB::setByte(0, MODULE, "Enabled", opt.enabled); + DB::setByte(0, MODULE, "Default", opt.defaultFTP); +} + +ServerList::FTP::FTP(int index) +{ + char buff[256]; + + this->bEnabled = ((opt.enabled >> index) & 1); + + if (DB::getStringF(0, MODULE, "Name%d", index, this->stzName)) + mir_sntprintf(this->stzName, SIZEOF(this->stzName), TranslateT("FTP Server %d"), index + 1); + + mir_snprintf(buff, sizeof(buff), "Password%d", index); + DB::getCryptedString(0, MODULE, buff, this->szPass); + + DB::getAStringF(0, MODULE, "Server%d", index, this->szServer); + DB::getAStringF(0, MODULE, "User%d", index, this->szUser); + DB::getAStringF(0, MODULE, "Url%d", index, this->szUrl); + DB::getAStringF(0, MODULE, "Dir%d", index, this->szDir); + DB::getAStringF(0, MODULE, "Chmod%d", index, this->szChmod); + this->ftpProto = (FTP::EProtoType)DB::getWordF(0, MODULE, "FtpProto%d", index, FTP::FT_STANDARD); + this->iPort = DB::getWordF(0, MODULE, "Port%d", index, 21); + this->bPassive = DB::getByteF(0, MODULE, "Passive%d", index, 0) ? true : false; +} + +ServerList::FTP *ServerList::getSelected() const +{ + return ftpList[opt.selected]; +} + +bool ServerList::FTP::isValid() const +{ + return (this->bEnabled && + this->szServer[0] && + this->szUser[0] && + this->szPass[0] && + this->szUrl[0]) ? true : false; +} + +char *ServerList::FTP::getProtoString() const +{ + switch (this->ftpProto) + { + case FT_STANDARD: + case FT_SSL_EXPLICIT: return "ftp://"; + case FT_SSL_IMPLICIT: return "ftps://"; + case FT_SSH: return "sftp://"; + } + + return NULL; +} diff --git a/plugins/FTPFileYM/serverlist.h b/plugins/FTPFileYM/serverlist.h new file mode 100644 index 0000000000..8a1a540172 --- /dev/null +++ b/plugins/FTPFileYM/serverlist.h @@ -0,0 +1,79 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "common.h" + +class ServerList +{ +private: + static ServerList *instance; + ServerList() { }; + ~ServerList() { instance = NULL; }; + +public: + class FTP + { + public: + enum EProtoType + { + FT_STANDARD = 0, + FT_SSL_EXPLICIT, + FT_SSL_IMPLICIT, + FT_SSH + }; + + bool bEnabled; + TCHAR stzName[64]; + char szServer[256]; + char szUser[64]; + char szPass[64]; + char szDir[64]; + char szChmod[256]; + char szUrl[256]; + EProtoType ftpProto; + int iPort; + bool bPassive; + + FTP(int index); + + bool isValid() const; + char *getProtoString() const; + }; + + static const int FTP_COUNT = 5; + + vector items; + + FTP *operator[] (int i) const { return items[i]; }; + void add(FTP *newItem) { items.push_back(newItem); } + size_t size() { return items.size(); } + + static ServerList &getInstance() + { + if (!instance) + instance = new ServerList(); + return *instance; + }; + + void init(); + void deinit(); + void saveToDb() const; + FTP *getSelected() const; +}; \ No newline at end of file diff --git a/plugins/FTPFileYM/utils.cpp b/plugins/FTPFileYM/utils.cpp new file mode 100644 index 0000000000..8b0acd14da --- /dev/null +++ b/plugins/FTPFileYM/utils.cpp @@ -0,0 +1,237 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#include "utils.h" +#include "dialog.h" +#include "options.h" + +extern Options &opt; +extern UploadDialog *uDlg; +extern LibCurl &curl; + +int Utils::getDeleteTimeMin() +{ + switch (opt.timeRange) + { + case (Options::TR_MINUTES): return (opt.iDeleteTime); + case (Options::TR_HOURS): return (opt.iDeleteTime * 60); + case (Options::TR_DAYS): return (opt.iDeleteTime * 60 * 24); + } + + return -1; +} + +int Utils::msgBox(TCHAR *stzMsg, UINT uType) +{ + HWND hwnd = (uDlg != NULL) ? uDlg->hwnd : 0; + return MessageBox(hwnd, stzMsg, TranslateT("FTP File"), uType); +} + +int Utils::msgBoxA(char *szMsg, UINT uType) +{ + HWND hwnd = (uDlg != NULL) ? uDlg->hwnd : 0; + return MessageBoxA(hwnd, szMsg, Translate("FTP File"), uType); +} + +HICON Utils::loadIconEx(char *szName) +{ + char buff[100]; + mir_snprintf(buff, sizeof(buff), "%s_%s", MODULE, szName); + return (HICON)CallService(MS_SKIN2_GETICON, 0, (LPARAM)buff); +} + +TCHAR *Utils::getFileNameFromPath(TCHAR *stzPath) +{ + TCHAR *pch = _tcsrchr(stzPath, '\\'); + if (pch) return pch + 1; + else return _T("file.zip"); +} + +TCHAR *Utils::getTextFragment(TCHAR *stzText, size_t length, TCHAR *buff) +{ + if (_tcslen(stzText) > length) + { + _tcscpy(buff, stzText); + buff[length - 1] = 0; + _tcscat(buff, _T("...")); + return buff; + } + + return stzText; +} + +void Utils::copyToClipboard(char *szText) +{ + if (szText) + { + if (OpenClipboard(NULL)) + { + EmptyClipboard(); + HGLOBAL hClipboardData = GlobalAlloc(GMEM_DDESHARE, 1024); + char *pchData = (char *)GlobalLock(hClipboardData); + strcpy(pchData, szText); + GlobalUnlock(hClipboardData); + SetClipboardData(CF_TEXT, hClipboardData); + CloseClipboard(); + } + } +} + +const char from_chars[] = "БЙНУЪЭЙЉИШЋПЌТбймнуъщэљишћпќт #{}^~[];,"; +const char to_chars[] = "AEIOUYESCRZDTNaeeiouuyscrzdtn__________"; + +char* Utils::makeSafeString(TCHAR *input, char *output) +{ + char *buff = mir_t2a(input); + size_t length = strlen(buff); + + for (UINT i = 0; i < length; i++) + { + for (int j = 0; from_chars[j] != 0; j++) + { + if (buff[i] == from_chars[j]) + { + buff[i] = to_chars[j]; + break; + } + } + } + + strcpy(output, buff); + FREE(buff); + + return output; +} + +void Utils::curlSetOpt(CURL *hCurl, ServerList::FTP *ftp, char *url, struct curl_slist *headerList, char *errorBuff) +{ + char buff[256]; + + curl.easy_setopt(hCurl, CURLOPT_ERRORBUFFER, errorBuff); + + curl.easy_setopt(hCurl, CURLOPT_POSTQUOTE, headerList); + curl.easy_setopt(hCurl, CURLOPT_NOPROGRESS, 1); + + curl.easy_setopt(hCurl, CURLOPT_URL, url); + curl.easy_setopt(hCurl, CURLOPT_PORT, ftp->iPort); + curl.easy_setopt(hCurl, CURLOPT_CONNECTTIMEOUT, 30); + curl.easy_setopt(hCurl, CURLOPT_FTP_RESPONSE_TIMEOUT, 20); + + curl.easy_setopt(hCurl, CURLOPT_FTP_USE_EPRT, 0); + curl.easy_setopt(hCurl, CURLOPT_FTP_USE_EPSV, 0); + + if (ftp->bPassive) + curl.easy_setopt(hCurl, CURLOPT_FTPPORT, 0); + else if (!DB::getAString(0, MODULE, "LocalIP", buff)) + curl.easy_setopt(hCurl, CURLOPT_FTPPORT, buff); + else + curl.easy_setopt(hCurl, CURLOPT_FTPPORT, "-"); + + mir_snprintf(buff, sizeof(buff), "%s:%s", ftp->szUser, ftp->szPass); + curl.easy_setopt(hCurl, CURLOPT_USERPWD, buff); + + if (ftp->ftpProto == ServerList::FTP::FT_SSL_EXPLICIT || ftp->ftpProto == ServerList::FTP::FT_SSL_IMPLICIT) + { + curl.easy_setopt(hCurl, CURLOPT_USE_SSL, CURLUSESSL_ALL); + curl.easy_setopt(hCurl, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_DEFAULT); + curl.easy_setopt(hCurl, CURLOPT_SSL_VERIFYPEER, 0); + curl.easy_setopt(hCurl, CURLOPT_SSL_VERIFYHOST, 2); + } + else if (ftp->ftpProto == ServerList::FTP::FT_SSH) + { + curl.easy_setopt(hCurl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_PASSWORD); + } +} + +INT_PTR CALLBACK Utils::DlgProcSetFileName(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TCHAR *fileName = (TCHAR *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + fileName = (TCHAR *)lParam; + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)fileName); + SetDlgItemText(hwndDlg, IDC_NAME, fileName); + + if (GetDlgCtrlID((HWND)wParam) != IDC_NAME) + { + SetFocus(GetDlgItem(hwndDlg, IDC_NAME)); + SendDlgItemMessage(hwndDlg, IDC_NAME, EM_SETSEL, 0, _tcslen(fileName) - 4); + return FALSE; + } + + return TRUE; + } + case WM_COMMAND: + { + if (HIWORD(wParam) == BN_CLICKED) + { + if (LOWORD(wParam) == IDOK) + { + GetDlgItemText(hwndDlg, IDC_NAME, fileName, 64); + EndDialog(hwndDlg, IDOK); + } + else if (LOWORD(wParam) == IDCANCEL) + { + EndDialog(hwndDlg, IDCANCEL); + } + } + + break; + } + } + + return FALSE; +} + +bool Utils::setFileNameDlg(TCHAR *nameBuff) +{ + if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_DLG_NAME), 0, DlgProcSetFileName, (LPARAM)nameBuff) == IDOK) + return true; + else + return false; +} + +bool Utils::setFileNameDlgA(char *nameBuff) +{ + TCHAR buff[64]; + TCHAR *tmp = mir_a2t(nameBuff); + _tcscpy(buff, tmp); + FREE(tmp); + + bool res = setFileNameDlg(buff); + if (res) + { + char *p = mir_t2a(buff); + strcpy(nameBuff, p); + FREE(p); + } + + return res; +} + +void Utils::createFileDownloadLink(char *szUrl, char *fileName, char *buff, int buffSize) +{ + if (szUrl[strlen(szUrl) - 1] == '/') + mir_snprintf(buff, buffSize, "%s%s", szUrl, fileName); + else + mir_snprintf(buff, buffSize, "%s/%s", szUrl, fileName); +} \ No newline at end of file diff --git a/plugins/FTPFileYM/utils.h b/plugins/FTPFileYM/utils.h new file mode 100644 index 0000000000..3b22ccc7d6 --- /dev/null +++ b/plugins/FTPFileYM/utils.h @@ -0,0 +1,71 @@ +/* +FTP File YM plugin +Copyright (C) 2007-2010 Jan Holub + +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 version 2 +of the License. + +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, see . +*/ + +#pragma once + +#include "common.h" +#include "serverlist.h" + +class Utils +{ +private: + static INT_PTR CALLBACK DlgProcSetFileName(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + +public: + static int msgBox(TCHAR *szMsg, UINT uType); + static int msgBoxA(char *szMsg, UINT uType); + static int getDeleteTimeMin(); + static HICON loadIconEx(char *szName); + + static TCHAR *getFileNameFromPath(TCHAR *stzPath); + static TCHAR *getTextFragment(TCHAR *stzText, size_t length, TCHAR *buff); + static char *makeSafeString(TCHAR *input, char *output); + + static void createFileDownloadLink(char *szUrl, char *fileName, char *buff, int buffSize); + static void copyToClipboard(char *szText); + static void curlSetOpt(CURL *hCurl, ServerList::FTP *ftp, char *url, struct curl_slist *headerList, char *errorBuff); + + static bool setFileNameDlg(TCHAR *nameBuff); + static bool setFileNameDlgA(char *nameBuff); +}; + +class Mutex +{ + friend class Lock; + +private: + void Acquire() { EnterCriticalSection (&_critSection); } + void Release() { LeaveCriticalSection (&_critSection); } + + CRITICAL_SECTION _critSection; + +public: + Mutex() { InitializeCriticalSection (&_critSection); } + ~Mutex() { DeleteCriticalSection (&_critSection); } +}; + +class Lock +{ +private: + Mutex &_mutex; + +public: + Lock (Mutex &mutex): _mutex(mutex) { _mutex.Acquire(); } + ~Lock () {_mutex.Release(); } +}; + diff --git a/plugins/FTPFileYM/version.h b/plugins/FTPFileYM/version.h new file mode 100644 index 0000000000..ca7d1ef7cd --- /dev/null +++ b/plugins/FTPFileYM/version.h @@ -0,0 +1,4 @@ +#define __FILEVERSION_STRING 0,5,0,0 +#define __VERSION_STRING "0.5.0.0" +#define __VERSION_DWORD PLUGIN_MAKE_VERSION(0, 5, 0, 0) + diff --git a/plugins/FTPFileYM/version.rc b/plugins/FTPFileYM/version.rc new file mode 100644 index 0000000000..e436e54e03 --- /dev/null +++ b/plugins/FTPFileYM/version.rc @@ -0,0 +1,37 @@ + +#include +#include "version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION __FILEVERSION_STRING + PRODUCTVERSION __FILEVERSION_STRING + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Author", "Jan Holub" + VALUE "CompanyName", "yaho" + VALUE "FileDescription", "FTP a file to a server and send the URL to your friend" + VALUE "FileVersion", __VERSION_STRING + VALUE "InternalName", "FTP File YM" + VALUE "LegalCopyright", "Copyright (c) 2007-2010 Jan Holub" + VALUE "OriginalFilename", "ftpfile.dll" + VALUE "ProductName", "FTP File YM" + VALUE "ProductVersion", __VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/plugins/FTPFileYM/zip/crypt.h b/plugins/FTPFileYM/zip/crypt.h new file mode 100644 index 0000000000..a01d08d932 --- /dev/null +++ b/plugins/FTPFileYM/zip/crypt.h @@ -0,0 +1,131 @@ +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) +{ + (*(pkeys+0)) = CRC32((*(pkeys+0)), c); + (*(pkeys+1)) += (*(pkeys+0)) & 0xff; + (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys+1)) >> 24); + (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) +{ + *(pkeys+0) = 305419896L; + *(pkeys+1) = 591751049L; + *(pkeys+2) = 878082192L; + while (*passwd != '\0') { + update_keys(pkeys,pcrc_32_tab,(int)*passwd); + passwd++; + } +} + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +static int crypthead(const char* passwd, /* password string */ + unsigned char* buf, /* where to write header */ + int bufSize, + unsigned long* pkeys, + const unsigned long* pcrc_32_tab, + unsigned long crcForCrypting) +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN-2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN-2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/plugins/FTPFileYM/zip/ioapi.c b/plugins/FTPFileYM/zip/ioapi.c new file mode 100644 index 0000000000..49958f61ff --- /dev/null +++ b/plugins/FTPFileYM/zip/ioapi.c @@ -0,0 +1,235 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#if (defined(_WIN32)) + #define _CRT_SECURE_NO_WARNINGS +#endif + +#include "ioapi.h" + +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) +{ + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); + } +} + +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); + } +} + +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); + else + { + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == ((uLong)-1)) + return (ZPOS64_T)-1; + else + return tell_uLong; + } +} + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) +{ + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; +} + + + +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); +static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); + +static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen64((const char*)filename, mode_fopen); + return file; +} + + +static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + + +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret; + ret = ftello64((FILE *)stream); + return ret; +} + +static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + if (fseek((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + return ret; +} + +static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + + if(fseeko64((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + + return ret; +} + + +static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/plugins/FTPFileYM/zip/ioapi.h b/plugins/FTPFileYM/zip/ioapi.h new file mode 100644 index 0000000000..8309c4cf8f --- /dev/null +++ b/plugins/FTPFileYM/zip/ioapi.h @@ -0,0 +1,200 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) + +*/ + +#ifndef _ZLIBIOAPI64_H +#define _ZLIBIOAPI64_H + +#if (!defined(_WIN32)) && (!defined(WIN32)) + + // Linux needs this to support file operation on files larger then 4+GB + // But might need better if/def to select just the platforms that needs them. + + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif +#endif + +#include +#include +#include "zlib.h" + +#if defined(USE_FILE32API) +#define fopen64 fopen +#define ftello64 ftell +#define fseeko64 fseek +#else +#ifdef _MSC_VER + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif +#endif +#endif + +/* +#ifndef ZPOS64_T + #ifdef _WIN32 + #define ZPOS64_T fpos_t + #else + #include + #define ZPOS64_T uint64_t + #endif +#endif +*/ + +#ifdef HAVE_MINIZIP64_CONF_H +#include "mz64conf.h" +#endif + +/* a type choosen by DEFINE */ +#ifdef HAVE_64BIT_INT_CUSTOM +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +#else +#ifdef HAS_STDINT_H +#include "stdint.h" +typedef uint64_t ZPOS64_T; +#else + + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 ZPOS64_T; +#else +typedef unsigned long long int ZPOS64_T; +#endif +#endif +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif +#endif + + + + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + + +/* here is the "old" 32 bits structure structure */ +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); + +typedef struct zlib_filefunc64_def_s +{ + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc64_def; + +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +/* now internal definition, only for zip.c and unzip.h */ +typedef struct zlib_filefunc64_32_def_s +{ + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; +} zlib_filefunc64_32_def; + + +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) + +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); +ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/plugins/FTPFileYM/zip/zconf.h b/plugins/FTPFileYM/zip/zconf.h new file mode 100644 index 0000000000..58880245c1 --- /dev/null +++ b/plugins/FTPFileYM/zip/zconf.h @@ -0,0 +1,416 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2010 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id$ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + * Even better than compiling with -DZ_PREFIX would be to use configure to set + * this permanently in zconf.h using "./configure --zprefix". + */ +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ + +/* all linked symbols */ +# define _dist_code z__dist_code +# define _length_code z__length_code +# define _tr_align z__tr_align +# define _tr_flush_block z__tr_flush_block +# define _tr_init z__tr_init +# define _tr_stored_block z__tr_stored_block +# define _tr_tally z__tr_tally +# define adler32 z_adler32 +# define adler32_combine z_adler32_combine +# define adler32_combine64 z_adler32_combine64 +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define crc32 z_crc32 +# define crc32_combine z_crc32_combine +# define crc32_combine64 z_crc32_combine64 +# define deflate z_deflate +# define deflateBound z_deflateBound +# define deflateCopy z_deflateCopy +# define deflateEnd z_deflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateInit_ z_deflateInit_ +# define deflateParams z_deflateParams +# define deflatePrime z_deflatePrime +# define deflateReset z_deflateReset +# define deflateSetDictionary z_deflateSetDictionary +# define deflateSetHeader z_deflateSetHeader +# define deflateTune z_deflateTune +# define deflate_copyright z_deflate_copyright +# define get_crc_table z_get_crc_table +# define gz_error z_gz_error +# define gz_intmax z_gz_intmax +# define gz_strwinerror z_gz_strwinerror +# define gzbuffer z_gzbuffer +# define gzclearerr z_gzclearerr +# define gzclose z_gzclose +# define gzclose_r z_gzclose_r +# define gzclose_w z_gzclose_w +# define gzdirect z_gzdirect +# define gzdopen z_gzdopen +# define gzeof z_gzeof +# define gzerror z_gzerror +# define gzflush z_gzflush +# define gzgetc z_gzgetc +# define gzgets z_gzgets +# define gzoffset z_gzoffset +# define gzoffset64 z_gzoffset64 +# define gzopen z_gzopen +# define gzopen64 z_gzopen64 +# define gzprintf z_gzprintf +# define gzputc z_gzputc +# define gzputs z_gzputs +# define gzread z_gzread +# define gzrewind z_gzrewind +# define gzseek z_gzseek +# define gzseek64 z_gzseek64 +# define gzsetparams z_gzsetparams +# define gztell z_gztell +# define gztell64 z_gztell64 +# define gzungetc z_gzungetc +# define gzwrite z_gzwrite +# define inflate z_inflate +# define inflateBack z_inflateBack +# define inflateBackEnd z_inflateBackEnd +# define inflateBackInit_ z_inflateBackInit_ +# define inflateCopy z_inflateCopy +# define inflateEnd z_inflateEnd +# define inflateGetHeader z_inflateGetHeader +# define inflateInit2_ z_inflateInit2_ +# define inflateInit_ z_inflateInit_ +# define inflateMark z_inflateMark +# define inflatePrime z_inflatePrime +# define inflateReset z_inflateReset +# define inflateReset2 z_inflateReset2 +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateUndermine z_inflateUndermine +# define inflate_copyright z_inflate_copyright +# define inflate_fast z_inflate_fast +# define inflate_table z_inflate_table +# define uncompress z_uncompress +# define zError z_zError +# define zcalloc z_zcalloc +# define zcfree z_zcfree +# define zlibCompileFlags z_zlibCompileFlags +# define zlibVersion z_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +# define Byte z_Byte +# define Bytef z_Bytef +# define alloc_func z_alloc_func +# define charf z_charf +# define free_func z_free_func +# define gzFile z_gzFile +# define gz_header z_gz_header +# define gz_headerp z_gz_headerp +# define in_func z_in_func +# define intf z_intf +# define out_func z_out_func +# define uInt z_uInt +# define uIntf z_uIntf +# define uLong z_uLong +# define uLongf z_uLongf +# define voidp z_voidp +# define voidpc z_voidpc +# define voidpf z_voidpf + +/* all zlib structs in zlib.h and zconf.h */ +# define gz_header_s z_gz_header_s +# define internal_state z_internal_state + +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) +# ifndef WIN32 +# define WIN32 +# endif +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifdef HAVE_VISIBILITY_PRAGMA +# define ZEXTERN __attribute__((visibility ("default"))) extern +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef Z_HAVE_UNISTD_H +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#ifdef _LARGEFILE64_SOURCE +# include +#endif + +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +# define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) + #pragma map(deflateInit_,"DEIN") + #pragma map(deflateInit2_,"DEIN2") + #pragma map(deflateEnd,"DEEND") + #pragma map(deflateBound,"DEBND") + #pragma map(inflateInit_,"ININ") + #pragma map(inflateInit2_,"ININ2") + #pragma map(inflateEnd,"INEND") + #pragma map(inflateSync,"INSY") + #pragma map(inflateSetDictionary,"INSEDI") + #pragma map(compressBound,"CMBND") + #pragma map(inflate_table,"INTABL") + #pragma map(inflate_fast,"INFA") + #pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/plugins/FTPFileYM/zip/zip.c b/plugins/FTPFileYM/zip/zip.c new file mode 100644 index 0000000000..3c34fc8bd4 --- /dev/null +++ b/plugins/FTPFileYM/zip/zip.c @@ -0,0 +1,2004 @@ +/* zip.c -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + Oct-2009 - Mathias Svensson - Remove old C style function prototypes + Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives + Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions. + Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data + It is used when recreting zip archive with RAW when deleting items from a zip. + ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed. + Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required) + Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer + +*/ + + +#include +#include +#include +#include +#include "zlib.h" +#include "zip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#ifndef VERSIONMADEBY +# define VERSIONMADEBY (0x0) /* platform depedent */ +#endif + +#ifndef Z_BUFSIZE +#define Z_BUFSIZE (64*1024) //(16384) +#endif + +#ifndef Z_MAXFILENAMEINZIP +#define Z_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +/* +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) +*/ + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + + +// NOT sure that this work on ALL platform +#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +#ifndef DEF_MEM_LEVEL +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +#endif +const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + + +#define SIZEDATA_INDATABLOCK (4096-(4*4)) + +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) +#define ZIP64ENDHEADERMAGIC (0x6064b50) +#define ZIP64ENDLOCHEADERMAGIC (0x7064b50) + +#define FLAG_LOCALHEADER_OFFSET (0x06) +#define CRC_LOCALHEADER_OFFSET (0x0e) + +#define SIZECENTRALHEADER (0x2e) /* 46 */ + +typedef struct linkedlist_datablock_internal_s +{ + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignement */ + unsigned char data[SIZEDATA_INDATABLOCK]; +} linkedlist_datablock_internal; + +typedef struct linkedlist_data_s +{ + linkedlist_datablock_internal* first_block; + linkedlist_datablock_internal* last_block; +} linkedlist_data; + + +typedef struct +{ + z_stream stream; /* zLib stream structure for inflate */ +#ifdef HAVE_BZIP2 + bz_stream bstream; /* bzLib stream structure for bziped */ +#endif + + int stream_initialised; /* 1 is stream is initialised */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ + + ZPOS64_T pos_local_header; /* offset of the local header of the file + currenty writing */ + char* central_header; /* central header data for the current file */ + uLong size_centralExtra; + uLong size_centralheader; /* size of the central header for cur file */ + uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ + uLong flag; /* flag of the file currently writing */ + + int method; /* compression method of file currenty wr.*/ + int raw; /* 1 for directly writing raw data */ + Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ + uLong dosDate; + uLong crc32; + int encrypt; + int zip64; /* Add ZIP64 extened information in the extra field */ + ZPOS64_T pos_zip64extrainfo; + ZPOS64_T totalCompressedData; + ZPOS64_T totalUncompressedData; +#ifndef NOCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; + int crypt_header_size; +#endif +} curfile64_info; + +typedef struct +{ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + linkedlist_data central_dir;/* datablock with central dir in construction*/ + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ + curfile64_info ci; /* info on the file curretly writing */ + + ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ + ZPOS64_T add_position_when_writting_offset; + ZPOS64_T number_entry; + +#ifndef NO_ADDFILEINEXISTINGZIP + char *globalcomment; +#endif + +} zip64_internal; + + +#ifndef NOCRYPT +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED +#include "crypt.h" +#endif + +local linkedlist_datablock_internal* allocate_new_datablock() +{ + linkedlist_datablock_internal* ldi; + ldi = (linkedlist_datablock_internal*) + ALLOC(sizeof(linkedlist_datablock_internal)); + if (ldi!=NULL) + { + ldi->next_datablock = NULL ; + ldi->filled_in_this_block = 0 ; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; + } + return ldi; +} + +local void free_datablock(linkedlist_datablock_internal* ldi) +{ + while (ldi!=NULL) + { + linkedlist_datablock_internal* ldinext = ldi->next_datablock; + TRYFREE(ldi); + ldi = ldinext; + } +} + +local void init_linkedlist(linkedlist_data* ll) +{ + ll->first_block = ll->last_block = NULL; +} + +local void free_linkedlist(linkedlist_data* ll) +{ + free_datablock(ll->first_block); + ll->first_block = ll->last_block = NULL; +} + + +local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) +{ + linkedlist_datablock_internal* ldi; + const unsigned char* from_copy; + + if (ll==NULL) + return ZIP_INTERNALERROR; + + if (ll->last_block == NULL) + { + ll->first_block = ll->last_block = allocate_new_datablock(); + if (ll->first_block == NULL) + return ZIP_INTERNALERROR; + } + + ldi = ll->last_block; + from_copy = (unsigned char*)buf; + + while (len>0) + { + uInt copy_this; + uInt i; + unsigned char* to_copy; + + if (ldi->avail_in_this_block==0) + { + ldi->next_datablock = allocate_new_datablock(); + if (ldi->next_datablock == NULL) + return ZIP_INTERNALERROR; + ldi = ldi->next_datablock ; + ll->last_block = ldi; + } + + if (ldi->avail_in_this_block < len) + copy_this = (uInt)ldi->avail_in_this_block; + else + copy_this = (uInt)len; + + to_copy = &(ldi->data[ldi->filled_in_this_block]); + + for (i=0;ifilled_in_this_block += copy_this; + ldi->avail_in_this_block -= copy_this; + from_copy += copy_this ; + len -= copy_this; + } + return ZIP_OK; +} + + + +/****************************************************************************/ + +#ifndef NO_ADDFILEINEXISTINGZIP +/* =========================================================================== + Inputs a long in LSB order to the given file + nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T) +*/ + +local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); +local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) +{ + unsigned char buf[8]; + int n; + for (n = 0; n < nbByte; n++) + { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + if (x != 0) + { /* data overflow - hack for ZIP64 (X Roche) */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } + + if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) + return ZIP_ERRNO; + else + return ZIP_OK; +} + +local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); +local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) +{ + unsigned char* buf=(unsigned char*)dest; + int n; + for (n = 0; n < nbByte; n++) { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + + if (x != 0) + { /* data overflow - hack for ZIP64 */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } +} + +/****************************************************************************/ + + +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) +{ + uLong year = (uLong)ptm->tm_year; + if (year>=1980) + year-=1980; + else if (year>=80) + year-=80; + return + (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | + ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); +} + + +/****************************************************************************/ + +local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); + +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) +{ + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return ZIP_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def,filestream)) + return ZIP_ERRNO; + else + return ZIP_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); + +local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +{ + uLong x ; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); + + +local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) +{ + ZPOS64_T x; + int i = 0; + int err; + + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x = (ZPOS64_T)i; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<8; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<16; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<24; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<32; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<40; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<48; + + if (err==ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); + x += ((ZPOS64_T)i)<<56; + + if (err==ZIP_OK) + *pX = x; + else + *pX = 0; + + return err; +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* +Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before +the global comment) +*/ +local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); + +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) +{ + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound=0; + uLong uL; + ZPOS64_T relativeOffset; + + if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); + if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + { + // Signature "0x07064b50" Zip64 end of central directory locater + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) + { + uPosFound = uReadPos+i; + break; + } + } + + if (uPosFound!=0) + break; + } + + TRYFREE(buf); + if (uPosFound == 0) + return 0; + + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature, already checked */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + /* number of the disk with the start of the zip64 end of central directory */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 0) + return 0; + + /* relative offset of the zip64 end of central directory record */ + if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) + return 0; + + /* total number of disks */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + if (uL != 1) + return 0; + + /* Goto Zip64 end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) + return 0; + + /* the signature */ + if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) + return 0; + + if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' + return 0; + + return relativeOffset; +} + +int LoadCentralDirectoryRecord(zip64_internal* pziinit) +{ + int err=ZIP_OK; + ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory */ + ZPOS64_T central_pos; + uLong uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + ZPOS64_T number_entry; + ZPOS64_T number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + uLong VersionMadeBy; + uLong VersionNeeded; + uLong size_comment; + + int hasZIP64Record = 0; + + // check first if we find a ZIP64 record + central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); + if(central_pos > 0) + { + hasZIP64Record = 1; + } + else if(central_pos == 0) + { + central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); + } + +/* disable to allow appending to empty ZIP archive + if (central_pos==0) + err=ZIP_ERRNO; +*/ + + if(hasZIP64Record) + { + ZPOS64_T sizeEndOfCentralDirectory; + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* size of zip64 end of central directory record */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version made by */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) + err=ZIP_ERRNO; + + /* version needed to extract */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory on this disk */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) + err=ZIP_ERRNO; + + // TODO.. + // read the comment from the standard central header. + size_comment = 0; + } + else + { + // Read End of central Directory info + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=ZIP_ERRNO; + + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of this disk */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) + err=ZIP_ERRNO; + + /* number of the disk with the start of the central directory */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) + err=ZIP_ERRNO; + + /* total number of entries in the central dir on this disk */ + number_entry = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry = uL; + + /* total number of entries in the central dir */ + number_entry_CD = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + number_entry_CD = uL; + + if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) + err=ZIP_BADZIPFILE; + + /* size of the central directory */ + size_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + size_central_dir = uL; + + /* offset of start of central directory with respect to the starting disk number */ + offset_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) + err=ZIP_ERRNO; + else + offset_central_dir = uL; + + + /* zipfile global comment length */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) + err=ZIP_ERRNO; + } + + if ((central_posz_filefunc, pziinit->filestream); + return ZIP_ERRNO; + } + + if (size_comment>0) + { + pziinit->globalcomment = (char*)ALLOC(size_comment+1); + if (pziinit->globalcomment) + { + size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); + pziinit->globalcomment[size_comment]=0; + } + } + + byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); + pziinit->add_position_when_writting_offset = byte_before_the_zipfile; + + { + ZPOS64_T size_central_dir_to_read = size_central_dir; + size_t buf_size = SIZEDATA_INDATABLOCK; + void* buf_read = (void*)ALLOC(buf_size); + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + while ((size_central_dir_to_read>0) && (err==ZIP_OK)) + { + ZPOS64_T read_this = SIZEDATA_INDATABLOCK; + if (read_this > size_central_dir_to_read) + read_this = size_central_dir_to_read; + + if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) + err=ZIP_ERRNO; + + if (err==ZIP_OK) + err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); + + size_central_dir_to_read-=read_this; + } + TRYFREE(buf_read); + } + pziinit->begin_pos = byte_before_the_zipfile; + pziinit->number_entry = number_entry_CD; + + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) + err=ZIP_ERRNO; + + return err; +} + + +#endif /* !NO_ADDFILEINEXISTINGZIP*/ + + +/************************************************************/ +extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) +{ + zip64_internal ziinit; + zip64_internal* zi; + int err=ZIP_OK; + + ziinit.z_filefunc.zseek32_file = NULL; + ziinit.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def==NULL) + fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); + else + ziinit.z_filefunc = *pzlib_filefunc64_32_def; + + ziinit.filestream = ZOPEN64(ziinit.z_filefunc, + pathname, + (append == APPEND_STATUS_CREATE) ? + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : + (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); + + if (ziinit.filestream == NULL) + return NULL; + + if (append == APPEND_STATUS_CREATEAFTER) + ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); + + ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); + ziinit.in_opened_file_inzip = 0; + ziinit.ci.stream_initialised = 0; + ziinit.number_entry = 0; + ziinit.add_position_when_writting_offset = 0; + init_linkedlist(&(ziinit.central_dir)); + + + + zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); + if (zi==NULL) + { + ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); + return NULL; + } + + /* now we add file in a zipfile */ +# ifndef NO_ADDFILEINEXISTINGZIP + ziinit.globalcomment = NULL; + if (append == APPEND_STATUS_ADDINZIP) + { + // Read and Cache Central Directory Records + err = LoadCentralDirectoryRecord(&ziinit); + } + + if (globalcomment) + { + *globalcomment = ziinit.globalcomment; + } +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + + if (err != ZIP_OK) + { +# ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(ziinit.globalcomment); +# endif /* !NO_ADDFILEINEXISTINGZIP*/ + TRYFREE(zi); + return NULL; + } + else + { + *zi = ziinit; + return (zipFile)zi; + } +} + +extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) +{ + if (pzlib_filefunc32_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + +extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) +{ + if (pzlib_filefunc_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; + zlib_filefunc64_32_def_fill.ztell32_file = NULL; + zlib_filefunc64_32_def_fill.zseek32_file = NULL; + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); +} + + + +extern zipFile ZEXPORT zipOpen (const char* pathname, int append) +{ + return zipOpen3((const void*)pathname,append,NULL,NULL); +} + +extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) +{ + return zipOpen3(pathname,append,NULL,NULL); +} + +int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) +{ + /* write the local header */ + int err; + uInt size_filename = (uInt)strlen(filename); + uInt size_extrafield = size_extrafield_local; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); + + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); + + // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ + } + if (err==ZIP_OK) + { + if(zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); + + if(zi->ci.zip64) + { + size_extrafield += 20; + } + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); + + if ((err==ZIP_OK) && (size_filename > 0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) + err = ZIP_ERRNO; + } + + if ((err==ZIP_OK) && (size_extrafield_local > 0)) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) + err = ZIP_ERRNO; + } + + + if ((err==ZIP_OK) && (zi->ci.zip64)) + { + // write the Zip64 extended info + short HeaderID = 1; + short DataSize = 16; + ZPOS64_T CompressedSize = 0; + ZPOS64_T UncompressedSize = 0; + + // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) + zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); + + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); + } + + return err; +} + +/* + NOTE. + When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped + before calling this function it can be done with zipRemoveExtraInfoBlock + + It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize + unnecessary allocations. + */ +extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase, int zip64) +{ + zip64_internal* zi; + uInt size_filename; + uInt size_comment; + uInt i; + int err = ZIP_OK; + +# ifdef NOCRYPT + if (password != NULL) + return ZIP_PARAMERROR; +# endif + + if (file == NULL) + return ZIP_PARAMERROR; + +#ifdef HAVE_BZIP2 + if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) + return ZIP_PARAMERROR; +#else + if ((method!=0) && (method!=Z_DEFLATED)) + return ZIP_PARAMERROR; +#endif + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + if (err != ZIP_OK) + return err; + } + + if (filename==NULL) + filename="-"; + + if (comment==NULL) + size_comment = 0; + else + size_comment = (uInt)strlen(comment); + + size_filename = (uInt)strlen(filename); + + if (zipfi == NULL) + zi->ci.dosDate = 0; + else + { + if (zipfi->dosDate != 0) + zi->ci.dosDate = zipfi->dosDate; + else + zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); + } + + zi->ci.flag = flagBase; + if ((level==8) || (level==9)) + zi->ci.flag |= 2; + if ((level==2)) + zi->ci.flag |= 4; + if ((level==1)) + zi->ci.flag |= 6; + if (password != NULL) + zi->ci.flag |= 1; + + zi->ci.crc32 = 0; + zi->ci.method = method; + zi->ci.encrypt = 0; + zi->ci.stream_initialised = 0; + zi->ci.pos_in_buffered_data = 0; + zi->ci.raw = raw; + zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); + + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; + zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data + + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); + + zi->ci.size_centralExtra = size_extrafield_global; + zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); + /* version info */ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); + zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); + zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); + zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); + zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ + zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ + zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); + zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); + zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); + else + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); + + if (zipfi==NULL) + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); + + if(zi->ci.pos_local_header >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); + else + zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); + + for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = + *(((const char*)extrafield_global)+i); + + for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ + size_extrafield_global+i) = *(comment+i); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; + + zi->ci.zip64 = zip64; + zi->ci.totalCompressedData = 0; + zi->ci.totalUncompressedData = 0; + zi->ci.pos_zip64extrainfo = 0; + + err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); + +#ifdef HAVE_BZIP2 + zi->ci.bstream.avail_in = (uInt)0; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + zi->ci.bstream.total_in_hi32 = 0; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_out_hi32 = 0; + zi->ci.bstream.total_out_lo32 = 0; +#endif + + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + zi->ci.stream.total_in = 0; + zi->ci.stream.total_out = 0; + zi->ci.stream.data_type = Z_BINARY; + +#ifdef HAVE_BZIP2 + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) +#else + if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) +#endif + { + if(zi->ci.method == Z_DEFLATED) + { + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)0; + + if (windowBits>0) + windowBits = -windowBits; + + err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); + + if (err==Z_OK) + zi->ci.stream_initialised = Z_DEFLATED; + } + else if(zi->ci.method == Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + // Init BZip stuff here + zi->ci.bstream.bzalloc = 0; + zi->ci.bstream.bzfree = 0; + zi->ci.bstream.opaque = (voidpf)0; + + err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); + if(err == BZ_OK) + zi->ci.stream_initialised = Z_BZIP2ED; +#endif + } + + } + +# ifndef NOCRYPT + zi->ci.crypt_header_size = 0; + if ((err==Z_OK) && (password != NULL)) + { + unsigned char bufHead[RAND_HEAD_LEN]; + unsigned int sizeHead; + zi->ci.encrypt = 1; + zi->ci.pcrc_32_tab = get_crc_table(); + /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ + + sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); + zi->ci.crypt_header_size = sizeHead; + + if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) + err = ZIP_ERRNO; + } +# endif + + if (err==Z_OK) + zi->in_opened_file_inzip = 1; + return err; +} + +extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, versionMadeBy, flagBase, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits,int memLevel, int strategy, + const char* password, uLong crcForCrypting, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int zip64) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); +} + +extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void*extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level) +{ + return zipOpenNewFileInZip4_64 (file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); +} + +local int zip64FlushWriteBuffer(zip64_internal* zi) +{ + int err=ZIP_OK; + + if (zi->ci.encrypt != 0) + { +#ifndef NOCRYPT + uInt i; + int t; + for (i=0;ici.pos_in_buffered_data;i++) + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); +#endif + } + + if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) + err = ZIP_ERRNO; + + zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED) + { + zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_in_hi32 = 0; + } + else +#endif + { + zi->ci.totalUncompressedData += zi->ci.stream.total_in; + zi->ci.stream.total_in = 0; + } + + + zi->ci.pos_in_buffered_data = 0; + + return err; +} + +extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) +{ + zip64_internal* zi; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + + zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); + +#ifdef HAVE_BZIP2 + if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) + { + zi->ci.bstream.next_in = (void*)buf; + zi->ci.bstream.avail_in = len; + err = BZ_RUN_OK; + + while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) + { + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + + + if(err != BZ_RUN_OK) + break; + + if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; +// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; + } + } + + if(err == BZ_RUN_OK) + err = ZIP_OK; + } + else +#endif + { + zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.avail_in = len; + + while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + + + if(err != ZIP_OK) + break; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_NO_FLUSH); + if(uTotalOutBefore > zi->ci.stream.total_out) + { + int bBreak = 0; + bBreak++; + } + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + else + { + uInt copy_this,i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; + + for (i = 0; i < copy_this; i++) + *(((char*)zi->ci.stream.next_out)+i) = + *(((const char*)zi->ci.stream.next_in)+i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out-= copy_this; + zi->ci.stream.next_in+= copy_this; + zi->ci.stream.next_out+= copy_this; + zi->ci.stream.total_in+= copy_this; + zi->ci.stream.total_out+= copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + }// while(...) + } + + return err; +} + +extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) +{ + return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); +} + +extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) +{ + zip64_internal* zi; + ZPOS64_T compressed_size; + uLong invalidValue = 0xffffffff; + short datasize = 0; + int err=ZIP_OK; + + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + zi->ci.stream.avail_in = 0; + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + while (err==ZIP_OK) + { + uLong uTotalOutBefore; + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.stream.total_out; + err=deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; + } + } + else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { +#ifdef HAVE_BZIP2 + err = BZ_FINISH_OK; + while (err==BZ_FINISH_OK) + { + uLong uTotalOutBefore; + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.bstream.total_out_lo32; + err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); + if(err == BZ_STREAM_END) + err = Z_STREAM_END; + + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); + } + + if(err == BZ_FINISH_OK) + err = ZIP_OK; +#endif + } + + if (err==Z_STREAM_END) + err=ZIP_OK; /* this is normal */ + + if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) + { + if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) + err = ZIP_ERRNO; + } + + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + int tmp_err = deflateEnd(&zi->ci.stream); + if (err == ZIP_OK) + err = tmp_err; + zi->ci.stream_initialised = 0; + } +#ifdef HAVE_BZIP2 + else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); + if (err==ZIP_OK) + err = tmperr; + zi->ci.stream_initialised = 0; + } +#endif + + if (!zi->ci.raw) + { + crc32 = (uLong)zi->ci.crc32; + uncompressed_size = zi->ci.totalUncompressedData; + } + compressed_size = zi->ci.totalCompressedData; + +# ifndef NOCRYPT + compressed_size += zi->ci.crypt_header_size; +# endif + + // update Current Item crc and sizes, + if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) + { + /*version Made by*/ + zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); + /*version needed*/ + zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); + + } + + zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ + + + if(compressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ + + /// set internal file attributes field + if (zi->ci.stream.data_type == Z_ASCII) + zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); + + if(uncompressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ + + // Add ZIP64 extra info field for uncompressed size + if(uncompressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for compressed size + if(compressed_size >= 0xffffffff) + datasize += 8; + + // Add ZIP64 extra info field for relative offset to local file header of current file + if(zi->ci.pos_local_header >= 0xffffffff) + datasize += 8; + + if(datasize > 0) + { + char* p = NULL; + + if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) + { + // we can not write more data to the buffer that we have room for. + return ZIP_BADZIPFILE; + } + + p = zi->ci.central_header + zi->ci.size_centralheader; + + // Add Extra Information Header for 'ZIP64 information' + zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID + p += 2; + zip64local_putValue_inmemory(p, datasize, 2); // DataSize + p += 2; + + if(uncompressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, uncompressed_size, 8); + p += 8; + } + + if(compressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, compressed_size, 8); + p += 8; + } + + if(zi->ci.pos_local_header >= 0xffffffff) + { + zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); + p += 8; + } + + // Update how much extra free space we got in the memory buffer + // and increase the centralheader size so the new ZIP64 fields are included + // ( 4 below is the size of HeaderID and DataSize field ) + zi->ci.size_centralExtraFree -= datasize + 4; + zi->ci.size_centralheader += datasize + 4; + + // Update the extra info size field + zi->ci.size_centralExtra += datasize + 4; + zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); + } + + if (err==ZIP_OK) + err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); + + free(zi->ci.central_header); + + if (err==ZIP_OK) + { + // Update the LocalFileHeader with the new values. + + ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ + + if(uncompressed_size >= 0xffffffff) + { + if(zi->ci.pos_zip64extrainfo > 0) + { + // Update the size in the ZIP64 extended field. + if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); + } + } + else + { + if (err==ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); + + if (err==ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); + } + + if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) + err = ZIP_ERRNO; + } + + zi->number_entry ++; + zi->in_opened_file_inzip = 0; + + return err; +} + +extern int ZEXPORT zipCloseFileInZip (zipFile file) +{ + return zipCloseFileInZipRaw (file,0,0); +} + +int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) +{ + int err = ZIP_OK; + ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); + + /*num disks*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + /*relative offset*/ + if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); + + /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); + + return err; +} + +int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + uLong Zip64DataSize = 44; + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? + + if (err==ZIP_OK) /* version made by */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* version needed */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* total number of entries in the central dir */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); + } + return err; +} +int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) +{ + int err = ZIP_OK; + + /*signature*/ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); + + if (err==ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + + if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ + { + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + } + + if (err==ZIP_OK) /* total number of entries in the central dir */ + { + if(zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); + } + + if (err==ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); + + if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff) + { + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); + } + else + err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); + } + + return err; +} + +int Write_GlobalComment(zip64_internal* zi, const char* global_comment) +{ + int err = ZIP_OK; + uInt size_global_comment = 0; + + if(global_comment != NULL) + size_global_comment = (uInt)strlen(global_comment); + + err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); + + if (err == ZIP_OK && size_global_comment > 0) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) + err = ZIP_ERRNO; + } + return err; +} + +extern int ZEXPORT zipClose (zipFile file, const char* global_comment) +{ + zip64_internal* zi; + int err = 0; + uLong size_centraldir = 0; + ZPOS64_T centraldir_pos_inzip; + ZPOS64_T pos; + + if (file == NULL) + return ZIP_PARAMERROR; + + zi = (zip64_internal*)file; + + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip (file); + } + +#ifndef NO_ADDFILEINEXISTINGZIP + if (global_comment==NULL) + global_comment = zi->globalcomment; +#endif + + centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + + if (err==ZIP_OK) + { + linkedlist_datablock_internal* ldi = zi->central_dir.first_block; + while (ldi!=NULL) + { + if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) + { + if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) + err = ZIP_ERRNO; + } + + size_centraldir += ldi->filled_in_this_block; + ldi = ldi->next_datablock; + } + } + free_linkedlist(&(zi->central_dir)); + + pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if(pos >= 0xffffffff) + { + ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); + Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); + } + + if (err==ZIP_OK) + err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + + if(err == ZIP_OK) + err = Write_GlobalComment(zi, global_comment); + + if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) + if (err == ZIP_OK) + err = ZIP_ERRNO; + +#ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(zi->globalcomment); +#endif + TRYFREE(zi); + + return err; +} + +extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) +{ + char* p = pData; + int size = 0; + char* pNewHeader; + char* pTmp; + short header; + short dataSize; + + int retVal = ZIP_OK; + + if(pData == NULL || *dataLen < 4) + return ZIP_PARAMERROR; + + pNewHeader = (char*)ALLOC(*dataLen); + pTmp = pNewHeader; + + while(p < (pData + *dataLen)) + { + header = *(short*)p; + dataSize = *(((short*)p)+1); + + if( header == sHeader ) // Header found. + { + p += dataSize + 4; // skip it. do not copy to temp buffer + } + else + { + // Extra Info block should not be removed, So copy it to the temp buffer. + memcpy(pTmp, p, dataSize + 4); + p += dataSize + 4; + size += dataSize + 4; + } + + } + + if(size < *dataLen) + { + // clean old extra info block. + memset(pData,0, *dataLen); + + // copy the new extra info block over the old + if(size > 0) + memcpy(pData, pNewHeader, size); + + // set the new extra info size + *dataLen = size; + + retVal = ZIP_OK; + } + else + retVal = ZIP_ERRNO; + + TRYFREE(pNewHeader); + + return retVal; +} diff --git a/plugins/FTPFileYM/zip/zip.h b/plugins/FTPFileYM/zip/zip.h new file mode 100644 index 0000000000..8aaebb6234 --- /dev/null +++ b/plugins/FTPFileYM/zip/zip.h @@ -0,0 +1,362 @@ +/* zip.h -- IO on .zip files using zlib + Version 1.1, February 14h, 2010 + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + --------------------------------------------------------------------------- + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + --------------------------------------------------------------------------- + + Changes + + See header of zip.h + +*/ + +#ifndef _zip12_H +#define _zip12_H + +#ifdef __cplusplus +extern "C" { +#endif + +//#define HAVE_BZIP2 + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#ifdef HAVE_BZIP2 +#include "bzlib.h" +#endif + +#define Z_BZIP2ED 12 + +#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagzipFile__ { int unused; } zipFile__; +typedef zipFile__ *zipFile; +#else +typedef voidp zipFile; +#endif + +#define ZIP_OK (0) +#define ZIP_EOF (0) +#define ZIP_ERRNO (Z_ERRNO) +#define ZIP_PARAMERROR (-102) +#define ZIP_BADZIPFILE (-103) +#define ZIP_INTERNALERROR (-104) + +#ifndef DEF_MEM_LEVEL +# if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +# else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +# endif +#endif +/* default memLevel */ + +/* tm_zip contain date/time info */ +typedef struct tm_zip_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_zip; + +typedef struct +{ + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ +/* uLong flag; */ /* general purpose bit flag 2 bytes */ + + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ +} zip_fileinfo; + +typedef const char* zipcharpc; + + +#define APPEND_STATUS_CREATE (0) +#define APPEND_STATUS_CREATEAFTER (1) +#define APPEND_STATUS_ADDINZIP (2) + +extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); +extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); +/* + Create a zipfile. + pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on + an Unix computer "zlib/zlib113.zip". + if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip + will be created at the end of the file. + (useful if the file contain a self extractor code) + if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will + add files in existing zip (be sure you don't add file that doesn't exist) + If the zipfile cannot be opened, the return value is NULL. + Else, the return value is a zipFile Handle, usable with other function + of this zip package. +*/ + +/* Note : there is no delete function into a zipfile. + If you want delete file into a zipfile, you must open a zipfile, and create another + Of couse, you can use RAW reading and writing to copy the file you did not want delte +*/ + +extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def)); + +extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc64_def* pzlib_filefunc_def)); + +extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level)); + +extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int zip64)); + +/* + Open a file in the ZIP for writing. + filename : the filename in zip (if NULL, '-' without quote will be used + *zipfi contain supplemental information + if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local + contains the extrafield data the the local header + if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global + contains the extrafield data the the local header + if comment != NULL, comment contain the comment string + method contain the compression method (0 for store, Z_DEFLATED for deflate) + level contain the level of compression (can be Z_DEFAULT_COMPRESSION) + zip64 is set to 1 if a zip64 extended information block should be added to the local file header. + this MUST be '1' if the uncompressed size is >= 0xffffffff. + +*/ + + +extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw)); + + +extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int zip64)); +/* + Same than zipOpenNewFileInZip, except if raw=1, we write raw file + */ + +extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting)); + +extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + int zip64 + )); + +/* + Same than zipOpenNewFileInZip2, except + windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 + password : crypting password (NULL for no crypting) + crcForCrypting : crc of file to compress (needed for crypting) + */ + +extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase + )); + + +extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase, + int zip64 + )); +/* + Same than zipOpenNewFileInZip4, except + versionMadeBy : value for Version made by field + flag : value for flag field (compression level info will be added) + */ + + +extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, + const void* buf, + unsigned len)); +/* + Write data in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); +/* + Close the current file in the zipfile +*/ + +extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, + uLong uncompressed_size, + uLong crc32)); + +extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, + ZPOS64_T uncompressed_size, + uLong crc32)); + +/* + Close the current file in the zipfile, for file opened with + parameter raw=1 in zipOpenNewFileInZip2 + uncompressed_size and crc32 are value for the uncompressed size +*/ + +extern int ZEXPORT zipClose OF((zipFile file, + const char* global_comment)); +/* + Close the zipfile +*/ + + +extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); +/* + zipRemoveExtraInfoBlock - Added by Mathias Svensson + + Remove extra information block from a extra information data for the local file header or central directory header + + It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode. + + 0x0001 is the signature header for the ZIP64 extra information blocks + + usage. + Remove ZIP64 Extra information from a central director extra field data + zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001); + + Remove ZIP64 Extra information from a Local File Header extra field data + zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001); +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _zip64_H */ diff --git a/plugins/FTPFileYM/zip/zlib.h b/plugins/FTPFileYM/zip/zlib.h new file mode 100644 index 0000000000..f5785be7e0 --- /dev/null +++ b/plugins/FTPFileYM/zip/zlib.h @@ -0,0 +1,1605 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.4, Mar 14th, 2010 + + Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.4" +#define ZLIB_VERNUM 0x1240 +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 4 +#define ZLIB_VER_SUBREVISION 0 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip streams in memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used + when writing a gzip file) */ +} gz_header; + +typedef gz_header FAR *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this if + the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers + returned by zalloc for objects of exactly 65536 bytes *must* have their + offset normalized to zero. The default allocation function provided by this + library ensures this (see zutil.c). To reduce memory requirements and avoid + any allocation of 64K objects, at the expense of compression ratio, compile + the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use in the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to Z_NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). Some + output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed code + block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the stream + are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least the + value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered + binary. This field is only for information purposes and does not affect the + compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the + exact value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit() does not process any header information -- that is deferred + until inflate() is called. +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing will + resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all the uncompressed data. (The size + of the uncompressed data may have been saved by the compressor for this + purpose.) The next operation on this stream must be inflateEnd to deallocate + the decompression state. The use of Z_FINISH is never required, but can be + used to inform inflate that a faster approach may be used for the single + inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK or Z_TREES is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained, so applications that need that information should + instead use raw inflate, see inflateInit2() below, or inflateBack() and + perform their own processing of the gzip header and trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by the + caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to 255 (unknown). If a + gzip stream is being written, strm->adler is a crc32 instead of an adler32. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any call + of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. The + stream will keep the same compression level and any other attributes that + may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression level is changed, the input available so far is + compressed with the old level (and may be flushed); the new level will take + effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to be + compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if + strm->avail_out was zero. +*/ + +ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not Z_NULL, name and comment are terminated with + a zero byte, and that if extra is not Z_NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been + found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the + success case, the application may save the current current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being Z_NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL). +*/ + +ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being Z_NULL), or if + the windowBits parameter is invalid. +*/ + +ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above or -1 << 16 if the provided + source stream state was inconsistent. +*/ + +ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not Z_NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not Z_NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not Z_NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not Z_NULL and the respective field is not + present in the header, then that field is set to Z_NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the normal + behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be Z_NULL only if in() returned an error. If + strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed buffer. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef voidp gzFile; /* opaque gzip file descriptor */ + +/* +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); + + Opens a gzip (.gz) file for reading or writing. The mode parameter is as + in fopen ("rb" or "wb") but can also include a compression level ("wb9") or + a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only + compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' + for fixed code compression as in "wb9F". (See the description of + deflateInit2 for more information about the strategy parameter.) Also "a" + can be used instead of "w" to request that the gzip stream that will be + written be appended to the file. "+" will result in an error, since reading + and writing to the same gzip file is not supported. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen associates a gzFile with the file descriptor fd. File descriptors + are obtained from calls like open, dup, creat, pipe or fileno (if the file + has been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +/* + Set the internal buffer size used by this library's functions. The + default buffer size is 8192 bytes. This function must be called after + gzopen() or gzdopen(), and before any other calls that read or write the + file. The buffer memory allocation is always deferred to the first read or + write. Two buffers are allocated, either both of the specified size when + writing, or one of the specified size and the other twice that size when + reading. A larger buffer size of, for example, 64K or 128K bytes will + noticeably increase the speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. If + the input file was not in gzip format, gzread copies the given number of + bytes into the buffer. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream, or failing that, reading the rest + of the input file directly without decompression. The entire input file + will be read if gzread is called until it returns less than the requested + len. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. +*/ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes written or 0 in case of + error. +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the arguments to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or 0 in case of error. The number of + uncompressed bytes written is limited to 8191, or one less than the buffer + size given to gzbuffer(). The caller should assure that this limit is not + exceeded. If it is exceeded, then gzprintf() will return an error (0) with + nothing written. In this case, there may also be a buffer overflow with + unpredictable consequences, which is possible only if zlib was compiled with + the insecure functions sprintf() or vsprintf() because the secure snprintf() + or vsnprintf() functions were not available. This can be determined using + zlibCompileFlags(). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or a + newline character is read and transferred to buf, or an end-of-file + condition is encountered. If any characters are read or if len == 1, the + string is terminated with a null character. If no characters are read due + to an end-of-file or len < 1, then the buffer is left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte or -1 + in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read as the first character + on the next read. At least one character of push-back is allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter flush + is as in the deflate() function. The return value is the zlib error number + (see function gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatented gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); + + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); + + Returns the starting position for the next gzread or gzwrite on the given + compressed file. This position represents a number of bytes in the + uncompressed data stream, and is zero when starting, even if appending or + reading a gzip stream from the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); + + Returns the current offset in the file being read or written. This offset + includes the count of bytes that precede the gzip stream, for example when + appending or when using gzdopen() for reading. When reading, the offset + does not include as yet unused buffered input. This information can be used + for a progress indicator. On error, gzoffset() returns -1. +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns true (1) if the end-of-file indicator has been set while reading, + false (0) otherwise. Note that the end-of-file indicator is set only if the + read tried to go past the end of the input, but came up short. Therefore, + just like feof(), gzeof() may return false even if there is no more data to + read, in the event that the last read request was for the exact number of + bytes remaining in the input file. This will happen if the input file size + is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +/* + Returns true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. This state can change from + false to true while reading the input file if the end of a gzip stream is + reached, but is followed by data that is not another gzip stream. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file and + deallocates the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, or Z_OK on success. +*/ + +ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the given + compressed file. errnum is set to zlib error number. If an error occurred + in the file system and not in the compression library, errnum is set to + Z_ERRNO and the application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is Z_NULL, this function returns the + required initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. + + Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, + z_off_t len2)); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. If buf is Z_NULL, this function returns the required + initial value for the for the crc. Pre- and post-conditioning (one's + complement) is performed within this function so it shouldn't be done by the + application. + + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +/* +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + +#ifdef _LARGEFILE64_SOURCE + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN off64_t ZEXPORT gzseek64 OF((gzFile, off64_t, int)); + ZEXTERN off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, off64_t)); +#endif + +#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS == 64 +# define gzopen gzopen64 +# define gzseek gzseek64 +# define gztell gztell64 +# define gzoffset gzoffset64 +# define adler32_combine adler32_combine64 +# define crc32_combine crc32_combine64 +# ifndef _LARGEFILE64_SOURCE + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN off_t ZEXPORT gzseek64 OF((gzFile, off_t, int)); + ZEXTERN off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, off_t)); +# endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#endif + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); +ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/plugins/SendScreenshotPlus/CSend.cpp b/plugins/SendScreenshotPlus/CSend.cpp new file mode 100644 index 0000000000..4e48ecb2b4 --- /dev/null +++ b/plugins/SendScreenshotPlus/CSend.cpp @@ -0,0 +1,416 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSend.cpp $ +Revision : $Revision: 19 $ +Last change on : $Date: 2010-04-09 03:24:04 +0400 (РџС‚, 09 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#include "CSend.h" + +//--------------------------------------------------------------------------- +CSend::CSend(HWND Owner, HANDLE hContact, bool bFreeOnExit) { + m_hWndO = Owner; + m_bFreeOnExit = bFreeOnExit; + m_pszFile = NULL; + m_pszFileDesc = NULL; + m_pszProto = NULL; + m_ChatRoom = NULL; + m_PFflag = NULL; + m_hContact = NULL; + if (hContact) SetContact(hContact); + m_hOnSend = NULL; + m_szEventMsg = NULL; + m_szEventMsgT = NULL; + m_pszSendTyp = NULL; + + m_ErrorMsg = NULL; + m_ErrorTitle = NULL; +} + +CSend::~CSend(){ + mir_free(m_pszFile); + mir_free(m_pszFileDesc); + mir_free(m_szEventMsg); + mir_free(m_szEventMsgT); + mir_free(m_ErrorMsg); + mir_free(m_ErrorTitle); + if (m_hOnSend) UnhookEvent(m_hOnSend); +} + +//--------------------------------------------------------------------------- +void CSend::SetContact(HANDLE hContact) { + m_hContact = hContact; + m_pszProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); + m_ChatRoom = DBGetContactSettingByte(hContact, m_pszProto, "ChatRoom", 0); + m_PFflag = hasCap(PF1_URLSEND); + m_PFflag = hasCap(PF1_CHAT); + m_PFflag = hasCap(PF1_IMSEND); +} + +//--------------------------------------------------------------------------- +bool CSend::hasCap(unsigned int Flag) { + return (Flag & CallContactService(m_hContact, PS_GETCAPS, (WPARAM)PFLAGNUM_1, NULL)) == Flag; +} + +//--------------------------------------------------------------------------- +void CSend::svcSendMsg(const char* szMessage) { + mir_freeAndNil(m_szEventMsg); + m_cbEventMsg=lstrlenA(szMessage)+1; + m_szEventMsg=(char*)mir_realloc(m_szEventMsg, sizeof(char)*m_cbEventMsg); + ZeroMemory(m_szEventMsg, m_cbEventMsg); + lstrcpyA(m_szEventMsg,szMessage); + if (m_pszFileDesc && m_pszFileDesc[0] != NULL) { + char *temp = mir_t2a(m_pszFileDesc); + mir_stradd(m_szEventMsg, "\r\n"); + mir_stradd(m_szEventMsg, temp); + m_cbEventMsg = lstrlenA(m_szEventMsg)+1; + mir_free(temp); + } + //create a HookEventObj on ME_PROTO_ACK + if (!m_hOnSend) { + int (__cdecl CSend::*hookProc)(WPARAM, LPARAM); + hookProc = &CSend::OnSend; + m_hOnSend = HookEventObj(ME_PROTO_ACK, (MIRANDAHOOKOBJ)*(void **)&hookProc, this); + } + //start PSS_MESSAGE service + m_hSend = (HANDLE)CallContactService(m_hContact, PSS_MESSAGE, NULL, (LPARAM)m_szEventMsg); + // check we actually got an ft handle back from the protocol + if (!m_hSend) { + Unhook(); + Error(SS_ERR_INIT, m_pszSendTyp); + Exit(ACKRESULT_FAILED); + } +} + +void CSend::svcSendUrl(const char* url) { +//szMessage should be encoded as the URL followed by the description, the +//separator being a single nul (\0). If there is no description, do not forget +//to end the URL with two nuls. + mir_freeAndNil(m_szEventMsg) + m_cbEventMsg=lstrlenA(url)+2; + m_szEventMsg=(char*)mir_realloc(m_szEventMsg, m_cbEventMsg); + ZeroMemory(m_szEventMsg, m_cbEventMsg); + lstrcpyA(m_szEventMsg,url); + if (m_pszFileDesc && m_pszFileDesc[0] != NULL) { + char *temp = mir_t2a(m_pszFileDesc); + m_cbEventMsg += lstrlenA(temp); + m_szEventMsg=(char*)mir_realloc(m_szEventMsg, sizeof(char)*m_cbEventMsg); + lstrcpyA(m_szEventMsg+lstrlenA(url)+1,temp); + m_szEventMsg[m_cbEventMsg-1] = 0; + mir_free(temp); + } + //create a HookEventObj on ME_PROTO_ACK + if (!m_hOnSend) { + int (__cdecl CSend::*hookProc)(WPARAM, LPARAM); + hookProc = &CSend::OnSend; + m_hOnSend = HookEventObj(ME_PROTO_ACK, (MIRANDAHOOKOBJ)*(void **)&hookProc, this); + } + //start PSS_URL service + m_hSend = (HANDLE)CallContactService(m_hContact, PSS_URL, NULL, (LPARAM)m_szEventMsg); + // check we actually got an ft handle back from the protocol + if (!m_hSend) { + //SetFtStatus(hwndDlg, LPGENT("Unable to initiate transfer."), FTS_TEXT); + //dat->waitingForAcceptance=0; + Unhook(); + } +} + +void CSend::svcSendChat() { + LPTSTR dirtyFix = NULL; + GC_INFO gci = {0}; + GCDEST gcd = {0}; + GCEVENT gce = {0}; + int res = GC_RESULT_NOSESSION; + int cnt = (int)CallService(MS_GC_GETSESSIONCOUNT, 0, (LPARAM)m_pszProto); + + //loop on all gc session to get the right (save) ptszID for the chatroom from m_hContact + gci.pszModule = m_pszProto; + for (int i = 0; i < cnt ; i++ ) { + gci.iItem = i; + gci.Flags = BYINDEX | HCONTACT | ID; //need dirty fix + CallService(MS_GC_GETINFO, 0, (LPARAM)(GC_INFO *) &gci); + if (gci.hContact == m_hContact) { + gcd.pszModule = m_pszProto; + gcd.iType = GC_EVENT_SENDMESSAGE; //GC_EVENT_MESSAGE ???; +#ifdef _UNICODE + gcd.ptszID = gci.pszID; +#else //dirty fix coz MS_GC_GETINFO dont know if caller is ansi or unicode. + //result from MS_GC_GETINFO only depend on type of chat.dll and not of caller type + if (mir_is_unicode()) { + dirtyFix = mir_u2t((wchar_t*)gci.pszID); + } + else { + dirtyFix = mir_tstrdup(gci.pszID); + } + gcd.ptszID = dirtyFix; //fixed gci.pszID; +#endif + gce.cbSize = sizeof(GCEVENT); + gce.pDest = &gcd; + gce.bIsMe = TRUE; + gce.dwFlags = GC_TCHAR|GCEF_ADDTOLOG; + gce.ptszText = m_szEventMsgT; + gce.time = time(NULL); + + //* returns 0 on success or error code on failure + res = 200 + (int)CallService(MS_GC_EVENT, 0, (LPARAM)(GCEVENT *) &gce); + mir_freeAndNil(dirtyFix); + break; + } + } + Exit(res); +} + +void CSend::svcSendChat(const char* szMessage) { + if (!m_ChatRoom) { + svcSendMsg(szMessage); + return; + } + mir_freeAndNil(m_szEventMsgT); + m_szEventMsgT = mir_a2t(szMessage); + if (m_pszFileDesc) { + mir_tcsadd(m_szEventMsgT, _T("\r\n")); + mir_tcsadd(m_szEventMsgT, m_pszFileDesc); + } + svcSendChat(); +} + +void CSend::svcSendFile() { +//szMessage should be encoded as the File followed by the description, the +//separator being a single nul (\0). If there is no description, do not forget +//to end the File with two nuls. + mir_freeAndNil(m_szEventMsg) + char *szFile = mir_t2a(m_pszFile); + m_cbEventMsg=lstrlenA(szFile)+2; + m_szEventMsg=(char*)mir_realloc(m_szEventMsg, sizeof(char)*m_cbEventMsg); + ZeroMemory(m_szEventMsg, m_cbEventMsg); + lstrcpyA(m_szEventMsg,szFile); + if (m_pszFileDesc && m_pszFileDesc[0] != NULL) { + char* temp = mir_t2a(m_pszFileDesc); + m_cbEventMsg += lstrlenA(temp); + m_szEventMsg=(char*)mir_realloc(m_szEventMsg, sizeof(char)*m_cbEventMsg); + lstrcpyA(m_szEventMsg+lstrlenA(szFile)+1,temp); + m_szEventMsg[m_cbEventMsg-1] = 0; + mir_freeAndNil(temp); + } + mir_freeAndNil(szFile); + + //create a HookEventObj on ME_PROTO_ACK + if (!m_hOnSend) { + int (__cdecl CSend::*hookProc)(WPARAM, LPARAM); + hookProc = &CSend::OnSend; + m_hOnSend = HookEventObj(ME_PROTO_ACK, (MIRANDAHOOKOBJ)*(void **)&hookProc, this); + } + // Start miranda PSS_FILE based on mir ver (T) + if ((CallService(MS_SYSTEM_GETVERSION,0,0) >= 0x090000) && mir_is_unicode()) { + TCHAR *ppFile[2]={0,0}; + TCHAR *pDesc = mir_tstrdup(m_pszFileDesc); + ppFile[0] = mir_tstrdup (m_pszFile); +/* #if defined( _UNICODE ) + TCHAR *ppFile[2]={0,0}; + TCHAR *pDesc = mir_tstrdup(m_pszFileDesc); + ppFile[0] = mir_tstrdup (m_pszFile); + #else + wchar_t *ppFile[2]={0,0}; + wchar_t *pDesc = mir_t2u (m_pszFileDesc); + ppFile[0] = mir_t2u (m_pszFile); + #endif */ + ppFile[1] = NULL; + m_hSend = (HANDLE)CallContactService(m_hContact, PSS_FILET, (WPARAM)pDesc, (LPARAM)ppFile); + mir_free(pDesc); + mir_free(ppFile[0]); + } + else { + char *pDesc = mir_t2a(m_pszFileDesc); + char *ppFile[2]={0}; + ppFile[0] = mir_t2a(m_pszFile); + ppFile[1] = NULL; + m_hSend = (HANDLE)CallContactService(m_hContact, PSS_FILE, (WPARAM)pDesc, (LPARAM)ppFile); + mir_free(pDesc); + mir_free(ppFile[0]); + } + // check we actually got an ft handle back from the protocol + if (!m_hSend) { + Unhook(); + Error(SS_ERR_INIT, m_pszSendTyp); + Exit(ACKRESULT_FAILED); + } +} + +//--------------------------------------------------------------------------- +int __cdecl CSend::OnSend(WPARAM wParam, LPARAM lParam){ + ACKDATA *ack=(ACKDATA*)lParam; + if(ack->hProcess!= m_hSend) return 0; + /* if(dat->waitingForAcceptance) { + SetTimer(hwndDlg,1,1000,NULL); + dat->waitingForAcceptance=0; + } + */ + + switch(ack->result) { + case ACKRESULT_INITIALISING: //SetFtStatus(hwndDlg, LPGENT("Initialising..."), FTS_TEXT); break; + case ACKRESULT_CONNECTING: //SetFtStatus(hwndDlg, LPGENT("Connecting..."), FTS_TEXT); break; + case ACKRESULT_CONNECTPROXY: //SetFtStatus(hwndDlg, LPGENT("Connecting to proxy..."), FTS_TEXT); break; + case ACKRESULT_LISTENING: //SetFtStatus(hwndDlg, LPGENT("Waiting for connection..."), FTS_TEXT); break; + case ACKRESULT_CONNECTED: //SetFtStatus(hwndDlg, LPGENT("Connected"), FTS_TEXT); break; + case ACKRESULT_SENTREQUEST: //SetFtStatus(hwndDlg, LPGENT("Decision sent"), FTS_TEXT); break; + case ACKRESULT_NEXTFILE: //SetFtStatus(hwndDlg, LPGENT("Moving to next file..."), FTS_TEXT); + case ACKRESULT_FILERESUME: // + case ACKRESULT_DATA: //transfer is on progress + break; + case ACKRESULT_DENIED: + Unhook(); + Exit(ack->result); + break; + case ACKRESULT_FAILED: + Unhook(); + Exit(ack->result); + //type=ACKTYPE_MESSAGE, result=success/failure, (char*)lParam=error message or NULL. + //type=ACKTYPE_URL, result=success/failure, (char*)lParam=error message or NULL. + //type=ACKTYPE_FILE, result=ACKRESULT_FAILED then lParam=(LPARAM)(const char*)szReason + break; + case ACKRESULT_SUCCESS: + Unhook(); + switch(ack->type) { + case ACKTYPE_CHAT: + break; + case ACKTYPE_MESSAGE: + DB_EventAdd((WORD)EVENTTYPE_MESSAGE); + break; + case ACKTYPE_URL: + DB_EventAdd((WORD)EVENTTYPE_URL); + break; + case ACKTYPE_FILE: + //MS_DB_EVENT_ADD need 4byte extra at the beginning of m_szEventMsg for ACKTYPE_FILE + m_szEventMsg = (char*) mir_realloc(m_szEventMsg, sizeof(DWORD) + m_cbEventMsg); + //memmove_s(m_szEventMsg+sizeof(DWORD), m_cbEventMsg, m_szEventMsg, m_cbEventMsg); + memmove(m_szEventMsg+sizeof(DWORD), m_szEventMsg, m_cbEventMsg); + m_cbEventMsg += sizeof(DWORD); + DB_EventAdd((WORD)EVENTTYPE_FILE); + break; + default: + break; + } + Exit(ack->result); + break; + default: + return 0; + break; + } + return 0; +} + +void CSend::DB_EventAdd(WORD EventType) { + DBEVENTINFO dbei={0}; + dbei.cbSize = sizeof(dbei); + dbei.szModule = m_pszProto; + dbei.eventType = EventType; + dbei.flags = DBEF_SENT; + dbei.timestamp = time(NULL); + #if defined( _UNICODE ) + dbei.flags |= DBEF_UTF; + #endif + dbei.cbBlob= m_cbEventMsg; + dbei.pBlob=(PBYTE)m_szEventMsg; + + CallService(MS_DB_EVENT_ADD,(WPARAM)m_hContact,(LPARAM)&dbei); +} + +//--------------------------------------------------------------------------- +void CSend::AfterSendDelete() { + if (m_pszFile && m_bDeleteAfterSend && (m_EnableItem & SS_DLG_DELETEAFTERSSEND) == SS_DLG_DELETEAFTERSSEND) { + DeleteFile(m_pszFile); + } +} + +//--------------------------------------------------------------------------- +void CSend::Exit(unsigned int Result) { + bool err = true; + if (m_hWndO && IsWindow(m_hWndO)){ + ; + } + switch(Result) { + case ACKRESULT_SUCCESS: + case GC_RESULT_SUCCESS: + SkinPlaySound("FileDone"); + err = false; + break; + case ACKRESULT_DENIED: + SkinPlaySound("FileDenied"); + Error(_T("%s (%i):\nFile transfer denied."),TranslateTS(m_pszSendTyp),Result); + MsgBoxService(NULL, (LPARAM)&m_box); + err = false; + break; + case GC_RESULT_WRONGVER: //.You appear to be using the wrong version of GC API. + Error(_T("%s (%i):\nYou appear to be using the wrong version of GC API"),TranslateT("GCHAT error"),Result); + break; + case GC_RESULT_ERROR: // An internal GC error occurred. + Error(_T("%s (%i):\nAn internal GC error occurred."),TranslateT("GCHAT error"),Result); + break; + case GC_RESULT_NOSESSION: // contact has no open GC session + Error(_T("%s (%i):\nContact has no open GC session."),TranslateT("GCHAT error"),Result); + break; + case ACKRESULT_FAILED: + default: + break; + } + if (err){ + SkinPlaySound("FileFailed"); + if(m_ErrorMsg && m_ErrorMsg[0] != 0) MsgBoxService(NULL, (LPARAM)&m_box); + else MsgErr(NULL, LPGENT("An unknown error has occured.")); + } + + AfterSendDelete(); + if(m_bFreeOnExit) delete this; +} + +void CSend::Error(LPCTSTR pszFormat, ...) { + if(!pszFormat) return; + + TCHAR tszTemp[MAX_SECONDLINE]; + va_list vl; + + mir_sntprintf(tszTemp, SIZEOF(tszTemp),_T("%s - %s") ,_T(MODNAME), TranslateT("Error")); + mir_freeAndNil(m_ErrorTitle); + m_ErrorTitle = mir_tstrdup(tszTemp); + + va_start(vl, pszFormat); + mir_vsntprintf(tszTemp, SIZEOF(tszTemp), TranslateTS(pszFormat), vl); + va_end(vl); + mir_freeAndNil(m_ErrorMsg); + m_ErrorMsg = mir_tstrdup(tszTemp); + + ZeroMemory(&m_box, sizeof(m_box)); + m_box.cbSize = sizeof(MSGBOX); + m_box.hParent = NULL; + m_box.hiLogo = IcoLib_GetIcon(ICO_PLUG_SSWINDOW1); + m_box.hiMsg = NULL; + m_box.ptszTitle = m_ErrorTitle; + m_box.ptszMsg = m_ErrorMsg; + m_box.uType = MB_OK|MB_ICON_ERROR; +} + diff --git a/plugins/SendScreenshotPlus/CSend.h b/plugins/SendScreenshotPlus/CSend.h new file mode 100644 index 0000000000..082f3e961a --- /dev/null +++ b/plugins/SendScreenshotPlus/CSend.h @@ -0,0 +1,113 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSend.h $ +Revision : $Revision: 17 $ +Last change on : $Date: 2010-04-03 18:01:11 +0400 (РЎР±, 03 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef _CSEND_H +#define _CSEND_H + +//--------------------------------------------------------------------------- +#include "global.h" +#include "Utils.h" +#include "dlg_msgbox.h" + + +//--------------------------------------------------------------------------- +#define SS_AUTOSEND 1 +#define SS_DELETEAFTERSSEND 2 + +#define SS_DLG_AUTOSEND 1 //Button_Enable(GetDlgItem(Owner, ID_chkEmulateClick), TRUE); +#define SS_DLG_DELETEAFTERSSEND 2 //Button_Enable(GetDlgItem(Owner, ID_btnDeleteAfterSend), TRUE); +#define SS_DLG_DESCRIPTION 4 //Button_Enable(GetDlgItem(Owner, ID_btnDesc), TRUE); + +#define GC_RESULT_SUCCESS 200 +#define GC_RESULT_WRONGVER 201 +#define GC_RESULT_ERROR 202 +#define GC_RESULT_NOSESSION 209 + +#define SS_ERR_INIT _T("Unable to initiate %s.") +#define SS_ERR_MAPI _T("MAPI error (%i):\n%s.") + +//--------------------------------------------------------------------------- +class CSend { + public: + CSend(HWND Owner, HANDLE hContact, bool bFreeOnExit); // oder (TfrmMain & Owner) + virtual ~CSend(); + + virtual void Send() = 0; + void SendSync(bool Sync) {m_SendSync = Sync;}; + bool m_bFreeOnExit; // need to "delete object;" on exit ? + void SetContact(HANDLE hContact); + BYTE GetEnableItem() {return m_EnableItem;}; + LPTSTR GetErrorMsg() {return m_ErrorMsg;}; + + LPTSTR m_pszFile; + LPTSTR m_pszFileDesc; + + BOOL m_bDeleteAfterSend; + + private: + + protected: + LPTSTR m_pszSendTyp; //hold string for error mess + HWND m_hWndO; //window handle of caller + HANDLE m_hContact; //Contact handle + char* m_pszProto; //Contact Proto Modul + BYTE m_EnableItem; //hold flag for send type + void AfterSendDelete(); + BYTE m_ChatRoom; //is Contact chatroom + bool m_SendSync; //send sync / async + + bool hasCap(unsigned int Flag); + unsigned int m_PFflag; + + void svcSendFile(); + void svcSendUrl (const char* url); + void svcSendMsg (const char* szMessage); + void svcSendChat(); //main GC service + void svcSendChat(const char* szMessage); //GC ansi wrapper + + DWORD m_cbEventMsg; //sizeof EventMsg(T) buffer + char* m_szEventMsg; //EventMsg char* + LPTSTR m_szEventMsgT; //EventMsg TCHAR* + HANDLE m_hSend; //protocol send handle + HANDLE m_hOnSend; //HookEventObj on ME_PROTO_ACK + int __cdecl OnSend(WPARAM wParam, LPARAM lParam); + void Unhook(){if(m_hOnSend) {UnhookEvent(m_hOnSend);m_hOnSend = NULL;}} + void DB_EventAdd(WORD EventType); + void Exit(unsigned int Result); + + MSGBOX m_box; + LPTSTR m_ErrorMsg; + LPTSTR m_ErrorTitle; + void Error(LPCTSTR pszFormat, ...); +}; + +#endif diff --git a/plugins/SendScreenshotPlus/CSendEmail.cpp b/plugins/SendScreenshotPlus/CSendEmail.cpp new file mode 100644 index 0000000000..14e539ea0d --- /dev/null +++ b/plugins/SendScreenshotPlus/CSendEmail.cpp @@ -0,0 +1,221 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSendEmail.cpp $ +Revision : $Revision: 13 $ +Last change on : $Date: 2010-04-02 02:54:30 +0400 (РџС‚, 02 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +//--------------------------------------------------------------------------- +#include "CSendEmail.h" + +//--------------------------------------------------------------------------- +CSendEmail::CSendEmail(HWND Owner, HANDLE hContact, bool bFreeOnExit) +: CSend(Owner, hContact, bFreeOnExit){ + m_EnableItem = SS_DLG_DELETEAFTERSSEND | SS_DLG_DESCRIPTION; // SS_DLG_AUTOSEND | ; + m_pszSendTyp = _T("Email transfer"); + m_pszFileA = NULL; + m_pszFileName = NULL; + m_Email = NULL; + m_FriendlyName = NULL; + m_Subject = NULL; +} + +CSendEmail::~CSendEmail(){ + mir_free(m_pszFileA); + mir_free(m_pszFileName); + mir_free(m_Email); + mir_free(m_FriendlyName); + mir_free(m_Subject); +} + +//--------------------------------------------------------------------------- +void CSendEmail::Send() { + + mir_freeAndNil(m_pszFileName); + m_pszFileName = (LPSTR)GetFileName(m_pszFile, DBVT_ASCIIZ); + + mir_freeAndNil(m_pszFileA); + m_pszFileA = mir_t2a(m_pszFile); + + +// AnsiString Email, Subject, FriendlyName; + CONTACTINFO ci={0}; + ci.cbSize = sizeof(ci); + ci.hContact = m_hContact; + ci.szProto = m_pszProto; + //ci.dwFlag = CNF_TCHAR; + + ci.dwFlag = CNF_EMAIL | CNF_TCHAR; + CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci); + m_Email = mir_t2a(ci.pszVal); + + ci.dwFlag = CNF_DISPLAY | CNF_TCHAR; + CallService(MS_CONTACT_GETCONTACTINFO,(WPARAM)0,(LPARAM)&ci); + m_FriendlyName = mir_t2a(ci.pszVal); + + mir_free(ci.pszVal); + + m_Subject = mir_t2a(m_pszFileDesc); + + //SendByEmail(m_pszFileA, "", m_FriendlyName, m_Email, m_Subject); + + //start Send thread + m_bFreeOnExit = TRUE; + mir_forkthread(&CSendEmail::SendThreadWrapper, this); +} + +void CSendEmail::SendThread() { + //This code based on SentTo.exe application. + //The default mail client for Simple MAPI or MAPI calls is defined by the + //HKLM\Software\Clients\Mail::(default) registry value. + + LPTSTR err = NULL; + MapiFileDesc arrfileDesc[1]; + + typedef ULONG (FAR PASCAL *MAPIFUNC)(LHANDLE,ULONG,lpMapiMessage,FLAGS,ULONG); + MapiMessage Msg; + MAPIFUNC lpMAPISendMail; + + HINSTANCE hMAPILib = ::LoadLibrary(_T("MAPI32.DLL")); + if (hMAPILib == NULL) { + //return -1; + Error(SS_ERR_INIT, m_pszSendTyp); + Exit(ACKRESULT_FAILED); + } + + lpMAPISendMail = (MAPIFUNC)GetProcAddress(hMAPILib, "MAPISendMail"); + if (lpMAPISendMail == NULL) { + ::FreeLibrary(hMAPILib); + //return -2; + Error(SS_ERR_INIT, m_pszSendTyp); + Exit(ACKRESULT_FAILED); + } + + memset(&Msg, 0, sizeof(Msg)); + + arrfileDesc[0].ulReserved = 0; + arrfileDesc[0].flFlags = 0; + arrfileDesc[0].lpFileType = NULL; + arrfileDesc[0].nPosition = -1; + arrfileDesc[0].lpszPathName = m_pszFileA; + arrfileDesc[0].lpszFileName = NULL; + + Msg.nFileCount = 1; + Msg.lpFiles = arrfileDesc; + Msg.lpszNoteText = ""; //body + Msg.lpszSubject = m_Subject; //subject + + Msg.nRecipCount = 1; + MapiRecipDesc recip; + recip.ulReserved = 0; + recip.ulRecipClass = MAPI_TO; + + if (m_FriendlyName && m_FriendlyName[0]!= NULL) { + recip.lpszName = m_FriendlyName; //friendly name set to contact's name + } + else { + recip.lpszName = m_Email; //friendly name set to contact's email + } + + recip.lpszAddress = m_Email; //email + recip.ulEIDSize = 0; + recip.lpEntryID = NULL; + Msg.lpRecips = &recip; + + try { + int res = lpMAPISendMail(NULL, NULL, &Msg, MAPI_LOGON_UI|MAPI_DIALOG, 0); + ::FreeLibrary(hMAPILib); + + switch (res) { + case SUCCESS_SUCCESS: + //The call succeeded and the message was sent. + Exit(ACKRESULT_SUCCESS); + return; + + // No message was sent + case MAPI_E_AMBIGUOUS_RECIPIENT: + err = _T("A recipient matched more than one of the recipient descriptor structures and MAPI_DIALOG was not set"); + break; + case MAPI_E_ATTACHMENT_NOT_FOUND: + err = _T("The specified attachment was not found"); + break; + case MAPI_E_ATTACHMENT_OPEN_FAILURE: + err = _T("The specified attachment could not be opened"); + break; + case MAPI_E_BAD_RECIPTYPE: + err = _T("The type of a recipient was not MAPI_TO, MAPI_CC, or MAPI_BCC"); + break; + case MAPI_E_FAILURE: + err = _T("One or more unspecified errors occurred"); + break; + case MAPI_E_INSUFFICIENT_MEMORY: + err = _T("There was insufficient memory to proceed"); + break; + case MAPI_E_INVALID_RECIPS: + err = _T("One or more recipients were invalid or did not resolve to any address"); + break; + case MAPI_E_LOGIN_FAILURE: + err = _T("There was no default logon, and the user failed to log on successfully when the logon dialog box was displayed"); + break; + case MAPI_E_TEXT_TOO_LARGE: + err = _T("The text in the message was too large"); + break; + case MAPI_E_TOO_MANY_FILES: + err = _T("There were too many file attachments"); + break; + case MAPI_E_TOO_MANY_RECIPIENTS: + err = _T("There were too many recipients"); + break; + case MAPI_E_UNKNOWN_RECIPIENT: + err = _T("A recipient did not appear in the address list"); + break; + case MAPI_E_USER_ABORT: + err = _T("The user canceled one of the dialog boxes"); + break; + default: + err = _T("Unknown Error"); + break; + } + Error(SS_ERR_MAPI, res, err); + Exit(ACKRESULT_FAILED); + + } catch (...) { + ::FreeLibrary(hMAPILib); + Error(SS_ERR_INIT, m_pszSendTyp); + Exit(ACKRESULT_FAILED); + //return -3; + return; + } +} + +void CSendEmail::SendThreadWrapper(void * Obj) { + reinterpret_cast(Obj)->SendThread(); +} + +//--------------------------------------------------------------------------- + diff --git a/plugins/SendScreenshotPlus/CSendEmail.h b/plugins/SendScreenshotPlus/CSendEmail.h new file mode 100644 index 0000000000..940558b0d6 --- /dev/null +++ b/plugins/SendScreenshotPlus/CSendEmail.h @@ -0,0 +1,63 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSendEmail.h $ +Revision : $Revision: 13 $ +Last change on : $Date: 2010-04-02 02:54:30 +0400 (РџС‚, 02 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef _CSEND_EMAIL_H +#define _CSEND_EMAIL_H + +//--------------------------------------------------------------------------- +#include "global.h" +#include "CSend.h" +#include + +//--------------------------------------------------------------------------- +class CSendEmail : public CSend { + public: + // Deklaration Standardkonstruktor/Standarddestructor + CSendEmail(HWND Owner, HANDLE hContact, bool bFreeOnExit); + ~CSendEmail(); + + void Send(); + + protected: + LPSTR m_pszFileA; + LPSTR m_pszFileName; + LPSTR m_Email; + LPSTR m_FriendlyName; + LPSTR m_Subject; + void SendThread(); + static void SendThreadWrapper(void * Obj); + +}; + +//--------------------------------------------------------------------------- + +#endif diff --git a/plugins/SendScreenshotPlus/CSendFTPFile.cpp b/plugins/SendScreenshotPlus/CSendFTPFile.cpp new file mode 100644 index 0000000000..d7512d2fe6 --- /dev/null +++ b/plugins/SendScreenshotPlus/CSendFTPFile.cpp @@ -0,0 +1,99 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSendFTPFile.cpp $ +Revision : $Revision: 13 $ +Last change on : $Date: 2010-04-02 02:54:30 +0400 (РџС‚, 02 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +//--------------------------------------------------------------------------- +#include "CSendFTPFile.h" + + +//--------------------------------------------------------------------------- +CSendFTPFile::CSendFTPFile(HWND Owner, HANDLE hContact, bool bFreeOnExit) +: CSend(Owner, hContact, bFreeOnExit){ + m_EnableItem = NULL ; //SS_DLG_DESCRIPTION| SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND; + m_pszSendTyp = _T("FTPFile transfer"); + m_pszFileName = NULL; + m_URL = NULL; +} + +CSendFTPFile::~CSendFTPFile(){ + mir_free(m_pszFileName); + mir_free(m_URL); +} + +//--------------------------------------------------------------------------- +void CSendFTPFile::Send() { + + /********************************************************************************************* + * Send file (files) to the FTP server and copy file URL + * to message log or clipboard (according to plugin setting) + * wParam = (HANDLE)hContact + * lParam = (char *)filename + * Filename format is same as GetOpenFileName (OPENFILENAME.lpstrFile) returns, + * see http://msdn2.microsoft.com/en-us/library/ms646839.aspx + * Returns 0 on success or nonzero on failure + * if (!wParam || !lParam) return 1 + ********************************************************************************************/ + mir_freeAndNil(m_pszFileName); + m_pszFileName = (LPSTR)GetFileName(m_pszFile, DBVT_ASCIIZ); + size_t size = sizeof(char)*(strlen(m_pszFileName)+2); + m_pszFileName = (LPSTR) mir_realloc(m_pszFileName, size); + m_pszFileName[size-1] = NULL; + + //start Send thread + m_bFreeOnExit = TRUE; + mir_forkthread(&CSendFTPFile::SendThreadWrapper, this); +} + +void CSendFTPFile::SendThread() { + int ret; + mir_freeAndNil(m_URL); + + ret = (int)CallService(MS_FTPFILE_SHAREFILE, (WPARAM)m_hContact, (LPARAM)m_pszFileName); + if (ret != 0) { + Error(_T("%s (%i):\nCould not add a share to the FTP File plugin."),TranslateTS(m_pszSendTyp),ret); + Exit(ret); + } + + //Can't delete the file since FTP File plugin will use it + m_bDeleteAfterSend = false; + + if (m_URL && m_URL[0]!= NULL) { + m_ChatRoom ? svcSendChat(m_URL) : svcSendMsg(m_URL); + return; + } +} + +void CSendFTPFile::SendThreadWrapper(void * Obj) { + reinterpret_cast(Obj)->SendThread(); +} + +//--------------------------------------------------------------------------- + diff --git a/plugins/SendScreenshotPlus/CSendFTPFile.h b/plugins/SendScreenshotPlus/CSendFTPFile.h new file mode 100644 index 0000000000..6012f76232 --- /dev/null +++ b/plugins/SendScreenshotPlus/CSendFTPFile.h @@ -0,0 +1,59 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSendFTPFile.h $ +Revision : $Revision: 13 $ +Last change on : $Date: 2010-04-02 02:54:30 +0400 (РџС‚, 02 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef _CSEND_FTP_FILE_H +#define _CSEND_FTP_FILE_H + +//--------------------------------------------------------------------------- +#include "global.h" +#include "CSend.h" + +//--------------------------------------------------------------------------- +class CSendFTPFile : public CSend { + public: + // Deklaration Standardkonstruktor/Standarddestructor + CSendFTPFile(HWND Owner, HANDLE hContact, bool bFreeOnExit); + ~CSendFTPFile(); + + void Send(); + + protected: + LPSTR m_pszFileName; + LPSTR m_URL; + void SendThread(); + static void SendThreadWrapper(void * Obj); + +}; + +//--------------------------------------------------------------------------- + +#endif diff --git a/plugins/SendScreenshotPlus/CSendFile.cpp b/plugins/SendScreenshotPlus/CSendFile.cpp new file mode 100644 index 0000000000..1884c8307f --- /dev/null +++ b/plugins/SendScreenshotPlus/CSendFile.cpp @@ -0,0 +1,53 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSendFile.cpp $ +Revision : $Revision: 13 $ +Last change on : $Date: 2010-04-02 02:54:30 +0400 (РџС‚, 02 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +//--------------------------------------------------------------------------- +#include "CSendFile.h" + +//--------------------------------------------------------------------------- +CSendFile::CSendFile(HWND Owner, HANDLE hContact, bool bFreeOnExit) +: CSend(Owner, hContact, bFreeOnExit){ + m_EnableItem = SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND | SS_DLG_DESCRIPTION; + m_pszSendTyp = _T("File transfer"); +} + +CSendFile::~CSendFile(){ + ; +} + +//--------------------------------------------------------------------------- +void CSendFile::Send() { + m_bFreeOnExit = TRUE; + svcSendFile(); +} + +//--------------------------------------------------------------------------- diff --git a/plugins/SendScreenshotPlus/CSendFile.h b/plugins/SendScreenshotPlus/CSendFile.h new file mode 100644 index 0000000000..edbb49822d --- /dev/null +++ b/plugins/SendScreenshotPlus/CSendFile.h @@ -0,0 +1,55 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSendFile.h $ +Revision : $Revision: 13 $ +Last change on : $Date: 2010-04-02 02:54:30 +0400 (РџС‚, 02 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef _CSEND_FILE_H +#define _CSEND_FILE_H + +//--------------------------------------------------------------------------- +#include "global.h" +#include "CSend.h" + +//--------------------------------------------------------------------------- +class CSendFile : public CSend { + public: + // Deklaration Standardkonstruktor/Standarddestructor + CSendFile(HWND Owner, HANDLE hContact, bool bFreeOnExit); + ~CSendFile(); + + void Send(); + + protected: + +}; + +//---------------------------------------------------------------------------*/ + +#endif diff --git a/plugins/SendScreenshotPlus/CSendHTTPServer.cpp b/plugins/SendScreenshotPlus/CSendHTTPServer.cpp new file mode 100644 index 0000000000..27eb42d9b4 --- /dev/null +++ b/plugins/SendScreenshotPlus/CSendHTTPServer.cpp @@ -0,0 +1,143 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSendHTTPServer.cpp $ +Revision : $Revision: 13 $ +Last change on : $Date: 2010-04-02 02:54:30 +0400 (РџС‚, 02 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +//--------------------------------------------------------------------------- +#include "CSendHTTPServer.h" +INT_PTR (*g_MirCallService)(const char *, WPARAM, LPARAM)=NULL; +//INT_PTR (*CallService)(const char *,WPARAM,LPARAM); + + +//--------------------------------------------------------------------------- +CSendHTTPServer::CSendHTTPServer(HWND Owner, HANDLE hContact, bool bFreeOnExit) +: CSend(Owner, hContact, bFreeOnExit){ + m_EnableItem = SS_DLG_DESCRIPTION ; //| SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND; + m_pszSendTyp = _T("HTTPServer transfer"); + m_pszFileName = NULL; + m_URL = NULL; + m_fsi_pszSrvPath = NULL; + m_fsi_pszRealPath = NULL; +} + +CSendHTTPServer::~CSendHTTPServer(){ + mir_free(m_pszFileName); + mir_free(m_URL); + mir_free(m_fsi_pszSrvPath); + mir_free(m_fsi_pszRealPath); +} + +//--------------------------------------------------------------------------- +void CSendHTTPServer::Send() { + + if (CallService(MS_HTTP_ACCEPT_CONNECTIONS, (WPARAM)true, (LPARAM)0) != 0) { + Error(NULL, _T("Could not start the HTTP Server plugin.")); + return; + } + + if (!m_pszFileName) { + m_pszFileName = (LPSTR)GetFileName(m_pszFile, DBVT_ASCIIZ); + } + mir_freeAndNil(m_fsi_pszSrvPath); + mir_stradd(m_fsi_pszSrvPath, "/"); + mir_stradd(m_fsi_pszSrvPath, m_pszFileName); + + mir_freeAndNil(m_fsi_pszRealPath); + m_fsi_pszRealPath = mir_t2a(m_pszFile); + + ZeroMemory(&m_fsi, sizeof(m_fsi)); + m_fsi.lStructSize = sizeof(STFileShareInfo); + m_fsi.pszSrvPath = m_fsi_pszSrvPath; + m_fsi.nMaxDownloads = -1; // -1 = infinite + m_fsi.pszRealPath = m_fsi_pszRealPath; + //m_fsi.dwOptions = NULL; //OPT_SEND_LINK only work on single chat; + + //start Send thread + m_bFreeOnExit = TRUE; + mir_forkthread(&CSendHTTPServer::SendThreadWrapper, this); +} + +void CSendHTTPServer::SendThread() { + int ret; + mir_freeAndNil(m_URL); + + if (ServiceExists(MS_HTTP_GET_LINK)) { + //patched plugin version + ret = (int)CallService(MS_HTTP_ADD_CHANGE_REMOVE, (WPARAM)m_hContact, (LPARAM)&m_fsi); + if (!ret) { + m_URL = (LPSTR)CallService(MS_HTTP_GET_LINK, (WPARAM)m_fsi.pszSrvPath, NULL); + } + } + else { + //original plugin + m_fsi.dwOptions = OPT_SEND_LINK; + g_MirCallService = pluginLink->CallService; //backup Miranda CallService + pluginLink->CallService = MyCallService; //Hack on Miranda CallService + + //send DATA and wait for reply + ret = (int)CallService(MS_HTTP_ADD_CHANGE_REMOVE, (WPARAM)m_hContact, (LPARAM)&m_fsi); + pluginLink->CallService = g_MirCallService; //restore Miranda CallService + } + + if (ret != 0) { + Error(_T("%s (%i):\nCould not add a share to the HTTP Server plugin."),TranslateTS(m_pszSendTyp),ret); + Exit(ret); + } + + //Share the file by HTTP Server plugin, SendSS does not own the file anymore = auto-delete won't work + m_bDeleteAfterSend = false; + + if (m_URL && m_URL[0]!= NULL) { + m_ChatRoom ? svcSendChat(m_URL) : svcSendMsg(m_URL); + return; + } + Exit(ACKRESULT_FAILED); +} + +void CSendHTTPServer::SendThreadWrapper(void * Obj) { + reinterpret_cast(Obj)->SendThread(); +} + +//--------------------------------------------------------------------------- +CSendHTTPServer::CContactMapping CSendHTTPServer::_CContactMapping; + +INT_PTR CSendHTTPServer::MyCallService(const char *name, WPARAM wParam, LPARAM lParam) { + CContactMapping::iterator Contact(_CContactMapping.end()); +/* + if ( wParam == m_hContact && ( + (strcmp(name, MS_MSG_SENDMESSAGE)== 0) || + (strcmp(name, "SRMsg/LaunchMessageWindow")== 0) )) + { + m_URL= mir_strdup((char*)lParam); + return 0; + }*/ + return g_MirCallService(name, wParam, lParam); +} + diff --git a/plugins/SendScreenshotPlus/CSendHTTPServer.h b/plugins/SendScreenshotPlus/CSendHTTPServer.h new file mode 100644 index 0000000000..129153e0c6 --- /dev/null +++ b/plugins/SendScreenshotPlus/CSendHTTPServer.h @@ -0,0 +1,67 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSendHTTPServer.h $ +Revision : $Revision: 13 $ +Last change on : $Date: 2010-04-02 02:54:30 +0400 (РџС‚, 02 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef _CSEND_HTTP_SERVER_H +#define _CSEND_HTTP_SERVER_H + +//--------------------------------------------------------------------------- +#include "global.h" +#include "CSend.h" + +//--------------------------------------------------------------------------- +class CSendHTTPServer : public CSend { + public: + // Deklaration Standardkonstruktor/Standarddestructor + CSendHTTPServer(HWND Owner, HANDLE hContact, bool bFreeOnExit); + ~CSendHTTPServer(); + + void Send(); + + protected: + LPSTR m_pszFileName; + LPSTR m_URL; + STFileShareInfo m_fsi; + LPSTR m_fsi_pszSrvPath; + LPSTR m_fsi_pszRealPath; + void SendThread(); + static void SendThreadWrapper(void * Obj); + + typedef std::map CContactMapping; + static CContactMapping _CContactMapping; + + static INT_PTR MyCallService(const char *name, WPARAM wParam, LPARAM lParam); + +}; + +//--------------------------------------------------------------------------- + +#endif diff --git a/plugins/SendScreenshotPlus/CSendImageShack.cpp b/plugins/SendScreenshotPlus/CSendImageShack.cpp new file mode 100644 index 0000000000..a27b4f5273 --- /dev/null +++ b/plugins/SendScreenshotPlus/CSendImageShack.cpp @@ -0,0 +1,299 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSendImageShack.cpp $ +Revision : $Revision: 13 $ +Last change on : $Date: 2010-04-02 02:54:30 +0400 (РџС‚, 02 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +//--------------------------------------------------------------------------- +#include +#include +#include + +#include "CSendImageShack.h" +#include "DevKey.h" + +//--------------------------------------------------------------------------- +CSendImageShack::CSendImageShack(HWND Owner, HANDLE hContact, bool bFreeOnExit) +: CSend(Owner, hContact, bFreeOnExit) { + m_EnableItem = SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND | SS_DLG_DESCRIPTION; + m_pszSendTyp = _T("Image upload"); + m_pszFileName = NULL; + m_pszContentType = NULL; + m_MFDRboundary = NULL; + m_nlreply = NULL; + m_SendSync = false; + m_Url = NULL; +} + +CSendImageShack::~CSendImageShack(){ + mir_free(m_pszFileName); + mir_free(m_MFDRboundary); + // FREEHTTPREQUESTSTRUCT* + if (m_nlreply) CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM) m_nlreply); + mir_free(m_Url); +}; + +//--------------------------------------------------------------------------- +void CSendImageShack::Send() { + // check Netlib + if( !hNetlibUser ) { + //PrintError(1,TRUE); + return; + } + if (!m_pszFileName) { + m_pszFileName = (LPSTR)GetFileName(m_pszFile, DBVT_ASCIIZ); + } + if (!m_pszContentType) GetContentType(); + + // create new boundary + MFDR_Reset(); + + // initialize the netlib request + ZeroMemory(&m_nlhr, sizeof(m_nlhr)); + m_nlhr.cbSize = sizeof(m_nlhr); + m_nlhr.requestType = REQUEST_POST; + m_nlhr.flags = NLHRF_HTTP11; //NLHRF_DUMPASTEXT; + m_nlhr.szUrl = "http://www.imageshack.us/upload_api.php"; + m_nlhr.headersCount = 6; + { //NETLIBHTTPHEADER start + m_nlhr.headers=(NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)*m_nlhr.headersCount); + m_nlhr.headers[0].szName = "Referer"; + m_nlhr.headers[0].szValue = "http://www.imageshack.us/upload_api.php"; + m_nlhr.headers[1].szName = "Connection"; + m_nlhr.headers[1].szValue = "Keep-alive"; + m_nlhr.headers[2].szName = "AcceptLanguage"; + m_nlhr.headers[2].szValue = "en-us, pt-br"; + m_nlhr.headers[3].szName = "Host"; + m_nlhr.headers[3].szValue = "imageshack.us"; + m_nlhr.headers[4].szName = "User-Agent"; + m_nlhr.headers[4].szValue = __USER_AGENT_STRING; //szAgent; /; + //nlhr.headers[x].szName = "Authorization"; + //nlhr.headers[x].szValue = auth; //Basic base-64-authorization + + //$header .= "Content-type: multipart/form-data; boundary=" . part::getBoundary() . "\r\n"; + sprintf(m_nlheader_ContentType, "multipart/form-data; boundary=%s", m_MFDRboundary); + m_nlhr.headers[m_nlhr.headersCount-1].szName = "Content-Type"; + m_nlhr.headers[m_nlhr.headersCount-1].szValue = m_nlheader_ContentType; + } //NETLIBHTTPHEADER end + +//POST DATA file-header, init DATA with MultipartFormDataRequest + //$params[] = new filepart('fileupload', $file, basename($file), $contentType, 'iso-8859-1'); + //($this->sendStart($h);) + AppendToData("--"); + AppendToData(m_MFDRboundary); + AppendToData("\r\n"); + //($this->sendDispositionHeader($h);) + AppendToData("Content-Disposition: form-data; name=\""); + AppendToData("fileupload"); + AppendToData("\"; filename=\""); + AppendToData(m_pszFileName); + AppendToData("\""); + AppendToData("\r\n"); + //($this->sendContentTypeHeader($h);) + AppendToData("Content-Type: "); + AppendToData(m_pszContentType); + AppendToData("; charset="); + AppendToData("iso-8859-1"); + //($this->sendEndOfHeader($h);) + AppendToData("\r\n"); + AppendToData("\r\n"); + //Now we add the file binary ($this->sendData($h)) + FILE * fileId = _tfsopen(m_pszFile, _T("rb"), _SH_DENYWR ); + if( !fileId) { + //PrintError(1,TRUE); + return; + } + fseek(fileId, NULL, SEEK_END); + size_t lenFile = ftell(fileId); + size_t sizeDest = sizeof(char)*(m_nlhr.dataLength + lenFile + 1); + m_nlhr.pData = (char *) mir_realloc(m_nlhr.pData, sizeDest); + fseek(fileId, NULL, SEEK_SET ); + int i; + int ch = fgetc( fileId ); + for( i=0; (i < (int)lenFile ) && ( feof( fileId ) == 0 ); i++ ) { + m_nlhr.pData[m_nlhr.dataLength+i] = (char)ch; + ch = fgetc( fileId ); + } + m_nlhr.pData[sizeDest-1] = 0; //NULL Termination for binary data + m_nlhr.dataLength = (int)sizeDest - 1; + fclose(fileId); + //($this->sendEnd($h);) + AppendToData("\r\n"); + +//POST DATA footer (for "optimage", 1) +//POST DATA footer (for "optsize", optsize) + +//POST DATA footer (for "tags", tags) +//POST DATA footer (for "rembar", "yes" : "no") +//POST DATA footer (for "public", "yes" : "no") +//POST DATA footer (for "cookie", cookie) + +//POST DATA footer (for "key", DEVKEY_IMAGESHACK) + //($this->sendStart($h);) + AppendToData("--"); + AppendToData(m_MFDRboundary); + AppendToData("\r\n"); + //($this->sendDispositionHeader($h);) + AppendToData("Content-Disposition: form-data; name=\""); + AppendToData("key"); + AppendToData("\""); + //($this->sendTransferEncodingHeader($h); ) + AppendToData("\r\n"); + AppendToData("Content-Transfer-Encoding: "); + AppendToData("8bit"); //??"binary" + //($this->sendEndOfHeader($h);) + AppendToData("\r\n"); + AppendToData("\r\n"); + //($this->sendData($h);) + AppendToData(DEVKEY_IMAGESHACK); + //($this->sendEnd($h);) + AppendToData("\r\n"); + +//POST DATA Exit + //$postdata = "--" . part::getBoundary() . "--\r\n"; + AppendToData("--"); + AppendToData(m_MFDRboundary); + AppendToData("--\r\n"); + +//start upload thread + if (m_SendSync) { + m_bFreeOnExit = FALSE; + SendThread(); + return; + } + m_bFreeOnExit = TRUE; + mir_forkthread(&CSendImageShack::SendThreadWrapper, this); +} + +void CSendImageShack::SendThread() { + //send DATA and wait for m_nlreply + m_nlreply = (NETLIBHTTPREQUEST *) CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM) hNetlibUser, (LPARAM) &m_nlhr); + mir_freeAndNil(m_nlhr.pData); + mir_freeAndNil(m_nlhr.headers); + if(m_nlreply){ + if( m_nlreply->resultCode >= 200 && m_nlreply->resultCode < 300 ){ + m_nlreply->pData[m_nlreply->dataLength] = 0;// make sure its null terminated + const char* URL = NULL; + LPTSTR err = NULL; + URL = GetTagContent(m_nlreply->pData, "", ""); + if (URL && URL[0]!= NULL) { + m_Url = mir_strdup(URL); + if(m_SendSync) { + Exit(ACKRESULT_SUCCESS); + return; + } + m_ChatRoom ? svcSendChat(URL) : svcSendMsg(URL); + return; + } + else{ //check error mess from server + err = mir_a2t(GetTagContent(m_nlreply->pData, "")); + if (err && err[0]!= NULL) { //parsed err messege + Error(NULL, err); + } + else{ //fallback to server response mess + mir_freeAndNil(err); + err = mir_a2t(m_nlreply->pData); + } + mir_free(err); + } + } + else { + Error(NULL, _T("Upload server did not respond timely.")); + } + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM) m_nlreply); + m_nlreply = NULL; + } + else { + Error(SS_ERR_INIT, m_pszSendTyp); + } + Exit(ACKRESULT_FAILED); +} + +void CSendImageShack::SendThreadWrapper(void * Obj) { + reinterpret_cast(Obj)->SendThread(); +} + +//--------------------------------------------------------------------------- +void CSendImageShack::MFDR_Reset() { + char Temp[64]; + DWORD dwBoundaryRand1 = GetTickCount(); + DWORD dwBoundaryRand2 = rand(); + + mir_freeAndNil(m_MFDRboundary); + sprintf(Temp, "B-O-U-N-D-A-R-Y%u%u", dwBoundaryRand1, dwBoundaryRand2); + mir_stradd(m_MFDRboundary,Temp); +} + +void CSendImageShack::GetContentType() { + if (m_pszContentType) mir_freeAndNil(m_pszContentType); + LPSTR FileExtension = (LPSTR)GetFileExt(m_pszFile, DBVT_ASCIIZ); + + if ((strcmp(FileExtension, ".jpeg")==0) || (strcmp(FileExtension, ".jpe")==0) || (strcmp(FileExtension ,".jpg")==0)) + m_pszContentType="image/jpeg"; + else if (strcmp(FileExtension, ".bmp")==0) + m_pszContentType="image/bmp"; + else if (strcmp(FileExtension, ".png")==0) + m_pszContentType="image/png"; + else if (strcmp(FileExtension, ".gif")==0) + m_pszContentType="image/gif"; + else if ((strcmp(FileExtension, ".tif")==0) || (strcmp(FileExtension, ".tiff")==0)) + m_pszContentType="image/tiff"; + else + m_pszContentType="application/octet-stream"; + + mir_free(FileExtension); + return; +} + +void CSendImageShack::AppendToData(const char *pszVal) { + if (!m_nlhr.pData) { + m_nlhr.pData = mir_strdup(pszVal); + m_nlhr.dataLength = (int)strlen(pszVal); + } + else { + size_t lenVal = strlen(pszVal); + size_t sizeNew = sizeof(char)*(m_nlhr.dataLength + lenVal + 1); + m_nlhr.pData = (char*) mir_realloc(m_nlhr.pData, sizeNew); + + strcpy(m_nlhr.pData + sizeof(char)*m_nlhr.dataLength, pszVal); + m_nlhr.pData[sizeNew-1] = 0; + m_nlhr.dataLength = (int)sizeNew -1; + } +} + +//--------------------------------------------------------------------------- +const char * CSendImageShack::GetTagContent(char * pszSource, const char * pszTagStart, const char * pszTagEnd) { + char * b = strstr(pszSource, pszTagStart); + if (!b) return NULL; + b += strlen(pszTagStart); + char * e = strstr(b, pszTagEnd); + if (e) *e = 0; + return b; +} + diff --git a/plugins/SendScreenshotPlus/CSendImageShack.h b/plugins/SendScreenshotPlus/CSendImageShack.h new file mode 100644 index 0000000000..eae406aca9 --- /dev/null +++ b/plugins/SendScreenshotPlus/CSendImageShack.h @@ -0,0 +1,77 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/CSendImageShack.h $ +Revision : $Revision: 13 $ +Last change on : $Date: 2010-04-02 02:54:30 +0400 (РџС‚, 02 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef _CSEND_IMAGESHACK_H +#define _CSEND_IMAGESHACK_H + +//--------------------------------------------------------------------------- +#include "global.h" +#include "Utils.h" +#include "CSend.h" + +//--------------------------------------------------------------------------- +class CSendImageShack : public CSend { + public: + // Deklaration Standardkonstruktor/Standarddestructor + CSendImageShack(HWND Owner, HANDLE hContact, bool bFreeOnExit); + ~CSendImageShack(); + + void Send(); + void SendSync(bool Sync) {m_SendSync = Sync;}; + LPSTR GetURL(){return m_Url;}; + LPSTR GetError(){return mir_t2a(m_ErrorMsg);}; + + protected: + LPSTR m_pszFileName; + NETLIBHTTPREQUEST m_nlhr; + NETLIBHTTPREQUEST* m_nlreply; + NETLIBHTTPHEADER* m_nlheader; + char m_nlheader_ContentType[64]; + LPSTR m_Url; + + void AppendToData(const char *pszVal); //append to netlib DATA + LPSTR m_pszContentType; //hold mimeType (does not need free) + void GetContentType(); //get mimeType + const char * GetTagContent(char * pszSource, const char * pszTagStart, const char * pszTagEnd); + + char* m_MFDRboundary; + void MFDR_Reset(); + + bool m_SendSync; + void SendThread(); + static void SendThreadWrapper(void * Obj); + +}; + +//--------------------------------------------------------------------------- + +#endif diff --git a/plugins/SendScreenshotPlus/Main.cpp b/plugins/SendScreenshotPlus/Main.cpp new file mode 100644 index 0000000000..f2a355a524 --- /dev/null +++ b/plugins/SendScreenshotPlus/Main.cpp @@ -0,0 +1,406 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/Main.cpp $ +Revision : $Revision: 22 $ +Last change on : $Date: 2010-05-02 21:25:02 +0400 (Р’СЃ, 02 май 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +//--------------------------------------------------------------------------- +#include "main.h" + +// Prototypes /////////////////////////////////////////////////////////////////////////// +MM_INTERFACE mmi; +UTF8_INTERFACE utfi; +//LIST_INTERFACE li; +FI_INTERFACE *FIP = 0; +HINSTANCE hInst; //!< Global reference to the application +MGLOBAL myGlobals; + + +PLUGINLINK *pluginLink; //!< Link between Miranda and this plugin +//Information gathered by Miranda, displayed in the plugin pane of the Option Dialog +PLUGININFOEX pluginInfo={ + sizeof(PLUGININFOEX), + __PLUGIN_NAME, // altered here and on file listing, so as not to match original + PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM), + __DESC, + __AUTHOR, + __AUTHOREMAIL, + __COPYRIGHT, + __AUTHORWEB, + UNICODE_AWARE, + 0, //doesn't replace anything built-in + MIID_PLUGIN +}; + +//static char szSendSS[]=SZ_SENDSS; + +HANDLE hsvc_SendScreenshot=0; +HANDLE hsvc_SendDesktop=0; +HANDLE hsvc_EditBitmap=0; +HANDLE hsvc_Send2ImageShack=0; + +HANDLE hNetlibUser = 0; //!< Netlib Register User +HANDLE hFolderScreenshot=0; + +HANDLE hhook_ModulesLoad=0; +HANDLE hhook_SystemPShutdown=0; + + +// Functions //////////////////////////////////////////////////////////////////////////// + +/*--------------------------------------------------------------------------- +* DLL entry point - Required to store the instance handle +*/ +extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + hInst = hinstDLL; + // Freeing some unneeded resources + DisableThreadLibraryCalls(GetModuleHandle(_T("sendss.dll"))); + + return TRUE; +} + +/*--------------------------------------------------------------------------- +* Called by Miranda to get the information associated to this plugin. +* It only returns the PLUGININFO structure, without any test on the version +* @param mirandaVersion The version of the application calling this function +*/ +extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion) { + pluginInfo.cbSize = sizeof(PLUGININFO); + return (PLUGININFO*) &pluginInfo; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) { + pluginInfo.cbSize = sizeof(PLUGININFOEX); + myGlobals.mirandaVersion = mirandaVersion; + return &pluginInfo; +} + +static const MUUID interfaces[] = { MIID_PLUGIN, MIID_LAST }; +extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void) { + return interfaces; +} + +/*--------------------------------------------------------------------------- +* Initializes the services provided and the link to those needed +* Called when the plugin is loaded into Miranda +*/ +extern "C" int __declspec(dllexport) Load(PLUGINLINK *link) { + pluginLink = link; + INT_PTR result = CALLSERVICE_NOTFOUND; + + if(ServiceExists(MS_IMG_GETINTERFACE)) + result = CallService(MS_IMG_GETINTERFACE, FI_IF_VERSION, (LPARAM)&FIP); + + if(FIP == NULL || result != S_OK) { + MessageBoxEx(NULL, TranslateT("Fatal error, image services not found. Send Screenshot will be disabled."), _T("Error"), MB_OK | MB_ICONERROR | MB_APPLMODAL, 0); + return 1; + } + + mmi.cbSize = sizeof(mmi); + mir_getMMI(&mmi); + utfi.cbSize = sizeof(utfi); + mir_getUTFI(&utfi); + + // load icon library (use UserInfoEx icon Pack) + IcoLib_LoadModule(); + + hhook_ModulesLoad = HookEvent(ME_SYSTEM_MODULESLOADED, hook_ModulesLoaded); + //hhook_options_init = HookEvent(ME_OPT_INITIALISE, hook_options_init); + //hhook_OkToExit = HookEvent(ME_SYSTEM_OKTOEXIT, hook_OkToExit); + hhook_SystemPShutdown = HookEvent(ME_SYSTEM_PRESHUTDOWN, hook_SystemPShutdown); + + AddMenuItems(); + RegisterServices(); + + return 0; +} + +int hook_ModulesLoaded(WPARAM, LPARAM) { + + myGlobals.PopUpExist = ServiceExists(MS_POPUP_ADDPOPUP); + myGlobals.PopUpActionsExist = ServiceExists(MS_POPUP_REGISTERACTIONS); + myGlobals.PluginHTTPExist = ServiceExists(MS_HTTP_ACCEPT_CONNECTIONS); + myGlobals.PluginFTPExist = ServiceExists(MS_FTPFILE_SHAREFILE); +// myGlobals.PluginUserinfoEx = ServiceExists(MS_USERINFO_VCARD_EXPORT); + + // Netlib register + if (!NetlibInit()){ + ; + } + + // load my button class + if(!ServiceExists("UserInfo/vCard/Export")) { + CtrlButtonLoadModule(); + } + + // Folders plugin support + if (ServiceExists(MS_FOLDERS_REGISTER_PATH)) { + hFolderScreenshot = (HANDLE) FoldersRegisterCustomPathT("SendSS", "Screenshots", + _T(PROFILE_PATH)_T("\\")_T(CURRENT_PROFILE)_T("\\Screenshots")); + } + // updater plugin support + if(ServiceExists(MS_UPDATE_REGISTER)) { + Update update = {0}; + char szVersion[16]; + update.cbSize = sizeof(Update); + update.szComponentName = pluginInfo.shortName; + update.pbVersion = (BYTE *)CreateVersionStringPluginEx(&pluginInfo, szVersion); + update.cpbVersion = (int)strlen((char *)update.pbVersion); + + update.szVersionURL = __FLVersionURL; + update.pbVersionPrefix = (BYTE *)__FLVersionPrefix; + update.cpbVersionPrefix = (int)strlen((char *)update.pbVersionPrefix); + update.szUpdateURL = __FLUpdateURL; + // update.szUpdateURL = UPDATER_AUTOREGISTER; + + update.szBetaVersionURL = __BetaVersionURL; + // bytes occuring in VersionURL before the version, used to locate the version information within the URL data + update.pbBetaVersionPrefix = (BYTE *)__BetaVersionPrefix; + update.cpbBetaVersionPrefix = (int)strlen((char *)update.pbBetaVersionPrefix); + update.szBetaUpdateURL = __BetaUpdateURL; + + // url for displaying changelog for beta versions + update.szBetaChangelogURL = __BetaChangelogURL; + + CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update); + } + + return 0; +} + +/*--------------------------------------------------------------------------- +* Prepare the plugin to stop +* Called by Miranda when it will exit or when the plugin gets deselected +*/ +extern "C" int __declspec(dllexport) Unload(void) { + UnhookEvent(hhook_SystemPShutdown); + + DestroyServiceFunction(MS_SENDSS_OPENDIALOG); + DestroyServiceFunction(MS_SENDSS_EDITBITMAP); + DestroyServiceFunction(MS_SENDSS_SENDDESKTOP); + DestroyServiceFunction(MS_SENDSS_SEND2IMAGESHACK); + return 0; +} + +int hook_SystemPShutdown(WPARAM wParam, LPARAM lParam) { + UnhookEvent(hhook_ModulesLoad); + + // Netlib unregister + NetlibClose(); + + // uninitialize classes + CtrlButtonUnloadModule(); + + return 0; +} + +//--------------------------------------------------------------------------- +// Netlib +HANDLE NetlibInit(void) { + NETLIBUSER nlu = {0}; + nlu.cbSize = sizeof(nlu); + nlu.szSettingsModule = (char*)PLUGNAME; + nlu.szDescriptiveName = Translate("SendSS HTTP connections"); + nlu.flags = NUF_OUTGOING|NUF_HTTPCONNS; //|NUF_NOHTTPSOPTION; + hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); + return hNetlibUser; +} + +void NetlibClose(void) { + Netlib_CloseHandle(hNetlibUser); +} + + +//--------------------------------------------------------------------------- +// Callback function of service +// 1. Send a screenshot of the desktop to the selected contact +// wParam = contact handle +// lParam = 0 +// 2. Open the capture dialog in take screenshot only mode (it will not be sent) +// wParam = 0 +// lParam = anything but 0 +INT_PTR service_CaptureAndSendDesktop(WPARAM wParam, LPARAM lParam) { + LPTSTR pszPath = NULL; + LPSTR pszProto = NULL; + bool bChatRoom; + + TfrmMain *frmMain=new TfrmMain(); + if (!frmMain) { + MessageBoxEx(NULL, TranslateT("Could not create main dialog."), TranslateT("Error"), MB_OK | MB_ICONERROR | MB_APPLMODAL, 0); + return -1; + } + pszPath = GetCustomPath(); + + pszProto = (LPSTR)CallService(MS_PROTO_GETCONTACTBASEPROTO,wParam,0); + bChatRoom = DBGetContactSettingByte((HANDLE)wParam, pszProto, "ChatRoom", 0) != 0; + frmMain->m_opt_chkTimed = false; + frmMain->m_opt_tabCapture = 1; + frmMain->m_opt_cboxDesktop = 0; + frmMain->m_opt_chkEditor = false; + frmMain->m_opt_cboxSendBy = bChatRoom ? SS_IMAGESHACK:SS_FILESEND; + frmMain->Init(pszPath, (HANDLE)wParam); // this method create the window hidden. + frmMain->btnCaptureClick(); // this method will call Close() + mir_free(pszPath); + return 0; +} + +//--------------------------------------------------------------------------- +// Callback function of service for contact menu and main menu +// wParam = contact handle +// lParam = 0 +INT_PTR service_OpenCaptureDialog(WPARAM wParam, LPARAM lParam) { + LPTSTR pszPath = NULL; + + TfrmMain *frmMain=new TfrmMain(); + if (!frmMain) { + MessageBoxEx(NULL, TranslateT("Could not create main dialog."), TranslateT("Error"), MB_OK | MB_ICONERROR | MB_APPLMODAL, 0); + return -1; + } + + pszPath = GetCustomPath(); + frmMain->Init(pszPath, (HANDLE)wParam); + mir_free(pszPath); + frmMain->Show(); + return 0; +} + +//--------------------------------------------------------------------------- +// Edit a in-memory bitmap on the edit window +// wParam = (SENDSSCB) callback function address to call when editing is done +// lParam = (HBITMAP) bitmap handle, a copy is made so the calling function can free this handle after the service function returns +// Returns: +INT_PTR service_EditBitmap(WPARAM wParam, LPARAM lParam) { +/* TfrmEdit *frmEdit=new TfrmEdit(NULL); + if (!frmEdit) + return -1; + + Graphics::TBitmap *bitmap=new Graphics::TBitmap(); + if (!bitmap) + return -2; + + bitmap->Handle = (void*)lParam; + frmEdit->InitEditor(bitmap); // a copy of the bitmap is made inside this function + frmEdit->Show(); + delete bitmap; +*/ + return 0; +} + +//--------------------------------------------------------------------------- +// Callback function of service for sending image to imageshack.us +// wParam = (char*)filename +// lParam = (HANDLE)contact (can be null) +INT_PTR service_Send2ImageShack(WPARAM wParam, LPARAM lParam) { + LPSTR result = NULL; + CSendImageShack* cSend = new CSendImageShack(NULL, (HANDLE)lParam, false); + cSend->m_pszFile = mir_a2t((char*)wParam); + cSend->m_bDeleteAfterSend = FALSE; + if (lParam != NULL) { + cSend->Send(); + return 0; + } + cSend->SendSync(TRUE); + cSend->Send(); + if (cSend->GetURL()) { + result = mir_strdup(cSend->GetURL()); + } + else { + result = cSend->GetError(); + } + delete cSend; + return (INT_PTR)result; +} + +//--------------------------------------------------------------------------- +// Add SendSS menu item in contact menu +void AddMenuItems(void) { + CLISTMENUITEM mi={0}; + + // Common + mi.cbSize = sizeof(mi); + // support new genmenu style + mi.flags = CMIF_ROOTHANDLE|CMIF_UNICODE; + mi.hParentMenu = HGENMENU_ROOT; + + // Add item to contact menu + mi.position = 1000000; + mi.ptszName = LPGENT("Send Screenshot"); + mi.hIcon = IcoLib_GetIcon(ICO_PLUG_SSWINDOW2); + mi.pszService = MS_SENDSS_OPENDIALOG; + CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); + + // Add item to contact menu + mi.position = 1000001; + mi.ptszName = LPGENT("Send desktop screenshot"); + mi.hIcon = IcoLib_GetIcon(ICO_PLUG_SSWINDOW2); + mi.pszService = MS_SENDSS_SENDDESKTOP; + CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, (LPARAM)&mi); + + // Add item to main menu + mi.position = 1000001; + mi.ptszName = LPGENT("Take a screenshot"); + mi.hIcon = IcoLib_GetIcon(ICO_PLUG_SSWINDOW2); + mi.pszService = MS_SENDSS_OPENDIALOG; + CallService(MS_CLIST_ADDMAINMENUITEM, 0, (LPARAM)&mi); +} + +//--------------------------------------------------------------------------- +// Register Send screenshot services +int RegisterServices(void) { + hsvc_SendScreenshot = CreateServiceFunction(MS_SENDSS_OPENDIALOG, service_OpenCaptureDialog); + if (!hsvc_SendScreenshot) + MessageBoxEx(NULL, TranslateT("Could not register miranda service."), _T("MS_SENDSS_OPENDIALOG"), MB_OK | MB_ICONERROR | MB_APPLMODAL, 0); + + hsvc_SendDesktop = CreateServiceFunction(MS_SENDSS_SENDDESKTOP, service_CaptureAndSendDesktop); + if (!hsvc_SendDesktop) + MessageBoxEx(NULL, TranslateT("Could not register miranda service."), _T("MS_SENDSS_SENDDESKTOP"), MB_OK | MB_ICONERROR | MB_APPLMODAL, 0); + + hsvc_EditBitmap = CreateServiceFunction(MS_SENDSS_EDITBITMAP, service_EditBitmap); + if (!hsvc_EditBitmap) + MessageBoxEx(NULL, TranslateT("Could not register miranda service."), _T("MS_SENDSS_EDITBITMAP"), MB_OK | MB_ICONERROR | MB_APPLMODAL, 0); + + hsvc_Send2ImageShack = CreateServiceFunction(MS_SENDSS_SEND2IMAGESHACK, service_Send2ImageShack); + if (!hsvc_Send2ImageShack) + MessageBoxEx(NULL, TranslateT("Could not register miranda service."), _T("MS_SENDSS_SEND2IMAGESHACK"), MB_OK | MB_ICONERROR | MB_APPLMODAL, 0); + + return 0; +} + +//--------------------------------------------------------------------------- +LPTSTR GetCustomPath() { + LPTSTR pszPath = NULL; + pszPath = Utils_ReplaceVarsT(_T("%miranda_userdata%\\Screenshots")); + if (hFolderScreenshot) { + TCHAR szPath[1024] = {'\0'}; + FoldersGetCustomPathT(hFolderScreenshot, szPath, 1024, pszPath); + mir_freeAndNil(pszPath); + pszPath = mir_tstrdup(szPath); + } + return pszPath; +} diff --git a/plugins/SendScreenshotPlus/Main.h b/plugins/SendScreenshotPlus/Main.h new file mode 100644 index 0000000000..67059fb73c --- /dev/null +++ b/plugins/SendScreenshotPlus/Main.h @@ -0,0 +1,65 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/Main.h $ +Revision : $Revision: 22 $ +Last change on : $Date: 2010-05-02 21:25:02 +0400 (Р’СЃ, 02 май 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef MainH +#define MainH + +//--------------------------------------------------------------------------- +#include "global.h" +#include "UMainForm.h" +//#include "UEditForm.h" + +extern HANDLE hNetlibUser; + +//--------------------------------------------------------------------------- + +HANDLE NetlibInit(void); +void NetlibClose(void); + +void IcoLib_LoadModule(void); +void AddMenuItems(void); +int RegisterServices(void); + +int hook_ModulesLoaded(WPARAM, LPARAM); +int hook_SystemPShutdown(WPARAM wParam, LPARAM lParam); + +INT_PTR service_CaptureAndSendDesktop(WPARAM wParam, LPARAM lParam); +INT_PTR service_OpenCaptureDialog(WPARAM wParam, LPARAM lParam); +INT_PTR service_EditBitmap(WPARAM wParam, LPARAM lParam); +INT_PTR service_Send2ImageShack(WPARAM wParam, LPARAM lParam); + +int OnSendScreenShot(WPARAM wParam, LPARAM lParam); + +LPTSTR GetCustomPath(); + +//--------------------------------------------------------------------------- +#endif diff --git a/plugins/SendScreenshotPlus/SendSS_9.vcproj b/plugins/SendScreenshotPlus/SendSS_9.vcproj new file mode 100644 index 0000000000..25fc100659 --- /dev/null +++ b/plugins/SendScreenshotPlus/SendSS_9.vcproj @@ -0,0 +1,621 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/SendScreenshotPlus/UAboutForm.cpp b/plugins/SendScreenshotPlus/UAboutForm.cpp new file mode 100644 index 0000000000..f4ea2b6bc2 --- /dev/null +++ b/plugins/SendScreenshotPlus/UAboutForm.cpp @@ -0,0 +1,212 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/UAboutForm.cpp $ +Revision : $Revision: 22 $ +Last change on : $Date: 2010-05-02 21:25:02 +0400 (Р’СЃ, 02 май 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#include "UAboutForm.h" + +//--------------------------------------------------------------------------- +TfrmAbout::CHandleMapping TfrmAbout::_HandleMapping; + +LRESULT CALLBACK TfrmAbout::DlgTfrmAbout(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_CTLCOLOREDIT || msg == WM_CTLCOLORSTATIC) { + switch ( GetWindowLongPtr(( HWND )lParam, GWL_ID )) { + case IDC_WHITERECT: + case IDC_BUILDTIME: + case IDC_CREDIT: + case IDC_LICENSE: + SetTextColor((HDC)wParam,GetSysColor(COLOR_WINDOWTEXT)); + break; + default: + return FALSE; + } + SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); + return (LRESULT)GetStockObject(WHITE_BRUSH); //GetSysColorBrush(COLOR_WINDOW); + } + + CHandleMapping::iterator wnd(_HandleMapping.end()); + if (msg == WM_INITDIALOG) { + wnd = _HandleMapping.insert(CHandleMapping::value_type(hWnd, reinterpret_cast(lParam))).first; + reinterpret_cast(lParam)->m_hWnd = hWnd; + return wnd->second->wmInitdialog(wParam, lParam); + } + else { + wnd = _HandleMapping.find(hWnd); + } + if (wnd == _HandleMapping.end()) { // something screwed up + return FALSE; //dialog! do not use ::DefWindowProc(hWnd, msg, wParam, lParam); + } + + switch (msg) + { + // case WM_INITDIALOG: done on top + case WM_COMMAND: + return wnd->second->wmCommand(wParam, lParam); + break; + case WM_CLOSE: + return wnd->second->wmClose(wParam, lParam); + break; + case WM_DESTROY: + delete wnd->second; + break; + } + return FALSE; +} + +//--------------------------------------------------------------------------- +//WM_INITDIALOG: +LRESULT TfrmAbout::wmInitdialog(WPARAM wParam, LPARAM lParam) { + char* pszMsg = NULL; + HRSRC hResInfo; + DWORD ResSize; + TCHAR oldTitle[256], newTitle[256]; + LPTSTR temp = NULL; + LPTSTR pszTitle = NULL; + // Headerbar + LPTSTR pszPlug = mir_a2t(__PLUGIN_NAME); + LPTSTR pszVer = mir_a2t(__VERSION_STRING_DOT); + GetDlgItemText( m_hWnd, IDC_HEADERBAR, oldTitle, SIZEOF( oldTitle )); + mir_sntprintf( newTitle, SIZEOF(newTitle), oldTitle, pszPlug, pszVer ); + mir_freeAndNil(pszPlug); + mir_freeAndNil(pszVer); + SetDlgItemText( m_hWnd, IDC_HEADERBAR, newTitle ); + SendMessage(GetDlgItem(m_hWnd, IDC_HEADERBAR), WM_SETICON, 0, (WPARAM)IcoLib_GetIcon(ICO_PLUG_SSWINDOW1, true)); + + //Buildtime + mir_sntprintf(newTitle,SIZEOF(newTitle),TranslateT("Built %s %s"),_T(__DATE__),_T(__TIME__)); + SetDlgItemText(m_hWnd,IDC_BUILDTIME,newTitle); + + //License + { mir_tcsadd(pszTitle ,_T(__COPYRIGHT)); + mir_tcsadd(pszTitle ,_T("\r\n\r\n")); + + hResInfo = FindResource(hInst,MAKEINTRESOURCE(IDR_LICENSE),_T("TEXT")); + ResSize = SizeofResource(hInst,hResInfo); + pszMsg = (char*)LockResource(LoadResource(hInst,hResInfo)); + temp = mir_a2t(pszMsg); + temp [ResSize] = 0; //LockResource is not NULL terminatet !! + mir_tcsadd(pszTitle ,temp); + mir_freeAndNil(temp); + SetDlgItemText(m_hWnd,IDC_LICENSE, pszTitle); + mir_freeAndNil(pszTitle); + } + + //Credit + { + hResInfo = FindResource(hInst,MAKEINTRESOURCE(IDR_CREDIT),_T("TEXT")); + ResSize = SizeofResource(hInst,hResInfo); + pszMsg = (char*)LockResource(LoadResource(hInst,hResInfo)); + temp = mir_a2t(pszMsg); + temp [ResSize] = 0; //LockResource is not NULL terminatet !! + mir_tcsadd(pszTitle ,temp); + mir_freeAndNil(temp); + SetDlgItemText(m_hWnd,IDC_CREDIT, pszTitle); + mir_freeAndNil(pszTitle); + } + + SendMessage(m_hWnd, WM_SETICON, ICON_BIG, (LPARAM)IcoLib_GetIcon(ICO_PLUG_SSWINDOW1, true)); + SendMessage(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)IcoLib_GetIcon(ICO_PLUG_SSWINDOW2)); + + //init controls + btnPageClick(); + SendMessage(GetDlgItem(m_hWnd, IDA_CONTRIBLINK), BUTTONSETDEFAULT, (WPARAM)1, NULL); + + TranslateDialogDefault(m_hWnd); + return FALSE; +} + +//WM_COMMAND: +LRESULT TfrmAbout::wmCommand(WPARAM wParam, LPARAM lParam) { + //--------------------------------------------------------------------------- + if (HIWORD(wParam) == BN_CLICKED) { + int IDControl = LOWORD(wParam); + HWND hCtrl = (HWND)lParam; + switch(IDControl) { + case IDCANCEL: + case IDCLOSE: + break; + case IDA_btnClose: + Close(); + break; + case IDA_CONTRIBLINK: + m_Page = m_Page ? 0 : 1; + btnPageClick(); + break; + default: + break; + } + } + return FALSE; +} + +//WM_CLOSE: +LRESULT TfrmAbout::wmClose(WPARAM wParam, LPARAM lParam) { + SendMessage(m_hWndOwner,UM_CLOSING, (WPARAM)m_hWnd, (LPARAM)IDD_UAboutForm); + DestroyWindow(m_hWnd); + return FALSE; +} + +//--------------------------------------------------------------------------- +// Standard konstruktor/destruktor +TfrmAbout::TfrmAbout(HWND Owner) { + m_hWndOwner = Owner; + // create window + m_hWnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_UAboutForm),0, (DLGPROC)DlgTfrmAbout,(LPARAM)this); + //register object + _HandleMapping.insert(CHandleMapping::value_type(m_hWnd, this)); + //init page + m_Page = 1; +} + +TfrmAbout::~TfrmAbout() { + _HandleMapping.erase(m_hWnd); +} + +//--------------------------------------------------------------------------- +void TfrmAbout::btnPageClick() { + HWND hCtrl = GetDlgItem(m_hWnd, IDA_CONTRIBLINK); + if(!m_Page) { + ShowWindow(GetDlgItem(m_hWnd, IDC_CREDIT), SW_HIDE); + ShowWindow(GetDlgItem(m_hWnd, IDC_LICENSE), SW_SHOW); + SendDlgItemMessage(m_hWnd, IDA_CONTRIBLINK, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Credits >"), MBF_TCHAR); + HICON hIcon = IcoLib_GetIcon(ICO_PLUG_ARROWR); + SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + SetWindowText(hCtrl, hIcon ? TranslateT("Credits") : TranslateT("Credits >")); + } + else { + ShowWindow(GetDlgItem(m_hWnd, IDC_CREDIT), SW_SHOW); + ShowWindow(GetDlgItem(m_hWnd, IDC_LICENSE), SW_HIDE); + SendDlgItemMessage(m_hWnd, IDA_CONTRIBLINK, BUTTONADDTOOLTIP, (WPARAM)TranslateT("< Copyright"), MBF_TCHAR); + HICON hIcon = IcoLib_GetIcon(ICO_PLUG_ARROWL); + SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + SetWindowText(hCtrl, hIcon ? TranslateT("Copyright") : TranslateT("< Copyright")); + } +} diff --git a/plugins/SendScreenshotPlus/UAboutForm.h b/plugins/SendScreenshotPlus/UAboutForm.h new file mode 100644 index 0000000000..d9d598aeb6 --- /dev/null +++ b/plugins/SendScreenshotPlus/UAboutForm.h @@ -0,0 +1,69 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/UAboutForm.h $ +Revision : $Revision: 19 $ +Last change on : $Date: 2010-04-09 03:24:04 +0400 (РџС‚, 09 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef UAboutFormH +#define UAboutFormH +//--------------------------------------------------------------------------- +#include "global.h" + +//--------------------------------------------------------------------------- +class TfrmAbout{ + + public: + // Deklaration Standardkonstruktor/Standarddestructor + TfrmAbout(HWND Owner); + ~TfrmAbout(); + + HWND m_hWndOwner; + void Show(){ShowWindow(m_hWnd,SW_SHOW);} + void Hide(){ShowWindow(m_hWnd,SW_HIDE);} + void Close(){SendMessage(m_hWnd,WM_CLOSE,0,0);} + + private: + HWND m_hWnd; + + protected: + UINT m_Page; + typedef std::map CHandleMapping; + static CHandleMapping _HandleMapping; + static LRESULT CALLBACK DlgTfrmAbout(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + + LRESULT wmInitdialog(WPARAM wParam, LPARAM lParam); + LRESULT wmCommand(WPARAM wParam, LPARAM lParam); + LRESULT wmClose(WPARAM wParam, LPARAM lParam); + + void btnPageClick(); + +}; + +//--------------------------------------------------------------------------- +#endif diff --git a/plugins/SendScreenshotPlus/UMainForm.cpp b/plugins/SendScreenshotPlus/UMainForm.cpp new file mode 100644 index 0000000000..2061f80d83 --- /dev/null +++ b/plugins/SendScreenshotPlus/UMainForm.cpp @@ -0,0 +1,1180 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/UMainForm.cpp $ +Revision : $Revision: 22 $ +Last change on : $Date: 2010-05-02 21:25:02 +0400 (Р’СЃ, 02 май 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#include "UMainForm.h" +#include "UAboutForm.h" +//#include "UEditForm.h" + +//--------------------------------------------------------------------------- +INT_PTR CALLBACK TfrmMain::DlgProc_CaptureWindow(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { +// main message handling is done inside TfrmMain::DlgTfrmMain + switch (uMsg) { + case WM_INITDIALOG: + Static_SetIcon(GetDlgItem(hDlg, ID_imgTarget), IcoLib_GetIcon(ICO_PLUG_SSTARGET)); + SetDlgItemText(hDlg, ID_edtCaption, _T("Drag&&Drop the target on the desired window.")); + TranslateDialogDefault(hDlg); + break; + case WM_CTLCOLOREDIT: //ctrl is NOT read-only or disabled + case WM_CTLCOLORSTATIC: //ctrl is read-only or disabled + // make the rectangle on the top white + switch (GetWindowLongPtr((HWND)lParam, GWL_ID)) { + case IDC_WHITERECT: + case ID_chkClientArea: + case ID_lblDropInfo: + case ID_edtCaption: + case ID_edtCaptionLabel: + case ID_edtSize: + case ID_edtSizeLabel: + case ID_bvlTarget: + case ID_imgTarget: + SetBkColor((HDC)wParam,GetSysColor(COLOR_WINDOW)); + SetTextColor((HDC)wParam,GetSysColor(COLOR_WINDOWTEXT)); + + //SetBkMode((HDC)wParam,OPAQUE); + //return (INT_PTR)GetSysColorBrush(COLOR_WINDOW); + return (LRESULT)GetStockObject(WHITE_BRUSH); + break; + default: + SetBkMode((HDC)wParam, TRANSPARENT); + return (LRESULT)GetStockObject(NULL_BRUSH); + break; + } + break; //this return false + case WM_COMMAND: + SendMessage(GetParent(hDlg), uMsg, wParam, lParam); + break; + case WM_MOUSEMOVE: + SendMessage(GetParent(hDlg), UM_TAB1, uMsg, 0); + break; + case WM_NOTIFY: + SendMessage(GetParent(hDlg), uMsg, wParam, lParam); + break; + case WM_DESTROY: + break; + } + return FALSE; +} + +//--------------------------------------------------------------------------- +INT_PTR CALLBACK TfrmMain::DlgProc_CaptureDesktop(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { +// main message handling is done inside TfrmMain::DlgTfrmMain + switch (uMsg) { + case WM_INITDIALOG: + Static_SetIcon(GetDlgItem(hDlg, ID_imgTarget), IcoLib_GetIcon(ICO_PLUG_SSMONITOR)); + break; + case WM_CTLCOLOREDIT: + case WM_CTLCOLORSTATIC: + // make the rectangle on the top white + switch (GetWindowLongPtr((HWND)lParam, GWL_ID)) { + case IDC_WHITERECT: + case ID_lblDropInfo: + case ID_edtCaption: + case ID_edtCaptionLabel: + case ID_edtSize: + case ID_edtSizeLabel: + case ID_bvlTarget: + case ID_imgTarget: + SetBkColor((HDC)wParam,GetSysColor(COLOR_WINDOW)); + SetTextColor((HDC)wParam,GetSysColor(COLOR_WINDOWTEXT)); + return (LRESULT)GetStockObject(WHITE_BRUSH); + break; + default: + SetBkMode((HDC)wParam, TRANSPARENT); + return (LRESULT)GetStockObject(NULL_BRUSH); + break; + } + break; + case WM_COMMAND: + SendMessage(GetParent(hDlg), uMsg, wParam, lParam); + break; + case WM_NOTIFY: + SendMessage(GetParent(hDlg), uMsg, wParam, lParam); + break; + case WM_DESTROY: + break; + } + return FALSE; +} + +//--------------------------------------------------------------------------- + +TfrmMain::CHandleMapping TfrmMain::_HandleMapping; + +LRESULT CALLBACK TfrmMain::DlgTfrmMain(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_CTLCOLOREDIT || msg == WM_CTLCOLORSTATIC) { + switch ( GetWindowLongPtr(( HWND )lParam, GWL_ID )) { + /* case IDC_WHITERECT:*/ + case IDC_HEADERBAR: + SetTextColor((HDC)wParam,GetSysColor(COLOR_WINDOWTEXT)); + break; + default: + return FALSE; + } + SetBkColor((HDC)wParam, GetSysColor(COLOR_WINDOW)); + return (LRESULT)GetStockObject(WHITE_BRUSH); //GetSysColorBrush(COLOR_WINDOW); + } + + CHandleMapping::iterator wnd(_HandleMapping.end()); + if (msg == WM_INITDIALOG) { + wnd = _HandleMapping.insert(CHandleMapping::value_type(hWnd, reinterpret_cast(lParam))).first; + reinterpret_cast(lParam)->m_hWnd = hWnd; + return wnd->second->wmInitdialog(wParam, lParam); + } + else { + wnd = _HandleMapping.find(hWnd); + } + if (wnd == _HandleMapping.end()) { // something screwed up + return FALSE; //dialog! do not use ::DefWindowProc(hWnd, msg, wParam, lParam); + } + + switch (msg) + { + // case WM_INITDIALOG: done on top + case WM_COMMAND: + return wnd->second->wmCommand(wParam, lParam); + break; + case WM_CLOSE: + return wnd->second->wmClose(wParam, lParam); + break; + case WM_DESTROY: + delete wnd->second; + break; + case UM_TAB1: + return wnd->second->UMTab1(wParam, lParam); + break; + case WM_NOTIFY: + return wnd->second->wmNotify(wParam, lParam); + break; + case WM_TIMER: + return wnd->second->wmTimer(wParam, lParam); + break; + case UM_CLOSING: + return wnd->second->UMClosing(wParam, lParam); + break; + case UM_EVENT: + return wnd->second->UMevent(wParam, lParam); + break; + } + return FALSE; +} + +//--------------------------------------------------------------------------- +//WM_INITDIALOG: +LRESULT TfrmMain::wmInitdialog(WPARAM wParam, LPARAM lParam) { + HWND hCtrl; + //Taskbar and Window icon + SendMessage(m_hWnd, WM_SETICON, ICON_BIG, (LPARAM)IcoLib_GetIcon(ICO_PLUG_SSWINDOW1, true)); + SendMessage(m_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)IcoLib_GetIcon(ICO_PLUG_SSWINDOW2)); + LPTSTR pt = mir_a2t(__PLUGIN_NAME); + SetWindowText(m_hWnd, pt); + mir_freeAndNil(pt); + + // Headerbar + pt = mir_tstrdup((LPTSTR)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)m_hContact, (LPARAM)GCDNF_TCHAR)); + if (pt && (m_hContact != 0)) { + LPTSTR lptString = NULL; + mir_tcsadd(lptString , TranslateT("Send screenshot to\n")); + mir_tcsadd(lptString , pt); + SetDlgItemText(m_hWnd, IDC_HEADERBAR, lptString); + mir_free(lptString); + } + mir_freeAndNil(pt); + + SendMessage(GetDlgItem(m_hWnd, IDC_HEADERBAR), WM_SETICON, 0, (WPARAM)IcoLib_GetIcon(ICO_PLUG_SSWINDOW1, true)); + + //Timed controls + CheckDlgButton(m_hWnd,ID_chkTimed, m_opt_chkTimed ? BST_CHECKED : BST_UNCHECKED); + SetDlgItemInt (m_hWnd,ID_edtTimed, (UINT)m_opt_edtTimed, FALSE); + SendDlgItemMessage(m_hWnd, ID_upTimed, UDM_SETRANGE, 0, (LPARAM)MAKELONG(250, 1)); + chkTimedClick(); //enable disable Timed controls + + //create Image list for tab control + if(m_himlTab == 0){ + //m_himlTab = ImageList_Create(16, 16, PluginConfig.m_bIsXP ? ILC_COLOR32 | ILC_MASK : ILC_COLOR8 | ILC_MASK, 2, 0); + m_himlTab = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 2, 0); + ImageList_AddIcon(m_himlTab, IcoLib_GetIcon(ICO_PLUG_SSWINDOW2)); + ImageList_AddIcon(m_himlTab, IcoLib_GetIcon(ICO_PLUG_SSWINDOW2)); + } + + //create the tab control. + { + TAB_INFO itab; + RECT rcClient, rcTab; + m_hwndTab = GetDlgItem(m_hWnd, IDC_CAPTURETAB); + TabCtrl_SetItemExtra(m_hwndTab, sizeof(TAB_INFO) - sizeof(TCITEMHEADER)); + + ZeroMemory(&itab, sizeof(itab)); + itab.hwndMain = m_hWnd; + itab.hwndTab = m_hwndTab; + + GetWindowRect(m_hwndTab, &rcTab); + GetWindowRect(m_hWnd, &rcClient); + + TabCtrl_SetImageList(m_hwndTab, m_himlTab); + + // Add a tab for each of the three child dialog boxes. + itab.tcih.mask = TCIF_PARAM|TCIF_TEXT|TCIF_IMAGE; + + itab.tcih.pszText = TranslateT("Window"); + itab.tcih.iImage = 0; + itab.hwndTabPage = CreateDialog(hInst,MAKEINTRESOURCE(IDD_UMain_CaptureWindow), m_hWnd,(DLGPROC)DlgProc_CaptureWindow); + TabCtrl_InsertItem(m_hwndTab, 0, &itab); + MoveWindow(itab.hwndTabPage, (rcTab.left - rcClient.left)+2, (rcTab.top - rcClient.top), (rcTab.right - rcTab.left) - 2*5, (rcTab.bottom - rcTab.top) - 2*20, TRUE); + ShowWindow(itab.hwndTabPage, SW_HIDE); + CheckDlgButton(itab.hwndTabPage, ID_chkClientArea, m_opt_chkClientArea ? BST_CHECKED : BST_UNCHECKED); + + itab.tcih.pszText = TranslateT("Desktop"); + itab.tcih.iImage = 1; + itab.hwndTabPage = CreateDialog(hInst,MAKEINTRESOURCE(IDD_UMain_CaptureDesktop), m_hWnd, DlgProc_CaptureDesktop); + TabCtrl_InsertItem(m_hwndTab, 1, &itab); + MoveWindow(itab.hwndTabPage, (rcTab.left - rcClient.left)+2, (rcTab.top - rcClient.top), (rcTab.right - rcTab.left) - 2*5, (rcTab.bottom - rcTab.top) - 2*20, TRUE); + ShowWindow(itab.hwndTabPage, SW_HIDE); + + hCtrl = GetDlgItem(itab.hwndTabPage, ID_edtCaption); + ComboBox_ResetContent(hCtrl); + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("")) ,(DWORD)0); + ComboBox_SetCurSel (hCtrl,0); + if(m_MonitorCount >1) { + TCHAR tszTemp[120]; + for (size_t i = 0; i < m_MonitorCount; ++i) { + mir_sntprintf(tszTemp, SIZEOF(tszTemp),_T("%i. %s%s"), + i+1, + TranslateT("Monitor"), + (m_Monitors[i].dwFlags & MONITORINFOF_PRIMARY) ? TranslateT(" (primary)") : _T("") + ); + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, (LPCTSTR)tszTemp) , i+1); + } + ComboBox_SelectItemData (hCtrl, -1, m_opt_cboxDesktop); //use Workaround for MS bug ComboBox_SelectItemData + } + PostMessage(m_hWnd, WM_COMMAND, MAKEWPARAM(ID_edtCaption, CBN_SELCHANGE),(LPARAM)hCtrl); + + //select tab and set m_hwndTabPage + TabCtrl_SetCurSel(m_hwndTab, m_opt_tabCapture); + ZeroMemory(&itab, sizeof(itab)); + itab.tcih.mask = TCIF_PARAM; + TabCtrl_GetItem(m_hwndTab,TabCtrl_GetCurSel(m_hwndTab),&itab); + ShowWindow(itab.hwndTabPage,SW_SHOW); + m_hwndTabPage = itab.hwndTabPage; + } + //init Format combo box + { + hCtrl = GetDlgItem(m_hWnd, ID_cboxFormat); + ComboBox_ResetContent(hCtrl); + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, _T("PNG")),0); + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, _T("JPG")),1); + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, _T("BMP")),2); + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, _T("TIF")),3); + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, _T("GIF")),4); + ComboBox_SelectItemData (hCtrl, -1, m_opt_cboxFormat); //use Workaround for MS bug ComboBox_SelectItemData + } + //init SendBy combo box + { + hCtrl = GetDlgItem(m_hWnd, ID_cboxSendBy); + ComboBox_ResetContent(hCtrl); + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("")) ,SS_JUSTSAVE); + if (m_hContact) { + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("File Transfer")),SS_FILESEND); + } + else if(m_opt_cboxSendBy == SS_FILESEND) { + m_opt_cboxSendBy = SS_IMAGESHACK; + } + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("E-mail")) ,SS_EMAIL); + if (myGlobals.PluginHTTPExist) { + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, _T("HTTP Server")) ,SS_HTTPSERVER); + } + else if(m_opt_cboxSendBy == SS_HTTPSERVER) { + m_opt_cboxSendBy = SS_IMAGESHACK; + } + if (myGlobals.PluginFTPExist) { + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("FTP File")) ,SS_FTPFILE); + } + else if(m_opt_cboxSendBy == SS_FTPFILE) { + m_opt_cboxSendBy = SS_IMAGESHACK; + } + ComboBox_SetItemData(hCtrl, ComboBox_AddString(hCtrl, TranslateT("ImageShack")) ,(BYTE)SS_IMAGESHACK); + ComboBox_SelectItemData (hCtrl, -1, m_opt_cboxSendBy); //use Workaround for MS bug ComboBox_SelectItemData + cboxSendByChange(); //enable disable controls + } + //init footer options + CheckDlgButton(m_hWnd,ID_chkOpenAgain, m_opt_chkOpenAgain ? BST_CHECKED : BST_UNCHECKED); + + if (hCtrl = GetDlgItem(m_hWnd, ID_btnAbout)) { + SendDlgItemMessage(m_hWnd, ID_btnAbout, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Information"), MBF_TCHAR); + HICON hIcon = IcoLib_GetIcon(ICO_PLUG_SSHELP); + SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + SetWindowText(hCtrl, hIcon ? _T("") : _T("?")); + } + + if (hCtrl = GetDlgItem(m_hWnd, ID_btnExplore)) { + SendDlgItemMessage(m_hWnd, ID_btnExplore, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Open Folder"), MBF_TCHAR); + HICON hIcon = IcoLib_GetIcon(ICO_PLUG_SSFOLDERO); + SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + SetWindowText(hCtrl, hIcon ? _T("") : _T("...")); + } + + if (hCtrl = GetDlgItem(m_hWnd, ID_btnDesc)) { + SendDlgItemMessage(m_hWnd, ID_btnDesc, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Fill description textbox."), MBF_TCHAR); + HICON hIcon = IcoLib_GetIcon(m_opt_btnDesc ? ICO_PLUG_SSDESKON : ICO_PLUG_SSDESKOFF); + SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + SetWindowText(hCtrl, hIcon ? _T("") : _T("D")); + SendMessage(hCtrl, BM_SETCHECK, m_opt_btnDesc ? BST_CHECKED : BST_UNCHECKED, NULL); + } + + if (hCtrl = GetDlgItem(m_hWnd, ID_btnDeleteAfterSend)) { + SendDlgItemMessage(m_hWnd, ID_btnDeleteAfterSend, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Delete after send"), MBF_TCHAR); + HICON hIcon = IcoLib_GetIcon(m_opt_btnDeleteAfterSend ? ICO_PLUG_SSDELON : ICO_PLUG_SSDELOFF); + SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + SetWindowText(hCtrl, hIcon ? _T("") : _T("X")); + SendMessage(hCtrl, BM_SETCHECK, m_opt_btnDeleteAfterSend ? BST_CHECKED : BST_UNCHECKED, NULL); + } + + if (hCtrl = GetDlgItem(m_hWnd, ID_btnCapture)) { + SendDlgItemMessage(m_hWnd, ID_btnCapture, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Capture"), MBF_TCHAR); + HICON hIcon = IcoLib_GetIcon(ICO_BTN_OK); + SendMessage(hCtrl, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + SetWindowText(hCtrl, TranslateT("&Capture")); + SendMessage(hCtrl, BUTTONSETDEFAULT, (WPARAM)1, NULL); + } + +// CheckDlgButton(m_hWnd,ID_chkEditor, m_opt_chkEditor ? BST_CHECKED : BST_UNCHECKED); + TranslateDialogDefault(m_hWnd); + return FALSE; +} + +//WM_COMMAND: +LRESULT TfrmMain::wmCommand(WPARAM wParam, LPARAM lParam) { + //--------------------------------------------------------------------------- + int IDControl = LOWORD(wParam); + switch (HIWORD(wParam)) { + case BN_CLICKED: //Button controls + switch(IDControl) { + case IDCANCEL: + case IDCLOSE: + break; + + case ID_chkTimed: + m_opt_chkTimed = (BYTE)Button_GetCheck((HWND)lParam); + TfrmMain::chkTimedClick(); + break; + case ID_chkClientArea: + m_opt_chkClientArea = (BYTE)Button_GetCheck((HWND)lParam); + if(m_hTargetWindow) + edtSizeUpdate(m_hTargetWindow, m_opt_chkClientArea, GetParent((HWND)lParam), ID_edtSize); + break; + case ID_chkOpenAgain: + m_opt_chkOpenAgain = (BYTE)Button_GetCheck((HWND)lParam); + break; + case ID_chkEditor: + m_opt_chkEditor = (BYTE)Button_GetCheck((HWND)lParam); + break; + + case ID_btnAbout: + TfrmMain::btnAboutClick(); + break; + case ID_btnExplore: + TfrmMain::btnExploreClick(); + break; + case ID_btnDesc: + { + m_opt_btnDesc = (m_opt_btnDesc == 0); + HICON hIcon = IcoLib_GetIcon(m_opt_btnDesc ? ICO_PLUG_SSDESKON : ICO_PLUG_SSDESKOFF); + SendMessage((HWND)lParam, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + } + break; + case ID_btnDeleteAfterSend: + { + m_opt_btnDeleteAfterSend = (m_opt_btnDeleteAfterSend == 0); + HICON hIcon = IcoLib_GetIcon(m_opt_btnDeleteAfterSend ? ICO_PLUG_SSDELON : ICO_PLUG_SSDELOFF); + SendMessage((HWND)lParam, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + if(m_cSend) m_cSend->m_bDeleteAfterSend = m_opt_btnDeleteAfterSend; + } + break; + case ID_btnCapture: + TfrmMain::btnCaptureClick(); + break; + default: + break; + } + break; + case CBN_SELCHANGE: //ComboBox controls + switch(IDControl) { + //lParam = Handle to the control + case ID_cboxFormat: //not finish + m_opt_cboxFormat = (BYTE)ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam)); + break; + case ID_cboxSendBy: + m_opt_cboxSendBy = (BYTE)ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam)); + cboxSendByChange(); + break; + case ID_edtCaption: //cboxDesktopChange + m_opt_cboxDesktop = (BYTE)ComboBox_GetItemData((HWND)lParam, ComboBox_GetCurSel((HWND)lParam)); + m_hTargetWindow = 0; + if (m_opt_cboxDesktop > 0) { + edtSizeUpdate(m_Monitors[m_opt_cboxDesktop-1].rcMonitor, GetParent((HWND)lParam), ID_edtSize); + } + else { + edtSizeUpdate(m_VirtualScreen, GetParent((HWND)lParam), ID_edtSize); + } + break; + default: + break; + } + break; + case EN_CHANGE: //Edit controls + switch(IDControl) { + //lParam = Handle to the control + case ID_edtQuality: + m_opt_edtQuality = (BYTE)GetDlgItemInt(m_hWnd, ID_edtQuality, NULL, FALSE); + break; + case ID_edtTimed: + m_opt_edtTimed = (BYTE)GetDlgItemInt(m_hWnd, ID_edtTimed, NULL, FALSE); + break; + default: + break; + } + break; + default: + break; + } + return FALSE; +} + +//WM_CLOSE: +LRESULT TfrmMain::wmClose(WPARAM wParam, LPARAM lParam) { + DestroyWindow(m_hWnd); + return FALSE; +} + +//WM_TIMER: +LRESULT TfrmMain::wmTimer(WPARAM wParam, LPARAM lParam) { + if (wParam == ID_bvlTarget) { // Timer for Target selector + if (m_hCursor) { //imgTarget is activ + //LmouseButton = false + if (!GetLmouse()) { + TfrmMain::imgTargetMouseUp(); + return FALSE; + } + //Timer action if LmouseButton = true + m_hLastWin = m_hTargetWindow; + POINT point={0}; + GetCursorPos(&point); + HWND hCurrentWin = WindowFromPoint(point); + while (GetParent(hCurrentWin)) { + hCurrentWin = GetParent(hCurrentWin); + } + if (m_hLastWin != hCurrentWin) { + LPTSTR lpTitle = NULL; + if (m_hLastWin) { + DrawBorderInverted(m_hLastWin); + } + int Count = GetWindowTextLength(hCurrentWin)+1; + if(Count > 1){ + lpTitle = (LPTSTR)mir_alloc(Count*sizeof(TCHAR)); + GetWindowText(hCurrentWin, lpTitle, Count); + } + else { + //no WindowText present, use WindowClass + lpTitle = (LPTSTR)mir_alloc(MAX_PATH*sizeof(TCHAR)); + RealGetWindowClass(hCurrentWin, lpTitle, MAX_PATH); + } + SetDlgItemText(m_hwndTabPage, ID_edtCaption, lpTitle); + mir_free(lpTitle); + edtSizeUpdate(hCurrentWin, m_opt_chkClientArea, m_hwndTabPage, ID_edtSize); + DrawBorderInverted(hCurrentWin); + m_hTargetWindow = hCurrentWin; + } + return FALSE; + } + //imgTarget is not activ (check if cursor is over ID_bvlTarget control) + RECT rc; + POINT pt; + GetWindowRect(GetDlgItem(m_hwndTabPage, wParam),&rc); + GetCursorPos(&pt); + //check Mouse cursor + if(!PtInRect(&rc,pt)) { // mouse must be gone, trigger mouse leave + //PostMessage(m_hWnd,WM_MOUSELEAVE,wParam,lParam); + KillTimer(m_hWnd,wParam); + } + else if (GetLmouse() && !m_hCursor) { //mouse hover + LButton + TfrmMain::imgTargetMouseDown(); + } + } + if (wParam == ID_chkTimed) { // Timer for Screenshot + #ifdef _DEBUG + OutputDebugStringA("SS Bitmap Timer Start\r\n" ); + #endif + if(!m_bCapture) { //only start once + if (m_Screenshot) { + FIP->FI_Unload(m_Screenshot); + m_Screenshot = NULL; + } + m_bCapture = true; + switch (m_opt_tabCapture) { + case 0: + m_Screenshot = CaptureWindow(m_hTargetWindow, (BOOL)m_opt_chkClientArea); + break; + case 1: + m_Screenshot = CaptureMonitor((m_opt_cboxDesktop > 0) ? m_Monitors[m_opt_cboxDesktop-1].szDevice : NULL); + break; + default: + KillTimer(m_hWnd,wParam); + m_bCapture = false; + #ifdef _DEBUG + OutputDebugStringA("SS Bitmap Timer Stop (no tabCapture)\r\n" ); + #endif + return FALSE; + } + if (!m_Screenshot) m_bCapture = false; + } + if (m_Screenshot) { + KillTimer(m_hWnd,wParam); + m_bCapture = false; + #ifdef _DEBUG + OutputDebugStringA("SS Bitmap Timer Stop (CaptureDone)\r\n" ); + #endif + SendMessage(m_hWnd,UM_EVENT, (WPARAM)0, (LPARAM)EVT_CaptureDone); + } + } + return FALSE; +} + +//WM_NOTIFY: +LRESULT TfrmMain::wmNotify(WPARAM wParam, LPARAM lParam) { + switch(((LPNMHDR)lParam)->idFrom) { + case IDC_CAPTURETAB: //TabControl IDC_CAPTURETAB + switch (((LPNMHDR)lParam)->code) { + // HWND hwndFrom; = member is handle to the tab control + // UINT_PTR idFrom; = member is the child window identifier of the tab control. + // UINT code; = member is TCN_SELCHANGE + case TCN_SELCHANGING: + { + TAB_INFO itab; + ZeroMemory(&itab, sizeof(itab)); + itab.tcih.mask = TCIF_PARAM; + TabCtrl_GetItem(m_hwndTab,TabCtrl_GetCurSel(m_hwndTab),&itab); + ShowWindow(itab.hwndTabPage,SW_HIDE); + m_hwndTabPage = NULL; + } + break; + + case TCN_SELCHANGE: + { + TAB_INFO itab; + ZeroMemory(&itab, sizeof(itab)); + itab.tcih.mask = TCIF_PARAM; + m_opt_tabCapture = TabCtrl_GetCurSel(m_hwndTab); + TabCtrl_GetItem(m_hwndTab, m_opt_tabCapture, &itab); + ShowWindow(itab.hwndTabPage, SW_SHOW); + m_hwndTabPage = itab.hwndTabPage; + } + break; + default: + break; + } + break; + default: + break; + } + return FALSE; +} + +//UM_CLOSING: +LRESULT TfrmMain::UMClosing(WPARAM wParam, LPARAM lParam) { + HWND hWnd = (HWND)wParam; + switch (lParam) { + case IDD_UAboutForm: + btnAboutOnCloseWindow(hWnd); + break; + case IDD_UEditForm: + ; + break; + default: + break; + } + return FALSE; +} + +//UM_TAB1: +LRESULT TfrmMain::UMTab1(WPARAM wParam, LPARAM lParam) { + switch (wParam) { + case WM_MOUSEMOVE: + if (m_opt_tabCapture == 0) { + // Call timer, used to start cheesy TrackMouseEvent faker + SetTimer(m_hWnd,ID_bvlTarget,BUTTON_POLLDELAY,NULL); + } + break; + default: + break; + } + return FALSE; +} + +//UM_EVENT: +LRESULT TfrmMain::UMevent(WPARAM wParam, LPARAM lParam) { + //HWND hWnd = (HWND)wParam; + switch (lParam) { + case EVT_CaptureDone: + if (!m_Screenshot) { + TCHAR *err = TranslateT("Cant create a Screenshot"); + MessageBox(m_hWnd,err,ERROR_TITLE,MB_OK|MB_ICONWARNING); + Show(); + return FALSE; + } + if (m_opt_chkEditor) { + /* TfrmEdit *frmEdit=new TfrmEdit(this); + m_bFormEdit = true; + + frmEdit->mniClose->Enabled = !chkJustSaveIt->Checked; + frmEdit->mniCloseSend->Enabled = frmEdit->mniClose->Enabled; + frmEdit->OnClose = OnCloseEditWindow; + frmEdit->InitEditor(Screenshot); // Screenshot is copied to another in-memory bitmap inside this method + frmEdit->Show(); + delete Screenshot; // This way we can delete it after the method returns + Screenshot = NULL; + */ + return FALSE; + } + else { + FormClose(); + } + break; + case EVT_SendFileDone: + break; + case EVT_CheckOpenAgain: + if (m_opt_chkOpenAgain) { + if (m_Screenshot) { + FIP->FI_Unload(m_Screenshot); + m_Screenshot = NULL; + } + m_hTargetWindow = m_hLastWin = NULL; + Show(); + } + else { + // Saving Options and close + SaveOptions(); + Close(); + } + break; + default: + break; + } + return FALSE; +} + +//--------------------------------------------------------------------------- +// Standard konstruktor/destruktor +TfrmMain::TfrmMain() { + m_hWnd = NULL; + m_hContact = NULL; + m_hTargetWindow = NULL; + m_hCursor = NULL; + m_Screenshot = NULL; + m_pszFile = m_pszFileDesc = m_FDestFolder = NULL; + m_bFormAbout = m_bFormEdit = m_bDeleteAfterSend = m_bSelectingWindow = false; + m_cSend = NULL; + m_bOnExitSave = TRUE; + LoadOptions(); + m_bCapture = false; + m_himlTab = NULL; + m_Monitors = NULL; + m_MonitorCount = MonitorInfoEnum(m_Monitors, m_VirtualScreen); + +} + +TfrmMain::~TfrmMain() { + _HandleMapping.erase(m_hWnd); + mir_free(m_pszFile); + mir_free(m_FDestFolder); + mir_free(m_pszFileDesc); + mir_free(m_Monitors); + if (m_Screenshot) FIP->FI_Unload(m_Screenshot); + if (m_cSend) delete m_cSend; +} + +//--------------------------------------------------------------------------- +// Load / Saving options from miranda's database +void TfrmMain::LoadOptions(void) { + DWORD rgb = DBGetContactSettingDword(NULL, SZ_SENDSS, "AlphaColor", 16777215); + m_AlphaColor.rgbRed = GetRValue(rgb); + m_AlphaColor.rgbGreen = GetGValue(rgb); + m_AlphaColor.rgbBlue = GetBValue(rgb); + m_AlphaColor.rgbReserved = 0; + +// m_opt_chkEmulateClick = DBGetContactSettingByte(NULL, SZ_SENDSS, "AutoSend", 1); + m_opt_edtQuality = DBGetContactSettingByte(NULL, SZ_SENDSS, "JpegQuality", 75); + + m_opt_tabCapture = DBGetContactSettingByte(NULL, SZ_SENDSS, "Capture", 0); + m_opt_chkClientArea = DBGetContactSettingByte(NULL, SZ_SENDSS, "ClientArea", 0); + m_opt_cboxDesktop = DBGetContactSettingByte(NULL, SZ_SENDSS, "Desktop", 0); + + m_opt_chkTimed = DBGetContactSettingByte(NULL, SZ_SENDSS, "TimedCap", 0); + m_opt_edtTimed = DBGetContactSettingByte(NULL, SZ_SENDSS, "CapTime", 3); + m_opt_cboxFormat = DBGetContactSettingByte(NULL, SZ_SENDSS, "OutputFormat", 3); + m_opt_cboxSendBy = DBGetContactSettingByte(NULL, SZ_SENDSS, "SendBy", 0); + + m_opt_chkEditor = DBGetContactSettingByte(NULL, SZ_SENDSS, "Preview", 0); + m_opt_btnDesc = DBGetContactSettingByte(NULL, SZ_SENDSS, "AutoDescription", 1); + m_opt_btnDeleteAfterSend = DBGetContactSettingByte(NULL, SZ_SENDSS, "DelAfterSend", 1); + m_opt_chkOpenAgain = DBGetContactSettingByte(NULL, SZ_SENDSS, "OpenAgain", 0); +} + +void TfrmMain::SaveOptions(void) { + if(m_bOnExitSave) { + DBWriteContactSettingDword(NULL, SZ_SENDSS, "AlphaColor", + (DWORD)RGB(m_AlphaColor.rgbRed, m_AlphaColor.rgbGreen, m_AlphaColor.rgbBlue)); + +// DBWriteContactSettingByte(NULL, SZ_SENDSS, "AutoSend", m_opt_chkEmulateClick); + DBWriteContactSettingByte(NULL, SZ_SENDSS, "JpegQuality", m_opt_edtQuality); + + DBWriteContactSettingByte(NULL, SZ_SENDSS, "Capture", m_opt_tabCapture); + DBWriteContactSettingByte(NULL, SZ_SENDSS, "ClientArea", m_opt_chkClientArea); + DBWriteContactSettingByte(NULL, SZ_SENDSS, "Desktop", m_opt_cboxDesktop); + + DBWriteContactSettingByte(NULL, SZ_SENDSS, "TimedCap", m_opt_chkTimed); + DBWriteContactSettingByte(NULL, SZ_SENDSS, "CapTime", m_opt_edtTimed); + DBWriteContactSettingByte(NULL, SZ_SENDSS, "OutputFormat", m_opt_cboxFormat); + DBWriteContactSettingByte(NULL, SZ_SENDSS, "SendBy", m_opt_cboxSendBy); + + DBWriteContactSettingByte(NULL, SZ_SENDSS, "AutoDescription", m_opt_btnDesc); + DBWriteContactSettingByte(NULL, SZ_SENDSS, "DelAfterSend", m_opt_btnDeleteAfterSend); + DBWriteContactSettingByte(NULL, SZ_SENDSS, "OpenAgain", m_opt_chkOpenAgain); + DBWriteContactSettingByte(NULL, SZ_SENDSS, "Preview", m_opt_chkEditor); + } +} + +//--------------------------------------------------------------------------- +void TfrmMain::Init(LPTSTR DestFolder, HANDLE Contact) { + m_FDestFolder = mir_tstrdup(DestFolder); + m_hContact = Contact; + if(!m_hContact) m_opt_cboxSendBy = SS_JUSTSAVE; + + // create window + m_hWnd = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_UMainForm),0, (DLGPROC)DlgTfrmMain,(LPARAM)this); + //register object + _HandleMapping.insert(CHandleMapping::value_type(m_hWnd, this)); + + //check Contact + if(m_cSend) m_cSend->SetContact(Contact); +} + +//--------------------------------------------------------------------------- +void TfrmMain::btnCaptureClick() { + m_bFormEdit = false; //until UEditForm is includet + + if (m_opt_tabCapture == 0 && m_hTargetWindow == 0) { + TCHAR *err = TranslateT("Select a target window."); + MessageBox(m_hWnd,err,ERROR_TITLE,MB_OK|MB_ICONWARNING); + return; + } + TfrmMain::Hide(); + + if (!m_hTargetWindow) m_hTargetWindow = GetDesktopWindow(); + + if (m_opt_chkTimed) { + SetTimer(m_hWnd, ID_chkTimed, m_opt_edtTimed ? m_opt_edtTimed*1000 : 500, NULL); + } + else if (m_opt_tabCapture == 1){ + //desktop need always time to update from TfrmMain::Hide() + SetTimer(m_hWnd, ID_chkTimed, 500, NULL); + } + else { + m_Screenshot = CaptureWindow(m_hTargetWindow, (BOOL)(m_opt_chkClientArea)); + SendMessage(m_hWnd,UM_EVENT, (WPARAM)0, (LPARAM)EVT_CaptureDone); + } +} + +//--------------------------------------------------------------------------- +void TfrmMain::chkTimedClick() { + Button_Enable(GetDlgItem(m_hWnd, ID_edtTimedLabel), (BOOL)m_opt_chkTimed); + Button_Enable(GetDlgItem(m_hWnd, ID_edtTimed), (BOOL)m_opt_chkTimed); + Button_Enable(GetDlgItem(m_hWnd, ID_upTimed), (BOOL)m_opt_chkTimed); +} + +//--------------------------------------------------------------------------- +void TfrmMain::imgTargetMouseDown() { + //if (Button != mbLeft) return; + m_hCursor = CopyCursor(GetCursor()); //backup cursor + //SetSystemCursor need a copy coz it destroy the handle + SetSystemCursor(CopyCursor(IcoLib_GetIcon(ICO_PLUG_SSTARGET)),OCR_NORMAL); + m_bSelectingWindow = true; + m_hTargetWindow = NULL; + Hide(); + SetCapture(m_hWnd); +} + +//--------------------------------------------------------------------------- +void TfrmMain::imgTargetMouseUp() { + //if (Button == mbLeft && m_bSelectingWindow && TimerCheckFocus->Enabled) + if (m_bSelectingWindow && m_hCursor) { + Show(); + ReleaseCapture(); + SetSystemCursor(m_hCursor, OCR_NORMAL); + m_hCursor = NULL; + if (m_hTargetWindow){ + DrawBorderInverted(m_hTargetWindow); + } + m_bSelectingWindow = false; + } +} + +//--------------------------------------------------------------------------- +void TfrmMain::cboxSendByChange() { + BOOL bState; + HICON hIcon; + BYTE itemFlag = SS_DLG_DESCRIPTION; //SS_DLG_AUTOSEND | SS_DLG_DELETEAFTERSSEND | + if (m_cSend && !m_cSend->m_bFreeOnExit) { + delete m_cSend; + m_cSend = NULL; + } + switch(m_opt_cboxSendBy) { + case SS_FILESEND: //"File Transfer" + m_cSend = new CSendFile(m_hWnd, m_hContact, false); + break; + case SS_EMAIL: //"E-mail" + m_cSend = new CSendEmail(m_hWnd, m_hContact, false); + break; + case SS_HTTPSERVER: //"HTTP Server" + m_cSend = new CSendHTTPServer(m_hWnd, m_hContact, false); + break; + case SS_FTPFILE: //"FTP File" + m_cSend = new CSendFTPFile(m_hWnd, m_hContact, false); + break; + case SS_IMAGESHACK: //"ImageShack" + m_cSend = new CSendImageShack(m_hWnd, m_hContact, false); + break; + default: //SS_JUSTSAVE - "Just save it " + m_cSend = NULL; + break; + } + if(m_cSend){ + itemFlag = m_cSend->GetEnableItem(); + m_cSend->m_bDeleteAfterSend = m_opt_btnDeleteAfterSend; + } + bState = ((itemFlag & SS_DLG_DELETEAFTERSSEND) == SS_DLG_DELETEAFTERSSEND); + hIcon = IcoLib_GetIcon(m_opt_btnDeleteAfterSend ? ICO_PLUG_SSDELON : ICO_PLUG_SSDELOFF); + SendMessage(GetDlgItem(m_hWnd, ID_btnDeleteAfterSend), BM_SETIMAGE, IMAGE_ICON, (LPARAM)(bState ? hIcon : 0)); + Button_Enable(GetDlgItem(m_hWnd, ID_btnDeleteAfterSend), bState); + + bState = ((itemFlag & SS_DLG_DESCRIPTION) == SS_DLG_DESCRIPTION); + hIcon = IcoLib_GetIcon(m_opt_btnDesc ? ICO_PLUG_SSDESKON : ICO_PLUG_SSDESKOFF); + SendMessage(GetDlgItem(m_hWnd, ID_btnDesc), BM_SETIMAGE, IMAGE_ICON, (LPARAM)(bState ? hIcon : 0)); + Button_Enable(GetDlgItem(m_hWnd, ID_btnDesc), bState); +} + +//--------------------------------------------------------------------------- +void TfrmMain::btnAboutClick() { + if (m_bFormAbout) return; + + TfrmAbout *frmAbout=new TfrmAbout(m_hWnd); + frmAbout->Show(); + m_bFormAbout = true; +} + +// Edit window call this event before it closes +void TfrmMain::btnAboutOnCloseWindow(HWND hWnd) { + m_bFormAbout = false; +} + +//--------------------------------------------------------------------------- +void TfrmMain::btnExploreClick() { + if (m_FDestFolder) + ShellExecute(NULL, _T("explore"), m_FDestFolder, NULL, NULL, SW_SHOW); +} + +//--------------------------------------------------------------------------- +void TfrmMain::edtSizeUpdate(HWND hWnd, BOOL ClientArea, HWND hTarget, UINT Ctrl) { + // get window dimensions + RECT rect = {0}; + RECT cliRect = {0}; + TCHAR B[33], H[16]; + GetWindowRect(hWnd, &rect); + if (ClientArea) { + POINT pt = {0}; + GetClientRect(hWnd, &cliRect); + pt.x = cliRect.left; + pt.y = cliRect.top; + ClientToScreen(hWnd, &pt); + pt.x = pt.x - rect.left; //offset x for client area + pt.y = pt.y - rect.top; //offset y for client area + rect = cliRect; + } +// _itot_s(rect.right - rect.left, B, 33, 10); + _itot(rect.right - rect.left, B, 10); +// _itot_s(rect.bottom - rect.top, H, 16, 10); + _itot(rect.bottom - rect.top, H, 10); + mir_tcsncat(B, _T("x"), 33); + mir_tcsncat(B, H, 33); + SetDlgItemText(hTarget, Ctrl, B); +} + +void TfrmMain::edtSizeUpdate(RECT rect, HWND hTarget, UINT Ctrl) { + TCHAR B[33], H[16]; +// _itot_s(ABS(rect.right - rect.left), B, 33, 10); + _itot(ABS(rect.right - rect.left), B, 10); +// _itot_s(ABS(rect.bottom - rect.top), H, 16, 10); + _itot(ABS(rect.bottom - rect.top), H, 10); + mir_tcsncat(B, _T("x"), 33); + mir_tcsncat(B, H, 33); + SetDlgItemText(hTarget, Ctrl, B); +} + +//--------------------------------------------------------------------------- +INT_PTR TfrmMain::SaveScreenshot(FIBITMAP* dib) { + //generate File name + FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; + LPTSTR ret = NULL; + LPTSTR path = NULL; + LPTSTR pszFilename = NULL; + LPTSTR pszFileDesc = NULL; + if (!dib) return 1; //error + + //Generate FileName + mir_tcsadd(path, m_FDestFolder); + if (path[_tcslen(path)-1] != _T('\\')) mir_tcsadd(path, _T("\\")); + mir_tcsadd(path, _T("shot%.5ld")); + int FileNumber=DBGetContactSettingDword(NULL, SZ_SENDSS, "FileNumber", 0) + 1; + // '00000'-'%.5ld'=0 (add more or less len if differ from 5 + size_t len = (_tcslen(path)+0+1); + pszFilename = (LPTSTR)mir_alloc(sizeof(TCHAR)*(len)); + mir_sntprintf(pszFilename, len, path, FileNumber); + mir_free(path); + + //Generate a description according to the screenshot + TCHAR winText[1024]; + mir_tcsadd(pszFileDesc, _T("Screenshot ")); + if (m_opt_tabCapture == 0 && m_opt_chkClientArea) { + mir_tcsadd(pszFileDesc, _T("for Client area ")); + } + mir_tcsadd(pszFileDesc, _T("of \"")); + GetDlgItemText(m_hwndTabPage, ID_edtCaption, winText, 1024); + mir_tcsadd(pszFileDesc, winText); + mir_tcsadd(pszFileDesc, _T("\" Window")); + + // convert to 32Bits (make shure it is 32bit) + FIBITMAP *dib_new = FIP->FI_ConvertTo32Bits(dib); + //RGBQUAD appColor = { 245, 0, 254, 0 }; //bgr0 schwarz + //FIP->FI_SetBackgroundColor(dib_new, &appColor); + FIP->FI_SetTransparent(dib_new,TRUE); + + // Investigates the color type of the bitmap (test for RGB or CMYK colour space) + switch (FREE_IMAGE_COLOR_TYPE ColTye=FIP->FI_GetColorType(dib_new)) { + case FIC_MINISBLACK: + //Monochrome bitmap (1-bit) : first palette entry is black. + //Palletised bitmap (4 or 8-bit) and single channel non standard bitmap: the bitmap has a greyscale palette + case FIC_MINISWHITE: + //Monochrome bitmap (1-bit) : first palette entry is white. + //Palletised bitmap (4 or 8-bit) : the bitmap has an inverted greyscale palette + case FIC_PALETTE: + //Palettized bitmap (1, 4 or 8 bit) + case FIC_RGB: + //High-color bitmap (16, 24 or 32 bit), RGB16 or RGBF + case FIC_RGBALPHA: + //High-color bitmap with an alpha channel (32 bit bitmap, RGBA16 or RGBAF) + case FIC_CMYK: + //CMYK bitmap (32 bit only) + default: + break; + } + + + if ((FIP->FI_GetICCProfile(dib_new)->flags & FIICC_COLOR_IS_CMYK) == FIICC_COLOR_IS_CMYK) { + // we are in CMYK colour space + bool bDummy = false; + } + else { + // we are in RGB colour space + bool bDummy = true; + } + + FIBITMAP *dib32 = NULL; + FIBITMAP *dib24 = NULL; + HWND hwndCombo = GetDlgItem(m_hWnd, ID_cboxFormat); + switch (ComboBox_GetItemData(hwndCombo, ComboBox_GetCurSel(hwndCombo))) { + case 0: //PNG + ret = SaveImage(fif,dib_new, pszFilename, _T("png")); + break; + + case 1: //JPG + /* + #define JPEG_QUALITYSUPERB 0x80 // save with superb quality (100:1) + #define JPEG_QUALITYGOOD 0x0100 // save with good quality (75:1) + #define JPEG_QUALITYNORMAL 0x0200 // save with normal quality (50:1) + #define JPEG_QUALITYAVERAGE 0x0400 // save with average quality (25:1) + #define JPEG_QUALITYBAD 0x0800 // save with bad quality (10:1) + #define JPEG_PROGRESSIVE 0x2000 // save as a progressive-JPEG (use | to combine with other save flags) + */ + dib32 = FIP->FI_Composite(dib_new,FALSE,&m_AlphaColor,NULL); + dib24 = FIP->FI_ConvertTo24Bits(dib32); + FIP->FI_Unload(dib32); dib32 = NULL; + ret = SaveImage(fif,dib24, pszFilename, _T("jpg")); + FIP->FI_Unload(dib24); dib24 = NULL; + break; + + case 2: //BMP + // ret = SaveImage(FIF_BMP,dib_new, pszFilename, _T("bmp")); //32bit alpha BMP + dib32 = FIP->FI_Composite(dib_new,FALSE,&m_AlphaColor,NULL); + dib24 = FIP->FI_ConvertTo24Bits(dib32); + FIP->FI_Unload(dib32); dib32 = NULL; + ret = SaveImage(FIF_BMP,dib24, pszFilename, _T("bmp")); + FIP->FI_Unload(dib24); dib24 = NULL; + break; + + case 3: //TIFF (miranda freeimage interface do not support save tiff, we udse GDI+) + { + LPTSTR pszFile = NULL; + mir_tcsadd(pszFile, pszFilename); + mir_tcsadd(pszFile, _T(".tif")); + + dib32 = FIP->FI_Composite(dib_new,FALSE,&m_AlphaColor,NULL); + dib24 = FIP->FI_ConvertTo24Bits(dib32); + FIP->FI_Unload(dib32); dib32 = NULL; + + HBITMAP hBmp = FIP->FI_CreateHBITMAPFromDIB(dib24); + FIP->FI_Unload(dib24); dib24 = NULL; + ret = SaveTIF(hBmp, pszFile) ? NULL : pszFile; + DeleteObject(hBmp); + } + break; + + case 4: //GIF + { + //dib24 = FIP->FI_ConvertTo8Bits(dib_new); + //ret = SaveImage(FIF_GIF,dib24, pszFilename, _T("gif")); + //FIP->FI_Unload(dib24); dib24 = NULL; + LPTSTR pszFile = NULL; + mir_tcsadd(pszFile, pszFilename); + mir_tcsadd(pszFile, _T(".gif")); + HBITMAP hBmp = FIP->FI_CreateHBITMAPFromDIB(dib_new); + SaveGIF(hBmp, pszFile); + ret = pszFile; + DeleteObject(hBmp); + } + break; + + default: + break; + } +/* //load PNG and save file in user format (if differ) + //this get better result for transparent aereas + //LPTSTR pszFormat = (LPTSTR)ComboBox_GetItemData(hwndCombo, ComboBox_GetCurSel(hwndCombo)); + TCHAR pszFormat[6]; + ComboBox_GetText(hwndCombo, pszFormat, 6); + if(ret && (_tcsicmp (pszFormat,_T("png")) != 0)) { + #if defined(_UNICODE) + fif = FIP->FI_GetFIFFromFilenameU(ret); + dib_new = FIP->FI_LoadU(fif, ret,0); + #else + fif = FIP->FI_GetFIFFromFilenameU(ret); + dib_new = FIP->FI_Load(fif, ret,0); + #endif + + if(dib_new) { + DeleteFile(ret); + mir_freeAndNil(ret); + FIBITMAP *dib_save = FIP->FI_ConvertTo24Bits(dib_new); + ret = SaveImage(FIF_UNKNOWN,dib_save, pszFilename, pszFormat); + FIP->FI_Unload(dib_new); dib_new = NULL; + FIP->FI_Unload(dib_save); dib_save = NULL; + } + }*/ + FIP->FI_Unload(dib_new); dib_new = NULL; + mir_freeAndNil(pszFilename); + + if (ret) { + DBWriteContactSettingDword(NULL, SZ_SENDSS, "FileNumber", (DWORD)FileNumber); + mir_freeAndNil(m_pszFile); + mir_freeAndNil(m_pszFileDesc); + m_pszFile = ret; + if (IsWindowEnabled(GetDlgItem(m_hWnd, ID_btnDesc)) && m_opt_btnDesc) { + m_pszFileDesc = pszFileDesc; + } + else { + mir_tcsadd(m_pszFileDesc, _T("")); + } + + if(m_cSend) { + mir_freeAndNil(m_cSend->m_pszFile); + mir_freeAndNil(m_cSend->m_pszFileDesc); + m_cSend->m_pszFile = mir_tstrdup(m_pszFile); + m_cSend->m_pszFileDesc = mir_tstrdup(m_pszFileDesc); + } + return 0; //OK + } + mir_freeAndNil(ret); + mir_freeAndNil(pszFileDesc); + return 1; //error +} + +//--------------------------------------------------------------------------- +void TfrmMain::FormClose() { + + // Saving the screenshot + if (SaveScreenshot(m_Screenshot)) { + Show(); // Error from SaveScreenshot + return; + } + + if (m_cSend && m_pszFile && m_hContact && !m_bFormEdit) { + m_cSend->Send(); + if (m_cSend->m_bFreeOnExit) cboxSendByChange(); +// Not finish delete this if events from m_opt_cboxSendBy implementet + SendMessage(m_hWnd,UM_EVENT, (WPARAM)0, (LPARAM)EVT_CheckOpenAgain); + } + else { + SendMessage(m_hWnd,UM_EVENT, (WPARAM)0, (LPARAM)EVT_CheckOpenAgain); + } +} + +//--------------------------------------------------------------------------- +/*/ Edit window call this event before it closes +void TfrmMain::OnCloseEditWindow(TObject *Sender, TCloseAction &Action) { + TfrmEdit *form=dynamic_cast(Sender); + form->Hide(); + + // delete the form automatically,after this event returns + Action = caFree; + + // This will saves settings, free resources, ... + form->CallBeforeClose(Action); + + // User selected "Capture" on action menu of edit window + if (form->ModalResult == mrCancel) { + this->Show(); + } else { + Screenshot = form->Screen; + bFormEdit = form->DontSend; + this->Close(); + } +}*/ + +//--------------------------------------------------------------------------- diff --git a/plugins/SendScreenshotPlus/UMainForm.h b/plugins/SendScreenshotPlus/UMainForm.h new file mode 100644 index 0000000000..a7fdcdc643 --- /dev/null +++ b/plugins/SendScreenshotPlus/UMainForm.h @@ -0,0 +1,157 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/UMainForm.h $ +Revision : $Revision: 22 $ +Last change on : $Date: 2010-05-02 21:25:02 +0400 (Р’СЃ, 02 май 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef UMainFormH +#define UMainFormH +//--------------------------------------------------------------------------- +#include "global.h" +#include "Utils.h" +#include "CSend.h" +#include "CSendFile.h" +#include "CSendImageShack.h" +#include "CSendHTTPServer.h" +#include "CSendFTPFile.h" +#include "CSendEmail.h" + +#define SS_JUSTSAVE 0 +#define SS_FILESEND 1 +#define SS_EMAIL 2 +#define SS_HTTPSERVER 3 +#define SS_FTPFILE 4 +#define SS_IMAGESHACK 5 + +// Used for our own cheap TrackMouseEvent +#define BUTTON_POLLDELAY 50 + +// User Events +#define EVT_CaptureDone 1 +#define EVT_SendFileDone 2 +#define EVT_CheckOpenAgain 3 + +extern FI_INTERFACE *FIP; + +typedef struct MyTabData { + TCITEMHEADER tcih; + HWND hwndMain; //main window + HWND hwndTab; //tab control + HWND hwndTabPage; //current child dialog box +}TAB_INFO; + +//--------------------------------------------------------------------------- +class TfrmMain{ + + public: + // Deklaration Standardkonstruktor/Standarddestructor + TfrmMain(); + ~TfrmMain(); + + BYTE m_opt_tabCapture; //capure tab page + BYTE m_opt_btnDesc; //TCheckBox *chkDesc; + BYTE m_opt_cboxDesktop; //TRadioButton *rbtnDesktop; + BYTE m_opt_chkEditor; //TCheckBox *chkEditor; + BYTE m_opt_chkTimed; //TCheckBox *chkTimed; + BYTE m_opt_cboxSendBy; //TComboBox *cboxSendBy; + bool m_bOnExitSave; + + void Show(){ShowWindow(m_hWnd,SW_SHOW);} + void Hide(){ShowWindow(m_hWnd,SW_HIDE);} + void Close(){SendMessage(m_hWnd,WM_CLOSE,0,0);} + void Init(LPTSTR DestFolder, HANDLE Contact); + void btnCaptureClick(); + void cboxSendByChange(); + + private: + HWND m_hWnd; + HANDLE m_hContact; + bool m_bSelectingWindow, m_bDeleteAfterSend; + bool m_bFormAbout, m_bFormEdit; + HWND m_hTargetWindow, m_hLastWin; + LPTSTR m_FDestFolder; + LPTSTR m_pszFile; + LPTSTR m_pszFileDesc; + FIBITMAP* m_Screenshot; //Graphics::TBitmap *Screenshot; + RGBQUAD m_AlphaColor; // + HCURSOR m_hCursor; + CSend* m_cSend; + + void chkTimedClick(); + void imgTargetMouseDown(); + void imgTargetMouseUp(); + void btnAboutClick(); + void btnAboutOnCloseWindow(HWND hWnd); + void btnExploreClick(); + void LoadOptions(void); + void SaveOptions(void); + INT_PTR SaveScreenshot(FIBITMAP* dib); + void FormClose(); + static void edtSizeUpdate(HWND hWnd, BOOL ClientArea, HWND hTarget, UINT Ctrl); + static void edtSizeUpdate(RECT rect, HWND hTarget, UINT Ctrl); + + protected: + size_t m_MonitorCount; + MONITORINFOEX* m_Monitors; + RECT m_VirtualScreen; + + BYTE m_opt_chkOpenAgain; //TCheckBox *chkOpenAgain; + BYTE m_opt_chkClientArea; //TCheckBox *chkClientArea; + BYTE m_opt_edtQuality; //TLabeledEdit *edtQuality; + BYTE m_opt_btnDeleteAfterSend; //TCheckBox *chkDeleteAfterSend; + BYTE m_opt_cboxFormat; //TComboBox *cboxFormat; + BYTE m_opt_edtTimed; //TLabeledEdit *edtTimed; + bool m_bCapture; //is capture activ + + typedef std::map CHandleMapping; + static CHandleMapping _HandleMapping; + static LRESULT CALLBACK DlgTfrmMain(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + + LRESULT wmInitdialog(WPARAM wParam, LPARAM lParam); + LRESULT wmCommand(WPARAM wParam, LPARAM lParam); + LRESULT wmClose(WPARAM wParam, LPARAM lParam); + LRESULT wmNotify(WPARAM wParam, LPARAM lParam); + LRESULT wmTimer(WPARAM wParam, LPARAM lParam); + + LRESULT UMevent(WPARAM wParam, LPARAM lParam); + LRESULT UMClosing(WPARAM wParam, LPARAM lParam); + LRESULT UMTab1(WPARAM wParam, LPARAM lParam); + + HWND m_hwndTab; //TabControl handle + HWND m_hwndTabPage; //TabControl activ page handle + HIMAGELIST m_himlTab; //TabControl imagelist + static INT_PTR CALLBACK DlgProc_CaptureWindow (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + static INT_PTR CALLBACK DlgProc_CaptureDesktop(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +// LRESULT CALLBACK DlgProc_UseLastFile (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +}; + +//--------------------------------------------------------------------------- + +#endif diff --git a/plugins/SendScreenshotPlus/Utils.cpp b/plugins/SendScreenshotPlus/Utils.cpp new file mode 100644 index 0000000000..f1b7251fd7 --- /dev/null +++ b/plugins/SendScreenshotPlus/Utils.cpp @@ -0,0 +1,579 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/Utils.cpp $ +Revision : $Revision: 22 $ +Last change on : $Date: 2010-05-02 21:25:02 +0400 (Р’СЃ, 02 май 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#include "Utils.h" + +//--------------------------------------------------------------------------- +extern HINSTANCE hInst; + +//--------------------------------------------------------------------------- +//Workaround for MS bug ComboBox_SelectItemData +int ComboBox_SelectItemData(HWND hwndCtl, int indexStart, LPARAM data) { + int i = 0; + for ( i ; i < ComboBox_GetCount(hwndCtl); i++) { + if(data == ComboBox_GetItemData(hwndCtl, i)) { + ComboBox_SetCurSel (hwndCtl,i); + return i; + } + } + return CB_ERR; +} + +//--------------------------------------------------------------------------- +// MonitorInfoEnum +size_t MonitorInfoEnum(MONITORINFOEX* & myMonitors, RECT & virtualScreen) { + MONITORS tmp = {0,0}; + if (EnumDisplayMonitors(NULL, NULL, MonitorInfoEnumProc, (LPARAM)&tmp)){ + myMonitors = tmp.info; + memset(&virtualScreen, 0, sizeof(virtualScreen)); + for (size_t i = 0; i < tmp.count; ++i) { + UnionRect(&virtualScreen, &virtualScreen, &tmp.info[i].rcMonitor); + } + return tmp.count; + } + else { + if (tmp.info) mir_free(tmp.info); + } + return 0; +} + +// MonitorInfoEnumProc - CALLBACK for MonitorInfoEnum +BOOL CALLBACK MonitorInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { + MONITORS* monitors = (MONITORS*)dwData; + monitors->count++; + monitors->info = (MONITORINFOEX*)mir_realloc(monitors->info, sizeof(MONITORINFOEX)*monitors->count); + monitors->info[monitors->count-1].cbSize = sizeof(MONITORINFOEX); + if(!GetMonitorInfo(hMonitor, (LPMONITORINFO)(monitors->info + monitors->count-1))) { + return FALSE; // stop enumeration if error + } + return TRUE; +} + +//--------------------------------------------------------------------------- +// capture window as FIBITMAP - caller must FIP->FI_Unload(dib) +FIBITMAP* CaptureWindow (HWND hCapture, BOOL ClientArea) { + FIBITMAP *dib = NULL; + HWND hForegroundWin = NULL; + HDC hScrDC; // screen DC + RECT rect= {0}; // screen RECT + SIZE size; // DIB width and height = window resolution + + if (!hCapture || !IsWindow(hCapture)) return 0; + hForegroundWin = GetForegroundWindow(); //Saving foreground window + BringWindowToTop(hCapture); // This window bring the target window to the top of all others + SetForegroundWindow(hCapture); // Make sure the target window is the foreground one + // redraw window to prevent runtime artefact in picture + UpdateWindow(hCapture); + + hScrDC = GetWindowDC(hCapture); + + // get window resolution + GetWindowRect(hCapture, &rect); + size.cx = ABS(rect.right - rect.left); + size.cy = ABS(rect.bottom - rect.top); + + //capture window and get FIBITMAP + dib = CaptureScreen(hScrDC, size, hCapture); + + if(ClientArea) { + RECT rectCA = {0}; + POINT pt = {0}; + GetClientRect (hCapture, &rectCA); + ClientToScreen(hCapture, &pt); + //crop the window to ClientArea + FIBITMAP* dibClient = FIP->FI_Copy(dib, + pt.x - rect.left, + pt.y - rect.top, + pt.x - rect.left + rectCA.right -1, + pt.y - rect.top + rectCA.bottom -1); + FIP->FI_Unload(dib); + dib = dibClient; + } + + ReleaseDC(NULL, hScrDC); + + // Restoring foreground window + if (hForegroundWin) { + SetForegroundWindow(hForegroundWin); + } + + return dib; +} + +FIBITMAP* CaptureMonitor (LPTSTR szDevice) { + SIZE size; + HDC hScrDC; + FIBITMAP *dib = NULL; + // get screen resolution + if(!szDevice) { + hScrDC = GetDC(NULL); /*Get full virtualscreen*/ + size.cx = GetSystemMetrics(SM_CXVIRTUALSCREEN); + size.cy = GetSystemMetrics(SM_CYVIRTUALSCREEN); + } + else { + hScrDC = CreateDC(szDevice, NULL, NULL, NULL); + size.cx = GetDeviceCaps(hScrDC, HORZRES); + size.cy = GetDeviceCaps(hScrDC, VERTRES); + } + dib = CaptureScreen (hScrDC, size); + ReleaseDC(NULL, hScrDC); + return dib; +} + +FIBITMAP* CaptureScreen (HDC hDC, SIZE size, HWND hCapture) { +//HDC GetDC (NULL) entire desktp +//HDC GetDC (HWND hWnd) client area of the specified window. +//HDC GetWindowDC (HWND hWnd) entire window. + FIBITMAP *dib = NULL; + HBITMAP hBitmap; // handles to device-dependent bitmaps + HDC hScrDC, hMemDC; // screen DC and memory DC + + // create a DC for the screen and create + // a memory DC compatible to screen DC + hScrDC = hDC ? hDC : GetDC(NULL/*Get full screen*/); + hMemDC = CreateCompatibleDC(hScrDC); + // create a bitmap compatible with the screen DC + hBitmap = CreateCompatibleBitmap(hScrDC, size.cx, size.cy); + + // select new bitmap into memory DC + HBITMAP hOld = (HBITMAP) SelectObject(hMemDC, hBitmap); + + if(hCapture) { + PrintWindow(hCapture, hMemDC, 0/*PW_CLIENTONLY is buggy*/); + } + else { + // bitblt screen DC to memory DC + BitBlt(hMemDC, 0, 0, size.cx, size.cy, hScrDC, 0, 0, CAPTUREBLT|SRCCOPY); + } + + dib = FIP->FI_CreateDIBFromHBITMAP(hBitmap); + + //alpha channel from window is always wrong, + //coz GDI do not draw all in alpha mode. + //we have to create our own new alpha channel. + bool bFixAlpha = true; + bool bInvert = false; + + // Create monochrome (1 bit) B+W mask bitmap. + HBITMAP hMask = CreateBitmap(size.cx,size.cy, 1, 1, NULL); + HDC hMaskDC = CreateCompatibleDC(0); + SelectBitmap(hMaskDC, hMask); + + //Create a SolidBrush object for non transparent area + HBRUSH hBr = CreateSolidBrush(RGB(255,255,255)); + + HRGN hrgn = NULL; + int regionType; + if(hCapture) { + hrgn = CreateRectRgn(0,0,0,0); + regionType = GetWindowRgn(hCapture, hrgn); + if (regionType != ERROR) { + // not layerd - fill the window region + FillRgn(hMaskDC, hrgn, hBr); + } + else { //layerd window (WS_EX_LAYERED) + BYTE bAlpha= 0; + COLORREF crKey=0; //0x00bbggrr + DWORD dwFlags=0; + if(GetLayeredWindowAttributes(hCapture,&crKey,&bAlpha,&dwFlags)) { + //per window transparency (like fading in a whole window). + if((dwFlags & LWA_ALPHA) == LWA_ALPHA) { + //Use bAlpha to determine the opacity of the layered window. + bFixAlpha = false; + } + if((dwFlags & LWA_COLORKEY) == LWA_COLORKEY) { + //Use crKey as the transparency color. + SetBkColor(hMemDC, crKey); + BitBlt(hMaskDC, 0, 0, size.cx, size.cy, hMemDC, 0, 0, SRCCOPY); + bInvert = true; + bFixAlpha = true; + } + } + else { + //per-pixel transparency (won't use the WM_PAINT ) + bFixAlpha = false; + } + } + } + else { //fill the desktop region + hrgn = CreateRectRgn(0,0,size.cx,size.cy); + FillRgn(hMaskDC, hrgn, hBr); + } + + if(bFixAlpha) { + FIBITMAP* dibMask = FIP->FI_CreateDIBFromHBITMAP(hMask); + if(bInvert) FIP->FI_Invert(dibMask); + FIBITMAP* dib8 = FIP->FI_ConvertTo8Bits(dibMask); + + //copy the dib8 alpha mask to dib32 main bitmap + FIP->FI_SetChannel(dib,dib8,FICC_ALPHA); + FIP->FI_Unload(dibMask); + FIP->FI_Unload(dib8); + } + + //clean up + DeleteObject(hBr); + if(hrgn) DeleteObject(hrgn); + DeleteDC(hMaskDC); + DeleteObject(hMask); + SelectObject(hMemDC, hOld); + DeleteDC(hMemDC); + if(!hDC) ReleaseDC(NULL, hScrDC); + DeleteObject(hBitmap); + + #ifdef _DEBUG + switch (FIP->FI_GetImageType(dib)){ + case FIT_UNKNOWN: + OutputDebugStringA("FIBITMAP Typ: FIT_UNKNOWN\r\n" ); + break; + case FIT_BITMAP: + OutputDebugStringA("FIBITMAP Typ: FIT_BITMAP\r\n" ); + break; + case FIT_UINT16: + OutputDebugStringA("FIBITMAP Typ: FIT_UINT16\r\n" ); + break; + case FIT_INT16: + OutputDebugStringA("FIBITMAP Typ: FIT_INT16\r\n" ); + break; + case FIT_UINT32: + OutputDebugStringA("FIBITMAP Typ: FIT_UINT32\r\n" ); + break; + case FIT_INT32: + OutputDebugStringA("FIBITMAP Typ: FIT_INT32\r\n" ); + break; + case FIT_FLOAT: + OutputDebugStringA("FIBITMAP Typ: FIT_FLOAT\r\n" ); + break; + case FIT_DOUBLE: + OutputDebugStringA("FIBITMAP Typ: FIT_DOUBLE\r\n" ); + break; + case FIT_COMPLEX: + OutputDebugStringA("FIBITMAP Typ: FIT_COMPLEX\r\n" ); + break; + case FIT_RGB16: + OutputDebugStringA("FIBITMAP Typ: FIT_RGB16\r\n" ); + break; + case FIT_RGBA16: + OutputDebugStringA("FIBITMAP Typ: FIT_RGBA16\r\n" ); + break; + case FIT_RGBF: + OutputDebugStringA("FIBITMAP Typ: FIT_RGBF\r\n" ); + break; + case FIT_RGBAF: + OutputDebugStringA("FIBITMAP Typ: FIT_RGBAF\r\n" ); + break; + default: + OutputDebugStringA("FIBITMAP Typ: nicht feststellbar\r\n" ); + break; + } + BOOL inf = FIP->FI_IsTransparent(dib); + OutputDebugStringA(inf ? "FIBITMAP Transparent: true\r\n" : "FIBITMAP Transparent: fase\r\n"); + #endif + + return dib; +} + +FIBITMAP* CaptureDesktop/*emulate print screen*/() { + FIBITMAP *dib = NULL; + HBITMAP hBitmap; // handles to device-dependent bitmaps + BOOL bBitmap = false; + int i = 0; + keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY, 0); + keybd_event(VK_SNAPSHOT, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); + do {//Clipboard need time to get bitmap from keybd_event, + i++; //we use a counter to get this time. + bBitmap = IsClipboardFormatAvailable(CF_BITMAP); + if(i == 500) return (FIBITMAP*)0; //emergency exit if something go wrong + } while (!bBitmap); + #ifdef _DEBUG + char mess[120] = {0}; + LPSTR pszMess = mess; + mir_snprintf(pszMess,120,"SS Bitmap counter: %i\r\n",i); + OutputDebugStringA( pszMess ); + #endif + //get clipboard data + OpenClipboard(NULL); + hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP); + + //create FIBITMAP * from HBITMAP + FIP->FI_CorrectBitmap32Alpha(hBitmap, FALSE); + dib = FIP->FI_CreateDIBFromHBITMAP(hBitmap); + CloseClipboard(); + + return dib; +} + +LPTSTR SaveImage(FREE_IMAGE_FORMAT fif, FIBITMAP* dib, LPTSTR pszFilename, LPTSTR pszExt, int flag) { + int ret=0; + LPTSTR pszFile = NULL; + LPTSTR FileExt = (LPTSTR)GetFileExt (pszFilename, DBVT_TCHAR); + if(!FileExt) { + if(!pszExt) return NULL; + mir_tcsadd(pszFile, pszFilename); + mir_tcsadd(pszFile, _T(".")); + mir_tcsadd(pszFile, pszExt); + } + else { + mir_tcsadd(pszFile, pszFilename); + } + + if(fif==FIF_UNKNOWN) { + #if defined(_UNICODE) + fif = FIP->FI_GetFIFFromFilenameU(pszFile); + #else + fif = FIP->FI_GetFIFFromFilename(pszFile); + #endif + } + if(FIP->FI_FIFSupportsICCProfiles(fif)) { + bool bDummy = true; + } + + #if defined(_UNICODE) + ret = FIP->FI_SaveU(fif, dib, pszFile, flag); + #else + ret = FIP->FI_Save(fif, dib, pszFile, flag); + #endif + + mir_free(FileExt); + + if(ret) return pszFile; + mir_free(pszFile); + return NULL; +} + +//--------------------------------------------------------------------------- +//Draws a selection border on the window under cursor +void DrawBorderInverted(HWND hWindow) { + if (!hWindow){ + return; + } + HDC hDC=GetWindowDC(hWindow); + RECT rect={0}; + GetWindowRect(hWindow, &rect); + + int dcSave = SaveDC(hDC); + + SetROP2(hDC, R2_NOT); + + HPEN hPen=0; + hPen = CreatePen(PS_SOLID, 10, RGB(0, 0, 0)); + + SelectObject(hDC, &hPen); + SelectObject(hDC, GetStockObject(NULL_BRUSH)); + + Rectangle(hDC, 0, 0, rect.right-rect.left, rect.bottom-rect.top); + Rectangle(hDC, 1, 1, rect.right-rect.left-1, rect.bottom-rect.top-1); + Rectangle(hDC, 2, 2, rect.right-rect.left-2, rect.bottom-rect.top-2); + + RestoreDC(hDC, dcSave); +} + +//--------------------------------------------------------------------------- +//is left mouse button down +BOOL GetLmouse() { + SHORT temp = GetAsyncKeyState((GetSystemMetrics(SM_SWAPBUTTON)) ? VK_RBUTTON : VK_LBUTTON); + if ((temp & 0x8000) == 0x8000) { // LBUTTON down + return TRUE; + } + return FALSE; +} + +//--------------------------------------------------------------------------- +//is miranda unicode +BOOL mir_is_unicode() { + char ver[1024]; + CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM) sizeof(ver), (LPARAM) ver); + return strstr(ver, "Unicode") != NULL; +} + +//--------------------------------------------------------------------------- +INT_PTR GetFileName(LPTSTR pszPath, UINT typ) { + /*DBVT_ASCIIZ, DBVT_WCHAR, DBVT_TCHAR*/ + LPTSTR slash = _tcsrchr(pszPath,_T('\\')); + if (slash) { + switch (typ) { + case DBVT_ASCIIZ: + return (INT_PTR)mir_t2a(slash+1); + case DBVT_WCHAR: + return (INT_PTR)mir_t2u(slash+1); + default: + return 0; + } + } + else { + switch (typ) { + case DBVT_ASCIIZ: + return (INT_PTR)mir_t2a(pszPath); + case DBVT_WCHAR: + return (INT_PTR)mir_t2u(pszPath); + default: + return 0; + } + } +} + +INT_PTR GetFileExt (LPTSTR pszPath, UINT typ) { + /*DBVT_ASCIIZ, DBVT_WCHAR, DBVT_TCHAR*/ + LPTSTR slash = _tcsrchr(pszPath,_T('.')); + if (slash) { + switch (typ) { + case DBVT_ASCIIZ: + return (INT_PTR)mir_t2a(slash); + case DBVT_WCHAR: + return (INT_PTR)mir_t2u(slash); + default: + return 0; + } + } + else { + return NULL; + } +} + +//--------------------------------------------------------------------------- +BOOL GetEncoderClsid(wchar_t *wchMimeType, CLSID& clsidEncoder) { + UINT uiNum = 0; + UINT uiSize = 0; + BOOL bOk = FALSE; + Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL; + Gdiplus::GetImageEncodersSize(&uiNum, &uiSize); + if( uiSize > 0 ) { + pImageCodecInfo = (Gdiplus::ImageCodecInfo *)new char[uiSize]; + if( pImageCodecInfo ) { + Gdiplus::GetImageEncoders(uiNum, uiSize, pImageCodecInfo); + for( UINT i = 0; i < uiNum; i++ ) { + if( wcscmp(pImageCodecInfo[i].MimeType, wchMimeType) == 0 ) { + clsidEncoder = pImageCodecInfo[i].Clsid; + bOk = TRUE; + } + } + } + delete pImageCodecInfo; + } + return bOk; +} + +INT_PTR SavePNG(HBITMAP hBmp, LPTSTR szFilename) { + Gdiplus::GdiplusStartupInput gdiplusStartupInput; + ULONG_PTR gdiplusToken; + Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); + + Gdiplus::Bitmap *pBitmap = Gdiplus::Bitmap::FromHBITMAP(hBmp, (HPALETTE)GetStockObject(DEFAULT_PALETTE) ); + if( pBitmap ) { + // Get the CLSID of the PNG encoder. + CLSID clsidEncoder; + if( GetEncoderClsid(L"image/png", clsidEncoder)) { + LPWSTR pswFile = mir_t2u(szFilename); + pBitmap->Save((const WCHAR*)pswFile, &clsidEncoder, NULL); + mir_free(pswFile); + } + delete pBitmap; + } + Gdiplus::GdiplusShutdown(gdiplusToken); + return 0; +} + +INT_PTR SaveGIF(HBITMAP hBmp, LPTSTR szFilename) { + Gdiplus::GdiplusStartupInput gdiplusStartupInput; + ULONG_PTR gdiplusToken; + Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); + + Gdiplus::Bitmap *pBitmap = Gdiplus::Bitmap::FromHBITMAP(hBmp, (HPALETTE)GetStockObject(DEFAULT_PALETTE) ); + if( pBitmap ) { + // Get the CLSID of the GIF encoder. + CLSID clsidEncoder; + if( GetEncoderClsid(L"image/gif", clsidEncoder)) { + LPWSTR pswFile = mir_t2u(szFilename); + pBitmap->Save((const WCHAR*)pswFile, &clsidEncoder, NULL); + mir_free(pswFile); + } + delete pBitmap; + } + Gdiplus::GdiplusShutdown(gdiplusToken); + return 0; +} + +INT_PTR SaveTIF(HBITMAP hBmp, LPTSTR szFilename) { +//http://www.codeproject.com/Messages/1406708/How-to-reduce-the-size-of-an-Image-using-GDIplus.aspx + ULONG_PTR gdiplusToken; + Gdiplus::GdiplusStartupInput gdiplusStartupInput; + Gdiplus::Status stat; + Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); + + Gdiplus::Bitmap *pBitmap = Gdiplus::Bitmap::FromHBITMAP(hBmp, (HPALETTE)GetStockObject(DEFAULT_PALETTE) ); + if( pBitmap ) { + // Get the CLSID of the GIF encoder. + CLSID EncCLSID; + if( GetEncoderClsid(L"image/tiff", EncCLSID)) { + //--- Create a 2-parameter array, for Compression and for Color Bit depth + Gdiplus::EncoderParameters* EncParams = (Gdiplus::EncoderParameters*) malloc(sizeof(Gdiplus::EncoderParameters) + 1 * sizeof(Gdiplus::EncoderParameter)); + // Gdiplus::EncoderParameters pEncoderParameters; + //--- Use LZW Compression instead of Group 4, since it works for color and G4 doesn't + ULONG ulCompression = Gdiplus::EncoderValueCompressionLZW ; + ULONG ulColorDepth = 24L ; + + EncParams->Count = 2 ; + EncParams->Parameter[0].Guid = Gdiplus::EncoderCompression ; + EncParams->Parameter[0].Type = Gdiplus::EncoderParameterValueTypeLong ; + EncParams->Parameter[0].NumberOfValues = 1 ; + EncParams->Parameter[0].Value = &ulCompression ; + EncParams->Parameter[1].Guid = Gdiplus::EncoderColorDepth ; + EncParams->Parameter[1].Type = Gdiplus::EncoderParameterValueTypeLong ; + EncParams->Parameter[1].NumberOfValues = 1 ; + EncParams->Parameter[1].Value = &ulColorDepth ; + + LPWSTR pswFile = mir_t2u(szFilename); + stat = pBitmap->Save((const WCHAR*)pswFile, &EncCLSID, EncParams); + mir_free(pswFile); + free(EncParams); + } + delete pBitmap; + } + Gdiplus::GdiplusShutdown(gdiplusToken); + return 0; +} + +//--------------------------------------------------------------------------- +/* Old stuff from Borland C++ */ +//--------------------------------------------------------------------------- +/*/Popup +void ShowPopUp(char *title, char *text) { + POPUPDATAEX pude={0}; + + strcpy(pude.lpzText, text); + strcpy(pude.lpzContactName, title); + pude.lchIcon = LoadIcon(g_hAppInstance, MAKEINTRESOURCE(MAIN)); + pude.colorBack = POPUP_USE_SKINNED_BG; + + CallService(MS_POPUP_ADDPOPUP, (WPARAM)&pude, 0); +}*/ + diff --git a/plugins/SendScreenshotPlus/Utils.h b/plugins/SendScreenshotPlus/Utils.h new file mode 100644 index 0000000000..2934391a8b --- /dev/null +++ b/plugins/SendScreenshotPlus/Utils.h @@ -0,0 +1,81 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/Utils.h $ +Revision : $Revision: 22 $ +Last change on : $Date: 2010-05-02 21:25:02 +0400 (Р’СЃ, 02 май 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef UTILSH +#define UTILSH + +#include "global.h" +//#include +//#include +#define SPP_USERPANE 1 + +extern FI_INTERFACE *FIP; + +#define ABS(x) ((x)<0?-(x):(x)) + +typedef struct TEnumDataTemp { +size_t count; +MONITORINFOEX* info; +}MONITORS; + +extern HWND g_hCapture; +extern HBITMAP g_hBitmap, g_hbmMask; + +//--------------------------------------------------------------------------- +int ComboBox_SelectItemData(HWND hwndCtl, int indexStart, LPARAM data); + +size_t MonitorInfoEnum(MONITORINFOEX* & myMonitors, RECT & virtualScreen); +BOOL CALLBACK MonitorInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData); + +FIBITMAP* CaptureWindow(HWND hCapture, BOOL ClientArea); +FIBITMAP* CaptureMonitor(LPTSTR szDevice); +FIBITMAP* CaptureScreen(HDC hDC, SIZE size, HWND hCapture=0); +FIBITMAP* CaptureDesktop(); /*emulate print screen (not used)*/ +LPTSTR SaveImage(FREE_IMAGE_FORMAT fif, FIBITMAP* dib, LPTSTR pszFilename, LPTSTR pszExt, int flag=0); + +void DrawBorderInverted(HWND hWindow); +BOOL GetLmouse(); +BOOL mir_is_unicode(); +INT_PTR GetFileName(LPTSTR pszPath, UINT typ); +INT_PTR GetFileExt (LPTSTR pszPath, UINT typ); + +BOOL GetEncoderClsid(wchar_t *wchMimeType, CLSID& clsidEncoder); +INT_PTR SavePNG(HBITMAP hBmp, LPTSTR szFilename); +INT_PTR SaveGIF(HBITMAP hBmp, LPTSTR szFilename); +INT_PTR SaveTIF(HBITMAP hBmp, LPTSTR szFilename); + +//--------------------------------------------------------------------------- +/* Old stuff from Borland C++ +//void ShowPopUp(char *title, char *text); + +*/ +#endif diff --git a/plugins/SendScreenshotPlus/ctrl_button.cpp b/plugins/SendScreenshotPlus/ctrl_button.cpp new file mode 100644 index 0000000000..ad8e542fa3 --- /dev/null +++ b/plugins/SendScreenshotPlus/ctrl_button.cpp @@ -0,0 +1,699 @@ +/* +Miranda IM +Copyright (C) 2002 Robert Rainwater + +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 "global.h" + +// Used for our own cheap TrackMouseEvent +#define BUTTON_POLLID 100 +#define BUTTON_POLLDELAY 50 + +#define MGPROC(x) GetProcAddress(themeAPIHandle,x) + +typedef struct TMBCtrl{ + HWND hwnd; + HANDLE hThemeButton; + HANDLE hThemeToolbar; + + HICON hIcon; + HICON arrow; // uses down arrow + HBITMAP hBitmap; + HFONT hFont; // font + + DWORD dwStyle; + BOOLEAN bFocus; + + INT stateId; // button state + INT defbutton; // default button + INT pbState; + TCHAR cHot; +} BTNCTRL, *LPBTNCTRL; + +// External theme methods and properties +CRITICAL_SECTION csTips; +HWND hwndToolTips = NULL; +HMODULE themeAPIHandle = NULL; + +// theme procedures +HANDLE (WINAPI *OpenThemeData)(HWND,LPCWSTR); +HRESULT (WINAPI *CloseThemeData)(HANDLE); +BOOL (WINAPI *IsThemeBackgroundPartiallyTransparent)(HANDLE,INT,INT); +HRESULT (WINAPI *DrawThemeParentBackground)(HWND,HDC,RECT *); +HRESULT (WINAPI *DrawThemeBackground)(HANDLE,HDC,INT,INT,const RECT *,const RECT *); +HRESULT (WINAPI *DrawThemeText)(HANDLE,HDC,INT,INT,LPCWSTR,INT,DWORD,DWORD,const RECT *); +HRESULT (WINAPI *GetThemeTextExtent)(HANDLE,HDC,INT,INT,LPCWSTR,INT,DWORD,OPTIONAL const RECT*, RECT *); +HRESULT (WINAPI *GetThemeBackgroundRegion)(HANDLE,HDC,INT,INT,const RECT *,HRGN *); + +/** + * name: ThemeSupport + * desc: Loads the uxtheme functions, if supported by the os + * param: none + * return: TRUE if themes are supported, FALSE if not + **/ +BOOLEAN __fastcall ThemeSupport() { + if (IsWinVerXPPlus()) { + if (!themeAPIHandle) { + themeAPIHandle = GetModuleHandleA("uxtheme"); + if (themeAPIHandle) { + OpenThemeData = (HANDLE (WINAPI *)(HWND,LPCWSTR))MGPROC("OpenThemeData"); + CloseThemeData = (HRESULT (WINAPI *)(HANDLE))MGPROC("CloseThemeData"); + IsThemeBackgroundPartiallyTransparent = (BOOL (WINAPI *)(HANDLE,INT,INT))MGPROC("IsThemeBackgroundPartiallyTransparent"); + DrawThemeParentBackground = (HRESULT (WINAPI *)(HWND,HDC,RECT *))MGPROC("DrawThemeParentBackground"); + DrawThemeBackground = (HRESULT (WINAPI *)(HANDLE,HDC,INT,INT,const RECT *,const RECT *))MGPROC("DrawThemeBackground"); + DrawThemeText = (HRESULT (WINAPI *)(HANDLE,HDC,INT,INT,LPCWSTR,INT,DWORD,DWORD,const RECT *))MGPROC("DrawThemeText"); + GetThemeTextExtent = (HRESULT (WINAPI *)(HANDLE,HDC,INT,INT,LPCWSTR,INT,DWORD,OPTIONAL const RECT*, RECT *))MGPROC("GetThemeTextExtent"); + GetThemeBackgroundRegion = (HRESULT (WINAPI *)(HANDLE,HDC,INT,INT,const RECT *,HRGN *))MGPROC("GetThemeBackgroundRegion"); + } + } + // Make sure all of these methods are valid (i would hope either all or none work) + if (OpenThemeData + && CloseThemeData + && IsThemeBackgroundPartiallyTransparent + && DrawThemeParentBackground + && DrawThemeBackground + && DrawThemeText + && GetThemeTextExtent) + { + return TRUE; + } + } + return FALSE; +} + +/** + * name: DestroyTheme + * desc: destroys theme data for buttons + * param: ctl - BTNCTRL structure with the information about the theme to close + * return: nothing + **/ +static VOID __fastcall DestroyTheme(BTNCTRL *ctl) { + if (ctl->hThemeButton) { + CloseThemeData(ctl->hThemeButton); + ctl->hThemeButton = NULL; + } + if (ctl->hThemeToolbar) { + CloseThemeData(ctl->hThemeToolbar); + ctl->hThemeToolbar = NULL; + } +} + +/** + * name: LoadTheme + * desc: load theme data for buttons if supported by os + * param: ctl - BTNCTRL structure with the information about the theme to load + * return: nothing + **/ +static VOID __fastcall LoadTheme(BTNCTRL *ctl) { + if (ThemeSupport()) { + DestroyTheme(ctl); + ctl->hThemeButton = OpenThemeData(ctl->hwnd,L"BUTTON"); + ctl->hThemeToolbar = OpenThemeData(ctl->hwnd,L"TOOLBAR"); + } +} + +/** + * name: TBStateConvert2Flat + * desc: convert button stateIDs + * param: state - state id for the normal theme button + * return: stateID for the flat theme button + **/ +static INT __fastcall TBStateConvert2Flat(INT state) { + switch (state) { + case PBS_NORMAL: return TS_NORMAL; + case PBS_HOT: return TS_HOT; + case PBS_PRESSED: return TS_PRESSED; + case PBS_DISABLED: return TS_DISABLED; + case PBS_DEFAULTED: return TS_NORMAL; + } + return TS_NORMAL; +} + +/** + * name: PaintIcon + * desc: Draws the Icon of the button + * param: ctl - BTNCTRL structure for the button + * hdcMem - device context to draw to + * ccText - character count of the text of the button + * rcClient - rectangle of the whole button + * rcText - rectangle of the text to draw later on + * return: nothing + **/ +static VOID __fastcall PaintIcon(BTNCTRL *ctl, HDC hdcMem, LPWORD ccText, LPRECT rcClient, LPRECT rcText) +{ + RECT rcImage; + + // draw icon on the left of the button + if (ctl->hIcon) { + rcImage.right = GetSystemMetrics(SM_CXSMICON); + rcImage.bottom = GetSystemMetrics(SM_CYSMICON); + rcImage.left = (rcClient->right - rcClient->left) / 2 - ((rcImage.right + rcText->right + (*ccText > 0 ? 4 : 0) + (ctl->arrow ? rcImage.right : 0)) / 2); + rcImage.top = (rcClient->bottom - rcClient->top - rcImage.bottom) / 2; + rcImage.right += rcImage.left; + rcImage.bottom += rcImage.top; + + OffsetRect(rcText, rcImage.right + 4, 0); + if (ctl->stateId == PBS_PRESSED) OffsetRect(&rcImage, 1, 1); + + DrawState(hdcMem, NULL, NULL, (LPARAM)ctl->hIcon, 0, + rcImage.left, rcImage.top, + rcImage.right - rcImage.left, rcImage.bottom - rcImage.top, + IsWindowEnabled(ctl->hwnd) ? DST_ICON | DSS_NORMAL : DST_ICON | DSS_DISABLED); + } + + // draw arrow on the right of the button + if (ctl->arrow) { + rcImage.right = GetSystemMetrics(SM_CXSMICON); + rcImage.left = (*ccText > 0 || ctl->hIcon) + ? rcClient->right - GetSystemMetrics(SM_CXSMICON) + : (rcClient->right - rcClient->left - rcImage.right) / 2; + rcImage.right += rcImage.left; + rcImage.bottom = GetSystemMetrics(SM_CYSMICON); + rcImage.top = (rcClient->bottom - rcClient->top - rcImage.bottom) / 2; + if (ctl->stateId == PBS_PRESSED) OffsetRect(&rcImage, 1, 1); + + DrawState(hdcMem, NULL, NULL, (LPARAM)ctl->arrow, 0, + rcImage.left, rcImage.top, + rcImage.right - rcImage.left, rcImage.bottom - rcImage.top, + IsWindowEnabled(ctl->hwnd) ? DST_ICON | DSS_NORMAL : DST_ICON | DSS_DISABLED); + } +} + +/** + * name: PaintThemeButton + * desc: Draws the themed button + * param: ctl - BTNCTRL structure for the button + * hdcMem - device context to draw to + * rcClient - rectangle of the whole button + * return: nothing + **/ +static VOID __fastcall PaintThemeButton(BTNCTRL *ctl, HDC hdcMem, LPRECT rcClient) +{ + RECT rcText = { 0, 0, 0, 0 }; + WCHAR wszText[MAX_PATH] = { 0 }; + WORD ccText; + + // Draw the flat button + if ((ctl->dwStyle & MBS_FLAT) && ctl->hThemeToolbar) { + INT state = IsWindowEnabled(ctl->hwnd) + ? (ctl->stateId == PBS_NORMAL && ctl->defbutton + ? PBS_DEFAULTED + : ctl->stateId) + : PBS_DISABLED; + if (IsThemeBackgroundPartiallyTransparent(ctl->hThemeToolbar, TP_BUTTON, TBStateConvert2Flat(state))) { + if (SUCCEEDED(DrawThemeParentBackground(ctl->hwnd, hdcMem, rcClient))) + DrawThemeParentBackground(GetParent(ctl->hwnd), hdcMem, rcClient); + } + DrawThemeBackground(ctl->hThemeToolbar, hdcMem, TP_BUTTON, TBStateConvert2Flat(state), rcClient, rcClient); + } + else { + // draw themed button background + if (ctl->hThemeButton) { + INT state = IsWindowEnabled(ctl->hwnd) + ? (ctl->stateId == PBS_NORMAL && ctl->defbutton + ? PBS_DEFAULTED + : ctl->stateId) + : PBS_DISABLED; + if (IsThemeBackgroundPartiallyTransparent(ctl->hThemeButton, BP_PUSHBUTTON, state)) { + if (SUCCEEDED(DrawThemeParentBackground(ctl->hwnd, hdcMem, rcClient))) + DrawThemeParentBackground(GetParent(ctl->hwnd), hdcMem, rcClient); + } + DrawThemeBackground(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, state, rcClient, rcClient); + } + } + + // calculate text rect + { + RECT sizeText; + HFONT hOldFont; + + ccText = GetWindowTextW(ctl->hwnd, wszText, sizeof(wszText) / sizeof(WCHAR)); + + if (ccText > 0) { + hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); + + GetThemeTextExtent( + ctl->hThemeButton, + hdcMem, + BP_PUSHBUTTON, + IsWindowEnabled(ctl->hwnd) ? ctl->stateId : PBS_DISABLED, + wszText, + ccText, + DST_PREFIXTEXT, + NULL, + &sizeText); + + if (ctl->cHot) { + RECT rcHot; + + GetThemeTextExtent(ctl->hThemeButton, + hdcMem, + BP_PUSHBUTTON, + IsWindowEnabled(ctl->hwnd) ? ctl->stateId : PBS_DISABLED, + L"&", + 1, + DST_PREFIXTEXT, + NULL, + &rcHot); + + sizeText.right -= (rcHot.right - rcHot.left); + } + SelectObject(hdcMem, hOldFont); + + rcText.left = (ctl->hIcon) ? 0 : (rcClient->right - rcClient->left - (sizeText.right - sizeText.left)) / 2; + rcText.top = (rcClient->bottom - rcClient->top - (sizeText.bottom - sizeText.top)) / 2; + rcText.right = rcText.left + (sizeText.right - sizeText.left); + rcText.bottom = rcText.top + (sizeText.bottom - sizeText.top); + if (ctl->stateId == PBS_PRESSED) { + OffsetRect(&rcText, 1, 1); + } + } + } + PaintIcon(ctl, hdcMem, &ccText, rcClient, &rcText); + // draw text + if (ccText > 0 && ctl->hThemeButton) { + HFONT hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); + DrawThemeText(ctl->hThemeButton, hdcMem, BP_PUSHBUTTON, IsWindowEnabled(ctl->hwnd) ? ctl->stateId : PBS_DISABLED, wszText, ccText, DST_PREFIXTEXT, 0, &rcText); + SelectObject(hdcMem, hOldFont); + } +} + +/** + * name: PaintThemeButton + * desc: Draws the none themed button + * param: ctl - BTNCTRL structure for the button + * hdcMem - device context to draw to + * rcClient - rectangle of the whole button + * return: nothing + **/ +static VOID __fastcall PaintButton(BTNCTRL *ctl, HDC hdcMem, LPRECT rcClient) +{ + RECT rcText = { 0, 0, 0, 0 }; + TCHAR szText[MAX_PATH] = { 0 }; + WORD ccText; + + // Draw the flat button + if (ctl->dwStyle & MBS_FLAT) { + HBRUSH hbr = NULL; + + if (ctl->stateId == PBS_PRESSED || ctl->stateId == PBS_HOT) + hbr = GetSysColorBrush(COLOR_3DLIGHT); + else { + HDC dc; + HWND hwndParent; + + hwndParent = GetParent(ctl->hwnd); + if (dc = GetDC(hwndParent)) { + hbr = (HBRUSH)SendMessage(hwndParent, WM_CTLCOLORDLG, (WPARAM)dc, (LPARAM)hwndParent); + ReleaseDC(hwndParent, dc); + } + } + if (hbr) { + FillRect(hdcMem, rcClient, hbr); + DeleteObject(hbr); + } + if (ctl->stateId == PBS_HOT || ctl->bFocus) { + if (ctl->pbState) DrawEdge(hdcMem, rcClient, EDGE_ETCHED, BF_RECT|BF_SOFT); + else DrawEdge(hdcMem, rcClient, BDR_RAISEDOUTER, BF_RECT|BF_SOFT|BF_FLAT); + } + else + if (ctl->stateId == PBS_PRESSED) + DrawEdge(hdcMem, rcClient, BDR_SUNKENOUTER, BF_RECT|BF_SOFT); + } + else { + UINT uState = DFCS_BUTTONPUSH|((ctl->stateId == PBS_HOT) ? DFCS_HOT : 0)|((ctl->stateId == PBS_PRESSED) ? DFCS_PUSHED : 0); + if (ctl->defbutton&&ctl->stateId==PBS_NORMAL) uState |= DLGC_DEFPUSHBUTTON; + DrawFrameControl(hdcMem, rcClient, DFC_BUTTON, uState); + // Draw focus rectangle if button has focus + if (ctl->bFocus) { + RECT focusRect = *rcClient; + InflateRect(&focusRect, -3, -3); + DrawFocusRect(hdcMem, &focusRect); + } + } + // calculate text rect + { + SIZE sizeText; + HFONT hOldFont; + + ccText = GetWindowText(ctl->hwnd, szText, SIZEOF(szText)); + + if (ccText > 0) { + hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); + GetTextExtentPoint32(hdcMem, szText, ccText, &sizeText); + if (ctl->cHot) { + SIZE sizeHot; + + GetTextExtentPoint32A(hdcMem, "&", 1, &sizeHot); + sizeText.cx -= sizeHot.cx; + } + SelectObject(hdcMem, hOldFont); + + rcText.left = (ctl->hIcon) ? 0 : (rcClient->right - rcClient->left - sizeText.cx) / 2; + rcText.top = (rcClient->bottom - rcClient->top - sizeText.cy) / 2; + rcText.right = rcText.left + sizeText.cx; + rcText.bottom = rcText.top + sizeText.cy; + if (ctl->stateId == PBS_PRESSED) + OffsetRect(&rcText, 1, 1); + } + } + PaintIcon(ctl, hdcMem, &ccText, rcClient, &rcText); + + // draw text + if (ccText > 0) { + HFONT hOldFont; + + hOldFont = (HFONT)SelectObject(hdcMem, ctl->hFont); + + SetBkMode(hdcMem, TRANSPARENT); + SetTextColor(hdcMem, + IsWindowEnabled(ctl->hwnd) || !ctl->hThemeButton + ? ctl->stateId == PBS_HOT + ? GetSysColor(COLOR_HOTLIGHT) + : GetSysColor(COLOR_BTNTEXT) + : GetSysColor(COLOR_GRAYTEXT)); + + DrawState(hdcMem, NULL, NULL, (LPARAM)szText, 0, + rcText.left, rcText.top, rcText.right - rcText.left, rcText.bottom - rcText.top, + IsWindowEnabled(ctl->hwnd) || ctl->hThemeButton ? DST_PREFIXTEXT | DSS_NORMAL : DST_PREFIXTEXT | DSS_DISABLED); + SelectObject(hdcMem, hOldFont); + } +} + +/** + * name: Button_WndProc + * desc: window procedure for the button class + * param: hwndBtn - window handle to the button + * uMsg - message to handle + * wParam - message specific parameter + * lParam - message specific parameter + * return: message specific + **/ +static LRESULT CALLBACK Button_WndProc(HWND hwndBtn, UINT uMsg, WPARAM wParam, LPARAM lParam) { + LPBTNCTRL bct = (LPBTNCTRL)GetWindowLongPtr(hwndBtn, 0); + + switch (uMsg) { + case WM_NCCREATE: + { + LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam; + + cs->style |= BS_OWNERDRAW; + if (!(bct = (LPBTNCTRL)malloc(sizeof(BTNCTRL)))) + return FALSE; + ZeroMemory(bct, sizeof(BTNCTRL)); + bct->hwnd = hwndBtn; + bct->stateId = PBS_NORMAL; + bct->hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); + bct->dwStyle = cs->style; + if (cs->style & MBS_DOWNARROW) + bct->arrow = IcoLib_GetIcon(ICO_BTN_DOWNARROW); + LoadTheme(bct); + SetWindowLongPtr(hwndBtn, 0, (LONG_PTR)bct); + if (cs->lpszName) SetWindowText(hwndBtn, cs->lpszName); + return TRUE; + } + case WM_DESTROY: + if (bct) { + EnterCriticalSection(&csTips); + if (hwndToolTips) { + TOOLINFO ti; + + ZeroMemory(&ti, sizeof(ti)); + ti.cbSize = sizeof(ti); + ti.uFlags = TTF_IDISHWND; + ti.hwnd = bct->hwnd; + ti.uId = (UINT)bct->hwnd; + if (SendMessage(hwndToolTips, TTM_GETTOOLINFO, 0, (LPARAM)&ti)) { + SendMessage(hwndToolTips, TTM_DELTOOL, 0, (LPARAM)&ti); + } + if (SendMessage(hwndToolTips, TTM_GETTOOLCOUNT, 0, (LPARAM)&ti) == 0) { + DestroyWindow(hwndToolTips); + hwndToolTips = NULL; + } + } + LeaveCriticalSection(&csTips); + DestroyTheme(bct); + free(bct); + } + SetWindowLongPtr(hwndBtn, 0, NULL); + break; + case WM_SETTEXT: + bct->cHot = 0; + if ((LPTSTR)lParam) { + LPTSTR tmp = (LPTSTR)lParam; + + while (*tmp) { + if (*tmp=='&' && *(tmp+1)) { + bct->cHot = _totlower(*(tmp+1)); + break; + } + tmp++; + } + InvalidateRect(bct->hwnd, NULL, TRUE); + } + break; + case WM_SYSKEYUP: + if (bct->stateId != PBS_DISABLED && bct->cHot && bct->cHot == _totlower((TCHAR)wParam)) { + if (bct->dwStyle & MBS_PUSHBUTTON) { + if (bct->pbState) bct->pbState = 0; + else bct->pbState = 1; + InvalidateRect(bct->hwnd, NULL, TRUE); + } + else + SetFocus(hwndBtn); + SendMessage(GetParent(hwndBtn), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndBtn), BN_CLICKED), (LPARAM)hwndBtn); + return 0; + } + break; + case WM_THEMECHANGED: + { + // themed changed, reload theme object + LoadTheme(bct); + InvalidateRect(bct->hwnd, NULL, TRUE); // repaint it + break; + } + case WM_SETFONT: // remember the font so we can use it later + bct->hFont = (HFONT)wParam; // maybe we should redraw? + break; + case WM_NCPAINT: + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdcPaint; + HDC hdcMem; + HBITMAP hbmMem; + HDC hOld; + RECT rcClient; + + if (hdcPaint = BeginPaint(hwndBtn, &ps)) { + GetClientRect(bct->hwnd, &rcClient); + hdcMem = CreateCompatibleDC(hdcPaint); + hbmMem = CreateCompatibleBitmap(hdcPaint, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top); + hOld = (HDC)SelectObject(hdcMem, hbmMem); + + // If its a push button, check to see if it should stay pressed + if ((bct->dwStyle & MBS_PUSHBUTTON) && bct->pbState) bct->stateId = PBS_PRESSED; + + if ((bct->dwStyle & MBS_FLAT) && bct->hThemeToolbar || bct->hThemeButton) + PaintThemeButton(bct, hdcMem, &rcClient); + else + PaintButton(bct, hdcMem, &rcClient); + + BitBlt(hdcPaint, 0, 0, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top, hdcMem, 0, 0, SRCCOPY); + SelectObject(hdcMem, hOld); + DeleteObject(hbmMem); + DeleteDC(hdcMem); + EndPaint(hwndBtn, &ps); + } + return 0; + } + case BM_SETIMAGE: + if (wParam == IMAGE_ICON) { + bct->hIcon = (HICON)lParam; + bct->hBitmap = NULL; + InvalidateRect(bct->hwnd, NULL, TRUE); + } + else if (wParam == IMAGE_BITMAP) { + bct->hIcon = NULL; + bct->hBitmap = (HBITMAP)lParam; + InvalidateRect(bct->hwnd, NULL, TRUE); + } + else if (wParam == NULL && lParam == NULL) { + bct->hIcon = NULL; + bct->hBitmap = NULL; + InvalidateRect(bct->hwnd, NULL, TRUE); + } + break; + case BM_SETCHECK: + if (!(bct->dwStyle & MBS_PUSHBUTTON)) break; + if (wParam == BST_CHECKED) { + bct->pbState = 1; + bct->stateId = PBS_PRESSED; + } + else if (wParam == BST_UNCHECKED) { + bct->pbState = 0; + bct->stateId = PBS_NORMAL; + } + InvalidateRect(bct->hwnd, NULL, TRUE); + break; + case BM_GETCHECK: + if (bct->dwStyle & MBS_PUSHBUTTON) return bct->pbState ? BST_CHECKED : BST_UNCHECKED; + return 0; + case BUTTONSETDEFAULT: + bct->defbutton = wParam ? 1 : 0; + InvalidateRect(bct->hwnd, NULL, TRUE); + break; + case BUTTONADDTOOLTIP: + { + if (!wParam) break; + EnterCriticalSection(&csTips); + if (!hwndToolTips) { + hwndToolTips = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); + } + + if (lParam == MBF_UNICODE) { + TOOLINFOW ti; + + ZeroMemory(&ti, sizeof(TOOLINFOW)); + ti.cbSize = sizeof(TOOLINFOW); + ti.uFlags = TTF_IDISHWND; + ti.hwnd = bct->hwnd; + ti.uId = (UINT)bct->hwnd; + if (SendMessage(hwndToolTips, TTM_GETTOOLINFOW, 0, (LPARAM)&ti)) { + SendMessage(hwndToolTips, TTM_DELTOOLW, 0, (LPARAM)&ti); + } + ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS; + ti.uId = (UINT)bct->hwnd; + ti.lpszText=(LPWSTR)wParam; + SendMessage(hwndToolTips, TTM_ADDTOOLW, 0, (LPARAM)&ti); + } + else { + TOOLINFOA ti; + + ZeroMemory(&ti, sizeof(TOOLINFOA)); + ti.cbSize = sizeof(TOOLINFOA); + ti.uFlags = TTF_IDISHWND; + ti.hwnd = bct->hwnd; + ti.uId = (UINT)bct->hwnd; + if (SendMessage(hwndToolTips, TTM_GETTOOLINFOA, 0, (LPARAM)&ti)) { + SendMessage(hwndToolTips, TTM_DELTOOLA, 0, (LPARAM)&ti); + } + ti.uFlags = TTF_IDISHWND|TTF_SUBCLASS; + ti.uId = (UINT)bct->hwnd; + ti.lpszText=(LPSTR)wParam; + SendMessage(hwndToolTips, TTM_ADDTOOLA, 0, (LPARAM)&ti); + } + LeaveCriticalSection(&csTips); + break; + } + case BUTTONTRANSLATE: + { + TCHAR szButton[MAX_PATH]; + GetWindowText(bct->hwnd, szButton, MAX_PATH); + SetWindowText(bct->hwnd, TranslateTS(szButton)); + break; + } + case WM_SETFOCUS: // set keybord bFocus and redraw + bct->bFocus = 1; + InvalidateRect(bct->hwnd, NULL, TRUE); + break; + case WM_KILLFOCUS: // kill bFocus and redraw + bct->bFocus = 0; + InvalidateRect(bct->hwnd, NULL, TRUE); + break; + case WM_WINDOWPOSCHANGED: + InvalidateRect(bct->hwnd, NULL, TRUE); + break; + case WM_ENABLE: // windows tells us to enable/disable + bct->stateId = wParam ? PBS_NORMAL : PBS_DISABLED; + InvalidateRect(bct->hwnd, NULL, TRUE); + break; + case WM_MOUSELEAVE: // faked by the WM_TIMER + if (bct->stateId != PBS_DISABLED) { // don't change states if disabled + bct->stateId = PBS_NORMAL; + InvalidateRect(bct->hwnd, NULL, TRUE); + } + break; + case WM_LBUTTONDOWN: + if (bct->stateId != PBS_DISABLED) { // don't change states if disabled + bct->stateId = PBS_PRESSED; + InvalidateRect(bct->hwnd, NULL, TRUE); + } + break; + case WM_LBUTTONUP: + if (bct->stateId != PBS_DISABLED) { // don't change states if disabled + BOOLEAN bPressed = bct->stateId == PBS_PRESSED; + + if (bct->dwStyle & MBS_PUSHBUTTON) { + if (bct->pbState) bct->pbState = 0; + else bct->pbState = 1; + } + bct->stateId = PBS_HOT; + + // Tell your daddy you got clicked, if mouse is still over the button. + if ((bct->dwStyle & MBS_PUSHBUTTON) || bPressed) + SendMessage(GetParent(hwndBtn), WM_COMMAND, MAKELONG(GetDlgCtrlID(hwndBtn), BN_CLICKED), (LPARAM)hwndBtn); + InvalidateRect(bct->hwnd, NULL, TRUE); + } + break; + case WM_MOUSEMOVE: + if (bct->stateId == PBS_NORMAL) { + bct->stateId = PBS_HOT; + InvalidateRect(bct->hwnd, NULL, TRUE); + } + // Call timer, used to start cheesy TrackMouseEvent faker + SetTimer(hwndBtn, BUTTON_POLLID, BUTTON_POLLDELAY, NULL); + break; + case WM_TIMER: // use a timer to check if they have did a mouseout + if (wParam == BUTTON_POLLID) { + RECT rc; + POINT pt; + + GetWindowRect(hwndBtn, &rc); + GetCursorPos(&pt); + if (!PtInRect(&rc, pt)) { // mouse must be gone, trigger mouse leave + PostMessage(hwndBtn, WM_MOUSELEAVE, 0, 0L); + KillTimer(hwndBtn, BUTTON_POLLID); + } + } + break; + case WM_ERASEBKGND: + return 1; + } + return DefWindowProc(hwndBtn, uMsg, wParam, lParam); +} + +VOID CtrlButtonUnloadModule() +{ + DeleteCriticalSection(&csTips); + UnregisterClass(UINFOBUTTONCLASS, hInst); +} + +VOID CtrlButtonLoadModule() +{ + WNDCLASSEX wc; + + ZeroMemory(&wc, sizeof(wc)); + wc.cbSize = sizeof(wc); + wc.lpszClassName = UINFOBUTTONCLASS; + wc.lpfnWndProc = Button_WndProc; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.cbWndExtra = sizeof(LPBTNCTRL); + wc.style = CS_GLOBALCLASS; + RegisterClassEx(&wc); + InitializeCriticalSection(&csTips); +} + diff --git a/plugins/SendScreenshotPlus/ctrl_button.h b/plugins/SendScreenshotPlus/ctrl_button.h new file mode 100644 index 0000000000..dc77334b05 --- /dev/null +++ b/plugins/SendScreenshotPlus/ctrl_button.h @@ -0,0 +1,43 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2009 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +aLONG with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef _UINFOEX_BOTTONS_H_INCLUDED_ +#define _UINFOEX_BOTTONS_H_INCLUDED_ 1 + +// theme procedures +extern HANDLE (WINAPI *OpenThemeData)(HWND,LPCWSTR); +extern HRESULT (WINAPI *CloseThemeData)(HANDLE); +extern BOOL (WINAPI *IsThemeBackgroundPartiallyTransparent)(HANDLE,INT,INT); +extern HRESULT (WINAPI *DrawThemeParentBackground)(HWND,HDC,RECT *); +extern HRESULT (WINAPI *DrawThemeBackground)(HANDLE,HDC,INT,INT,const RECT *,const RECT *); +extern HRESULT (WINAPI *DrawThemeText)(HANDLE,HDC,INT,INT,LPCWSTR,INT,DWORD,DWORD,const RECT *); +extern HRESULT (WINAPI *GetThemeTextExtent)(HANDLE,HDC,INT,INT,LPCWSTR,INT,DWORD,OPTIONAL const RECT*, RECT *); +extern HRESULT (WINAPI *GetThemeBackgroundRegion)(HANDLE,HDC,INT,INT,const RECT *,HRGN *); + + +VOID CtrlButtonLoadModule(); +VOID CtrlButtonUnloadModule(); + +BOOLEAN __fastcall ThemeSupport(); + +#endif /* _UINFOEX_BOTTONS_H_INCLUDED_ */ \ No newline at end of file diff --git a/plugins/SendScreenshotPlus/dlg_msgbox.cpp b/plugins/SendScreenshotPlus/dlg_msgbox.cpp new file mode 100644 index 0000000000..86fa25cbae --- /dev/null +++ b/plugins/SendScreenshotPlus/dlg_msgbox.cpp @@ -0,0 +1,854 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2009 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +aLONG with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: https://userinfoex.googlecode.com/svn/trunk/dlg_msgbox.cpp $ +Revision : $Revision: 164 $ +Last change on : $Date: 2009-12-02 21:24:35 +0100 (Mi, 02. Dez 2009) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#include "dlg_msgbox.h" + +typedef struct _MSGPOPUPDATA +{ + POPUPACTION pa[3]; + HWND hDialog; +} +MSGPOPUPDATA, *LPMSGPOPUPDATA; + +/** + * This helper function moves and resizes a dialog box's control element. + * + * @param hDlg - the dialog box's window handle + * @param idCtrl - the identication number of the control to move + * @param dx -ґnumber of pixels to horizontal move the control + * @param dy - number of pixels to vertical move the control + * @param dw - number of pixels to horizontal resize the control + * @param dh - number of pixels to vertical resize the control + * + * @return nothing + **/ +static FORCEINLINE VOID MoveCtrl(HWND hDlg, INT idCtrl, INT dx, INT dy, INT dw, INT dh) +{ + RECT ws; + HWND hCtrl = GetDlgItem(hDlg, idCtrl); + GetWindowRect(hCtrl, &ws); + OffsetRect(&ws, dx, dy); + MoveWindow(hCtrl, ws.left, ws.top, ws.right - ws.left + dw, ws.bottom - ws.top + dh, FALSE); +} + +/** + * This function loads the icon to display for the current message. + * + * @param pMsgBox - pointer to a MSGBOX structure, with information about the message to display. + * + * @retval HICON - The function returns an icon to display with the message. + * @retval NULL - There is no icon for the message. + **/ +HICON MsgLoadIcon(LPMSGBOX pMsgBox) +{ + HICON hIcon; + + // load the desired status icon + switch (pMsgBox->uType & MB_ICONMASK) + { + + // custom icon defined by caller function + case MB_ICON_OTHER: + { + hIcon = pMsgBox->hiMsg; + } + break; + + // default windows icons + case MB_ICON_ERROR: + case MB_ICON_QUESTION: + case MB_ICON_WARNING: + case MB_ICON_INFO: + { + LPCTSTR ico[] = { 0, IDI_ERROR, IDI_QUESTION, IDI_WARNING, IDI_INFORMATION }; + hIcon = LoadIcon(NULL, ico[MB_ICON_INDEX(pMsgBox->uType)]); + } + break; + + // no icon + default: + { + hIcon = NULL; + } + } + return hIcon; +} + +/** + * This function fills a given POPUPACTION structure with the data of a given message id, + * which is normally used by the message box. This is required to let the user interact + * with a popup in the same way as with a normal message dialog box. + * + * @param pa - reference to a POPUPACTION structure to fill + * @param id - the message id + * @param result - This parameter is passed to the POPUPACTION structure as is. + * + * @return nothing + **/ +void MakePopupAction(POPUPACTION &pa, INT id) +{ + pa.cbSize = sizeof(POPUPACTION); + pa.flags = PAF_ENABLED; + pa.wParam = MAKEWORD(id, BN_CLICKED); + pa.lParam = 0; + + switch (id) + { + case IDOK: + { + pa.lchIcon = IcoLib_GetIcon(ICO_BTN_OK); + mir_strcpy(pa.lpzTitle, MODNAME"/Ok"); + } + break; + + case IDCLOSE: + case IDCANCEL: + { + pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL); + mir_strcpy(pa.lpzTitle, MODNAME"/Cancel"); + } + break; + + case IDABORT: + { + pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL); + mir_strcpy(pa.lpzTitle, MODNAME"/Abort"); + } + break; + + case IDRETRY: + { + pa.lchIcon = IcoLib_GetIcon(ICO_BTN_UPDATE); + mir_strcpy(pa.lpzTitle, MODNAME"/Retry"); + } + break; + + case IDIGNORE: + { + pa.lchIcon = IcoLib_GetIcon(ICO_BTN_OK); + mir_strcpy(pa.lpzTitle, MODNAME"/Ignore"); + } + break; + + case IDYES: + { + pa.lchIcon = IcoLib_GetIcon(ICO_BTN_OK); + mir_strcpy(pa.lpzTitle, MODNAME"/Yes"); + } + break; + + case IDNO: + { + pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL); + mir_strcpy(pa.lpzTitle, MODNAME"/No"); + } + break; + + case IDHELP: + { + pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL); + mir_strcpy(pa.lpzTitle, MODNAME"/Help"); + } + break; + + case IDALL: + { + pa.lchIcon = IcoLib_GetIcon(ICO_BTN_OK); + mir_strcpy(pa.lpzTitle, MODNAME"/All"); + } + break; + + case IDNONE: + { + pa.lchIcon = IcoLib_GetIcon(ICO_BTN_CANCEL); + mir_strcpy(pa.lpzTitle, MODNAME"/None"); + } + } +} + +/** + * This is the message procedure for my nice looking message box + * + * @param hDlg - window handle + * @param uMsg - message to handle + * @param wParam - message specific parameter + * @param lParam - message specific parameter + * + * @return TRUE, FALSE, IDOK, IDYES, IDALL, IDNO or IDCANCEL + **/ +INT_PTR CALLBACK MsgBoxProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static INT retOk = IDOK; + static INT retAll = IDALL; + static INT retNon = IDNONE; + static INT retCancel = IDCANCEL; + + switch (uMsg) + { + case WM_INITDIALOG: + { + LPMSGBOX pMsgBox = (LPMSGBOX)lParam; + + if (PtrIsValid(pMsgBox)) + { + INT icoWidth = 0; + INT InfoBarHeight = 0; + HFONT hNormalFont; + + hNormalFont = (HFONT)SendDlgItemMessage(hDlg, TXT_NAME, WM_GETFONT, 0, 0); + if (pMsgBox->uType & MB_INFOBAR) + { + LOGFONT lf; + + // set bold font for name in description area + GetObject(hNormalFont, sizeof(lf), &lf); + lf.lfWeight = FW_BOLD; + hNormalFont = CreateFontIndirect(&lf); + + // set infobar's textfont + SendDlgItemMessage(hDlg, TXT_NAME, WM_SETFONT, (WPARAM)hNormalFont, 0); + + // set infobar's logo icon + SendDlgItemMessage(hDlg, ICO_DLGLOGO, STM_SETIMAGE, IMAGE_ICON, + (LPARAM)((pMsgBox->hiLogo) ? pMsgBox->hiLogo : IcoLib_GetIcon(ICO_DLG_DETAILS))); + + // anable headerbar + ShowWindow(GetDlgItem(hDlg, TXT_NAME), SW_SHOW); + ShowWindow(GetDlgItem(hDlg, ICO_DLGLOGO), SW_SHOW); + } + else + { + RECT rc; + GetClientRect(GetDlgItem(hDlg, TXT_NAME), &rc); + InfoBarHeight = rc.bottom; + + if (pMsgBox->hiLogo) + { + SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)pMsgBox->hiLogo); + } + } + + // draw the desired status icon + HICON hIcon = MsgLoadIcon(pMsgBox); + if (hIcon) + { + SendDlgItemMessage(hDlg, ICO_MSGDLG, STM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + } + else + { + RECT ws; + GetWindowRect(GetDlgItem(hDlg, ICO_MSGDLG), &ws); + icoWidth = ws.right - ws.left; + ShowWindow(GetDlgItem(hDlg, ICO_MSGDLG), SW_HIDE); + } + + // resize the messagebox and reorganize the buttons + if (HDC hDC = GetDC(hDlg)) + { + POINT mpt = {0,0}; + RECT ws = {0,0,0,0}; + INT txtWidth, + txtHeight, + needX, needY; + RECT rcDlg; + SIZE ts; + LPTSTR h, rs; + + SelectObject(hDC, hNormalFont); + + for (rs = h = pMsgBox->ptszMsg, txtHeight = 0, txtWidth = 0; h; h++) + { + if (*h == '\n' || *h == '\0') + { + GetTextExtentPoint32(hDC, rs, h - rs, &ts); + if (ts.cx > txtWidth) + { + txtWidth = ts.cx; + } + txtHeight += ts.cy; + if (*h == '\0') + { + break; + } + rs = h + 1; + } + } + ReleaseDC(hDlg, hDC); + + // calc new dialog size + GetWindowRect(hDlg, &rcDlg); + GetWindowRect(GetDlgItem(hDlg, TXT_MESSAGE), &ws); + needX = txtWidth - (ws.right - ws.left) - icoWidth; + needY = max(0, txtHeight - (ws.bottom - ws.top) + 5); + rcDlg.left -= needX/2; rcDlg.right += needX/2; + rcDlg.top -= (needY-InfoBarHeight)/2; rcDlg.bottom += (needY-InfoBarHeight)/2; + + // resize dialog window + MoveWindow(hDlg, + rcDlg.left, rcDlg.top, + rcDlg.right - rcDlg.left, + rcDlg.bottom - rcDlg.top, + FALSE); + ClientToScreen(hDlg, &mpt); + + MoveCtrl(hDlg, STATIC_WHITERECT, -mpt.x, -mpt.y, needX, needY - InfoBarHeight); + MoveCtrl(hDlg, TXT_NAME, -mpt.x, -mpt.y, needX, 0); + MoveCtrl(hDlg, ICO_DLGLOGO, -mpt.x + needX, -mpt.y, 0, 0); + MoveCtrl(hDlg, ICO_MSGDLG, -mpt.x, -mpt.y - InfoBarHeight, 0, 0); + MoveCtrl(hDlg, TXT_MESSAGE, -mpt.x - icoWidth, -mpt.y - InfoBarHeight, needX, needY); + MoveCtrl(hDlg, STATIC_LINE2, -mpt.x, -mpt.y + needY - InfoBarHeight, needX, 0); + + // + // Do pushbutton positioning + // + { + RECT rcOk, rcAll, rcNone, rcCancel; + LONG okWidth, caWidth, allWidth, noneWidth, dlgMid; + + // get button rectangles + GetWindowRect(GetDlgItem(hDlg, IDOK), &rcOk); + OffsetRect(&rcOk, -mpt.x, -mpt.y + needY - InfoBarHeight); + + GetWindowRect(GetDlgItem(hDlg, IDALL), &rcAll); + OffsetRect(&rcAll, -mpt.x, -mpt.y + needY - InfoBarHeight); + + GetWindowRect(GetDlgItem(hDlg, IDNONE), &rcNone); + OffsetRect(&rcNone, -mpt.x, -mpt.y + needY - InfoBarHeight); + + GetWindowRect(GetDlgItem(hDlg, IDCANCEL), &rcCancel); + OffsetRect(&rcCancel, -mpt.x, -mpt.y + needY - InfoBarHeight); + + okWidth = rcOk.right - rcOk.left; + allWidth = rcAll.right - rcAll.left; + noneWidth = rcNone.right - rcNone.left; + caWidth = rcCancel.right - rcCancel.left; + dlgMid = (rcDlg.right - rcDlg.left) / 2; + + // load button configuration + switch (MB_TYPE(pMsgBox->uType)) + { + + case MB_OK: + { + rcOk.left = dlgMid - (okWidth / 2); + rcOk.right = rcOk.left + okWidth; + ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); + } + break; + + case MB_OKCANCEL: + { + retOk = IDRETRY; + SetDlgItemText(hDlg, IDOK, LPGENT("OK")); + retCancel = IDCANCEL; + SetDlgItemText(hDlg, IDCANCEL, LPGENT("Cancel")); + rcOk.left = dlgMid - okWidth - 10; + rcOk.right = rcOk.left + okWidth; + rcCancel.left = dlgMid + 10; + rcCancel.right = rcCancel.left + caWidth; + ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); + ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); + } + break; + + case MB_RETRYCANCEL: + { + retOk = IDRETRY; + SetDlgItemText(hDlg, IDOK, LPGENT("Retry")); + retCancel = IDCANCEL; + SetDlgItemText(hDlg, IDCANCEL, LPGENT("Cancel")); + rcOk.left = dlgMid - okWidth - 10; + rcOk.right = rcOk.left + okWidth; + rcCancel.left = dlgMid + 10; + rcCancel.right = rcCancel.left + caWidth; + ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); + ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); + } + break; + + case MB_YESNO: + { + retOk = IDYES; + SetDlgItemText(hDlg, IDOK, LPGENT("Yes")); + retCancel = IDNO; + SetDlgItemText(hDlg, IDCANCEL, LPGENT("No")); + rcOk.left = dlgMid - okWidth - 10; + rcOk.right = rcOk.left + okWidth; + rcCancel.left = dlgMid + 10; + rcCancel.right = rcCancel.left + caWidth; + ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); + ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); + } + break; + + case MB_ABORTRETRYIGNORE: + { + retOk = IDABORT; + SetDlgItemText(hDlg, IDOK, LPGENT("Abord")); + retAll = IDABORT; + SetDlgItemText(hDlg, IDALL, LPGENT("Retry")); + retCancel = IDCANCEL; + SetDlgItemText(hDlg, IDCANCEL, LPGENT("Ignore")); + rcAll.left = dlgMid - (allWidth / 2); + rcAll.right = rcAll.left + allWidth; + rcOk.left = rcAll.left - okWidth - 5; + rcOk.right = rcOk.left + okWidth; + rcCancel.left = rcAll.right + 5; + rcCancel.right = rcCancel.left + caWidth; + ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); + ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW); + ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); + } + break; + + case MB_YESNOCANCEL: + { + retOk = IDYES; + SetDlgItemText(hDlg, IDOK, LPGENT("Yes")); + retAll = IDNO; + SetDlgItemText(hDlg, IDALL, LPGENT("No")); + retCancel = IDCANCEL; + SetDlgItemText(hDlg, IDCANCEL, LPGENT("Cancel")); + rcAll.left = dlgMid - (allWidth / 2); + rcAll.right = rcAll.left + allWidth; + rcOk.left = rcAll.left - okWidth - 5; + rcOk.right = rcOk.left + okWidth; + rcCancel.left = rcAll.right + 5; + rcCancel.right = rcCancel.left + caWidth; + ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); + ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW); + ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); + } + break; + + case MB_YESALLNO: + { + retOk = IDYES; + SetDlgItemText(hDlg, IDOK, LPGENT("Yes")); + retAll = IDALL; + SetDlgItemText(hDlg, IDALL, LPGENT("All")); + //retNon = IDNONE; + SetDlgItemText(hDlg, IDNONE, LPGENT("None")); + retCancel = IDNO; + SetDlgItemText(hDlg, IDCANCEL, LPGENT("No")); + rcCancel.right = rcDlg.right - rcDlg.left - 10; + rcCancel.left = rcCancel.right - caWidth; + rcNone.right = rcCancel.left - 5; + rcNone.left = rcNone.right - noneWidth; + rcAll.right = rcNone.left - 5; + rcAll.left = rcAll.right - allWidth; + rcOk.right = rcAll.left - 5; + rcOk.left = rcOk.right - okWidth; + // show buttons + ShowWindow(GetDlgItem(hDlg, IDOK), SW_SHOW); + ShowWindow(GetDlgItem(hDlg, IDALL), SW_SHOW); + ShowWindow(GetDlgItem(hDlg, IDNONE), SW_SHOW); + ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_SHOW); + } + break; + + default: + { + rcOk.left = dlgMid - (okWidth / 2); + rcOk.right = rcOk.left + okWidth; + } + } + // move ok button + MoveWindow(GetDlgItem(hDlg, IDOK), + rcOk.left, rcOk.top, + rcOk.right - rcOk.left, rcOk.bottom - rcOk.top, + FALSE); + // move all button + MoveWindow(GetDlgItem(hDlg, IDALL), + rcAll.left, rcAll.top, + rcAll.right - rcAll.left, rcAll.bottom - rcAll.top, + FALSE); + // move none button + MoveWindow(GetDlgItem(hDlg, IDNONE), + rcNone.left, rcNone.top, + rcNone.right - rcNone.left, rcNone.bottom - rcNone.top, + FALSE); + // move cancel button + MoveWindow(GetDlgItem(hDlg, IDCANCEL), + rcCancel.left, rcCancel.top, + rcCancel.right - rcCancel.left, rcCancel.bottom - rcCancel.top, + FALSE); + } // end* Do pushbutton positioning + } // end* resize the messagebox and reorganize the buttons + + TranslateDialogDefault(hDlg); + + // set text's + SetWindowText(hDlg, pMsgBox->ptszTitle); + SetDlgItemText(hDlg, TXT_NAME, pMsgBox->ptszInfoText); + SetDlgItemText(hDlg, TXT_MESSAGE, pMsgBox->ptszMsg); + + return TRUE; + } // end* PtrIsValid(pMsgBox) + } // end* WM_INITDIALOG: + break; + + case WM_CTLCOLORSTATIC: + { + switch (GetWindowLong((HWND)lParam, GWL_ID)) + { + case STATIC_WHITERECT: + case ICO_DLGLOGO: + case ICO_MSGDLG: + case TXT_MESSAGE: + case TXT_NAME: + { + SetTextColor((HDC)wParam, GetSysColor(COLOR_WINDOWTEXT)); + return GetSysColor(COLOR_WINDOW); + } + } + } + break; + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDOK: + EndDialog(hDlg, retOk); + break; + case IDCANCEL: + EndDialog(hDlg, retCancel); + break; + case IDALL: + EndDialog(hDlg, retAll); + break; + case IDNONE: + EndDialog(hDlg, retNon); + } + } + break; + + case WM_DESTROY: + { + DeleteObject((HFONT)SendDlgItemMessage(hDlg, TXT_NAME, WM_GETFONT, 0, 0)); + } + break; + } + return FALSE; +} + + +/** + * Dummi modal MsgBox for popup, + * this set call function in wait stait and do not freece miranda main thread + * the window is outside the desktop + */ +INT_PTR CALLBACK MsgBoxPop(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + POPUPDATAT pd; + LPMSGPOPUPDATA pmpd; + LPMSGBOX pMsgBox = (LPMSGBOX)lParam; + + MoveWindow(hDlg,-10,-10,0,0,FALSE); + pmpd = (LPMSGPOPUPDATA)mir_alloc(sizeof(MSGPOPUPDATA)); + if (pmpd) + { + ZeroMemory(&pd, sizeof(pd)); + pd.cbSize = sizeof(POPUPDATAT); + pd.lchContact = NULL; //(HANDLE)wParam; + // icon + pd.lchIcon = MsgLoadIcon(pMsgBox); + mir_tcsncpy(pd.lptzContactName, pMsgBox->ptszTitle, SIZEOF(pd.lptzContactName)); + mir_tcsncpy(pd.lptzText, pMsgBox->ptszMsg, SIZEOF(pd.lptzText)); + + // CALLBAC Proc + pd.PluginWindowProc = (WNDPROC)PopupProc; + // + pd.PluginData = pmpd; + + pd.iSeconds = -1; + + pd.hNotification = NULL; + pd.lpActions = pmpd->pa; + + // set color of popup + switch (pMsgBox->uType & MB_ICONMASK) + { + case MB_ICON_ERROR: + { + pd.colorBack = RGB(200, 10, 0); + pd.colorText = RGB(255, 255, 255); + } + break; + + case MB_ICON_WARNING: + { + pd.colorBack = RGB(200, 100, 0); + pd.colorText = RGB(255, 255, 255); + } + break; + + default: + { + if (pMsgBox->uType & MB_CUSTOMCOLOR) + { + pd.colorBack = pMsgBox->colorBack; + pd.colorText = pMsgBox->colorText; + } + } + } + + // handle for MakePopupAction + pmpd->hDialog = hDlg; + + // active buttons + switch (MB_TYPE(pMsgBox->uType)) + { + case MB_OK: + { + MakePopupAction(pmpd->pa[pd.actionCount++], IDOK); + } + break; + + case MB_OKCANCEL: + { + MakePopupAction(pmpd->pa[pd.actionCount++], IDOK); + MakePopupAction(pmpd->pa[pd.actionCount++], IDCANCEL); + } + break; + + case MB_RETRYCANCEL: + { + MakePopupAction(pmpd->pa[pd.actionCount++], IDRETRY); + MakePopupAction(pmpd->pa[pd.actionCount++], IDCANCEL); + } + break; + + case MB_YESNO: + { + MakePopupAction(pmpd->pa[pd.actionCount++], IDYES); + MakePopupAction(pmpd->pa[pd.actionCount++], IDNO); + } + break; + + case MB_ABORTRETRYIGNORE: + { + MakePopupAction(pmpd->pa[pd.actionCount++], IDABORT); + MakePopupAction(pmpd->pa[pd.actionCount++], IDRETRY); + MakePopupAction(pmpd->pa[pd.actionCount++], IDIGNORE); + } + break; + + case MB_YESNOCANCEL: + { + MakePopupAction(pmpd->pa[pd.actionCount++], IDYES); + MakePopupAction(pmpd->pa[pd.actionCount++], IDNO); + MakePopupAction(pmpd->pa[pd.actionCount++], IDCANCEL); + } + break; + + case MB_YESALLNO: + { + MakePopupAction(pmpd->pa[pd.actionCount++], IDYES); + MakePopupAction(pmpd->pa[pd.actionCount++], IDALL); + MakePopupAction(pmpd->pa[pd.actionCount++], IDNO); + } + break; + + } // end* switch + + // create popup + CallService(MS_POPUP_ADDPOPUPT, (WPARAM) &pd, APF_NEWDATA); + if (MB_TYPE(pMsgBox->uType) == MB_OK) + { + EndDialog(hDlg, IDOK); + } + } // end*if (pmpd) + break; + } // end* WM_INITDIALOG: + } // end* switch (uMsg) + return FALSE; +} + +/** + * This is the message procedure for popup + * + * @param hDlg - window handle + * @param uMsg - message to handle + * @param wParam - message specific parameter + * @param lParam - message specific parameter + * + * @return TRUE, FALSE, IDOK, IDYES, IDALL, IDNO or IDCANCEL + **/ +INT_PTR CALLBACK PopupProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case UM_POPUPACTION: + { + if (HIWORD(wParam) == BN_CLICKED) + { + LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)PUGetPluginData(hDlg); + + if (pmpd) + { + switch (LOWORD(wParam)) + { + case IDOK: + case IDCANCEL: + case IDABORT: + case IDRETRY: + case IDIGNORE: + case IDYES: + case IDNO: + case IDALL: + case IDNONE: + { + if (IsWindow(pmpd->hDialog)) + EndDialog(pmpd->hDialog, LOWORD(wParam)); + } + break; + + default: + { + if (IsWindow(pmpd->hDialog)) + EndDialog(pmpd->hDialog, IDCANCEL); + } + } + } + PUDeletePopUp(hDlg); + } + } + break; + + case UM_FREEPLUGINDATA: + { + LPMSGPOPUPDATA pmpd = (LPMSGPOPUPDATA)PUGetPluginData(hDlg); + if (pmpd > 0) { + mir_freeAndNil(pmpd); + } + return TRUE; //TRUE or FALSE is the same, it gets ignored. + } + break; + + default: + break; + } + return DefWindowProc(hDlg, uMsg, wParam, lParam); +} + +/** + * This is the service function for external plugins to use the nice messagebox + * + * @param wParam - HANDLE hContact which can display an avatar for popups + * @param lParam - MSGBOX structure holding parameters + * + * @return The function returns the ID of the clicked button (IDOK, IDCANCEL, ...) + * or -1 on error. + **/ +INT_PTR MsgBoxService(WPARAM wParam, LPARAM lParam) +{ + INT rc = -1; + LPMSGBOX pMsgBox = (LPMSGBOX)lParam; + + // check input + if (PtrIsValid(pMsgBox) && pMsgBox->cbSize == sizeof(MSGBOX)) + { + // Shall the MessageBox displayed as popup? + if (!(pMsgBox->uType & (MB_INFOBAR|MB_NOPOPUP)) && // message box can be a popup? + ServiceExists(MS_POPUP_ADDPOPUPT) && // popups exist? + myGlobals.PopUpActionsExist == 1 && // popup support ext stuct? + (DBGetContactSettingDword(NULL, "PopUp","Actions", 0) & 1) && // popup++ actions on? + DBGetContactSettingByte(NULL, MODNAME, SET_POPUPMSGBOX, DEFVAL_POPUPMSGBOX) // user likes popups? + ) + { + rc = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_MSGBOXDUMMI), pMsgBox->hParent, (DLGPROC)MsgBoxPop, lParam); + } + else + { + rc = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_MSGBOX), pMsgBox->hParent, (DLGPROC)MsgBoxProc, lParam); + } + } + return rc; +} + +/** + * name: MsgBox + * desc: calls a messagebox + * param: + **/ +INT_PTR MsgBox(HWND hParent, UINT uType, LPTSTR pszTitle, LPTSTR pszInfo, LPTSTR pszFormat, ...) +{ + MSGBOX mb = {0}; + TCHAR tszMsg[MAX_SECONDLINE]; + va_list vl; + + va_start(vl, pszFormat); + mir_vsntprintf(tszMsg, SIZEOF(tszMsg), TranslateTS(pszFormat), vl); + va_end(vl); + + mb.cbSize = sizeof(MSGBOX); + mb.hParent = hParent; + mb.hiLogo = LoadIcon(hInst, MAKEINTRESOURCE(IDI_PLUG_MAIN)); + mb.hiMsg = NULL; + mb.ptszTitle = TranslateTS(pszTitle); + mb.ptszInfoText = TranslateTS(pszInfo); + mb.ptszMsg = tszMsg; + mb.uType = uType; + return MsgBoxService(NULL, (LPARAM)&mb); +} + +/** + * name: MsgErr + * desc: calls a messagebox + * param: + **/ +INT_PTR MsgErr(HWND hParent, LPCTSTR pszFormat, ...) +{ + if(!pszFormat) return -1; + MSGBOX mb = {0}; + TCHAR tszTitle[MAX_SECONDLINE]; + TCHAR tszMsg[MAX_SECONDLINE]; + va_list vl; + + mir_sntprintf(tszTitle, SIZEOF(tszMsg),_T("%s - %s") ,_T(MODNAME), TranslateT("Error")); + + va_start(vl, pszFormat); + mir_vsntprintf(tszMsg, SIZEOF(tszMsg), TranslateTS(pszFormat), vl); + va_end(vl); + + mb.cbSize = sizeof(MSGBOX); + mb.hParent = hParent; + mb.hiLogo = LoadIcon(hInst, MAKEINTRESOURCE(IDI_PLUG_MAIN)); + mb.hiMsg = NULL; + mb.ptszTitle = tszTitle; + mb.ptszMsg = tszMsg; + mb.uType = MB_OK|MB_ICON_ERROR; + return MsgBoxService(NULL, (LPARAM)&mb); +} diff --git a/plugins/SendScreenshotPlus/dlg_msgbox.h b/plugins/SendScreenshotPlus/dlg_msgbox.h new file mode 100644 index 0000000000..a6cd04c6b7 --- /dev/null +++ b/plugins/SendScreenshotPlus/dlg_msgbox.h @@ -0,0 +1,108 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2009 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +aLONG with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: https://userinfoex.googlecode.com/svn/trunk/dlg_msgbox.h $ +Revision : $Revision: 164 $ +Last change on : $Date: 2009-12-02 21:24:35 +0100 (Mi, 02. Dez 2009) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef _DLG_MSGBOX +#define _DLG_MSGBOX 1 + +//--------------------------------------------------------------------------- +#include "global.h" + +//--------------------------------------------------------------------------- +#define SET_POPUPMSGBOX "PopupMsgBox" +#define DEFVAL_POPUPMSGBOX TRUE //FALSE + +/* UserInfo/MsgBox v0.1.0.3+ +Some little changed message box for nicer look of miranda's messages or questions :-) +wParam=hContact - can be null +lParam=(_MSGBOX*)pMsg - structure that holds information about the look of the message dialog +uType member of _MSGBOX can be a combination of the following values, where most of them are defined in winuser.h: +MB_OK +MB_OKCANCEL +MB_YESALLNO +MB_YESNO +For valid icon values use one of the following MB_ICON_... +Funktion returns: IDOK, IDYES, IDALL, IDNO or IDCANCEL +*/ + +/* + Defined in winuser.h + ******************** + +#define MB_OK 0x00000000L +#define MB_OKCANCEL 0x00000001L +#define MB_ABORTRETRYIGNORE 0x00000002L +#define MB_YESNOCANCEL 0x00000003L +#define MB_YESNO 0x00000004L +#define MB_RETRYCANCEL 0x00000005L +*/ +#define MB_YESALLNO 0x00000007L +#define MB_TYPE(p) ((p)&MB_TYPEMASK) + +/* +valid predefined icon values +*/ +#define MB_ICON_NONE 0x00000000L // 0 - no icon +#define MB_ICON_ERROR 0x00000010L // 16 - error icon +#define MB_ICON_QUESTION 0x00000020L // 32 - question mark +#define MB_ICON_WARNING 0x00000030L // 48 - warning +#define MB_ICON_INFO 0x00000040L // 64 - info +#define MB_ICON_OTHER 0x00000080L // 240 - use icon _MSGBOX->hiMsg +#define MB_ICON_INDEX(p) (((p)&MB_ICONMASK)>>4) + +/* +flags +*/ +#define MB_INFOBAR 0x00000100L +#define MB_NOPOPUP 0x00000200L +#define MB_CUSTOMCOLOR 0x00000300L + +typedef struct _MSGBOX +{ + UINT cbSize; // size of this structure + UINT uType; // parameters + HICON hiLogo; // right upper icon of the info bar + HICON hiMsg; // icon left next to the message text + LPTSTR ptszTitle; + LPTSTR ptszInfoText; + LPTSTR ptszMsg; + HWND hParent; // parent window for the messagebox + COLORREF colorBack; // valid if MB_CUSTOMCOLOR is set + COLORREF colorText; // valid if MB_CUSTOMCOLOR is set +} MSGBOX, *LPMSGBOX; + + +INT_PTR CALLBACK MsgBoxProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK MsgBoxPop (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK PopupProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +INT_PTR MsgBoxService(WPARAM wParam, LPARAM lParam); +INT_PTR MsgBox(HWND hParent, UINT uType, LPTSTR pszTitle, LPTSTR pszInfo, LPTSTR pszFormat, ...); +INT_PTR MsgErr(HWND hParent, LPCTSTR pszFormat, ...); + +#endif /* _DLG_MSGBOX */ \ No newline at end of file diff --git a/plugins/SendScreenshotPlus/global.h b/plugins/SendScreenshotPlus/global.h new file mode 100644 index 0000000000..0320949957 --- /dev/null +++ b/plugins/SendScreenshotPlus/global.h @@ -0,0 +1,196 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +(c) 2004-2006 Sйrgio Vieira Rolanski (portet from Borland C++) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/global.h $ +Revision : $Revision: 22 $ +Last change on : $Date: 2010-05-02 21:25:02 +0400 (Р’СЃ, 02 май 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef _GLOBAL_H_ +#define _GLOBAL_H_ + +#define WINVER 0x0700 +#define _WIN32_WINNT 0x0700 +#define _WIN32_IE 0x0601 + +#define OEMRESOURCE + +#define MIRANDA_VER 0x0800 + +#ifdef _WIN32 + #pragma warning(disable:4786) +#endif + +// Windows includes +#include +#include + +// Standard includes +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +// Miranda IM SDK includes +#include +#include +#include +#include // This must be included first +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// plugins SDK +#include +#include +#include +#include +#include "sdk/m_popup.h" // +#include "sdk/icons.h" //from uiex icon pack + +// Project resources +#include "sdk/m_sendss.h" +#include "mir_string.h" +#include "mir_icolib.h" +#include "ctrl_button.h" +#include "dlg_msgbox.h" +#include "resource.h" +#include "version.h" + +#ifdef ComboBox_SelectItemData + // use Workaround for MS bug ComboBox_SelectItemData; + #undef ComboBox_SelectItemData +#endif + +#define UM_CLOSING WM_USER+1 +#define UM_EVENT WM_USER+2 +#define UM_TAB1 WM_USER+11 + +// Generic Message Box for Errors +#define MSGERROR(text) MessageBox(NULL, text, _T("SendSS"), MB_OK | MB_ICONERROR) +#define MSGINFO (text) MessageBox(NULL, text, _T("SendSS"), MB_OK | MB_ICONINFORMATION) + +typedef struct _MGLOBAL { + DWORD mirandaVersion; // mirandaVersion + BOOLEAN PopUpExist : 1; // Popup or MS_POPUP_ADDPOPUP exist + BOOLEAN PopUpActionsExist : 1; // Popup++ or MS_POPUP_REGISTERACTIONS exist + BOOLEAN PluginHTTPExist : 1; // HTTPServer or MS_HTTP_ACCEPT_CONNECTIONS exist + BOOLEAN PluginFTPExist : 1; // FTPFile or MS_FTPFILE_SHAREFILE exist + +} MGLOBAL, *LPMGLOBAL; + +//--------------------------------------------------------------------------- +#define ERROR_TITLE _T("SendScreenshot - Error") + +// Miranda Database Key +#define SZ_SENDSS "SendSS" +#define MODNAME "SendSS" + +extern HINSTANCE hInst; +extern MGLOBAL myGlobals; +extern MM_INTERFACE mmi; +extern UTF8_INTERFACE utfi; +extern HANDLE hNetlibUser; + +#define PtrIsValid(p) (((p)!=0)&&(((HANDLE)(p))!=INVALID_HANDLE_VALUE)) + +template +std::basic_string<_Elem> replace(const std::basic_string<_Elem> & Origninal, const std::basic_string<_Elem> & What, const std::basic_string<_Elem> & With) +{ + std::basic_string<_Elem> res; + size_t l = 0; + size_t p = 0; + + for (size_t p = Origninal.find(What.c_str(), 0); p != std::basic_string<_Elem>::npos; p = Origninal.find(What.c_str(), l)) + { + if (l != p) + res.append(Origninal.c_str() + l, p - l); + res.append(With); + l = p + What.length(); + } + if (l < Origninal.length()) + res.append(Origninal.c_str() + l); + + return res; +} + +#endif + +/************************************************************* + * Uinfobuttonclass module + */ + +// button styles +#define MBS_DEFBUTTON 0x00001000L // default button +#define MBS_PUSHBUTTON 0x00002000L // toggle button +#define MBS_FLAT 0x00004000L // flat button +#define MBS_DOWNARROW 0x00008000L // has arrow on the right + +#define MBF_UNICODE 1 +#ifdef _UNICODE + #define MBF_TCHAR MBF_UNICODE +#else + #define MBF_TCHAR 0 +#endif + +// BUTTONADDTOOLTIP +// use lParam=MBF_UNICODE to set unicode tooltips +// for lParam=0 the string is interpreted as ansi + +// message to explicitly translate the buttons text, +// as it is not done by default translation routine +// wParam=lParam=NULL +#define BUTTONTRANSLATE (WM_USER+6) + +/* UserInfo/MsgBox v0.1.0.4+ +Slightly modified version of MButtonClass, to draw both text and icon in a button control +*/ +#define UINFOBUTTONCLASS _T("UInfoButtonClass") + diff --git a/plugins/SendScreenshotPlus/mir_icolib.cpp b/plugins/SendScreenshotPlus/mir_icolib.cpp new file mode 100644 index 0000000000..dc9a7ad02f --- /dev/null +++ b/plugins/SendScreenshotPlus/mir_icolib.cpp @@ -0,0 +1,382 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2009 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +aLONG with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +this file is taken from UserinfoEx plugin and support UserinfoEx icon pack !!!! + +*/ + +#include "global.h" + + +typedef struct _ICODESC +{ + LPSTR pszName; + LPSTR pszDesc; + LPSTR pszSection; + BOOL bfromIconPack; + WORD idResource; + BYTE size; +} ICODESC; + +HICON ghDefIcon = NULL; + +//IDI_PLUG_MAIN must be the first icon from Plugin.dll, all other icon must be IDI_PLUG_MAIN+n +static ICODESC icoDesc[] = +{ + // common + { ICO_PLUG_SSWINDOW1, "Screenshot Icon1", SECT_COMMON, 0, IDI_PLUG_MAIN, -1 }, + { ICO_PLUG_SSWINDOW2, "Screenshot Icon2", SECT_COMMON, 0, IDI_PLUG_ICON1, 0 }, + { ICO_PLUG_SSTARGET, "Target Cursor", SECT_COMMON, 0, IDI_PLUG_ICON2, 1 }, + { ICO_PLUG_SSMONITOR, "Target Desktop", SECT_COMMON, 0, IDI_PLUG_ICON3, 1 }, + { ICO_PLUG_SSDEFAULT, "Default", SECT_COMMON, 0, IDI_PLUG_DEFAULT, 0 }, + + // overlays + { ICO_PLUG_OVERLAYON, "overlay on", SECT_OVERLAY, 0, IDI_PLUG_OVERLAYON, 0 }, + { ICO_PLUG_OVERLAYOFF, "overlay off", SECT_OVERLAY, 0, IDI_PLUG_OVERLAYOFF,0 }, + + // dialogs +// { ICO_DLG_DETAILS, "Details Infobar", SECT_DLG, 1, IDI_DLG_DETAILS, 48 }, +// { ICO_DLG_PHONE, "Phone Infobar", SECT_DLG, 1, IDI_DLG_PHONE, 1 }, +// { ICO_DLG_EMAIL, "E-Mail Infobar", SECT_DLG, 1, IDI_DLG_EMAIL, 1 }, + + // button icons + { ICO_PLUG_SSHELP, "Help", SECT_BUTTONS, 0, IDI_PLUG_HELP, 0 }, + { ICO_PLUG_SSFOLDERO, "Open Folder", SECT_BUTTONS, 0, IDI_PLUG_FOLDERO, 0 }, + { ICO_PLUG_SSDESKOFF, "description off", SECT_BUTTONS, 0, IDI_PLUG_DESKOFF, 0 }, + { ICO_PLUG_SSDESKON, "description on", SECT_BUTTONS, 0, IDI_PLUG_DESKON, 0 }, + { ICO_PLUG_SSDELOFF, "delete off", SECT_BUTTONS, 0, IDI_PLUG_DELOFF, 0 }, + { ICO_PLUG_SSDELON, "delete on", SECT_BUTTONS, 0, IDI_PLUG_DELON, 0 }, + { ICO_PLUG_ARROWL, "Prev", SECT_BUTTONS, 0, IDI_PLUG_ARROWL, 0 }, + { ICO_PLUG_ARROWR, "Next", SECT_BUTTONS, 0, IDI_PLUG_ARROWR, 0 }, + + { ICO_BTN_UPDATE, "Update", SECT_BUTTONS, 1, IDI_BTN_UPDATE, 0 }, + { ICO_BTN_OK, "Ok", SECT_BUTTONS, 1, IDI_BTN_OK, 0 }, + { ICO_BTN_CANCEL, "Cancel", SECT_BUTTONS, 1, IDI_BTN_CLOSE, 0 }, + { ICO_BTN_APPLY, "Apply", SECT_BUTTONS, 1, IDI_BTN_APPLY, 0 }, +// { ICO_BTN_GOTO, "Goto", SECT_BUTTONS, 1, IDI_BTN_GOTO, 0 }, +// { ICO_BTN_EMAIL, "e-mail", SECT_BUTTONS, 1, IDI_BTN_EMAIL, 0 }, +// { ICO_BTN_DOWNARROW, "Down arrow", SECT_BUTTONS, 1, IDI_BTN_DOWNARROW, 0 }, +// { ICO_BTN_ADD, "Add", SECT_BUTTONS, 1, IDI_BTN_ADD, 0 }, + { ICO_BTN_EDIT, "Edit", SECT_BUTTONS, 1, IDI_BTN_EDIT, 0 }, +// { ICO_BTN_DELETE, "Delete", SECT_BUTTONS, 1, IDI_BTN_DELETE, 0 }, +// { ICO_BTN_SEARCH, "Search", SECT_BUTTONS, 1, IDI_SEARCH, 0 }, +// { ICO_BTN_YES, "Yes", SECT_BUTTONS, 1, IDI_BTN_YES, 0 }, +// { ICO_BTN_NO, "No", SECT_BUTTONS, 1, IDI_BTN_NO, 0 }, +// { ICO_BTN_IGNORE, "Ignore", SECT_BUTTONS, 1, IDI_BTN_IGNORE, 0 }, + +}; + +/** + * This function finds the default iconpack file and return its path. + * + * @param - none + * + * @return This function returns the relative path to an existing icon pack. + **/ +LPTSTR IcoLib_GetDefaultIconFileName() +{ + static LPTSTR path[] = { + _T("Icons\\uinfoex_icons.dll"), + _T("Plugins\\uinfoex_icons.dll"), + _T("Customize\\Icons\\uinfoex_icons.dll") + }; + TCHAR absolute[MAX_PATH]; + + for (INT i = 0; i < SIZEOF(path); i++) + { + CallService(MS_UTILS_PATHTOABSOLUTET, (WPARAM)path[i], (LPARAM)absolute); + if (PathFileExists(absolute)) + { + return path[i]; + } + } + return NULL; +} + +/** + * This function checks the version of an iconpack. + * If the icon pack's version differs from the desired one, + * dialog with a warning is displayed. + * + * @param szIconPack - This is the path to the icon pack. + * It can be absolute or relative. + * + * @return nothing + **/ +static VOID IcoLib_CheckIconPackVersion(LPTSTR szIconPack) +{ + //if (DB::Setting::GetByte(SET_ICONS_CHECKFILEVERSION, TRUE)) + if (DBGetContactSettingByte(NULL,MODNAME,SET_ICONS_CHECKFILEVERSION, TRUE)) + { + if (szIconPack) + { + TCHAR szAbsolutePath[MAX_PATH]; + HMODULE hIconDll; + + CallService(MS_UTILS_PATHTOABSOLUTET, (WPARAM)szIconPack, (LPARAM)szAbsolutePath); + + hIconDll = LoadLibrary(szAbsolutePath); + if (hIconDll) + { + CHAR szFileVersion[64]; + + if (!LoadStringA(hIconDll, IDS_ICOPACKVERSION, szFileVersion, sizeof(szFileVersion)) || + mir_strcmp(szFileVersion, "__UserInfoEx_IconPack_1.2__")) + { + MsgErr(NULL, LPGENT("Warning: Your current IconPack's version differs from the one UserInfoEx is designed for.\nSome icons may not be displayed correctly")); + } + FreeLibrary(hIconDll); + } + } + else + { + MsgErr(NULL, LPGENT("Warning: No IconPack found in one of the following directories: 'customize\\icons', 'icons' or 'plugins'!")); + } + } +} + +/** + * Returns a icon, identified by a name + * + * @param pszIcon - name of the icon + * + * @return: HICON if the icon is loaded, NULL otherwise + **/ +HICON IcoLib_GetIcon(LPCSTR pszIcon, bool big) +{ + return (pszIcon) ? (HICON)CallService(MS_SKIN2_GETICON, (WPARAM)big, (LPARAM) pszIcon) : NULL; +} + +/** + * Returns a icon, identified by a name + * + * @param hIconItem - this is the pointer to an IconItem structure in icolib. + * + * @return: HICON if the icon is loaded, NULL otherwise + **/ +HICON IcoLib_GetIconByHandle(HANDLE hIconItem, bool big) +{ + return (HICON)CallService(MS_SKIN2_GETICONBYHANDLE, (WPARAM)big, (LPARAM) hIconItem); +} + +/** + * Set the icon of each control in the list + * + * @param hDlg - handle to the dialog control, that owns the controls + * @param pCtrl - list to all controls and its icon names + * @param numCtrls - number of elements in the pCtrl list + * + * @return nothing + **/ +VOID IcoLib_SetCtrlIcons(HWND hDlg, const ICONCTRL* pCtrl, BYTE numCtrls) +{ + HICON hIcon; + BYTE i; + HWND hCtrl; + + for (i = 0; i < numCtrls; i++) + { + hIcon = IcoLib_GetIcon(pCtrl[i].pszIcon); + if (pCtrl[i].idCtrl) + { + hCtrl = GetDlgItem(hDlg, pCtrl[i].idCtrl); + switch (pCtrl[i].Message) + { + case STM_SETICON: + case STM_SETIMAGE: + { + ShowWindow(hCtrl, hIcon ? SW_SHOW : SW_HIDE); + } + case BM_SETIMAGE: + { + SendMessage(hCtrl, pCtrl[i].Message, IMAGE_ICON, (LPARAM) hIcon); + } + } + } + else + { + SendMessage(hDlg, pCtrl[i].Message, ICON_BIG, (LPARAM) hIcon); + } + } +} + +/** + * This function manually registers a single icon from the default icon library. + * + * @param szIconID - This is the uniquely identifying string for an icon. + * This string is the setting name in the database and should + * only use ASCII characters. + * @param szDescription - This is the description displayed in the options dialog. + * @param szSection - This is the subsection, where the icon is organized in the options dialog. + * @param szDefaultFile - This is the validated path to the default icon file. + * @param idIcon - This is the ResourceID of the icon in the default file. + * @param Size - This is the desired size of the icon to load. + * 0: default size for small icons (16x16) + * 1: default size for normal icons (32x32) + * @param hDefIcon - This is the default icon to use if the default icon + * file does not exist and no custom icon is set up in the config. + * + * @return This function returns the HANDLE of the icon item. + **/ +static HANDLE IcoLib_RegisterIconHandleEx(LPSTR szIconID, LPSTR szDescription, LPSTR szSection, LPTSTR szDefaultFile, INT idIcon, INT Size, HICON hDefIcon) +{ + HANDLE hIconHandle = NULL; + + if (szIconID && szDescription && szSection) + { + SKINICONDESC sid; + + ZeroMemory(&sid, sizeof(sid)); + sid.cbSize = sizeof(sid); + sid.flags = SIDF_ALL_TCHAR; + sid.pszName = szIconID; + sid.ptszDescription = mir_a2t(szDescription); + sid.ptszSection = mir_a2t(szSection); + + if (sid.ptszDescription && sid.ptszSection) + { + switch (Size) + { + // small and big icons + case -1: + { + sid.cx = sid.cy = 0; + break; + } + // small icons (16x16) + case 0: + { + sid.cx = GetSystemMetrics(SM_CXSMICON); + sid.cy = GetSystemMetrics(SM_CYSMICON); + break; + } + // normal icons (32x32) + case 1: + { + sid.cx = GetSystemMetrics(SM_CXICON); + sid.cy = GetSystemMetrics(SM_CYICON); + break; + } + // custom icon size + default: + { + sid.cx = sid.cy = Size; + break; + } + } + + sid.ptszDefaultFile = szDefaultFile; + if (sid.ptszDefaultFile && sid.ptszDefaultFile[0]) + { + if(idIcon < IDI_FIRST_ICON || idIcon > IDI_LASTICON) { + // Icon from Plugin.dll + sid.iDefaultIndex = idIcon - IDI_PLUG_MAIN; + } + else{ + //UserinfoEx Icon pack + sid.iDefaultIndex = ICONINDEX(idIcon); + } + } + else + { + sid.hDefaultIcon = hDefIcon; + sid.iDefaultIndex = -1; + } + hIconHandle = (HANDLE) CallService(MS_SKIN2_ADDICON, 0, (LPARAM)&sid); + } + mir_freeAndNil(sid.ptszDescription); + mir_freeAndNil(sid.ptszSection); + } + return hIconHandle; +} + +/** + * This function manually registers a single icon from the default icon library. + * + * @param szIconID - This is the uniquely identifying string for an icon. + * This string is the setting name in the database and should + * only use ASCII characters. + * @param szDescription - This is the description displayed in the options dialog. + * @param szSection - This is the subsection, where the icon is organized in the options dialog. + * @param idIcon - This is the ResourceID of the icon in the default file + * @param Size - This is the desired size of the icon to load. + * 0: default size for small icons (16x16) + * 1: default size for normal icons (32x32) + * + * @return This function returns the HANDLE of the icon item. + **/ +HANDLE IcoLib_RegisterIconHandle(LPSTR szIconID, LPSTR szDescription, LPSTR szSection, INT idIcon, INT Size) +{ + return IcoLib_RegisterIconHandleEx(szIconID, szDescription, szSection, IcoLib_GetDefaultIconFileName(), idIcon, Size, ghDefIcon); +} + +/** + * This function manually registers a single icon from the default icon library. + * + * @param szIconID - This is the uniquely identifying string for an icon. + * This string is the setting name in the database and should + * only use ASCII characters. + * @param szDescription - This is the description displayed in the options dialog. + * @param szSection - This is the subsection, where the icon is organized in the options dialog. + * @param idIcon - This is the ResourceID of the icon in the default file + * @param Size - This is the desired size of the icon to load. + * 0: default size for small icons (16x16) + * 1: default size for normal icons (32x32) + * + * @return This function returns the HICON of the icon itself. + **/ +HICON IcoLib_RegisterIcon(LPSTR szIconID, LPSTR szDescription, LPSTR szSection, INT idIcon, INT Size) +{ + return IcoLib_GetIconByHandle(IcoLib_RegisterIconHandle(szIconID, szDescription, szSection, idIcon, Size)); +} + +/** + * Add default icons to the skin library or load customized icons + * + * @param none + * + * @return nothing + **/ +VOID IcoLib_LoadModule() +{ + LPTSTR szDefaultFile; + LPTSTR szPluginFile; + INT_PTR i; + + // search for default icon file + szDefaultFile = IcoLib_GetDefaultIconFileName(); + IcoLib_CheckIconPackVersion(szDefaultFile); + + szPluginFile = _T("Plugins\\")_T(__FILENAME); + + // load default icon if required + ghDefIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_PLUG_DEFAULT), IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0); + + for (i = 0; i < SIZEOF(icoDesc); i++) + { + IcoLib_RegisterIconHandleEx( + icoDesc[i].pszName, icoDesc[i].pszDesc, icoDesc[i].pszSection, + icoDesc[i].bfromIconPack ? szDefaultFile : szPluginFile, icoDesc[i].idResource, icoDesc[i].size, ghDefIcon); + } +} + diff --git a/plugins/SendScreenshotPlus/mir_icolib.h b/plugins/SendScreenshotPlus/mir_icolib.h new file mode 100644 index 0000000000..b80c014a07 --- /dev/null +++ b/plugins/SendScreenshotPlus/mir_icolib.h @@ -0,0 +1,139 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2009 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +aLONG with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ +#ifndef _UINFOEX_ICONS_H_INCLUDED_ +#define _UINFOEX_ICONS_H_INCLUDED_ 1 + +#include "m_icolib.h" + +// sections +#define SECT_COMMON MODNAME +#define SECT_DLG MODNAME"/Dialogs" +#define SECT_BUTTONS MODNAME"/Buttons" +#define SECT_OVERLAY MODNAME"/overlays" +#define SECT_TOOLBAR "ToolBar" // global toolbar section as used by modern clist + +// icons +#define ICO_PLUG_SSWINDOW1 MODNAME"_plug_SSwindow1" +#define ICO_PLUG_SSWINDOW2 MODNAME"_plug_SSwindow2" +#define ICO_PLUG_SSMONITOR MODNAME"_plug_SSmonitor" +#define ICO_PLUG_SSDEFAULT MODNAME"_plug_SSdefault" +#define ICO_PLUG_SSTARGET MODNAME"_plug_SSTarget" +#define ICO_PLUG_SSHELP MODNAME"_plug_SSHelp" +#define ICO_PLUG_SSFOLDERO MODNAME"_plug_SSFolderOpen" +#define ICO_PLUG_ARROWL MODNAME"_plug_SSArrowL" +#define ICO_PLUG_ARROWR MODNAME"_plug_SSArrowR" +#define ICO_PLUG_SSDESKOFF MODNAME"_plug_SSDeskOff" +#define ICO_PLUG_SSDESKON MODNAME"_plug_SSDeskOn" +#define ICO_PLUG_SSDELOFF MODNAME"_plug_SSDelOff" +#define ICO_PLUG_SSDELON MODNAME"_plug_SSDelOn" + +#define ICO_PLUG_OVERLAYOFF MODNAME"_plug_SSOverlayOff" +#define ICO_PLUG_OVERLAYON MODNAME"_plug_SSOverlayOn" + +#define ICO_COMMON_IM MODNAME"_common_im" +#define ICO_COMMON_FEMALE MODNAME"_common_female" +#define ICO_COMMON_MALE MODNAME"_common_male" +#define ICO_COMMON_CLOCK MODNAME"_common_clock" +#define ICO_COMMON_MARITAL MODNAME"_common_marital" +#define ICO_COMMON_PASSWORD MODNAME"_common_password" +#define ICO_COMMON_ADDRESS MODNAME"_common_address" +#define ICO_TREE_DEFAULT MODNAME"_tree_default" +#define ICO_DLG_DETAILS MODNAME"_dlg_details" +#define ICO_DLG_PHONE MODNAME"_dlg_phone" +#define ICO_DLG_EMAIL MODNAME"_dlg_email" +#define ICO_DLG_EXPORT MODNAME"_dlg_export" +#define ICO_DLG_IMPORT MODNAME"_dlg_import" +#define ICO_DLG_SEARCH MODNAME"_dlg_search" +#define ICO_LST_MODULES MODNAME"_lst_modules" +#define ICO_LST_FOLDER MODNAME"_lst_folder" +#define ICO_BTN_UPDATE MODNAME"_btn_update" +#define ICO_BTN_OK MODNAME"_btn_ok" +#define ICO_BTN_CANCEL MODNAME"_btn_cancel" +#define ICO_BTN_APPLY MODNAME"_btn_apply" +#define ICO_BTN_GOTO MODNAME"_btn_goto" +#define ICO_BTN_ADD MODNAME"_btn_add" +#define ICO_BTN_EDIT MODNAME"_btn_edit" +#define ICO_BTN_DELETE MODNAME"_btn_delete" +#define ICO_BTN_IMPORT MODNAME"_btn_import" +#define ICO_BTN_EXPORT MODNAME"_btn_export" +#define ICO_BTN_NOTES MODNAME"_btn_notes" +#define ICO_BTN_ABOUT MODNAME"_btn_about" +#define ICO_BTN_PROFILE MODNAME"_btn_profile" +#define ICO_BTN_DOWNARROW MODNAME"_btn_downarrow" +#define ICO_BTN_PHONE MODNAME"_btn_phone" +#define ICO_BTN_FAX MODNAME"_btn_fax" +#define ICO_BTN_CELLULAR MODNAME"_btn_cellular" +#define ICO_BTN_EMAIL MODNAME"_btn_email" +#define ICO_BTN_SEARCH MODNAME"_btn_search" +#define ICO_BTN_YES MODNAME"_btn_yes" +#define ICO_BTN_NO MODNAME"_btn_no" +#define ICO_BTN_IGNORE MODNAME"_btn_ignore" + +#define ICO_RMD_DTB0 MODNAME"_rmd_dtb0" +#define ICO_RMD_DTB1 MODNAME"_rmd_dtb1" +#define ICO_RMD_DTB2 MODNAME"_rmd_dtb2" +#define ICO_RMD_DTB3 MODNAME"_rmd_dtb3" +#define ICO_RMD_DTB4 MODNAME"_rmd_dtb4" +#define ICO_RMD_DTB5 MODNAME"_rmd_dtb5" +#define ICO_RMD_DTB6 MODNAME"_rmd_dtb6" +#define ICO_RMD_DTB7 MODNAME"_rmd_dtb7" +#define ICO_RMD_DTB8 MODNAME"_rmd_dtb8" +#define ICO_RMD_DTB9 MODNAME"_rmd_dtb9" +#define ICO_RMD_DTBX MODNAME"_rmd_dtbx" + +#define ICO_RMD_DTA0 MODNAME"_rmd_dta0" +#define ICO_RMD_DTA1 MODNAME"_rmd_dta1" +#define ICO_RMD_DTA2 MODNAME"_rmd_dta2" +#define ICO_RMD_DTA3 MODNAME"_rmd_dta3" +#define ICO_RMD_DTA4 MODNAME"_rmd_dta4" +#define ICO_RMD_DTA5 MODNAME"_rmd_dta5" +#define ICO_RMD_DTA6 MODNAME"_rmd_dta6" +#define ICO_RMD_DTA7 MODNAME"_rmd_dta7" +#define ICO_RMD_DTA8 MODNAME"_rmd_dta8" +#define ICO_RMD_DTA9 MODNAME"_rmd_dta9" +#define ICO_RMD_DTAX MODNAME"_rmd_dtax" + +#define SET_ICONS_CHECKFILEVERSION "CheckIconPackVersion" +#define SET_ICONS_BUTTONS "ButtonIcons" + +#define ICONINDEX(id) max((min((id), IDI_LASTICON)) - IDI_FIRST_ICON, 0) + +typedef struct TIconCtrl +{ + LPCSTR pszIcon; + UINT Message; + WORD idCtrl; +} ICONCTRL, *LPICONCTRL; + +LPTSTR IcoLib_GetDefaultIconFileName(); +VOID IcoLib_SetCtrlIcons(HWND hDlg, const ICONCTRL* pCtrl, BYTE numCtrls); + +HANDLE IcoLib_RegisterIconHandle(LPSTR szName, LPSTR szDescription, LPSTR szSection, INT idIcon, INT Size); +HICON IcoLib_RegisterIcon(LPSTR szName, LPSTR szDescription, LPSTR szSection, INT idIcon, INT Size); +HICON IcoLib_GetIcon(LPCSTR pszIcon, bool big = false); +HICON IcoLib_GetIconByHandle(HANDLE hIconItem, bool big = false); + +VOID IcoLib_LoadModule(); + +#endif /* _UINFOEX_ICONS_H_INCLUDED_ */ diff --git a/plugins/SendScreenshotPlus/mir_string.cpp b/plugins/SendScreenshotPlus/mir_string.cpp new file mode 100644 index 0000000000..0ee154b7b9 --- /dev/null +++ b/plugins/SendScreenshotPlus/mir_string.cpp @@ -0,0 +1,179 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +from UserInfoEx Plugin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/mir_string.cpp $ +Revision : $Revision: 13 $ +Last change on : $Date: 2010-04-02 02:54:30 +0400 (РџС‚, 02 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#include "global.h" +#include "mir_string.h" + +char *mir_strncpy(char *pszDest, const char *pszSrc, const size_t cchDest) +{ + if (!pszDest || !pszSrc || !cchDest) + return NULL; + pszDest = strncpy(pszDest, pszSrc, cchDest-1); + pszDest[cchDest-1] = 0; + return pszDest; +} + +wchar_t *mir_wcsncpy(wchar_t *pszDest, const wchar_t *pszSrc, const size_t cchDest) +{ + if (!pszDest || !pszSrc || !cchDest) + return NULL; + pszDest = wcsncpy(pszDest, pszSrc, cchDest-1); + pszDest[cchDest-1] = 0; + return pszDest; +} + +char *mir_strncat(char *pszDest, const char *pszSrc, const size_t cchDest) +{ + if (!pszDest || !pszSrc || !cchDest) + return NULL; + strncat(pszDest, pszSrc, cchDest-1); + pszDest[cchDest-1] = 0; + return pszDest; +} + +wchar_t *mir_wcsncat(wchar_t *pszDest, const wchar_t *pszSrc, const size_t cchDest) +{ + if (!pszDest || !pszSrc || !cchDest) + return NULL; + pszDest = wcsncat(pszDest, pszSrc, cchDest-1); + pszDest[cchDest-1] = 0; + return pszDest; +} + +char *mir_strncat_c(char *pszDest, const char cSrc) { + size_t lenNew = strlen(pszDest) + 2; + if (!pszDest) + pszDest = (char *) mir_alloc(sizeof(char) * lenNew); + else + pszDest = (char *) mir_realloc(pszDest, sizeof(char) * lenNew); + pszDest[lenNew-2] = cSrc; + pszDest[lenNew-1] = 0; + return pszDest; +} + +wchar_t *mir_wcsncat_c(wchar_t *pwszDest, const wchar_t wcSrc) { + size_t lenNew = wcslen(pwszDest) + 2; + if (!pwszDest) + pwszDest = (wchar_t *) mir_alloc(sizeof(wchar_t) * lenNew); + else + pwszDest = (wchar_t *) mir_realloc(pwszDest, sizeof(wchar_t) * lenNew); + pwszDest[lenNew-2] = wcSrc; + pwszDest[lenNew-1] = 0; + return pwszDest; +} + +char *mir_strnerase(char *pszDest, size_t sizeFrom, size_t sizeTo) { + char *pszReturn = NULL; + size_t sizeNew, sizeLen = strlen(pszDest); + if (sizeFrom >= 0 && sizeFrom < sizeLen && sizeTo >= 0 && sizeTo <= sizeLen && sizeFrom < sizeTo) { + sizeNew = sizeLen - (sizeTo - sizeFrom); + size_t sizeCopy = sizeNew - sizeFrom; + pszReturn = (char *) mir_alloc(sizeNew + 1); + memcpy(pszReturn, pszDest, sizeFrom); + memcpy(pszReturn + sizeFrom, pszDest + sizeTo, sizeCopy); + pszReturn[sizeNew] = 0; + } + + pszDest = (char *) mir_realloc(pszDest, sizeNew + 1); + pszDest = mir_strcpy(pszDest, pszReturn); + mir_free(pszReturn); + return pszDest; +} + +size_t mir_vsnwprintf(wchar_t *pszDest, const size_t cchDest, const wchar_t *pszFormat, va_list& argList) +{ + size_t iRet, cchMax; + + if (!pszDest || !pszFormat || !*pszFormat) + return -1; + + cchMax = cchDest - 1; + iRet = _vsnwprintf(pszDest, cchMax, pszFormat, argList); + if (iRet < 0) pszDest[0] = 0; + else if (iRet >= cchMax) { + pszDest[cchMax] = 0; + iRet = cchMax; + } + return iRet; +} + +size_t mir_snwprintf(wchar_t *pszDest, const size_t cchDest, const wchar_t *pszFormat, ...) +{ + size_t iRet; + va_list argList; + + va_start(argList, pszFormat); + iRet = mir_vsnwprintf(pszDest, cchDest, pszFormat, argList); + va_end(argList); + return iRet; +} + +//--------------------------------------------------------------------------- +void mir_stradd(char* &pszDest, const char *pszSrc) +{ + if(!pszSrc) { + return; + } + else if(!pszDest) { + pszDest = mir_strdup(pszSrc); + } + else { + size_t lenDest = strlen(pszDest); + size_t lenSrc = strlen(pszSrc); + size_t lenNew = lenDest + lenSrc + 1; + pszDest = (char *) mir_realloc(pszDest, sizeof(char)* lenNew); + + strcpy(pszDest + lenDest, pszSrc); + pszDest[lenNew-1] = 0; + } +} + +void mir_wcsadd(wchar_t* &pszDest, const wchar_t *pszSrc) +{ + if(!pszSrc) { + return; + } + else if(!pszDest) { + pszDest = mir_wstrdup(pszSrc); + } + else { + size_t lenDest = wcslen(pszDest); + size_t lenSrc = wcslen(pszSrc); + size_t lenNew = lenDest + lenSrc + 1; + pszDest = (wchar_t *) mir_realloc(pszDest, sizeof(wchar_t)*lenNew); + + wcscpy(pszDest + lenDest, pszSrc); + pszDest[lenNew-1] = 0; + } +} + diff --git a/plugins/SendScreenshotPlus/mir_string.h b/plugins/SendScreenshotPlus/mir_string.h new file mode 100644 index 0000000000..11f8276d1b --- /dev/null +++ b/plugins/SendScreenshotPlus/mir_string.h @@ -0,0 +1,129 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* +Copyright 2000-2009 Miranda ICQ/IM project, + +This file is part of Send Screenshot Plus, a Miranda IM plugin. +Copyright (c) 2010 Ing.U.Horn + +Parts of this file based on original sorce code +from UserInfoEx Plugin + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +File name : $HeadURL: http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSSPlus/mir_string.h $ +Revision : $Revision: 13 $ +Last change on : $Date: 2010-04-02 02:54:30 +0400 (РџС‚, 02 апр 2010) $ +Last change by : $Author: ing.u.horn $ + +*/ + +#ifndef _MIR_STRING_H_INCLUDED_ +#define _MIR_STRING_H_INCLUDED_ + +class _A2T +{ + public: + _A2T(const char* s) : + buf(mir_a2t(s)) + {} + + _A2T(const char* s, int cp) : + buf(mir_a2t_cp(s, cp)) + {} + + ~_A2T() + { mir_free(buf); + } + + __inline operator TCHAR*() const + { return buf; + } + + private: TCHAR* buf; +}; + +#define mir_wcsdup mir_wstrdup + +#ifdef _UNICODE + #define mir_tcslen mir_wcslen + #define mir_tcscpy mir_wcscpy + #define mir_tcsncpy mir_wcsncpy + #define mir_tcsncat mir_wcsncat + #define mir_tcsdup mir_wcsdup + #define mir_tcscmp mir_wcscmp + #define mir_tcsncmp mir_wcsncmp + #define mir_tcsicmp mir_wcsicmp + #define mir_tcsnicmp mir_wcsnicmp + #define mir_tcschr mir_wcschr + #define mir_tcsrchr mir_wcsrchr + #define mir_tcsncat_c mir_wcsncat_c + #define mir_tcsadd mir_wcsadd +#else + #define mir_tcslen mir_strlen + #define mir_tcscpy mir_strcpy + #define mir_tcsncpy mir_strncpy + #define mir_tcsncat mir_strncat + #define mir_tcsdup mir_strdup + #define mir_tcscmp mir_strcmp + #define mir_tcsncmp mir_strncmp + #define mir_tcsicmp mir_stricmp + #define mir_tcsnicmp mir_strnicmp + #define mir_tcschr mir_strchr + #define mir_tcsrchr mir_strrchr + #define mir_tcsncat_c mir_strncat_c + #define mir_tcsadd mir_stradd +#endif + + +#define mir_strlen(s) (((s)!=0)?strlen(s):0) +#define mir_strcpy(d,s) (((s)!=0&&(d)!=0)?strcpy(d,s):0) +#define mir_strcmp(s1,s2) ((s1)==0||(s2)==0||strcmp((s1),(s2))) +#define mir_strncmp(s1,s2,n) ((s1)==0||(s2)==0||strncmp((s1),(s2),(n))) +#define mir_stricmp(s1,s2) ((s1)==0||(s2)==0||_stricmp((s1),(s2))) +#define mir_strnicmp(s1,s2,n) ((s1)==0||(s2)==0||_strnicmp((s1),(s2),(n))) +#define mir_strchr(s,c) (((s)!=0)?strchr((s),(c)):0) +#define mir_strrchr(s,c) (((s)!=0)?strrchr((s),(c)):0) + +#define mir_wcslen(s) (((s)!=0)?wcslen(s):0) +#define mir_wcscpy(d,s) (((s)!=0&&(d)!=0)?wcscpy(d,s):0) +#define mir_wcscmp(s1,s2) ((s1)==0||(s2)==0||wcscmp((s1),(s2))) +#define mir_wcsncmp(s1,s2,n) ((s1)==0||(s2)==0||wcsncmp((s1),(s2),(n))) +#define mir_wcsicmp(s1,s2) ((s1)==0||(s2)==0||_wcsicmp((s1),(s2))) +#define mir_wcsnicmp(s1,s2,n) ((s1)==0||(s2)==0||_wcsnicmp((s1),(s2),(n))) +#define mir_wcschr(s,c) (((s)!=0)?wcschr((s),(c)):0) +#define mir_wcsrchr(s,c) (((s)!=0)?wcsrchr((s),(c)):0) + +//#define mir_free(ptr) (if (x) mmi.free(x); *(&(x)) = 0;} +#define mir_freeAndNil(ptr) {if(ptr) mir_free(ptr); ptr = NULL;} + +char * mir_strncpy(char *pszDest, const char *pszSrc, const size_t cchDest); +wchar_t * mir_wcsncpy(wchar_t *pszDest, const wchar_t *pszSrc, const size_t cchDest); + +char * mir_strncat(char *pszDest, const char *pszSrc, const size_t cchDest); +wchar_t * mir_wcsncat(wchar_t *pszDest, const wchar_t *pszSrc, const size_t cchDest); + +char * mir_strncat_c(char *pszDest, const char cSrc); +char * mir_wcsncat_c(char *pszDest, const char cSrc); + +size_t mir_vsnwprintf(wchar_t *pszDest, const size_t cchDest, const wchar_t *pszFormat, va_list& argList); +size_t mir_snwprintf(wchar_t *pszDest, const size_t cchDest, const wchar_t *pszFormat, ...); + +char * mir_strnerase(char *pszDest, size_t sizeFrom, size_t sizeTo); + +void mir_stradd(char * &pszDest, const char *pszSrc); +void mir_wcsadd(wchar_t * &pszDest, const wchar_t *pszSrc); + +#endif /* _MIR_STRING_H_INCLUDED_ */ \ No newline at end of file diff --git a/plugins/SendScreenshotPlus/res/UEditForm_nvr_1.bmp b/plugins/SendScreenshotPlus/res/UEditForm_nvr_1.bmp new file mode 100644 index 0000000000..d25117bb9b Binary files /dev/null and b/plugins/SendScreenshotPlus/res/UEditForm_nvr_1.bmp differ diff --git a/plugins/SendScreenshotPlus/res/UEditForm_nvr_2.bmp b/plugins/SendScreenshotPlus/res/UEditForm_nvr_2.bmp new file mode 100644 index 0000000000..3427b7875f Binary files /dev/null and b/plugins/SendScreenshotPlus/res/UEditForm_nvr_2.bmp differ diff --git a/plugins/SendScreenshotPlus/res/credits.txt b/plugins/SendScreenshotPlus/res/credits.txt new file mode 100644 index 0000000000..122042be3b --- /dev/null +++ b/plugins/SendScreenshotPlus/res/credits.txt @@ -0,0 +1,10 @@ +Special thanks to Michael Kunz aka "Protogenes" +for helping me with 1001 tips and suggestions +to design the program code. +http://www-user.tu-chemnitz.de/~kunmi/?dbx_tree&lang=de + +Thanks to the "UserinfoEx" programmers group +for the nice button class code. +http://code.google.com/p/userinfoex/ + +and special thanks to all beta-testers... diff --git a/plugins/SendScreenshotPlus/res/license.txt b/plugins/SendScreenshotPlus/res/license.txt new file mode 100644 index 0000000000..c5ebcce31f --- /dev/null +++ b/plugins/SendScreenshotPlus/res/license.txt @@ -0,0 +1,15 @@ +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. diff --git a/plugins/SendScreenshotPlus/res/overlay_disabled.ico b/plugins/SendScreenshotPlus/res/overlay_disabled.ico new file mode 100644 index 0000000000..69ba107250 Binary files /dev/null and b/plugins/SendScreenshotPlus/res/overlay_disabled.ico differ diff --git a/plugins/SendScreenshotPlus/res/overlay_enabled.ico b/plugins/SendScreenshotPlus/res/overlay_enabled.ico new file mode 100644 index 0000000000..389f1c4945 Binary files /dev/null and b/plugins/SendScreenshotPlus/res/overlay_enabled.ico differ diff --git a/plugins/SendScreenshotPlus/res/ssArrow_Left.ico b/plugins/SendScreenshotPlus/res/ssArrow_Left.ico new file mode 100644 index 0000000000..917ac2734d Binary files /dev/null and b/plugins/SendScreenshotPlus/res/ssArrow_Left.ico differ diff --git a/plugins/SendScreenshotPlus/res/ssArrow_Right.ico b/plugins/SendScreenshotPlus/res/ssArrow_Right.ico new file mode 100644 index 0000000000..53f65a295f Binary files /dev/null and b/plugins/SendScreenshotPlus/res/ssArrow_Right.ico differ diff --git a/plugins/SendScreenshotPlus/res/ssCamera_1.ico b/plugins/SendScreenshotPlus/res/ssCamera_1.ico new file mode 100644 index 0000000000..908327790e Binary files /dev/null and b/plugins/SendScreenshotPlus/res/ssCamera_1.ico differ diff --git a/plugins/SendScreenshotPlus/res/ssCamera_2.ico b/plugins/SendScreenshotPlus/res/ssCamera_2.ico new file mode 100644 index 0000000000..c480cfebc2 Binary files /dev/null and b/plugins/SendScreenshotPlus/res/ssCamera_2.ico differ diff --git a/plugins/SendScreenshotPlus/res/ssDefault.ico b/plugins/SendScreenshotPlus/res/ssDefault.ico new file mode 100644 index 0000000000..8b3af75f05 Binary files /dev/null and b/plugins/SendScreenshotPlus/res/ssDefault.ico differ diff --git a/plugins/SendScreenshotPlus/res/ssDelOff.ico b/plugins/SendScreenshotPlus/res/ssDelOff.ico new file mode 100644 index 0000000000..12816c8966 Binary files /dev/null and b/plugins/SendScreenshotPlus/res/ssDelOff.ico differ diff --git a/plugins/SendScreenshotPlus/res/ssDelOn.ico b/plugins/SendScreenshotPlus/res/ssDelOn.ico new file mode 100644 index 0000000000..4aeb63226f Binary files /dev/null and b/plugins/SendScreenshotPlus/res/ssDelOn.ico differ diff --git a/plugins/SendScreenshotPlus/res/ssDeskOff.ico b/plugins/SendScreenshotPlus/res/ssDeskOff.ico new file mode 100644 index 0000000000..b3dcb08226 Binary files /dev/null and b/plugins/SendScreenshotPlus/res/ssDeskOff.ico differ diff --git a/plugins/SendScreenshotPlus/res/ssDeskOn.ico b/plugins/SendScreenshotPlus/res/ssDeskOn.ico new file mode 100644 index 0000000000..aa853d0b2f Binary files /dev/null and b/plugins/SendScreenshotPlus/res/ssDeskOn.ico differ diff --git a/plugins/SendScreenshotPlus/res/ssMonitor.ico b/plugins/SendScreenshotPlus/res/ssMonitor.ico new file mode 100644 index 0000000000..93c9150e47 Binary files /dev/null and b/plugins/SendScreenshotPlus/res/ssMonitor.ico differ diff --git a/plugins/SendScreenshotPlus/res/ssOpen.ico b/plugins/SendScreenshotPlus/res/ssOpen.ico new file mode 100644 index 0000000000..735bf034b3 Binary files /dev/null and b/plugins/SendScreenshotPlus/res/ssOpen.ico differ diff --git a/plugins/SendScreenshotPlus/res/ssTarget.ico b/plugins/SendScreenshotPlus/res/ssTarget.ico new file mode 100644 index 0000000000..d69801cd5b Binary files /dev/null and b/plugins/SendScreenshotPlus/res/ssTarget.ico differ diff --git a/plugins/SendScreenshotPlus/res/sshelp.ico b/plugins/SendScreenshotPlus/res/sshelp.ico new file mode 100644 index 0000000000..63161b4c2b Binary files /dev/null and b/plugins/SendScreenshotPlus/res/sshelp.ico differ diff --git a/plugins/SendScreenshotPlus/resource.h b/plugins/SendScreenshotPlus/resource.h new file mode 100644 index 0000000000..6818f5b23f --- /dev/null +++ b/plugins/SendScreenshotPlus/resource.h @@ -0,0 +1,102 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDOK 1 +#define IDA_btnClose 1 +#define IDCANCEL 2 +#define IDB_Bmp1 2 +#define IDABORT 3 +#define IDB_Bmp2 3 +#define IDRETRY 4 +#define IDIGNORE 5 +#define IDYES 6 +#define IDNO 7 +#define IDCLOSE 8 +#define IDHELP 9 +#define IDTRYAGAIN 10 +#define IDCONTINUE 11 +#define IDALL 21 +#define IDD_UMainForm 101 +#define MAIN 102 +#define IDR_LICENSE 103 +#define IDD_UMain_CaptureWindow 107 +#define IDD_CAPTURE 111 +#define IDR_CREDIT 116 +#define IDI_PLUG_MAIN 190 +#define IDI_PLUG_DEFAULT 191 +#define IDI_PLUG_ICON1 192 +#define IDI_PLUG_ICON2 193 +#define IDI_PLUG_ICON3 194 +#define IDI_PLUG_HELP 195 +#define IDI_PLUG_FOLDERO 196 +#define IDI_PLUG_ARROWL 197 +#define IDI_PLUG_ARROWR 198 +#define IDI_PLUG_OVERLAYON 199 +#define IDI_PLUG_OVERLAYOFF 200 +#define IDD_UAboutForm 201 +#define IDI_PLUG_DESKOFF 201 +#define IDI_PLUG_DESKON 202 +#define IDI_PLUG_DELOFF 203 +#define IDI_PLUG_DELON 204 +#define IDD_UEditForm 301 +#define IDC_CAPTURETAB 1005 +#define IDD_MSGBOX 1008 +#define IDC_CREDIT 1009 +#define IDD_MSGBOXDUMMI 1024 +#define IDD_UMain_CaptureDesktop 1025 +#define STATIC_WHITERECT 1100 +#define STATIC_LINE2 1103 +#define ICO_DLGLOGO 1105 +#define ICO_MSGDLG 1106 +#define IDC_BUILDTIME 1108 +#define TXT_NAME 1114 +#define TXT_MESSAGE 1126 +#define ID_edtCaption 1201 +#define ID_edtSize 1202 +#define ID_edtQuality 1203 +#define ID_upQuality 1204 +#define ID_edtTimed 1205 +#define ID_upTimed 1206 +#define IDC_WHITERECT 1221 +#define ID_cboxFormat 1301 +#define ID_cboxSendBy 1302 +#define ID_lblFmtInfo 1501 +#define IDE_Image 1501 +#define ID_lblSendBy 1502 +#define IDE_imgSelection 1502 +#define ID_bvlTarget 1503 +#define IDC_COPYRIGHT 1503 +#define ID_lblDropInfo 1504 +#define ID_imgTarget 1505 +#define ID_edtCaptionLabel 1506 +#define ID_edtSizeLabel 1507 +#define ID_edtQualityLabel 1508 +#define ID_edtTimedLabel 1509 +#define IDNONE 1565 +#define IDA_CONTRIBLINK 1586 +#define IDC_LICENSE 1589 +#define ID_gboxAreaToTake 1602 +#define ID_gboxOptions 1603 +#define ID_chkEditor 1701 +#define ID_chkClientArea 1704 +#define ID_chkTimed 1708 +#define ID_chkOpenAgain 1710 +#define IDC_HEADERBAR 1734 +#define ID_btnAbout 2001 +#define ID_btnExplore 2002 +#define ID_btnDesc 2003 +#define ID_btnDeleteAfterSend 2004 +#define ID_btnCapture 2005 +#define IDE_StatusBar 2501 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 123 +#define _APS_NEXT_COMMAND_VALUE 40002 +#define _APS_NEXT_CONTROL_VALUE 1011 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/SendScreenshotPlus/resource.rc b/plugins/SendScreenshotPlus/resource.rc new file mode 100644 index 0000000000..8e24cc0204 --- /dev/null +++ b/plugins/SendScreenshotPlus/resource.rc @@ -0,0 +1,274 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Deutsch (Deutschland) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_MSGBOX DIALOGEX 0, 0, 219, 97 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialog" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "",STATIC_WHITERECT,0,0,219,72 + LTEXT "",TXT_NAME,11,3,173,20,SS_ENDELLIPSIS | NOT WS_VISIBLE,WS_EX_TRANSPARENT + ICON "",ICO_DLGLOGO,191,3,21,20,NOT WS_VISIBLE + ICON "",ICO_MSGDLG,7,29,21,20 + LTEXT "",TXT_MESSAGE,34,37,180,35 + CONTROL "",STATIC_LINE2,"Static",SS_ETCHEDHORZ,0,71,219,1 + DEFPUSHBUTTON "OK",IDOK,6,78,50,14 + PUSHBUTTON "All",IDALL,58,78,50,14,NOT WS_VISIBLE + PUSHBUTTON "None",IDNONE,110,78,50,14,NOT WS_VISIBLE + PUSHBUTTON "Cancel",IDCANCEL,162,78,50,14,NOT WS_VISIBLE +END + +IDD_MSGBOXDUMMI DIALOGEX 65526, 65526, 1, 1 +STYLE DS_ABSALIGN | DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_SYSMENU +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN +END + +IDD_UMainForm DIALOGEX 0, 0, 231, 164 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +CAPTION "Send screenshot" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "Send screenshot to\n",IDC_HEADERBAR, + "MHeaderbarCtrl",0x0,0,0,231,25 + CONTROL "",IDC_CAPTURETAB,"SysTabControl32",TCS_RAGGEDRIGHT | WS_TABSTOP,8,36,218,68,WS_EX_TRANSPARENT + CONTROL "Ti&med capture",ID_chkTimed,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,106,85,10 + RTEXT "Time (secs) :",ID_edtTimedLabel,9,119,49,8 + EDITTEXT ID_edtTimed,62,117,31,13,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",ID_upTimed,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,81,117,11,13 + LTEXT "&Format :",ID_lblFmtInfo,100,107,41,8 + COMBOBOX ID_cboxFormat,100,117,41,84,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_HASSTRINGS | CBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + LTEXT "Send B&y :",ID_lblSendBy,148,107,75,8 + COMBOBOX ID_cboxSendBy,148,117,75,84,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_HASSTRINGS | CBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + CONTROL "?",ID_btnAbout,"UInfoButtonClass",WS_TABSTOP | 0x4000,3,145,16,14,WS_EX_NOACTIVATE | 0x10000000L + CONTROL "E&xplore",ID_btnExplore,"UInfoButtonClass",WS_TABSTOP | 0x4000,21,145,16,14,WS_EX_NOACTIVATE | 0x10000000L + CONTROL "&Fill description textbox.",ID_btnDesc,"UInfoButtonClass",WS_TABSTOP | 0x6000,39,145,16,14,WS_EX_NOACTIVATE | 0x10000000L + CONTROL "Delete &after send",ID_btnDeleteAfterSend, + "UInfoButtonClass",WS_TABSTOP | 0x6000,57,145,16,14,WS_EX_NOACTIVATE | 0x10000000L + CONTROL "Open again",ID_chkOpenAgain,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,147,57,9 + CONTROL "&Capture",ID_btnCapture,"UInfoButtonClass",WS_GROUP | WS_TABSTOP | 0x1000,169,145,54,14,WS_EX_NOACTIVATE | 0x10000000L + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,139,231,1 +END + +IDD_UAboutForm DIALOGEX 0, 0, 214, 185 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOPMOST +CAPTION "About" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "%s\nv%s",IDC_HEADERBAR,"MHeaderbarCtrl",0x0,0,0,214,25 + CONTROL "Credits >",IDA_CONTRIBLINK,"UInfoButtonClass",WS_GROUP | WS_TABSTOP,5,166,61,14,WS_EX_NOACTIVATE | 0x10000000L + PUSHBUTTON "&Close",IDA_btnClose,149,166,60,14 + LTEXT "",IDC_WHITERECT,0,25,213,135,NOT WS_GROUP + EDITTEXT IDC_LICENSE,5,37,204,95,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | WS_VSCROLL + EDITTEXT IDC_CREDIT,5,37,204,95,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | WS_VSCROLL + EDITTEXT IDC_BUILDTIME,5,147,146,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER | NOT WS_TABSTOP + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,160,213,1 +END + +IDD_UEditForm DIALOGEX 217, 152, 329, 285 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT +CAPTION "Edit" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + CONTROL "",IDE_Image,"Static",SS_BITMAP | WS_GROUP,0,0,265,194 + CONTROL "",IDE_imgSelection,"Static",SS_BITMAP | WS_GROUP,195,133,100,76 + CONTROL "",IDE_StatusBar,"msctls_statusbar32",WS_CLIPSIBLINGS | 0x100,0,272,323,12 +END + +IDD_UMain_CaptureWindow DIALOGEX 0, 0, 214, 48 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "",IDC_WHITERECT,0,0,214,48 + CONTROL "C&lient Area",ID_chkClientArea,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,100,30,62,8,WS_EX_RIGHT + LTEXT "Caption :",ID_edtCaptionLabel,4,1,158,8 + EDITTEXT ID_edtCaption,4,12,158,13,ES_AUTOHSCROLL | ES_READONLY + RTEXT "Size (HxW) :",ID_edtSizeLabel,0,30,50,8 + EDITTEXT ID_edtSize,52,28,43,13,ES_CENTER | ES_AUTOHSCROLL | ES_READONLY + CTEXT "Target Tool",ID_lblDropInfo,162,1,51,8 + LTEXT "",ID_bvlTarget,174,12,29,29,SS_NOTIFY | SS_SUNKEN + ICON IDI_PLUG_ICON2,ID_imgTarget,178,16,20,20,SS_NOTIFY | SS_CENTERIMAGE | WS_GROUP +END + +IDD_UMain_CaptureDesktop DIALOGEX 0, 0, 214, 48 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "",IDC_WHITERECT,0,0,214,48 + LTEXT "Caption :",ID_edtCaptionLabel,4,1,158,8 + RTEXT "Size (HxW) :",ID_edtSizeLabel,0,30,50,8 + EDITTEXT ID_edtSize,52,28,43,13,ES_AUTOHSCROLL | ES_READONLY + LTEXT "",ID_bvlTarget,174,12,29,29,SS_NOTIFY | SS_SUNKEN + ICON "",ID_imgTarget,178,16,20,20,SS_NOTIFY | SS_CENTERIMAGE | WS_GROUP + COMBOBOX ID_edtCaption,4,12,158,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_TABSTOP +END + +IDD_CAPTURE DIALOGEX 0, 0, 316, 180 +STYLE DS_SYSMODAL | DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Dialog" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_PLUG_MAIN ICON "res\\ssCamera_1.ico" +IDI_PLUG_ICON1 ICON "res\\ssCamera_2.ico" +IDI_PLUG_DEFAULT ICON "res\\ssDefault.ico" +IDI_PLUG_ICON2 ICON "res\\ssTarget.ico" +IDI_PLUG_ICON3 ICON "res\\ssMonitor.ico" +IDI_PLUG_HELP ICON "res\\sshelp.ico" +IDI_PLUG_FOLDERO ICON "res\\ssOpen.ico" +IDI_PLUG_ARROWL ICON "res\\ssArrow_Left.ico" +IDI_PLUG_ARROWR ICON "res\\ssArrow_Right.ico" +IDI_PLUG_OVERLAYOFF ICON "res\\overlay_disabled.ico" +IDI_PLUG_OVERLAYON ICON "res\\overlay_enabled.ico" +IDI_PLUG_DESKOFF ICON "res\\ssDeskOff.ico" +IDI_PLUG_DESKON ICON "res\\ssDeskOn.ico" +IDI_PLUG_DELOFF ICON "res\\ssDelOff.ico" +IDI_PLUG_DELON ICON "res\\ssDelOn.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_Bmp1 BITMAP "res\\UEditForm_nvr_1.bmp" +IDB_Bmp2 BITMAP "res\\UEditForm_nvr_2.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// TEXT +// + +IDR_CREDIT TEXT "./res/credits.txt" +IDR_LICENSE TEXT "./res/license.txt" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_MSGBOX, DIALOG + BEGIN + HORZGUIDE, 23 + HORZGUIDE, 29 + HORZGUIDE, 72 + END + + IDD_UMainForm, DIALOG + BEGIN + HORZGUIDE, 159 + END + + IDD_UAboutForm, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 209 + BOTTOMMARGIN, 180 + END + + IDD_UEditForm, DIALOG + BEGIN + RIGHTMARGIN, 230 + END + + IDD_UMain_CaptureWindow, DIALOG + BEGIN + RIGHTMARGIN, 213 + VERTGUIDE, 162 + END + + IDD_UMain_CaptureDesktop, DIALOG + BEGIN + VERTGUIDE, 162 + END + + IDD_CAPTURE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 309 + TOPMARGIN, 7 + BOTTOMMARGIN, 173 + END +END +#endif // APSTUDIO_INVOKED + +#endif // Deutsch (Deutschland) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/SendScreenshotPlus/resource_6.rc b/plugins/SendScreenshotPlus/resource_6.rc new file mode 100644 index 0000000000..7989eaa16b --- /dev/null +++ b/plugins/SendScreenshotPlus/resource_6.rc @@ -0,0 +1,2 @@ +#include "resource.rc" +#include "version.rc" diff --git a/plugins/SendScreenshotPlus/sdk/DevKey.h b/plugins/SendScreenshotPlus/sdk/DevKey.h new file mode 100644 index 0000000000..2999f74466 --- /dev/null +++ b/plugins/SendScreenshotPlus/sdk/DevKey.h @@ -0,0 +1,3 @@ +#ifndef DEVKEY_IMAGESHACK +#define DEVKEY_IMAGESHACK "IA5ZRTV6fb6256ccbc3c38650bdce6e6dcfc9e55" /*Test DevKey*/ +#endif diff --git a/plugins/SendScreenshotPlus/sdk/icons.h b/plugins/SendScreenshotPlus/sdk/icons.h new file mode 100644 index 0000000000..46871836bd --- /dev/null +++ b/plugins/SendScreenshotPlus/sdk/icons.h @@ -0,0 +1,112 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by uinfoex_icons.rc +// +#define IDI_FIRST_ICON 101 + +// dialog inforbar +#define IDI_DLG_DETAILS 101 +#define IDI_DLG_PHONE 102 +#define IDI_DLG_EMAIL 103 + +// dialog infobar & buttons +#define IDI_ANNIVERSARY 104 +#define IDI_EXPORT 105 +#define IDI_IMPORT 106 +#define IDI_SEARCH 107 + +// common icons of details dialog pages +#define IDI_MIRANDA 108 +#define IDI_PASSWORD 109 +#define IDI_FEMALE 110 +#define IDI_MALE 111 +#define IDI_CLOCK 112 +#define IDI_MARITAL 113 + +// commonly used buttons +#define IDI_BTN_UPDATE 114 +#define IDI_BTN_OK 115 +#define IDI_BTN_CLOSE 116 +#define IDI_BTN_APPLY 117 +#define IDI_BTN_GOTO 118 +#define IDI_BTN_PHONE 119 +#define IDI_BTN_FAX 120 +#define IDI_BTN_CELLULAR 121 +#define IDI_BTN_CUSTOMPHONE 122 +#define IDI_BTN_EMAIL 123 +#define IDI_BTN_DOWNARROW 124 +#define IDI_BTN_ADD 125 +#define IDI_BTN_EDIT 126 +#define IDI_BTN_DELETE 127 +#define IDI_BTN_EXIMPORT 128 +#define IDI_BTN_BIRTHDAY_BACKUP 129 + +// details treeview icons +#define IDI_TREE_GENERAL 130 +#define IDI_TREE_ADVANCED 131 +#define IDI_TREE_COMPANY 132 +#define IDI_TREE_CONTACT 133 +#define IDI_TREE_ABOUT 134 +#define IDI_TREE_PHOTO 135 +#define IDI_TREE_ADDRESS 136 +#define IDI_TREE_NOTES 137 +#define IDI_TREE_PROFILE 138 + +// export: choose modules +#define IDI_LST_MODULES 139 +#define IDI_LST_FOLDER 140 + +// zodiac icons +#define IDI_ZOD_AQUARIUS 141 +#define IDI_ZOD_ARIES 142 +#define IDI_ZOD_CANCER 143 +#define IDI_ZOD_CAPRICORN 144 +#define IDI_ZOD_GEMINI 145 +#define IDI_ZOD_LEO 146 +#define IDI_ZOD_LIBRA 147 +#define IDI_ZOD_PISCES 148 +#define IDI_ZOD_SAGITTARIUS 149 +#define IDI_ZOD_SCORPIO 150 +#define IDI_ZOD_TAURUS 151 +#define IDI_ZOD_VIRGO 152 + +// reminder +#define IDI_BIRTHDAY 153 +#define IDI_RMD_DTB0 154 +#define IDI_RMD_DTB1 155 +#define IDI_RMD_DTB2 156 +#define IDI_RMD_DTB3 157 +#define IDI_RMD_DTB4 158 +#define IDI_RMD_DTB5 159 +#define IDI_RMD_DTB6 160 +#define IDI_RMD_DTB7 161 +#define IDI_RMD_DTB8 162 +#define IDI_RMD_DTB9 163 +#define IDI_RMD_DTBX 164 +#define IDI_RMD_DTA0 165 +#define IDI_RMD_DTA1 166 +#define IDI_RMD_DTA2 167 +#define IDI_RMD_DTA3 168 +#define IDI_RMD_DTA4 169 +#define IDI_RMD_DTA5 170 +#define IDI_RMD_DTA6 171 +#define IDI_RMD_DTA7 172 +#define IDI_RMD_DTA8 173 +#define IDI_RMD_DTA9 174 +#define IDI_RMD_DTAX 175 + +#define IDI_LASTICON 175 + +// version text +#define IDS_ICOPACKVERSION 1001 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 1002 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/SendScreenshotPlus/version.h b/plugins/SendScreenshotPlus/version.h new file mode 100644 index 0000000000..b4fe6f1849 --- /dev/null +++ b/plugins/SendScreenshotPlus/version.h @@ -0,0 +1,45 @@ +#define PLUGNAME "Send Screenshot+" +#define __MAJOR_VERSION 0 +#define __MINOR_VERSION 8 +#define __RELEASE_NUM 0 +#define __BUILD_NUM 0 + +#define __STRINGIFY(x) #x +#define __STRINGIFY2(x) __STRINGIFY(x) +#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM +#define __FILEVERSION_STRING_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM + +#define __VERSION_STRING __STRINGIFY2(__FILEVERSION_STRING) +#define __VERSION_STRING_DOT __STRINGIFY2(__FILEVERSION_STRING_DOTS) + +#define __FILENAME "SendSS.dll" +#define __DESC "Take a screenshot and send it to a contact." +#define __AUTHOR "Merlin" +#define __AUTHOREMAIL "ing.u.horn@googlemail.com" +#define __COPYRIGHT "© 2010 Merlin, © 2004-2006 Sergio Vieira Rolanski" +#define __AUTHORWEB "http://code.google.com/p/merlins-miranda" + +#ifndef MIID_PLUGIN // {ED39AF7C-BECD-404e-9499-4D04F711B9CB} +#define MIID_PLUGIN { 0xed39af7c, 0xbecd, 0x404e, { 0x94, 0x99, 0x4d, 0x04, 0xf7, 0x11, 0xb9, 0xcb } } +#endif + +#ifdef _UNICODE +#define __PLUGIN_NAME "Send Screenshot+ (Unicode)" +#define __FLVersionURL "http://addons.miranda-im.org/details.php?action=viewfile&id=1428" +#define __FLVersionPrefix "SendSS (Unicode) " +#define __FLUpdateURL "http://addons.miranda-im.org/feed.php?dlfile=1428" +#define __BetaUpdateURL "http://merlins-miranda.googlecode.com/files/SendSSW.zip" +#else +#define __PLUGIN_NAME "Send Screenshot+ (2in1)" +#define __FLVersionURL "http://addons.miranda-im.org/details.php?action=viewfile&id=1428" +#define __FLVersionPrefix "SendSS (2in1) " +#define __FLUpdateURL "http://addons.miranda-im.org/feed.php?dlfile=1428" +#define __BetaUpdateURL "http://merlins-miranda.googlecode.com/files/SendSS.zip" +#endif + +#define __BetaVersionURL "http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSS/changelog.txt" +#define __BetaVersionPrefix "SendSS Plus: " +#define __BetaChangelogURL "http://merlins-miranda.googlecode.com/svn/trunk/miranda/plugins/SendSS/changelog.txt" + +#define __USER_AGENT_STRING __PLUGIN_NAME##" v"##__VERSION_STRING_DOT + diff --git a/plugins/SendScreenshotPlus/version.rc b/plugins/SendScreenshotPlus/version.rc new file mode 100644 index 0000000000..16f5845ed6 --- /dev/null +++ b/plugins/SendScreenshotPlus/version.rc @@ -0,0 +1,38 @@ +#include // include for version info constants +#include "version.h" + +// +// TO CHANGE VERSION INFORMATION, EDIT PROJECT OPTIONS... +// +VS_VERSION_INFO VERSIONINFO + FILEVERSION __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM + PRODUCTVERSION __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", "" + VALUE "FileVersion", __VERSION_STRING_DOT + VALUE "FileDescription", __DESC + VALUE "InternalName", __PLUGIN_NAME + VALUE "LegalCopyright", __COPYRIGHT + VALUE "OriginalFilename", __FILENAME + VALUE "ProductName", __PLUGIN_NAME + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END + diff --git a/plugins/ShlExt/clean.bat b/plugins/ShlExt/clean.bat new file mode 100644 index 0000000000..575eed729c --- /dev/null +++ b/plugins/ShlExt/clean.bat @@ -0,0 +1 @@ +del *.o *.ppu *.dll *.a fpc-res.res *.or \ No newline at end of file diff --git a/plugins/ShlExt/docs/HowToBuild.txt b/plugins/ShlExt/docs/HowToBuild.txt new file mode 100644 index 0000000000..53b6738616 --- /dev/null +++ b/plugins/ShlExt/docs/HowToBuild.txt @@ -0,0 +1,22 @@ +shlext 2.0.0.9 + +Info +======================= + +This source code is based on shlext 1.0.6.6 with minor changes so that it works +with FreePascal 2.2.2. + +The included headers (inc dir) are from Miranda 0.3.3.1 SDK and so if you want newer APIs +then get the API headers from the latest SVN tree. + +Note: I have included v0.8.xx API changes for GUIDs within a new file (m_v8.inc) + + +How to build +======================= + +Make sure you have installed the FreePascal compiler ( http://freepascal.org ) +the latest version is 2.2.2 at the time of writing. + +Run "make.bat" in this directory, this contains all the command line switches +for the newer version should produce shlext.dll diff --git a/plugins/ShlExt/docs/shlext release notes.txt b/plugins/ShlExt/docs/shlext release notes.txt new file mode 100644 index 0000000000..0e58edf9ff --- /dev/null +++ b/plugins/ShlExt/docs/shlext release notes.txt @@ -0,0 +1,344 @@ +shlext 2.0.1.2 + +Contents: + + Introduction ``What is shlext?`` + Why so long? + What you need + New features + Features + Quirks + Important changes + But Miranda has drag'n'drop! + Installation + Upgrading/Removing + Translation + License + Contact/Bug reporting + Credits + + + + ---Introduction ``What is shlext?`` + + shlext is a Miranda and Explorer shell plugin, it allows you to use your + contact list under any file/directory from Windows. + + This means that you can right click on a file/folder, see "Miranda" and then + see your entire contact list! this is a feature that ICQ has built in. + + shlext is better of course. + + ---Why so long? + + A few people contacted me aeons ago about implementing a better file scanner + so that they could recreate directories whilst sending, etc, I said I would do + this as soon as I had time, that was several months ago. + + I had made several changes/bugfixes when I had time, because I'm a Miranda + dev too, I don't usually have lots of time for this plugin, however lately I needed + shlext to run again, since I was sending lots of docs/logs around with Miranda. + + So I fixed several things and improved lots of other stuff so that other users + could use shlext again (the XP bug was really annoying as soon as I got XP myself ;) + + + ---What you need + + (2008) You will need 0.7.xx or 0.8.x -- older versions will not work. + + shlext should work on all Window Explorer versions that support it, + certain features will not work on older Explorers, i.e. icons, but you will + still be able to use the main function of shlext, selection 'n' transfer. + + ---New Features (2.0.1.2) + + * shlext is now compiled with Free Pascal 2.2.4 + + * shlext now works with Windows Vista: + + 1. shlext cannot automatically register itself with Windows Explorer due to permissions issues in Vista, + therefore you will be UAC prompted if shlext detects you are running Vista and that shlext isn't registered + with Explorer. + + This is almost automatic, and you just have to press "OK". + + 2. The entire menu drawing was overhauled and now looks much better, new APIs are used so that Vista draws the menus + (with theme) but the status icons are still present. + + * added UAC button for "Remove" from the options dialog. + + * Removed GetMenuItemInfo() debug message box. + + * Note: Miranda is a 32bit application, 64bit editions of Windows require a 64bit extension DLL, this is not possible at present. + + ---New features (2.0.0.9+) + + * shlext is now compiled with Free Pascal 2.2.2 which is a newer compiler with better + optimisations so shlext should be faster. (2002 v.s. 2008) + + * shlext now works with Miranda 0.8.x UUID typing system and 0.8.xx plugin loading APIs, + 0.7.xx still works too however. + + * shlext now keeps track of recently used contacts and builds a "MRU" menu for quick + access within the menu system. This cannot be disabled, if you hate this feature, + please stick pins into a voodoo doll named "Christian", that is all. + + * The menu strings "Recently" and "Clear entries" are translate()able but MRU is not. + + ---New features (1.0.6.6+) + + * shlext will now use all your icons per protocol, **not** just the first iconset + it finds, it will also use everything properly (because it doesn't do the icon + extraction, it just asks Miranda [don't ask why it didn't do this before :P]) + + * shlext will now use a Translate()'d version of "Miranda" so that each menu + shown for a profile can be given a custom user string + + * reimplemented file/folder selection, finally! a work-as-expected version, it will + scan and add all files and folders you give it, producing a file list in the background + (scanning your drive) and then send the list to Miranda to send to your selected contact. + + * Added option for disabling status icons in menus, which means that you can use shlext + with shell variants/file managers that invoke the shlext interface, such as FAR, but + don't need/use the icons. + + * Added option about hiding offline users from the context menu, if this option is off + it will fall back onto syncing with your contact list's "hide offline users" + + * Added proper thread safety because Miranda 0.3 now has it. + + * Completely reimplemented group parsing, which means that all the old group bugs + can be expected to be gone, note that shlext will now even create menus for + subgroups of the same name, e.g. "Miranda\Miranda". + + * shlext will now not show a menu for a running Miranda fails the following checks: + + * not running shlext (duh) + * no non-offline contacts (or you have the setting 'hide offline users') + * and so on + + * shlext will now also completely ignore contacts on protocols who have no file transfer support + + + ---Features + + shlext can: + + * allow you to refer to your entire contact list from a file/folder context + menu, this includes multiple profiles! if you have Miranda running + different profiles, you'll see all your profiles as menu items as long + as you're running shlext as a Miranda plugin in that profile. + + * Group ability, see a faithful menu rendition of your group hierarchy. + This means you can go something like File->My Profile->Work->Friends->Dude... + + This feature can also be turned off, or enabled in sync with your contact + list option to "Disable groups", this is a per profile setting, i.e. setting + disable groups on one profile won't affect other profiles running shlext. + + * Multi protocol aware, shlext can send to anyone on your contact list + not just ICQ! + + * Each contact will be shown next to their status icon, as selected in your + profile(s) which means that you'll easily feel at home with the icons, + because they will be used as how they are set in each profile. + + * lots of files, shlext will now, if given a directory/folder go into that + folder and scan for files and sub directories/folders til it's added + everything. + + This means if you send c:\foobar, it will search c:\foobar\*.* for more + files to add, it will also add c:\foobar as a directory space to send. + Which means that if the other side hasn't got a 'foobar' directory, it will + be created! (Note: recreating directory trees depends on the protocol being used to send) + + + --Quirks + + * shlext displays all your users by default, if your contact list is set to + NOT show offline users, then shlext will not show them. + + * shlext doesn't use all your group settings, it will not ad here to + "hide offline users in here", however if a group has got offline users + it won't show them (per setting option!) + + + + ---Important changes + + Older versions of shlext did not go into folders more than one level, i.e. + if you added c:\foobar it would scan for c:\foobar\*.* and add all the files + but not go into each directory\folder deeper than that! + + shlext also now does background selection scanning, which means when you select + a group of files/folders/directories, it will let you get on with chating + until it's made a file list which you can send to the person you've selected. + + shlext will NOT send any file/folder/directory that is marked "hidden" + + Also, sometimes you will see "n files, 1 directory" when you say select something + e.g. c:\foobar, this is because shlext now also includes the top level directory so that the + remote side will know to create it, as well as sub directories. + + + + ---But Miranda has drag'n'drop! + + Yeah, that's okay when you can reach Miranda, but I have multiple profiles and + the "hide after NN seconds" option enabled, also I have groups! + + Miranda doesn't auto expand a group when someone is online unless you do that + yourself, which means drag 'n' drop has failed. Also, when you've selected a + large amount of files, Miranda will *freeze* completely whilst + it 1) scans all those files, 2) builds a copy of the given send list + + Whilst shlext only freezes Miranda for the latter, and that is seldom a "complete freeze". + + And of course, shlext uses Miranda 0.3's advanced threading services, which means + if you've asked shlext to build a massive send list, you can still exit Miranda safely + which you can't with drag 'n' drop! + + + + ---Installation + + If you've never installed shlext before, all you have to do is install it like + any other Miranda plugin, i.e. copy it to your plugins directory. + + That's it! you should goto Miranda->Options->Plugins->Shell Context Menus + to see if you'd like to set any of the options, however shlext works straight + out of the box and you don't really need to set anything up after that. + + If you want to use shlext with multiple profiles, you don't have to do any + special setting up either, just make sure that shlext is running with each Miranda + you want shlext to show a menu contact list for. + + Make sure ALL copies of shlext.dll are the same, i.e. 1.0.6.6, if they're not + then shlext will fail (this doesn't mean 'crash'). + + + ---Upgrading/Removing + + Upgrading shlext has always been a pain for users (and me!) this is because + shlext.dll runs in Windows and in Miranda (at the same time). + + So when you've shutdown Miranda, shlext.dll maybe kept in memory by Windows + to make things worse, clicking any file/folder will result in shlext.dll being + reloaded, so if you do shlext.dll->Delete, Windows will ask shlext.dll if + it wants to show any menus, nevermind the fact delete was selected! + + This happens also if you just press 'delete' whilst shlext.dll is selected. + + However! All is not lost, this is what you do: + + * goto M->Options->Plugins and disable shlext.dll as a Miranda plugin + * goto M->Options->Plugins->Shell context menus and click 'Remove'. + * Shutdown Miranda IM + + Advanced users only: ---------------------------------------------------- + + * Do all the above and then open a console window (Command prompt, etc) + * Make sure all applications have been shutdown + * Goto the directory where Miranda is, e.g. c:\, cd Miranda + * Goto Start->Shutdown, let the dialog come up and hold CTRL+ALT+SHIFT + and press cancel. + + This will shutdown Explorer but not Windows, you can now do: del shlext.dll + + * now run Explorer.exe usually in C:\Windows, shlext.dll will be removed. + + ---------------------------------------------------------------------------- + + The remove button will ask Windows not to load it anymore, by removing + all shlext registry entries, the button will also remove any settings from your + profile settings database that it may of made. + + You should now be able to delete shlext.dll! however if you still are unable + to, you may need to log out (if you're using XP/2000/NT) if you're using + 9x then you may have to restart Windows (pain I know, sorry!) + + You should now be free of old shlext copies and you can refer to "Installation" + above. + + If you were using shlext.dll with multiple profiles, the remove shlext + from each profile as stated above and then copy the newer shlext.dll to + your plugins folder. + + ---Translation + + I haven't been nice about translation strings in the past, but you + can pretty much translate everything shlext uses a string, even + "Miranda" which is shown in the menu. + + Note that some strings can't be translated, this is because some parts + of the plugin run within Explorer and that doesn't have access to Miranda's + langpacks, the "Miranda" string that appears in menus is a special exception + + ; + ; Translate()'able strings for shlext/2.0.0.9 + ; + + ;"Miranda" limited to 63characters! (exceed and it's chopped) + ;[Miranda] + ;[Problem, registration missing/deleted.] + ;[Successfully created shell registration.] + ;[Not Approved] + ;[Approved] + ;[Are you sure? this will remove all the settings stored in your database and all registry entries created for shlext to work with Explorer] + ;[Disable/Remove shlext] + ;[Shell context menus] + + ; new in 2.0.0.9, both these strings cannot be longer than 63 chracters + ;[Clear entries] + ;[Recently] + + ;IDD_SHLOPTS + ;[Menus] + ;[Display contacts in their assigned groups (if any)] + ;[Only if/when the contact list is using them] + ;[Display hidden, ignored or temporary contacts] + ;[Shell Status] + ;[Do not display the profile name in use] + ;[Contact Status] + ;[Show contacts that you have set privacy rules for] + ;[Remove] + ;[Do not show status icons in menus] + ;[Do not show contacts that are offline, even if my contact list does] + + + + + ---License + + Like Miranda, shlext is released under the GPL, you may find the full + FreePascal source-code on the CVS in plugins module 'shlext' + + You will need at least FreePascal/2.2.2, GNU make (if you want to use the makefile) + + Follow the CVS links from http://sf.net/projects/miranda-icq/ + + Note: All the tools used to build shlext are also under the GPL! + + + ---Contact/Bug reporting + + In the past shlext hasn't been as stable as it could be, but this was mainly + due to the problems of 0.2.0.0 and early 0.3.0.0 Miranda builds, I've taken + care to make sure things are stable as can be. + + If you have any problems/crashes, please contact me at: egodust at users.sf.net. + + Please include the following information: Windows version, service packs installed, + build version of Explorer, Miranda version, shlext version, a list of plugins + that you think maybe involved in crashes, steps to reproduce errors and so on. + + Note that shlext has been blamed for several bugs that were not shlext's fault, + for example the file xfer cancel bug was in ICQ and Miranda but not shlext ;) + + + ---Credits + + Tig-crash\d - Thanks for beta testing every version before this one ;) + Erik?, DD Of Borg - Thanks for beta testing 0.0.2.2/1.0.6.6 -- ideas and suggestions + as well what to exactly steal from ShellFileSend, heh.. \ No newline at end of file diff --git a/plugins/ShlExt/inc/README.txt b/plugins/ShlExt/inc/README.txt new file mode 100644 index 0000000000..4c0ab5f0cf --- /dev/null +++ b/plugins/ShlExt/inc/README.txt @@ -0,0 +1,92 @@ + + - Miranda Module API for Borland Delphi, FreePascal - + + These include files allow you to write modules to extend Miranda + Older versions of these files + limited support for FPC, versions & compilers are : + + Borland Delphi 2.0 thru 6.0 + FreePascal 1.0.4, 1.0.6 + + You can now create modules for Miranda (v0.1.2.2) and use + new stuff like Netlib! though you can still write for + the current stable release (v0.1.2.1) but you'll have to + be aware of version dependant things. + + Worry not though, every service/event is marked with a version + code if it's not present in older Miranda versions. + + Be warned, this is a brand new porting though it has borrowed + from older ports (see CVS, oh this is viewCVS? mmm, cheese.) + Things are presented in a more Delphi esque than a C esque manner + so if you feel confused refer to the C header. + + A word of warning, don't try to compile /delphiplugins examples + with these include files and expect it to work, + + + Include files use the {$include } syntax and will never work + as units. + + -- FPC support? -- + + FPC is now properly supported, but you may need to use -SD -S2 + command line switches (for Delphi, BP7 mode) remember to use -Fi + and -Fu to give the path to these files or use {$UNITPATH} and {$INCLUDEPATH} + + These include files don't any FPC stuff like macros + and inlined functions. + + -- Things to be aware of -- + + This version is not yet directly supported, if you want to learn + the API look at the CVS tree for documentation on plugins, as well + as guidelines and examples of the general structure of Miranda. + + This is my cop out for now, I'll try to write a more general 'guide' later + on. + + - + + Miranda uses a manifest to allow COMCTRL v6 to be loaded on XP, + This causes problems with image lists with Delphi (there are work arounds) + see borland.com for the article. + + You may want to refuse to load on XP or try to use Miranda's API to work with + imagelists and load images from resource as bitmaps (ugh) + + - lstrcat, lstrcpy + + I've used the Windows API calls to these C functions over Delphi's RTL + because SysUtils.pas just adds a bloat. + + - *If* you use SysUtils.pas + + Delphi loads OLE for variant support, it maybe advisable to unload + the DLL as soon as you start, this maybe a problem though, since Miranda + also uses OLE for extended image support, it doesn't however keep + it loaded all the time. + + There should be no problem in just decrementing the reference count + to the DLL and it'll unload if you were the only reference. + + if however you're using variants in your code, blergh. + + -- How you get it to work -- + + see testdll.dpr, it won't do much but it'll show a pretty description in the + options dialog (oh impressive!) + + To bring in new files, just use {$include that_file_you_want.inc} + If other include files are needed by the include file you bring in, + it'll try to include it itself. + + Of course you need to add the path to where the .inc files are to the project's + search path, or if you compile via the command line, use -U and -I + -U is needed because m_globaldefs.pas is a unit. + + Each header file is marked with "UNITDEP" which will tell you which units + it requires. + + All files that require the PLUGINLINK structure require m_globaldefs.pas + (this is all the C header files that use such macros!) diff --git a/plugins/ShlExt/inc/m_addcontact.inc b/plugins/ShlExt/inc/m_addcontact.inc new file mode 100644 index 0000000000..2e74ad1279 --- /dev/null +++ b/plugins/ShlExt/inc/m_addcontact.inc @@ -0,0 +1,54 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_ADDCONTACT} +{$DEFINE M_ADDCONTACT} + +const + + HANDLE_SEARCHRESULT = 0; + HANDLE_EVENT = 1; + HANDLE_CONTACT = 2; + +type + + PADDCONTACTSTRUCT = ^TADDCONTACTSTRUCT; + TADDCONTACTSTRUCT = record + handleType: Integer; + handle: THandle; // HDBEVENT, HCONTACT, SearchResult + szProto: PChar; // used by search result only + psr: Pointer; // @PROTOSEARCHRESULT + end; + +const + + { + wParam : (HWND) Parent window of the dialog that will be presented + lParam : Pointer to an initialised TADDCONTACTSTRUCT + Affect : Open's the add contact dialog + Version: 0.1.2.2+ + } + MS_ADDCONTACT_SHOW = 'AddContact/Show'; + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_api.pas b/plugins/ShlExt/inc/m_api.pas new file mode 100644 index 0000000000..78fda24976 --- /dev/null +++ b/plugins/ShlExt/inc/m_api.pas @@ -0,0 +1,75 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFDEF FPC} + {$PACKRECORDS C} + {$MODE Delphi} +{$ENDIF} + +unit m_api; + +interface + +uses + + m_globaldefs, windows; + + {$include m_plugins.inc} + {$include m_system.inc} + {$include m_database.inc} + {$include m_findadd.inc} + {$include m_awaymsg.inc} + {$include m_email.inc} + {$include m_history.inc} + {$include m_message.inc} + {$include m_url.inc} + {$include newpluginapi.inc} + {$include m_clui.inc} + {$include m_ignore.inc} + {$include m_skin.inc} + {$include m_file.inc} + {$include m_netlib.inc} + {$include m_langpack.inc} + {$include m_clist.inc} + {$include m_clc.inc} + {$include m_userinfo.inc} + {$include m_protosvc.inc} + {$include m_options.inc} + {$include m_icq.inc} + {$include m_protocols.inc} + {$include m_protomod.inc} + {$include m_utils.inc} + {$include m_addcontact.inc} + {$include statusmodes.inc} + {$include m_contacts.inc} + {$define M_API_UNIT} + {$include m_helpers.inc} + +implementation + + {$undef M_API_UNIT} + {$include m_helpers.inc} + +end. + diff --git a/plugins/ShlExt/inc/m_awaymsg.inc b/plugins/ShlExt/inc/m_awaymsg.inc new file mode 100644 index 0000000000..2ad330f9de --- /dev/null +++ b/plugins/ShlExt/inc/m_awaymsg.inc @@ -0,0 +1,40 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_AWAYMSG} +{$DEFINE M_AWAYMSG} + +const + + { + wParam : HCONTACT + lParam : 0 + Affect : Show the away/na/etc message for a contact + Returns: 0 on success, non zero on failure, see notes + notes : returns without waiting for the message to be shown. + version: v0.1.0.1+ + } + MS_AWAYMSG_SHOWAWAYMSG = 'SRAway/GetMessage'; + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_clc.inc b/plugins/ShlExt/inc/m_clc.inc new file mode 100644 index 0000000000..d55ecc7438 --- /dev/null +++ b/plugins/ShlExt/inc/m_clc.inc @@ -0,0 +1,284 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_CLC} +{$DEFINE M_CLC} + +const + + CLISTCONTROL_CLASS = 'CListControl'; + + // styles + + CLS_MANUALUPDATE = $0001; // todo + CLS_SHOWHIDDEN = $0002; + CLS_HIDEOFFLINE = $0004; // hides all offline users + CLS_CHECKBOXES = $0008; + CLS_MULTICOLUMN = $0010; // not true multi-column, just for ignore/vis options + CLS_HIDEEMPTYGROUPS = $0020; // note: this flag will be spontaneously removed if the 'new subgroup' menu item is clicked, for obvious reasons + CLS_USEGROUPS = $0040; + CLS_NOHIDEOFFLINE = $0080; // overrides CLS_HIDEOFFLINE and the per-group hideoffline setting + CLS_GREYALTERNATE = $0100; // make every other line slightly grey + CLS_GROUPCHECKBOXES = $0200; // put checkboxes on groups too (managed by CLC) + + CLS_EX_DISABLEDRAGDROP = $00000001; + CLS_EX_EDITLABELS = $00000002; + CLS_EX_SHOWSELALWAYS = $00000004; + CLS_EX_TRACKSELECT = $00000008; + CLS_EX_SHOWGROUPCOUNTS = $00000010; + CLS_EX_DIVIDERONOFF = $00000020; + CLS_EX_HIDECOUNTSWHENEMPTY = $00000040; + CLS_EX_NOTRANSLUCENTSEL = $00000080; + CLS_EX_LINEWITHGROUPS = $00000100; + CLS_EX_QUICKSEARCHVISONLY = $00000200; + CLS_EX_SORTGROUPSALPHA = $00000400; + CLS_EX_NOSMOOTHSCROLLING = $00000800; + + CLM_FIRST = $1000; // this is the same as LVM_FIRST + CLM_LAST = $1100; + +// messages, compare with equivalent TVM_* in the WINAPI + + CLM_ADDCONTACT = (CLM_FIRST+0); // wParam=hContact + CLM_ADDGROUP = (CLM_FIRST+1); // wParam=hGroup + CLM_AUTOREBUILD = (CLM_FIRST+2); + CLM_DELETEITEM = (CLM_FIRST+3); // wParam=hItem + CLM_EDITLABEL = (CLM_FIRST+4); // wParam=hItem + CLM_ENDEDITLABELNOW = (CLM_FIRST+5); // wParam=cancel, 0 to save + CLM_ENSUREVISIBLE = (CLM_FIRST+6); // wParam=hItem, lParam=partialOk + + CLE_TOGGLE = -1; + CLE_COLLAPSE = 0; + CLE_EXPAND = 1; + CLE_INVALID = $FFFF; + + CLM_EXPAND = (CLM_FIRST+7); // wParam=hItem, lParam=CLE_ + CLM_FINDCONTACT = (CLM_FIRST+8); // wParam=hContact, returns an hItem + CLM_FINDGROUP = (CLM_FIRST+9); // wParam=hGroup, returns an hItem + CLM_GETBKCOLOR = (CLM_FIRST+10); // returns a COLORREF + CLM_GETCHECKMARK = (CLM_FIRST+11); // wParam=hItem, returns 1 or 0 + CLM_GETCOUNT = (CLM_FIRST+12); // returns the total number of items + + CLM_GETEDITCONTROL = (CLM_FIRST+13); // returns the HWND, or NULL + CLM_GETEXPAND = (CLM_FIRST+14); // wParam=hItem, returns a CLE_, CLE_INVALID if not a group + CLM_GETEXTRACOLUMNS = (CLM_FIRST+15); // returns number of extra columns + CLM_GETEXTRAIMAGE = (CLM_FIRST+16); // wParam=hItem, lParam=MAKELPARAM(iColumn (0 based),0), returns iImage or $FF + CLM_GETEXTRAIMAGELIST = (CLM_FIRST+17); // returns HIMAGELIST + CLM_GETFONT = (CLM_FIRST+18); // wParam=fontId, see clm_setfont. returns hFont. + CLM_GETINDENT = (CLM_FIRST+19); // wParam=new group indent + CLM_GETISEARCHSTRING = (CLM_FIRST+20); // lParam=(char*)pszStr, max 120 bytes, returns number of chars in string + CLM_GETITEMTEXT = (CLM_FIRST+21); // wParam=hItem, lParam=(char*)pszStr, max 120 bytes + CLM_GETSCROLLTIME = (CLM_FIRST+22); // returns time in ms + CLM_GETSELECTION = (CLM_FIRST+23); // returns hItem + + CLCHT_ABOVE = $0001; // above client area + CLCHT_BELOW = $0002; // below client area + CLCHT_TOLEFT = $0004; // left of client area + CLCHT_TORIGHT = $0008; // right of client area + CLCHT_NOWHERE = $0010; // in client area, not on an item + CLCHT_ONITEMICON = $0020; + CLCHT_ONITEMCHECK = $0040; + CLCHT_ONITEMLABEL = $0080; + CLCHT_ONITEMINDENT = $0100; // to the left of an item icon + CLCHT_ONITEMEXTRA = $0200; // on an extra icon, HIBYTE(HIWORD()) says which + CLCHT_ONITEM = $03E0; + CLCHT_INLEFTMARGIN = $0400; + CLCHT_BELOWITEMS = $0800; // in client area but below last item + + CLM_HITTEST = (CLM_FIRST+25); // lParam=MAKELPARAM(x,y) (relative to control), wParam=(PDWORD)&hitTest (see encoding of HitTest() in clc.h, can be NULL) returns hItem or NULL + CLM_SELECTITEM = (CLM_FIRST+26); // wParam=hItem + + CLB_TOPLEFT = 0; + CLB_STRETCHV = 1; + CLB_STRETCHH = 2; // and tile vertically + CLB_STRETCH = 3; + + CLBM_TYPE = $00FF; + CLBF_TILEH = $1000; + CLBF_TILEV = $2000; + CLBF_PROPORTIONAL = $4000; + CLBF_SCROLL = $8000; + + CLM_SETBKBITMAP = (CLM_FIRST+27); // wParam=mode, lParam=hBitmap (don't delete it), NULL for none + CLM_SETBKCOLOR = (CLM_FIRST+28); // wParam=a COLORREF, default is GetSysColor(COLOR_3DFACE) + CLM_SETCHECKMARK = (CLM_FIRST+29); // wParam=hItem, lParam=1 or 0 + CLM_SETEXTRACOLUMNS = (CLM_FIRST+30); // wParam=number of extra columns (zero to MAXEXTRACOLUMNS from clc.h, currently 16) + CLM_SETEXTRAIMAGE = (CLM_FIRST+31); // wParam=hItem, lParam=MAKELPARAM(iColumn (0 based),iImage). iImage=$FF is a blank + CLM_SETEXTRAIMAGELIST = (CLM_FIRST+32); // lParam=HIMAGELIST + + FONTID_CONTACTS = 0; + FONTID_INVIS = 1; + FONTID_OFFLINE = 2; + FONTID_NOTONLIST = 3; + FONTID_GROUPS = 4; + FONTID_GROUPCOUNTS = 5; + FONTID_DIVIDERS = 6; + FONTID_OFFINVIS = 7; + FONTID_MAX = 7; + + CLM_SETFONT = (CLM_FIRST+33); // wParam=hFont, lParam=MAKELPARAM(fRedraw,fontId) + CLM_SETINDENT = (CLM_FIRST+34); // wParam=new indent, default is 3 pixels + CLM_SETITEMTEXT = (CLM_FIRST+35); // wParam=hItem, lParam=(char*)pszNewText + CLM_SETSCROLLTIME = (CLM_FIRST+36); // wParam=time in ms, default 200 + CLM_SETHIDEEMPTYGROUPS = (CLM_FIRST+38); // wParam=TRUE/FALSE + + GREYF_UNFOCUS = $80000000; + MODEF_OFFLINE = $40000000; + + // and use the PF2_ #defines from m_protosvc.inc + CLM_SETGREYOUTFLAGS = (CLM_FIRST+39); // wParam=new flags + CLM_GETHIDEOFFLINEROOT = (CLM_FIRST+40); // returns TRUE/FALSE + CLM_SETHIDEOFFLINEROOT = (CLM_FIRST+41); // wParam=TRUE/FALSE + CLM_SETUSEGROUPS = (CLM_FIRST+42); // wParam=TRUE/FALSE + CLM_SETOFFLINEMODES = (CLM_FIRST+43); // for 'hide offline', wParam=PF2_ flags and MODEF_OFFLINE + CLM_GETEXSTYLE = (CLM_FIRST+44); // returns CLS_EX_ flags + CLM_SETEXSTYLE = (CLM_FIRST+45); // wParam=CLS_EX_ flags + CLM_GETLEFTMARGIN = (CLM_FIRST+46); // returns count of pixels + CLM_SETLEFTMARGIN = (CLM_FIRST+47); // wParam=pixels + // the order of info items is never changed, so make sure you add them in the + // order you want them to remain + CLM_ADDINFOITEM = (CLM_FIRST+48); // lParam=&TCLCINFOITEM, returns hItem + CLM_GETITEMTYPE = (CLM_FIRST+49); // wParam=hItem, returns a CLCIT_ + CLM_GETNEXTITEM = (CLM_FIRST+50); // wParam=flag, lParam=hItem, returns an hItem + CLM_GETTEXTCOLOR = (CLM_FIRST+51); // wParam=FONTID_, returns COLORREF + CLM_SETTEXTCOLOR = (CLM_FIRST+52); // wParam=FONTID_, lParam=COLORREF + + CLCIIF_BELOWGROUPS = 1; // put it between groups and contacts, default is at top + CLCIIF_BELOWCONTACTS = 2; // put it at the bottom + CLCIIF_CHECKBOX = $40; // give this item a check box + CLCIIF_GROUPFONT = $80; // draw the item using FONTID_GROUPS + + CLCIT_INVALID = -1; + CLCIT_GROUP = 0; + CLCIT_CONTACT = 1; + CLCIT_DIVIDER = 2; + CLCIT_INFO = 3; + + CLGN_ROOT = 0; + CLGN_CHILD = 1; + CLGN_PARENT = 2; + CLGN_NEXT = 3; + CLGN_PREVIOUS = 4; + CLGN_NEXTCONTACT = 5; + CLGN_PREVIOUSCONTACT = 6; + CLGN_NEXTGROUP = 7; + CLGN_PREVIOUSGROUP = 8; + + CLNF_ISGROUP = 1; + CLNF_ISINFO = 2; + + CLN_FIRST = (0-100); + CLN_EXPANDED = (CLN_FIRST-0); // hItem=hGroup, action=CLE_* + CLN_LISTREBUILT = (CLN_FIRST-1); + CLN_ITEMCHECKED = (CLN_FIRST-2); // todo // hItem,action,flags valid + CLN_DRAGGING = (CLN_FIRST-3); // hItem,pt,flags valid. only sent when cursor outside window, return nonzero if processed + CLN_DROPPED = (CLN_FIRST-4); // hItem,pt,flags valid. only sent when cursor outside window, return nonzero if processed + CLN_LISTSIZECHANGE = (CLN_FIRST-5); // pt.y valid. the vertical height of the visible items in the list has changed. + CLN_OPTIONSCHANGED = (CLN_FIRST-6); // nothing valid. If you set some extended options they have been overwritten and should be re-set + CLN_DRAGSTOP = (CLN_FIRST-7); // hItem,flags valid. sent when cursor goes back in to the window having been outside, return nonzero if processed + CLN_NEWCONTACT = (CLN_FIRST-8); // hItem,flags valid. sent when a new contact is added without a full list rebuild + CLN_CONTACTMOVED = (CLN_FIRST-9); // hItem,flags valid. sent when contact is moved without a full list rebuild + CLN_CHECKCHANGED = (CLN_FIRST-10); // hItem,flags valid. sent when any check mark is changed, but only for one change if there are many + +type + + PCLCINFOITEM = ^TCLCINFOITEM; + TCLCINFOITEM = record + cbSize: int; + pszText: PChar; + hParentGroup: THandle; + flags: DWORD; + hIcon: THandle; // todo + end; + + PNMCLISTCONTROL = ^TNMCLISTCONTROL; + TNMCLISTCONTROL = record + hdr: TNMHDR; // depends on Windows.pas + hItem: THandle; + action: int; + iColumn: int; // -1 if not on an extra column + flags: DWORD; + pt: TPoint; // depends on Windows.pas + end; + + PCLCINFOTIP = ^TCLCINFOTIP; + TCLCINFOTIP = record + cbSize: int; + isTreeFocused: int; // so the plugin can provide an option + isGroup: int; // 0 if it's contact, 1 if it's a group + hItem: THandle; // handle to group or contact + ptCursor: TPoint; + rcItem: TRect; + end; + +const + + { + wParam : 0 + lParam : Pointer to a TCLCINFOTIP structure + Affect : An InfoTip for an item should be shown now, see notes + Returns: [non zero] if you process this, because it makes no sense + for more than one module to process this. + Notes : It's upto the module where to put the InfoTip, Normally + it's a few pixels below and to the right of the cursor. + - + This event is called after the mouse ehas been stationary over + a contact for (by default) 200ms + } + ME_CLC_SHOWINFOTIP = 'CLC/ShowInfoTip'; + + { + wParam : 0 + lParam : Pointer to an initialised TCLCINFOTIP + Affect : It's time to destroy an infotip, see notes + Notes : Only cbSize, isGroup, hItem are set + notes : This is sent when the mouse moves off a contact when ME_CLC_SHOWINFOTIP + has previously been called. + - + If you don't want this behaviour, you should have grabbed the mouse + capture yourself -- + } + ME_CLC_HIDEINFOTIP = 'CLC/HideInfoTip'; + + { + wParam : new_time + lParam : 0 + Affect : Set a new hover time before the info tip hooks are called, see notes + Returns: 0 on success, [non zero] on failure + Notes : The value of this setting is applid to all current CLC windows + and saved to b applied to all future windows, it is persistent. + - + Time is in milliseconds, default is 750ms + } + MS_CLC_SETINFOTIPHOVERTIME = 'CLC/SetInfoTipHoverTime'; + + { + wParam : 0 + lParam : 0 + Affect : get the hover time before the infotip hooks are called + returns: the hover time in MS + } + MS_CLC_GETINFOTIPHOVERTIME = 'CLC/GetInfoTipHoverTime'; + +{$ENDIF} \ No newline at end of file diff --git a/plugins/ShlExt/inc/m_clist.inc b/plugins/ShlExt/inc/m_clist.inc new file mode 100644 index 0000000000..58f59fac14 --- /dev/null +++ b/plugins/ShlExt/inc/m_clist.inc @@ -0,0 +1,641 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_CLIST} +{$DEFINE M_CLIST} + +{$ifndef STATUSMODES} + {$include statusmodes.inc} +{$endif} + +const + + // for MS_CLIST_GETSTATUSMODEDESCRIPTION + + GSMDF_PREFIXONLINE = 1; // prefix "Online :" for online submodes, e.g. 'away' + + // for MS_CLIST_ADDMAINMENUITEM + + CMIF_GRAYED = 1; + CMIF_CHECKED = 2; + CMIF_HIDDEN = 4; // only works on contact menus + CMIF_NOTOFFLINE = 8; // item won't appear for contacts that are offline + CMIF_NOTONLINE = 16; // " online + CMIF_NOTONLIST = 32; // item won't appear on standard contacts + CMIF_NOTOFFLIST = 64; // item won't appear on contacts that have the 'NotOnList' setting + + // for MS_CLIST_MODIFYMENUITEM + + CMIM_NAME = $80000000; + CMIM_FLAGS = $40000000; + CMIM_ICON = $20000000; + CMIM_HOTKEY = $10000000; + CMIM_ALL = $F0000000; + + // for MS_CLIST_GETCONTACTDISPLAYNAME + + // will never return the user's custom name, even if that's the one to be displayed + GCDNF_NOMYHANDLE = 1; + + // for MS_CLIST_ADDEVENT + + //flashes the icon even if the user is occupied, and puts the event + // at the top of the queue + CLEF_URGENT = 1; + { icon will not flash forever, only a few times, e.g. online alert } + CLEF_ONLYAFEW = 2; + + // for MS_CLIST_GETICONSIMAGELIST + + IMAGE_GROUPOPEN = 11; + IMAGE_GROUPSHUT = 12; + + // for MS_CLIST_MENUPROCESSCOMMAND + + MPCF_CONTACTMENU = 1; // test commands from a contact menu + MPCF_MAINMENU = 2; // test commands from the main menu + + // for MS_CLIST_GROUPGETNAME/2 + + GROUPF_EXPANDED = $04; + GROUPF_HIDEOFFLINE = $08; + + // + + SETTING_TOOLWINDOW_DEFAULT = 1; + SETTING_SHOWMAINMENU_DEFAULT = 1; + SETTING_SHOWCAPTION_DEFAULT = 1; + SETTING_CLIENTDRAG_DEFAULT = 0; + SETTING_ONTOP_DEFAULT = 1; + SETTING_MIN2TRAY_DEFAULT = 1; + SETTING_TRAY1CLICK_DEFAULT = 0; + SETTING_HIDEOFFLINE_DEFAULT = 0; + SETTING_HIDEEMPTYGROUPS_DEFAULT = 0; + SETTING_USEGROUPS_DEFAULT = 1; + SETTING_SORTBYSTATUS_DEFAULT = 0; + SETTING_TRANSPARENT_DEFAULT = 0; + SETTING_ALPHA_DEFAULT = 200; + SETTING_AUTOALPHA_DEFAULT = 150; + SETTING_CONFIRMDELETE_DEFAULT = 1; + SETTING_AUTOHIDE_DEFAULT = 0; + SETTING_HIDETIME_DEFAULT = 30; + SETTING_CYCLETIME_DEFAULT = 4; + SETTING_ALWAYSSTATUS_DEFAULT = 0; + SETTING_ALWAYSMULTI_DEFAULT = 0; + SETTING_TRAYICON_SINGLE = 0; + SETTING_TRAYICON_CYCLE = 1; + SETTING_TRAYICON_MULTI = 2; + SETTING_TRAYICON_DEFAULT = SETTING_TRAYICON_SINGLE; + SETTING_STATE_HIDDEN = 0; + SETTING_STATE_MINIMIZED = 1; + SETTING_STATE_NORMAL = 2; + +type + + PCLISTMENUITEM = ^TCLISTMENUITEM; + TCLISTMENUITEM = record + cbSize: int; // size in bytes of this structure + pszName: PChar; // text of the menu item + flags: DWORD; + position: int; // approx position on the menu, lower numbers go nearer the top + hIcon: THandle; // icon to put by the item, if this was *not* loaded from + // a resource, you can delete it straight after the call + pszService: PChar; // name of the service to call when the service is clicked + pszPopupName: PChar;// name of the popup menu that this item is on, if this + // is NULL the iteem is on the root of the menu + popupPosition: int; // position of the popup menu on the root menu, ignored + // if pszPopupName is NULL(0) or if the popup menu already exists + hotKey: DWORD; // keyboard accelerator, same as lParam of WM_HOTKEY, 0 for none + pszContactOwner: PChar; // contact menus only, the protocol module that owns + // the contacts to which this to which this menu item + // applies, NULL(0) if it applies to all contacts. + // if it applies to multiple but not all protocols + // add multiple menu items or use ME_CLIST_PREBUILDCONTACTMENU + end; + + PCLISTDOUBLECLICKACTION = ^TCLISTDOUBLECLICKACTION; + TCLISTDOUBLECLICKACTION = record + cbSize: int; + pszContactOwner: PChar; // name of the protocol owning the contact or NULL(0) for all + flags: DWORD; // CMIF_NOT flags above + pszService: PChar; // service to call on double click, is called with wParam=hContact, lParam=0 + end; + + PCLISTEVENT = ^TCLISTEVENT; + TCLISTEVENT = record + cbSize: int; // size in bytes + hContact: THandle; // handle to the contact to put the icon by + hIcon: THandle; // icon to flash! + flags: DWORD; + hDBEvent: THandle; // caller defined, but should be unique for hContact + lParam: LPARAM; + pszService: PChar; // name of service to call on activation + pszTooltip: PChar; // short description of the event to display as a tooltip on the systray + end; + +const + + { + wParam : new_status + lParam : 0 + Affect : Sent when the user acks to change their status, see notes + Notes : Also sent due to a MS_CLIST_SETSTATUSMODE + } + ME_CLIST_STATUSMODECHANGE = 'CList/StatusModeChange'; + + { + wParam : new_status + lParam : 0 + Affect : Force a change of status mode, see statusmodes.inc + } + MS_CLIST_SETSTATUSMODE = 'CList/SetStatusMode'; + + { + wParam : 0 + lParam : 0 + Affect : Get the current status mode, see notes + Notes : This is the status, as set by the user, not any protocol specific status + all protocol modules will attempt to conform to this setting at ALL times. + } + MS_CLIST_GETSTATUSMODE = 'CList/GetStatusMode'; + + { + wParam : status_mode + lParam : flags + Affect : Get a textual description of the given status mode + Returns: pointer to a static buffer of the description of the given status mode + or NULL(0) if the mode was unknown. + Version: v0.1.0.1+ + } + MS_CLIST_GETSTATUSMODEDESCRIPTION = 'CList/GetStatusModeDescription'; + + { + wParam : 0 + lParam : Pointer to a initalised TCLISTMENUITEM structure + Affect : Add a new menu item to the main menu, see notes + Returns: A handle to the new MENU item or NULL(0) on failure + Notes : The given TCLISTMENUITEM.pszService in is called when the item + get clicked with : + - + wParam = 0, lParam = hwndContactList + } + MS_CLIST_ADDMAINMENUITEM = 'CList/AddMainMenuItem'; + + { + wParam : 0 + lParam : Pointer to a initalised TCLISTMENUITEM structure + Affect : Add a new item to the user contact menus, see notes + Notes : exactly the same as MS_CLIST_ADDMAINMENUITEM except when an item + is selected, the service gets called with wParam=hContact, + pszContactOwner is obeyed. + - + Popup menus are not supported, pszPopupName and popupPosition + are ignored. If CTRL is held down when right clicking the menu + position numbers will be displayed in brackets afterr the menu item + text, this only works in debug builds! + } + MS_CLIST_ADDCONTACTMENUITEM = 'CList/AddContactMenuItem'; + + { + wParam : HMENUITEM + lParam : Pointer to a initalised TCLISTMENUITEM + Affect : Modify an existing menu item, see notes + Returns: 0 on success, [non zero] on failure + Notes : hMenuItem will have been returned by MS_CLIST_ADD[MAIN]MENUITEM + TCLISTMENUITEM.flags should contain CMIM_* constants (see above) + to mark which fields should be updated, if it's not present, they + can't be updated -- if flags do not exist for a field it can not + be updated. + Version: v0.1.0.1+ + } + MS_CLIST_MODIFYMENUITEM = 'CList/ModifyMenuItem'; + + { + wParam : HCONTACT + lParam : 0 + Affect : the context menu for a contact is about to be built, see notes + Notes : modules should use this to change menu items that are specific + to the contact that has them + Version: v0.1.0.1+ + } + ME_CLIST_PREBUILDCONTACTMENU = 'CList/PreBuildContactMenu'; + + { + wParam : 0 + lParam : Pointer to a initalised TCLISTDOUBLECLICKACTION structure + Affect : Sets the service to call when a contact is double-clicked, see notes + Returns: 0 on success, [non zero] on failure + Notes : in case of conflicts, the first module to have registered + will get the double click, no others will, this service + will return success even for duplicates + - + This service was dropped from development during 0.3.0.0, it is no + longer supported, see ME_CLIST_DOUBLECLICKED + Version: 0.1.2.2+, 0.2.0+ ONLY (not 3.0a) + } + MS_CLIST_SETDOUBLECLICKACTION = 'CList/SetDoubleClickAction'; + + { + wParam : HCONTACT + lParam : + Affect : Register with this event to be notified of a double click on the CList + against a HCONTACT, you will not be notified if there is a pending CList event + that the double click clears, (i.e. flashing icon is presented to be clicked) + Version: 0.3.0.0 + } + ME_CLIST_DOUBLECLICKED = 'CList/DoubleClicked'; + + { + wParam : HCONTACT + lParam : flags + Affect : Gets the string that the contact list will use to represent a contact + Returns: Always a pointer + Notes : Returns a pointer to the name, will always succeed, even if it needs + to return "(Unknown Contact)" + - + this pointer is a statically allocated buffer which will + be overwritten on every call to this service, callers should make + sure that they copy the information before they call it again + Version: v0.1.2.0+, 0.2.0+ ONLY (0.3a supports the contacts module) + } + MS_CLIST_GETCONTACTDISPLAYNAME = 'CList/GetContactDisplayName'; + + { + wParam : 0 + lParam : Pointer to a TCLISTEVENT + Affect : Add's an event to the list + Notes : The service will flash TCLISTEVENT.hIcon, next to the + contact, TCLISTEVENT.hContact + - + pszService is called is called wParam=hwndContactList, + lParam=pointer to a TCLISTEVENT. + - + the TCLISTEVENT data is invalidated after this service returns + so copy anything from it if required. + - + TCLISTEVENT.pszService will also be called if the user + double clicks on the icon, at which point it will be removed + from the contact lists queue automatically. + - + TCLISTEVENT.hContact and TCLISTEVENT.hDBEvent should be unique. + } + MS_CLIST_ADDEVENT = 'CList/AddEvent'; + + { + wParam : HCONTACT + lParam : HDBEVENT + Affect : Remove an event from the contact list queue + Returns: 0 on success, [non zero] on failure + } + MS_CLIST_REMOVEEVENT = 'Clist/RemoveEvent'; + + { + wParam : HCONTACT + lParam : iEvent + Affect : Get the details of an event in the queue, see notes + Returns: A CLISTEVENT* or NULL(0) on failure + Notes : Returns the iEvent'1st/2nd/3rd/nth elemented queried, + e.g. iEvent=0 will get the event that will be returned if the + user double clicks on that HCONTACT + - + Use HCONTACT=NULL, iEvent=0 for example to get the event + the user will get if they double click on the tray. + Version: v0.1.2.1+ + } + MS_CLIST_GETEVENT = 'CList/GetEvent'; + + { + wParam : ControlID + lParam : Pointer to MEASUREITEMSTRUCT struct + Affect : Process a WM_MEASUREITEM message for user context menus, see notes + Notes : just because wParam, lParam is defined here, only pass them + opaquely to this service, as is. + - + This is just to draw icons, if it is not called, the icons + will not be drawn + Version: v0.1.1.0+ + } + MS_CLIST_MENUMEASUREITEM = 'CList/MenuMeasureItem'; + + { + wParam : + lParam : + Affect : Process a WM_DRAWITEM message for user context menus, + wParam, lParam should be passed from such message handler. + Version: v0.1.1.0+ + } + MS_CLIST_MENUDRAWITEM = 'CList/MenuDrawItem'; + + { + wParam : HCONTACT + lParam : 0 + Affect : Built the context menu for a specific contact + Returns: A HMENU handle identifying the menu, thhis should be DestroyMenu()ed + when done. + Version: v0.1.1.0+ + } + MS_CLIST_MENUBUILDCONTACT = 'CList/MenuBuildContact'; + + { + wParam : 0 + lParam : 0 + Affect : Get the image list handle with all the useful icons in it + Version: v0.1.1.0+ + } + MS_CLIST_GETICONSIMAGELIST = 'CList/GetIconsImageList'; + + { + wParam : HCONTACT + lParam : 0 + Affect : Get the icon that should be associated with a contact + Returns: an index into the contact list imagelist, if the icon + is a flashing icon, this service won't return information about it + see below + Version: v0.1.2.0+ + } + MS_CLIST_GETCONTACTICON = 'CList/GetContactIcon'; + + { + wParam : HCONTACT + lParam : ICON_ID + Affect : The icon of a contact in the contact list has changed, + ICON_ID is an index to what image has changed + Version: v0.1.2.1+ + } + ME_CLIST_CONTACTICONCHANGED = 'CList/ContactIconChanged'; + + // ideally only used by a CLIST UI module + + { + wParam : 0 + lParam : 0 + Affect : Get the handle to Miranda's main menu + Version: v0.1.1.0+ + } + MS_CLIST_MENUGETMAIN = 'CList/MenuGetMain'; + + { + wParam : 0 + lParam : 0 + Affect : Get a handle to Miranda's status menu + Version: v0.1.1.0+ + } + MS_CLIST_MENUGETSTATUS = 'CList/MenuGetStatus'; + + { + wParam : MAKEWPARAM(LOWORD(wParam of WM_COMMAND),flags) + lParam : HCONTACT + Affect : Process a mennu selection from a menu, see notes + Returns: True if it processed the command, False otherwise + notes : hContact is the currently selected contact, it is not used + if this is a main menu command, if this is NULL then the command + is a contact menu one, the command is ignored + Version: v0.1.1.0+ + } + MS_CLIST_MENUPROCESSCOMMAND = 'CList/MenuProcessCommand'; + + { + wParam : virtual key code + lParam : MPCF_* flags + Affect : Process a menu hotkey, see notes + Returns: True if it processed the command, False otherwise + Notes : this should be called in WM_KEYDOWN + Version: v0.1.1.0+ + } + MS_CLIST_MENUPROCESSHOTKEY = 'CList/MenuProcessHotkey'; + + { + wParam : Pointer to a MSG structurer + lParam : Pointer to an LRESULT + Affect : Process all the messages required for docking, see notes + Returns: True if the message should NOT be processed anymore, False otherwise + Notes : only msg.hwnd, msg.message, msg.wParam and msg.lParam are used + your WndProc should return the lResult if AND only IF, TRUE is returned + Version: v0.1.1.0+ + } + MS_CLIST_DOCKINGPROCESSMESSAGE = 'CList/DockingProcessMessage'; + + { + wParam : 0 + lParam : 0 + Affect : Determines wheter the contact list docked + Returns: pnon zero] if the contact list is docked, or 0 if it's not + Version: v0.1.1.0+ + } + MS_CLIST_DOCKINGISDOCKED = 'CList/DockingIsDocked'; + + { + wParam : Pointer to a TMSG + lParam : Pointer to an LRESULT + Affect : Process all the messages required for the tray icon, see notes + Returns: TRUE if the message should not be processed anymore, False otherwise + Notes : Only msg.hwnd, msg.message, msg.wparam and msg.lParam are used + your WndProc should return LRESULT if and ONLY if TRUE is returned + Version: v0.1.1.0+ + } + MS_CLIST_TRAYICONPROCESSMESSAGE = 'CList/TrayIconProcessMessage'; + + { + wParam : Pointer to TMSG + lParam : Pointer to an LRESULT + Affect : Process all the messages required for hotkeys, see notes + Returns: True if the message should not be processed anymore or False otherwise + Notes : only msg.hwnd, msg.message, msg.wParam, msg.lParam are used + Version: v0.1.1.0+ + } + MS_CLIST_HOTKEYSPROCESSMESSAGE = 'CList/HotkeysProcessMessage'; + + { + wParam : 0 + lParam : 0 + Affect : Toggles the show/hide status of the contact list + Returns: 0 on success, [non zero] on failure + Version: v0.1.1.0+ + } + MS_CLIST_SHOWHIDE = 'CList/ShowHide'; + + { + wParam : 0 + lParam : 0 + Affect : temporarily disable the autohide feature, see notes + Notes : this service will restart the auto hide timer, so if you need + to keep the window visible you'll have to bee getting user input + or calling this service each time + Version: v0.1.2.1+ + } + MS_CLIST_PAUSEAUTOHIDE = 'CList/PauseAutoHide'; + + { + wParam : HPARENTGROUP + lParam : 0 + Affect : Create a new group and calls CLUI to display it, see notes + Returns: A handle to the new group. + Notes : If HPARENTGROUP is NULL(0) it will create a group at the root. + Version: v0.1.1.0+ + } + MS_CLIST_GROUPCREATE = 'CList/GroupCreate'; + + { + wParam : HGROUP + lParam : 0 + Affect : Delete a group and call CLUI to display the change + Returns: 0 on success, [non zero] on failure + Version: v0.1.1.0+ + } + MS_CLIST_GROUPDELETE = 'CList/GroupDelete'; + + { + wParam : HGROUP + lParam : newState + Affect : Change the expanded state flag for a group internally, see notes + Returns: 0 on success, [non zero] on failure + Notes : if newState is non zero then the group is expanded, 0 it's collapsed + CLUI IS *NOT* called when the change is made. + Version: v0.1.1.0+ + } + MS_CLIST_GROUPSETEXPANDED = 'CList/GroupSetExpanded'; + + { + wParam : HGROUP + lParam : MAKELPARAM(flags, flagsMask) + Affect : Change the flag for a group, see notes + Returns: 0 on success, [non zero] on failure + Notes : only if flags given in flagsmask are altered, + CLUI is called on change to GROUPF_HIDEOFFLINE + Version: v0.1.2.1+ + } + MS_CLIST_GROUPSETFLAGS = 'CList/GroupSetFlags'; + + { + wParam : HGROUP + lParam : Pointer to a integer to be filled with expanded state + Affect : get the name of a group, see notes + Returns: a static buffer pointing to the name of the group + returns NULL(0) if HGROUP is invalid. + Notes : the returned buffer is only valid til the next call + to this service, lParam can be NULL(0) if you don't + want to know if the group is expanded + Version: v0.1.1.0+ + } + MS_CLIST_GROUPGETNAME = 'CList/GroupGetName'; + + { + wParam : HGROUP + lParam : Pointer to flags + Affect : Get the name of the group, see notes + Returns: A static buffer pointing to the name of the group + returns NULL(0) if HGROUP is invalid + Note : this buffer is only valid til the next call to this service + flags can be NULL(0), otherwise it'll return GROUPF_* constants + Version: v0.1.2.1+ + } + MS_CLIST_GROUPGETNAME2 = 'CList/GroupGetName2'; + + { + wParam : HGROUP + lParam : HBEFOREGROUP + Affect : Move a group directly before another group + Returns: the new handle of the group on success, NULL(0) on failure + Notes : the order is represented by the order in which MS_CLUI_GROUPADDED + is called, however UI's are free to ignore this order and sort + if they wish. + Version: v0.1.2.1+ + } + MS_CLIST_GROUPMOVEBEFORE = 'CList/GroupMoveBefore'; + + { + wParam : HGROUP + lParam : Pointer to a null terminated string containing the new name + Affect : Rename a group internally, see notes + Returns: 0 on success, [non zero] on failure + Notes : this will fail if the group name is a duplicate of an existing + a name, CLUI is not called when this change is made. + Version: v0.1.1.0+ + } + MS_CLIST_GROUPRENAME = 'CList/GroupRename'; + + { + wParam : 0 + lParam : 0 + Affect : Build a menu of the group tree, see notes + Returns: Handle to the menu, NULL(0) on failure + Notes : NULL be returned if the user doesn't have any groups + the dwItemData of every menu item is the handle to that group. + Menu item ID's are assigned starting at 100 in no particular order + Version: v0.1.2.1+ + } + MS_CLIST_GROUPBUILDMENU = 'CList/GroupBuildMenu'; + + { + wParam : newValue + lParam : 0 + Affect : Changes the 'hide offline contacts' flag and calls CLUI, see notes + Returns: 0 success, [non zero] on failure + Notes : newValue is 0 to show all contacts, 1 to show only online contacts + -1 to toggle the value + Version: v0.1.1.0+ + } + MS_CLIST_SETHIDEOFFLINE = 'CList/SetHideOffline'; + + { + wParam : HCONTACT + lParam : 0 + Affect : Do the message processing associated with the double clicking a contact + Returns: 0 on success, [non zero] on failure + Version: v0.1.1.0+ + } + MS_CLIST_CONTACTDOUBLECLICKED = 'CList/ContactDoubleClicked'; + + { + wParam : HCONTACT + lParam : Pointer to an array of pchar's containing files/dirs + Affect : Do the processing when some files are droppeed on a contact, see notes + Returns: 0 on success, [non zero] on failure + Notes : the array is terminated when a NULL(0) entry is found + Version: v0.1.2.1+ + } + MS_CLIST_CONTACTFILESDROPPED = 'CList/ContactFilesDropped'; + + { + wParam : HCONTACT + lParam : HGROUP + Affect : Change the group a contact belongs to, see notes + Returns: 0 on success, [non zero] on failure + Notes : use hGroup=NULL(0) to remove any group association with the contact + Version: v0.1.1.0+ + } + MS_CLIST_CONTACTCHANGEGROUP = 'CList/ContactChangeGroup'; + + { + wParam : HCONTACT_1 + lParam : HCONTACT_2 + Affect : Determine the ordering of two given contacts + Returns: 0 if hContact1 is the same as hContact2 + 1 if hContact1 should be displayed before hContact2 + -1 if hContact1 should be displayed after hCotnact2 + Version: v0.1.1.0+ + } + MS_CLIST_CONTACTSCOMPARE = 'CList/ContactsCompare'; + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_clui.inc b/plugins/ShlExt/inc/m_clui.inc new file mode 100644 index 0000000000..09f2b999a3 --- /dev/null +++ b/plugins/ShlExt/inc/m_clui.inc @@ -0,0 +1,215 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_CLUI} +{$DEFINE M_CLUI} + + {<>} + +const + + { + wParam : 0 + lParam : 0 + Affects: Returns a window handle for the contact list window, see notes + Returns: "" + Notes : This call has a very specific purpose internally Miranda + and shouldn't be used gratuitously, in almost all cases + there's another call to do whatever it is that you're + trying to do. + } + MS_CLUI_GETHWND = 'CLUI/GetHwnd'; + + { + wParam : new status + lParam : null terminated string to a protocol ID + Affects: Change the protocol specific status indicators, see notes! + Returns: 0 on success, [non zero] on failure + Notes : protocol modules don't want to call this, they want + clist/protocolstatuschanged instead + } + MS_CLUI_PROTOCOLSTATUSCHANGED = 'CLUI/ProtocolStatusChanged'; + + { + wParam : Handle to a group + lParam : 1 or 0 + Affect : A new group was created, add it to the list, see notes + Notes : lParam is set to 1 or 0 if the user just created + the group or not. + - + this is also called when the contact list is being rebuilt, + new groups are always created with the name 'New group' + } + MS_CLUI_GROUPADDED = 'CLUI/GroupCreated'; + + { + wParam : HCONTACT + lParam : ICON_ID + Affect : Change the icon for a contact, see notes + Returns: 0 on success, [non zero] on failure + Notes : ICON_ID is an offset in the imagelist, see clist/geticonsimagelist + } + MS_CLUI_CONTACTSETICON = 'CLUI/ContactSetIcon'; + + { + wParam : HCONTACT + lParam : 0 + Affect : Remove a contact from the list, see notes + Returns: 0 on success, [non zereo] on failure + Notes : this contact is NOT actually being deleted, since if + a contact goes offline while 'hide offline' option is sset, + this service will be called then ALSO + } + MS_CLUI_CONTACTDELETED = 'CLUI/ContactDeleted'; + + { + wParam : HCONTACT + lParam : ICON_ID + Affect : Add a contact to the list, see note + returns: 0 on success, [non zero] on failure + Notes : the caller processes the 'hide offline' setting, so the callee + should not do further processing based on the value of this setting + - + WARNING: this will be called to re-add a contact when they come + online if 'hide offline' is on, but it cannot determine if + the contact is already on the list, so you may get requests to + add a contact when it is already on the list, which you should ignore. + - + You'll also get this whenever an event is added for a contact, + since if the contact was offline, it needs to be shown to + display the mesage, even if 'hide offlines' is on. + - + you should not resort the list on this call, a seperate resort + request will be sent. + - + ICON_ID is an offset in the image list, see clist/geticonsimagelist + + } + MS_CLUI_CONTACTADDED = 'CLUI/ContactAdded'; + + { + wParam : HCONTACT + lParam : 0 + Affect : Reename a contact in the lists, see notes + Returns: 0 on success, [non zero] on failure + Notes : You should not re-sort the list on this call, a separate resort + request will be sent, you can get the new name from clist/getcontactdisplayname + } + MS_CLUI_CONTACTRENAMED = 'CLUI/ContactRenamed'; + + { + wParam : 0 + lParam : 0 + Affect : Start a rebuild of the contact list, see notes + Returns: 0 on success, [non zero] on failure + Notes : this is the cue to clear the existing content of the list + expect to get a series of : + + clui/groupadded + clui/contactadded + clui/resortlist + } + MS_CLUI_LISTBEGINREBUILD = 'CLUI/ListBeginRebuild'; + + { + wParam : 0 + lParam : 0 + Affect : End a rebuild of the contact list, see notes + Returns: 0 on success, [non zero] on error + Notes : if you dissplayed an hourglass in beginbuild, set it back + here, you do not need to explicitly sort the list + } + MS_CLUI_LISTENDREBUILD = 'CLUI/ListEndRebuild'; + + { + wParam : 0 + lParam : 0 + Affect : Sort the contact list now, see notes + Returns: 0 success, [non zero] on failure + Notes : Sorts are buffered so you won't get this message lots of times + if the lists needs to be resorted many times rapidly + } + MS_CLUI_SORTLIST = 'CLUI/SortList'; + + { + wParam : CLUICAPS_* + lParam : 0 + Affect : Gets a load of capabilites for the loaded CLUI, see notes + Returns: the requested value, 0 of wParam is unknown -- + if this service is not implemented it is assumed all return + values will be 0. + Version: v0.1.2.1+ + } + + { can only provide this flag to return the following set of caps, the strings + show the database setting/type to store the list option, changing the value + does not reflect what the change is, i.e. ontop can only be affected with + a call to SetWindowPos() } + CLUICAPS_FLAGS1 = 0; + { empty groups aren't shown, 'CList/HideEmptyGroups' (byte) [changes make the list reload] } + CLUIF_HIDEEMPTYGROUPS = 1; + { groups can be disabled, lists can be merged into one seamlessly, (byte) 'CList/UseGroups' } + CLUIF_DISABLEGROUPS = 2; + { list can be displayed 'on top' of all other windows, 4 (byte) 'CList/OnTop' } + CLUIF_HASONTOPOPTION = 4; + { can disappear after a while of inactive use, + (byte) 'CList/AutoHide' (word) 'CList/HideTime' } + CLUIF_HASAUTOHIDEOPTION = 8; + + MS_CLUI_GETCAPS = 'CLUI/GetCaps'; + + { + wParam : HCONTACT + lParam : MAKELPARAM(screenX, screenY) + Affect : A contact is being dragged outside the main window + Return : return [non zero] to show the drag cursor as "accepting" the drag + or zero to show the circle/slash 'not allowed' + Version: v0.1.2.0+ + } + ME_CLUI_CONTACTDRAGGING = 'CLUI/ContactDragging'; + + { + wParam : HCONTACT + lParam : MAKELPARAM(screenX, screenY) + Affect : a contact has just been dropped outside the main window, see notes + Notes : return non zero to stop other hooks processing this event. + Version: v0.1.2.0+ + } + ME_CLUI_CONTACTDROPPED = 'CLUI/ContactDropped'; + + { + wParam : HCONTACT + lParam : 0 + Affect : A contact that *was* being dragged outside the main window + has gone back to the main window + Return : always return 0 + Version: v0.1.2.1+ + } + ME_CLUI_CONTACTDRAGSTOP = 'CLUI/ContactDragStop'; + +{$ENDIF} \ No newline at end of file diff --git a/plugins/ShlExt/inc/m_contacts.inc b/plugins/ShlExt/inc/m_contacts.inc new file mode 100644 index 0000000000..7ba6f68bbb --- /dev/null +++ b/plugins/ShlExt/inc/m_contacts.inc @@ -0,0 +1,90 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +type + + PCONTACTINFO = ^TCONTACTINFO; + TCONTACTINFO = record + cbSize: int; + dwFlag: Byte; + hContact: THandle; + szProto: PChar; + type_: Byte; + retval: record (* in C this is a nameless union *) + case longint of + 0: (bVal: Byte); + 1: (wVal: WORD); + 2: (dVal: DWORD); + 3: (pszVal: PChar); + 4: (cchVal: Word); + end; + end; + +const + +// CNF_* Types of information you can retreive by setting the dwFlag in CONTACTINFO + + CNF_FIRSTNAME = 1; // returns first name (string) + CNF_LASTNAME = 2; // returns last name (string) + CNF_NICK = 3; // returns nick name (string) + CNF_CUSTOMNICK = 4; // returns custom nick name, clist name (string) + CNF_EMAIL = 5; // returns email (string) + CNF_CITY = 6; // returns city (string) + CNF_STATE = 7; // returns state (string) + CNF_COUNTRY = 8; // returns country (string) + CNF_PHONE = 9; // returns phone (string) + CNF_HOMEPAGE = 10; // returns homepage (string) + CNF_ABOUT = 11; // returns about info (string) + CNF_GENDER = 12; // returns gender (byte,'M','F' character) + CNF_AGE = 13; // returns age (byte, 0==unspecified) + CNF_FIRSTLAST = 14; // returns first name + last name (string) + CNF_UNIQUEID = 15; // returns uniqueid, protocol username (must check type for type of return) + +// Special types +// Return the custom name using the name order setting +// IMPORTANT: When using CNF_DISPLAY you MUST free the string returned +// You must **NOT** do this from your version of free() you have to use Miranda's free() +// you can get a function pointer to Miranda's free() via MS_SYSTEM_GET_MMI, see m_system.h + CNF_DISPLAY = 16; +// Same as CNF_DISPLAY except the custom handle is not used +// IMPORTANT: When using CNF_DISPLAYNC you MUST free the string returned +// You must **NOT** do this from your version of free() you have to use Miranda's free() +// you can get a function pointer to Miranda's free() via MS_SYSTEM_GET_MMI, see m_system.h + CNF_DISPLAYNC = 17; + +// If MS_CONTACT_GETCONTACTINFO returns 0 (valid), then one of the following +// types is setting telling you what type of info you received + CNFT_BYTE = 1; + CNFT_WORD = 2; + CNFT_DWORD = 3; + CNFT_ASCIIZ = 4; + + { + wParam : not used + lParam : Pointer to an initialised TCONTACTINFO structure + affects: Get contact information + returns: Zero on success, non zero on failure. + notes : If successful, the type is set and the result is put into the associated member of TCONTACTINFO + } + MS_CONTACT_GETCONTACTINFO = 'Miranda/Contact/GetContactInfo'; diff --git a/plugins/ShlExt/inc/m_database.inc b/plugins/ShlExt/inc/m_database.inc new file mode 100644 index 0000000000..f2b26508df --- /dev/null +++ b/plugins/ShlExt/inc/m_database.inc @@ -0,0 +1,654 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_DATABASE} +{$DEFINE M_DATABASE} + +const + + DBVT_DELETED = 0; // setting got deleted, no values are valid + DBVT_BYTE = 1; // bVal, cVal are valid + DBVT_WORD = 2; // wVal, sVal are valid + DBVT_DWORD = 4; // dVal, lVal are valid + DBVT_ASCIIZ = 255; // pszVal is valid + DBVT_BLOB = 254; // cpbVal and pbVal are valid + DBVTF_VARIABLELENGTH = $80; // ? + +type + + HCONTACT = Integer; + HDBEVENT = Integer; + + PDBVARIANT = ^TDBVARIANT; + TDBVARIANT = record + type_: Byte; + case LongInt of + 0: (bVal: Byte); + 1: (cVal: Char); + 2: (wVal: Word); + 3: (sVal: SmallInt); + 4: (dVal: LongInt); + 5: (lVal: Integer); + 6: ( + pszVal: PChar; + cchVal: Word; + ); + 7: ( + cpbVal: Word; + pbVal: PByte; + ); + end; + +const + + { + wParam : size of the buffer to be filled + lParam : pointer to the buffer to be filled + affect : Get's the name of the current profile being used by the database + module -- this is the same as the filename of the profile without + the .ext + return : 0 on success, non zero on failure + } + MS_DB_GETPROFILENAME = 'DB/GetProfileName'; + + { + wParam : size of buffer pointed to by lParam + lParam : pointer to a buffer to be filled + affect : Fill a buffer with the current profile path being used, this does not include the trailing backslash. + return : 0 on success, non zero on failure + version: 0.3a only + } + MS_DB_GETPROFILEPATH = 'DB/GetProfilePath'; + +type + + PDBCONTACTGETSETTING = ^TDBCONTACTGETSETTING; + TDBCONTACTGETSETTING = record + { name of the module that wrote the setting to get } + szModule: PChar; + { the name of the setting to get } + szSetting: PChar; + { pointer to DBVARIANT to receive the value -- must be allocated for GETSETTINGSTATIC + calls thou } + pValue: PDBVARIANT; + end; + + PDBCONTACTWRITESETTING = ^TDBCONTACTWRITESETTING; + TDBCONTACTWRITESETTING = record + { module sig to write this setting under } + szModule: PChar; + { setting name to write } + szSetting: PChar; + { variant containing value to set } + value: TDBVARIANT; + end; + +const + + { + wParam : Handle of a contact to get the setting for (see notes) + lParam : pointer to a TDBCONTACTGETSETTING structure to be filled with setting + this structure also has to be initalised (see notes) + affect : Queries the database module for a setting from a contact. + returns: 0 on success, non zero on failure (contact not found, setting doesn't exist) + notes : TDBCONTACTGETSETTING must be filled with the module name that created + /wrote the setting you want to get (e.g. your module name) + and the actual setting to read with TDBCONTACTGETSETTING.szModule and + TDBCONTACTGETSETTING.szSetting -- TDBCONTACTGETSETTING.pValue is + a pointer to a TDBVARIANT with the returned setting, this maybe nil + and MUST be freed after you're done with it with FreeVariant() + + There are helper functions for reading/writing/deleting common types to and + from the database -- see DBGetContactSetting + + the contact handle (hContact) can be returned by FindContact/AddContact + } + MS_DB_CONTACT_GETSETTING = 'DB/Contact/GetSetting'; + + { + wParam : Handle for a contact to query a setting for + lParam : Pointer to a TDBCONTACTGETSETTING structure + affects: This service is almost the same as the one above, but it does + not return a dynamic copy (with malloc()) -- the caller + must do this for datatypes which require it, e.g. a string. + + This means the TDBCONTACTGETSETTING.pValue *has* to exist and be + allocated by the caller (doesn't have to be allocated from the heap) + the DBVARIANT structure has to be initalised with the type wanted + and enough buffer space around to return the info, do not + expect this service to be as fast as the one above. + + returns: 0 on success, non zero on failure. + } + MS_DB_CONTACT_GETSETTINGSTATIC = 'DB/Contact/GetSettingStatic'; + + { + wParam : 0 + lParam : Pointer to a TDBVARIANT structure + affect : Free's the passed DBVARIANT's dynamic memory (if any) see notes + returns: 0 on success, non zero on failure + notes : use the helper function FreeVariant() + } + MS_DB_CONTACT_FREEVARIANT = 'DB/Contact/FreeVariant'; + + { + wParam : Handle to contact to write setting for + lParam : Pointer to TDBCONTACTWRITESETTING which must be initalised + affects: writes a setting under a contact -- TDBCONTACTWRITESETTING structure + must contain the module name writing -- the setting name, and the value + to write (which is NOT a pointer) .szModule, .szSetting, .Value, see notes + returns: 0 on success, non zero on failure + notes : this service triggers 'DB/Contact/SettingChanged' before it returns + as always, there is a helper function to use this service. + } + MS_DB_CONTACT_WRITESETTING = 'DB/Contact/WriteSetting'; + + { + wParam : hContact under which the setting should be deleted + lParam : Pointer to a TDBCONTACTGETSETTING structure + affects: Deletes the given setting for a contact, the TDBCONTACTGETSETTING.pValue + field is ignored -- only .szModule and .szSetting are needed, see notes + returns: 0 on success, non zero on failure + notes : triggers 'DB/Contact/SettingChanged' BEFORE it deletes the given + setting, when the service returns the TDBVARIANT structure .type_ is set + to 0 and no fields are valid, there is a helper function for this + service, see below. + } + MS_DB_CONTACT_DELETESETTING = 'DB/Contact/DeleteSetting'; + + { + wParam : Handle of a contact to enum settings for + lParam : Pointer to a TDBCONTACTENUMSETTINGS structure, must be initalised + affect : Enumerates all settings for a given contact under a module, + TDBCONTACTENUMSETTINGS must be filled with the function pointer to call + the TDBCONTACTENUMSETTINGS.lParam value to pass to it each time, + as well as the .szModule under which the contact is valid + returns: returns the value of the last call to the enum function, or -1 + if no settings could be enumerated + notes : the szSetting argument passed to the enumeration function is only + valid for the duration of that enumeration call, + it must be allocated dynamically if it is required after that call frame + has returned. + Also, deleting settings as they are enumerated has unpredictable results! + but writing a new value for a setting is okay. + it is unclear how you stop the enumeration once it is started, maybe + possible to return -1 to stop it. + vesion : only valid for 0.1.0.1+ + } + +type + + TDBSETTINGENUMPROC = function(const szSetting: PChar; lParam: LPARAM): int; cdecl; + + PDBCONTACTENUMSETTINGS = ^TDBCONTACTENUMSETTINGS; + TDBCONTACTENUMSETTINGS = record + { function pointer to call to start the enum via MS_DB_CONTACT_ENUMSETTINGS } + pfnEnumProc: TDBSETTINGENUMPROC; + { passed to the above function } + lParam: LPARAM; + { name of the module to get settings for } + szModule: PChar; + { not used by us } + ofsSettings: DWORD; + end; + +const + + MS_DB_CONTACT_ENUMSETTINGS = 'DB/Contact/EnumSettings'; + + { + wParam : 0 + lParam : 0 + affect : none + returns: Returns the number of contacts in the database for the loaded profile + not including the profile user, see notes. + notes : the contacts in the database can be read with FindFirst/FindNext + } + MS_DB_CONTACT_GETCOUNT = 'DB/Contact/GetCount'; + + { + wParam : 0 + lParam : 0 + returns: Returns a handle to the first contact in the database, + this handle does not need to be closed, if there are no users + NULL(0) is returned. + } + MS_DB_CONTACT_FINDFIRST = 'DB/Contact/FindFirst'; + + { + wParam : Contact handle + lParam : 0 + returns: Returns a handle to the next contact after the given contact in + wParam, this handle does not neeed to be closed -- may return NULL(0) + if the given contact in wParam was the last in the database, or the + given contact was invalid + } + MS_DB_CONTACT_FINDNEXT = 'DB/Contact/FindNext'; + + { + wParam : Handle of a contact to delete + lParam : 0 + affect : the user by the given handle is deleted from the database, see notes + returns: Returns 0 on success or nonzero if the handle was invalid + notes : this triggers DB/Contact/Deleted BEFORE it actually deletes the contact + all events are also deleted -- other modules may end up with invalid + handles because of this, which they should be prepared for. + } + MS_DB_CONTACT_DELETE = 'DB/Contact/Delete'; + + { + wParam : 0 + lParam : 0 + affects: creates a new contact in the database, they have no settings, + settings must be added with MS_DB_CONTACT_WRITESETTING or + database helper functions for writing, see notes + returns: A handle to a new contact or NULL(0) on failure. + notes : triggers the ME_DB_CONTACT_ADDED event just before the service returns + } + MS_DB_CONTACT_ADD = 'DB/Contact/Add'; + + + { + wParam : (HANDLE) hContact + lParam : 0 + affects: Checks the given handle within the database for valid information, for + a proper internal header. + returns: Returns 1 if the contact handle is valid, 0 if it is not + notes : Due to the nature of multiple threading a contact handle can be deleted + soon after this service has returned a handle as valid, however it will never point + to another contact. + } + MS_DB_CONTACT_IS = 'DB/Contact/Is'; + + + { + wParam : contact handle for events count is needed + lParam : 0 + service: Gets the number of events in the chain belonging to a contact + in the databasee. + returns: the numbef of events owned by hContact or -1 if hContact + is invalid, they can be found with the event/find* servicees + } + MS_DB_EVENT_GETCOUNT = 'DB/Event/GetCount'; + + { + wParam : contact handle to add an event for + lParam : Pointer to TDBEVENTINFO initialised with data + affect : Add's an event to the contact's event list, the TDBEVENTINFO + structure should be filled with the event of message -- see notes + returns: a handle to a DB event (HDBEVENT), or NULL on error + notes : Triggers DB/Event/Added event just before it returns, + Events are sorted chronologically as they are entered, + so you cannot guarantee that the new hEvent is the last event in the chain, + however if a new event is added that has a timestamp less than + 90 seconds *before* the event that should be after it, + it will be added afterwards, to allow for protocols that only + store times to the nearest minute, and slight delays in transports. + There are a few predefined eventTypes below for easier compatibility, but + modules are free to define their own, beginning at 2000 + DBEVENTINFO.timestamp is in GMT, as returned by time() + } + + DBEF_FIRST = 1; // internally only, do not use + DBEF_SENT = 2; // if set, the event was sent by the user, otherwise it was received + DBEF_READ = 4; // event has been read by the user -- only needed for history + + EVENTTYPE_MESSAGE = 0; + EVENTTYPE_URL = 1; + EVENTTYPE_CONTACTS = 2; // v0.1.2.2+ + EVENTTYPE_ADDED = 1000; // v0.1.1.0+: these used to be module- + EVENTTYPE_AUTHREQUEST = 1001; // specific codes, hence the module- + EVENTTYPE_FILE = 1002; // specific limit has been raised to 2000 + +type + + PDBEVENTINFO = ^TDBEVENTINFO; + TDBEVENTINFO = record + { size of the structure } + cbSize: int; + { module that 'owns' this event and controls the data format } + szModule: PChar; + { timestamp in UNIX time } + timestamp: DWORD; + { the DBEF_* flags above } + flags: DWORD; + { event type, such as message, can be module defined } + eventType: WORD; + { size in bytes of pBlob^ } + cbBlob: DWORD; + { pointer to buffer containing the module defined event data } + pBlob: PByte; + end; + +const + + MS_DB_EVENT_ADD = 'DB/Event/Add'; + + + + { + wParam : Handle to the contact + lParam : HDBEVENT handle to delete + affects: Removes a single event from the database for the given contact + returns: 0 on success, nonzero on failure + notes : Triggers DB/Event/Deleted just before the event *is* deleted + } + MS_DB_EVENT_DELETE = 'DB/Event/Delete'; + + { + wParam : Handle to DB event + lParam : 0 + returns: Returns the space in bytes requried to store the blob in HDBEVENT + given by HDBEVENT(wParam) -- or -1 on error + } + MS_DB_EVENT_GETBLOBSIZE = 'DB/Event/GetBlobSize'; + + { + wParam : Handle to a DB event + lParam : Pointer to a TDBEVENTINFO structure which must be initialised + affects: Returns all the information about an DB event handle to a TDBEVENTINFO + structure which must be initalised, DBEI.cbSize, DBEI.pBlob and DBEI.cbSize + before calling this service, the size can be assertained with + GetBlobSize() service, see notes + returns: Returns 0 on success, non zero on failure + notes : The correct value dbe.cbBlob can be got using db/event/getblobsize + If successful, all the fields of dbe are filled. dbe.cbBlob is set to the + actual number of bytes retrieved and put in dbe.pBlob + If dbe.cbBlob is too small, dbe.pBlob is filled up to the size of dbe.cbBlob + and then dbe.cbBlob is set to the required size of data to go in dbe.pBlob + On return, dbe.szModule is a pointer to the database module's + own internal list of modules. Look but don't touch. + } + MS_DB_EVENT_GET = 'DB/Event/Get'; + + { + wParam : HCONTACT + lParam : HDBEVENT + affect : Changes the flag for an event to mark it as read + Returns: Returns the entire flag DWORD for the event after the change, or -1 + if HDBEVENT is invalid, see notes + notes : This iss one of the database write operations that does not trigger + an event, modules should not save flagss states for any length of time. + } + MS_DB_EVENT_MARKREAD = 'DB/Event/MarkRead'; + + { + wParam : HDBEVENT + lParam : 0 + Affect : Returns a handle to a contact that owns the HDBEVENT, + see notes + Returns: Returns a handle if successful or HDBEEVENT(-1) on failure + notes : This service is very slow, only use wheen you have no other choice + at all. + } + MS_DB_EVENT_GETCONTACT = 'DB/Event/GetContact'; + + { + wParam : HCONTACT + lParam : 0 + Affect : Retrieves a handlee to the first event in the chain + for a HCONTACT + returns: Returns a handle, or NULL(0) if HCONTACT is invalid or has + no events, events in a chain are sorted chronologically automatically + } + MS_DB_EVENT_FINDFIRST = 'DB/Event/FindFirst'; + + { + wParam : HCONTACT + lParam : 0 + Affect : Retrieves a handle to the first unreead event in a chain for a HCONTACT + see notes + Returns: Returns a HDBEVENT handle or NULL(0) if the HCONTACT is invalid + or all it's events have beeen read. + Notes : Events in a chain are sorted chronologically automatically, + but this does not necessarily mean that all events after + the first unread are unread too. + They should be checked individually with event/findnext and event/get + This service is designed for startup, reloading all the events that remained + unread from last time + } + MS_DB_EVENT_FINDFIRSTUNREAD = 'DB/Event/FindFirstUnread'; + + { + wParam : HCONTACT + lParam : 0; + Affects: Retrieves a handle to the lasts event in the chain for a HCONTACT + Returns: Returns a handle or NULL(0) if HCONTACT is invalid or has no events + } + MS_DB_EVENT_FINDLAST = 'DB/Event/FindLast'; + + { + wParam : HDBEVENT + lParam : 0 + Affects: Retrieves a handle to the next event in a chain after HDBEVENT + Returns: A handle to the next DB event or NULL(0) if HDBEVENT is invalid + or the last event in the chain. + } + MS_DB_EVENT_FINDNEXT = 'DB/Event/FindNext'; + + { + wParam : HDBEVENT + lParam : 0 + Affects: Retrieves a handle to the previous event in a chain before HDBEVENT + Returns: A handle to the previous HDBEVENT or NULL(0) if HDBEVENT is invalid + or is the first event in the chain + } + MS_DB_EVENT_FINDPREV = 'DB/Event/FindPrev'; + + + + { + wParam : size in bytes of string buffer (including null term) + lParam : pointer to string buffer + Affect : Scrambles the string buffer in place using a strange encryption algorithm, + see notes + Returns: Always returns 0 + notes : this service may be changed at a later date such that it increasess + the length of the string + } + MS_DB_CRYPT_ENCODESTRING = 'DB/Crypt/EncodeString'; + + { + wParam : size in bytes of string buffer, including null term + lParam : pointer to string buffer + Affect : Descrambles pszString in-place using the strange encryption algorithm, + see notes. + Return : Always returns 0 + notes : Reverses the operation done by MS_DB_CRYPT_ENCODINGSTRING + } + MS_DB_CRYPT_DECODESTRING = 'DB/Crypt/DecodeString'; + + + + { + wParam : timestamp (DWORD) + lParam : 0 + Affect : Converts a GMT timestap into local time + Returns: Returns the converted value, see notes + Notes : Timestamps have a zereo at midnight 1/1/1970 GMT, this service + converts such a value to be based at midnight 1/1/1970 local time. + This service does not use a simple conversion based on the current offset + between GMT and local. Rather, it figures out whether daylight savings time + would have been in place at the time of the stamp and gives the local time as + it would have been at the time and date the stamp contains. + } + MS_DB_TIME_TIMESTAMPTOLOCAL = 'DB/Time/TimestampToLocal'; + + { + wParam : timestamp (DWORD) + lParam : pointer to initalised DBTIMETOSTRING structure + Affect : Converts a GMT timestamp to a customisable local time string + see notes + Returns: Always returns 0 + notes : The string is formatted according to thhe current user's locale + language and preference -- + + .szFormat can have the following special chars : + t time without seconds, e.g. hh:mm + s time with seconds, e.g. hh:mm:ss + m time without minutes e.g. hh + d short date, e.g. dd/mm/yyyy + D long date, e.g. d mmmm yyyy + + all other characters are copied as is. + } + +type + + PDBTIMETOSTRING = ^TDBTIMETOSTRING; + TDBTIMETOSTRING = record + { format string, see above } + szFormat: PChar; + { pointer to dest buffer to store the result } + szDest: PChar; + { size of the buffer } + cbDest: int; + end; + +const + + MS_DB_TIME_TIMESTAMPTOSTRING = 'DB/Time/TimestampToString'; + + + + { + wParam : newSetting (BOOLEAN) + lParam : 0 + Affect : Miranda's database is normally protected against corruption by + aggressively flushing data to the disk on writes, if you're doing + alot of writes e.g. an import plugin, it can sometimes be desirable + to switch this feature off to speed up the process, if you do switch + it off, you must remember that crashes are far more likely to be + catastrophic, so switch it back on at the earliest possible opportunity. + if you're doing a lot of setting writes, the flush is already delayed + so you need not use this service for that purpose, see notes. + Returns: Always returns 0 (successful) + notes : This is set to true initally + } + MS_DB_SETSAFETYMODE = 'DB/SetSafetyMode'; + + { + wParam : (caller defined data) will be passed to lParam of the call back + lParam : function pointer to TDBMODULEENUMPROC + Affects: Enumerates the names of all modules that have stored or + requested information from the database, + the modules are returned in no real order -- + Writing to the database while module names are being enumerated will cause + unpredictable results in the enumeration, but the write will work. + + the enumeration will stop if the callback returns a non zero value. + + Returns: the last return value from the enumeration call back. + Notes : This service is only useful for debugging or EnumSettings + version: The service registered to enumerate all modules that have touched + the database module uses wParam as the lParam cookie value and the lParam + value given here is the function pointer -- this is not safe + to use before v0.1.2.1 because I don't know if this was done in v0.1.2.1- + + prior to v0.1.2.1 you can not pass a value to the enumeration because + of a bug -- which is fixed, but hey :) -- [sam] + } +type + TDBMODULEENUMPROC = function(const szModule: PChar; ofsModuleName: DWORD; lParam: LPARAM): int; cdecl; +const + MS_DB_MODULES_ENUM = 'DB/Modules/Enum'; + + + + { + wParam : HCONTACT + lParam : HDBCONTACT + Affect : Called when a new event has been added to the event chain + for a contact, HCONTACT contains the contact who added the event, + HDBCONTACT a handle to what was added. + see notes + notes : since events are sorted chronologically, you can not guarantee + that HDBEVEnT is in any particular position in the chain. + + } + ME_DB_EVENT_ADDED = 'DB/Event/Added'; + + { + wParam : HANDLE (hContact) + lParam : @DBEVENTINFO + Affects: Hook is fired before any DBEVENTS are created within the database for + a contact (or a user, if hContact is NULL(0)) - It allows a module to + query/change DBEVENTINFO before it is created, see notes. + Returns: Hook should return 1 to stop event being added (will stop other hooks seeing the event too) + Or 0 to continue processing (passing the data on as well) + Notes : This hook is fired for all event types, and the BLOBS that the eventypes mark + Maybe changed, therefore be careful about using BLOB formats. + Because the memory pointing within the DBEVENTINFO CAN NOT BE OWNED or free()'d + it is recommended that the hook only be used to stop events. + Version: 0.3.3a+ (2003/12/03) + } + ME_DB_EVENT_FILTER_ADD = 'DB/Event/FilterAdd'; + + { + wParam : HCONTACT + lParam : HDBEVENT + Affect : Called when an event is about to be deleted from the event chain + for a contact, see notes + notes : Returning non zero from your hook will NOT stop the deletion, + but it will as usual stop other hooks being called + } + ME_DB_EVENT_DELETED = 'DB/Event/Deleted'; + + + + { + wParam : HCONTACT + lParam : 0 + Affect : Called when a new contact has been added to the database, + HCONTACT contains a handle to the new contact. + } + ME_DB_CONTACT_ADDED = 'DB/Contact/Added'; + + { + wParam : HCONTACT + lParam : 0 + Affect : Called when a contact is about to be deleted + Returns: Returning nonzero from your hook will not stop the deletion + but it will stop the other hooks from being called + } + ME_DB_CONTACT_DELETED = 'DB/Contact/Deleted'; + + { + wParam : HCONTACT + lParam : Pointer to a TDBCONTACTWRITESETTING + Affect : Calleed when a contact has one of it's settings changed + hContact is a valid handle to the contact that has changed, + see notes. + notes : this event will be triggered many times rapidly when alot of values + are set. + Modules that hook this should be aware of this fact and quickly + return if they are not interested in the value that has changed. + Careful not to get into infinite loops with this event, + + The TDBCONTACTWRITESETTING pointer is the same one as the + original service all, so don't change any of it's fields + } + ME_DB_CONTACT_SETTINGCHANGED = 'DB/Contact/SettingChanged'; + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_email.inc b/plugins/ShlExt/inc/m_email.inc new file mode 100644 index 0000000000..93312c7e59 --- /dev/null +++ b/plugins/ShlExt/inc/m_email.inc @@ -0,0 +1,39 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) +{$IFNDEF M_EMAIL} +{$DEFINE M_EMAIL} + +const + + { + wParam : HCONTACT + lParam : 0 + Affects: Send an e-mail to the specified contact, see notes + Returns: Returns 0 on success or nonzero on failure + Notes : If an error occurs the service displays a message box + with the error text -- use this service to alter this + } + MS_EMAIL_SENDEMAIL = 'SREMail/SendCommand'; + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_file.inc b/plugins/ShlExt/inc/m_file.inc new file mode 100644 index 0000000000..dd14286455 --- /dev/null +++ b/plugins/ShlExt/inc/m_file.inc @@ -0,0 +1,66 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_FILE} +{$DEFINE M_FILE} + +const + + { + wParam : HCONTACT + lParam : 0 + Affects: Brings up the send file dialog for a contact, see notes + Returns: 0 on success [non zero] on failure + Notes : Returns immediately without waiting for the send + } + MS_FILE_SENDFILE = 'SRFile/SendCommand'; + + { + wParam : HCONTACT + lParam : pointer to an array of PChar's the first nil item + terminates the list -- see notes + Affects: Brings up the send file dialog with specifieed files already chosen + the user is not prevented from editing the list -- + Returns: 0 on success [non zero] on failure -- returns immediately without + waiting for the send to finish + Notes : both directories and files can be given + Version: v0.1.2.1+ + } + MS_FILE_SENDSPECIFICFILES = 'SRFile/SendSpecificFiles'; + + { + wParam : HCONTACT + lParam : Pointer to a buffer + Affects: returns the received files folder for a contact, the buffer + should be at least MAX_PATH long (defined with WinAPI), + the returned path may not exist -- see notes + Returns: Returns 0 on success [non zero] on failure + notes : If HCONTACT is NULL(0) the path returned is the path + without the postfix contact name. + Version: v0.1.2.2+ + } + MS_FILE_GETRECEIVEDFILESFOLDER = 'SRFile/GetReceivedFilesFolder'; + + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_findadd.inc b/plugins/ShlExt/inc/m_findadd.inc new file mode 100644 index 0000000000..61b0d066b1 --- /dev/null +++ b/plugins/ShlExt/inc/m_findadd.inc @@ -0,0 +1,38 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) +{$IFNDEF M_FINDADD} +{$DEFINE M_FINDADD} + +const + + { + wParam : 0 + lParam : 0 + Affects: Openss the find/add users dialog box, or gives it focus if it's + already open. + Returns: Always returns 0 + } + MS_FINDADDFINDADD = 'FindAdd/FindAddCommand'; + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_globaldefs.pas b/plugins/ShlExt/inc/m_globaldefs.pas new file mode 100644 index 0000000000..614719a68c --- /dev/null +++ b/plugins/ShlExt/inc/m_globaldefs.pas @@ -0,0 +1,99 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFDEF FPC} + {$PACKRECORDS C} + {$MODE Delphi} +{$ENDIF} + +unit m_globaldefs; + +interface + +uses + +{$ifdef FPC} + strings; +{$else} + Windows; +{$endif} + +type + + PByte = ^Byte; + int = Integer; + pint = ^int; + WPARAM = Integer; + LPARAM = Integer; + DWORD = Integer; + THandle = Integer; + + // strcpy() + + {$ifdef FPC} + TStrCpy = function(Dst, Src: PChar): PChar; + {$else} + TStrCpy = function(Dst, Src: PChar): PChar; stdcall; + {$endif} + + // strcat() + + {$ifdef FPC} + TStrCat = function(Dst, Src: PChar): PChar; + {$else} + TStrCat = function(Dst, Src: PChar): PChar; stdcall; + {$endif} + +const + + {$ifdef FPC} + strcpy: TStrCpy = strings.strcopy; + {$else} + strcpy: TStrCpy = lstrcpy; + {$endif} + + {$ifdef FPC} + strcat: TStrCat = strings.strcat; + {$else} + strcat: TStrCat = lstrcat; + {$endif} + + {$include newpluginapi.inc} + {$include m_v8.inc} + +var + { this is now a pointer to a record of function pointers to match the C API, + and to break old code and annoy you. } + + PLUGINLINK: PPLUGINLINK; + + { has to be returned via MirandaPluginInfo and has to be statically allocated, + this means only one module can return info, you shouldn't be merging them anyway! } + + PLUGININFO: TPLUGININFO; + PLUGININFOEX: TPLUGININFOEX; + +implementation + +end. diff --git a/plugins/ShlExt/inc/m_globaldefs.ppu b/plugins/ShlExt/inc/m_globaldefs.ppu new file mode 100644 index 0000000000..dff0527ff7 Binary files /dev/null and b/plugins/ShlExt/inc/m_globaldefs.ppu differ diff --git a/plugins/ShlExt/inc/m_helpers.inc b/plugins/ShlExt/inc/m_helpers.inc new file mode 100644 index 0000000000..ef8edeb088 --- /dev/null +++ b/plugins/ShlExt/inc/m_helpers.inc @@ -0,0 +1,613 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$ifdef M_API_UNIT} + + function PLUGIN_MAKE_VERSION(a,b,c,d: Cardinal): int; + function PLUGIN_CMP_VERSION(verA: LongInt; verB: LongInt): int; + +{$else} + + function PLUGIN_MAKE_VERSION(a,b,c,d: Cardinal): int; + {$ifdef FPC} + inline; + {$endif} + begin + Result := (a shl 24) or (b shl 16) or (c shl 8) or d; + end; + + function PLUGIN_CMP_VERSION(verA: LongInt; verB: LongInt): int; + {$ifdef FPC} + inline; + {$endif} + begin + Result := 0; + { could be used to compare for severity of age for positive values, if a 0 then + Result := ErrorValue + else + Result := dbv.bVal; + end; + + function DBGetContactSettingWord(hContact: THandle; + const szModule: PChar; const szSetting: PChar; errorValue: Integer): Integer; + {$ifdef FPC} + inline; + {$endif} + var + dbv: TDBVARIANT; + cgs: TDBCONTACTGETSETTING; + begin + cgs.szModule := szModule; + cgs.szSetting := szSetting; + cgs.pValue := @dbv; + If PluginLink^.CallService(MS_DB_CONTACT_GETSETTING, hContact, lParam(@cgs)) <> 0 then + Result := ErrorValue + else + Result := dbv.wVal; + end; + + function DBGetContactSettingDword(hContact: THandle; + const szModule: PChar; const szSetting: PChar; errorValue: Integer): Integer; + {$ifdef FPC} + inline; + {$endif} + var + dbv: TDBVARIANT; + cgs: TDBCONTACTGETSETTING; + begin + cgs.szModule := szModule; + cgs.szSetting := szSetting; + cgs.pValue := @dbv; + If PluginLink^.CallService(MS_DB_CONTACT_GETSETTING, hContact, lParam(@cgs)) <> 0 then + Result := ErrorValue + else + Result := dbv.dVal; + end; + + function DBGetContactSetting(hContact: THandle; + const szModule: PChar; const szSetting: PChar; dbv: PDBVARIANT): Integer; + {$ifdef FPC} + inline; + {$endif} + var + cgs: TDBCONTACTGETSETTING; + begin + cgs.szModule := szModule; + cgs.szSetting := szSetting; + cgs.pValue := dbv; + Result := PluginLink^.CallService(MS_DB_CONTACT_GETSETTING, hContact, lParam(@cgs)); + end; + + function DBFreeVariant(dbv: PDBVARIANT): Integer; + {$ifdef FPC} + inline; + {$endif} + begin + Result := PluginLink^.CallService(MS_DB_CONTACT_FREEVARIANT, 0, lParam(dbv)); + end; + + function DBDeleteContactSetting(hContact: THandle; const szModule: PChar; const szSetting: PChar): Integer; + {$ifdef FPC} + inline; + {$endif} + var + cgs: TDBCONTACTGETSETTING; + begin + cgs.szModule := szModule; + cgs.szSetting := szSetting; + Result := PluginLink^.CallService(MS_DB_CONTACT_DELETESETTING, hContact, lParam(@cgs)); + end; + + function DBWriteContactSettingByte(hContact: THandle; const szModule: PChar; const szSetting: PChar; val: Byte): Integer; + {$ifdef FPC} + inline; + {$endif} + var + cws: TDBCONTACTWRITESETTING; + begin + cws.szModule := szModule; + cws.szSetting := szSetting; + cws.value.type_ := DBVT_BYTE; + cws.value.bVal := Val; + Result := PluginLink^.CallService(MS_DB_CONTACT_WRITESETTING, hContact, lParam(@cws)); + end; + + function DBWriteContactSettingWord(hContact: THandle; const szModule: PChar; const szSetting: PChar; val: Word): Integer; + {$ifdef FPC} + inline; + {$endif} + var + cws: TDBCONTACTWRITESETTING; + begin + cws.szModule := szModule; + cws.szSetting := szSetting; + cws.value.type_ := DBVT_WORD; + cws.value.wVal := Val; + Result := PluginLink^.CallService(MS_DB_CONTACT_WRITESETTING, hContact, lParam(@cws)); + end; + + function DBWriteContactSettingDWord(hContact: THandle; const szModule: PChar; const szSetting: PChar; val: LongInt): Integer; + {$ifdef FPC} + inline; + {$endif} + var + cws: TDBCONTACTWRITESETTING; + begin + cws.szModule := szModule; + cws.szSetting := szSetting; + cws.value.type_ := DBVT_DWORD; + cws.value.dVal := Val; + Result := PluginLink^.CallService(MS_DB_CONTACT_WRITESETTING, hContact, lParam(@cws)); + end; + + function DBWriteContactSettingString(hContact: THandle; const szModule: PChar; const szSetting: PChar; const val: PChar): Integer; + {$ifdef FPC} + inline; + {$endif} + var + cws: TDBCONTACTWRITESETTING; + begin + cws.szModule := szModule; + cws.szSetting := szSetting; + cws.value.type_ := DBVT_ASCIIZ; + cws.value.pszVal := Val; + Result := PluginLink^.CallService(MS_DB_CONTACT_WRITESETTING, hContact, lParam(@cws)); + end; + + {$endif} + +{$endif} + +{$ifdef M_NETLIB} + + {$ifdef M_API_UNIT} + + function Netlib_CloseHandle(Handle: THandle): int; + + function Netlib_GetBase64DecodedBufferSize(const cchEncoded: int): int; + + function Netlib_GetBase64EncodedBufferSize(const cbDecoded: int): int; + + function Netlib_Send(hConn: THandle; const buf: PChar; len: int; flags: int): int; + + function Netlib_Recv(hConn: THandle; const buf: PChar; len: int; flags: int): int; + + procedure Netlib_Log(hNetLib: THandle; const sz: PChar); + + {$else} + + function Netlib_CloseHandle(Handle: THandle): int; + {$ifdef FPC} + inline; + {$endif} + begin + Result := PluginLink^.CallService(MS_NETLIB_CLOSEHANDLE, Handle, 0); + end; + + function Netlib_GetBase64DecodedBufferSize(const cchEncoded: int): int; + {$ifdef FPC} + inline; + {$endif} + begin + Result := (cchEncoded shr 2) * 3; + end; + + function Netlib_GetBase64EncodedBufferSize(const cbDecoded: int): int; + {$ifdef FPC} + inline; + {$endif} + begin + Result := (cbDecoded * 4+11) div 12*4+1; + end; + + function Netlib_Send(hConn: THandle; const buf: PChar; len: int; flags: int): int; + {$ifdef FPC} + inline; + {$endif} + var + nlb: TNETLIBBUFFER; + begin + nlb.buf := buf; + nlb.len := len; + nlb.flags := flags; + Result := PluginLink^.CallService(MS_NETLIB_SEND, wParam(hConn), lParam(@nlb)); + end; + + function Netlib_Recv(hConn: THandle; const buf: PChar; len: int; flags: int): int; + {$ifdef FPC} + inline; + {$endif} + var + nlb: TNETLIBBUFFER; + begin + nlb.buf := buf; + nlb.len := len; + nlb.flags := flags; + Result := PluginLink^.CallService(MS_NETLIB_RECV, wParam(hConn), lParam(@nlb)); + end; + + procedure Netlib_Log(hNetLib: THandle; const sz: PChar); + {$ifdef FPC} + inline; + {$endif} + begin + PluginLink^.CallService(MS_NETLIB_LOG, hNetLib, lParam(sz)); + end; + + {$endif} + +{$endif} + +{$ifdef M_UTILS} + + {$ifdef M_API_UNIT} + + function WindowList_Add(hList: THandle; hWnd: HWND; hContact: THandle): int; + + function WindowList_Remove(hList: THandle; hWnd: THandle): int; + + function WindowList_Find(hList: THandle; hContact: THandle): int; + + function WindowList_Broadcast(hList: THandle; message: int; wParam: WPARAM; lParam: LPARAM): int; + + function Utils_SaveWindowPosition(hWnd: THandle; hContact: THandle; const szModule, szNamePrefix: PChar): int; + + function Utils_RestoreWindowPosition(hWnd: THandle; hContact: THandle; Flags: int; const szModule, szNamePrefix: PChar): int; + + {$else} + + function WindowList_Add(hList: THandle; hWnd: hWnd; hContact: THandle): int; + var + wle: TWINDOWLISTENTRY; + begin + wle.hList := hList; + wle.hWnd := hWnd; + wle.hContact := hContact; + Result := PluginLink^.CallService(MS_UTILS_ADDTOWINDOWLIST, 0, lParam(@wle)); + end; + + function WindowList_Remove(hList: THandle; hWnd: THandle): int; + begin + Result := PluginLink^.CallService(MS_UTILS_REMOVEFROMWINDOWLIST, hList, hWnd); + end; + + function WindowList_Find(hList: THandle; hContact: THandle): int; + begin + Result := PluginLink^.CallService(MS_UTILS_FINDWINDOWINLIST, hList, hContact); + end; + + function WindowList_Broadcast(hList: THandle; message: int; wParam: WPARAM; lParam: LPARAM): int; + var + msg: TMSG; + begin + msg.message := message; + msg.wParam := wParam; + msg.lParam := lParam; + Result := PluginLink^.CallService(MS_UTILS_BROADCASTTOWINDOWLIST, hList, Integer(@Msg)); + end; + + function Utils_SaveWindowPosition(hWnd: THandle; hContact: THandle; const szModule, szNamePrefix: PChar): int; + var + swp: TSAVEWINDOWPOS; + begin + swp.hWnd := hWnd; + swp.hContact := hContact; + swp.szModule := szModule; + swp.szNamePrefix := szNamePrefix; + Result := PluginLink^.CallService(MS_UTILS_SAVEWINDOWPOSITION, 0, lParam(@swp)); + end; + + function Utils_RestoreWindowPosition(hWnd: THandle; hContact: THandle; Flags: int; const szModule, szNamePrefix: PChar): int; + var + swp: TSAVEWINDOWPOS; + begin + swp.hWnd := hWnd; + swp.hContact := hContact; + swp.szModule := szModule; + swp.szNamePrefix := szNamePrefix; + Result := PluginLink^.CallService(MS_UTILS_RESTOREWINDOWPOSITION, Flags, lParam(@swp)); + end; + + {$endif} + +{$endif} + +{$ifdef M_LANGPACK} + + {$ifdef M_API_UNIT} + + function Translate(sz: PChar): PChar; + + function TranslateString(sz: string): string; + + function TranslateDialogDefault(hwndDlg: THandle): int; + + {$else} + + function Translate(sz: PChar): PChar; + {$ifdef FPC} + inline; + {$endif} + begin + { the return value maybe NULL(0) -- it's upto the caller to know if the allocated + string has to be removed from the DLL heap, this has little to do with Miranda, + but if a dynamic string is passed and a return string is used -- the dynamic + string is lost -- be careful, lazy? use TranslateString (note it's slower) } + Result := PChar(PluginLink^.CallService(MS_LANGPACK_TRANSLATESTRING, 0, lParam(sz))); + end; + + function TranslateString(sz: string): string; + {$ifdef FPC} + inline; + {$endif} + begin + Result := string(PChar( PluginLink^.CallService(MS_LANGPACK_TRANSLATESTRING, 0, lParam(sz)))); + end; + + function TranslateDialogDefault(hwndDlg: THandle): int; + {$ifdef FPC} + inline; + {$endif} + var + lptd: TLANGPACKTRANSLATEDIALOG; + begin + lptd.cbSize := sizeof(lptd); + lptd.flags := 0; + lptd.hwndDlg := hwndDlg; + lptd.ignoreControls := nil; + Result := PluginLink^.CallService(MS_LANGPACK_TRANSLATEDIALOG, 0, lParam(@lptd)); + end; + + {$endif} + +{$endif} + +{$ifdef M_PROTOCOLS} + {$ifdef M_API_UNIT} + + function CallContactService(hContact: THandle; const szProtoService: PChar; wParam: WPARAM; lParam: LPARAM): int; + + function CallProtoService(const szModule, szService: PChar; wParam: WPARAM; lParam: LPARAM): int; + + {$else} + + function CallContactService(hContact: THandle; const szProtoService: PChar; wParam: WPARAM; lParam: LPARAM): int; + {$ifdef FPC} + inline; + {$endif} + var + css: TCCSDATA; + begin + css.hContact := hContact; + css.szProtoService := szProtoService; + css.wParam := wParam; + css.lParam := lParam; + Result := PluginLink^.CallService(MS_PROTO_CALLCONTACTSERVICE, 0, Integer(@css)); + end; + + function CallProtoService(const szModule, szService: PChar; wParam: WPARAM; lParam: LPARAM): int; + {$ifdef FPC} + inline; + {$endif} + var + szStr: array[0..MAXMODULELABELLENGTH] of Char; + begin + strcpy(szStr, szModule); + strcat(szStr, szService); + Result := PluginLink^.CallService(szStr, wParam, lParam); + end; + + {$endif} +{$endif} + +{$ifdef M_PROTOMOD} + {$ifdef M_API_UNIT} + + function ProtoBroadcastAck(const szModule: PChar; hContact: THandle; type_: int; result_: int; hProcess: THandle; lParam: LPARAM): int; + + function CreateProtoServiceFunction(const szModule, szService: PChar; serviceProc: TMIRANDASERVICE): int; + + {$else} + + function ProtoBroadcastAck(const szModule: PChar; hContact: THandle; type_: int; result_: int; hProcess: THandle; lParam: LPARAM): int; + {$ifdef FPC} + inline; + {$endif} + var + ack: TACKDATA; + begin + ack.cbSize := sizeof(TACKDATA); + ack.szModule := szModule; + ack.hContact := hContact; + ack.type_ := type_; + ack.result_ := result_; + ack.hProcess := hProcess; + ack.lParam := lParam; + Result := PluginLink^.CallService(MS_PROTO_BROADCASTACK, 0, Integer(@ack)); + end; + + function CreateProtoServiceFunction(const szModule, szService: PChar; serviceProc: TMIRANDASERVICE): int; + {$ifdef FPC} + inline; + {$endif} + var + szStr: array[0..MAXMODULELABELLENGTH] of Char; + begin + strcpy(szStr, szModule); + strcat(szStr, szService); + Result := PluginLink^.CreateServiceFunction(szStr, @serviceProc); + end; + + {$endif} + +{$endif} + +{$ifdef M_SKIN} + + {$ifdef M_API_UNIT} + + function LoadSkinnedIcon(id: int): THandle; + + function LoadSkinnedProtoIcon(const szProto: PChar; status: int): THandle; + + function SkinAddNewSound(const name, description, defaultFile: PChar): int; + + function SkinPlaySound (const name: PChar): int; + + {$else} + + function LoadSkinnedIcon(id: int): THandle; + {$ifdef FPC} + inline; + {$endif} + begin + Result := PluginLink^.CallService(MS_SKIN_LOADICON, id, 0); + end; + + function LoadSkinnedProtoIcon(const szProto: PChar; status: int): THandle; + {$ifdef FPC} + inline; + {$endif} + begin + Result := PluginLink^.CallService(MS_SKIN_LOADPROTOICON, wParam(szProto), status); + end; + + function SkinAddNewSound(const name, description, defaultFile: PChar): int; + {$ifdef FPC} + inline; + {$endif} + var + ssd: TSKINSOUNDDESC; + begin + ssd.cbSize := sizeof(ssd); + ssd.pszName := name; + ssd.pszDescription := description; + ssd.pszDefaultFile := defaultFile; + Result := PluginLink^.CallService(MS_SKIN_ADDNEWSOUND, 0, lParam(@ssd)); + end; + + function SkinPlaySound (const name: PChar): int; + {$ifdef FPC} + inline; + {$endif} + begin + Result := PluginLink^.CallService(MS_SKIN_PLAYSOUND, 0, lParam(name)); + end; + + {$endif} + +{$endif} diff --git a/plugins/ShlExt/inc/m_history.inc b/plugins/ShlExt/inc/m_history.inc new file mode 100644 index 0000000000..325afad909 --- /dev/null +++ b/plugins/ShlExt/inc/m_history.inc @@ -0,0 +1,37 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) +{$IFNDEF M_HISTORY} +{$DEFINE M_HISTORY} + +const + + { + wParam : HCONTACT + lParam : 0 + Affects: Show's the history dialog box for a contact, see notes + Notes : HCONTACT can be NULL(0) to show system messages + } + MS_HISTORY_SHOWCONTACTHISTORY = 'History/ShowContactHistory'; + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_icq.inc b/plugins/ShlExt/inc/m_icq.inc new file mode 100644 index 0000000000..d359eae928 --- /dev/null +++ b/plugins/ShlExt/inc/m_icq.inc @@ -0,0 +1,191 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_ICQ} +{$DEFINE M_ICQ} + +const + + // extra database event type + ICQEVENTTYPE_WEBPAGER = 2003; + + // extra flags for PSS_MESSAGE + PIMF_ROUTE_DEFAULT = 0; + PIMF_ROUTE_DIRECT = $10000; + PIMF_ROUTE_THRUSERVER = $20000; + PIMF_ROUTE_BESTWAY = $30000; + PIMF_ROUTE_MASK = $30000; + + // for SMS + + ICQACKTYPE_SMS = 1001; + ICQEVENTTYPE_SMS = 2001; // database event type + + // for e-mail express + + { + BLOB: + text: ASCIIZ usually in the form "Subject: %s\r\n%s" + from-name: ASCIIZ + from-e-mail: ASCIIZ + } + + ICQEVENTTYPE_EMAILEXPRESS = 2002; + + // for server side lists, used internally only + + // hProcess=dwSequence, lParam=server's error code, 0 for success + ICQACKTYPE_SERVERCLIST = 1003; + +{$ifndef m_protosvc} + {$include m_protosvc.inc} +{$endif} + +type + + PICQSEARCHRESULT = ^TICQSEARCHRESULT; + TICQSEARCHRESULT = record + hdr: TPROTOSEARCHRESULT; + uin: DWORD; + auth: Byte; + end; + + PICQDETAILSSEARCH = ^TICQDETAILSSEARCH; + TICQDETAILSSEARCH = record + nick: PChar; + firstName: PChar; + lastNamee: PChar; + end; + +const + + { + wParam : 0 + lParam : null terminated string containing e-mail to search + affects: Start a search for all ICQ users by e-mail -- see notes + returns: Returnss a handle to the search on success, NULL(0) on failure + notes : uses the same scheme as PSS_BASICSEARCH, + *DEPRECATED* in favour of PS_SEARCHBYEMAIL + } + MS_ICQ_SEARCHBYEMAIL = 'ICQ/SearchByEmail'; + + { + wParam : 0 + lParam : POinter to a TICQDETAILSSEARCH structure + Affect : Start a search of all ICQ users by details, see notes + Returns: A handle to the search on success, NULL(0) on failure + Notes : Results are returned in the same scheme as in PSS_BASICSEARCH, + Not recommended, use PS_SEARCHBYNAME + } + MS_ICQ_SEARCHBYDETAILS = 'ICQ/SearchByDetails'; + + { + wParam : Pointer to a null terminated string containing phone number + lParam : Pointer to a null terminated string containing the message + Affect : Send an SMS via the ICQ network, See notes + Returns: Handle to the send on success, NULL(0) on failure + Notes : the phone number should be the full number with internation code + and prefixed by + e.g. +44 + } + MS_ICQ_SENDSMS = 'ICQ/SendSMS'; + + { + wParam : level + lParam : null terminated string containing logging message + Affect : a logging message was sent from ICQLib + } + ME_ICQ_LOG = 'ICQ/Log'; + +{$ENDIF} + + {$ifdef __} +//Changing user info: +//See documentation of PS_CHANGEINFO +//The changing user info stuff built into the protocol is purposely extremely +//thin, to the extent that your data is passed as-is to the server without +//verification. Don't mess up. +//Everything is byte-aligned +//WORD: 2 bytes, little-endian (that's x86 order) +//DWORD: 4 bytes, little-endian +//LNTS: a WORD containing the length of the string, followed by the string +// itself. No zero terminator. +#define ICQCHANGEINFO_MAIN 0xEA03 +/* pInfoData points to: + WORD datalen + LNTS nick + LNTS first + LNTS last + LNTS email + LNTS city + LNTS state + LNTS phone + LNTS fax + LNTS street + LNTS cellular (if SMS-able string contains an ending ' SMS') + LNTS zip + WORD country + BYTE gmt + BYTE unknown, usually 0 +*/ +#define ICQCHANGEINFO_MORE 0xFD03 +/* pInfoData points to: + WORD datalen + BYTE age + BYTE 0 + BYTE sex + LNTS homepage + WORD birth-year + BYTE birth-month + BYTE birth-day + BYTE lang1 + BYTE lang2 + BYTE lang3 +*/ +#define ICQCHANGEINFO_ABOUT 0x0604 +/* pInfoData points to: + WORD datalen + LNTS about +*/ +#define ICQCHANGEINFO_WORK 0xF303 +/* pInfoData points to: + WORD datalen + LNTS city + LNTS state + DWORD 0 + LNTS street + LNTS zip + WORD country + LNTS company-name + LNTS company-dept + LNTS company-position + WORD 0 + LNTS company-web +*/ +#define ICQCHANGEINFO_PASSWORD 0x2E04 +/* pInfoData points to: + WORD datalen + LNTS newpassword +*/ + {$endif} + diff --git a/plugins/ShlExt/inc/m_ignore.inc b/plugins/ShlExt/inc/m_ignore.inc new file mode 100644 index 0000000000..e4c9e3c062 --- /dev/null +++ b/plugins/ShlExt/inc/m_ignore.inc @@ -0,0 +1,74 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) +{$IFNDEF M_IGNORE} +{$DEFINE M_IGNORE} + + { this module only provides UI and storage for blocking only, protocol modules + are responsible for implementing the block } + +const + + IGNOREEVENT_ALL = LPARAM(-1); + IGNOREEVENT_MESSAGE = 1; + IGNOREEVENT_URL = 2; + IGNOREEVENT_FILE = 3; + IGNOREEVENT_USERONLINE = 4; + IGNOREEVENT_AUTHORIZATION=5; + IGNOREEVENT_YOUWEREADDED=6; // 0.3.3a+ + + { + wParam : HCONTACT + lParam : IGNOREEVENT_* + Affects: Determines if a message type to a contact should be ignored, see notes + Returns: 0 if the message type MUST be shown [non zero] if it MUST be ignored + Notes : HCONTACT can be NULL(0) to see what to do with a contact + that isn't on the list (or is unknown in some way) + don't use the IGNOREEVENT_ALL type! + Version: v0.1.0.1+ + } + MS_IGNORE_ISIGNORED = 'Ignore/IsIgnored'; + + { + wParam : HCONTACT + lParam : IGNOREEVENT_* constant + Affects: Ignore future messages from a contact, see notes + Returns: 0 on success, [nonzero] on failure + Notes : wParam: NULL(0) can be used to see if an unknown contact should be ignored + or not - you can't SET unknown contact's ignore types, this is to stop + a plugin allowing certain functions (I guess) + Version: v0.1.0.1+ + } + MS_IGNORE_IGNORE = 'Ignore/Ignore'; + + { + wParam : HCONTACT + lParam : IGNOREEVENT_* + Affects: Receive future messages from a contact -- of the given type, see notes + Returns: 0 on success, non zero on failure + Notes : Use NULL(0) for HCONTACT to retrieve the setting for an unknown contact + Version: v0.1.0.1+ + } + MS_IGNORE_UNIGNORE = 'Ignore/Unignore'; + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_langpack.inc b/plugins/ShlExt/inc/m_langpack.inc new file mode 100644 index 0000000000..498f844997 --- /dev/null +++ b/plugins/ShlExt/inc/m_langpack.inc @@ -0,0 +1,82 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_LANGPACK} +{$DEFINE M_LANGPACK} + +const + + { + wParam : 0 + lParam : pointer to a null terminated string + Affects: Returns a pointer to a localised string, if there is no known + translation it will return lParam, the return value does *not* + have to be freed in anyway (if successful) -- see notes + Returns: a pointer to a null terminated string + Notes : No check is done to see if Miranda has the required version + Version: v0.1.1.0+ + } + MS_LANGPACK_TRANSLATESTRING = 'LangPack/TranslateString'; + + { + wParam : 0 + lParam : Pointer to a LANGPACKTRANSLATEDIALOG initialised structure, see notes + Affects: Translates a dialog into the user's local language + Returns: 0 on successs [non zero] on failure + Notes : this service only knows about the following window classes/elements: + Window titles, STATIC, EDIT, Hyperlink, BUTTON. + Version: v0.1.1.0+ + } + +type + + PLANGPACKTRANSLATEDIALOG = ^TLANGPACKTRANSLATEDIALOG; + TLANGPACKTRANSLATEDIALOG = record + cbSize: int; + flags: DWORD; + hwndDlg: THandle; + ignoreControls: ^Integer; // pointer to an array of integers? mebbe? + end; + +const + + { translate all edit controls, by default non-read-only edit controls are not } + LPTDF_NOIGNOREEDIT = 1; + { don't translate the title of the dialog } + LPTDF_NOTITLE = 2; + + MS_LANGPACK_TRANSLATEDIALOG = 'LangPack/TranslateDialog'; + + { + wParam : HMENU handle (WinAPI handle to a menu) + lParam : 0 + Affects: Translates a menu into the user's local language -- see notes + Returns: 0 on success [non zero] on failure + Notes : This doesn't work with owner draw menus that store their + captions in a structure known by the owner -- something to be aware of ;) + version: v0.1.1.0+ + } + MS_LANGPACK_TRANSLATEMENU = 'LangPack/TranslateMenu'; + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_message.inc b/plugins/ShlExt/inc/m_message.inc new file mode 100644 index 0000000000..5cee0040b3 --- /dev/null +++ b/plugins/ShlExt/inc/m_message.inc @@ -0,0 +1,57 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_MESSAGE} +{$DEFINE M_MESSAGE} + +const + + { + wParam : HCONTACT + lParam : Pointer to a null terminated string + Affects: brings up the send message dialog for a contact, see notes + Returns: 0 on success, non zero on failure + Notes : returns immediately, just after the send dialog is shown, + the lParam is entered into the editbox of the window, + but it's not sent. + Version: v0.1.2.0+ only supports a string, prior NULL(0) is expected + this service was defined as 'SRMsg/LaunchMessageWindow' + use both if compatibility use both, the correct one will work, + but don't rely on the message to be displayed + + } + MS_MSG_SENDMESSAGE = 'SRMsg/SendCommand'; + MS_MSG_SENDMESSAGE_OLD = 'SRMsg/LaunchMessageWindow'; + + { + wParam : 0 + lParam : Pointer to a null termed string + Affects: displays the send message dialog with the 'multiple' option open + and no contacts selected + Returns: Returns 0 on success, nonzero on failure + Version: only present after v0.1.2.1+ + } + MS_MSG_FORWARDMESSAGE = 'SRMsg/ForwardMessage'; + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_netlib.inc b/plugins/ShlExt/inc/m_netlib.inc new file mode 100644 index 0000000000..11334c9897 --- /dev/null +++ b/plugins/ShlExt/inc/m_netlib.inc @@ -0,0 +1,713 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_NETLIB} +{$DEFINE M_NETLIB} + +{>>/ + + NetLib : + + Instead of you writing all the code for working with sockets and supporting + app level protocols such as SOCKS5, it's all done for you. + + NetLib takes care of all that and you can even register a special abstract + nexus, e.g. ICQ direct, the user can configure all this from the options dialog + and you don't have to bother with any of it. + + NetLib wraps up any Winsock calls but you can still get the socket handle + from your netlib handle and do stuff. + + It gives all modules an abstract way of dealing with transport -- mainly sockets + and proxies, Now the but.. + + It's new (mmmm) thus unsupported by any older version of Miranda, and if you + want to be lazy and not write any "wrapper" mini netlib then you'll have + the kudos of "only works with nightly build version of Miranda" :) + +/<<} + + {$ifndef M_SYSTEM} + {$include m_system.inc} + {$endif} + +const + + // for TNETLIBUSER.flags + + { bind incoming ports } + NUF_INCOMING = $01; + { makes outgoing plain connections } + NUF_OUTGOING = $02; + { can use HTTP gateway for plain sockets. ???HttpGateway* are valid, + enables the HTTP proxy option, displayed in options } + NUF_HTTPGATEWAY = $04; + { don't show this as an entry for custom settings to be defined for, + TNETLIB.szDescriptiveName is ignored } + NUF_NOOPTIONS = $08; + { some connections are made for HTTP communication, + enables the HTTP proxy option, displayed in options } + NUF_HTTPCONNS = $10; + { Disables the HTTPS proxy option in options, Use this if all communication + is HTTP } + NUF_NOHTTPSOPTION = $20; + + // for TNETLIBUSERSETTINGS.proxyType + + { SOCKS4 -- No DNS or multi addressing mode (proxy side) -- optional username can + be given, no password } + PROXYTYPE_SOCKS4 = 1; + { SOCKS5 -- DNS names can be given as addresses to connect to, optional + plain text username/password scheme (which may cause failure due to denied access) + IP address maybe returned for DNS addresses -- thus server side DNS } + PROXYTYPE_SOCKS5 = 2; + PROXYTYPE_HTTP = 3; + PROXYTYPE_HTTPS = 4; + + // for TNETLIBOPENCONNECTION.flags + + { this connection will be useed for HTTP communications, + if configured for an HTTP(S) proxy the connection is opened as if there + was no proxy } + + NLOCF_HTTP = $0001; + + // for TNETLIBHTTPPROXYINFO.flags + + { append sequence numbers to GET requests } + NLHPIF_USEGETSEQUENCE = $0001; + { append sequence numbers to POST requests } + NLHPIF_USEPOSTSEQUENCE = $0002; + { GET and POST use the same sequence } + NLHPIF_GETPOSTSAMESEQUENCE = $0004; + + // for TNETLIBHTTPREQUEST.flags, .requestType + + { used by MS_NETLIB_RECVHTTPHEADERS returned structure } + + REQUEST_RESPONSE = 0; + REQUEST_GET = 1; + REQUEST_POST = 2; + REQUEST_CONNECT = 3; + + { auto generate a 'host' header from .szUrl } + NLHRF_GENERATEHOST = $00000001; + { remove any host and/or protocol portion of szUrl before sending it } + NLHRF_REMOVEHOST = $00000002; + { removes host and/or protocol from szUrl unless the connection was + opened through an HTTP or HTTPS proxy. } + NLHRF_SMARTREMOVEHOST = $00000004; + { if the connection was opened through an HTTP or HTTPS proxy then + send a Proxy-Authorization header if required. } + NLHRF_SMARTAUTHHEADER = $00000008; + { never dump this to the log } + NLHRF_NODUMP = $00010000; + { don't dump http headers (only useful for POSTs and MS_NETLIB_HTTPTRANSACTION } + NLHRF_NODUMPHEADERS = $00020000; + { this transaction is a proxy communication. For dump filtering only. } + NLHRF_DUMPPROXY = $00040000; + { dump posted and reply data as text. Headers are always dumped as text. } + NLHRF_DUMPASTEXT = $00080000; + + // for TNETLIBBUFFER.flags + + { don't wrap outgoing packet using TNETLIBUSER.pfnHttpGatewayWrapSend } + MSG_NOHTTPGATEWAYWRAP = $010000; + { don't dump this packet to the log } + MSG_NODUMP = $020000; + { this iss proxy communication, for dump filtering only } + MSG_DUMPPROXY = $040000; + { don't dump as hex, it's text } + MSG_DUMPASTEXT = $080000; + { send as raw, bybpass HTTP proxy stuff } + MSG_RAW = $100000; + + + // all record types structures are declared in their own block because the C header + // file used forward declaration (to get typed parameters for certain function pointers) + // This sort of define-type-pointer-before-type can only be done in the same type block + // in D2 (don't know about later versions) + +type + + { forward typed pointers to records } + + PNETLIBOPENCONNECTION = ^TNETLIBOPENCONNECTION; + PNETLIBHTTPREQUEST = ^TNETLIBHTTPREQUEST; + + { This function pointer is to the CRT realloc() used by Miranda -- it allows reallocation of memory passed + to us (not that we could EVER share the same CRT) but to allow DLLs in general to reallocate memory } + TNetlibRealloc = function(Mem: Pointer; size_t: int): Pointer; cdecl; + TNetlibHTTPGatewayInitProc = function(hConn: THandle; nloc: PNETLIBOPENCONNECTION; nlhr: PNETLIBHTTPREQUEST): int; cdecl; + TNetlibHTTPGatewayBeginProc = function(hConn: THandle; nloc: PNETLIBOPENCONNECTION): int; cdecl; + TNetlibHTTPGatewayWrapSendProc = function(hConn: THandle; buf: PByte; len: int; flags: int; pfnNetLibSend: TMIRANDASERVICE): int; cdecl; + TNetlibHTTPGatewayUnwrapRecvProc = function(nlhr: PNETLIBHTTPREQUEST; buf: PByte; len: int; outBufLen: pInt; NetlibRealloc: TNetlibRealloc): PByte; cdecl; + + PNETLIBUSER = ^TNETLIBUSER; + TNETLIBUSER = record + cbSize: int; + { used for DB settings and log, 'NL' stuff } + szSettingsModule: PChar; + { shows a descriptive name for which different proxy settings can be defined } + szDescriptiveName: PChar; + { see NUF_* constants above } + flags: DWORD; + szHttpGatewayHello: PChar; + { can be NULL(0) to send no User-Agent: also used by HTTPS proxies } + szHttpGatewayUserAgent: PChar; + pfnHttpGatewayInit: TNetlibHTTPGatewayInitProc; + { can be NULL(0) if no begin is required } + pfnHttpGatewayBegin: TNetlibHTTPGatewayBeginProc; + { can be NULL(0) if no wrapping is required } + pfnHttpGatewayWrapSend: TNetlibHTTPGatewayWrapSendProc; + { can be NULL(0) " " } + pfnHttpGatewayUnwrapRecv: TNetlibHTTPGatewayUnwrapRecvProc; + { only if NUF_INCOMING, will be used for validation of user input } + minIncomingPorts: int; + end; + + PNETLIBUSERSETTINGS = ^TNETLIBUSERSETTINGS; + TNETLIBUSERSETTINGS = record + { filled before calling } + cbSize: int; + { 1 or 0 } + useProxy: int; + { PROXYTYPE_* constant, see above } + proxyType: int; + { can be NULL(0) } + szProxyServer: PChar; + { in host byte order } + wProxyPort: int; + { 1 or 0, always 0 for SOCKS4 (doesn't have auth) } + useProxyAuth: int; + { can be NULL(0), always used by SOCKS4 } + szProxyAuthUser: PChar; + { can be NULL(0) } + szProxyAuthPassword: PChar; + { 1 or 0, only used by HTTP, HTTPS } + useProxyAuthNtlm: int; + { 1 or 0 } + dnsThroughProxy: int; + { 1 or 0 } + specifyIncomingPorts: int; + { can be NULL(0), form '1024-1050,1060-1070,2000' } + szIncomingPorts: PChar; + end; + + TNetlibNewConnectionProc = procedure(hNewConnection: THandle; dwRemoveIP: DWORD); cdecl; + + PNETLIBBIND = ^TNETLIBBIND; + TNETLIBBIND = record + cbSize: int; + { function to call when there's a new connection, dwRemoteIP is in host byte + order -- the handle is to the new connection } + pfnNewConnection: TNetlibNewConnectionProc; + { set on return, host byte order } + dwInternalIP: DWORD; + { set on return, host byte order } + wPort: WORD; + end; + + { Pointered type is above } + TNETLIBOPENCONNECTION = record + cbSize: int; + szHost: PChar; // can be an IP in string form + wPort: Word; + flags: DWORD; // see NLOCF_* flags + end; + + PNETLIBHTTPPROXYINFO = ^TNETLIBHTTPPROXYINFO; + TNETLIBHTTPPROXYINFO = record + cbSize: int; + { see NLHPIF_* above } + flags: DWORD; + szHttpPostUrl: PChar; + szHttpGetUrl: PChar; + firstGetSequence: int; + firstPostSequence: int; + end; + + PNETLIBBASE64 = ^TNETLIBBASE64; + TNETLIBBASE64 = record + pszEncoded: PChar; + cchEncoded: int; + pbDecoded: PByte; + cbDecoded: int; + end; + + PNETLIBHTTPHEADER = ^TNETLIBHTTPHEADER; + TNETLIBHTTPHEADER = record + szName: PChar; + szValue: PChar; + end; + + { PNETLIBHTTPREQUEST = ^TNETLIBHTTPREQUEST, defined above because this is + forward referenced from there } + TNETLIBHTTPREQUEST = record + cbSize: int; + requestType: int; // REQUEST_* constant + flags: DWORD; + szUrl: PChar; + { doesn't contain Content-Length, it'll be added automatically } + headers: PNETLIBHTTPHEADER; // pointer to an array of em? + headersCount: int; // yes they do + pData: PChar; // data to be sent on POST request + dataLength: int; // must be 0 for REQUEST_GET/REQUEST_CONNECT + resultCode: int; + szResultDescr: PChar; + end; + + PNETLIBBUFFER = ^TNETLIBBUFFER; + TNETLIBBUFFER = record + buf: PChar; + len: int; + { see MSG_* constants above } + flags: int; + end; + + PNETLIBSELECT = ^TNETLIBSELECT; + TNETLIBSELECT = record + cbSize: int; + dwTimeout: DWORD; // in milliseconds, INFINITE is acceptable + hReadConns: array[0..64+1] of THandle; + hWriteConns: array[0..64+1] of THandle; + hExceptConns: array[0..64+1] of THandle; + end; + + PNETLIBPACKETRECVER = ^TNETLIBPACKETRECVER; + TNETLIBPACKETRECVER = record + cbSize: int; + { infinite is allowed -- initialise before use } + dwTimeout: DWORD; + { this many bytes are removed from the start of the buffer, + set to 0 on return -- initialise before use } + bytesUsed: int; + { equal the returnd value by service, unless the return value is 0 (connection closed) } + bytesAvailable: int; + { same as the parameter given to MS_NETLIB_CREATEPACKETRECVER: wParam } + bufferSize: int; + { contains the read data } + buffer: PByte; + end; + +const + + { + wParam : 0 + lParam : Pointer to an initalised TNETLIBUSER structure + Affects: Initialises the netlib for a set of connections, see notes + Returns: Returns a handle for future netlib calls, NULL on failure. + Notes : Netlib is loaded AFTER all plugins, thus a call to this service + in Load() will fail, hook ME_SYSTEM_MODULESLOADED and call it + from there. + - + Netlib will save settings under .szSettings module, all settings + (being?) begin with 'NL'. + - + Defacto settings are the same as combobox entry option + as seen in Miranda->Options->Network + Version: v0.1.2.2+ + Errors : ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY, ERROR_DUP_NAME + } + MS_NETLIB_REGISTERUSER = 'Netlib/RegisterUser'; + + { + wParam : HANDLE + lParam : Pointer to a initalised TNETLIBUSERSETTINGS structure + Affects: Gets the user configured settings for a Netlib user, see notes + Returns: [non zero] on SUCCESS, NULL(0) on failure + Notes : .cbSize must be filled with sizeof() before calling -- + the returned null terminated strings (in the structure) are valid + as long as HANDLE remains open or proxy options are changed + again, do not rely on them being around forever. + Version: v0.1.2.2+ + Errors : ERROR_INVALID_PARAMETER + } + MS_NETLIB_GETUSERSETTINGS = 'Netlib/GetUserSettings'; + + { + wParam : HANDLE + lParam : Pointer to a initalised NETLIBUSERSETTINGS structure + Affect : Changes the configurable settings for a Netlib user -- see notes + Returns: [non zero] on success, NULL(0) on failure + Notes : This service is only really useful for people that specify NUF_NOOPTIONS + when registering and want to create their own options. + Settings will be stored even if the option to enable it, is it not enabled, + e.g. useProxyAuth is 0, szProxyAuthPassword will still be saved + Errors : ERROR_INVALID_PARAMETER + } + MS_NETLIB_SETUSERSETTINGS = 'Netlib/SetUserSettings'; + + { + wParam : HANDLE / SOCKET + lParam : 0 + Affects: Closes a handle, see notes + Returns: Returns [non zero] on success, NULL(0) on failure + Notes : All netlib handles should be closed once they're finished with, + If a SOCKET type is passed instead of netlib handle type, it is closed + Errors : ERROR_INVALID_PARAMETER + } + MS_NETLIB_CLOSEHANDLE = 'Netlib/CloseHandle'; + + { + wParam : HANDLE + lParam : Pointer to a initialised TNETLIBBIND + Affects: Open a port and wait for connections on it -- see notes + Returns: Returns a handle on success, NULL(0) on failure + Notes : this function does the equivalent of socket(), bind(), getsockname(), + listen(), accept() -- internally this function creates a new thread + which waits around in accept() for new connections. + When one is received, TNETLIBBIND.pfnNewConnection is called, + from the context of the NEW thread and then it + returns to waiting for connections. + - + Close the returned handle to end the thread and close the port. + - + Errors : ERROR_INVALID_PARAMETER, any returned by socket(), bind(), listen() + getsockname() + } + MS_NETLIB_BINDPORT = 'Netlib/BindPort'; + + { + wParam : HANDLE + lParam : Pointer to an initalised TNETLIBOPENCONNECTION structure + Affects: Opens a connection -- see notes + Returns: Returns a Handle to a new connection on success, NULL(0) on failure + Notes : internally this service is the equivalent of socket(), gethostbyname(), + connect() + - + If NLOCF_HTTP is set and HANDLE is configured for HTTP(S) proxy + then this function will connect() to that proxy server ONLY, + without performing any initialisation conversation. + - + If HANDLE is configured for an HTTP proxy and does not support + HTTP gateways and you try to open a connection without NLOCF_HTTP + then this service will first attempt to open an HTTPS connection, + if that fails, it will try a direct connection, if *that* fails + then it will return failure with the error + from connect() during the connection attempt + Errors : ERROR_INVALID_PARAMETER, any returned by socket(), gethostbyname(), + connect(), MS_NETLIB_SEND, MS_NETLIB_RECV, select() + - + ERROR_TIMEOUT (during proxy communication) + ERROR_BAD_FORMAT (very invalid proxy reply) + ERROR_ACCESS_DENIED (by proxy) + ERROR_CONNECTION_UNAVAIL (socks proxy can't connect to identd) + ERROR_INVALID_ACCESS (proxy refused identd auth) + ERROR_INVALID_DATA (proxy returned invalid code) + ERROR_INVALID_ID_AUTHORITY (proxy requires use of auth method that's not supported) + ERROR_GEN_FAILURE (socks5/https general failure) + ERROR_CALL_NOT_IMPLEMENTED (socks5 command not supported) + ERROR_INVALID_ADDRESS (socks5 address type not supported) + - + HTTP: anything from TNETLIBUSER.pfnHttpGatewayInit, TNETLIBUSER.pfnHttpGatewayBegin, + MS_NETLIB_SENDHTTPREQUEST or MS_NETLIB_RECVHTTPHEADERS + } + MS_NETLIB_OPENCONNECTION = 'Netlib/OpenConnection'; + + { + wParam : HANDLE + lParam : Pointer to an initialised NETLIBHTTPPROXYINFO structure + Affects: Sets the required information for an HTTP proxy connection -- see notes + Returns: [non zero] on success, NULL(0) on failure + Notes : This service is designed to be called from + within TNETLIBUSER.pfnHttpGatewayInit (see notes in C header under + MS_NETLIB_REGISTERUSER) + Errors : ERROR_INVALID_PARAMETER + } + MS_NETLIB_SETHTTPPROXYINFO = 'Netlib/SetHttpProxyInfo'; + + { + wParam : HANDLE + lParam : 0 + Affects: Get's the SOCKET associated with a handle -- see notes + Returns: the SOCKET on success, INVALID_SOCKET on failure + Notes : The Netlib handle passed to this service should only be passed + if they were returned with MS_NETLIB_OPENCONNECTION or MS_NETLIB_BINDPORT + - + Be careful how you use this socket because you might be connected via an + HTTP proxy, in which case calling send/recv() will break things + - + Errors : ERROR_INVALID_PARAMETER + } + MS_NETLIB_GETSOCKET = 'Netlib/GetSocket'; + + { + wParam : 0 + lParam : Pointer to a null terminated string + Affects: URL-encodes a string for x-www-form-urlencoded (and other uses) -- see notes + Returns: A pointer to a null terminated string, NULL(0) on failure + Notes : The returned string must be freed after it's no longer needed, + to do this Miranda's process heap must be used (under the WINAPI), e.g. + HeapFree(GetProcessHeap(), 0, the_returned_string) + Errors : ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY + } + MS_NETLIB_URLENCODE = 'Netlib/UrlEncode'; + + { + wParam : 0 + lParam : Pointer to a TNETLIBBASE64 initialised structure + Affects: Decodes a Base64 null terminated string, see notes + Returns: [non zero] on success, NULL(0) on failure + Notes : TNETLIBBASE64.pszEncoded and cchEncoded must contain a pointer to + a buffer to use as input, and it's length, the length + should not include space taken for null termination -- + - + Output is placed in ..pbDecoded and ..cbDecoded for buffer and + length of buffer -- the maxiumum output for a given input can + be worked out with Netlib_GetBase64DecodedBufferSize() function + see below. + - + For more information on Base64 see rfc-1421. + Errors : ERROR_INVALID_PARAMETER, ERROR_INVALID_DATA, ERROR_BUFFER_OVERFLOW + } + MS_NETLIB_BASE64DECODE = 'Netlib/Base64Decode'; + + { + wParam : 0 + lParam : Pointer to an initialised TNETLIBBASE64 structure + Affect : Base64 encode a string, see notes + Returns: [non zero] on success, NULL(0) on failure + Notes : TNETLIBBASE64.pbDecode and TNETLIBBASE64.cbDecoded contain + the input buffer and it's length -- + TNETLIBBASE64.pszEncoded and TNETLIBBASE64.cchEncoded contain the + buffer in which to put the output and it's length. + - + The maximum output size for a given input can be worked + out with the function Netlib_GetBase64EncodedBufferSize() below + .pszEncoded is null terminated, on return TNETLIBBASE64.cchEncoded + is set to the actual length excluding 0. + Errors : ERROR_INVALID_PARAMETER, ERROR_BUFFER_OVERFLOW + } + MS_NETLIB_BASE64ENCODE = 'Netlib/Base64Encode'; + + { + wParam : HANDLE + lParam : Pointer to a initialised TNETLIBHTTPREQUEST structure + Affect : Send an HTTP request over a connection, see notes + Returns: The number of bytes on success, SOCKET_ERROR on failure + Notes : HANDLE must of been returned by MS_NETLIB_OPENCONNECTION,, + If you use NLHRF_SMARTAUTHHEADER and NTLM auth is in use then + full NTLM auth transcation occurs, comprising sending the + domain, getting the challenge, sending the response. + NETLIBHTTPREQUEST.resultCode and NETLIBHTTPREQUEST.szResultDescr are + ignored by this service. + Errors : ERROR_INVALID_PARAMETER, MS_NETLIB_SEND (return codes) + } + MS_NETLIB_SENDHTTPREQUEST = 'Netlib/SendHttpRequest'; + + { + wParam : HANDLE + lParam : 0 + Affect : Receive HTTP headers, see notes + Returns: A pointer to a TNETLIBHTTPREQUEST structure on success, NULL(0) on failure + Notes : The returned pointer must be freed after it's done with + use MS_NETLIB_FREEHTTPREQUESTSTRUCT. + - + HANDLE must be returned by MS_NETLIB_OPENCONNECTION + - + Return^.pData=NIL and Return^.dataLength=0 always + - + The returned data should be retrieved using MS_NETLIB_RECV once + the headers have been parsed. + If headers haven't finished within 60 seconds the function returns + NULL(0) and ERROR_TIMEOUT + Errors : ERROR_INVALID_PARAMETER, any MS_NETLIB_RECV or select() + ERROR_HANDLE_EOF (connection closed bfore headers complete) + ERROR_TIMEOUT (headers still not complete after 60 seconds) + ERROR_BAD_FORMAT (invalid character or line ending in headers, or first line is blank) + ERROR_BUFFER_OVERFLOW (each header line must be less than 4096 chars long) + ERROR_INVALID_DATA (first header line is malformed ("http/[01].[0-9] [0-9]+ .*", or no colon in subsequent line) + + } + MS_NETLIB_RECVHTTPHEADERS = 'Netlib/RecvHttpHeaders'; + + { + wParam : 0 + lParam : Pointer returned by MS_NETLIB_RECVHTTPHEADERS to free + Affect : Free the memory used by a TNETLIBHTTPREQUEST structure, see notes + Returns: [non zero] on success, NULL(0) on failure + Notes : This service should only be used with memory pointers returned + by either MS_NETLIB_RECVHTTPHEADERS or MS_NETLIB_HTTPTRANSACTION!. + Errors : ERROR_INVALID_PARAMETER + + } + MS_NETLIB_FREEHTTPREQUESTSTRUCT = 'Netlib/FreeHttpRequestStruct'; + + { + wParam : HANDLE + lParam : Pointer to a TNETLIBHTTPREQUEST structure + Affect : Carry out an entire HTTP transaction, see notes + Returns: another pointer to a TNETLIBHTTPREQUEST structure or NULL(0) + on failure + Notes : The returned pointer must be freed at some point + with MS_NETLIB_FREEHTTPREQUESTSTRUCT, + - + TNETLIBHTTPREQUEST.szUrl should have a full HTTP URL, if it + does not start with http://, that will be assumed, but do not + take this assumption to stay assumed (heh..) in the future + - + this service equivalent of open(), sendhttp(), getheaders() + netlib_recv(), netlib_closehandle() + - + TNETLIBHTTPREQUEST.headers will be added to with the following + headers if they're not already present : + "Host" (even if it is requested in .flags) + "User-Agent" (in form : 'Miranda/d.d.d.d <(status of release)>') + "Content-Length" (for POSTs only, set to TNETLIBHTTPREQUEST.dataLength) + + If you don't want to send any of these headers -- + set TNETLIBHTTPREQUEST.headers to NULL(0) + - + In the returned pointer, pData[dataLen] is always 0 for 'safety' + also : headers, headersCount, pData, dataLength, resultCode and + szResultDescr are all valid + - + Also take care not to assume that a returned pointer means that + at the HTTP level it all worked out -- refer to the resultCode for + 2xx before doing anything else + - + Errors : ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY + Errors returned by the aforementioned internally used functions + } + MS_NETLIB_HTTPTRANSACTION = 'Netlib/HttpTransaction'; + + { + wParam : HANDLE + lParam : Pointer to an initialised TNETLIBBUFFER structure + Affect : Send data over an open connection see notes + Returns: The number of bytes sent on success, SOCKET_ERROR on failure + Notes : see Netlib_Send() helper function + Errors : ERROR_INVALID_PARAMETER, + anything from socket(), connect() + send(), TNETLIBUSER.pfnHttpGatewayWrapSend(), + (HTTP proxy): ERROR_GEN_FAILURE (http result code wasn't 2xx) + MS_NETLIB_SENDHTTPREQUEST, MS_NETLIB_RECVHTTPHEADERS + } + MS_NETLIB_SEND = 'Netlib/Send'; + + { + wParam : HANDLE + lParam : Pointer to an initialised TNETLIBBUFFER structure + Affect : Receive data over a connection, see notes + Returns: The number of bytes read on success, SOCKET_ERROR on failure + Notes : + This service uses some of the same flags as MS_NETLIB_SEND : + MSG_PEEK, + MSG_NODUMP, + MSG_DUMPPROXY, + MSG_NOHTTPGATEWAYWRAP, + MSG_DUMPASTEXT, + MSG_RAW + - + On using MSG_NOHTTPGATEWAYWRAP: Because packets through an HTTP proxy are + batched and cached and stuff, using this flag is not a guarantee that it + will be obeyed, and if it is it may even be propogated to future calls + even if you don't specify it then. Because of this, the flag should be + considered an all-or-nothing thing: either use it for the entire duration + of a connection, or not at all. + Errors : ERROR_INVALID_PARAMETER, anything from recv() + (HTTP proxy): + ERROR_GEN_FAILURE (http result code wasn't 2xx) + ERROR_INVALID_DATA (no Content-Length header in reply) + ERROR_NOT_ENOUGH_MEMORY (Content-Length very large) + ERROR_HANDLE_EOF (connection closed before Content-Length bytes recved) + anything from select(), + MS_NETLIB_RECVHTTPHEADERS, nlu.pfnHttpGatewayUnwrapRecv, socket(), + connect(), MS_NETLIB_SENDHTTPREQUEST + + } + MS_NETLIB_RECV = 'Netlib/Recv'; + + { + wParam : 0 + lParam : Pointer to an initialised TNETLIBSELECT structure + Affect : Determine the status of one or more connections, see notes + Returns: The numbe of ready connections, SOCKET_ERROR on failure + Notes : All handles passed to this service must have been returned + either by MS_NETLIB_OPENCONNECTION or MS_NETLIB_BINDPORT, + the last handle in each list must be followed by either NULL + or INVALID_HANDLE_VALUE. + Errors : ERROR_INVALID_HANDLE, ERROR_INVALID_DATA, anything from select() + } + MS_NETLIB_SELECT = 'Netlib/Select'; + + { + wParam : HANDLE + lParam : maxPacketSize + Affect : Create a packet receiver, see notes + Returns: A handle on success, NULL(0) on failure + Notes : The packet receiver implements the common situation where + you have a variable length of packets coming thru over a connection + and you want them split up in order to handle them. + - + The major limiation is, that the buffer is created in memory, + so you can't have arbitrarily large packets + Errors : ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY + } + MS_NETLIB_CREATEPACKETRECVER = 'Netlib/CreatePacketRecver'; + + { + wParam : Handle returned by MS_NETLIB_CREATEPACKETRECVER + lParam : Pointer to an initialised TNETLIBPACKETRECVER + Returns: The total number of bytes available in the buffer, NULL(0) + if the connection was closed or SOCKET_ERROR. + - + If TNETLIBPACKETRECVER.bytesUsed is set to zero and the + buffer is already full up to the maxPacketSize, it is assumed + that a too large packet has been received, All data in + the buffer is discarded and receiving has started anew. + - + This will probably cause alignment problem so if you think + that tis iss likely to happen, then you should deal with it + yourself. + - + Closing the packet receiver will not close the associated + connection but will discard any bytes still in the buffer, + so if you intend to carry on reading from that connection, + make sure you have processed the buffer first. + - + This service is equivalent of memmove() to remove + the first bytesUsed from the buffer, select(), if dwTimeOut + is not INFINITE, then MS_NETLIB_RECV + Errors : ERROR_INVALID_PARAMETER, ERROR_TIMEOUT, anything from select(), + MS_NETLIB_RECV + } + MS_NETLIB_GETMOREPACKETS = 'Netlib/GetMorePackets'; + + { + wParam : HANDLE + lParam : Pointer to null terminated string to uh, log. + Affect : Add a message to the log (if it's running) see notes + Returns: non zeror on success, NULL(0) on failure + Notes : Don't include \r\n or #13#10 it's not needed, + - + Doesn't support formatting like the given C code for + Netlib_Logf, just use FmtStr() and then call this service + if you want that. + Errors : ERROR_INVALID_PARAMETER + } + MS_NETLIB_LOG = 'Netlib/Log'; + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_options.inc b/plugins/ShlExt/inc/m_options.inc new file mode 100644 index 0000000000..6a011fecdc --- /dev/null +++ b/plugins/ShlExt/inc/m_options.inc @@ -0,0 +1,109 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_OPTIONS} +{$DEFINE M_OPTIONS} + +const + + { + wParam : addinfo + lParam : 0 + Affects: The user opened the options dialog, see notes + Notes : Modules should do whatever initalisation they need and call + MS_OPT_ADDPAGE with the wParam -- MS_OPT_ADDPAGE + can be called one or more times + if more than one page wants to be displayed. + } + ME_OPT_INITIALISE = 'Opt/Initialise'; + + { + wParam : wParam from ME_OPT_INITIALISE + lParam : Pointer to an initialised TOPTIONSDIALOGPAGE + Affects: Adds a page to the options dialog, see notes + Notes : Strings in the structure can be released as soon as the + service returns -- but icons must be kept around, this iss + not a problem if you're loading theem from a resource. + - + This service should only be called within the ME_OPT_INITIALISE + event hook. + - + Pages in the options dialog operate just like pages in property + sheets, See the WinAPI documentation for details on how they operate. + Version: Prior to v0.1.2.1 the options dialog would resize + to fit the largest page, but since then it's a fixed size + The largest page that fits neatly is 314x240 DLU's + - + Some of OPTIONSDIALOGPAGE's fields are version dependant. + } + MS_OPT_ADDPAGE = 'Opt/AddPage'; + + { defacto size } + + OPTIONSDIALOGPAGE_V0100_SIZE = $18; + OPTIONSDIALOGPAGE_V0120_SIZE = $28; + + { page is only shown when in 'simple' mode } + ODPF_SIMPLEONLY = 1; + { page is only shown when in 'expert' mode } + ODPF_EXPERTONLY = 2; + { give group box titles a bold font } + ODPF_BOLDGROUPS = 4; + +type + + POPTIONSDIALOGPAGE = ^TOPTIONSDIALOGPAGE; + TOPTIONSDIALOGPAGE = record + cbSize: int; + position: int; // position number, lower numbers are top most + pszTitle: PChar; + pfnDlgProc: Pointer; // DLGPROC prototype + pszTemplate: PChar; + hInstance: THandle; + hIcon: THandle; // v0.1.0.1+ + pszGroup: PChar; // v0.1.0.1+ + groupPosition: int; // v0.1.0.1+ + hGroupIcon: THandle; // v0.1.0.1+ + flags: DWORD; // v0.1.2.1+ + { if in simple mode the dialog will be cut off AFTER this control ID, 0 + for disable } + nIDBottomSimpleControl: int; // v0.1.2.1+ + { if in simple mode the dialog will cut off AFTER this control ID, 0 to disable } + nIDRightSimpleControl: int; // v0.1.2.1+ + { these controls will be hidden in simple mode, pointer to an array of ID's + must remain valid for the duration of the dialog } + expertOnlyControls: ^int; + nExpertOnlyControls: int; // v0.1.2.1+ + end; + +const + + { sent to pages via WM_NOTIFY when the expert checkbox is clicked, lParam = new state } + PSN_EXPERTCHANGED = 2; + { returns true/false } + PSM_ISEXPERT = ($0400 + 101); + { returns HFONT used for group box titles } + PSM_GETBOLDFONT = ($0400 + 102); + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_plugins.inc b/plugins/ShlExt/inc/m_plugins.inc new file mode 100644 index 0000000000..72d5ff69a3 --- /dev/null +++ b/plugins/ShlExt/inc/m_plugins.inc @@ -0,0 +1,70 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_PLUGINS} +{$DEFINE M_PLUGINS} + +const + + DEFMOD_PROTOCOLICQ = 1; // removed from v0.3.0.0 alpha + DEFMOD_PROTOCOLMSN = 2; // removed from v0.1.2.0+ + DEFMOD_UIFINDADD = 3; + DEFMOD_UIUSERINFO = 4; + DEFMOD_SRMESSAGE = 5; + DEFMOD_SRURL = 6; + DEFMOD_SREMAIL = 7; + DEFMOD_SRAUTH = 8; + DEFMOD_SRFILE = 9; + DEFMOD_UIHELP = 10; + DEFMOD_UIHISTORY = 11; + DEFMOD_RNDCHECKUPD = 12; + DEFMOD_RNDICQIMPORT = 13; // not built in to v0.1.0.1+ + DEFMOD_RNDAUTOAWAY = 14; + DEFMOD_RNDUSERONLINE = 15; + DEFMOD_RNDCRYPT = 16; // v0.1.0.1-v0.1.2.0 + DEFMOD_SRAWAY = 17; // v0.1.0.1+ + DEFMOD_RNDIGNORE = 18; // v0.1.0.1+ + DEFMOD_UIVISIBILITY = 19; // v0.1.1.0+, options page only + DEFMOD_UICLUI = 20; // v0.1.1.0+ + DEFMOD_UIPLUGINOPTS = 21; // v0.1.2.1+ + DEFMOD_PROTOCOLNETLIB = 22; // v0.1.2.2+ + + DEFMOD_HIGHEST = 22; + + + + { + wParam : 0 + lParam : 0 + Affect : Gets an array of modules that the plugins report they want to replace + Returns: Returns a pointer to an array of ints, with elements 1 or 0, + indexed by the DEFMOD_* constants, 1 is to mark that the default + module shouldn't be loaded, see notes + Notes : this is primarily for use by the core's module initialiser, + but could also be used by modules that are doing + naughty things that are very feature-dependent. + } + MS_PLUGINS_GETDISABLEDEFAULTARRAY = 'Plugins/GetDisableDefaultArray'; + +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_popup.inc b/plugins/ShlExt/inc/m_popup.inc new file mode 100644 index 0000000000..f8d2ea9df9 --- /dev/null +++ b/plugins/ShlExt/inc/m_popup.inc @@ -0,0 +1,222 @@ +(* +=============================================================================== + PopUp plugin +Plugin Name: PopUp +Plugin author: hrk, Luca Santarelli, hrk@users.sourceforge.net +This file has been created by egodust, Sam, egodust@users.sourceforge.net +=============================================================================== + +The purpose of this plugin is to give developers a common "platform/interface" to show PopUps. It is born from the source code of NewStatusNotify, another plugin I've made. + +Remember that users *must* have this plugin enabled, or they won't get any popup. Write this in the requirements, do whatever you wish ;-)... but tell them! +=============================================================================== + +-- To use this file you need Windows.pas, m_globaldefs.pas (get it from the CVS under the 'inc' module) +-- To include this in the source, use {$include m_popup.h} + +*) + +{$ifndef M_POPUP_H} +{$define M_POPUP_H} + +{$ifdef FPC} + {$PACKRECORDS C} + {$MODE Delphi} +{$endif} + +const + + MAX_CONTACTNAME = 2048; + MAX_SECONDLINE = 2048; + + SM_WARNING = $01; //Triangle icon. + SM_NOTIFY = $02; //Exclamation mark icon. + +type + + // for info on what this stuff is, see m_popup.h + + PPOPUPDATA = ^TPOPUPDATA; + TPOPUPDATA = record + lchContact: HCONTACT; + lchIcon: THandle; + lpszContactName: array[0..MAX_CONTACTNAME-1] of Char; + lpszText: array[0..MAX_SECONDLINE-1] of Char; + colorBack: COLORREF; + colorForeText: COLORREF; + PluginWindowProc: Pointer; // must be a window procedure using stdcall + PluginData: Pointer; + end; + +type + + // for info on what this stuff is, see m_popup.h + + PPOPUPDATAEX = ^TPOPUPDATAEX; + TPOPUPDATAEX = record + lchContact: HCONTACT; + lchIcon: THandle; + lpszContactName: array[0..MAX_CONTACTNAME-1] of Char; + lpszText: array[0..MAX_SECONDLINE-1] of Char; + colorBack: COLORREF; + colorForeText: COLORREF; + PluginWindowProc: Pointer; // must be a window procedure using stdcall + PluginData: Pointer; + iSeconds: int; //Custom delay time in seconds. -1 means "forever", 0 means "default time". + cZero: array[0..15] of Char; //16 unused bytes which may come useful in the future. + end; + +const + +(* + Creates, adds and shows a popup, given a (valid) POPUPDATA structure pointer. + wParam = (WPARAM)(*POPUPDATA)PopUpDataAddress + lParam = 0 + Returns: > 0 on success, 0 if creation went bad, -1 if the PopUpData contained unacceptable values. + NOTE: it returns -1 if the PopUpData was not valid, if there were already too many popups, if the module was disabled. + Otherwise, it can return anything else... +*) + + MS_POPUP_ADDPOPUP = 'PopUp/AddPopUp'; + +(* + The same, but with a POPUPDATAEX structure pointer. + wParam = (WPARAM)(*POPUPDATAEX)PopUpDataExAddress + lParam = 0 +*) + + MS_POPUP_ADDPOPUPEX = 'PopUp/AddPopUpEx'; + +(* + Returns the handle to the contact associated to the specified PopUpWindow. + You will probably need to know this handle inside your WNDPROC. Exampole: you want to open the MessageWindow. :-) + Call MS_POPUP_GETCONTACT on the hWnd you were given in the WNDPROC. + wParam = (WPARAM)(HWND)hPopUpWindow + lParam = 0; + Returns: the HANDLE of the contact. Can return NULL, meaning it's the main contact. -1 means failure. +*) + + MS_POPUP_GETCONTACT = 'PopUp/GetContact'; + +(* + wParam = hPopUpWindow + lParam = PluginDataAddress; + Returns: the address of the PLUGINDATA structure. Can return NULL, meaning nothing was given. -1 means failure. + IMPORTANT NOTE: it doesn't seem to work if you do: + CallService(..., (LPARAM)aPointerToAStruct); + and then use that struct. + Do this, instead: + aPointerToStruct = CallService(..., (LPARAM)aPointerToAStruct); + and it will work. Just look at the example I've written above (PopUpDlgProc). +*) + MS_POPUP_GETPLUGINDATA = 'PopUp/GetPluginData'; + +(* + wParam = 0 + lParam = 0 + Returns: 0 if the user has chosen not to have the second line, 1 if he choose to have the second line. +*) + MS_POPUP_ISSECONDLINESHOWN = 'PopUp/IsSecondLineShown'; + +(* + UM_FREEPLUGINDATA + wParam = lParam = 0. Process this message if you have allocated your own memory. (i.e.: POPUPDATA.PluginData != NULL) +*) + UM_FREEPLUGINDATA = ((*WM_USER*)$400 + $200); + +(* + UM_DESTROYPOPUP + wParam = lParam = 0. Send this message when you want to destroy the popup, or use the function below. +*) + UM_DESTROYPOPUP = ((*WM_USER*)$400 + $201); + +(* + UM_INITPOPUP + wParam = (WPARAM)(HWND)hPopUpWindow (but this is useless, since I'll directly send it to your hPopUpWindow + lParam = 0. + This message is sent to the PopUp when its creation has been finished, so POPUPDATA (and thus your PluginData) is reachable. + Catch it if you needed to catch WM_CREATE or WM_INITDIALOG, which you'll never ever get in your entire popup-life. + Return value: if you process this message, return 0. If you don't process it, return 0. Do whatever you like ;-) +*) + UM_INITPOPUP = ($400(*WM_USER*) + $202); + +(* + wParam = hPopUpWindow + lParam = lpzNewText + returns: > 0 for success, -1 for failure, 0 if the failure is due to second line not being shown. (but you could call PUIsSecondLineShown() before changing the text...) + Changes the text displayed in the second line of the popup. +*) + MS_POPUP_CHANGETEXT = 'PopUp/Changetext'; + +(* + This is mainly for developers. + Shows a warning message in a PopUp. It's useful if you need a "MessageBox" like function, but you don't want a modal window (which will interfere with a DialogProcedure. MessageBox steals focus and control, this one not. + wParam = lpzMessage + lParam = 0; Returns: 0 if the popup was shown, -1 in case of failure. +*) + MS_POPUP_SHOWMESSAGE = 'PopUp/ShowMessage'; + + + (* helper functions, will be inlined on FPC if you have the swithces enabled *) + + function PUAddPopup(ppdp: PPOPUPDATA): int; + {$ifdef FPC} + inline; + {$endif} + begin + Result := CallService(MS_POPUP_ADDPOPUP, WPARAM(ppdp), 0); + end; + + function PUGetContact(hPopUpWindow: THandle): THandle; + {$ifdef FPC} + inline; + {$endif} + begin + Result := CallService(MS_POPUP_GETCONTACT, WPARAM(hPopUpWindow), 0); + end; + + function PUGetPluginData(hPopUpWindow: THandle): Pointer; + {$ifdef FPC} + inline; + {$endif} + var + dummy: pointer; + begin + dummy := nil; + Int(Result) := CallService(MS_POPUP_GETPLUGINDATA, WPARAM(hPopUpWindow), LPARAM(dummy)); + end; + + function PUIsSecondLineShown: BOOL; + {$ifdef FPC} + inline; + {$endif} + begin + Int(Result) := CallService(MS_POPUP_ISSECONDLINESHOWN, 0, 0); + end; + + function PUDeletePopUp(hWndPopUp: THandle): int; + {$ifdef FPC} + inline; + {$endif} + begin + Result := SendMessage(hWndPopUp, UM_DESTROYPOPUP, 0, 0); + end; + + function PUChangeText(hWndPopUp: THandle; lpzNewText: PChar): int; + {$ifdef FPC} + inline; + {$endif} + begin + Result := CallService(MS_POPUP_CHANGETEXT, WPARAM(hWndPopUp), LPARAM(lpzNewText)); + end; + + function PUShowMessage(lpzText: PChar; kind: Byte): int; + {$ifdef FPC} + inline; + {$endif} + begin + Result := CallService(MS_POPUP_SHOWMESSAGE, WPARAM(lpzText), LPARAM(kind)); + end; + +{$endif} + diff --git a/plugins/ShlExt/inc/m_protocols.inc b/plugins/ShlExt/inc/m_protocols.inc new file mode 100644 index 0000000000..90bd12366b --- /dev/null +++ b/plugins/ShlExt/inc/m_protocols.inc @@ -0,0 +1,180 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_PROTOCOLS} +{$DEFINE M_PROTOCOLS} + +const + + ACKTYPE_MESSAGE = 0; + ACKTYPE_URL = 1; + ACKTYPE_FILE = 2; + ACKTYPE_CHAT = 3; + ACKTYPE_AWAYMSG = 4; + ACKTYPE_AUTHREQ = 5; + ACKTYPE_ADDED = 6; + ACKTYPE_GETINFO = 7; + ACKTYPE_SETINFO = 8; + ACKTYPE_LOGIN = 9; + ACKTYPE_SEARCH = 10; + ACKTYPE_NEWUSER = 11; + ACKTYPE_STATUS = 12; + ACKTYPE_CONTACTS = 13; //send/recv of contacts + + ACKRESULT_SUCCESS = 0; + ACKRESULT_FAILED = 1; + //'in progress' result codes: + ACKRESULT_CONNECTING = 100; + ACKRESULT_CONNECTED = 101; + ACKRESULT_INITIALISING = 102; + ACKRESULT_SENTREQUEST = 103; // waiting for reply... + ACKRESULT_DATA = 104; // blob of file data sent/recved, or search result + ACKRESULT_NEXTFILE = 105; // file transfer went to next file + ACKRESULT_FILERESUME = 106; // a file is about to be received, see PS_FILERESUME + ACKRESULT_DENIED = 107; // a file send has been denied (0.3a + only) + + // for PROTOCOLDESCRIPTOR.type + + PROTOTYPE_PROTOCOL = 1000; + PROTOTYPE_ENCRYPTION = 2000; + PROTOTYPE_FILTER = 3000; + PROTOTYPE_TRANSLATION = 4000; + PROTOTYPE_OTHER = 10000;//avoid using this if at all possible + +type + + PCCSDATA = ^TCCSDATA; + TCCSDATA = record + hContact: THandle; + szProtoService: PChar; // a PS_* constant + wParam: WPARAM; + lParam: LPARAM; + end; + + PACKDATA = ^TACKDATA; + TACKDATA = record + cbSize: int; + szModule: PChar; // the name of the protocol module which initiated this ack + hContact: THandle; + type_: int; // an ACKTYPE_* constant + result_: int; // an ACKRESULT_* constant + hProcess: THandle; // caller defined seq, I mean process code + lParam: LPARAM; // caller defined data + end; + + // when type=ACKTYPE_FILE and (result=ACKRESULT_DATA or result=ACKRESULT_FILERESUME) + + PPROTOFILETRANSFERSTATUS = ^TPROTOFILETRANSFERSTATUS; + TPROTOFILETRANSFERSTATUS = record + cbSize: int; + hContact: THandle; + sending: int; // true if sending, false if receiving + files: PChar; // pointer to an array of pchar's + totalFiles: int; + currentFileNumber: int; + totalBytes: LongInt; + totalProgress: LongInt; + workingDir: PChar; + currentFile: PChar; + currentFileSize: LongInt; + currentFileProgress: LongInt; + currentFileTime: LongInt; // UNIX time + end; + + // for registering a protocol, enumeration + + PPROTOCOLDESCRIPTOR = ^TPROTOCOLDESCRIPTOR; + TPROTOCOLDESCRIPTOR = record + cbSize: int; + szName: PChar; // unique name of module + type_: int; // a PROTOTYPE_* constant + end; + +const + + { + wParam : 0 + lParam : Pointer to an initalised CSSDATA structure + Affect : Send a general request thru the protocol chain for a contact + Return : the return value documented in the PS_* def (m_protosvc.inc) + } + MS_PROTO_CALLCONTACTSERVICE = 'Proto/CallContactService'; + + { + wParam : 0 + lParam : Pointer to an initalised TACKDATA structure + Affect : a general 'ack', see notes + Notes : Just because defs are here doesn't mean they will be sent + read the docs for the function you are calling to see what + replies you will get. + } + ME_PROTO_ACK = 'Proto/Ack'; + + { + wParam : pointer to an int to store number of protocols + lParam : Pointer to an an array of PPROTOCOLDESCRIPTOR pointers + Affect : Enumerate the currently running protocols, see notes + Returns: 0 on success, [non zero] on failure + Notes : Neither wParam/lParam maybe NULL(0), the list returned by + this service is the protocol modules currently installed + and running, it is not a complete list of protocols that have + ever been installed. + - + A protocol module does not have to be a protocol running thru + the internet, it can be a vast number of things + } + MS_PROTO_ENUMPROTOCOLS = 'Proto/EnumProtocols'; + + { + wParam : 0 + lParam : Pointer to null terminated string containing protocol name + Affect : Determines if a protocol is running or not. + Returns: A pointer to the PPROTOCOLDESCRIPTOR if the protocol is loaded + or NULL(0) if it isn't + } + MS_PROTO_ISPROTOCOLLOADED = 'Proto/IsProtocolLoaded'; + + { + wParam : HCONTACT + lParam : Pointer to a null terminated string containing a name + Affect : Determine whether the given contact has the given protocol + in it's chain. + Returns : 0 if the protocol isn't in the chain, [non zero] if it is + } + MS_PROTO_ISPROTOONCONTACT = 'Proto/IsProtoOnContact'; + + { + wParam : HCONTACT + lParam : 0 + Affect : Gets the network-level protocol associated with a contact + Returns: a PChar pointing to the ASCIIZ name of the protocol or NULL(0) + if the contact has no protocol, There's no need to dispsose + the returned string. + - + This is the name of the module that actually accesses the network + for that contact. + } + MS_PROTO_GETCONTACTBASEPROTO = 'Proto/GetContactBaseProto'; + +{$ENDIF} \ No newline at end of file diff --git a/plugins/ShlExt/inc/m_protomod.inc b/plugins/ShlExt/inc/m_protomod.inc new file mode 100644 index 0000000000..8bf245316c --- /dev/null +++ b/plugins/ShlExt/inc/m_protomod.inc @@ -0,0 +1,105 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_PROTOMOD} +{$DEFINE M_PROTOMOD} + + {$ifndef M_PROTOCOLS} + {$include m_protocols.inc} + {$endif} + +const + + { + wParam : 0 + lParam : Pointer to a initalised TPROTOCOLDESCRIPTOR structure + Affect : Register a protocol module, see notes + Returns: 0 on success, [non zero] on failure + Notes : This service MUST be called from your module's Load() function + TPROTOCOLDESCRIPTOR.type can be a value other than PROTOTYPE_* + which are used to provide a more precise positioning information + for the contact protocol lists. + - + Relative values to the constants can be given, but this MUST NOT + be done for PROTOTYPE_PROTOCOL. + } + MS_PROTO_REGISTERMODULE = 'Proto/RegisterModule'; + + { + wParam : HCONTACT + lParam : protocol_name_string + Affect : Add the given protocol module to the chain for a contact, see notes + Returns: 0 success, [non zero] on failure + Notes : The module is added to the correct positioning according to it's + registered type. + } + MS_PROTO_ADDTOCONTACT = 'Proto/AddToContact'; + + { + wParam : HCONTACT + lParam : protocol_name_string + Affect : Remove the given protocol name from the chain for the given contact + Returns: 0 on success, [non zero] on failure + } + MS_PROTO_REMOVEFROMCONTACT = 'Proto/RemoveFromContact'; + + { see m_globaldefs.pas for CreateProtoServiceFunction } + + { + wParam : wParam [arg] + lParam : lParam [arg] + Affect : Call the next service in the chain for the send operation, see notes + Return : Return value should be returned by CallService(MS_PROTO_CHAINSEND,wParam,lParam) + Notes : wParam MUST remain untouched, lParam is a pointer to a CSSDATA structure + and can be modified or copid if needed. + wParam and lParam should be the values passed to your service, + typically your service should return ASAP. + } + MS_PROTO_CHAINSEND = 'Proto/ChainSend'; + + { + wParam : wParam [arg] + lParam : lParam [arg] + Affect : Call the next service in the chain in this receive operation, see notes + Return : Return value should be returned by CallService(MS_PROTO_CHAINRECV,wParam,lParam) + Notes : wParam MUST remain untouched, lParam is a pointer to a CSSDATA structure + and can be modified or copied if needed. + wParam and lParam should be the values passed to your service, + typically your service should return ASAP. + - + MS_PROTO_CHAINRECV is thread safe since 0.1.2.0 -- calls + are translated to the main thread and passed from there. + } + MS_PROTO_CHAINRECV = 'Proto/ChainRecv'; + + { + wParam : 0 + lParam : Pointer to an initalised ACKDATA + Affect : Broadcast a ME_PROTO_ACK event, see notes + Returns: The return value of the NotifyEventHooks() call + Notes : ME_PROTO_ACK is completely thread safe since 01.2.0 + see notes in core/modules.h under NotifyEventHooks() + } + MS_PROTO_BROADCASTACK = 'Proto/BroadcastAck'; +{$ENDIF} diff --git a/plugins/ShlExt/inc/m_protosvc.inc b/plugins/ShlExt/inc/m_protosvc.inc new file mode 100644 index 0000000000..9fde8268bb --- /dev/null +++ b/plugins/ShlExt/inc/m_protosvc.inc @@ -0,0 +1,753 @@ +(* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2004 Miranda ICQ/IM project, +all portions of this codebase are copyrighted to the people +listed in contributors.txt. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*) + +{$IFNDEF M_PROTOSVC} +{$DEFINE M_PROTOSVC} + +{<>} + +const + + PFLAGNUM_1 = $1; + PF1_IMSEND = $00000001; // supports IM sending + PF1_IMRECV = $00000002; // supports IM receiving + PF1_IM = (PF1_IMSEND or PF1_IMRECV); + PF1_URLSEND = $00000004; // supports separate URL sending + PF1_URLRECV = $00000008; // supports separate URL receiving + PF1_URL = (PF1_URLSEND or PF1_URLRECV); + PF1_FILESEND = $00000010; // supports file sending + PF1_FILERECV = $00000020; // supports file receiving + PF1_FILE = (PF1_FILESEND or PF1_FILERECV); + PF1_MODEMSGSEND = $00000040; // supports broadcasting away messages + PF1_MODEMSGRECV = $00000080; // supports reading others' away messages + PF1_MODEMSG = (PF1_MODEMSGSEND or PF1_MODEMSGRECV); + PF1_SERVERCLIST = $00000100; // contact lists are stored on the server, not locally. See notes below + PF1_AUTHREQ = $00000200; // will get authorisation requests for some or all contacts + PF1_ADDED = $00000400; // will get 'you were added' notifications + PF1_VISLIST = $00000800; // has an invisible list + PF1_INVISLIST = $00001000; // has a visible list for when in invisible mode + PF1_INDIVSTATUS = $00002000; // supports setting different status modes to each contact + PF1_EXTENSIBLE = $00004000; // the protocol is extensible and supports plugin-defined messages + PF1_PEER2PEER = $00008000; // supports direct (not server mediated) communication between clients + PF1_NEWUSER = $00010000; // supports creation of new user IDs + PF1_CHAT = $00020000; // has a realtime chat capability + PF1_INDIVMODEMSG = $00040000; // supports replying to a mode message request with different text depending on the contact requesting + PF1_BASICSEARCH = $00080000; // supports a basic user searching facility + PF1_EXTSEARCH = $00100000; // supports one or more protocol-specific extended search schemes + PF1_CANRENAMEFILE = $00200000; // supports renaming of incoming files as they are transferred + PF1_FILERESUME = $00400000; // can resume broken file transfers, see PS_FILERESUME below + PF1_ADDSEARCHRES = $00800000; // can add search results to the contact list + PF1_CONTACTSEND = $01000000; // can send contacts to other users + PF1_CONTACTRECV = $02000000; // can receive contacts from other users + PF1_CONTACT = (PF1_CONTACTSEND or PF1_CONTACTRECV); + PF1_CHANGEINFO = $04000000; // can change our user information stored on server + PF1_SEARCHBYEMAIL = $08000000; // supports a search by e-mail feature + PF1_USERIDISEMAIL = $10000000; // set if the uniquely identifying field of the network is the e-mail address + PF1_SEARCHBYNAME = $20000000; // supports searching by nick/first/last names + PF1_EXTSEARCHUI = $40000000; // has a dialog box to allow searching all the possible fields + PF1_NUMERICUSERID = $80000000; // the unique user IDs for this protocol are numeric + + PFLAGNUM_2 = 2; // the status modes that the protocol supports + PF2_ONLINE = $00000001; // an unadorned online mode + PF2_INVISIBLE = $00000002; + PF2_SHORTAWAY = $00000004; // Away on ICQ, BRB on MSN + PF2_LONGAWAY = $00000008; // NA on ICQ, Away on MSN + PF2_LIGHTDND = $00000010; // Occupied on ICQ, Busy on MSN + PF2_HEAVYDND = $00000020; // DND on ICQ + PF2_FREECHAT = $00000040; + PF2_OUTTOLUNCH = $00000080; + PF2_ONTHEPHONE = $00000100; + + PFLAGNUM_3 = 3; //the status modes that the protocol supports + //away-style messages for. Uses the PF2_ flags. + PFLAG_UNIQUEIDTEXT = 100; //returns a static buffer of text describing the unique field by which this protocol identifies users (already translated), or NULL + + PFLAG_MAXCONTACTSPERPACKET = 200; //v0.1.2.2+: returns the maximum number of contacts which can be sent in a single PSS_CONTACTS. + + PFLAGNUM_4 = 4; // v0.3+: flag asking a protocol plugin how auths are handled + PF4_FORCEAUTH = $00000001; // protocol has to send auth's for things to work + PF4_FORCEADDED = $00000002; // protocol has to tell people that they were added (otherwise things don't work) + PF4_NOCUSTOMAUTH = $00000004; // protocol can't send a custom message while asking others for auth + + PFLAG_UNIQUEIDSETTING = 300; // v0.3+: returns the DB setting name (e.g. szProto=ICQ, szSetting=UIN) that has the ID which makes this user unique on that system (0.3a ONLY), the string is statically allocated so no need to free() + + // for PS_SETSTATUS + + LOGINERR_WRONGPASSWORD = 1; + LOGINERR_NONETWORK = 2; + LOGINERR_PROXYFAILURE = 3; + LOGINERR_BADUSERID = 4; + LOGINERR_NOSERVER = 5; + LOGINERR_TIMEOUT = 6; + LOGINERR_WRONGPROTOCOL = 7; + + // flag for PS_ADDTOLIST + + PALF_TEMPORARY = 1; // add the contact temporarily and invisibly, just to get user info or something + + // flags for PS_GETINFO + + SGIF_MINIMAL = 1; // get only the most basic information. This should + // contain at least a Nick and e-mail. + + // for PSR_MESSAGE + + PREF_CREATEREAD = 1; // create the database event with the 'read' flag set + + // for PS_FILERESUME + + FILERESUME_OVERWRITE= 1; + FILERESUME_RESUME = 2; + FILERESUME_RENAME = 3; + FILERESUME_SKIP = 4; + +type + + PPROTOSEARCHRESULT = ^TPROTOSEARCHRESULT; + TPROTOSEARCHRESULT = record + cbSize: int; + nick: PChar; + firstName: PChar; + lastName: PChar; + email: PChar; + reserved: array [0..15] of Byte; + // Protocols may extend this structure with extra members at will and supply + // a larger cbSize to reflect the new information, but they must not change + // any elements above this comment + // The 'reserved' field is part of the basic structure, not space to + // overwrite with protocol-specific information. + // If modules do this, they should take steps to ensure that information + // they put there will be retained by anyone trying to save this structure. + end; + + PPROTOSEARCHBYNAME = ^TPROTOSEARCHBYNAME; + TPROTOSEARCHBYNAME = record + pszNick: PChar; + pszFirstName: PChar; + pszLastName: PChar; + end; + + PPROTORECVEVENT = ^TPROTORECVEVENT; + TPROTORECVEVENT = record + flags: DWORD; + timestamp: DWORD; + szMessage: PChar; + lParam: LPARAM; + end; + + PPROTORECVFILE = ^TPROTORECVFILE; + TPROTORECVFILE = record + flags: DWORD; + timestamp: DWORD; // unix time + szDescription: PChar; + pFiles: PChar; // pointer to an array of pchar's + lParam: LPARAM; + end; + + PPROTOFILERESUME = ^TPROTOFILERESUME; + TPROTOFILERESUME = record + action: int; // FILERESUME_* flag + szFilename: PChar; // full path, only valid if action=FILERESUME_RENAME + end; + +const + + { + wParam : PFLAGNUM_* (see above) + lParam : 0 + Affects: Returns a bitfield for settings corresponding to flag number, see notes + Returns: a bitfield of supported features -- or 0 if flag_num is not supported + Notes : this checks what sort of things are actively supported by a protocol + module + } + PS_GETCAPS = '/GetCaps'; + + { + wParam : cchName + lParam : Pointer to a buffer to fill with human-readable name + Affect : Get a human-readable name for the protocol, see notes + Result : 0 on success, [non zero] on failure + Notes : Should be translated before being returned, cchName + has the size of the buffer, example strings: "ICQ", "AIM" + } + PS_GETNAME = '/GetName'; + + { + wParam : whichIcon + lParam : 0 + Affect : Loads one of the protocol-sspecific icons + Returns: the HICON or NULL on failure, the returned icon + must be DestroyIcon()ed, the UI should overlay + the online icon with further UI-specified icon to + repressent the exact status mode. + } + PLI_PROTOCOL = $1; // An icon representing the protocol (eg the multicoloured flower for ICQ) + PLI_ONLINE = $2; // Online state icon for that protocol (eg green flower for ICQ) + PLI_OFFLINE = $3; // Offline state icon for that protocol (eg red flower for ICQ) + PLIF_LARGE = $0; // Or with one of the above to get the large (32x32 by default) icon + PLIF_SMALL = $10000; // Or with one of the above to get the small (16x16 by default) icon + + PS_LOADICON = '/LoadIcon'; + + { + wParam : status_mode + lParam : Pointer to a null terminated string containing message + Affect : Sets the status mode specific message for the user, see notes + Returns: 0 on success, [non zero] on failure + Notes : This service is not available unless PF1_MODEMSGSEND is set, + and PF1_INDIVMODEMSG is *not* set. + If PF1_INDIVMODEMSG is set, then see PSS_AWAYMSSG for details + of operations of away messages. + - + Protocol modules smust support lParam=NULL, it may eithere mean + to use an empty message or (preferably) not to reply at all to + any requests. + } + PS_SETAWAYMSG = '/SetAwayMsg'; + + { + wParam : newMode from statusmodes.inc + lParam : 0 + Affect : Change the protocol's status mode, see notes + Returns: 0 on success, [non zero] on failure + Notes : Will send an ack with : + type=ACKTYPE_SUCCESS, result=ACKRESULT_SUCCESS, hProcess=previousMode, lParam=newMode + - + when the change completes. This ack is sent for all changes, not + just ones caused by calling this function. + - + NewMode can be ID_STATUS_CONNECTING<=newMode