From 1ce002432b3a5c0bb0a4c9f9eb8d399d649fe283 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 6 Jul 2012 08:31:38 +0000 Subject: - mir_core.dll moved to the core :) - plugins now obtain the fake langpack id if langpack is absent git-svn-id: http://svn.miranda-ng.org/main/trunk@787 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- bin10/mir_full.sln | 20 +- bin10/mir_full_pro.sln | 22 +- bin10/miranda32.sln | 19 +- plugins/Mir_core/commonheaders.cpp | 2 - plugins/Mir_core/commonheaders.h | 63 --- plugins/Mir_core/db.cpp | 191 -------- plugins/Mir_core/langpack.cpp | 640 --------------------------- plugins/Mir_core/lists.cpp | 278 ------------ plugins/Mir_core/md5.cpp | 358 --------------- plugins/Mir_core/memory.cpp | 280 ------------ plugins/Mir_core/mir_core.def | 127 ------ plugins/Mir_core/mir_core_10.vcxproj | 238 ---------- plugins/Mir_core/mir_core_10.vcxproj.filters | 76 ---- plugins/Mir_core/miranda.cpp | 97 ---- plugins/Mir_core/miranda.h | 132 ------ plugins/Mir_core/modules.cpp | 601 ------------------------- plugins/Mir_core/path.cpp | 210 --------- plugins/Mir_core/sha1.cpp | 155 ------- plugins/Mir_core/threads.cpp | 372 ---------------- plugins/Mir_core/utf.cpp | 406 ----------------- plugins/Mir_core/utils.cpp | 150 ------- src/core/miranda.h | 6 +- src/mir_core/commonheaders.cpp | 2 + src/mir_core/commonheaders.h | 63 +++ src/mir_core/db.cpp | 191 ++++++++ src/mir_core/langpack.cpp | 631 ++++++++++++++++++++++++++ src/mir_core/lists.cpp | 278 ++++++++++++ src/mir_core/md5.cpp | 358 +++++++++++++++ src/mir_core/memory.cpp | 280 ++++++++++++ src/mir_core/mir_core.def | 126 ++++++ src/mir_core/mir_core_10.vcxproj | 238 ++++++++++ src/mir_core/mir_core_10.vcxproj.filters | 76 ++++ src/mir_core/miranda.cpp | 97 ++++ src/mir_core/miranda.h | 131 ++++++ src/mir_core/modules.cpp | 601 +++++++++++++++++++++++++ src/mir_core/path.cpp | 210 +++++++++ src/mir_core/sha1.cpp | 155 +++++++ src/mir_core/threads.cpp | 372 ++++++++++++++++ src/mir_core/utf.cpp | 406 +++++++++++++++++ src/mir_core/utils.cpp | 150 +++++++ src/modules/icolib/extracticon.cpp | 2 +- src/modules/langpack/lpservices.cpp | 4 +- src/modules/options/options.cpp | 2 - src/modules/plugins/newplugins.cpp | 102 +++-- src/modules/plugins/pluginopts.cpp | 2 +- src/modules/plugins/plugins.h | 3 +- 46 files changed, 4468 insertions(+), 4455 deletions(-) delete mode 100644 plugins/Mir_core/commonheaders.cpp delete mode 100644 plugins/Mir_core/commonheaders.h delete mode 100644 plugins/Mir_core/db.cpp delete mode 100644 plugins/Mir_core/langpack.cpp delete mode 100644 plugins/Mir_core/lists.cpp delete mode 100644 plugins/Mir_core/md5.cpp delete mode 100644 plugins/Mir_core/memory.cpp delete mode 100644 plugins/Mir_core/mir_core.def delete mode 100644 plugins/Mir_core/mir_core_10.vcxproj delete mode 100644 plugins/Mir_core/mir_core_10.vcxproj.filters delete mode 100644 plugins/Mir_core/miranda.cpp delete mode 100644 plugins/Mir_core/miranda.h delete mode 100644 plugins/Mir_core/modules.cpp delete mode 100644 plugins/Mir_core/path.cpp delete mode 100644 plugins/Mir_core/sha1.cpp delete mode 100644 plugins/Mir_core/threads.cpp delete mode 100644 plugins/Mir_core/utf.cpp delete mode 100644 plugins/Mir_core/utils.cpp create mode 100644 src/mir_core/commonheaders.cpp create mode 100644 src/mir_core/commonheaders.h create mode 100644 src/mir_core/db.cpp create mode 100644 src/mir_core/langpack.cpp create mode 100644 src/mir_core/lists.cpp create mode 100644 src/mir_core/md5.cpp create mode 100644 src/mir_core/memory.cpp create mode 100644 src/mir_core/mir_core.def create mode 100644 src/mir_core/mir_core_10.vcxproj create mode 100644 src/mir_core/mir_core_10.vcxproj.filters create mode 100644 src/mir_core/miranda.cpp create mode 100644 src/mir_core/miranda.h create mode 100644 src/mir_core/modules.cpp create mode 100644 src/mir_core/path.cpp create mode 100644 src/mir_core/sha1.cpp create mode 100644 src/mir_core/threads.cpp create mode 100644 src/mir_core/utf.cpp create mode 100644 src/mir_core/utils.cpp diff --git a/bin10/mir_full.sln b/bin10/mir_full.sln index 30f45701c3..0a15d730fa 100644 --- a/bin10/mir_full.sln +++ b/bin10/mir_full.sln @@ -240,8 +240,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Clist_classic", "..\plugins EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NewEventNotify", "..\plugins\NewEventNotify\neweventnotify.vcxproj", "{2E0A2793-94C3-82E7-2AB0-FD421816CFBF}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Mir_core", "..\plugins\Mir_core\mir_core_10.vcxproj", "{D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileAsMessage", "..\plugins\FileAsMessage\fileecho.vcxproj", "{D7A3B8D0-425A-2286-8E2F-2C0BF1EE5C2E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WhoUsesMyFiles", "..\plugins\WhoUsesMyFiles\wumf.vcxproj", "{F29CCB9B-79CF-4341-AA05-3626A036D3E3}" @@ -259,6 +257,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AvatarHistory", "..\plugins EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stduserinfo", "..\src\core\stduserinfo\stduserinfo_10.vcxproj", "{1C856B14-54CD-4D07-B18B-5F7DB073AB51}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mir_core", "..\src\mir_core\mir_core_10.vcxproj", "{D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -1222,14 +1222,6 @@ Global {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Release|Win32.Build.0 = Release|Win32 {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Release|x64.ActiveCfg = Release|x64 {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Release|x64.Build.0 = Release|x64 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|Win32.ActiveCfg = Debug|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|Win32.Build.0 = Debug|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|x64.ActiveCfg = Debug|x64 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|x64.Build.0 = Debug|x64 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|Win32.ActiveCfg = Release|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|Win32.Build.0 = Release|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|x64.ActiveCfg = Release|x64 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|x64.Build.0 = Release|x64 {D7A3B8D0-425A-2286-8E2F-2C0BF1EE5C2E}.Debug|Win32.ActiveCfg = Debug|Win32 {D7A3B8D0-425A-2286-8E2F-2C0BF1EE5C2E}.Debug|Win32.Build.0 = Debug|Win32 {D7A3B8D0-425A-2286-8E2F-2C0BF1EE5C2E}.Debug|x64.ActiveCfg = Debug|x64 @@ -1286,6 +1278,14 @@ Global {1C856B14-54CD-4D07-B18B-5F7DB073AB51}.Release|Win32.Build.0 = Release|Win32 {1C856B14-54CD-4D07-B18B-5F7DB073AB51}.Release|x64.ActiveCfg = Release|x64 {1C856B14-54CD-4D07-B18B-5F7DB073AB51}.Release|x64.Build.0 = Release|x64 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|Win32.ActiveCfg = Debug|Win32 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|Win32.Build.0 = Debug|Win32 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|x64.ActiveCfg = Debug|x64 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|x64.Build.0 = Debug|x64 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|Win32.ActiveCfg = Release|Win32 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|Win32.Build.0 = Release|Win32 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|x64.ActiveCfg = Release|x64 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/bin10/mir_full_pro.sln b/bin10/mir_full_pro.sln index 1f3b737852..ae7e5f8348 100644 --- a/bin10/mir_full_pro.sln +++ b/bin10/mir_full_pro.sln @@ -240,8 +240,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Clist_classic", "..\plugins EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NewEventNotify", "..\plugins\NewEventNotify\neweventnotify.vcxproj", "{2E0A2793-94C3-82E7-2AB0-FD421816CFBF}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Mir_core", "..\plugins\Mir_core\mir_core_10.vcxproj", "{D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileAsMessage", "..\plugins\FileAsMessage\fileecho.vcxproj", "{D7A3B8D0-425A-2286-8E2F-2C0BF1EE5C2E}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WhoUsesMyFiles", "..\plugins\WhoUsesMyFiles\wumf.vcxproj", "{F29CCB9B-79CF-4341-AA05-3626A036D3E3}" @@ -293,6 +291,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{CBBD3DE7-9 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stduserinfo", "..\src\core\stduserinfo\stduserinfo_10.vcxproj", "{1C856B14-54CD-4D07-B18B-5F7DB073AB51}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mir_core", "..\src\mir_core\mir_core_10.vcxproj", "{D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -1256,14 +1256,6 @@ Global {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Release|Win32.Build.0 = Release|Win32 {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Release|x64.ActiveCfg = Release|x64 {2E0A2793-94C3-82E7-2AB0-FD421816CFBF}.Release|x64.Build.0 = Release|x64 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|Win32.ActiveCfg = Debug|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|Win32.Build.0 = Debug|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|x64.ActiveCfg = Debug|x64 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|x64.Build.0 = Debug|x64 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|Win32.ActiveCfg = Release|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|Win32.Build.0 = Release|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|x64.ActiveCfg = Release|x64 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|x64.Build.0 = Release|x64 {D7A3B8D0-425A-2286-8E2F-2C0BF1EE5C2E}.Debug|Win32.ActiveCfg = Debug|Win32 {D7A3B8D0-425A-2286-8E2F-2C0BF1EE5C2E}.Debug|Win32.Build.0 = Debug|Win32 {D7A3B8D0-425A-2286-8E2F-2C0BF1EE5C2E}.Debug|x64.ActiveCfg = Debug|x64 @@ -1320,6 +1312,14 @@ Global {1C856B14-54CD-4D07-B18B-5F7DB073AB51}.Release|Win32.Build.0 = Release|Win32 {1C856B14-54CD-4D07-B18B-5F7DB073AB51}.Release|x64.ActiveCfg = Release|x64 {1C856B14-54CD-4D07-B18B-5F7DB073AB51}.Release|x64.Build.0 = Release|x64 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|Win32.ActiveCfg = Debug|Win32 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|Win32.Build.0 = Debug|Win32 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|x64.ActiveCfg = Debug|x64 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|x64.Build.0 = Debug|x64 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|Win32.ActiveCfg = Release|Win32 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|Win32.Build.0 = Release|Win32 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|x64.ActiveCfg = Release|x64 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1354,9 +1354,9 @@ Global {B988F96C-F87A-484C-AB15-D0674B22F291} = {87D96006-542C-4396-87EF-68E3C3D2797F} {268BD296-8DD3-4715-A386-CF120398EC98} = {87D96006-542C-4396-87EF-68E3C3D2797F} {F9916510-9055-4C9F-997A-3755DEC1511B} = {CBBD3DE7-97CE-479D-87E3-8EACD035AF9B} - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60} = {CBBD3DE7-97CE-479D-87E3-8EACD035AF9B} {E2A369CD-EDA3-414F-8AD0-E732CD7EE68C} = {CBBD3DE7-97CE-479D-87E3-8EACD035AF9B} {1C856B14-54CD-4D07-B18B-5F7DB073AB51} = {CBBD3DE7-97CE-479D-87E3-8EACD035AF9B} + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60} = {CBBD3DE7-97CE-479D-87E3-8EACD035AF9B} {20D781FB-4A20-4B75-B863-304A47182966} = {BB69C74C-04FF-498B-8288-8259C3C5A41C} {A2E9DA24-95E4-4414-94AF-488A382E276A} = {BB69C74C-04FF-498B-8288-8259C3C5A41C} {6D3DC604-9CA0-45A2-85D7-1EFE3309F23B} = {BB69C74C-04FF-498B-8288-8259C3C5A41C} diff --git a/bin10/miranda32.sln b/bin10/miranda32.sln index 01b359dbe4..89225e9983 100644 --- a/bin10/miranda32.sln +++ b/bin10/miranda32.sln @@ -74,10 +74,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Toolbar_icons", "..\plugins EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Clist_classic", "..\plugins\Clist_classic\clist_10.vcxproj", "{E71C1722-A41D-4475-87F4-29961A3654BB}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Mir_core", "..\plugins\Mir_core\mir_core_10.vcxproj", "{D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stduserinfo", "..\src\core\stduserinfo\stduserinfo_10.vcxproj", "{1C856B14-54CD-4D07-B18B-5F7DB073AB51}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mir_core", "..\src\mir_core\mir_core_10.vcxproj", "{D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -382,13 +382,6 @@ Global {E71C1722-A41D-4475-87F4-29961A3654BB}.Release|Win32.Build.0 = Release|Win32 {E71C1722-A41D-4475-87F4-29961A3654BB}.Release|x64.ActiveCfg = Release|x64 {E71C1722-A41D-4475-87F4-29961A3654BB}.Release|x64.Build.0 = Release|x64 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|Win32.ActiveCfg = Debug|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|Win32.Build.0 = Debug|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|x64.ActiveCfg = Debug|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|Win32.ActiveCfg = Release|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|Win32.Build.0 = Release|Win32 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|x64.ActiveCfg = Release|x64 - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|x64.Build.0 = Release|x64 {1C856B14-54CD-4D07-B18B-5F7DB073AB51}.Debug|Win32.ActiveCfg = Debug|Win32 {1C856B14-54CD-4D07-B18B-5F7DB073AB51}.Debug|Win32.Build.0 = Debug|Win32 {1C856B14-54CD-4D07-B18B-5F7DB073AB51}.Debug|x64.ActiveCfg = Debug|x64 @@ -397,6 +390,14 @@ Global {1C856B14-54CD-4D07-B18B-5F7DB073AB51}.Release|Win32.Build.0 = Release|Win32 {1C856B14-54CD-4D07-B18B-5F7DB073AB51}.Release|x64.ActiveCfg = Release|x64 {1C856B14-54CD-4D07-B18B-5F7DB073AB51}.Release|x64.Build.0 = Release|x64 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|Win32.ActiveCfg = Debug|Win32 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|Win32.Build.0 = Debug|Win32 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|x64.ActiveCfg = Debug|x64 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Debug|x64.Build.0 = Debug|x64 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|Win32.ActiveCfg = Release|Win32 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|Win32.Build.0 = Release|Win32 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|x64.ActiveCfg = Release|x64 + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/plugins/Mir_core/commonheaders.cpp b/plugins/Mir_core/commonheaders.cpp deleted file mode 100644 index 95b2201163..0000000000 --- a/plugins/Mir_core/commonheaders.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "commonheaders.h" - diff --git a/plugins/Mir_core/commonheaders.h b/plugins/Mir_core/commonheaders.h deleted file mode 100644 index 2d04e12f4b..0000000000 --- a/plugins/Mir_core/commonheaders.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - -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. -*/ - -#define MIRANDA_VER 0x0A00 - -#define WINVER 0x0700 -#define _WIN32_WINNT 0x0700 -#define _WIN32_IE 0x0601 - -#define INCL_WINSOCK_API_TYPEDEFS 1 - -#include "m_stdhdr.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "miranda.h" - -#include -#include diff --git a/plugins/Mir_core/db.cpp b/plugins/Mir_core/db.cpp deleted file mode 100644 index 37b89d8399..0000000000 --- a/plugins/Mir_core/db.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - -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. -*/ - -#include "commonheaders.h" - -MIR_CORE_DLL(int) db_get_b(HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) -{ - DBVARIANT dbv; - DBCONTACTGETSETTING cgs; - cgs.szModule = szModule; - cgs.szSetting = szSetting; - cgs.pValue = &dbv; - if (CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&cgs)) - return errorValue; - return dbv.bVal; -} - -MIR_CORE_DLL(int) db_get_w(HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) -{ - DBVARIANT dbv; - DBCONTACTGETSETTING cgs; - cgs.szModule = szModule; - cgs.szSetting = szSetting; - cgs.pValue = &dbv; - if (CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&cgs)) - return errorValue; - return dbv.wVal; -} - -MIR_CORE_DLL(DWORD) db_get_dw(HANDLE hContact, const char *szModule, const char *szSetting, DWORD errorValue) -{ - DBVARIANT dbv; - DBCONTACTGETSETTING cgs; - cgs.szModule = szModule; - cgs.szSetting = szSetting; - cgs.pValue = &dbv; - if (CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&cgs)) - return errorValue; - return dbv.dVal; -} - -MIR_CORE_DLL(INT_PTR) db_get(HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv) -{ - DBCONTACTGETSETTING cgs; - cgs.szModule = szModule; - cgs.szSetting = szSetting; - cgs.pValue = dbv; - - return CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&cgs); -} - -MIR_CORE_DLL(INT_PTR) db_get_s(HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv, const int nType) -{ - DBCONTACTGETSETTING cgs; - cgs.szModule = szModule; - cgs.szSetting = szSetting; - cgs.pValue = dbv; - dbv->type = (BYTE)nType; - return CallService(MS_DB_CONTACT_GETSETTING_STR, (WPARAM)hContact, (LPARAM)&cgs); -} - -MIR_CORE_DLL(char*) db_get_sa(HANDLE hContact, const char *szModule, const char *szSetting) -{ - char *str = NULL; - DBVARIANT dbv = {0}; - db_get_s(hContact, szModule, szSetting, &dbv, DBVT_ASCIIZ); - if (dbv.type == DBVT_ASCIIZ) - str = mir_strdup(dbv.pszVal); - DBFreeVariant(&dbv); - return str; -} - -MIR_CORE_DLL(wchar_t*) db_get_wsa(HANDLE hContact, const char *szModule, const char *szSetting) -{ - wchar_t *str = NULL; - DBVARIANT dbv={0}; - db_get_s(hContact, szModule, szSetting, &dbv, DBVT_WCHAR); - if (dbv.type == DBVT_WCHAR) - str = mir_wstrdup(dbv.pwszVal); - DBFreeVariant(&dbv); - return str; -} - -MIR_CORE_DLL(INT_PTR) db_free(DBVARIANT *dbv) -{ - return CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)dbv); -} - -MIR_CORE_DLL(INT_PTR) db_unset(HANDLE hContact, const char *szModule, const char *szSetting) -{ - DBCONTACTGETSETTING cgs; - cgs.szModule = szModule; - cgs.szSetting = szSetting; - return CallService(MS_DB_CONTACT_DELETESETTING, (WPARAM)hContact, (LPARAM)&cgs); -} - -MIR_CORE_DLL(INT_PTR) db_set_b(HANDLE hContact, const char *szModule, const char *szSetting, BYTE val) -{ - DBCONTACTWRITESETTING cws; - cws.szModule = szModule; - cws.szSetting = szSetting; - cws.value.type = DBVT_BYTE; - cws.value.bVal = val; - return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); -} - -MIR_CORE_DLL(INT_PTR) db_set_w(HANDLE hContact, const char *szModule, const char *szSetting, WORD val) -{ - DBCONTACTWRITESETTING cws; - - cws.szModule = szModule; - cws.szSetting = szSetting; - cws.value.type = DBVT_WORD; - cws.value.wVal = val; - return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); -} - -MIR_CORE_DLL(INT_PTR) db_set_dw(HANDLE hContact, const char *szModule, const char *szSetting, DWORD val) -{ - DBCONTACTWRITESETTING cws; - cws.szModule = szModule; - cws.szSetting = szSetting; - cws.value.type = DBVT_DWORD; - cws.value.dVal = val; - return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); -} - -MIR_CORE_DLL(INT_PTR) db_set_s(HANDLE hContact, const char *szModule, const char *szSetting, const char *val) -{ - DBCONTACTWRITESETTING cws; - - cws.szModule = szModule; - cws.szSetting = szSetting; - cws.value.type = DBVT_ASCIIZ; - cws.value.pszVal = (char*)val; - return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); -} - -MIR_CORE_DLL(INT_PTR) db_set_ws(HANDLE hContact, const char *szModule, const char *szSetting, const WCHAR *val) -{ - DBCONTACTWRITESETTING cws; - - cws.szModule = szModule; - cws.szSetting = szSetting; - cws.value.type = DBVT_WCHAR; - cws.value.pwszVal = (WCHAR*)val; - return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); -} - -MIR_CORE_DLL(INT_PTR) db_set_utf(HANDLE hContact, const char *szModule, const char *szSetting, const char *val) -{ - DBCONTACTWRITESETTING cws; - - cws.szModule = szModule; - cws.szSetting = szSetting; - cws.value.type = DBVT_UTF8; - cws.value.pszVal = (char*)val; - return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); -} - -MIR_CORE_DLL(INT_PTR) db_set_blob(HANDLE hContact, const char *szModule, const char *szSetting, void *val, unsigned len) -{ - DBCONTACTWRITESETTING cws; - - cws.szModule = szModule; - cws.szSetting = szSetting; - cws.value.type = DBVT_BLOB; - cws.value.cpbVal = (WORD)len; - cws.value.pbVal = (unsigned char*)val; - return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); -} diff --git a/plugins/Mir_core/langpack.cpp b/plugins/Mir_core/langpack.cpp deleted file mode 100644 index 90c11a4a65..0000000000 --- a/plugins/Mir_core/langpack.cpp +++ /dev/null @@ -1,640 +0,0 @@ -/* - -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. -*/ -#include "commonheaders.h" - -#define LANGPACK_BUF_SIZE 4000 - -static int CompareMuuids(const MUUID* p1, const MUUID* p2) -{ - return memcmp(p1, p2, sizeof(MUUID)); -} - -static LIST lMuuids(10, CompareMuuids); -static MUUID* pCurrentMuuid = NULL; - -static BOOL bModuleInitialized = FALSE; - -struct LangPackEntry { - DWORD englishHash; - char *local; - wchar_t *wlocal; - MUUID* pMuuid; - LangPackEntry* pNext; // for langpack items with the same hash value -}; - -struct LangPackStruct { - TCHAR filename[MAX_PATH]; - TCHAR filePath[MAX_PATH]; - char language[64]; - char lastModifiedUsing[64]; - char authors[256]; - char authorEmail[128]; - LangPackEntry *entry; - int entryCount, entriesAlloced; - LCID localeID; - UINT defaultANSICp; -} static langPack; - -static int IsEmpty(char *str) -{ - int i = 0; - - while (str[i]) - { - if (str[i] != ' ' && str[i] != '\r' && str[i] != '\n') - return 0; - i++; - } - return 1; -} - -static void ConvertBackslashes(char *str, UINT fileCp) -{ - char *pstr; - for (pstr = str; *pstr; pstr = CharNextExA(fileCp, pstr, 0)) { - if (*pstr == '\\') { - switch(pstr[1]) { - case 'n': *pstr = '\n'; break; - case 't': *pstr = '\t'; break; - case 'r': *pstr = '\r'; break; - default: *pstr = pstr[1]; break; - } - memmove(pstr+1, pstr+2, strlen(pstr+2) + 1); -} } } - -#ifdef _DEBUG -//#pragma optimize("gt", on) -#endif - -// MurmurHash2 -MIR_CORE_DLL(unsigned int) mir_hash(const void * key, unsigned int len) -{ - // 'm' and 'r' are mixing constants generated offline. - // They're not really 'magic', they just happen to work well. - const unsigned int m = 0x5bd1e995; - const int r = 24; - - // Initialize the hash to a 'random' value - unsigned int h = len; - - // Mix 4 bytes at a time into the hash - const unsigned char * data = (const unsigned char *)key; - - while (len >= 4) - { - unsigned int k = *(unsigned int *)data; - - k *= m; - k ^= k >> r; - k *= m; - - h *= m; - h ^= k; - - data += 4; - len -= 4; - } - - // Handle the last few bytes of the input array - switch(len) - { - case 3: h ^= data[2] << 16; - case 2: h ^= data[1] << 8; - case 1: h ^= data[0]; - h *= m; - }; - - // Do a few final mixes of the hash to ensure the last few - // bytes are well-incorporated. - h ^= h >> 13; - h *= m; - h ^= h >> 15; - - return h; -} - -static unsigned int __fastcall hashstrW(const char * key) -{ - if (key == NULL) return 0; - const unsigned int len = (unsigned int)wcslen((const wchar_t*)key); - char* buf = (char*)alloca(len + 1); - for (unsigned i = 0; i <= len ; ++i) - buf[i] = key[i << 1]; - return mir_hash(buf, len); -} - -static int SortLangPackHashesProc(LangPackEntry *arg1, LangPackEntry *arg2) -{ - if (arg1->englishHash < arg2->englishHash) return -1; - if (arg1->englishHash > arg2->englishHash) return 1; - - return (arg1->pMuuid < arg2->pMuuid) ? -1 : 1; -} - -static void swapBytes(void* p, size_t iSize) -{ - char *head = (char *)p; // here - char *tail = head + iSize - 1; - - for (; tail > head; --tail, ++head) { - char temp = *head; - *head = *tail; - *tail = temp; - } -} - -static bool EnterMuuid(const char* p, MUUID& result) -{ - if (*p++ != '{') - return false; - - BYTE* d = (BYTE*)&result; - - for (int nBytes = 0; *p && nBytes < 24; p++) { - if (*p == '-') - continue; - - if (*p == '}') - break; - - if ( !isxdigit(*p)) - return false; - - if ( !isxdigit(p[1])) - return false; - - int c = 0; - if (sscanf(p, "%2x", &c) != 1) - return false; - - *d++ = (BYTE)c; - nBytes++; - p++; - } - - if (*p != '}') - return false; - - swapBytes(&result.a, sizeof(result.a)); - swapBytes(&result.b, sizeof(result.b)); - swapBytes(&result.c, sizeof(result.c)); - return true; -} - -static void LoadLangPackFile(FILE* fp, char* line, UINT fileCp) -{ - while ( !feof(fp)) { - if (fgets(line, LANGPACK_BUF_SIZE, fp) == NULL) - break; - - if (IsEmpty(line) || line[0] == ';' || line[0] == 0) - continue; - - rtrim(line); - - if (line[0] == '#') { - strlwr(line); - - if ( !memcmp(line+1, "include", 7)) { - TCHAR tszFileName[ MAX_PATH ]; - TCHAR* fileName = mir_a2t(ltrim(line+9)); - mir_sntprintf(tszFileName, SIZEOF(tszFileName), _T("%s%s"), langPack.filePath, fileName); - mir_free(fileName); - - FILE* p = _tfopen(tszFileName, _T("r")); - if (p) { - line[0] = 0; - fgets(line, SIZEOF(line), p); - - UINT fileCp = CP_ACP; - if (strlen(line) >= 3 && line[0] == '\xef' && line[1] == '\xbb' && line[2] == '\xbf') { - fileCp = CP_UTF8; - fseek(p, 3, SEEK_SET); - } - else { - fileCp = langPack.defaultANSICp; - fseek(p, 0, SEEK_SET); - } - - LoadLangPackFile(p, line, fileCp); - fclose(p); - } - } - else if ( !memcmp(line+1, "muuid", 5)) { - MUUID t; - if ( !EnterMuuid(line+7, t)) - continue; - - MUUID* pNew = (MUUID*)mir_alloc(sizeof(MUUID)); - memcpy(pNew, &t, sizeof(t)); - lMuuids.insert(pNew); - pCurrentMuuid = pNew; - } - - continue; - } - - ConvertBackslashes(line, fileCp); - - if (line[0] == '[' && line[ lstrlenA(line)-1 ] == ']') { - if (langPack.entryCount && langPack.entry[ langPack.entryCount-1].local == NULL) - langPack.entryCount--; - - char* pszLine = line+1; - line[ lstrlenA(line)-1 ] = '\0'; - if (++langPack.entryCount > langPack.entriesAlloced) { - langPack.entriesAlloced += 128; - langPack.entry = (LangPackEntry*)mir_realloc(langPack.entry, sizeof(LangPackEntry)*langPack.entriesAlloced); - } - - LangPackEntry* E = &langPack.entry[ langPack.entryCount-1 ]; - E->englishHash = mir_hashstr(pszLine); - E->local = NULL; - E->wlocal = NULL; - E->pMuuid = pCurrentMuuid; - E->pNext = NULL; - continue; - } - - if ( !langPack.entryCount) - continue; - - LangPackEntry* E = &langPack.entry[ langPack.entryCount-1 ]; - if (E->local == NULL) { - E->local = mir_strdup(line); - if (fileCp == CP_UTF8) - Utf8DecodeCP(E->local, langPack.defaultANSICp, NULL); - - int iNeeded = MultiByteToWideChar(fileCp, 0, line, -1, 0, 0); - E->wlocal = (wchar_t *)mir_alloc((iNeeded+1) * sizeof(wchar_t)); - MultiByteToWideChar(fileCp, 0, line, -1, E->wlocal, iNeeded); - } - else { - size_t iOldLenA = strlen(E->local); - E->local = (char*)mir_realloc(E->local, iOldLenA + strlen(line) + 2); - strcat(E->local, "\n"); - strcat(E->local, line); - - if (fileCp == CP_UTF8) - Utf8DecodeCP(E->local + iOldLenA + 1, langPack.defaultANSICp, NULL); - - int iNeeded = MultiByteToWideChar(fileCp, 0, line, -1, 0, 0); - size_t iOldLen = wcslen(E->wlocal); - E->wlocal = (wchar_t*)mir_realloc(E->wlocal, (sizeof(wchar_t) * (iOldLen + iNeeded + 2))); - wcscat(E->wlocal, L"\n"); - MultiByteToWideChar(fileCp, 0, line, -1, E->wlocal + iOldLen + 1, iNeeded); - } - } -} - -MIR_CORE_DLL(int) LoadLangPack(const TCHAR *szLangPack) -{ - int startOfLine=0; - USHORT langID; - - lstrcpy(langPack.filename, szLangPack); - lstrcpy(langPack.filePath, szLangPack); - TCHAR* p = _tcsrchr(langPack.filePath, '\\'); - if (p) - p[1] = 0; - - FILE *fp = _tfopen(szLangPack, _T("rt")); - if (fp == NULL) - return 1; - - char line[ LANGPACK_BUF_SIZE ] = ""; - fgets(line, SIZEOF(line), fp); - - UINT fileCp = CP_ACP; - size_t lineLen = strlen(line); - if (lineLen >= 3 && line[0] == '\xef' && line[1] == '\xbb' && line[2] == '\xbf') - { - fileCp = CP_UTF8; - memmove(line, line + 3, lineLen - 2); - } - - lrtrim(line); - if (lstrcmpA(line, "Miranda Language Pack Version 1")) { - fclose(fp); - return 2; - } - - //headers - while ( !feof(fp)) { - startOfLine = ftell(fp); - if (fgets(line, SIZEOF(line), fp) == NULL) - break; - - lrtrim(line); - if (IsEmpty(line) || line[0] == ';' || line[0] == 0) - continue; - - if (line[0] == '[' || line[0] == '#') - break; - - char* pszColon = strchr(line, ':'); - if (pszColon == NULL) { - fclose(fp); - return 3; - } - - *pszColon++ = 0; - if ( !lstrcmpA(line, "Language")) {mir_snprintf(langPack.language, sizeof(langPack.language), "%s", pszColon); lrtrim(langPack.language);} - else if ( !lstrcmpA(line, "Last-Modified-Using")) {mir_snprintf(langPack.lastModifiedUsing, sizeof(langPack.lastModifiedUsing), "%s", pszColon); lrtrim(langPack.lastModifiedUsing);} - else if ( !lstrcmpA(line, "Authors")) {mir_snprintf(langPack.authors, sizeof(langPack.authors), "%s", pszColon); lrtrim(langPack.authors);} - else if ( !lstrcmpA(line, "Author-email")) {mir_snprintf(langPack.authorEmail, sizeof(langPack.authorEmail), "%s", pszColon); lrtrim(langPack.authorEmail);} - else if ( !lstrcmpA(line, "Locale")) { - char szBuf[20], *stopped; - - lrtrim(pszColon + 1); - langID = (USHORT)strtol(pszColon, &stopped, 16); - langPack.localeID = MAKELCID(langID, 0); - GetLocaleInfoA(langPack.localeID, LOCALE_IDEFAULTANSICODEPAGE, szBuf, 10); - szBuf[5] = 0; // codepages have max. 5 digits - langPack.defaultANSICp = atoi(szBuf); - if (fileCp == CP_ACP) - fileCp = langPack.defaultANSICp; - } - } - - //body - fseek(fp, startOfLine, SEEK_SET); - langPack.entriesAlloced = 0; - - LoadLangPackFile(fp, line, fileCp); - fclose(fp); - pCurrentMuuid = NULL; - - qsort(langPack.entry, langPack.entryCount, sizeof(LangPackEntry), (int(*)(const void*, const void*))SortLangPackHashesProc); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static int SortLangPackHashesProc2(LangPackEntry *arg1, LangPackEntry *arg2) -{ - if (arg1->englishHash < arg2->englishHash) return -1; - if (arg1->englishHash > arg2->englishHash) return 1; - return 0; -} - -static char *LangPackTranslateString(MUUID* pUuid, const char *szEnglish, const int W) -{ - if (langPack.entryCount == 0 || szEnglish == NULL) - return (char*)szEnglish; - - LangPackEntry key, *entry; - key.englishHash = W ? hashstrW(szEnglish) : mir_hashstr(szEnglish); - entry = (LangPackEntry*)bsearch(&key, langPack.entry, langPack.entryCount, sizeof(LangPackEntry), (int(*)(const void*, const void*))SortLangPackHashesProc2); - if (entry == NULL) - return (char*)szEnglish; - - // try to find the exact match, otherwise the first entry will be returned - if (pUuid) { - for (LangPackEntry* p = entry->pNext; p != NULL; p = p->pNext) { - if (p->pMuuid == pUuid) { - entry = p; - break; - } } } - - return W ? (char *)entry->wlocal : entry->local; -} - -MIR_CORE_DLL(int) Langpack_GetDefaultCodePage() -{ - return langPack.defaultANSICp; -} - -MIR_CORE_DLL(int) Langpack_GetDefaultLocale() -{ - return (langPack.localeID == 0) ? LOCALE_USER_DEFAULT : langPack.localeID; -} - -MIR_CORE_DLL(TCHAR*) Langpack_PcharToTchar(const char* pszStr) -{ - if (pszStr == NULL) - return NULL; - - int len = (int)strlen(pszStr); - TCHAR* result = (TCHAR*)alloca((len+1)*sizeof(TCHAR)); - MultiByteToWideChar(Langpack_GetDefaultCodePage(), 0, pszStr, -1, result, len); - result[len] = 0; - return mir_wstrdup(TranslateW(result)); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_CORE_DLL(char*) TranslateA_LP(const char* str, int hLangpack) -{ - return (char*)LangPackTranslateString(Langpack_LookupUuid(hLangpack), str, FALSE); -} - -MIR_CORE_DLL(WCHAR*) TranslateW_LP(const WCHAR* str, int hLangpack) -{ - return (WCHAR*)LangPackTranslateString(Langpack_LookupUuid(hLangpack), (LPCSTR)str, TRUE); -} - -MIR_CORE_DLL(void) TranslateMenu_LP(HMENU hMenu, int hLangpack) -{ - MUUID* uuid = Langpack_LookupUuid(hLangpack); - - MENUITEMINFO mii; - mii.cbSize = MENUITEMINFO_V4_SIZE; - for (int i = GetMenuItemCount(hMenu)-1; i >= 0; i--) { - TCHAR str[256]; - mii.fMask = MIIM_TYPE|MIIM_SUBMENU; - mii.dwTypeData = (TCHAR*)str; - mii.cch = SIZEOF(str); - GetMenuItemInfo(hMenu, i, TRUE, &mii); - - if (mii.cch && mii.dwTypeData) { - TCHAR* result = (TCHAR*)LangPackTranslateString(uuid, (const char*)mii.dwTypeData, TRUE); - if (result != mii.dwTypeData) { - mii.dwTypeData = result; - mii.fMask = MIIM_TYPE; - SetMenuItemInfo(hMenu, i, TRUE, &mii); - } } - - if (mii.hSubMenu != NULL) TranslateMenu_LP(mii.hSubMenu, hLangpack); - } -} - -static void TranslateWindow(MUUID* pUuid, HWND hwnd) -{ - TCHAR title[2048]; - GetWindowText(hwnd, title, SIZEOF(title)); - - TCHAR* result = (TCHAR*)LangPackTranslateString(pUuid, (const char*)title, TRUE); - if (result != title) - SetWindowText(hwnd, result); -} - -struct LANGPACKTRANSLATEDIALOG -{ - HWND hwndDlg; - int hLangpack; -}; - -static BOOL CALLBACK TranslateDialogEnumProc(HWND hwnd, LPARAM lParam) -{ - int hLangpack = (int)lParam; - TCHAR szClass[32]; - int id = GetDlgCtrlID(hwnd); - - MUUID* uuid = Langpack_LookupUuid(hLangpack); - - GetClassName(hwnd, szClass, SIZEOF(szClass)); - if ( !lstrcmpi(szClass, _T("static")) || !lstrcmpi(szClass, _T("hyperlink")) || !lstrcmpi(szClass, _T("button")) || !lstrcmpi(szClass, _T("MButtonClass")) || !lstrcmpi(szClass, _T("MHeaderbarCtrl"))) - TranslateWindow(uuid, hwnd); - else if ( !lstrcmpi(szClass, _T("edit"))) { - if (GetWindowLongPtr(hwnd, GWL_STYLE) & ES_READONLY) - TranslateWindow(uuid, hwnd); - } - return TRUE; -} - -MIR_CORE_DLL(void) TranslateDialog_LP(HWND hDlg, int hLangpack) -{ - TranslateWindow( Langpack_LookupUuid(hLangpack), hDlg); - EnumChildWindows(hDlg, TranslateDialogEnumProc, hLangpack); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_CORE_DLL(MUUID*) Langpack_LookupUuid(WPARAM wParam) -{ - int idx = (wParam >> 16) & 0xFFFF; - return (idx > 0 && idx <= lMuuids.getCount()) ? lMuuids[ idx-1 ] : NULL; -} - -MIR_CORE_DLL(int) Langpack_GetPluginHandle(PLUGININFOEX* pInfo) -{ - int idx = lMuuids.getIndex(&pInfo->uuid); - if (idx == -1) - return 0; - - return (idx+1) << 16; -} - -MIR_CORE_DLL(int) Langpack_MarkPluginLoaded(PLUGININFOEX* pInfo) -{ - int idx = lMuuids.getIndex(&pInfo->uuid); - if (idx == -1) - return 0; - - return (idx+1) << 16; -} - -MIR_CORE_DLL(void) Langpack_SortDuplicates(void) -{ - if (langPack.entryCount == 0) - return; - - LangPackEntry *s = langPack.entry+1, *d = s, *pLast = langPack.entry; - DWORD dwSavedHash = langPack.entry->englishHash; - bool bSortNeeded = false; - - for (int i=1; i < langPack.entryCount; i++, s++) { - if (s->englishHash != dwSavedHash) { - pLast = d; - if (s != d) - *d++ = *s; - else - d++; - dwSavedHash = s->englishHash; - } - else { - bSortNeeded = true; - LangPackEntry* p = (LangPackEntry*)mir_alloc(sizeof(LangPackEntry)); - *p = *s; - pLast->pNext = p; pLast = p; - } - } - - if (bSortNeeded) { - langPack.entryCount = (int)(d - langPack.entry); - qsort(langPack.entry, langPack.entryCount, sizeof(LangPackEntry), (int(*)(const void*, const void*))SortLangPackHashesProc); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_CORE_DLL(int) LoadLangPackModule(void) -{ - bModuleInitialized = TRUE; - - ZeroMemory(&langPack, sizeof(langPack)); - - TCHAR szSearch[MAX_PATH]; - PathToAbsoluteT(_T("langpack_*.txt"), szSearch, NULL); - - WIN32_FIND_DATA fd; - HANDLE hFind = FindFirstFile(szSearch, &fd); - if (hFind != INVALID_HANDLE_VALUE) { - PathToAbsoluteT(fd.cFileName, szSearch, NULL); - FindClose(hFind); - LoadLangPack(szSearch); - } - return 0; -} - -void UnloadLangPackModule() -{ - if ( !bModuleInitialized) return; - - int i; - for (i=0; i < lMuuids.getCount(); i++) - mir_free(lMuuids[i]); - lMuuids.destroy(); - - LangPackEntry* p = langPack.entry; - for (i=0; i < langPack.entryCount; i++, p++) { - if (p->pNext != NULL) { - for (LangPackEntry* p1 = p->pNext; p1 != NULL;) { - LangPackEntry* p2 = p1; p1 = p1->pNext; - mir_free(p2->local); - mir_free(p2->wlocal); - mir_free(p2); - } } - - mir_free(p->local); - mir_free(p->wlocal); - } - - if (langPack.entryCount) { - mir_free(langPack.entry); - langPack.entry=0; - langPack.entryCount=0; -} } - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_CORE_DLL(void) ReloadLangpack(TCHAR *pszStr) -{ - if (pszStr == NULL) - pszStr = langPack.filename; - - UnloadLangPackModule(); - LoadLangPack(pszStr); - Langpack_SortDuplicates(); -} diff --git a/plugins/Mir_core/lists.cpp b/plugins/Mir_core/lists.cpp deleted file mode 100644 index e4996fc156..0000000000 --- a/plugins/Mir_core/lists.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* - -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. -*/ - -#include "commonheaders.h" - -/* a simple sorted list implementation */ - -MIR_CORE_DLL(SortedList*) List_Create(int p_limit, int p_increment) -{ - SortedList* result = (SortedList*)mir_calloc(sizeof(SortedList)); - if (result == NULL) - return(NULL); - - result->increment = p_increment; - result->limit = p_limit; - return(result); -} - -MIR_CORE_DLL(void) List_Destroy(SortedList* p_list) -{ - if (p_list == NULL) - return; - - if (p_list->items != NULL) { - mir_free(p_list->items); - p_list->items = NULL; - } - - p_list->realCount = p_list->limit = 0; -} - -MIR_CORE_DLL(void*) List_Find(SortedList* p_list, void* p_value) -{ - int index; - - if ( !List_GetIndex(p_list, p_value, &index)) - return(NULL); - - return(p_list->items[ index ]); -} - -#ifdef _DEBUG -#pragma optimize("gt", on) -#endif - -MIR_CORE_DLL(int) List_GetIndex(SortedList* p_list, void* p_value, int* p_index) -{ - if (p_value == NULL) - { - *p_index = -1; - return 0; - } - - switch ((INT_PTR)p_list->sortFunc) - { - case 0: - break; - - case HandleKeySort: -#ifdef _WIN64 - { - const unsigned __int64 val = *(unsigned __int64 *)p_value; - int low = 0; - int high = p_list->realCount - 1; - - while (low <= high) - { - int i = (low + high) / 2; - unsigned __int64 vali = *(unsigned __int64 *)p_list->items[i]; - if (vali == val) - { - *p_index = i; - return 1; - } - - if (vali < val) - low = i + 1; - else - high = i - 1; - } - - *p_index = low; - } - break; -#endif - - case NumericKeySort: - { - const unsigned val = *(unsigned *)p_value; - int low = 0; - int high = p_list->realCount - 1; - - while (low <= high) - { - int i = (low + high) / 2; - unsigned vali = *(unsigned *)p_list->items[i]; - if (vali == val) - { - *p_index = i; - return 1; - } - - if (vali < val) - low = i + 1; - else - high = i - 1; - } - - *p_index = low; - } - break; - - case PtrKeySort: - { - int low = 0; - int high = p_list->realCount - 1; - - while (low <= high) - { - int i = (low + high) / 2; - const void* vali = p_list->items[i]; - if (vali == p_value) - { - *p_index = i; - return 1; - } - - if (vali < p_value) - low = i + 1; - else - high = i - 1; - } - - *p_index = low; - } - break; - - default: - { - int low = 0; - int high = p_list->realCount - 1; - - while (low <= high) - { - int i = (low + high) / 2; - int result = p_list->sortFunc(p_list->items[i], p_value); - if (result == 0) - { - *p_index = i; - return 1; - } - - if (result < 0) - low = i + 1; - else - high = i - 1; - } - - *p_index = low; - } - break; - } - - return 0; -} - -MIR_CORE_DLL(int) List_IndexOf(SortedList* p_list, void* p_value) -{ - if (p_value == NULL) - return -1; - - int i; - for (i=0; i < p_list->realCount; i++) - if (p_list->items[i] == p_value) - return i; - - return -1; -} - -#ifdef _DEBUG -#pragma optimize("", on) -#endif - -MIR_CORE_DLL(int) List_Insert(SortedList* p_list, void* p_value, int p_index) -{ - if (p_value == NULL || p_index > p_list->realCount) - return 0; - - if (p_list->realCount == p_list->limit) - { - p_list->items = (void**)mir_realloc(p_list->items, sizeof(void*)*(p_list->realCount + p_list->increment)); - p_list->limit += p_list->increment; - } - - if (p_index < p_list->realCount) - memmove(p_list->items+p_index+1, p_list->items+p_index, sizeof(void*)*(p_list->realCount-p_index)); - - p_list->realCount++; - - p_list->items[ p_index ] = p_value; - return 1; -} - -MIR_CORE_DLL(int) List_InsertPtr(SortedList* list, void* p) -{ - if (p == NULL) - return -1; - - int idx = list->realCount; - List_GetIndex(list, p, &idx); - return List_Insert(list, p, idx); -} - -MIR_CORE_DLL(int) List_Remove(SortedList* p_list, int index) -{ - if (index < 0 || index > p_list->realCount) - return(0); - - p_list->realCount--; - if (p_list->realCount > index) - { - memmove(p_list->items+index, p_list->items+index+1, sizeof(void*)*(p_list->realCount-index)); - p_list->items[ p_list->realCount ] = NULL; - } - - return 1; -} - -MIR_CORE_DLL(int) List_RemovePtr(SortedList* list, void* p) -{ - int idx = -1; - if (List_GetIndex(list, p, &idx)) - List_Remove(list, idx); - - return idx; -} - -MIR_CORE_DLL(void) List_Copy(SortedList* s, SortedList* d, size_t itemSize) -{ - d->increment = s->increment; - d->limit = s->limit; - d->realCount = s->realCount; - d->items = (void**)mir_alloc( sizeof(void*) * d->realCount); - memcpy(d->items, s->items, sizeof(void*) * d->realCount); -} - -MIR_CORE_DLL(void) List_ObjCopy(SortedList* s, SortedList* d, size_t itemSize) -{ - int i; - - d->increment = s->increment; - d->sortFunc = s->sortFunc; - - for (i = 0; i < s->realCount; i++) { - void* item = new char[ itemSize ]; - memcpy(item, s->items[i], itemSize); - List_Insert(d, item, i); -} } diff --git a/plugins/Mir_core/md5.cpp b/plugins/Mir_core/md5.cpp deleted file mode 100644 index a7d7a641e3..0000000000 --- a/plugins/Mir_core/md5.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/* - Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. - - 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. - - L. Peter Deutsch - ghost@aladdin.com - - */ -/* $Id: md5.c 2874 2006-05-16 21:38:00Z ghazan $ */ -/* - Independent implementation of MD5 (RFC 1321). - - This code implements the MD5 Algorithm defined in RFC 1321, whose - text is available at - http://www.ietf.org/rfc/rfc1321.txt - The code is derived from the text of the RFC, including the test suite - (section A.5) but excluding the rest of Appendix A. It does not include - any code or documentation that is identified in the RFC as being - copyrighted. - - The original and principal author of md5.c is L. Peter Deutsch - . Other authors are noted in the change history - that follows (in reverse chronological order): - - 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order - either statically or dynamically; added missing #include - in library. - 2002-03-11 lpd Corrected argument list for main(), and added int return - type, in test program and T value program. - 2002-02-21 lpd Added missing #include in test program. - 2000-07-03 lpd Patched to eliminate warnings about "constant is - unsigned in ANSI C, signed in traditional"; made test program - self-checking. - 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. - 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). - 1999-05-03 lpd Original version. - */ - -// (C) 2005 Joe @ Whale - changed to compile with Miranda - -#include "commonheaders.h" - -#define T_MASK ((mir_md5_word_t)~0) -#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) -#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) -#define T3 0x242070db -#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) -#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) -#define T6 0x4787c62a -#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) -#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) -#define T9 0x698098d8 -#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) -#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) -#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) -#define T13 0x6b901122 -#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) -#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) -#define T16 0x49b40821 -#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) -#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) -#define T19 0x265e5a51 -#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) -#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) -#define T22 0x02441453 -#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) -#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) -#define T25 0x21e1cde6 -#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) -#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) -#define T28 0x455a14ed -#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) -#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) -#define T31 0x676f02d9 -#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) -#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) -#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) -#define T35 0x6d9d6122 -#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) -#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) -#define T38 0x4bdecfa9 -#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) -#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) -#define T41 0x289b7ec6 -#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) -#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) -#define T44 0x04881d05 -#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) -#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) -#define T47 0x1fa27cf8 -#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) -#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) -#define T50 0x432aff97 -#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) -#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) -#define T53 0x655b59c3 -#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) -#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) -#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) -#define T57 0x6fa87e4f -#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) -#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) -#define T60 0x4e0811a1 -#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) -#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) -#define T63 0x2ad7d2bb -#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) - -//gfd* -static void md5_process(mir_md5_state_t *pms, const mir_md5_byte_t *data /*[64]*/) -{ - mir_md5_word_t - a = pms->abcd[0], b = pms->abcd[1], - c = pms->abcd[2], d = pms->abcd[3]; - mir_md5_word_t t; - /* Define storage for little-endian or both types of CPUs. */ - mir_md5_word_t xbuf[16]; - const mir_md5_word_t *X; - - { - /* - * Determine dynamically whether this is a big-endian or - * little-endian machine, since we can use a more efficient - * algorithm on the latter. - */ - static const int w = 1; - - if (*((const mir_md5_byte_t *)&w)) /* dynamic little-endian */ - { - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if ( !((data - (const mir_md5_byte_t *)0) & 3)) { - /* data are properly aligned */ - X = (const mir_md5_word_t *)data; - } else { - /* not aligned */ - memcpy(xbuf, data, 64); - X = xbuf; - } - } - else /* dynamic big-endian */ - { - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const mir_md5_byte_t *xp = data; - int i; - - X = xbuf; /* (dynamic only) */ - for (i = 0; i < 16; ++i, xp += 4) - xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - } - } - -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b, c, d) + X[k] + T[i]) <<< s). */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define SET1(a, b, c, d, k, s, Ti)\ - t = a + F(b, c, d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET1(a, b, c, d, 0, 7, T1); - SET1(d, a, b, c, 1, 12, T2); - SET1(c, d, a, b, 2, 17, T3); - SET1(b, c, d, a, 3, 22, T4); - SET1(a, b, c, d, 4, 7, T5); - SET1(d, a, b, c, 5, 12, T6); - SET1(c, d, a, b, 6, 17, T7); - SET1(b, c, d, a, 7, 22, T8); - SET1(a, b, c, d, 8, 7, T9); - SET1(d, a, b, c, 9, 12, T10); - SET1(c, d, a, b, 10, 17, T11); - SET1(b, c, d, a, 11, 22, T12); - SET1(a, b, c, d, 12, 7, T13); - SET1(d, a, b, c, 13, 12, T14); - SET1(c, d, a, b, 14, 17, T15); - SET1(b, c, d, a, 15, 22, T16); - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b, c, d) + X[k] + T[i]) <<< s). */ -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define SET2(a, b, c, d, k, s, Ti)\ - t = a + G(b, c, d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET2(a, b, c, d, 1, 5, T17); - SET2(d, a, b, c, 6, 9, T18); - SET2(c, d, a, b, 11, 14, T19); - SET2(b, c, d, a, 0, 20, T20); - SET2(a, b, c, d, 5, 5, T21); - SET2(d, a, b, c, 10, 9, T22); - SET2(c, d, a, b, 15, 14, T23); - SET2(b, c, d, a, 4, 20, T24); - SET2(a, b, c, d, 9, 5, T25); - SET2(d, a, b, c, 14, 9, T26); - SET2(c, d, a, b, 3, 14, T27); - SET2(b, c, d, a, 8, 20, T28); - SET2(a, b, c, d, 13, 5, T29); - SET2(d, a, b, c, 2, 9, T30); - SET2(c, d, a, b, 7, 14, T31); - SET2(b, c, d, a, 12, 20, T32); - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b, c, d) + X[k] + T[i]) <<< s). */ -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define SET3(a, b, c, d, k, s, Ti)\ - t = a + H(b, c, d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET3(a, b, c, d, 5, 4, T33); - SET3(d, a, b, c, 8, 11, T34); - SET3(c, d, a, b, 11, 16, T35); - SET3(b, c, d, a, 14, 23, T36); - SET3(a, b, c, d, 1, 4, T37); - SET3(d, a, b, c, 4, 11, T38); - SET3(c, d, a, b, 7, 16, T39); - SET3(b, c, d, a, 10, 23, T40); - SET3(a, b, c, d, 13, 4, T41); - SET3(d, a, b, c, 0, 11, T42); - SET3(c, d, a, b, 3, 16, T43); - SET3(b, c, d, a, 6, 23, T44); - SET3(a, b, c, d, 9, 4, T45); - SET3(d, a, b, c, 12, 11, T46); - SET3(c, d, a, b, 15, 16, T47); - SET3(b, c, d, a, 2, 23, T48); - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b, c, d) + X[k] + T[i]) <<< s). */ -#define I(x, y, z) ((y) ^ ((x) | ~(z))) -#define SET4(a, b, c, d, k, s, Ti)\ - t = a + I(b, c, d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET4(a, b, c, d, 0, 6, T49); - SET4(d, a, b, c, 7, 10, T50); - SET4(c, d, a, b, 14, 15, T51); - SET4(b, c, d, a, 5, 21, T52); - SET4(a, b, c, d, 12, 6, T53); - SET4(d, a, b, c, 3, 10, T54); - SET4(c, d, a, b, 10, 15, T55); - SET4(b, c, d, a, 1, 21, T56); - SET4(a, b, c, d, 8, 6, T57); - SET4(d, a, b, c, 15, 10, T58); - SET4(c, d, a, b, 6, 15, T59); - SET4(b, c, d, a, 13, 21, T60); - SET4(a, b, c, d, 4, 6, T61); - SET4(d, a, b, c, 11, 10, T62); - SET4(c, d, a, b, 2, 15, T63); - SET4(b, c, d, a, 9, 21, T64); - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - pms->abcd[0] += a; - pms->abcd[1] += b; - pms->abcd[2] += c; - pms->abcd[3] += d; -} - -MIR_CORE_DLL(void) mir_md5_init(mir_md5_state_t *pms) -{ - pms->count[0] = pms->count[1] = 0; - pms->abcd[0] = 0x67452301; - pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - pms->abcd[3] = 0x10325476; -} - -MIR_CORE_DLL(void) mir_md5_append(mir_md5_state_t *pms, const mir_md5_byte_t *data, int nbytes) -{ - const mir_md5_byte_t *p = data; - int left = nbytes; - int offset = (pms->count[0] >> 3) & 63; - mir_md5_word_t nbits = (mir_md5_word_t)(nbytes << 3); - - if (nbytes <= 0) - return; - - /* Update the message length. */ - pms->count[1] += nbytes >> 29; - pms->count[0] += nbits; - if (pms->count[0] < nbits) - pms->count[1]++; - - /* Process an initial partial block. */ - if (offset) { - int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); - - memcpy(pms->buf + offset, p, copy); - if (offset + copy < 64) - return; - p += copy; - left -= copy; - md5_process(pms, pms->buf); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - md5_process(pms, p); - - /* Process a final partial block. */ - if (left) - memcpy(pms->buf, p, left); -} - -MIR_CORE_DLL(void) mir_md5_finish(mir_md5_state_t *pms, mir_md5_byte_t digest[16]) -{ - static const mir_md5_byte_t pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - mir_md5_byte_t data[8]; - int i; - - /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = (mir_md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); - /* Pad to 56 bytes mod 64. */ - mir_md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); - /* Append the length. */ - mir_md5_append(pms, data, 8); - for (i = 0; i < 16; ++i) - digest[i] = (mir_md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); -} - -MIR_CORE_DLL(void) mir_md5_hash(const mir_md5_byte_t *data, int len, mir_md5_byte_t digest[16]) -{ - mir_md5_state_t state; - mir_md5_init(&state); - mir_md5_append(&state, data, len); - mir_md5_finish(&state, digest); -} diff --git a/plugins/Mir_core/memory.cpp b/plugins/Mir_core/memory.cpp deleted file mode 100644 index 0ecddc6717..0000000000 --- a/plugins/Mir_core/memory.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* - -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. -*/ - -#include "commonheaders.h" - -#define BLOCK_ALLOCED 0xABBABABA -#define BLOCK_FREED 0xDEADBEEF - -static int CheckBlock(void* blk) -{ - int result = FALSE; - char* p = (char*)blk - sizeof(DWORD)*2; - DWORD size, *b, *e; - - __try - { - size = *(DWORD*)p; - b = (DWORD*)&p[ sizeof(DWORD) ]; - e = (DWORD*)&p[ sizeof(DWORD)*2 + size ]; - - if (*b != BLOCK_ALLOCED || *e != BLOCK_ALLOCED) - { - if (*b == BLOCK_FREED && *e == BLOCK_FREED) - OutputDebugStringA("memory block is already deleted\n"); - else - OutputDebugStringA("memory block is corrupted\n"); - #if defined(_DEBUG) - DebugBreak(); - #endif - } - else result = TRUE; - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - OutputDebugStringA("access violation during checking memory block\n"); - #if defined(_DEBUG) - DebugBreak(); - #endif - } - - return result; -} - -/******************************************************************************/ - -MIR_C_CORE_DLL(void*) mir_alloc(size_t size) -{ - if (size == 0) - return NULL; - { - char* p = (char*)malloc(size + sizeof(DWORD)*3); - if (p == NULL) { - OutputDebugStringA("memory overflow\n"); - #if defined(_DEBUG) - DebugBreak(); - #endif - return NULL; - } - - *(DWORD*)p = (DWORD)size; - *(DWORD*)&p[ sizeof(DWORD) ] = BLOCK_ALLOCED; - *(DWORD*)&p[ size + sizeof(DWORD)*2 ] = BLOCK_ALLOCED; - return p + sizeof(DWORD)*2; -} } - -/******************************************************************************/ - -MIR_C_CORE_DLL(void*) mir_calloc(size_t size) -{ - void* p = mir_alloc(size); - if (p != NULL) - memset(p, 0, size); - return p; -} - -/******************************************************************************/ - -MIR_C_CORE_DLL(void*) mir_realloc(void* ptr, size_t size) -{ - char* p; - - if (ptr != NULL) { - if ( !CheckBlock(ptr)) - return NULL; - p = (char*)ptr - sizeof(DWORD)*2; - } - else p = NULL; - - p = (char*)realloc(p, size + sizeof(DWORD)*3); - if (p == NULL) { - OutputDebugStringA("memory overflow\n"); - #if defined(_DEBUG) - DebugBreak(); - #endif - return NULL; - } - - *(DWORD*)p = (DWORD)size; - *(DWORD*)&p[ sizeof(DWORD) ] = BLOCK_ALLOCED; - *(DWORD*)&p[ size + sizeof(DWORD)*2 ] = BLOCK_ALLOCED; - return p + sizeof(DWORD)*2; -} - -/******************************************************************************/ - -MIR_C_CORE_DLL(void) mir_free(void* ptr) -{ - char* p; - DWORD size; - - if (ptr == NULL) - return; - if ( !CheckBlock(ptr)) - return; - - p = (char*)ptr - sizeof(DWORD)*2; - size = *(DWORD*)p; - *(DWORD*)&p[ sizeof(DWORD) ] = BLOCK_FREED; - *(DWORD*)&p[ size + sizeof(DWORD)*2 ] = BLOCK_FREED; - free(p); -} - -/******************************************************************************/ - -MIR_CORE_DLL(char*) mir_strdup(const char* str) -{ - if (str != NULL) { - char* p = (char*)mir_alloc(strlen(str)+1); - if (p) - strcpy(p, str); - return p; - } - return NULL; -} - -/******************************************************************************/ - -MIR_CORE_DLL(char*) mir_strndup(const char* str, size_t len) -{ - if (str != NULL && len != 0) { - char* p = (char*)mir_alloc(len + 1); - if ( !p) { - memcpy(p, str, len); - p[ len ] = 0; - } - return p; - } - return NULL; -} - -/******************************************************************************/ - -MIR_CORE_DLL(WCHAR*) mir_wstrdup(const WCHAR* str) -{ - if (str != NULL) { - WCHAR* p = (WCHAR*)mir_alloc(sizeof(WCHAR)*(wcslen(str)+1)); - if (p) - wcscpy(p, str); - return p; - } - return NULL; -} - -/******************************************************************************/ - -MIR_CORE_DLL(int) mir_snprintf(char *buffer, size_t count, const char* fmt, ...) -{ - va_list va; - int len; - - va_start(va, fmt); - len = _vsnprintf(buffer, count-1, fmt, va); - va_end(va); - buffer[count-1] = 0; - return len; -} - -/******************************************************************************/ - -MIR_CORE_DLL(int) mir_sntprintf(TCHAR *buffer, size_t count, const TCHAR* fmt, ...) -{ - va_list va; - int len; - - va_start(va, fmt); - len = _vsntprintf(buffer, count-1, fmt, va); - va_end(va); - buffer[count-1] = 0; - return len; -} - -/******************************************************************************/ - -MIR_CORE_DLL(int) mir_vsnprintf(char *buffer, size_t count, const char* fmt, va_list va) -{ - int len; - - len = _vsnprintf(buffer, count-1, fmt, va); - buffer[count-1] = 0; - return len; -} - -/******************************************************************************/ - -MIR_CORE_DLL(int) mir_vsntprintf(TCHAR *buffer, size_t count, const TCHAR* fmt, va_list va) -{ - int len; - - len = _vsntprintf(buffer, count-1, fmt, va); - buffer[count-1] = 0; - return len; -} - -/******************************************************************************/ - -MIR_CORE_DLL(wchar_t*) mir_a2u_cp(const char* src, int codepage) -{ - if (src == NULL) - return NULL; - - int cbLen = MultiByteToWideChar(codepage, 0, src, -1, NULL, 0); - wchar_t* result = (wchar_t*)mir_alloc(sizeof(wchar_t)*(cbLen+1)); - if (result == NULL) - return NULL; - - MultiByteToWideChar(codepage, 0, src, -1, result, cbLen); - result[ cbLen ] = 0; - return result; -} - -/******************************************************************************/ - -MIR_CORE_DLL(wchar_t*) mir_a2u(const char* src) -{ - return mir_a2u_cp(src, Langpack_GetDefaultCodePage()); -} - -/******************************************************************************/ - -MIR_CORE_DLL(char*) mir_u2a_cp(const wchar_t* src, int codepage) -{ - if (src == NULL) - return NULL; - - int cbLen = WideCharToMultiByte(codepage, 0, src, -1, NULL, 0, NULL, NULL); - char* result = (char*)mir_alloc(cbLen+1); - if (result == NULL) - return NULL; - - WideCharToMultiByte(codepage, 0, src, -1, result, cbLen, NULL, NULL); - result[ cbLen ] = 0; - return result; -} - -/******************************************************************************/ - -MIR_CORE_DLL(char*) mir_u2a(const wchar_t* src) -{ - return mir_u2a_cp(src, Langpack_GetDefaultCodePage()); -} diff --git a/plugins/Mir_core/mir_core.def b/plugins/Mir_core/mir_core.def deleted file mode 100644 index b985fa7efb..0000000000 --- a/plugins/Mir_core/mir_core.def +++ /dev/null @@ -1,127 +0,0 @@ -LIBRARY mir_core - -EXPORTS -CallContactService @1 -CallProtoService @2 -Langpack_LookupUuid @3 -Langpack_MarkPluginLoaded @4 -CallFunctionAsync @5 -CallPluginEventHook @7 -CallService @8 -CallServiceSync @9 -CreateDirectoryTree @10 -CreateDirectoryTreeW @11 -CreateHookableEvent @12 -CreatePathToFile @13 -CreatePathToFileW @14 -CreateServiceFunction @15 -CreateServiceFunctionObj @16 -CreateServiceFunctionObjParam @17 -CreateServiceFunctionParam @18 -DestroyHookableEvent @19 -DestroyServiceFunction @20 -GetExceptionFilter @21 -GetInstByAddress @22 -HookEvent @23 -HookEventMessage @24 -HookEventObj @25 -HookEventObjParam @26 -HookEventParam @27 -KillModuleEventHooks @28 -KillModuleServices @29 -KillObjectEventHooks @30 -KillObjectServices @31 -KillObjectThreads @32 -Langpack_SortDuplicates @33 -Langpack_GetDefaultCodePage @34 -Langpack_GetDefaultLocale @35 -Langpack_PcharToTchar @36 -List_Copy @37 -List_Create @38 -List_Destroy @39 -List_Find @40 -List_GetIndex @41 -List_IndexOf @42 -List_Insert @43 -List_InsertPtr @44 -List_ObjCopy @45 -List_Remove @46 -List_RemovePtr @47 -LoadLangPack @48 -LoadLangPackModule @49 -NotifyEventHooks @50 -PathToAbsolute @51 -PathToAbsoluteW @52 -PathToRelative @53 -PathToRelativeW @54 -RegisterModule @55 -ReloadLangpack @56 -ServiceExists @57 -SetExceptionFilter @58 -SetHookDefaultForHookableEvent @59 -Thread_Pop @60 -Thread_Push @61 -Thread_Wait @62 -TranslateA_LP @63 -TranslateDialog_LP @64 -TranslateMenu_LP @65 -TranslateW_LP @66 -Ucs2toUtf8Len @67 -UnhookEvent @68 -UnregisterModule @69 -Utf8Decode @70 -Utf8DecodeCP @71 -Utf8DecodeW @72 -Utf8Encode @73 -Utf8EncodeCP @74 -Utf8EncodeW @75 -forkthread @76 -forkthreadex @77 -ltrim @78 -ltrimp @79 -mir_a2u @80 -mir_a2u_cp @81 -mir_alloc @82 -mir_calloc @83 -mir_free @84 -mir_hash @85 -mir_md5_append @86 -mir_md5_finish @87 -mir_md5_hash @88 -mir_md5_init @89 -mir_realloc @90 -mir_sha1_append @91 -mir_sha1_finish @92 -mir_sha1_hash @93 -mir_sha1_init @94 -mir_strdup @95 -mir_strndup @96 -mir_u2a @97 -mir_u2a_cp @98 -mir_vsnprintf @99 -mir_vsntprintf @100 -mir_wstrdup @101 -rtrim @102 -wildcmp @103 -wrtrim @104 -mir_snprintf @105 -mir_sntprintf @106 -db_unset @107 -db_free @108 -db_get @109 -db_get_b @110 -db_get_dw @111 -db_get_s @112 -db_get_sa @113 -db_get_w @114 -db_get_wsa @115 -db_set_b @116 -db_set_blob @117 -db_set_dw @118 -db_set_s @119 -db_set_utf @120 -db_set_w @121 -db_set_ws @122 -UnloadCoreModule @123 -Thread_SetName @124 -Langpack_GetPluginHandle @125 diff --git a/plugins/Mir_core/mir_core_10.vcxproj b/plugins/Mir_core/mir_core_10.vcxproj deleted file mode 100644 index 03ea9c52e1..0000000000 --- a/plugins/Mir_core/mir_core_10.vcxproj +++ /dev/null @@ -1,238 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - - - - - - - - - Mir_core - {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60} - - - - DynamicLibrary - true - Unicode - - - DynamicLibrary - Unicode - - - DynamicLibrary - true - Unicode - - - DynamicLibrary - Unicode - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30128.1 - $(SolutionDir)$(Configuration)\ - $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ - $(SolutionDir)$(Configuration)64\ - $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ - $(SolutionDir)$(Configuration)\ - $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ - $(SolutionDir)$(Configuration)64\ - $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ - - - - Disabled - ..\..\include;%(AdditionalIncludeDirectories) - EnableFastChecks - MultiThreadedDebugDLL - true - Level3 - EditAndContinue - 4996;%(DisableSpecificWarnings) - WIN32;_DEBUG;_WINDOWS;MIR_CORE_EXPORTS;_USRDLL;%(PreprocessorDefinitions) - Use - commonheaders.h - - - _DEBUG;%(PreprocessorDefinitions) - ..\..\include\msapi - - - mir_core.def - true - false - Windows - miranda32.lib;ws2_32.lib;comctl32.lib;winmm.lib;version.lib;%(AdditionalDependencies) - $(SolutionDir)\lib - $(IntDir)$(TargetName).lib - - - - - - - - - - - - - Disabled - ..\..\include;%(AdditionalIncludeDirectories) - EnableFastChecks - MultiThreadedDebugDLL - true - Level3 - 4996;%(DisableSpecificWarnings) - WIN64;_DEBUG;_WINDOWS;MIR_CORE_EXPORTS;_USRDLL;%(PreprocessorDefinitions) - Use - commonheaders.h - - - _DEBUG;%(PreprocessorDefinitions) - ..\..\include\msapi - - - mir_core.def - true - false - $(IntDir)$(TargetName)64.lib - Windows - miranda64.lib;ws2_32.lib;comctl32.lib;winmm.lib;version.lib;%(AdditionalDependencies) - $(SolutionDir)\lib - /ignore:4197 %(AdditionalOptions) - - - - - Full - OnlyExplicitInline - Size - ..\..\include;%(AdditionalIncludeDirectories) - true - false - true - Level3 - 4996;%(DisableSpecificWarnings) - WIN32;NDEBUG;_WINDOWS;MIR_CORE_EXPORTS;_USRDLL;%(PreprocessorDefinitions) - Use - commonheaders.h - - - NDEBUG;%(PreprocessorDefinitions) - ..\..\include\msapi - - - mir_core.def - true - true - true - false - Windows - miranda32.lib;ws2_32.lib;comctl32.lib;winmm.lib;version.lib;%(AdditionalDependencies) - $(SolutionDir)\lib - $(IntDir)$(TargetName).lib - - - - - - - - - - - - - Full - OnlyExplicitInline - Size - ..\..\include;%(AdditionalIncludeDirectories) - true - false - true - Level3 - 4996;%(DisableSpecificWarnings) - WIN64;NDEBUG;_WINDOWS;MIR_CORE_EXPORTS;_USRDLL;%(PreprocessorDefinitions) - Use - commonheaders.h - - - NDEBUG;%(PreprocessorDefinitions) - ..\..\include\msapi - - - mir_core.def - true - true - true - false - $(IntDir)$(TargetName)64.lib - Windows - miranda64.lib;ws2_32.lib;comctl32.lib;winmm.lib;version.lib;%(AdditionalDependencies) - $(SolutionDir)\lib - /ignore:4197 %(AdditionalOptions) - - - - - - \ No newline at end of file diff --git a/plugins/Mir_core/mir_core_10.vcxproj.filters b/plugins/Mir_core/mir_core_10.vcxproj.filters deleted file mode 100644 index 27b6a42604..0000000000 --- a/plugins/Mir_core/mir_core_10.vcxproj.filters +++ /dev/null @@ -1,76 +0,0 @@ - - - - - {bf74d1c9-acd8-4fba-837d-734f024521c9} - cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - - - {a578a180-0eb9-4c3e-b4ae-0eaefa01d207} - - - - - 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 - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/plugins/Mir_core/miranda.cpp b/plugins/Mir_core/miranda.cpp deleted file mode 100644 index b059e11cb7..0000000000 --- a/plugins/Mir_core/miranda.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - -Miranda IM: the free IM client for Microsoft* Windows* - -Copyright 2000-2012 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. - -*/ - -#include "commonheaders.h" - -HWND hAPCWindow = NULL; - -int InitPathUtils(void); -void (*RecalculateTime)(void); - -int hLangpack = 0; -HINSTANCE hInst = 0; - -HANDLE hStackMutex, hThreadQueueEmpty; - -///////////////////////////////////////////////////////////////////////////////////////// -// module init - -static LRESULT CALLBACK APCWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (msg == WM_NULL) SleepEx(0, TRUE); - if (msg == WM_TIMECHANGE && RecalculateTime) - RecalculateTime(); - return DefWindowProc(hwnd, msg, wParam, lParam); -} - -static void LoadCoreModule(void) -{ - INITCOMMONCONTROLSEX icce = {0}; - icce.dwSize = sizeof(icce); - icce.dwICC = ICC_WIN95_CLASSES | ICC_USEREX_CLASSES; - InitCommonControlsEx(&icce); - - if ( IsWinVerXPPlus()) { - hAPCWindow=CreateWindowEx(0, _T("ComboLBox"), NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); - SetClassLongPtr(hAPCWindow, GCL_STYLE, GetClassLongPtr(hAPCWindow, GCL_STYLE) | CS_DROPSHADOW); - DestroyWindow(hAPCWindow); - hAPCWindow = NULL; - } - - hAPCWindow = CreateWindowEx(0, _T("STATIC"), NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); - SetWindowLongPtr(hAPCWindow, GWLP_WNDPROC, (LONG_PTR)APCWndProc); - hStackMutex = CreateMutex(NULL, FALSE, NULL); - hThreadQueueEmpty = CreateEvent(NULL, TRUE, TRUE, NULL); - - #ifdef WIN64 - HMODULE mirInst = GetModuleHandleA("miranda64.exe"); - #else - HMODULE mirInst = GetModuleHandleA("miranda32.exe"); - #endif - RecalculateTime = (void (*)()) GetProcAddress(mirInst, "RecalculateTime"); - - InitPathUtils(); - InitialiseModularEngine(); -} - -MIR_CORE_DLL(void) UnloadCoreModule(void) -{ - DestroyWindow(hAPCWindow); - CloseHandle(hStackMutex); - - DestroyModularEngine(); - UnloadLangPackModule(); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// entry point - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - if (fdwReason == DLL_PROCESS_ATTACH) { - hInst = hinstDLL; - LoadCoreModule(); - } - return TRUE; -} diff --git a/plugins/Mir_core/miranda.h b/plugins/Mir_core/miranda.h deleted file mode 100644 index 06aae73420..0000000000 --- a/plugins/Mir_core/miranda.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - -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. -*/ - -#define NEWSTR_ALLOCA(A) (A == NULL)?NULL:strcpy((char*)alloca(strlen(A)+1), A) -#define NEWTSTR_ALLOCA(A) (A == NULL)?NULL:_tcscpy((TCHAR*)alloca((_tcslen(A)+1)* sizeof(TCHAR)), A) - -extern "C" -{ - MIR_CORE_DLL(int) Langpack_GetPluginHandle(PLUGININFOEX* pInfo); - MIR_CORE_DLL(int) Langpack_MarkPluginLoaded(PLUGININFOEX* pInfo); -}; - -MIR_CORE_DLL(MUUID*) Langpack_LookupUuid(WPARAM wParam); - -void UnloadLangPackModule(void); - -int InitialiseModularEngine(void); -void DestroyModularEngine(void); - -int InitPathUtils(void); - -extern HINSTANCE hInst; -extern HWND hAPCWindow; -extern HANDLE hStackMutex, hThreadQueueEmpty; - -/**** modules.cpp **********************************************************************/ - -struct THookSubscriber -{ - HINSTANCE hOwner; - int type; - union { - struct { - union { - MIRANDAHOOK pfnHook; - MIRANDAHOOKPARAM pfnHookParam; - MIRANDAHOOKOBJ pfnHookObj; - MIRANDAHOOKOBJPARAM pfnHookObjParam; - }; - void* object; - LPARAM lParam; - }; - struct { - HWND hwnd; - UINT message; - }; - }; -}; - -#define HOOK_SECRET_SIGNATURE 0xDEADBABA - -struct THook -{ - char name[ MAXMODULELABELLENGTH ]; - int id; - int subscriberCount; - THookSubscriber* subscriber; - MIRANDAHOOK pfnHook; - DWORD secretSignature; - CRITICAL_SECTION csHook; -}; - -extern LIST pluginListAddr; - -/**** langpack.cpp *********************************************************************/ - -char* LangPackTranslateString(MUUID* pUuid, const char *szEnglish, const int W); -TCHAR* LangPackTranslateStringT(int hLangpack, const TCHAR* tszEnglish); - -/**** options.cpp **********************************************************************/ - -HTREEITEM FindNamedTreeItemAtRoot(HWND hwndTree, const TCHAR* name); - -/**** utils.cpp ************************************************************************/ - -void HotkeyToName(TCHAR *buf, int size, BYTE shift, BYTE key); -WORD GetHotkeyValue(INT_PTR idHotkey); - -HBITMAP ConvertIconToBitmap(HICON hIcon, HIMAGELIST hIml, int iconId); - -class StrConvUT -{ -private: - wchar_t* m_body; - -public: - StrConvUT(const char* pSrc) : - m_body(mir_a2u(pSrc)) {} - - ~StrConvUT() { mir_free(m_body); } - operator const wchar_t* () const { return m_body; } -}; - -class StrConvAT -{ -private: - char* m_body; - -public: - StrConvAT(const wchar_t* pSrc) : - m_body(mir_u2a(pSrc)) {} - - ~StrConvAT() { mir_free(m_body); } - operator const char* () const { return m_body; } - operator const wchar_t* () const { return (wchar_t*)m_body; } // type cast to fake the interface definition - operator const LPARAM () const { return (LPARAM)m_body; } -}; - -#define StrConvT(x) StrConvUT(x) -#define StrConvTu(x) x -#define StrConvA(x) StrConvAT(x) -#define StrConvU(x) x diff --git a/plugins/Mir_core/modules.cpp b/plugins/Mir_core/modules.cpp deleted file mode 100644 index f87c7bb192..0000000000 --- a/plugins/Mir_core/modules.cpp +++ /dev/null @@ -1,601 +0,0 @@ -/* - -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. -*/ - -#include "commonheaders.h" -#include - -// list of hooks - -static int compareHooks(const THook* p1, const THook* p2) -{ - return strcmp(p1->name, p2->name); -} - -static LIST hooks(50, compareHooks); - -struct THookToMainThreadItem -{ - THook* hook; - HANDLE hDoneEvent; - WPARAM wParam; - LPARAM lParam; - int result; -}; - -// list of services - -struct TService -{ - DWORD nameHash; - HINSTANCE hOwner; - union { - MIRANDASERVICE pfnService; - MIRANDASERVICEPARAM pfnServiceParam; - MIRANDASERVICEOBJ pfnServiceObj; - MIRANDASERVICEOBJPARAM pfnServiceObjParam; - }; - int flags; - LPARAM lParam; - void* object; - char name[1]; -}; - -LIST services(100, NumericKeySortT); - -typedef struct -{ - HANDLE hDoneEvent; - WPARAM wParam; - LPARAM lParam; - int result; - const char *name; -} - TServiceToMainThreadItem; - -// other static variables -static BOOL bServiceMode = FALSE; -static CRITICAL_SECTION csHooks, csServices; -static DWORD mainThreadId; -static int hookId = 1; -static HANDLE hMainThread; -static HANDLE hMissingService; -static THook *pLastHook = NULL; - -///////////////////////////////////////////////////////////////////////////////////////// - -static int QueueMainThread(PAPCFUNC pFunc, void* pParam, HANDLE hDoneEvent) -{ - int result = QueueUserAPC(pFunc, hMainThread, (ULONG_PTR)pParam); - PostMessage(hAPCWindow, WM_NULL, 0, 0); // let this get processed in its own time - if (hDoneEvent) { - WaitForSingleObject(hDoneEvent, INFINITE); - CloseHandle(hDoneEvent); - } - return result; -} - -/////////////////////////////////////////////////////////////////////////////// -// HOOKS - -MIR_CORE_DLL(HANDLE) CreateHookableEvent(const char *name) -{ - if (name == NULL) - return NULL; - - mir_cslock lck(csHooks); - - int idx; - if ((idx = hooks.getIndex((THook*)name)) != -1) - return hooks[idx]; - - THook* newItem = (THook*)mir_alloc(sizeof(THook)); - strncpy(newItem->name, name, sizeof(newItem->name)); newItem->name[ MAXMODULELABELLENGTH-1 ] = 0; - newItem->id = hookId++; - newItem->subscriberCount = 0; - newItem->subscriber = NULL; - newItem->pfnHook = NULL; - newItem->secretSignature = HOOK_SECRET_SIGNATURE; - InitializeCriticalSection(&newItem->csHook); - hooks.insert(newItem); - return (HANDLE)newItem; -} - -MIR_CORE_DLL(int) DestroyHookableEvent(HANDLE hEvent) -{ - if (pLastHook == (THook*)hEvent) - pLastHook = NULL; - - mir_cslock lck(csHooks); - - int idx; - if ((idx = hooks.getIndex((THook*)hEvent)) == -1) - return 1; - - THook* p = hooks[idx]; - p->secretSignature = 0; - if (p->subscriberCount) { - mir_free(p->subscriber); - p->subscriber = NULL; - p->subscriberCount = 0; - } - hooks.remove(idx); - DeleteCriticalSection(&p->csHook); - mir_free(p); - return 0; -} - -MIR_CORE_DLL(int) SetHookDefaultForHookableEvent(HANDLE hEvent, MIRANDAHOOK pfnHook) -{ - THook* p = (THook*)hEvent; - - mir_cslock lck(csHooks); - if (hooks.getIndex(p) != -1) - p->pfnHook = pfnHook; - return 0; -} - -MIR_CORE_DLL(int) CallPluginEventHook(HINSTANCE hInst, HANDLE hEvent, WPARAM wParam, LPARAM lParam) -{ - THook* p = (THook*)hEvent; - if (p == NULL) - return -1; - - mir_cslock lck(p->csHook); - for (int i = 0; i < p->subscriberCount; i++) { - THookSubscriber* s = &p->subscriber[i]; - if (s->hOwner != hInst) - continue; - - int returnVal; - switch (s->type) { - case 1: returnVal = s->pfnHook(wParam, lParam); break; - case 2: returnVal = s->pfnHookParam(wParam, lParam, s->lParam); break; - case 3: returnVal = s->pfnHookObj(s->object, wParam, lParam); break; - case 4: returnVal = s->pfnHookObjParam(s->object, wParam, lParam, s->lParam); break; - case 5: returnVal = SendMessage(s->hwnd, s->message, wParam, lParam); break; - default: continue; - } - if (returnVal) - return returnVal; - } - - if (p->subscriberCount == 0 && p->pfnHook != 0) - return p->pfnHook(wParam, lParam); - - return 0; -} - -static int CallHookSubscribers(THook* p, WPARAM wParam, LPARAM lParam) -{ - if (p == NULL) - return -1; - - mir_cslock lck(p->csHook); - - // NOTE: We've got the critical section while all this lot are called. That's mostly safe, though. - for (int i = 0; i < p->subscriberCount; i++) { - THookSubscriber* s = &p->subscriber[i]; - - int returnVal; - switch (s->type) { - case 1: returnVal = s->pfnHook(wParam, lParam); break; - case 2: returnVal = s->pfnHookParam(wParam, lParam, s->lParam); break; - case 3: returnVal = s->pfnHookObj(s->object, wParam, lParam); break; - case 4: returnVal = s->pfnHookObjParam(s->object, wParam, lParam, s->lParam); break; - case 5: returnVal = SendMessage(s->hwnd, s->message, wParam, lParam); break; - default: continue; - } - if (returnVal) - return returnVal; - } - - // call the default hook if any - if (p->pfnHook != 0) - return p->pfnHook(wParam, lParam); - - return 0; -} - -enum { hookOk, hookEmpty, hookInvalid }; - -__forceinline int checkHook(THook* p) -{ - if (p == NULL) - return hookInvalid; - - int ret; - __try - { - if (p->secretSignature != HOOK_SECRET_SIGNATURE) - ret = hookInvalid; - else if (p->subscriberCount == 0 && p->pfnHook == NULL) - ret = hookEmpty; - else - ret = hookOk; - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - ret = hookInvalid; - } - - return ret; -} - -static void CALLBACK HookToMainAPCFunc(ULONG_PTR dwParam) -{ - THookToMainThreadItem* item = (THookToMainThreadItem*)dwParam; - item->result = CallHookSubscribers(item->hook, item->wParam, item->lParam); - SetEvent(item->hDoneEvent); -} - -MIR_CORE_DLL(int) NotifyEventHooks(HANDLE hEvent, WPARAM wParam, LPARAM lParam) -{ - switch ( checkHook((THook*)hEvent)) { - case hookInvalid: return -1; - case hookEmpty: return 0; - } - - if ( GetCurrentThreadId() == mainThreadId) - return CallHookSubscribers((THook*)hEvent, wParam, lParam); - - mir_ptr item; - item->hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - item->hook = (THook*)hEvent; - item->wParam = wParam; - item->lParam = lParam; - QueueMainThread(HookToMainAPCFunc, item, item->hDoneEvent); - return item->result; -} - -static HANDLE HookEventInt(int type, const char* name, MIRANDAHOOK hookProc, void* object, LPARAM lParam) -{ - mir_cslock lck(csHooks); - - int idx; - if ((idx = hooks.getIndex((THook*)name)) == -1) - return NULL; - - THook* p = hooks[ idx ]; - p->subscriber = (THookSubscriber*)mir_realloc(p->subscriber, sizeof(THookSubscriber)*(p->subscriberCount+1)); - p->subscriber[ p->subscriberCount ].type = type; - p->subscriber[ p->subscriberCount ].pfnHook = hookProc; - p->subscriber[ p->subscriberCount ].object = object; - p->subscriber[ p->subscriberCount ].lParam = lParam; - p->subscriber[ p->subscriberCount ].hOwner = GetInstByAddress(hookProc); - p->subscriberCount++; - - return (HANDLE)((p->id << 16) | p->subscriberCount); -} - -MIR_CORE_DLL(HANDLE) HookEvent(const char* name, MIRANDAHOOK hookProc) -{ - return HookEventInt(1, name, hookProc, 0, 0); -} - -MIR_CORE_DLL(HANDLE) HookEventParam(const char* name, MIRANDAHOOKPARAM hookProc, LPARAM lParam) -{ - return HookEventInt(2, name, (MIRANDAHOOK)hookProc, 0, lParam); -} - -MIR_CORE_DLL(HANDLE) HookEventObj(const char* name, MIRANDAHOOKOBJ hookProc, void* object) -{ - return HookEventInt(3, name, (MIRANDAHOOK)hookProc, object, 0); -} - -MIR_CORE_DLL(HANDLE) HookEventObjParam(const char* name, MIRANDAHOOKOBJPARAM hookProc, void* object, LPARAM lParam) -{ - return HookEventInt(4, name, (MIRANDAHOOK)hookProc, object, lParam); -} - -MIR_CORE_DLL(HANDLE) HookEventMessage(const char* name, HWND hwnd, UINT message) -{ - mir_cslock lck(csHooks); - - int idx; - if ((idx = hooks.getIndex((THook*)name)) == -1) - return NULL; - - THook* p = hooks[ idx ]; - p->subscriber = (THookSubscriber*)mir_realloc(p->subscriber, sizeof(THookSubscriber)*(p->subscriberCount+1)); - p->subscriber[ p->subscriberCount ].type = 5; - p->subscriber[ p->subscriberCount ].hwnd = hwnd; - p->subscriber[ p->subscriberCount ].message = message; - p->subscriberCount++; - return (HANDLE)((p->id << 16) | p->subscriberCount); -} - -MIR_CORE_DLL(int) UnhookEvent(HANDLE hHook) -{ - if (hHook == NULL) - return 0; - - int hookId = (int)hHook >> 16; - int subscriberId = ((int)hHook & 0xFFFF) - 1; - - mir_cslock lck(csHooks); - - THook* p = NULL; - for (int i = 0; i < hooks.getCount(); i++) - if (hooks[i]->id == hookId) { - p = hooks[i]; - break; - } - - if (p == NULL) - return 1; - - if (subscriberId >= p->subscriberCount || subscriberId < 0) - return 1; - - p->subscriber[subscriberId].type = 0; - p->subscriber[subscriberId].pfnHook = NULL; - p->subscriber[subscriberId].hOwner = NULL; - while (p->subscriberCount && p->subscriber[p->subscriberCount-1].type == 0) - p->subscriberCount--; - if (p->subscriberCount == 0) { - if (p->subscriber) mir_free(p->subscriber); - p->subscriber = NULL; - } - return 0; -} - -MIR_CORE_DLL(void) KillModuleEventHooks(HINSTANCE hInst) -{ - mir_cslock lck(csHooks); - - for (int i = hooks.getCount()-1; i >= 0; i--) { - if (hooks[i]->subscriberCount == 0) - continue; - - for (int j = hooks[i]->subscriberCount-1; j >= 0; j--) { - if (hooks[i]->subscriber[j].hOwner != hInst) - continue; - - char szModuleName[ MAX_PATH ]; - GetModuleFileNameA(hooks[i]->subscriber[j].hOwner, szModuleName, sizeof(szModuleName)); - UnhookEvent((HANDLE)((hooks[i]->id << 16) + j + 1)); - if (hooks[i]->subscriberCount == 0) - break; - } - } -} - -MIR_CORE_DLL(void) KillObjectEventHooks(void* pObject) -{ - mir_cslock lck(csHooks); - - for (int i = hooks.getCount()-1; i >= 0; i--) { - if (hooks[i]->subscriberCount == 0) - continue; - - for (int j = hooks[i]->subscriberCount-1; j >= 0; j--) { - if (hooks[i]->subscriber[j].object == pObject) { - UnhookEvent((HANDLE)((hooks[i]->id << 16) + j + 1)); - if (hooks[i]->subscriberCount == 0) - break; - } - } - } -} - -static void DestroyHooks() -{ - mir_cslock lck(csHooks); - - for (int i=0; i < hooks.getCount(); i++) { - THook* p = hooks[i]; - if (p->subscriberCount) - mir_free(p->subscriber); - DeleteCriticalSection(&p->csHook); - mir_free(p); - } -} - -/////////////////////SERVICES - -static __inline TService* FindServiceByName(const char *name) -{ - unsigned hash = mir_hashstr(name); - return services.find((TService*)&hash); -} - -static HANDLE CreateServiceInt(int type, const char *name, MIRANDASERVICE serviceProc, void* object, LPARAM lParam) -{ - if (name == NULL) - return NULL; - - TService tmp; - tmp.nameHash = mir_hashstr(name); - - mir_cslock lck(csServices); - - if (services.getIndex(&tmp) != -1) - return NULL; - - TService* p = (TService*)mir_alloc(sizeof(*p) + strlen(name)); - strcpy(p->name, name); - p->nameHash = tmp.nameHash; - p->pfnService = serviceProc; - p->hOwner = GetInstByAddress(serviceProc); - p->flags = type; - p->lParam = lParam; - p->object = object; - services.insert(p); - - return (HANDLE)tmp.nameHash; -} - -MIR_CORE_DLL(HANDLE) CreateServiceFunction(const char *name, MIRANDASERVICE serviceProc) -{ - return CreateServiceInt(0, name, serviceProc, 0, 0); -} - -MIR_CORE_DLL(HANDLE) CreateServiceFunctionParam(const char *name, MIRANDASERVICEPARAM serviceProc, LPARAM lParam) -{ - return CreateServiceInt(1, name, (MIRANDASERVICE)serviceProc, 0, lParam); -} - -MIR_CORE_DLL(HANDLE) CreateServiceFunctionObj(const char *name, MIRANDASERVICEOBJ serviceProc, void* object) -{ - return CreateServiceInt(2, name, (MIRANDASERVICE)serviceProc, object, 0); -} - -MIR_CORE_DLL(HANDLE) CreateServiceFunctionObjParam(const char *name, MIRANDASERVICEOBJPARAM serviceProc, void* object, LPARAM lParam) -{ - return CreateServiceInt(3, name, (MIRANDASERVICE)serviceProc, object, lParam); -} - -MIR_CORE_DLL(int) DestroyServiceFunction(HANDLE hService) -{ - mir_cslock lck(csServices); - - int idx; - if ((idx = services.getIndex((TService*)&hService)) != -1) { - mir_free(services[idx]); - services.remove(idx); - } - - return 0; -} - -MIR_CORE_DLL(int) ServiceExists(const char *name) -{ - if (name == NULL) - return FALSE; - - mir_cslock lck(csServices); - return FindServiceByName(name) != NULL; -} - -MIR_CORE_DLL(INT_PTR) CallService(const char *name, WPARAM wParam, LPARAM lParam) -{ - if (name == NULL) - return CALLSERVICE_NOTFOUND; - - TService *pService; - { - mir_cslock lck(csServices); - if ((pService = FindServiceByName(name)) == NULL) - return CALLSERVICE_NOTFOUND; - } - - MIRANDASERVICE pfnService = pService->pfnService; - int flags = pService->flags; - LPARAM fnParam = pService->lParam; - void* object = pService->object; - switch(flags) { - case 1: return ((MIRANDASERVICEPARAM)pfnService)(wParam, lParam, fnParam); - case 2: return ((MIRANDASERVICEOBJ)pfnService)(object, wParam, lParam); - case 3: return ((MIRANDASERVICEOBJPARAM)pfnService)(object, wParam, lParam, fnParam); - default: return pfnService(wParam, lParam); -} } - -static void CALLBACK CallServiceToMainAPCFunc(ULONG_PTR dwParam) -{ - TServiceToMainThreadItem *item = (TServiceToMainThreadItem*) dwParam; - item->result = CallService(item->name, item->wParam, item->lParam); - SetEvent(item->hDoneEvent); -} - -MIR_CORE_DLL(INT_PTR) CallServiceSync(const char *name, WPARAM wParam, LPARAM lParam) -{ - if (name == NULL) - return CALLSERVICE_NOTFOUND; - - // the service is looked up within the main thread, since the time it takes - // for the APC queue to clear the service being called maybe removed. - // even thou it may exists before the call, the critsec can't be locked between calls. - if (GetCurrentThreadId() == mainThreadId) - return CallService(name, wParam, lParam); - - mir_ptr item; - item->wParam = wParam; - item->lParam = lParam; - item->name = name; - item->hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - QueueMainThread(CallServiceToMainAPCFunc, item, item->hDoneEvent); - return item->result; -} - -MIR_CORE_DLL(int) CallFunctionAsync(void (__stdcall *func)(void *), void *arg) -{ - QueueMainThread((PAPCFUNC)func, arg, 0); - return 0; -} - -MIR_CORE_DLL(void) KillModuleServices(HINSTANCE hInst) -{ - mir_cslock lck(csServices); - - for (int i = services.getCount()-1; i >= 0; i--) { - if (services[i]->hOwner == hInst) { - char szModuleName[ MAX_PATH ]; - GetModuleFileNameA(services[i]->hOwner, szModuleName, sizeof(szModuleName)); - DestroyServiceFunction((HANDLE)services[i]->nameHash); - } - } -} - -MIR_CORE_DLL(void) KillObjectServices(void* pObject) -{ - mir_cslock lck(csServices); - - for (int i = services.getCount()-1; i >= 0; i--) - if (services[i]->object == pObject) - DestroyServiceFunction((HANDLE)services[i]->nameHash); -} - -static void DestroyServices() -{ - mir_cslock lck(csServices); - - for (int j=0; j < services.getCount(); j++) - mir_free(services[j]); -} - -/////////////////////////////////////////////////////////////////////////////// - -int InitialiseModularEngine(void) -{ - InitializeCriticalSection(&csHooks); - InitializeCriticalSection(&csServices); - - mainThreadId = GetCurrentThreadId(); - DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hMainThread, 0, FALSE, DUPLICATE_SAME_ACCESS); - - hMissingService = CreateHookableEvent(ME_SYSTEM_MISSINGSERVICE); - return 0; -} - -void DestroyModularEngine(void) -{ - DestroyHooks(); - hooks.destroy(); - DeleteCriticalSection(&csHooks); - - DestroyServices(); - services.destroy(); - DeleteCriticalSection(&csServices); - - CloseHandle(hMainThread); -} diff --git a/plugins/Mir_core/path.cpp b/plugins/Mir_core/path.cpp deleted file mode 100644 index fada3dcd18..0000000000 --- a/plugins/Mir_core/path.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - -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. -*/ -#include "commonheaders.h" - -static char szMirandaPath[MAX_PATH]; -static char szMirandaPathLower[MAX_PATH]; -static TCHAR szMirandaPathW[MAX_PATH]; -static TCHAR szMirandaPathWLower[MAX_PATH]; - -static int pathIsAbsolute(const char *path) -{ - if (strlen(path) <= 2) - return 0; - if ((path[1] == ':' && path[2] == '\\') || (path[0] == '\\' && path[1] == '\\')) - return 1; - return 0; -} - -MIR_CORE_DLL(int) PathToRelative(const char *pSrc, char *pOut) -{ - if ( !pSrc || !strlen(pSrc) || strlen(pSrc)>MAX_PATH) return 0; - if ( !pathIsAbsolute(pSrc)) { - mir_snprintf(pOut, MAX_PATH, "%s", pSrc); - return (int)strlen(pOut); - } - - char szTmp[MAX_PATH]; - mir_snprintf(szTmp, SIZEOF(szTmp), "%s", pSrc); - _strlwr(szTmp); - if (strstr(szTmp, szMirandaPathLower)) { - mir_snprintf(pOut, MAX_PATH, "%s", pSrc+strlen(szMirandaPathLower)); - return (int)strlen(pOut); - } - else { - mir_snprintf(pOut, MAX_PATH, "%s", pSrc); - return (int)strlen(pOut); - } -} - -MIR_CORE_DLL(int) PathToAbsolute(const char *pSrc, char *pOut, char* base) -{ - if ( !pSrc || !strlen(pSrc) || strlen(pSrc) > MAX_PATH) - return 0; - - if (base == NULL) - base = szMirandaPath; - - char buf[MAX_PATH]; - if (pSrc[0] < ' ') - return mir_snprintf(pOut, MAX_PATH, "%s", pSrc); - else if (pathIsAbsolute(pSrc)) - return GetFullPathNameA(pSrc, MAX_PATH, pOut, NULL); - else if (pSrc[0] != '\\') - mir_snprintf(buf, MAX_PATH, "%s%s", base, pSrc); - else - mir_snprintf(buf, MAX_PATH, "%s%s", base, pSrc+1); - - return GetFullPathNameA(buf, MAX_PATH, pOut, NULL); -} - -MIR_CORE_DLL(void) CreatePathToFile(char* szFilePath) -{ - char* pszLastBackslash = strrchr(szFilePath, '\\'); - if (pszLastBackslash == NULL) - return; - - *pszLastBackslash = '\0'; - CreateDirectoryTree(szFilePath); - *pszLastBackslash = '\\'; -} - -MIR_CORE_DLL(int) CreateDirectoryTree(const char *szDir) -{ - DWORD dwAttributes; - char *pszLastBackslash, szTestDir[ MAX_PATH ]; - - lstrcpynA(szTestDir, szDir, SIZEOF(szTestDir)); - if ((dwAttributes = GetFileAttributesA(szTestDir)) != INVALID_FILE_ATTRIBUTES && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)) - return 0; - - pszLastBackslash = strrchr(szTestDir, '\\'); - if (pszLastBackslash == NULL) - return 0; - - *pszLastBackslash = '\0'; - CreateDirectoryTree(szTestDir); - *pszLastBackslash = '\\'; - return (CreateDirectoryA(szTestDir, NULL) == 0) ? GetLastError() : 0; -} - -/////////////////////////////////////////////////////////////////////////////// - -static int pathIsAbsoluteW(const TCHAR *path) -{ - if (lstrlen(path) <= 2) - return 0; - if ((path[1] == ':' && path[2] == '\\') || (path[0] == '\\' && path[1] == '\\')) - return 1; - return 0; -} - -MIR_CORE_DLL(int) PathToRelativeW(const WCHAR *pSrc, WCHAR *pOut) -{ - if ( !pSrc || !lstrlen(pSrc) || lstrlen(pSrc) > MAX_PATH) - return 0; - - if ( !pathIsAbsoluteW(pSrc)) - mir_sntprintf(pOut, MAX_PATH, _T("%s"), pSrc); - else { - TCHAR szTmp[MAX_PATH]; - - mir_sntprintf(szTmp, SIZEOF(szTmp), _T("%s"), pSrc); - _tcslwr(szTmp); - if (_tcsstr(szTmp, szMirandaPathWLower)) - mir_sntprintf(pOut, MAX_PATH, _T("%s"), pSrc+lstrlen(szMirandaPathWLower)); - else - mir_sntprintf(pOut, MAX_PATH, _T("%s"), pSrc); - } - return lstrlen(pOut); -} - -MIR_CORE_DLL(int) PathToAbsoluteW(const TCHAR *pSrc, TCHAR *pOut, TCHAR* base) -{ - if ( !pSrc || !wcslen(pSrc) || wcslen(pSrc) > MAX_PATH) - return 0; - - if (base == NULL) - base = szMirandaPathW; - - TCHAR buf[MAX_PATH]; - if (pSrc[0] < ' ') - return mir_sntprintf(pOut, MAX_PATH, _T("%s"), pSrc); - else if (pathIsAbsoluteW(pSrc)) - return GetFullPathName(pSrc, MAX_PATH, pOut, NULL); - else if (pSrc[0] != '\\') - mir_sntprintf(buf, MAX_PATH, _T("%s%s"), base, pSrc); - else - mir_sntprintf(buf, MAX_PATH, _T("%s%s"), base, pSrc+1); - - return GetFullPathName(buf, MAX_PATH, pOut, NULL); -} - -MIR_CORE_DLL(void) CreatePathToFileW(WCHAR* wszFilePath) -{ - WCHAR* pszLastBackslash = wcsrchr(wszFilePath, '\\'); - if (pszLastBackslash == NULL) - return; - - *pszLastBackslash = '\0'; - CreateDirectoryTreeW(wszFilePath); - *pszLastBackslash = '\\'; -} - -MIR_CORE_DLL(int) CreateDirectoryTreeW(const WCHAR* szDir) -{ - DWORD dwAttributes; - WCHAR* pszLastBackslash, szTestDir[ MAX_PATH ]; - - lstrcpynW(szTestDir, szDir, SIZEOF(szTestDir)); - if ((dwAttributes = GetFileAttributesW(szTestDir)) != INVALID_FILE_ATTRIBUTES && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)) - return 0; - - pszLastBackslash = wcsrchr(szTestDir, '\\'); - if (pszLastBackslash == NULL) - return 0; - - *pszLastBackslash = '\0'; - CreateDirectoryTreeW(szTestDir); - *pszLastBackslash = '\\'; - return (CreateDirectoryW(szTestDir, NULL) == 0) ? GetLastError() : 0; -} - -int InitPathUtils(void) -{ - char *p = 0; - GetModuleFileNameA(hInst, szMirandaPath, SIZEOF(szMirandaPath)); - p = strrchr(szMirandaPath, '\\'); - if (p) - p[1] = 0; - mir_snprintf(szMirandaPathLower, MAX_PATH, "%s", szMirandaPath); - _strlwr(szMirandaPathLower); - - GetModuleFileName(hInst, szMirandaPathW, SIZEOF(szMirandaPathW)); - TCHAR *tp = _tcsrchr(szMirandaPathW, '\\'); - if (tp) - tp[1] = 0; - mir_sntprintf(szMirandaPathWLower, SIZEOF(szMirandaPathWLower), _T("%s"), szMirandaPathW); - _tcslwr(szMirandaPathWLower); - return 0; -} diff --git a/plugins/Mir_core/sha1.cpp b/plugins/Mir_core/sha1.cpp deleted file mode 100644 index 9e1b376d92..0000000000 --- a/plugins/Mir_core/sha1.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is SHA 180-1 Reference Implementation (Compact version). - * - * The Initial Developer of the Original Code is - * Paul Kocher of Cryptography Research. - * Portions created by the Initial Developer are Copyright (C) 1995-9 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "commonheaders.h" - -#define SHA_ROTL(X, n) (((X) << (n)) | ((X) >> (32-(n)))) - -static void shaHashBlock(mir_sha1_ctx *ctx) -{ - int t; - unsigned long A, B, C, D, E, TEMP; - - for (t = 16; t <= 79; t++) - ctx->W[t] = - SHA_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1); - - A = ctx->H[0]; - B = ctx->H[1]; - C = ctx->H[2]; - D = ctx->H[3]; - E = ctx->H[4]; - - for (t = 0; t <= 19; t++) { - TEMP = SHA_ROTL(A, 5) + (((C^D)&B)^D) + E + ctx->W[t] + 0x5a827999L; - E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; - } - for (t = 20; t <= 39; t++) { - TEMP = SHA_ROTL(A, 5) + (B^C^D) + E + ctx->W[t] + 0x6ed9eba1L; - E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; - } - for (t = 40; t <= 59; t++) { - TEMP = SHA_ROTL(A, 5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdcL; - E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; - } - for (t = 60; t <= 79; t++) { - TEMP = SHA_ROTL(A, 5) + (B^C^D) + E + ctx->W[t] + 0xca62c1d6L; - E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; - } - - ctx->H[0] += A; - ctx->H[1] += B; - ctx->H[2] += C; - ctx->H[3] += D; - ctx->H[4] += E; -} - -MIR_CORE_DLL(void) mir_sha1_init(mir_sha1_ctx *ctx) -{ - ctx->lenW = 0; - ctx->sizeHi = ctx->sizeLo = 0; - - /* Initialize H with the magic constants (see FIPS180 for constants) - */ - ctx->H[0] = 0x67452301L; - ctx->H[1] = 0xefcdab89L; - ctx->H[2] = 0x98badcfeL; - ctx->H[3] = 0x10325476L; - ctx->H[4] = 0xc3d2e1f0L; - - for (int i = 0; i < 80; i++) - ctx->W[i] = 0; -} - -MIR_CORE_DLL(void) mir_sha1_append(mir_sha1_ctx *ctx, mir_sha1_byte_t *dataIn, int len) -{ - /* Read the data into W and process blocks as they get full - */ - for (int i = 0; i < len; i++) { - ctx->W[ctx->lenW / 4] <<= 8; - ctx->W[ctx->lenW / 4] |= (unsigned long)dataIn[i]; - if ((++ctx->lenW) % 64 == 0) { - shaHashBlock(ctx); - ctx->lenW = 0; - } - ctx->sizeLo += 8; - ctx->sizeHi += (ctx->sizeLo < 8); - } -} - -MIR_CORE_DLL(void) mir_sha1_finish(mir_sha1_ctx *ctx, mir_sha1_byte_t hashout[20]) -{ - unsigned char pad0x80 = 0x80; - unsigned char pad0x00 = 0x00; - unsigned char padlen[8]; - int i; - - /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length - */ - padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255); - padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255); - padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255); - padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255); - padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255); - padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255); - padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255); - padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255); - mir_sha1_append(ctx, &pad0x80, 1); - while (ctx->lenW != 56) - mir_sha1_append(ctx, &pad0x00, 1); - mir_sha1_append(ctx, padlen, 8); - - /* Output hash - */ - for (i = 0; i < 20; i++) { - hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24); - ctx->H[i / 4] <<= 8; - } - - /* - * Re-initialize the context (also zeroizes contents) - */ - mir_sha1_init(ctx); -} - -MIR_CORE_DLL(void) mir_sha1_hash(mir_sha1_byte_t *dataIn, int len, mir_sha1_byte_t hashout[20]) -{ - mir_sha1_ctx ctx; - - mir_sha1_init(&ctx); - mir_sha1_append(&ctx, dataIn, len); - mir_sha1_finish(&ctx, hashout); -} diff --git a/plugins/Mir_core/threads.cpp b/plugins/Mir_core/threads.cpp deleted file mode 100644 index 90dcdaaf5d..0000000000 --- a/plugins/Mir_core/threads.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/* - -Miranda IM: the free IM client for Microsoft* Windows* - -Copyright 2000-2012 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. - -*/ - -#include "commonheaders.h" - -///////////////////////////////////////////////////////////////////////////////////////// -// APC and mutex functions - -static void __stdcall DummyAPCFunc(ULONG_PTR) -{ - /* called in the context of thread that cleared it's APC queue */ - return; -} - -static int MirandaWaitForMutex(HANDLE hEvent) -{ - for (;;) { - // will get WAIT_IO_COMPLETE for QueueUserAPC() which isnt a result - DWORD rc = MsgWaitForMultipleObjectsEx(1, &hEvent, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE); - if (rc == WAIT_OBJECT_0 + 1) { - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if (IsDialogMessage(msg.hwnd, &msg)) continue; - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - else if (rc == WAIT_OBJECT_0) { // got object - return 1; - } - else if (rc == WAIT_ABANDONED_0 || rc == WAIT_FAILED) - return 0; - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// exception handling - -static DWORD __cdecl sttDefaultFilter(DWORD, EXCEPTION_POINTERS*) -{ - return EXCEPTION_EXECUTE_HANDLER; -} - -pfnExceptionFilter pMirandaExceptFilter = sttDefaultFilter; - -MIR_CORE_DLL(pfnExceptionFilter) GetExceptionFilter() -{ - return pMirandaExceptFilter; -} - -MIR_CORE_DLL(pfnExceptionFilter) SetExceptionFilter(pfnExceptionFilter pMirandaExceptFilter) -{ - pfnExceptionFilter oldOne = pMirandaExceptFilter; - if (pMirandaExceptFilter != 0) - pMirandaExceptFilter = pMirandaExceptFilter; - return oldOne; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// thread support functions - -struct THREAD_WAIT_ENTRY -{ - DWORD dwThreadId; // valid if hThread isn't signalled - HANDLE hThread; - HINSTANCE hOwner; - void* pObject; - //PVOID addr; -}; - -static LIST threads(10, NumericKeySortT); - -struct FORK_ARG { - HANDLE hEvent; - pThreadFunc threadcode; - pThreadFuncEx threadcodeex; - void *arg, *owner; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// forkthread - starts a new thread - -void __cdecl forkthread_r(void * arg) -{ - struct FORK_ARG * fa = (struct FORK_ARG *) arg; - void (*callercode)(void*)=fa->threadcode; - void * cookie=fa->arg; - Thread_Push(( HINSTANCE)callercode); - SetEvent(fa->hEvent); - __try - { - callercode(cookie); - } - __except(pMirandaExceptFilter(GetExceptionCode(), GetExceptionInformation())) - { - } - - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - Thread_Pop(); - return; -} - -MIR_CORE_DLL(UINT_PTR) forkthread( void (__cdecl *threadcode)(void*), unsigned long stacksize, void *arg) -{ - UINT_PTR rc; - struct FORK_ARG fa; - fa.hEvent=CreateEvent(NULL, FALSE, FALSE, NULL); - fa.threadcode=threadcode; - fa.arg=arg; - rc=_beginthread(forkthread_r, stacksize, &fa); - if ((UINT_PTR)-1L != rc) - WaitForSingleObject(fa.hEvent, INFINITE); - - CloseHandle(fa.hEvent); - return rc; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// forkthreadex - starts a new thread with the extended info and returns the thread id - -unsigned __stdcall forkthreadex_r(void * arg) -{ - struct FORK_ARG *fa = (struct FORK_ARG *)arg; - pThreadFuncEx threadcode = fa->threadcodeex; - pThreadFuncOwner threadcodeex = (pThreadFuncOwner)fa->threadcodeex; - void *cookie = fa->arg; - void *owner = fa->owner; - unsigned long rc = 0; - - Thread_Push((HINSTANCE)threadcode, fa->owner); - SetEvent(fa->hEvent); - __try - { - if (owner) - rc = threadcodeex(owner, cookie); - else - rc = threadcode(cookie); - } - __except(pMirandaExceptFilter(GetExceptionCode(), GetExceptionInformation())) - { - } - - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - Thread_Pop(); - return rc; -} - -MIR_CORE_DLL(UINT_PTR) forkthreadex( - void *sec, - unsigned stacksize, - unsigned (__stdcall *threadcode)(void*), - void* owner, - void *arg, - unsigned *thraddr) -{ - UINT_PTR rc; - struct FORK_ARG fa = { 0 }; - fa.threadcodeex = threadcode; - fa.arg = arg; - fa.owner = owner; - fa.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - rc = _beginthreadex(sec, stacksize, forkthreadex_r, (void *)&fa, 0, thraddr); - if (rc) - WaitForSingleObject(fa.hEvent, INFINITE); - - CloseHandle(fa.hEvent); - return rc; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_CORE_DLL(void) KillObjectThreads(void* owner) -{ - if (owner == NULL) - return; - - WaitForSingleObject(hStackMutex, INFINITE); - - HANDLE* threadPool = (HANDLE*)alloca(threads.getCount()*sizeof(HANDLE)); - int threadCount = 0; - - for (int j = threads.getCount(); j--;) { - THREAD_WAIT_ENTRY* p = threads[j]; - if (p->pObject == owner) - threadPool[ threadCount++ ] = p->hThread; - } - ReleaseMutex(hStackMutex); - - // is there anything to kill? - if (threadCount > 0) { - if ( WaitForMultipleObjects(threadCount, threadPool, TRUE, 5000) == WAIT_TIMEOUT) { - // forcibly kill all remaining threads after 5 secs - WaitForSingleObject(hStackMutex, INFINITE); - for (int j = threads.getCount()-1; j >= 0; j--) { - THREAD_WAIT_ENTRY* p = threads[j]; - if (p->pObject == owner) { - TerminateThread(p->hThread, 9999); - CloseHandle(p->hThread); - threads.remove(j); - mir_free(p); - } - } - ReleaseMutex(hStackMutex); - } - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static void CALLBACK KillAllThreads(HWND, UINT, UINT_PTR, DWORD) -{ - if ( MirandaWaitForMutex(hStackMutex)) { - for (int j=0; j < threads.getCount(); j++) { - THREAD_WAIT_ENTRY* p = threads[j]; - char szModuleName[ MAX_PATH ]; - GetModuleFileNameA(p->hOwner, szModuleName, sizeof(szModuleName)); - TerminateThread(p->hThread, 9999); - CloseHandle(p->hThread); - mir_free(p); - } - - threads.destroy(); - - ReleaseMutex(hStackMutex); - SetEvent(hThreadQueueEmpty); - } -} - -MIR_CORE_DLL(void) Thread_Wait(void) -{ - // acquire the list and wake up any alertable threads - if ( MirandaWaitForMutex(hStackMutex)) { - for (int j=0; j < threads.getCount(); j++) - QueueUserAPC(DummyAPCFunc, threads[j]->hThread, 0); - ReleaseMutex(hStackMutex); - } - - // give all unclosed threads 5 seconds to close - SetTimer(NULL, 0, 5000, KillAllThreads); - - // wait til the thread list is empty - MirandaWaitForMutex(hThreadQueueEmpty); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -typedef LONG (WINAPI *pNtQIT)(HANDLE, LONG, PVOID, ULONG, PULONG); -#define ThreadQuerySetWin32StartAddress 9 - -static void* GetCurrentThreadEntryPoint() -{ - LONG ntStatus; - HANDLE hDupHandle, hCurrentProcess; - DWORD_PTR dwStartAddress; - - pNtQIT NtQueryInformationThread = (pNtQIT)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQueryInformationThread" ); - if(NtQueryInformationThread == NULL) return 0; - - hCurrentProcess = GetCurrentProcess(); - if(!DuplicateHandle(hCurrentProcess, GetCurrentThread(), hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)){ - SetLastError(ERROR_ACCESS_DENIED); - return NULL; - } - ntStatus = NtQueryInformationThread(hDupHandle, ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD_PTR), NULL); - CloseHandle(hDupHandle); - - if(ntStatus != ERROR_SUCCESS) return 0; - return ( void* )dwStartAddress; -} - -MIR_CORE_DLL(INT_PTR) Thread_Push(HINSTANCE hInst, void* pOwner) -{ - ResetEvent(hThreadQueueEmpty); // thread list is not empty - if ( WaitForSingleObject(hStackMutex, INFINITE) == WAIT_OBJECT_0) { - THREAD_WAIT_ENTRY* p = (THREAD_WAIT_ENTRY*)mir_calloc(sizeof(THREAD_WAIT_ENTRY)); - - DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &p->hThread, 0, FALSE, DUPLICATE_SAME_ACCESS); - p->dwThreadId = GetCurrentThreadId(); - p->pObject = pOwner; - if (pluginListAddr.getIndex(hInst) != -1) - p->hOwner = hInst; - else - p->hOwner = GetInstByAddress(( hInst != NULL ) ? (PVOID)hInst : GetCurrentThreadEntryPoint()); - - threads.insert(p); - - ReleaseMutex(hStackMutex); - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_CORE_DLL(INT_PTR) Thread_Pop() -{ - if ( WaitForSingleObject(hStackMutex, INFINITE) == WAIT_OBJECT_0) { - DWORD dwThreadId = GetCurrentThreadId(); - for (int j=0; j < threads.getCount(); j++) { - THREAD_WAIT_ENTRY* p = threads[j]; - if (p->dwThreadId == dwThreadId) { - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - CloseHandle(p->hThread); - threads.remove(j); - mir_free(p); - - if ( !threads.getCount()) { - threads.destroy(); - ReleaseMutex(hStackMutex); - SetEvent(hThreadQueueEmpty); // thread list is empty now - return 0; - } - - ReleaseMutex(hStackMutex); - return 0; - } - } - ReleaseMutex(hStackMutex); - } - return 1; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -const DWORD MS_VC_EXCEPTION=0x406D1388; - -#pragma pack(push,8) -typedef struct tagTHREADNAME_INFO -{ - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -} THREADNAME_INFO; -#pragma pack(pop) - -MIR_CORE_DLL(void) Thread_SetName(const char *szThreadName) -{ - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = szThreadName; - info.dwThreadID = GetCurrentThreadId(); - info.dwFlags = 0; - - __try - { - RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - } -} diff --git a/plugins/Mir_core/utf.cpp b/plugins/Mir_core/utf.cpp deleted file mode 100644 index ddf2d1ca9f..0000000000 --- a/plugins/Mir_core/utf.cpp +++ /dev/null @@ -1,406 +0,0 @@ -/* - -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. - - Copyright 2000 Alexandre Julliard of Wine project - (UTF-8 conversion routines) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "commonheaders.h" - -/* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */ -static const char utf8_length[128] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xaf */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0-0xbf */ - 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xc0-0xcf */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xd0-0xdf */ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xe0-0xef */ - 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0-0xff */ -}; - -/* first byte mask depending on UTF-8 sequence length */ -static const unsigned char utf8_mask[4] = { 0x7f, 0x1f, 0x0f, 0x07 }; - -/* minimum Unicode value depending on UTF-8 sequence length */ -static const unsigned int utf8_minval[4] = { 0x0, 0x80, 0x800, 0x10000 }; - -/* get the next char value taking surrogates into account */ -static unsigned int getSurrogateValue(const wchar_t *src, unsigned int srclen) -{ - if (src[0] >= 0xd800 && src[0] <= 0xdfff) { /* surrogate pair */ - if (src[0] > 0xdbff || /* invalid high surrogate */ - srclen <= 1 || /* missing low surrogate */ - src[1] < 0xdc00 || src[1] > 0xdfff) /* invalid low surrogate */ - return 0; - return 0x10000 + ((src[0] & 0x3ff) << 10) + (src[1] & 0x3ff); - } - return src[0]; -} - -/* query necessary dst length for src string */ -static int Ucs2toUtf8Len(const wchar_t *src, unsigned int srclen) -{ - int len; - unsigned int val; - - for (len = 0; srclen; srclen--, src++) { - if (*src < 0x80) { /* 0x00-0x7f: 1 byte */ - len++; - continue; - } - if (*src < 0x800) { /* 0x80-0x7ff: 2 bytes */ - len += 2; - continue; - } - if ( !(val = getSurrogateValue(src, srclen))) - return -2; - - if (val < 0x10000) /* 0x800-0xffff: 3 bytes */ - len += 3; - else { /* 0x10000-0x10ffff: 4 bytes */ - len += 4; - src++; - srclen--; - } - } - return len; -} - -MIR_CORE_DLL(int) Ucs2toUtf8Len(const wchar_t *src) -{ - if (src == 0) - return 0; - - return Ucs2toUtf8Len(src, (int)wcslen(src)); -} - -/* wide char to UTF-8 string conversion */ -/* return -1 on dst buffer overflow, -2 on invalid input char */ -int Ucs2toUtf8(const wchar_t *src, int srclen, char *dst, int dstlen) -{ - int len; - - for (len = dstlen; srclen; srclen--, src++) - { - WCHAR ch = *src; - unsigned int val; - - if (ch < 0x80) /* 0x00-0x7f: 1 byte */ - { - if ( !len--) return -1; /* overflow */ - *dst++ = ch; - continue; - } - - if (ch < 0x800) /* 0x80-0x7ff: 2 bytes */ - { - if ((len -= 2) < 0) return -1; /* overflow */ - dst[1] = 0x80 | (ch & 0x3f); - ch >>= 6; - dst[0] = 0xc0 | ch; - dst += 2; - continue; - } - - if ( !(val = getSurrogateValue(src, srclen))) - { - return -2; - } - - if (val < 0x10000) /* 0x800-0xffff: 3 bytes */ - { - if ((len -= 3) < 0) return -1; /* overflow */ - dst[2] = 0x80 | (val & 0x3f); - val >>= 6; - dst[1] = 0x80 | (val & 0x3f); - val >>= 6; - dst[0] = 0xe0 | val; - dst += 3; - } - else /* 0x10000-0x10ffff: 4 bytes */ - { - if ((len -= 4) < 0) return -1; /* overflow */ - dst[3] = 0x80 | (val & 0x3f); - val >>= 6; - dst[2] = 0x80 | (val & 0x3f); - val >>= 6; - dst[1] = 0x80 | (val & 0x3f); - val >>= 6; - dst[0] = 0xf0 | val; - dst += 4; - src++; - srclen--; - } - } - return dstlen - len; -} - -/* helper for the various utf8 mbstowcs functions */ -static unsigned int decodeUtf8Char(unsigned char ch, const char **str, const char *strend) -{ - unsigned int len = utf8_length[ch-0x80]; - unsigned int res = ch & utf8_mask[len]; - const char *end = *str + len; - - if (end > strend) return ~0; - switch(len) - { - case 3: - if ((ch = end[-3] ^ 0x80) >= 0x40) break; - res = (res << 6) | ch; - (*str)++; - case 2: - if ((ch = end[-2] ^ 0x80) >= 0x40) break; - res = (res << 6) | ch; - (*str)++; - case 1: - if ((ch = end[-1] ^ 0x80) >= 0x40) break; - res = (res << 6) | ch; - (*str)++; - if (res < utf8_minval[len]) break; - return res; - } - return ~0; -} - -/* query necessary dst length for src string */ -static inline int Utf8toUcs2Len(const char *src, int srclen) -{ - int ret = 0; - unsigned int res; - const char *srcend = src + srclen; - - while (src < srcend) - { - unsigned char ch = *src++; - if (ch < 0x80) /* special fast case for 7-bit ASCII */ - { - ret++; - continue; - } - if ((res = decodeUtf8Char(ch, &src, srcend)) <= 0x10ffff) - { - if (res > 0xffff) ret++; - ret++; - } - else return -2; /* bad char */ - /* otherwise ignore it */ - } - return ret; -} - -/* UTF-8 to wide char string conversion */ -/* return -1 on dst buffer overflow, -2 on invalid input char */ -int Utf8toUcs2(const char *src, int srclen, wchar_t *dst, int dstlen) -{ - unsigned int res; - const char *srcend = src + srclen; - wchar_t *dstend = dst + dstlen; - - while ((dst < dstend) && (src < srcend)) - { - unsigned char ch = *src++; - if (ch < 0x80) /* special fast case for 7-bit ASCII */ - { - *dst++ = ch; - continue; - } - if ((res = decodeUtf8Char(ch, &src, srcend)) <= 0xffff) - { - *dst++ = res; - } - else if (res <= 0x10ffff) /* we need surrogates */ - { - if (dst == dstend - 1) return -1; /* overflow */ - res -= 0x10000; - *dst++ = 0xd800 | (res >> 10); - *dst++ = 0xdc00 | (res & 0x3ff); - } - else return -2; /* bad char */ - /* otherwise ignore it */ - } - if (src < srcend) return -1; /* overflow */ - return dstlen - (dstend - dst); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Utf8Decode - converts UTF8-encoded string to the UCS2/MBCS format - -MIR_CORE_DLL(char*) Utf8DecodeCP(char* str, int codepage, wchar_t** ucs2) -{ - int len; - bool needs_free = false; - wchar_t* tempBuf = NULL; - if (ucs2) - *ucs2 = NULL; - - if (str == NULL) - return NULL; - - len = (int)strlen(str); - - if (len < 2) { - if (ucs2 != NULL) { - *ucs2 = tempBuf = (wchar_t*)mir_alloc((len + 1) * sizeof(wchar_t)); - MultiByteToWideChar(codepage, 0, str, len, tempBuf, len); - tempBuf[len] = 0; - } - return str; - } - - int destlen = Utf8toUcs2Len(str, len); - if (destlen < 0) - return NULL; - - if (ucs2 == NULL) { - __try - { - tempBuf = (wchar_t*)alloca((destlen + 1) * sizeof(wchar_t)); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - tempBuf = NULL; - needs_free = true; - } - } - - if (tempBuf == NULL) { - tempBuf = (wchar_t*)mir_alloc((destlen + 1) * sizeof(wchar_t)); - if (tempBuf == NULL) - return NULL; - } - - Utf8toUcs2(str, len, tempBuf, destlen); - tempBuf[destlen] = 0; - WideCharToMultiByte(codepage, 0, tempBuf, -1, str, len + 1, "?", NULL); - - if (ucs2) - *ucs2 = tempBuf; - else if (needs_free) - mir_free(tempBuf); - - return str; -} - -MIR_CORE_DLL(char*) Utf8Decode(char* str, wchar_t** ucs2) -{ - return Utf8DecodeCP(str, Langpack_GetDefaultCodePage(), ucs2); -} - -MIR_CORE_DLL(wchar_t*) Utf8DecodeW(const char* str) -{ - if (str == NULL) - return NULL; - - int len = (int)strlen(str); - - int destlen = Utf8toUcs2Len(str, len); - if (destlen < 0) return NULL; - - wchar_t* ucs2 = (wchar_t*)mir_alloc((destlen + 1) * sizeof(wchar_t)); - if (ucs2 == NULL) return NULL; - - if (Utf8toUcs2(str, len, ucs2, destlen) >= 0) - { - ucs2[destlen] = 0; - return ucs2; - } - - mir_free(ucs2); - - return NULL; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Utf8Encode - converts MBCS string to the UTF8-encoded format - -MIR_CORE_DLL(char*) Utf8EncodeCP(const char* src, int codepage) -{ - int len; - bool needs_free = false; - char* result = NULL; - wchar_t* tempBuf; - - if (src == NULL) - return NULL; - - len = (int)strlen(src); - - __try - { - tempBuf = (wchar_t*)alloca((len + 1) * sizeof(wchar_t)); - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - tempBuf = (wchar_t*)mir_alloc((len + 1) * sizeof(wchar_t)); - if (tempBuf == NULL) return NULL; - needs_free = true; - } - - len = MultiByteToWideChar(codepage, 0, src, -1, tempBuf, len + 1); - - int destlen = Ucs2toUtf8Len(tempBuf, len); - if (destlen >= 0) - { - result = (char*)mir_alloc(destlen + 1); - if (result) - { - Ucs2toUtf8(tempBuf, len, result, destlen); - result[destlen] = 0; - } - } - - if (needs_free) - mir_free(tempBuf); - - return result; -} - -MIR_CORE_DLL(char*) Utf8Encode(const char* src) -{ - return Utf8EncodeCP(src, Langpack_GetDefaultCodePage()); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Utf8Encode - converts UCS2 string to the UTF8-encoded format - -MIR_CORE_DLL(char*) Utf8EncodeW(const wchar_t* src) -{ - if (src == NULL) - return NULL; - - int len = (int)wcslen(src); - - int destlen = Ucs2toUtf8Len(src, len); - if (destlen < 0) return NULL; - - char* result = (char*)mir_alloc(destlen + 1); - if (result == NULL) - return NULL; - - Ucs2toUtf8(src, len, result, destlen); - result[destlen] = 0; - - return result; -} diff --git a/plugins/Mir_core/utils.cpp b/plugins/Mir_core/utils.cpp deleted file mode 100644 index 4ebba2f293..0000000000 --- a/plugins/Mir_core/utils.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/* - -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. -*/ - -#include "commonheaders.h" - -MIR_CORE_DLL(char*) rtrim(char* str) -{ - if (str == NULL) - return NULL; - - char* p = strchr(str, 0); - while (--p >= str) { - switch (*p) { - case ' ': case '\t': case '\n': case '\r': - *p = 0; break; - default: - return str; - } - } - return str; -} - -MIR_CORE_DLL(WCHAR*) wrtrim(WCHAR *str) -{ - if (str == NULL) - return NULL; - - WCHAR* p = _tcschr(str, 0); - while (--p >= str) { - switch (*p) { - case ' ': case '\t': case '\n': case '\r': - *p = 0; break; - default: - return str; - } - } - return str; -} - -MIR_CORE_DLL(char*) ltrim(char* str) -{ - if (str == NULL) - return NULL; - - char* p = str; - for (;;) { - switch (*p) { - case ' ': case '\t': case '\n': case '\r': - ++p; break; - default: - memmove(str, p, strlen(p) + 1); - return str; - } - } -} - -MIR_CORE_DLL(char*) ltrimp(char* str) -{ - if (str == NULL) - return NULL; - - char* p = str; - for (;;) { - switch (*p) { - case ' ': case '\t': case '\n': case '\r': - ++p; break; - default: - return p; - } - } -} - -MIR_CORE_DLL(int) wildcmp(char * name, char * mask) -{ - char * last='\0'; - for (;; mask++, name++) { - if (*mask != '?' && *mask != *name) break; - if (*name == '\0') return ((BOOL)!*mask); - } - if (*mask != '*') return FALSE; - for (;; mask++, name++){ - while (*mask == '*') { - last = mask++; - if (*mask == '\0') return ((BOOL)!*mask); /* true */ - } - if (*name == '\0') return ((BOOL)!*mask); /* *mask == EOS */ - if (*mask != '?' && *mask != *name) name -= (size_t)(mask - last) - 1, mask = last; - } -} - -/////////////////////////////////////////////////////////////////////////////// - -static int sttComparePlugins(const HINSTANCE__* p1, const HINSTANCE__* p2) -{ - if (p1 == p2) - return 0; - - return (p1 < p2) ? -1 : 1; -} - -LIST pluginListAddr(10, sttComparePlugins); - -MIR_CORE_DLL(void) RegisterModule(HINSTANCE hInst) -{ - pluginListAddr.insert(hInst); -} - -MIR_CORE_DLL(void) UnregisterModule(HINSTANCE hInst) -{ - pluginListAddr.remove(hInst); -} - -MIR_CORE_DLL(HINSTANCE) GetInstByAddress(void* codePtr) -{ - if (pluginListAddr.getCount() == 0) - return NULL; - - int idx; - List_GetIndex((SortedList*)&pluginListAddr, codePtr, &idx); - if (idx > 0) - idx--; - - HINSTANCE result = pluginListAddr[idx]; - if (result < hInst && codePtr > hInst) - result = hInst; - else if (idx == 0 && codePtr < (void*)result) - result = NULL; - - return result; -} diff --git a/src/core/miranda.h b/src/core/miranda.h index 3b08c636ba..c1dcb75f95 100644 --- a/src/core/miranda.h +++ b/src/core/miranda.h @@ -128,6 +128,11 @@ void KillModuleSounds(int hLangpack); extern HINSTANCE hInst; extern HANDLE hOkToExitEvent, hModulesLoadedEvent, hevLoadModule, hevUnloadModule; +/**** newplugins.cpp *******************************************************************/ + +char* GetPluginNameByInstance(HINSTANCE hInstance); +int GetPluginFakeId(const MUUID &uuid, int hLangpack); + /**** utf.cpp **************************************************************************/ __forceinline char* Utf8DecodeA(const char* src) @@ -247,6 +252,5 @@ public: extern "C" { - MIR_CORE_DLL(int) Langpack_GetPluginHandle(PLUGININFOEX* pInfo); MIR_CORE_DLL(int) Langpack_MarkPluginLoaded(PLUGININFOEX* pInfo); }; diff --git a/src/mir_core/commonheaders.cpp b/src/mir_core/commonheaders.cpp new file mode 100644 index 0000000000..95b2201163 --- /dev/null +++ b/src/mir_core/commonheaders.cpp @@ -0,0 +1,2 @@ +#include "commonheaders.h" + diff --git a/src/mir_core/commonheaders.h b/src/mir_core/commonheaders.h new file mode 100644 index 0000000000..2d04e12f4b --- /dev/null +++ b/src/mir_core/commonheaders.h @@ -0,0 +1,63 @@ +/* + +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. +*/ + +#define MIRANDA_VER 0x0A00 + +#define WINVER 0x0700 +#define _WIN32_WINNT 0x0700 +#define _WIN32_IE 0x0601 + +#define INCL_WINSOCK_API_TYPEDEFS 1 + +#include "m_stdhdr.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "miranda.h" + +#include +#include diff --git a/src/mir_core/db.cpp b/src/mir_core/db.cpp new file mode 100644 index 0000000000..37b89d8399 --- /dev/null +++ b/src/mir_core/db.cpp @@ -0,0 +1,191 @@ +/* + +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. +*/ + +#include "commonheaders.h" + +MIR_CORE_DLL(int) db_get_b(HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) +{ + DBVARIANT dbv; + DBCONTACTGETSETTING cgs; + cgs.szModule = szModule; + cgs.szSetting = szSetting; + cgs.pValue = &dbv; + if (CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&cgs)) + return errorValue; + return dbv.bVal; +} + +MIR_CORE_DLL(int) db_get_w(HANDLE hContact, const char *szModule, const char *szSetting, int errorValue) +{ + DBVARIANT dbv; + DBCONTACTGETSETTING cgs; + cgs.szModule = szModule; + cgs.szSetting = szSetting; + cgs.pValue = &dbv; + if (CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&cgs)) + return errorValue; + return dbv.wVal; +} + +MIR_CORE_DLL(DWORD) db_get_dw(HANDLE hContact, const char *szModule, const char *szSetting, DWORD errorValue) +{ + DBVARIANT dbv; + DBCONTACTGETSETTING cgs; + cgs.szModule = szModule; + cgs.szSetting = szSetting; + cgs.pValue = &dbv; + if (CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&cgs)) + return errorValue; + return dbv.dVal; +} + +MIR_CORE_DLL(INT_PTR) db_get(HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv) +{ + DBCONTACTGETSETTING cgs; + cgs.szModule = szModule; + cgs.szSetting = szSetting; + cgs.pValue = dbv; + + return CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&cgs); +} + +MIR_CORE_DLL(INT_PTR) db_get_s(HANDLE hContact, const char *szModule, const char *szSetting, DBVARIANT *dbv, const int nType) +{ + DBCONTACTGETSETTING cgs; + cgs.szModule = szModule; + cgs.szSetting = szSetting; + cgs.pValue = dbv; + dbv->type = (BYTE)nType; + return CallService(MS_DB_CONTACT_GETSETTING_STR, (WPARAM)hContact, (LPARAM)&cgs); +} + +MIR_CORE_DLL(char*) db_get_sa(HANDLE hContact, const char *szModule, const char *szSetting) +{ + char *str = NULL; + DBVARIANT dbv = {0}; + db_get_s(hContact, szModule, szSetting, &dbv, DBVT_ASCIIZ); + if (dbv.type == DBVT_ASCIIZ) + str = mir_strdup(dbv.pszVal); + DBFreeVariant(&dbv); + return str; +} + +MIR_CORE_DLL(wchar_t*) db_get_wsa(HANDLE hContact, const char *szModule, const char *szSetting) +{ + wchar_t *str = NULL; + DBVARIANT dbv={0}; + db_get_s(hContact, szModule, szSetting, &dbv, DBVT_WCHAR); + if (dbv.type == DBVT_WCHAR) + str = mir_wstrdup(dbv.pwszVal); + DBFreeVariant(&dbv); + return str; +} + +MIR_CORE_DLL(INT_PTR) db_free(DBVARIANT *dbv) +{ + return CallService(MS_DB_CONTACT_FREEVARIANT, 0, (LPARAM)dbv); +} + +MIR_CORE_DLL(INT_PTR) db_unset(HANDLE hContact, const char *szModule, const char *szSetting) +{ + DBCONTACTGETSETTING cgs; + cgs.szModule = szModule; + cgs.szSetting = szSetting; + return CallService(MS_DB_CONTACT_DELETESETTING, (WPARAM)hContact, (LPARAM)&cgs); +} + +MIR_CORE_DLL(INT_PTR) db_set_b(HANDLE hContact, const char *szModule, const char *szSetting, BYTE val) +{ + DBCONTACTWRITESETTING cws; + cws.szModule = szModule; + cws.szSetting = szSetting; + cws.value.type = DBVT_BYTE; + cws.value.bVal = val; + return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); +} + +MIR_CORE_DLL(INT_PTR) db_set_w(HANDLE hContact, const char *szModule, const char *szSetting, WORD val) +{ + DBCONTACTWRITESETTING cws; + + cws.szModule = szModule; + cws.szSetting = szSetting; + cws.value.type = DBVT_WORD; + cws.value.wVal = val; + return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); +} + +MIR_CORE_DLL(INT_PTR) db_set_dw(HANDLE hContact, const char *szModule, const char *szSetting, DWORD val) +{ + DBCONTACTWRITESETTING cws; + cws.szModule = szModule; + cws.szSetting = szSetting; + cws.value.type = DBVT_DWORD; + cws.value.dVal = val; + return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); +} + +MIR_CORE_DLL(INT_PTR) db_set_s(HANDLE hContact, const char *szModule, const char *szSetting, const char *val) +{ + DBCONTACTWRITESETTING cws; + + cws.szModule = szModule; + cws.szSetting = szSetting; + cws.value.type = DBVT_ASCIIZ; + cws.value.pszVal = (char*)val; + return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); +} + +MIR_CORE_DLL(INT_PTR) db_set_ws(HANDLE hContact, const char *szModule, const char *szSetting, const WCHAR *val) +{ + DBCONTACTWRITESETTING cws; + + cws.szModule = szModule; + cws.szSetting = szSetting; + cws.value.type = DBVT_WCHAR; + cws.value.pwszVal = (WCHAR*)val; + return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); +} + +MIR_CORE_DLL(INT_PTR) db_set_utf(HANDLE hContact, const char *szModule, const char *szSetting, const char *val) +{ + DBCONTACTWRITESETTING cws; + + cws.szModule = szModule; + cws.szSetting = szSetting; + cws.value.type = DBVT_UTF8; + cws.value.pszVal = (char*)val; + return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); +} + +MIR_CORE_DLL(INT_PTR) db_set_blob(HANDLE hContact, const char *szModule, const char *szSetting, void *val, unsigned len) +{ + DBCONTACTWRITESETTING cws; + + cws.szModule = szModule; + cws.szSetting = szSetting; + cws.value.type = DBVT_BLOB; + cws.value.cpbVal = (WORD)len; + cws.value.pbVal = (unsigned char*)val; + return CallService(MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&cws); +} diff --git a/src/mir_core/langpack.cpp b/src/mir_core/langpack.cpp new file mode 100644 index 0000000000..015af8f469 --- /dev/null +++ b/src/mir_core/langpack.cpp @@ -0,0 +1,631 @@ +/* + +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. +*/ +#include "commonheaders.h" + +#define LANGPACK_BUF_SIZE 4000 + +static int CompareMuuids(const MUUID* p1, const MUUID* p2) +{ + return memcmp(p1, p2, sizeof(MUUID)); +} + +static LIST lMuuids(10, CompareMuuids); +static MUUID* pCurrentMuuid = NULL; + +static BOOL bModuleInitialized = FALSE; + +struct LangPackEntry { + DWORD englishHash; + char *local; + wchar_t *wlocal; + MUUID* pMuuid; + LangPackEntry* pNext; // for langpack items with the same hash value +}; + +struct LangPackStruct { + TCHAR filename[MAX_PATH]; + TCHAR filePath[MAX_PATH]; + char language[64]; + char lastModifiedUsing[64]; + char authors[256]; + char authorEmail[128]; + LangPackEntry *entry; + int entryCount, entriesAlloced; + LCID localeID; + UINT defaultANSICp; +} static langPack; + +static int IsEmpty(char *str) +{ + int i = 0; + + while (str[i]) + { + if (str[i] != ' ' && str[i] != '\r' && str[i] != '\n') + return 0; + i++; + } + return 1; +} + +static void ConvertBackslashes(char *str, UINT fileCp) +{ + char *pstr; + for (pstr = str; *pstr; pstr = CharNextExA(fileCp, pstr, 0)) { + if (*pstr == '\\') { + switch(pstr[1]) { + case 'n': *pstr = '\n'; break; + case 't': *pstr = '\t'; break; + case 'r': *pstr = '\r'; break; + default: *pstr = pstr[1]; break; + } + memmove(pstr+1, pstr+2, strlen(pstr+2) + 1); +} } } + +#ifdef _DEBUG +//#pragma optimize("gt", on) +#endif + +// MurmurHash2 +MIR_CORE_DLL(unsigned int) mir_hash(const void * key, unsigned int len) +{ + // 'm' and 'r' are mixing constants generated offline. + // They're not really 'magic', they just happen to work well. + const unsigned int m = 0x5bd1e995; + const int r = 24; + + // Initialize the hash to a 'random' value + unsigned int h = len; + + // Mix 4 bytes at a time into the hash + const unsigned char * data = (const unsigned char *)key; + + while (len >= 4) + { + unsigned int k = *(unsigned int *)data; + + k *= m; + k ^= k >> r; + k *= m; + + h *= m; + h ^= k; + + data += 4; + len -= 4; + } + + // Handle the last few bytes of the input array + switch(len) + { + case 3: h ^= data[2] << 16; + case 2: h ^= data[1] << 8; + case 1: h ^= data[0]; + h *= m; + }; + + // Do a few final mixes of the hash to ensure the last few + // bytes are well-incorporated. + h ^= h >> 13; + h *= m; + h ^= h >> 15; + + return h; +} + +static unsigned int __fastcall hashstrW(const char * key) +{ + if (key == NULL) return 0; + const unsigned int len = (unsigned int)wcslen((const wchar_t*)key); + char* buf = (char*)alloca(len + 1); + for (unsigned i = 0; i <= len ; ++i) + buf[i] = key[i << 1]; + return mir_hash(buf, len); +} + +static int SortLangPackHashesProc(LangPackEntry *arg1, LangPackEntry *arg2) +{ + if (arg1->englishHash < arg2->englishHash) return -1; + if (arg1->englishHash > arg2->englishHash) return 1; + + return (arg1->pMuuid < arg2->pMuuid) ? -1 : 1; +} + +static void swapBytes(void* p, size_t iSize) +{ + char *head = (char *)p; // here + char *tail = head + iSize - 1; + + for (; tail > head; --tail, ++head) { + char temp = *head; + *head = *tail; + *tail = temp; + } +} + +static bool EnterMuuid(const char* p, MUUID& result) +{ + if (*p++ != '{') + return false; + + BYTE* d = (BYTE*)&result; + + for (int nBytes = 0; *p && nBytes < 24; p++) { + if (*p == '-') + continue; + + if (*p == '}') + break; + + if ( !isxdigit(*p)) + return false; + + if ( !isxdigit(p[1])) + return false; + + int c = 0; + if (sscanf(p, "%2x", &c) != 1) + return false; + + *d++ = (BYTE)c; + nBytes++; + p++; + } + + if (*p != '}') + return false; + + swapBytes(&result.a, sizeof(result.a)); + swapBytes(&result.b, sizeof(result.b)); + swapBytes(&result.c, sizeof(result.c)); + return true; +} + +static void LoadLangPackFile(FILE* fp, char* line, UINT fileCp) +{ + while ( !feof(fp)) { + if (fgets(line, LANGPACK_BUF_SIZE, fp) == NULL) + break; + + if (IsEmpty(line) || line[0] == ';' || line[0] == 0) + continue; + + rtrim(line); + + if (line[0] == '#') { + strlwr(line); + + if ( !memcmp(line+1, "include", 7)) { + TCHAR tszFileName[ MAX_PATH ]; + TCHAR* fileName = mir_a2t(ltrim(line+9)); + mir_sntprintf(tszFileName, SIZEOF(tszFileName), _T("%s%s"), langPack.filePath, fileName); + mir_free(fileName); + + FILE* p = _tfopen(tszFileName, _T("r")); + if (p) { + line[0] = 0; + fgets(line, SIZEOF(line), p); + + UINT fileCp = CP_ACP; + if (strlen(line) >= 3 && line[0] == '\xef' && line[1] == '\xbb' && line[2] == '\xbf') { + fileCp = CP_UTF8; + fseek(p, 3, SEEK_SET); + } + else { + fileCp = langPack.defaultANSICp; + fseek(p, 0, SEEK_SET); + } + + LoadLangPackFile(p, line, fileCp); + fclose(p); + } + } + else if ( !memcmp(line+1, "muuid", 5)) { + MUUID t; + if ( !EnterMuuid(line+7, t)) + continue; + + MUUID* pNew = (MUUID*)mir_alloc(sizeof(MUUID)); + memcpy(pNew, &t, sizeof(t)); + lMuuids.insert(pNew); + pCurrentMuuid = pNew; + } + + continue; + } + + ConvertBackslashes(line, fileCp); + + if (line[0] == '[' && line[ lstrlenA(line)-1 ] == ']') { + if (langPack.entryCount && langPack.entry[ langPack.entryCount-1].local == NULL) + langPack.entryCount--; + + char* pszLine = line+1; + line[ lstrlenA(line)-1 ] = '\0'; + if (++langPack.entryCount > langPack.entriesAlloced) { + langPack.entriesAlloced += 128; + langPack.entry = (LangPackEntry*)mir_realloc(langPack.entry, sizeof(LangPackEntry)*langPack.entriesAlloced); + } + + LangPackEntry* E = &langPack.entry[ langPack.entryCount-1 ]; + E->englishHash = mir_hashstr(pszLine); + E->local = NULL; + E->wlocal = NULL; + E->pMuuid = pCurrentMuuid; + E->pNext = NULL; + continue; + } + + if ( !langPack.entryCount) + continue; + + LangPackEntry* E = &langPack.entry[ langPack.entryCount-1 ]; + if (E->local == NULL) { + E->local = mir_strdup(line); + if (fileCp == CP_UTF8) + Utf8DecodeCP(E->local, langPack.defaultANSICp, NULL); + + int iNeeded = MultiByteToWideChar(fileCp, 0, line, -1, 0, 0); + E->wlocal = (wchar_t *)mir_alloc((iNeeded+1) * sizeof(wchar_t)); + MultiByteToWideChar(fileCp, 0, line, -1, E->wlocal, iNeeded); + } + else { + size_t iOldLenA = strlen(E->local); + E->local = (char*)mir_realloc(E->local, iOldLenA + strlen(line) + 2); + strcat(E->local, "\n"); + strcat(E->local, line); + + if (fileCp == CP_UTF8) + Utf8DecodeCP(E->local + iOldLenA + 1, langPack.defaultANSICp, NULL); + + int iNeeded = MultiByteToWideChar(fileCp, 0, line, -1, 0, 0); + size_t iOldLen = wcslen(E->wlocal); + E->wlocal = (wchar_t*)mir_realloc(E->wlocal, (sizeof(wchar_t) * (iOldLen + iNeeded + 2))); + wcscat(E->wlocal, L"\n"); + MultiByteToWideChar(fileCp, 0, line, -1, E->wlocal + iOldLen + 1, iNeeded); + } + } +} + +MIR_CORE_DLL(int) LoadLangPack(const TCHAR *szLangPack) +{ + int startOfLine=0; + USHORT langID; + + lstrcpy(langPack.filename, szLangPack); + lstrcpy(langPack.filePath, szLangPack); + TCHAR* p = _tcsrchr(langPack.filePath, '\\'); + if (p) + p[1] = 0; + + FILE *fp = _tfopen(szLangPack, _T("rt")); + if (fp == NULL) + return 1; + + char line[ LANGPACK_BUF_SIZE ] = ""; + fgets(line, SIZEOF(line), fp); + + UINT fileCp = CP_ACP; + size_t lineLen = strlen(line); + if (lineLen >= 3 && line[0] == '\xef' && line[1] == '\xbb' && line[2] == '\xbf') + { + fileCp = CP_UTF8; + memmove(line, line + 3, lineLen - 2); + } + + lrtrim(line); + if (lstrcmpA(line, "Miranda Language Pack Version 1")) { + fclose(fp); + return 2; + } + + //headers + while ( !feof(fp)) { + startOfLine = ftell(fp); + if (fgets(line, SIZEOF(line), fp) == NULL) + break; + + lrtrim(line); + if (IsEmpty(line) || line[0] == ';' || line[0] == 0) + continue; + + if (line[0] == '[' || line[0] == '#') + break; + + char* pszColon = strchr(line, ':'); + if (pszColon == NULL) { + fclose(fp); + return 3; + } + + *pszColon++ = 0; + if ( !lstrcmpA(line, "Language")) {mir_snprintf(langPack.language, sizeof(langPack.language), "%s", pszColon); lrtrim(langPack.language);} + else if ( !lstrcmpA(line, "Last-Modified-Using")) {mir_snprintf(langPack.lastModifiedUsing, sizeof(langPack.lastModifiedUsing), "%s", pszColon); lrtrim(langPack.lastModifiedUsing);} + else if ( !lstrcmpA(line, "Authors")) {mir_snprintf(langPack.authors, sizeof(langPack.authors), "%s", pszColon); lrtrim(langPack.authors);} + else if ( !lstrcmpA(line, "Author-email")) {mir_snprintf(langPack.authorEmail, sizeof(langPack.authorEmail), "%s", pszColon); lrtrim(langPack.authorEmail);} + else if ( !lstrcmpA(line, "Locale")) { + char szBuf[20], *stopped; + + lrtrim(pszColon + 1); + langID = (USHORT)strtol(pszColon, &stopped, 16); + langPack.localeID = MAKELCID(langID, 0); + GetLocaleInfoA(langPack.localeID, LOCALE_IDEFAULTANSICODEPAGE, szBuf, 10); + szBuf[5] = 0; // codepages have max. 5 digits + langPack.defaultANSICp = atoi(szBuf); + if (fileCp == CP_ACP) + fileCp = langPack.defaultANSICp; + } + } + + //body + fseek(fp, startOfLine, SEEK_SET); + langPack.entriesAlloced = 0; + + LoadLangPackFile(fp, line, fileCp); + fclose(fp); + pCurrentMuuid = NULL; + + qsort(langPack.entry, langPack.entryCount, sizeof(LangPackEntry), (int(*)(const void*, const void*))SortLangPackHashesProc); + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static int SortLangPackHashesProc2(LangPackEntry *arg1, LangPackEntry *arg2) +{ + if (arg1->englishHash < arg2->englishHash) return -1; + if (arg1->englishHash > arg2->englishHash) return 1; + return 0; +} + +static char *LangPackTranslateString(MUUID* pUuid, const char *szEnglish, const int W) +{ + if (langPack.entryCount == 0 || szEnglish == NULL) + return (char*)szEnglish; + + LangPackEntry key, *entry; + key.englishHash = W ? hashstrW(szEnglish) : mir_hashstr(szEnglish); + entry = (LangPackEntry*)bsearch(&key, langPack.entry, langPack.entryCount, sizeof(LangPackEntry), (int(*)(const void*, const void*))SortLangPackHashesProc2); + if (entry == NULL) + return (char*)szEnglish; + + // try to find the exact match, otherwise the first entry will be returned + if (pUuid) { + for (LangPackEntry* p = entry->pNext; p != NULL; p = p->pNext) { + if (p->pMuuid == pUuid) { + entry = p; + break; + } } } + + return W ? (char *)entry->wlocal : entry->local; +} + +MIR_CORE_DLL(int) Langpack_GetDefaultCodePage() +{ + return langPack.defaultANSICp; +} + +MIR_CORE_DLL(int) Langpack_GetDefaultLocale() +{ + return (langPack.localeID == 0) ? LOCALE_USER_DEFAULT : langPack.localeID; +} + +MIR_CORE_DLL(TCHAR*) Langpack_PcharToTchar(const char* pszStr) +{ + if (pszStr == NULL) + return NULL; + + int len = (int)strlen(pszStr); + TCHAR* result = (TCHAR*)alloca((len+1)*sizeof(TCHAR)); + MultiByteToWideChar(Langpack_GetDefaultCodePage(), 0, pszStr, -1, result, len); + result[len] = 0; + return mir_wstrdup(TranslateW(result)); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_CORE_DLL(char*) TranslateA_LP(const char* str, int hLangpack) +{ + return (char*)LangPackTranslateString(Langpack_LookupUuid(hLangpack), str, FALSE); +} + +MIR_CORE_DLL(WCHAR*) TranslateW_LP(const WCHAR* str, int hLangpack) +{ + return (WCHAR*)LangPackTranslateString(Langpack_LookupUuid(hLangpack), (LPCSTR)str, TRUE); +} + +MIR_CORE_DLL(void) TranslateMenu_LP(HMENU hMenu, int hLangpack) +{ + MUUID* uuid = Langpack_LookupUuid(hLangpack); + + MENUITEMINFO mii; + mii.cbSize = MENUITEMINFO_V4_SIZE; + for (int i = GetMenuItemCount(hMenu)-1; i >= 0; i--) { + TCHAR str[256]; + mii.fMask = MIIM_TYPE|MIIM_SUBMENU; + mii.dwTypeData = (TCHAR*)str; + mii.cch = SIZEOF(str); + GetMenuItemInfo(hMenu, i, TRUE, &mii); + + if (mii.cch && mii.dwTypeData) { + TCHAR* result = (TCHAR*)LangPackTranslateString(uuid, (const char*)mii.dwTypeData, TRUE); + if (result != mii.dwTypeData) { + mii.dwTypeData = result; + mii.fMask = MIIM_TYPE; + SetMenuItemInfo(hMenu, i, TRUE, &mii); + } } + + if (mii.hSubMenu != NULL) TranslateMenu_LP(mii.hSubMenu, hLangpack); + } +} + +static void TranslateWindow(MUUID* pUuid, HWND hwnd) +{ + TCHAR title[2048]; + GetWindowText(hwnd, title, SIZEOF(title)); + + TCHAR* result = (TCHAR*)LangPackTranslateString(pUuid, (const char*)title, TRUE); + if (result != title) + SetWindowText(hwnd, result); +} + +struct LANGPACKTRANSLATEDIALOG +{ + HWND hwndDlg; + int hLangpack; +}; + +static BOOL CALLBACK TranslateDialogEnumProc(HWND hwnd, LPARAM lParam) +{ + int hLangpack = (int)lParam; + TCHAR szClass[32]; + int id = GetDlgCtrlID(hwnd); + + MUUID* uuid = Langpack_LookupUuid(hLangpack); + + GetClassName(hwnd, szClass, SIZEOF(szClass)); + if ( !lstrcmpi(szClass, _T("static")) || !lstrcmpi(szClass, _T("hyperlink")) || !lstrcmpi(szClass, _T("button")) || !lstrcmpi(szClass, _T("MButtonClass")) || !lstrcmpi(szClass, _T("MHeaderbarCtrl"))) + TranslateWindow(uuid, hwnd); + else if ( !lstrcmpi(szClass, _T("edit"))) { + if (GetWindowLongPtr(hwnd, GWL_STYLE) & ES_READONLY) + TranslateWindow(uuid, hwnd); + } + return TRUE; +} + +MIR_CORE_DLL(void) TranslateDialog_LP(HWND hDlg, int hLangpack) +{ + TranslateWindow( Langpack_LookupUuid(hLangpack), hDlg); + EnumChildWindows(hDlg, TranslateDialogEnumProc, hLangpack); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_CORE_DLL(MUUID*) Langpack_LookupUuid(WPARAM wParam) +{ + int idx = (wParam >> 16) & 0xFFFF; + return (idx > 0 && idx <= lMuuids.getCount()) ? lMuuids[ idx-1 ] : NULL; +} + +MIR_CORE_DLL(int) Langpack_MarkPluginLoaded(PLUGININFOEX* pInfo) +{ + int idx = lMuuids.getIndex(&pInfo->uuid); + if (idx == -1) + return 0; + + return (idx+1) << 16; +} + +MIR_CORE_DLL(void) Langpack_SortDuplicates(void) +{ + if (langPack.entryCount == 0) + return; + + LangPackEntry *s = langPack.entry+1, *d = s, *pLast = langPack.entry; + DWORD dwSavedHash = langPack.entry->englishHash; + bool bSortNeeded = false; + + for (int i=1; i < langPack.entryCount; i++, s++) { + if (s->englishHash != dwSavedHash) { + pLast = d; + if (s != d) + *d++ = *s; + else + d++; + dwSavedHash = s->englishHash; + } + else { + bSortNeeded = true; + LangPackEntry* p = (LangPackEntry*)mir_alloc(sizeof(LangPackEntry)); + *p = *s; + pLast->pNext = p; pLast = p; + } + } + + if (bSortNeeded) { + langPack.entryCount = (int)(d - langPack.entry); + qsort(langPack.entry, langPack.entryCount, sizeof(LangPackEntry), (int(*)(const void*, const void*))SortLangPackHashesProc); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_CORE_DLL(int) LoadLangPackModule(void) +{ + bModuleInitialized = TRUE; + + ZeroMemory(&langPack, sizeof(langPack)); + + TCHAR szSearch[MAX_PATH]; + PathToAbsoluteT(_T("langpack_*.txt"), szSearch, NULL); + + WIN32_FIND_DATA fd; + HANDLE hFind = FindFirstFile(szSearch, &fd); + if (hFind != INVALID_HANDLE_VALUE) { + PathToAbsoluteT(fd.cFileName, szSearch, NULL); + FindClose(hFind); + LoadLangPack(szSearch); + } + return 0; +} + +void UnloadLangPackModule() +{ + if ( !bModuleInitialized) return; + + int i; + for (i=0; i < lMuuids.getCount(); i++) + mir_free(lMuuids[i]); + lMuuids.destroy(); + + LangPackEntry* p = langPack.entry; + for (i=0; i < langPack.entryCount; i++, p++) { + if (p->pNext != NULL) { + for (LangPackEntry* p1 = p->pNext; p1 != NULL;) { + LangPackEntry* p2 = p1; p1 = p1->pNext; + mir_free(p2->local); + mir_free(p2->wlocal); + mir_free(p2); + } } + + mir_free(p->local); + mir_free(p->wlocal); + } + + if (langPack.entryCount) { + mir_free(langPack.entry); + langPack.entry=0; + langPack.entryCount=0; +} } + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_CORE_DLL(void) ReloadLangpack(TCHAR *pszStr) +{ + if (pszStr == NULL) + pszStr = langPack.filename; + + UnloadLangPackModule(); + LoadLangPack(pszStr); + Langpack_SortDuplicates(); +} diff --git a/src/mir_core/lists.cpp b/src/mir_core/lists.cpp new file mode 100644 index 0000000000..e4996fc156 --- /dev/null +++ b/src/mir_core/lists.cpp @@ -0,0 +1,278 @@ +/* + +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. +*/ + +#include "commonheaders.h" + +/* a simple sorted list implementation */ + +MIR_CORE_DLL(SortedList*) List_Create(int p_limit, int p_increment) +{ + SortedList* result = (SortedList*)mir_calloc(sizeof(SortedList)); + if (result == NULL) + return(NULL); + + result->increment = p_increment; + result->limit = p_limit; + return(result); +} + +MIR_CORE_DLL(void) List_Destroy(SortedList* p_list) +{ + if (p_list == NULL) + return; + + if (p_list->items != NULL) { + mir_free(p_list->items); + p_list->items = NULL; + } + + p_list->realCount = p_list->limit = 0; +} + +MIR_CORE_DLL(void*) List_Find(SortedList* p_list, void* p_value) +{ + int index; + + if ( !List_GetIndex(p_list, p_value, &index)) + return(NULL); + + return(p_list->items[ index ]); +} + +#ifdef _DEBUG +#pragma optimize("gt", on) +#endif + +MIR_CORE_DLL(int) List_GetIndex(SortedList* p_list, void* p_value, int* p_index) +{ + if (p_value == NULL) + { + *p_index = -1; + return 0; + } + + switch ((INT_PTR)p_list->sortFunc) + { + case 0: + break; + + case HandleKeySort: +#ifdef _WIN64 + { + const unsigned __int64 val = *(unsigned __int64 *)p_value; + int low = 0; + int high = p_list->realCount - 1; + + while (low <= high) + { + int i = (low + high) / 2; + unsigned __int64 vali = *(unsigned __int64 *)p_list->items[i]; + if (vali == val) + { + *p_index = i; + return 1; + } + + if (vali < val) + low = i + 1; + else + high = i - 1; + } + + *p_index = low; + } + break; +#endif + + case NumericKeySort: + { + const unsigned val = *(unsigned *)p_value; + int low = 0; + int high = p_list->realCount - 1; + + while (low <= high) + { + int i = (low + high) / 2; + unsigned vali = *(unsigned *)p_list->items[i]; + if (vali == val) + { + *p_index = i; + return 1; + } + + if (vali < val) + low = i + 1; + else + high = i - 1; + } + + *p_index = low; + } + break; + + case PtrKeySort: + { + int low = 0; + int high = p_list->realCount - 1; + + while (low <= high) + { + int i = (low + high) / 2; + const void* vali = p_list->items[i]; + if (vali == p_value) + { + *p_index = i; + return 1; + } + + if (vali < p_value) + low = i + 1; + else + high = i - 1; + } + + *p_index = low; + } + break; + + default: + { + int low = 0; + int high = p_list->realCount - 1; + + while (low <= high) + { + int i = (low + high) / 2; + int result = p_list->sortFunc(p_list->items[i], p_value); + if (result == 0) + { + *p_index = i; + return 1; + } + + if (result < 0) + low = i + 1; + else + high = i - 1; + } + + *p_index = low; + } + break; + } + + return 0; +} + +MIR_CORE_DLL(int) List_IndexOf(SortedList* p_list, void* p_value) +{ + if (p_value == NULL) + return -1; + + int i; + for (i=0; i < p_list->realCount; i++) + if (p_list->items[i] == p_value) + return i; + + return -1; +} + +#ifdef _DEBUG +#pragma optimize("", on) +#endif + +MIR_CORE_DLL(int) List_Insert(SortedList* p_list, void* p_value, int p_index) +{ + if (p_value == NULL || p_index > p_list->realCount) + return 0; + + if (p_list->realCount == p_list->limit) + { + p_list->items = (void**)mir_realloc(p_list->items, sizeof(void*)*(p_list->realCount + p_list->increment)); + p_list->limit += p_list->increment; + } + + if (p_index < p_list->realCount) + memmove(p_list->items+p_index+1, p_list->items+p_index, sizeof(void*)*(p_list->realCount-p_index)); + + p_list->realCount++; + + p_list->items[ p_index ] = p_value; + return 1; +} + +MIR_CORE_DLL(int) List_InsertPtr(SortedList* list, void* p) +{ + if (p == NULL) + return -1; + + int idx = list->realCount; + List_GetIndex(list, p, &idx); + return List_Insert(list, p, idx); +} + +MIR_CORE_DLL(int) List_Remove(SortedList* p_list, int index) +{ + if (index < 0 || index > p_list->realCount) + return(0); + + p_list->realCount--; + if (p_list->realCount > index) + { + memmove(p_list->items+index, p_list->items+index+1, sizeof(void*)*(p_list->realCount-index)); + p_list->items[ p_list->realCount ] = NULL; + } + + return 1; +} + +MIR_CORE_DLL(int) List_RemovePtr(SortedList* list, void* p) +{ + int idx = -1; + if (List_GetIndex(list, p, &idx)) + List_Remove(list, idx); + + return idx; +} + +MIR_CORE_DLL(void) List_Copy(SortedList* s, SortedList* d, size_t itemSize) +{ + d->increment = s->increment; + d->limit = s->limit; + d->realCount = s->realCount; + d->items = (void**)mir_alloc( sizeof(void*) * d->realCount); + memcpy(d->items, s->items, sizeof(void*) * d->realCount); +} + +MIR_CORE_DLL(void) List_ObjCopy(SortedList* s, SortedList* d, size_t itemSize) +{ + int i; + + d->increment = s->increment; + d->sortFunc = s->sortFunc; + + for (i = 0; i < s->realCount; i++) { + void* item = new char[ itemSize ]; + memcpy(item, s->items[i], itemSize); + List_Insert(d, item, i); +} } diff --git a/src/mir_core/md5.cpp b/src/mir_core/md5.cpp new file mode 100644 index 0000000000..a7d7a641e3 --- /dev/null +++ b/src/mir_core/md5.cpp @@ -0,0 +1,358 @@ +/* + Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. + + 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. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/* $Id: md5.c 2874 2006-05-16 21:38:00Z ghazan $ */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.c is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order + either statically or dynamically; added missing #include + in library. + 2002-03-11 lpd Corrected argument list for main(), and added int return + type, in test program and T value program. + 2002-02-21 lpd Added missing #include in test program. + 2000-07-03 lpd Patched to eliminate warnings about "constant is + unsigned in ANSI C, signed in traditional"; made test program + self-checking. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). + 1999-05-03 lpd Original version. + */ + +// (C) 2005 Joe @ Whale - changed to compile with Miranda + +#include "commonheaders.h" + +#define T_MASK ((mir_md5_word_t)~0) +#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) +#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) +#define T3 0x242070db +#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) +#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) +#define T6 0x4787c62a +#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) +#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) +#define T9 0x698098d8 +#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) +#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) +#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) +#define T13 0x6b901122 +#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) +#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) +#define T16 0x49b40821 +#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) +#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) +#define T19 0x265e5a51 +#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) +#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) +#define T22 0x02441453 +#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) +#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) +#define T25 0x21e1cde6 +#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) +#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) +#define T28 0x455a14ed +#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) +#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) +#define T31 0x676f02d9 +#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) +#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) +#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) +#define T35 0x6d9d6122 +#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) +#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) +#define T38 0x4bdecfa9 +#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) +#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) +#define T41 0x289b7ec6 +#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) +#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) +#define T44 0x04881d05 +#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) +#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) +#define T47 0x1fa27cf8 +#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) +#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) +#define T50 0x432aff97 +#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) +#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) +#define T53 0x655b59c3 +#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) +#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) +#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) +#define T57 0x6fa87e4f +#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) +#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) +#define T60 0x4e0811a1 +#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) +#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) +#define T63 0x2ad7d2bb +#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) + +//gfd* +static void md5_process(mir_md5_state_t *pms, const mir_md5_byte_t *data /*[64]*/) +{ + mir_md5_word_t + a = pms->abcd[0], b = pms->abcd[1], + c = pms->abcd[2], d = pms->abcd[3]; + mir_md5_word_t t; + /* Define storage for little-endian or both types of CPUs. */ + mir_md5_word_t xbuf[16]; + const mir_md5_word_t *X; + + { + /* + * Determine dynamically whether this is a big-endian or + * little-endian machine, since we can use a more efficient + * algorithm on the latter. + */ + static const int w = 1; + + if (*((const mir_md5_byte_t *)&w)) /* dynamic little-endian */ + { + /* + * On little-endian machines, we can process properly aligned + * data without copying it. + */ + if ( !((data - (const mir_md5_byte_t *)0) & 3)) { + /* data are properly aligned */ + X = (const mir_md5_word_t *)data; + } else { + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; + } + } + else /* dynamic big-endian */ + { + /* + * On big-endian machines, we must arrange the bytes in the + * right order. + */ + const mir_md5_byte_t *xp = data; + int i; + + X = xbuf; /* (dynamic only) */ + for (i = 0; i < 16; ++i, xp += 4) + xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + } + } + +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b, c, d) + X[k] + T[i]) <<< s). */ +#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define SET1(a, b, c, d, k, s, Ti)\ + t = a + F(b, c, d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET1(a, b, c, d, 0, 7, T1); + SET1(d, a, b, c, 1, 12, T2); + SET1(c, d, a, b, 2, 17, T3); + SET1(b, c, d, a, 3, 22, T4); + SET1(a, b, c, d, 4, 7, T5); + SET1(d, a, b, c, 5, 12, T6); + SET1(c, d, a, b, 6, 17, T7); + SET1(b, c, d, a, 7, 22, T8); + SET1(a, b, c, d, 8, 7, T9); + SET1(d, a, b, c, 9, 12, T10); + SET1(c, d, a, b, 10, 17, T11); + SET1(b, c, d, a, 11, 22, T12); + SET1(a, b, c, d, 12, 7, T13); + SET1(d, a, b, c, 13, 12, T14); + SET1(c, d, a, b, 14, 17, T15); + SET1(b, c, d, a, 15, 22, T16); + + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b, c, d) + X[k] + T[i]) <<< s). */ +#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define SET2(a, b, c, d, k, s, Ti)\ + t = a + G(b, c, d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET2(a, b, c, d, 1, 5, T17); + SET2(d, a, b, c, 6, 9, T18); + SET2(c, d, a, b, 11, 14, T19); + SET2(b, c, d, a, 0, 20, T20); + SET2(a, b, c, d, 5, 5, T21); + SET2(d, a, b, c, 10, 9, T22); + SET2(c, d, a, b, 15, 14, T23); + SET2(b, c, d, a, 4, 20, T24); + SET2(a, b, c, d, 9, 5, T25); + SET2(d, a, b, c, 14, 9, T26); + SET2(c, d, a, b, 3, 14, T27); + SET2(b, c, d, a, 8, 20, T28); + SET2(a, b, c, d, 13, 5, T29); + SET2(d, a, b, c, 2, 9, T30); + SET2(c, d, a, b, 7, 14, T31); + SET2(b, c, d, a, 12, 20, T32); + + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b, c, d) + X[k] + T[i]) <<< s). */ +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define SET3(a, b, c, d, k, s, Ti)\ + t = a + H(b, c, d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET3(a, b, c, d, 5, 4, T33); + SET3(d, a, b, c, 8, 11, T34); + SET3(c, d, a, b, 11, 16, T35); + SET3(b, c, d, a, 14, 23, T36); + SET3(a, b, c, d, 1, 4, T37); + SET3(d, a, b, c, 4, 11, T38); + SET3(c, d, a, b, 7, 16, T39); + SET3(b, c, d, a, 10, 23, T40); + SET3(a, b, c, d, 13, 4, T41); + SET3(d, a, b, c, 0, 11, T42); + SET3(c, d, a, b, 3, 16, T43); + SET3(b, c, d, a, 6, 23, T44); + SET3(a, b, c, d, 9, 4, T45); + SET3(d, a, b, c, 12, 11, T46); + SET3(c, d, a, b, 15, 16, T47); + SET3(b, c, d, a, 2, 23, T48); + + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b, c, d) + X[k] + T[i]) <<< s). */ +#define I(x, y, z) ((y) ^ ((x) | ~(z))) +#define SET4(a, b, c, d, k, s, Ti)\ + t = a + I(b, c, d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET4(a, b, c, d, 0, 6, T49); + SET4(d, a, b, c, 7, 10, T50); + SET4(c, d, a, b, 14, 15, T51); + SET4(b, c, d, a, 5, 21, T52); + SET4(a, b, c, d, 12, 6, T53); + SET4(d, a, b, c, 3, 10, T54); + SET4(c, d, a, b, 10, 15, T55); + SET4(b, c, d, a, 1, 21, T56); + SET4(a, b, c, d, 8, 6, T57); + SET4(d, a, b, c, 15, 10, T58); + SET4(c, d, a, b, 6, 15, T59); + SET4(b, c, d, a, 13, 21, T60); + SET4(a, b, c, d, 4, 6, T61); + SET4(d, a, b, c, 11, 10, T62); + SET4(c, d, a, b, 2, 15, T63); + SET4(b, c, d, a, 9, 21, T64); + + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + pms->abcd[0] += a; + pms->abcd[1] += b; + pms->abcd[2] += c; + pms->abcd[3] += d; +} + +MIR_CORE_DLL(void) mir_md5_init(mir_md5_state_t *pms) +{ + pms->count[0] = pms->count[1] = 0; + pms->abcd[0] = 0x67452301; + pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; + pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; + pms->abcd[3] = 0x10325476; +} + +MIR_CORE_DLL(void) mir_md5_append(mir_md5_state_t *pms, const mir_md5_byte_t *data, int nbytes) +{ + const mir_md5_byte_t *p = data; + int left = nbytes; + int offset = (pms->count[0] >> 3) & 63; + mir_md5_word_t nbits = (mir_md5_word_t)(nbytes << 3); + + if (nbytes <= 0) + return; + + /* Update the message length. */ + pms->count[1] += nbytes >> 29; + pms->count[0] += nbits; + if (pms->count[0] < nbits) + pms->count[1]++; + + /* Process an initial partial block. */ + if (offset) { + int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buf + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buf); + } + + /* Process full blocks. */ + for (; left >= 64; p += 64, left -= 64) + md5_process(pms, p); + + /* Process a final partial block. */ + if (left) + memcpy(pms->buf, p, left); +} + +MIR_CORE_DLL(void) mir_md5_finish(mir_md5_state_t *pms, mir_md5_byte_t digest[16]) +{ + static const mir_md5_byte_t pad[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + mir_md5_byte_t data[8]; + int i; + + /* Save the length before padding. */ + for (i = 0; i < 8; ++i) + data[i] = (mir_md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + /* Pad to 56 bytes mod 64. */ + mir_md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); + /* Append the length. */ + mir_md5_append(pms, data, 8); + for (i = 0; i < 16; ++i) + digest[i] = (mir_md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); +} + +MIR_CORE_DLL(void) mir_md5_hash(const mir_md5_byte_t *data, int len, mir_md5_byte_t digest[16]) +{ + mir_md5_state_t state; + mir_md5_init(&state); + mir_md5_append(&state, data, len); + mir_md5_finish(&state, digest); +} diff --git a/src/mir_core/memory.cpp b/src/mir_core/memory.cpp new file mode 100644 index 0000000000..0ecddc6717 --- /dev/null +++ b/src/mir_core/memory.cpp @@ -0,0 +1,280 @@ +/* + +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. +*/ + +#include "commonheaders.h" + +#define BLOCK_ALLOCED 0xABBABABA +#define BLOCK_FREED 0xDEADBEEF + +static int CheckBlock(void* blk) +{ + int result = FALSE; + char* p = (char*)blk - sizeof(DWORD)*2; + DWORD size, *b, *e; + + __try + { + size = *(DWORD*)p; + b = (DWORD*)&p[ sizeof(DWORD) ]; + e = (DWORD*)&p[ sizeof(DWORD)*2 + size ]; + + if (*b != BLOCK_ALLOCED || *e != BLOCK_ALLOCED) + { + if (*b == BLOCK_FREED && *e == BLOCK_FREED) + OutputDebugStringA("memory block is already deleted\n"); + else + OutputDebugStringA("memory block is corrupted\n"); + #if defined(_DEBUG) + DebugBreak(); + #endif + } + else result = TRUE; + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + OutputDebugStringA("access violation during checking memory block\n"); + #if defined(_DEBUG) + DebugBreak(); + #endif + } + + return result; +} + +/******************************************************************************/ + +MIR_C_CORE_DLL(void*) mir_alloc(size_t size) +{ + if (size == 0) + return NULL; + { + char* p = (char*)malloc(size + sizeof(DWORD)*3); + if (p == NULL) { + OutputDebugStringA("memory overflow\n"); + #if defined(_DEBUG) + DebugBreak(); + #endif + return NULL; + } + + *(DWORD*)p = (DWORD)size; + *(DWORD*)&p[ sizeof(DWORD) ] = BLOCK_ALLOCED; + *(DWORD*)&p[ size + sizeof(DWORD)*2 ] = BLOCK_ALLOCED; + return p + sizeof(DWORD)*2; +} } + +/******************************************************************************/ + +MIR_C_CORE_DLL(void*) mir_calloc(size_t size) +{ + void* p = mir_alloc(size); + if (p != NULL) + memset(p, 0, size); + return p; +} + +/******************************************************************************/ + +MIR_C_CORE_DLL(void*) mir_realloc(void* ptr, size_t size) +{ + char* p; + + if (ptr != NULL) { + if ( !CheckBlock(ptr)) + return NULL; + p = (char*)ptr - sizeof(DWORD)*2; + } + else p = NULL; + + p = (char*)realloc(p, size + sizeof(DWORD)*3); + if (p == NULL) { + OutputDebugStringA("memory overflow\n"); + #if defined(_DEBUG) + DebugBreak(); + #endif + return NULL; + } + + *(DWORD*)p = (DWORD)size; + *(DWORD*)&p[ sizeof(DWORD) ] = BLOCK_ALLOCED; + *(DWORD*)&p[ size + sizeof(DWORD)*2 ] = BLOCK_ALLOCED; + return p + sizeof(DWORD)*2; +} + +/******************************************************************************/ + +MIR_C_CORE_DLL(void) mir_free(void* ptr) +{ + char* p; + DWORD size; + + if (ptr == NULL) + return; + if ( !CheckBlock(ptr)) + return; + + p = (char*)ptr - sizeof(DWORD)*2; + size = *(DWORD*)p; + *(DWORD*)&p[ sizeof(DWORD) ] = BLOCK_FREED; + *(DWORD*)&p[ size + sizeof(DWORD)*2 ] = BLOCK_FREED; + free(p); +} + +/******************************************************************************/ + +MIR_CORE_DLL(char*) mir_strdup(const char* str) +{ + if (str != NULL) { + char* p = (char*)mir_alloc(strlen(str)+1); + if (p) + strcpy(p, str); + return p; + } + return NULL; +} + +/******************************************************************************/ + +MIR_CORE_DLL(char*) mir_strndup(const char* str, size_t len) +{ + if (str != NULL && len != 0) { + char* p = (char*)mir_alloc(len + 1); + if ( !p) { + memcpy(p, str, len); + p[ len ] = 0; + } + return p; + } + return NULL; +} + +/******************************************************************************/ + +MIR_CORE_DLL(WCHAR*) mir_wstrdup(const WCHAR* str) +{ + if (str != NULL) { + WCHAR* p = (WCHAR*)mir_alloc(sizeof(WCHAR)*(wcslen(str)+1)); + if (p) + wcscpy(p, str); + return p; + } + return NULL; +} + +/******************************************************************************/ + +MIR_CORE_DLL(int) mir_snprintf(char *buffer, size_t count, const char* fmt, ...) +{ + va_list va; + int len; + + va_start(va, fmt); + len = _vsnprintf(buffer, count-1, fmt, va); + va_end(va); + buffer[count-1] = 0; + return len; +} + +/******************************************************************************/ + +MIR_CORE_DLL(int) mir_sntprintf(TCHAR *buffer, size_t count, const TCHAR* fmt, ...) +{ + va_list va; + int len; + + va_start(va, fmt); + len = _vsntprintf(buffer, count-1, fmt, va); + va_end(va); + buffer[count-1] = 0; + return len; +} + +/******************************************************************************/ + +MIR_CORE_DLL(int) mir_vsnprintf(char *buffer, size_t count, const char* fmt, va_list va) +{ + int len; + + len = _vsnprintf(buffer, count-1, fmt, va); + buffer[count-1] = 0; + return len; +} + +/******************************************************************************/ + +MIR_CORE_DLL(int) mir_vsntprintf(TCHAR *buffer, size_t count, const TCHAR* fmt, va_list va) +{ + int len; + + len = _vsntprintf(buffer, count-1, fmt, va); + buffer[count-1] = 0; + return len; +} + +/******************************************************************************/ + +MIR_CORE_DLL(wchar_t*) mir_a2u_cp(const char* src, int codepage) +{ + if (src == NULL) + return NULL; + + int cbLen = MultiByteToWideChar(codepage, 0, src, -1, NULL, 0); + wchar_t* result = (wchar_t*)mir_alloc(sizeof(wchar_t)*(cbLen+1)); + if (result == NULL) + return NULL; + + MultiByteToWideChar(codepage, 0, src, -1, result, cbLen); + result[ cbLen ] = 0; + return result; +} + +/******************************************************************************/ + +MIR_CORE_DLL(wchar_t*) mir_a2u(const char* src) +{ + return mir_a2u_cp(src, Langpack_GetDefaultCodePage()); +} + +/******************************************************************************/ + +MIR_CORE_DLL(char*) mir_u2a_cp(const wchar_t* src, int codepage) +{ + if (src == NULL) + return NULL; + + int cbLen = WideCharToMultiByte(codepage, 0, src, -1, NULL, 0, NULL, NULL); + char* result = (char*)mir_alloc(cbLen+1); + if (result == NULL) + return NULL; + + WideCharToMultiByte(codepage, 0, src, -1, result, cbLen, NULL, NULL); + result[ cbLen ] = 0; + return result; +} + +/******************************************************************************/ + +MIR_CORE_DLL(char*) mir_u2a(const wchar_t* src) +{ + return mir_u2a_cp(src, Langpack_GetDefaultCodePage()); +} diff --git a/src/mir_core/mir_core.def b/src/mir_core/mir_core.def new file mode 100644 index 0000000000..43dd94d7ac --- /dev/null +++ b/src/mir_core/mir_core.def @@ -0,0 +1,126 @@ +LIBRARY mir_core + +EXPORTS +CallContactService @1 +CallProtoService @2 +Langpack_LookupUuid @3 +Langpack_MarkPluginLoaded @4 +CallFunctionAsync @5 +CallPluginEventHook @7 +CallService @8 +CallServiceSync @9 +CreateDirectoryTree @10 +CreateDirectoryTreeW @11 +CreateHookableEvent @12 +CreatePathToFile @13 +CreatePathToFileW @14 +CreateServiceFunction @15 +CreateServiceFunctionObj @16 +CreateServiceFunctionObjParam @17 +CreateServiceFunctionParam @18 +DestroyHookableEvent @19 +DestroyServiceFunction @20 +GetExceptionFilter @21 +GetInstByAddress @22 +HookEvent @23 +HookEventMessage @24 +HookEventObj @25 +HookEventObjParam @26 +HookEventParam @27 +KillModuleEventHooks @28 +KillModuleServices @29 +KillObjectEventHooks @30 +KillObjectServices @31 +KillObjectThreads @32 +Langpack_SortDuplicates @33 +Langpack_GetDefaultCodePage @34 +Langpack_GetDefaultLocale @35 +Langpack_PcharToTchar @36 +List_Copy @37 +List_Create @38 +List_Destroy @39 +List_Find @40 +List_GetIndex @41 +List_IndexOf @42 +List_Insert @43 +List_InsertPtr @44 +List_ObjCopy @45 +List_Remove @46 +List_RemovePtr @47 +LoadLangPack @48 +LoadLangPackModule @49 +NotifyEventHooks @50 +PathToAbsolute @51 +PathToAbsoluteW @52 +PathToRelative @53 +PathToRelativeW @54 +RegisterModule @55 +ReloadLangpack @56 +ServiceExists @57 +SetExceptionFilter @58 +SetHookDefaultForHookableEvent @59 +Thread_Pop @60 +Thread_Push @61 +Thread_Wait @62 +TranslateA_LP @63 +TranslateDialog_LP @64 +TranslateMenu_LP @65 +TranslateW_LP @66 +Ucs2toUtf8Len @67 +UnhookEvent @68 +UnregisterModule @69 +Utf8Decode @70 +Utf8DecodeCP @71 +Utf8DecodeW @72 +Utf8Encode @73 +Utf8EncodeCP @74 +Utf8EncodeW @75 +forkthread @76 +forkthreadex @77 +ltrim @78 +ltrimp @79 +mir_a2u @80 +mir_a2u_cp @81 +mir_alloc @82 +mir_calloc @83 +mir_free @84 +mir_hash @85 +mir_md5_append @86 +mir_md5_finish @87 +mir_md5_hash @88 +mir_md5_init @89 +mir_realloc @90 +mir_sha1_append @91 +mir_sha1_finish @92 +mir_sha1_hash @93 +mir_sha1_init @94 +mir_strdup @95 +mir_strndup @96 +mir_u2a @97 +mir_u2a_cp @98 +mir_vsnprintf @99 +mir_vsntprintf @100 +mir_wstrdup @101 +rtrim @102 +wildcmp @103 +wrtrim @104 +mir_snprintf @105 +mir_sntprintf @106 +db_unset @107 +db_free @108 +db_get @109 +db_get_b @110 +db_get_dw @111 +db_get_s @112 +db_get_sa @113 +db_get_w @114 +db_get_wsa @115 +db_set_b @116 +db_set_blob @117 +db_set_dw @118 +db_set_s @119 +db_set_utf @120 +db_set_w @121 +db_set_ws @122 +UnloadCoreModule @123 +Thread_SetName @124 diff --git a/src/mir_core/mir_core_10.vcxproj b/src/mir_core/mir_core_10.vcxproj new file mode 100644 index 0000000000..e5f452eb61 --- /dev/null +++ b/src/mir_core/mir_core_10.vcxproj @@ -0,0 +1,238 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + mir_core + {D9EFEA4B-B817-4DE1-BD62-68A5DB8F5F60} + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30128.1 + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)\ + $(SolutionDir)$(Configuration)\Obj\$(ProjectName)\ + $(SolutionDir)$(Configuration)64\ + $(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\ + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + EnableFastChecks + MultiThreadedDebugDLL + true + Level3 + EditAndContinue + 4996;%(DisableSpecificWarnings) + WIN32;_DEBUG;_WINDOWS;MIR_CORE_EXPORTS;_USRDLL;%(PreprocessorDefinitions) + Use + commonheaders.h + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + mir_core.def + true + false + Windows + miranda32.lib;ws2_32.lib;comctl32.lib;winmm.lib;version.lib;%(AdditionalDependencies) + $(SolutionDir)\lib + $(IntDir)$(TargetName).lib + + + + + + + + + + + + + Disabled + ..\..\include;%(AdditionalIncludeDirectories) + EnableFastChecks + MultiThreadedDebugDLL + true + Level3 + 4996;%(DisableSpecificWarnings) + WIN64;_DEBUG;_WINDOWS;MIR_CORE_EXPORTS;_USRDLL;%(PreprocessorDefinitions) + Use + commonheaders.h + + + _DEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + mir_core.def + true + false + $(IntDir)$(TargetName)64.lib + Windows + miranda64.lib;ws2_32.lib;comctl32.lib;winmm.lib;version.lib;%(AdditionalDependencies) + $(SolutionDir)\lib + /ignore:4197 %(AdditionalOptions) + + + + + Full + OnlyExplicitInline + Size + ..\..\include;%(AdditionalIncludeDirectories) + true + false + true + Level3 + 4996;%(DisableSpecificWarnings) + WIN32;NDEBUG;_WINDOWS;MIR_CORE_EXPORTS;_USRDLL;%(PreprocessorDefinitions) + Use + commonheaders.h + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + mir_core.def + true + true + true + false + Windows + miranda32.lib;ws2_32.lib;comctl32.lib;winmm.lib;version.lib;%(AdditionalDependencies) + $(SolutionDir)\lib + $(IntDir)$(TargetName).lib + + + + + + + + + + + + + Full + OnlyExplicitInline + Size + ..\..\include;%(AdditionalIncludeDirectories) + true + false + true + Level3 + 4996;%(DisableSpecificWarnings) + WIN64;NDEBUG;_WINDOWS;MIR_CORE_EXPORTS;_USRDLL;%(PreprocessorDefinitions) + Use + commonheaders.h + + + NDEBUG;%(PreprocessorDefinitions) + ..\..\include\msapi + + + mir_core.def + true + true + true + false + $(IntDir)$(TargetName)64.lib + Windows + miranda64.lib;ws2_32.lib;comctl32.lib;winmm.lib;version.lib;%(AdditionalDependencies) + $(SolutionDir)\lib + /ignore:4197 %(AdditionalOptions) + + + + + + \ No newline at end of file diff --git a/src/mir_core/mir_core_10.vcxproj.filters b/src/mir_core/mir_core_10.vcxproj.filters new file mode 100644 index 0000000000..27b6a42604 --- /dev/null +++ b/src/mir_core/mir_core_10.vcxproj.filters @@ -0,0 +1,76 @@ + + + + + {bf74d1c9-acd8-4fba-837d-734f024521c9} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {a578a180-0eb9-4c3e-b4ae-0eaefa01d207} + + + + + 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 + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/src/mir_core/miranda.cpp b/src/mir_core/miranda.cpp new file mode 100644 index 0000000000..b059e11cb7 --- /dev/null +++ b/src/mir_core/miranda.cpp @@ -0,0 +1,97 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2012 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. + +*/ + +#include "commonheaders.h" + +HWND hAPCWindow = NULL; + +int InitPathUtils(void); +void (*RecalculateTime)(void); + +int hLangpack = 0; +HINSTANCE hInst = 0; + +HANDLE hStackMutex, hThreadQueueEmpty; + +///////////////////////////////////////////////////////////////////////////////////////// +// module init + +static LRESULT CALLBACK APCWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_NULL) SleepEx(0, TRUE); + if (msg == WM_TIMECHANGE && RecalculateTime) + RecalculateTime(); + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +static void LoadCoreModule(void) +{ + INITCOMMONCONTROLSEX icce = {0}; + icce.dwSize = sizeof(icce); + icce.dwICC = ICC_WIN95_CLASSES | ICC_USEREX_CLASSES; + InitCommonControlsEx(&icce); + + if ( IsWinVerXPPlus()) { + hAPCWindow=CreateWindowEx(0, _T("ComboLBox"), NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); + SetClassLongPtr(hAPCWindow, GCL_STYLE, GetClassLongPtr(hAPCWindow, GCL_STYLE) | CS_DROPSHADOW); + DestroyWindow(hAPCWindow); + hAPCWindow = NULL; + } + + hAPCWindow = CreateWindowEx(0, _T("STATIC"), NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL); + SetWindowLongPtr(hAPCWindow, GWLP_WNDPROC, (LONG_PTR)APCWndProc); + hStackMutex = CreateMutex(NULL, FALSE, NULL); + hThreadQueueEmpty = CreateEvent(NULL, TRUE, TRUE, NULL); + + #ifdef WIN64 + HMODULE mirInst = GetModuleHandleA("miranda64.exe"); + #else + HMODULE mirInst = GetModuleHandleA("miranda32.exe"); + #endif + RecalculateTime = (void (*)()) GetProcAddress(mirInst, "RecalculateTime"); + + InitPathUtils(); + InitialiseModularEngine(); +} + +MIR_CORE_DLL(void) UnloadCoreModule(void) +{ + DestroyWindow(hAPCWindow); + CloseHandle(hStackMutex); + + DestroyModularEngine(); + UnloadLangPackModule(); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// entry point + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + if (fdwReason == DLL_PROCESS_ATTACH) { + hInst = hinstDLL; + LoadCoreModule(); + } + return TRUE; +} diff --git a/src/mir_core/miranda.h b/src/mir_core/miranda.h new file mode 100644 index 0000000000..af71276ac4 --- /dev/null +++ b/src/mir_core/miranda.h @@ -0,0 +1,131 @@ +/* + +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. +*/ + +#define NEWSTR_ALLOCA(A) (A == NULL)?NULL:strcpy((char*)alloca(strlen(A)+1), A) +#define NEWTSTR_ALLOCA(A) (A == NULL)?NULL:_tcscpy((TCHAR*)alloca((_tcslen(A)+1)* sizeof(TCHAR)), A) + +extern "C" +{ + MIR_CORE_DLL(int) Langpack_MarkPluginLoaded(PLUGININFOEX* pInfo); +}; + +MIR_CORE_DLL(MUUID*) Langpack_LookupUuid(WPARAM wParam); + +void UnloadLangPackModule(void); + +int InitialiseModularEngine(void); +void DestroyModularEngine(void); + +int InitPathUtils(void); + +extern HINSTANCE hInst; +extern HWND hAPCWindow; +extern HANDLE hStackMutex, hThreadQueueEmpty; + +/**** modules.cpp **********************************************************************/ + +struct THookSubscriber +{ + HINSTANCE hOwner; + int type; + union { + struct { + union { + MIRANDAHOOK pfnHook; + MIRANDAHOOKPARAM pfnHookParam; + MIRANDAHOOKOBJ pfnHookObj; + MIRANDAHOOKOBJPARAM pfnHookObjParam; + }; + void* object; + LPARAM lParam; + }; + struct { + HWND hwnd; + UINT message; + }; + }; +}; + +#define HOOK_SECRET_SIGNATURE 0xDEADBABA + +struct THook +{ + char name[ MAXMODULELABELLENGTH ]; + int id; + int subscriberCount; + THookSubscriber* subscriber; + MIRANDAHOOK pfnHook; + DWORD secretSignature; + CRITICAL_SECTION csHook; +}; + +extern LIST pluginListAddr; + +/**** langpack.cpp *********************************************************************/ + +char* LangPackTranslateString(MUUID* pUuid, const char *szEnglish, const int W); +TCHAR* LangPackTranslateStringT(int hLangpack, const TCHAR* tszEnglish); + +/**** options.cpp **********************************************************************/ + +HTREEITEM FindNamedTreeItemAtRoot(HWND hwndTree, const TCHAR* name); + +/**** utils.cpp ************************************************************************/ + +void HotkeyToName(TCHAR *buf, int size, BYTE shift, BYTE key); +WORD GetHotkeyValue(INT_PTR idHotkey); + +HBITMAP ConvertIconToBitmap(HICON hIcon, HIMAGELIST hIml, int iconId); + +class StrConvUT +{ +private: + wchar_t* m_body; + +public: + StrConvUT(const char* pSrc) : + m_body(mir_a2u(pSrc)) {} + + ~StrConvUT() { mir_free(m_body); } + operator const wchar_t* () const { return m_body; } +}; + +class StrConvAT +{ +private: + char* m_body; + +public: + StrConvAT(const wchar_t* pSrc) : + m_body(mir_u2a(pSrc)) {} + + ~StrConvAT() { mir_free(m_body); } + operator const char* () const { return m_body; } + operator const wchar_t* () const { return (wchar_t*)m_body; } // type cast to fake the interface definition + operator const LPARAM () const { return (LPARAM)m_body; } +}; + +#define StrConvT(x) StrConvUT(x) +#define StrConvTu(x) x +#define StrConvA(x) StrConvAT(x) +#define StrConvU(x) x diff --git a/src/mir_core/modules.cpp b/src/mir_core/modules.cpp new file mode 100644 index 0000000000..f87c7bb192 --- /dev/null +++ b/src/mir_core/modules.cpp @@ -0,0 +1,601 @@ +/* + +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. +*/ + +#include "commonheaders.h" +#include + +// list of hooks + +static int compareHooks(const THook* p1, const THook* p2) +{ + return strcmp(p1->name, p2->name); +} + +static LIST hooks(50, compareHooks); + +struct THookToMainThreadItem +{ + THook* hook; + HANDLE hDoneEvent; + WPARAM wParam; + LPARAM lParam; + int result; +}; + +// list of services + +struct TService +{ + DWORD nameHash; + HINSTANCE hOwner; + union { + MIRANDASERVICE pfnService; + MIRANDASERVICEPARAM pfnServiceParam; + MIRANDASERVICEOBJ pfnServiceObj; + MIRANDASERVICEOBJPARAM pfnServiceObjParam; + }; + int flags; + LPARAM lParam; + void* object; + char name[1]; +}; + +LIST services(100, NumericKeySortT); + +typedef struct +{ + HANDLE hDoneEvent; + WPARAM wParam; + LPARAM lParam; + int result; + const char *name; +} + TServiceToMainThreadItem; + +// other static variables +static BOOL bServiceMode = FALSE; +static CRITICAL_SECTION csHooks, csServices; +static DWORD mainThreadId; +static int hookId = 1; +static HANDLE hMainThread; +static HANDLE hMissingService; +static THook *pLastHook = NULL; + +///////////////////////////////////////////////////////////////////////////////////////// + +static int QueueMainThread(PAPCFUNC pFunc, void* pParam, HANDLE hDoneEvent) +{ + int result = QueueUserAPC(pFunc, hMainThread, (ULONG_PTR)pParam); + PostMessage(hAPCWindow, WM_NULL, 0, 0); // let this get processed in its own time + if (hDoneEvent) { + WaitForSingleObject(hDoneEvent, INFINITE); + CloseHandle(hDoneEvent); + } + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +// HOOKS + +MIR_CORE_DLL(HANDLE) CreateHookableEvent(const char *name) +{ + if (name == NULL) + return NULL; + + mir_cslock lck(csHooks); + + int idx; + if ((idx = hooks.getIndex((THook*)name)) != -1) + return hooks[idx]; + + THook* newItem = (THook*)mir_alloc(sizeof(THook)); + strncpy(newItem->name, name, sizeof(newItem->name)); newItem->name[ MAXMODULELABELLENGTH-1 ] = 0; + newItem->id = hookId++; + newItem->subscriberCount = 0; + newItem->subscriber = NULL; + newItem->pfnHook = NULL; + newItem->secretSignature = HOOK_SECRET_SIGNATURE; + InitializeCriticalSection(&newItem->csHook); + hooks.insert(newItem); + return (HANDLE)newItem; +} + +MIR_CORE_DLL(int) DestroyHookableEvent(HANDLE hEvent) +{ + if (pLastHook == (THook*)hEvent) + pLastHook = NULL; + + mir_cslock lck(csHooks); + + int idx; + if ((idx = hooks.getIndex((THook*)hEvent)) == -1) + return 1; + + THook* p = hooks[idx]; + p->secretSignature = 0; + if (p->subscriberCount) { + mir_free(p->subscriber); + p->subscriber = NULL; + p->subscriberCount = 0; + } + hooks.remove(idx); + DeleteCriticalSection(&p->csHook); + mir_free(p); + return 0; +} + +MIR_CORE_DLL(int) SetHookDefaultForHookableEvent(HANDLE hEvent, MIRANDAHOOK pfnHook) +{ + THook* p = (THook*)hEvent; + + mir_cslock lck(csHooks); + if (hooks.getIndex(p) != -1) + p->pfnHook = pfnHook; + return 0; +} + +MIR_CORE_DLL(int) CallPluginEventHook(HINSTANCE hInst, HANDLE hEvent, WPARAM wParam, LPARAM lParam) +{ + THook* p = (THook*)hEvent; + if (p == NULL) + return -1; + + mir_cslock lck(p->csHook); + for (int i = 0; i < p->subscriberCount; i++) { + THookSubscriber* s = &p->subscriber[i]; + if (s->hOwner != hInst) + continue; + + int returnVal; + switch (s->type) { + case 1: returnVal = s->pfnHook(wParam, lParam); break; + case 2: returnVal = s->pfnHookParam(wParam, lParam, s->lParam); break; + case 3: returnVal = s->pfnHookObj(s->object, wParam, lParam); break; + case 4: returnVal = s->pfnHookObjParam(s->object, wParam, lParam, s->lParam); break; + case 5: returnVal = SendMessage(s->hwnd, s->message, wParam, lParam); break; + default: continue; + } + if (returnVal) + return returnVal; + } + + if (p->subscriberCount == 0 && p->pfnHook != 0) + return p->pfnHook(wParam, lParam); + + return 0; +} + +static int CallHookSubscribers(THook* p, WPARAM wParam, LPARAM lParam) +{ + if (p == NULL) + return -1; + + mir_cslock lck(p->csHook); + + // NOTE: We've got the critical section while all this lot are called. That's mostly safe, though. + for (int i = 0; i < p->subscriberCount; i++) { + THookSubscriber* s = &p->subscriber[i]; + + int returnVal; + switch (s->type) { + case 1: returnVal = s->pfnHook(wParam, lParam); break; + case 2: returnVal = s->pfnHookParam(wParam, lParam, s->lParam); break; + case 3: returnVal = s->pfnHookObj(s->object, wParam, lParam); break; + case 4: returnVal = s->pfnHookObjParam(s->object, wParam, lParam, s->lParam); break; + case 5: returnVal = SendMessage(s->hwnd, s->message, wParam, lParam); break; + default: continue; + } + if (returnVal) + return returnVal; + } + + // call the default hook if any + if (p->pfnHook != 0) + return p->pfnHook(wParam, lParam); + + return 0; +} + +enum { hookOk, hookEmpty, hookInvalid }; + +__forceinline int checkHook(THook* p) +{ + if (p == NULL) + return hookInvalid; + + int ret; + __try + { + if (p->secretSignature != HOOK_SECRET_SIGNATURE) + ret = hookInvalid; + else if (p->subscriberCount == 0 && p->pfnHook == NULL) + ret = hookEmpty; + else + ret = hookOk; + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + ret = hookInvalid; + } + + return ret; +} + +static void CALLBACK HookToMainAPCFunc(ULONG_PTR dwParam) +{ + THookToMainThreadItem* item = (THookToMainThreadItem*)dwParam; + item->result = CallHookSubscribers(item->hook, item->wParam, item->lParam); + SetEvent(item->hDoneEvent); +} + +MIR_CORE_DLL(int) NotifyEventHooks(HANDLE hEvent, WPARAM wParam, LPARAM lParam) +{ + switch ( checkHook((THook*)hEvent)) { + case hookInvalid: return -1; + case hookEmpty: return 0; + } + + if ( GetCurrentThreadId() == mainThreadId) + return CallHookSubscribers((THook*)hEvent, wParam, lParam); + + mir_ptr item; + item->hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + item->hook = (THook*)hEvent; + item->wParam = wParam; + item->lParam = lParam; + QueueMainThread(HookToMainAPCFunc, item, item->hDoneEvent); + return item->result; +} + +static HANDLE HookEventInt(int type, const char* name, MIRANDAHOOK hookProc, void* object, LPARAM lParam) +{ + mir_cslock lck(csHooks); + + int idx; + if ((idx = hooks.getIndex((THook*)name)) == -1) + return NULL; + + THook* p = hooks[ idx ]; + p->subscriber = (THookSubscriber*)mir_realloc(p->subscriber, sizeof(THookSubscriber)*(p->subscriberCount+1)); + p->subscriber[ p->subscriberCount ].type = type; + p->subscriber[ p->subscriberCount ].pfnHook = hookProc; + p->subscriber[ p->subscriberCount ].object = object; + p->subscriber[ p->subscriberCount ].lParam = lParam; + p->subscriber[ p->subscriberCount ].hOwner = GetInstByAddress(hookProc); + p->subscriberCount++; + + return (HANDLE)((p->id << 16) | p->subscriberCount); +} + +MIR_CORE_DLL(HANDLE) HookEvent(const char* name, MIRANDAHOOK hookProc) +{ + return HookEventInt(1, name, hookProc, 0, 0); +} + +MIR_CORE_DLL(HANDLE) HookEventParam(const char* name, MIRANDAHOOKPARAM hookProc, LPARAM lParam) +{ + return HookEventInt(2, name, (MIRANDAHOOK)hookProc, 0, lParam); +} + +MIR_CORE_DLL(HANDLE) HookEventObj(const char* name, MIRANDAHOOKOBJ hookProc, void* object) +{ + return HookEventInt(3, name, (MIRANDAHOOK)hookProc, object, 0); +} + +MIR_CORE_DLL(HANDLE) HookEventObjParam(const char* name, MIRANDAHOOKOBJPARAM hookProc, void* object, LPARAM lParam) +{ + return HookEventInt(4, name, (MIRANDAHOOK)hookProc, object, lParam); +} + +MIR_CORE_DLL(HANDLE) HookEventMessage(const char* name, HWND hwnd, UINT message) +{ + mir_cslock lck(csHooks); + + int idx; + if ((idx = hooks.getIndex((THook*)name)) == -1) + return NULL; + + THook* p = hooks[ idx ]; + p->subscriber = (THookSubscriber*)mir_realloc(p->subscriber, sizeof(THookSubscriber)*(p->subscriberCount+1)); + p->subscriber[ p->subscriberCount ].type = 5; + p->subscriber[ p->subscriberCount ].hwnd = hwnd; + p->subscriber[ p->subscriberCount ].message = message; + p->subscriberCount++; + return (HANDLE)((p->id << 16) | p->subscriberCount); +} + +MIR_CORE_DLL(int) UnhookEvent(HANDLE hHook) +{ + if (hHook == NULL) + return 0; + + int hookId = (int)hHook >> 16; + int subscriberId = ((int)hHook & 0xFFFF) - 1; + + mir_cslock lck(csHooks); + + THook* p = NULL; + for (int i = 0; i < hooks.getCount(); i++) + if (hooks[i]->id == hookId) { + p = hooks[i]; + break; + } + + if (p == NULL) + return 1; + + if (subscriberId >= p->subscriberCount || subscriberId < 0) + return 1; + + p->subscriber[subscriberId].type = 0; + p->subscriber[subscriberId].pfnHook = NULL; + p->subscriber[subscriberId].hOwner = NULL; + while (p->subscriberCount && p->subscriber[p->subscriberCount-1].type == 0) + p->subscriberCount--; + if (p->subscriberCount == 0) { + if (p->subscriber) mir_free(p->subscriber); + p->subscriber = NULL; + } + return 0; +} + +MIR_CORE_DLL(void) KillModuleEventHooks(HINSTANCE hInst) +{ + mir_cslock lck(csHooks); + + for (int i = hooks.getCount()-1; i >= 0; i--) { + if (hooks[i]->subscriberCount == 0) + continue; + + for (int j = hooks[i]->subscriberCount-1; j >= 0; j--) { + if (hooks[i]->subscriber[j].hOwner != hInst) + continue; + + char szModuleName[ MAX_PATH ]; + GetModuleFileNameA(hooks[i]->subscriber[j].hOwner, szModuleName, sizeof(szModuleName)); + UnhookEvent((HANDLE)((hooks[i]->id << 16) + j + 1)); + if (hooks[i]->subscriberCount == 0) + break; + } + } +} + +MIR_CORE_DLL(void) KillObjectEventHooks(void* pObject) +{ + mir_cslock lck(csHooks); + + for (int i = hooks.getCount()-1; i >= 0; i--) { + if (hooks[i]->subscriberCount == 0) + continue; + + for (int j = hooks[i]->subscriberCount-1; j >= 0; j--) { + if (hooks[i]->subscriber[j].object == pObject) { + UnhookEvent((HANDLE)((hooks[i]->id << 16) + j + 1)); + if (hooks[i]->subscriberCount == 0) + break; + } + } + } +} + +static void DestroyHooks() +{ + mir_cslock lck(csHooks); + + for (int i=0; i < hooks.getCount(); i++) { + THook* p = hooks[i]; + if (p->subscriberCount) + mir_free(p->subscriber); + DeleteCriticalSection(&p->csHook); + mir_free(p); + } +} + +/////////////////////SERVICES + +static __inline TService* FindServiceByName(const char *name) +{ + unsigned hash = mir_hashstr(name); + return services.find((TService*)&hash); +} + +static HANDLE CreateServiceInt(int type, const char *name, MIRANDASERVICE serviceProc, void* object, LPARAM lParam) +{ + if (name == NULL) + return NULL; + + TService tmp; + tmp.nameHash = mir_hashstr(name); + + mir_cslock lck(csServices); + + if (services.getIndex(&tmp) != -1) + return NULL; + + TService* p = (TService*)mir_alloc(sizeof(*p) + strlen(name)); + strcpy(p->name, name); + p->nameHash = tmp.nameHash; + p->pfnService = serviceProc; + p->hOwner = GetInstByAddress(serviceProc); + p->flags = type; + p->lParam = lParam; + p->object = object; + services.insert(p); + + return (HANDLE)tmp.nameHash; +} + +MIR_CORE_DLL(HANDLE) CreateServiceFunction(const char *name, MIRANDASERVICE serviceProc) +{ + return CreateServiceInt(0, name, serviceProc, 0, 0); +} + +MIR_CORE_DLL(HANDLE) CreateServiceFunctionParam(const char *name, MIRANDASERVICEPARAM serviceProc, LPARAM lParam) +{ + return CreateServiceInt(1, name, (MIRANDASERVICE)serviceProc, 0, lParam); +} + +MIR_CORE_DLL(HANDLE) CreateServiceFunctionObj(const char *name, MIRANDASERVICEOBJ serviceProc, void* object) +{ + return CreateServiceInt(2, name, (MIRANDASERVICE)serviceProc, object, 0); +} + +MIR_CORE_DLL(HANDLE) CreateServiceFunctionObjParam(const char *name, MIRANDASERVICEOBJPARAM serviceProc, void* object, LPARAM lParam) +{ + return CreateServiceInt(3, name, (MIRANDASERVICE)serviceProc, object, lParam); +} + +MIR_CORE_DLL(int) DestroyServiceFunction(HANDLE hService) +{ + mir_cslock lck(csServices); + + int idx; + if ((idx = services.getIndex((TService*)&hService)) != -1) { + mir_free(services[idx]); + services.remove(idx); + } + + return 0; +} + +MIR_CORE_DLL(int) ServiceExists(const char *name) +{ + if (name == NULL) + return FALSE; + + mir_cslock lck(csServices); + return FindServiceByName(name) != NULL; +} + +MIR_CORE_DLL(INT_PTR) CallService(const char *name, WPARAM wParam, LPARAM lParam) +{ + if (name == NULL) + return CALLSERVICE_NOTFOUND; + + TService *pService; + { + mir_cslock lck(csServices); + if ((pService = FindServiceByName(name)) == NULL) + return CALLSERVICE_NOTFOUND; + } + + MIRANDASERVICE pfnService = pService->pfnService; + int flags = pService->flags; + LPARAM fnParam = pService->lParam; + void* object = pService->object; + switch(flags) { + case 1: return ((MIRANDASERVICEPARAM)pfnService)(wParam, lParam, fnParam); + case 2: return ((MIRANDASERVICEOBJ)pfnService)(object, wParam, lParam); + case 3: return ((MIRANDASERVICEOBJPARAM)pfnService)(object, wParam, lParam, fnParam); + default: return pfnService(wParam, lParam); +} } + +static void CALLBACK CallServiceToMainAPCFunc(ULONG_PTR dwParam) +{ + TServiceToMainThreadItem *item = (TServiceToMainThreadItem*) dwParam; + item->result = CallService(item->name, item->wParam, item->lParam); + SetEvent(item->hDoneEvent); +} + +MIR_CORE_DLL(INT_PTR) CallServiceSync(const char *name, WPARAM wParam, LPARAM lParam) +{ + if (name == NULL) + return CALLSERVICE_NOTFOUND; + + // the service is looked up within the main thread, since the time it takes + // for the APC queue to clear the service being called maybe removed. + // even thou it may exists before the call, the critsec can't be locked between calls. + if (GetCurrentThreadId() == mainThreadId) + return CallService(name, wParam, lParam); + + mir_ptr item; + item->wParam = wParam; + item->lParam = lParam; + item->name = name; + item->hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + QueueMainThread(CallServiceToMainAPCFunc, item, item->hDoneEvent); + return item->result; +} + +MIR_CORE_DLL(int) CallFunctionAsync(void (__stdcall *func)(void *), void *arg) +{ + QueueMainThread((PAPCFUNC)func, arg, 0); + return 0; +} + +MIR_CORE_DLL(void) KillModuleServices(HINSTANCE hInst) +{ + mir_cslock lck(csServices); + + for (int i = services.getCount()-1; i >= 0; i--) { + if (services[i]->hOwner == hInst) { + char szModuleName[ MAX_PATH ]; + GetModuleFileNameA(services[i]->hOwner, szModuleName, sizeof(szModuleName)); + DestroyServiceFunction((HANDLE)services[i]->nameHash); + } + } +} + +MIR_CORE_DLL(void) KillObjectServices(void* pObject) +{ + mir_cslock lck(csServices); + + for (int i = services.getCount()-1; i >= 0; i--) + if (services[i]->object == pObject) + DestroyServiceFunction((HANDLE)services[i]->nameHash); +} + +static void DestroyServices() +{ + mir_cslock lck(csServices); + + for (int j=0; j < services.getCount(); j++) + mir_free(services[j]); +} + +/////////////////////////////////////////////////////////////////////////////// + +int InitialiseModularEngine(void) +{ + InitializeCriticalSection(&csHooks); + InitializeCriticalSection(&csServices); + + mainThreadId = GetCurrentThreadId(); + DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hMainThread, 0, FALSE, DUPLICATE_SAME_ACCESS); + + hMissingService = CreateHookableEvent(ME_SYSTEM_MISSINGSERVICE); + return 0; +} + +void DestroyModularEngine(void) +{ + DestroyHooks(); + hooks.destroy(); + DeleteCriticalSection(&csHooks); + + DestroyServices(); + services.destroy(); + DeleteCriticalSection(&csServices); + + CloseHandle(hMainThread); +} diff --git a/src/mir_core/path.cpp b/src/mir_core/path.cpp new file mode 100644 index 0000000000..fada3dcd18 --- /dev/null +++ b/src/mir_core/path.cpp @@ -0,0 +1,210 @@ +/* + +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. +*/ +#include "commonheaders.h" + +static char szMirandaPath[MAX_PATH]; +static char szMirandaPathLower[MAX_PATH]; +static TCHAR szMirandaPathW[MAX_PATH]; +static TCHAR szMirandaPathWLower[MAX_PATH]; + +static int pathIsAbsolute(const char *path) +{ + if (strlen(path) <= 2) + return 0; + if ((path[1] == ':' && path[2] == '\\') || (path[0] == '\\' && path[1] == '\\')) + return 1; + return 0; +} + +MIR_CORE_DLL(int) PathToRelative(const char *pSrc, char *pOut) +{ + if ( !pSrc || !strlen(pSrc) || strlen(pSrc)>MAX_PATH) return 0; + if ( !pathIsAbsolute(pSrc)) { + mir_snprintf(pOut, MAX_PATH, "%s", pSrc); + return (int)strlen(pOut); + } + + char szTmp[MAX_PATH]; + mir_snprintf(szTmp, SIZEOF(szTmp), "%s", pSrc); + _strlwr(szTmp); + if (strstr(szTmp, szMirandaPathLower)) { + mir_snprintf(pOut, MAX_PATH, "%s", pSrc+strlen(szMirandaPathLower)); + return (int)strlen(pOut); + } + else { + mir_snprintf(pOut, MAX_PATH, "%s", pSrc); + return (int)strlen(pOut); + } +} + +MIR_CORE_DLL(int) PathToAbsolute(const char *pSrc, char *pOut, char* base) +{ + if ( !pSrc || !strlen(pSrc) || strlen(pSrc) > MAX_PATH) + return 0; + + if (base == NULL) + base = szMirandaPath; + + char buf[MAX_PATH]; + if (pSrc[0] < ' ') + return mir_snprintf(pOut, MAX_PATH, "%s", pSrc); + else if (pathIsAbsolute(pSrc)) + return GetFullPathNameA(pSrc, MAX_PATH, pOut, NULL); + else if (pSrc[0] != '\\') + mir_snprintf(buf, MAX_PATH, "%s%s", base, pSrc); + else + mir_snprintf(buf, MAX_PATH, "%s%s", base, pSrc+1); + + return GetFullPathNameA(buf, MAX_PATH, pOut, NULL); +} + +MIR_CORE_DLL(void) CreatePathToFile(char* szFilePath) +{ + char* pszLastBackslash = strrchr(szFilePath, '\\'); + if (pszLastBackslash == NULL) + return; + + *pszLastBackslash = '\0'; + CreateDirectoryTree(szFilePath); + *pszLastBackslash = '\\'; +} + +MIR_CORE_DLL(int) CreateDirectoryTree(const char *szDir) +{ + DWORD dwAttributes; + char *pszLastBackslash, szTestDir[ MAX_PATH ]; + + lstrcpynA(szTestDir, szDir, SIZEOF(szTestDir)); + if ((dwAttributes = GetFileAttributesA(szTestDir)) != INVALID_FILE_ATTRIBUTES && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)) + return 0; + + pszLastBackslash = strrchr(szTestDir, '\\'); + if (pszLastBackslash == NULL) + return 0; + + *pszLastBackslash = '\0'; + CreateDirectoryTree(szTestDir); + *pszLastBackslash = '\\'; + return (CreateDirectoryA(szTestDir, NULL) == 0) ? GetLastError() : 0; +} + +/////////////////////////////////////////////////////////////////////////////// + +static int pathIsAbsoluteW(const TCHAR *path) +{ + if (lstrlen(path) <= 2) + return 0; + if ((path[1] == ':' && path[2] == '\\') || (path[0] == '\\' && path[1] == '\\')) + return 1; + return 0; +} + +MIR_CORE_DLL(int) PathToRelativeW(const WCHAR *pSrc, WCHAR *pOut) +{ + if ( !pSrc || !lstrlen(pSrc) || lstrlen(pSrc) > MAX_PATH) + return 0; + + if ( !pathIsAbsoluteW(pSrc)) + mir_sntprintf(pOut, MAX_PATH, _T("%s"), pSrc); + else { + TCHAR szTmp[MAX_PATH]; + + mir_sntprintf(szTmp, SIZEOF(szTmp), _T("%s"), pSrc); + _tcslwr(szTmp); + if (_tcsstr(szTmp, szMirandaPathWLower)) + mir_sntprintf(pOut, MAX_PATH, _T("%s"), pSrc+lstrlen(szMirandaPathWLower)); + else + mir_sntprintf(pOut, MAX_PATH, _T("%s"), pSrc); + } + return lstrlen(pOut); +} + +MIR_CORE_DLL(int) PathToAbsoluteW(const TCHAR *pSrc, TCHAR *pOut, TCHAR* base) +{ + if ( !pSrc || !wcslen(pSrc) || wcslen(pSrc) > MAX_PATH) + return 0; + + if (base == NULL) + base = szMirandaPathW; + + TCHAR buf[MAX_PATH]; + if (pSrc[0] < ' ') + return mir_sntprintf(pOut, MAX_PATH, _T("%s"), pSrc); + else if (pathIsAbsoluteW(pSrc)) + return GetFullPathName(pSrc, MAX_PATH, pOut, NULL); + else if (pSrc[0] != '\\') + mir_sntprintf(buf, MAX_PATH, _T("%s%s"), base, pSrc); + else + mir_sntprintf(buf, MAX_PATH, _T("%s%s"), base, pSrc+1); + + return GetFullPathName(buf, MAX_PATH, pOut, NULL); +} + +MIR_CORE_DLL(void) CreatePathToFileW(WCHAR* wszFilePath) +{ + WCHAR* pszLastBackslash = wcsrchr(wszFilePath, '\\'); + if (pszLastBackslash == NULL) + return; + + *pszLastBackslash = '\0'; + CreateDirectoryTreeW(wszFilePath); + *pszLastBackslash = '\\'; +} + +MIR_CORE_DLL(int) CreateDirectoryTreeW(const WCHAR* szDir) +{ + DWORD dwAttributes; + WCHAR* pszLastBackslash, szTestDir[ MAX_PATH ]; + + lstrcpynW(szTestDir, szDir, SIZEOF(szTestDir)); + if ((dwAttributes = GetFileAttributesW(szTestDir)) != INVALID_FILE_ATTRIBUTES && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)) + return 0; + + pszLastBackslash = wcsrchr(szTestDir, '\\'); + if (pszLastBackslash == NULL) + return 0; + + *pszLastBackslash = '\0'; + CreateDirectoryTreeW(szTestDir); + *pszLastBackslash = '\\'; + return (CreateDirectoryW(szTestDir, NULL) == 0) ? GetLastError() : 0; +} + +int InitPathUtils(void) +{ + char *p = 0; + GetModuleFileNameA(hInst, szMirandaPath, SIZEOF(szMirandaPath)); + p = strrchr(szMirandaPath, '\\'); + if (p) + p[1] = 0; + mir_snprintf(szMirandaPathLower, MAX_PATH, "%s", szMirandaPath); + _strlwr(szMirandaPathLower); + + GetModuleFileName(hInst, szMirandaPathW, SIZEOF(szMirandaPathW)); + TCHAR *tp = _tcsrchr(szMirandaPathW, '\\'); + if (tp) + tp[1] = 0; + mir_sntprintf(szMirandaPathWLower, SIZEOF(szMirandaPathWLower), _T("%s"), szMirandaPathW); + _tcslwr(szMirandaPathWLower); + return 0; +} diff --git a/src/mir_core/sha1.cpp b/src/mir_core/sha1.cpp new file mode 100644 index 0000000000..9e1b376d92 --- /dev/null +++ b/src/mir_core/sha1.cpp @@ -0,0 +1,155 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is SHA 180-1 Reference Implementation (Compact version). + * + * The Initial Developer of the Original Code is + * Paul Kocher of Cryptography Research. + * Portions created by the Initial Developer are Copyright (C) 1995-9 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "commonheaders.h" + +#define SHA_ROTL(X, n) (((X) << (n)) | ((X) >> (32-(n)))) + +static void shaHashBlock(mir_sha1_ctx *ctx) +{ + int t; + unsigned long A, B, C, D, E, TEMP; + + for (t = 16; t <= 79; t++) + ctx->W[t] = + SHA_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1); + + A = ctx->H[0]; + B = ctx->H[1]; + C = ctx->H[2]; + D = ctx->H[3]; + E = ctx->H[4]; + + for (t = 0; t <= 19; t++) { + TEMP = SHA_ROTL(A, 5) + (((C^D)&B)^D) + E + ctx->W[t] + 0x5a827999L; + E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; + } + for (t = 20; t <= 39; t++) { + TEMP = SHA_ROTL(A, 5) + (B^C^D) + E + ctx->W[t] + 0x6ed9eba1L; + E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; + } + for (t = 40; t <= 59; t++) { + TEMP = SHA_ROTL(A, 5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdcL; + E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; + } + for (t = 60; t <= 79; t++) { + TEMP = SHA_ROTL(A, 5) + (B^C^D) + E + ctx->W[t] + 0xca62c1d6L; + E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; + } + + ctx->H[0] += A; + ctx->H[1] += B; + ctx->H[2] += C; + ctx->H[3] += D; + ctx->H[4] += E; +} + +MIR_CORE_DLL(void) mir_sha1_init(mir_sha1_ctx *ctx) +{ + ctx->lenW = 0; + ctx->sizeHi = ctx->sizeLo = 0; + + /* Initialize H with the magic constants (see FIPS180 for constants) + */ + ctx->H[0] = 0x67452301L; + ctx->H[1] = 0xefcdab89L; + ctx->H[2] = 0x98badcfeL; + ctx->H[3] = 0x10325476L; + ctx->H[4] = 0xc3d2e1f0L; + + for (int i = 0; i < 80; i++) + ctx->W[i] = 0; +} + +MIR_CORE_DLL(void) mir_sha1_append(mir_sha1_ctx *ctx, mir_sha1_byte_t *dataIn, int len) +{ + /* Read the data into W and process blocks as they get full + */ + for (int i = 0; i < len; i++) { + ctx->W[ctx->lenW / 4] <<= 8; + ctx->W[ctx->lenW / 4] |= (unsigned long)dataIn[i]; + if ((++ctx->lenW) % 64 == 0) { + shaHashBlock(ctx); + ctx->lenW = 0; + } + ctx->sizeLo += 8; + ctx->sizeHi += (ctx->sizeLo < 8); + } +} + +MIR_CORE_DLL(void) mir_sha1_finish(mir_sha1_ctx *ctx, mir_sha1_byte_t hashout[20]) +{ + unsigned char pad0x80 = 0x80; + unsigned char pad0x00 = 0x00; + unsigned char padlen[8]; + int i; + + /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length + */ + padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255); + padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255); + padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255); + padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255); + padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255); + padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255); + padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255); + padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255); + mir_sha1_append(ctx, &pad0x80, 1); + while (ctx->lenW != 56) + mir_sha1_append(ctx, &pad0x00, 1); + mir_sha1_append(ctx, padlen, 8); + + /* Output hash + */ + for (i = 0; i < 20; i++) { + hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24); + ctx->H[i / 4] <<= 8; + } + + /* + * Re-initialize the context (also zeroizes contents) + */ + mir_sha1_init(ctx); +} + +MIR_CORE_DLL(void) mir_sha1_hash(mir_sha1_byte_t *dataIn, int len, mir_sha1_byte_t hashout[20]) +{ + mir_sha1_ctx ctx; + + mir_sha1_init(&ctx); + mir_sha1_append(&ctx, dataIn, len); + mir_sha1_finish(&ctx, hashout); +} diff --git a/src/mir_core/threads.cpp b/src/mir_core/threads.cpp new file mode 100644 index 0000000000..90dcdaaf5d --- /dev/null +++ b/src/mir_core/threads.cpp @@ -0,0 +1,372 @@ +/* + +Miranda IM: the free IM client for Microsoft* Windows* + +Copyright 2000-2012 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. + +*/ + +#include "commonheaders.h" + +///////////////////////////////////////////////////////////////////////////////////////// +// APC and mutex functions + +static void __stdcall DummyAPCFunc(ULONG_PTR) +{ + /* called in the context of thread that cleared it's APC queue */ + return; +} + +static int MirandaWaitForMutex(HANDLE hEvent) +{ + for (;;) { + // will get WAIT_IO_COMPLETE for QueueUserAPC() which isnt a result + DWORD rc = MsgWaitForMultipleObjectsEx(1, &hEvent, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE); + if (rc == WAIT_OBJECT_0 + 1) { + MSG msg; + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if (IsDialogMessage(msg.hwnd, &msg)) continue; + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + else if (rc == WAIT_OBJECT_0) { // got object + return 1; + } + else if (rc == WAIT_ABANDONED_0 || rc == WAIT_FAILED) + return 0; + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// exception handling + +static DWORD __cdecl sttDefaultFilter(DWORD, EXCEPTION_POINTERS*) +{ + return EXCEPTION_EXECUTE_HANDLER; +} + +pfnExceptionFilter pMirandaExceptFilter = sttDefaultFilter; + +MIR_CORE_DLL(pfnExceptionFilter) GetExceptionFilter() +{ + return pMirandaExceptFilter; +} + +MIR_CORE_DLL(pfnExceptionFilter) SetExceptionFilter(pfnExceptionFilter pMirandaExceptFilter) +{ + pfnExceptionFilter oldOne = pMirandaExceptFilter; + if (pMirandaExceptFilter != 0) + pMirandaExceptFilter = pMirandaExceptFilter; + return oldOne; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// thread support functions + +struct THREAD_WAIT_ENTRY +{ + DWORD dwThreadId; // valid if hThread isn't signalled + HANDLE hThread; + HINSTANCE hOwner; + void* pObject; + //PVOID addr; +}; + +static LIST threads(10, NumericKeySortT); + +struct FORK_ARG { + HANDLE hEvent; + pThreadFunc threadcode; + pThreadFuncEx threadcodeex; + void *arg, *owner; +}; + +///////////////////////////////////////////////////////////////////////////////////////// +// forkthread - starts a new thread + +void __cdecl forkthread_r(void * arg) +{ + struct FORK_ARG * fa = (struct FORK_ARG *) arg; + void (*callercode)(void*)=fa->threadcode; + void * cookie=fa->arg; + Thread_Push(( HINSTANCE)callercode); + SetEvent(fa->hEvent); + __try + { + callercode(cookie); + } + __except(pMirandaExceptFilter(GetExceptionCode(), GetExceptionInformation())) + { + } + + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + Thread_Pop(); + return; +} + +MIR_CORE_DLL(UINT_PTR) forkthread( void (__cdecl *threadcode)(void*), unsigned long stacksize, void *arg) +{ + UINT_PTR rc; + struct FORK_ARG fa; + fa.hEvent=CreateEvent(NULL, FALSE, FALSE, NULL); + fa.threadcode=threadcode; + fa.arg=arg; + rc=_beginthread(forkthread_r, stacksize, &fa); + if ((UINT_PTR)-1L != rc) + WaitForSingleObject(fa.hEvent, INFINITE); + + CloseHandle(fa.hEvent); + return rc; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// forkthreadex - starts a new thread with the extended info and returns the thread id + +unsigned __stdcall forkthreadex_r(void * arg) +{ + struct FORK_ARG *fa = (struct FORK_ARG *)arg; + pThreadFuncEx threadcode = fa->threadcodeex; + pThreadFuncOwner threadcodeex = (pThreadFuncOwner)fa->threadcodeex; + void *cookie = fa->arg; + void *owner = fa->owner; + unsigned long rc = 0; + + Thread_Push((HINSTANCE)threadcode, fa->owner); + SetEvent(fa->hEvent); + __try + { + if (owner) + rc = threadcodeex(owner, cookie); + else + rc = threadcode(cookie); + } + __except(pMirandaExceptFilter(GetExceptionCode(), GetExceptionInformation())) + { + } + + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + Thread_Pop(); + return rc; +} + +MIR_CORE_DLL(UINT_PTR) forkthreadex( + void *sec, + unsigned stacksize, + unsigned (__stdcall *threadcode)(void*), + void* owner, + void *arg, + unsigned *thraddr) +{ + UINT_PTR rc; + struct FORK_ARG fa = { 0 }; + fa.threadcodeex = threadcode; + fa.arg = arg; + fa.owner = owner; + fa.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + rc = _beginthreadex(sec, stacksize, forkthreadex_r, (void *)&fa, 0, thraddr); + if (rc) + WaitForSingleObject(fa.hEvent, INFINITE); + + CloseHandle(fa.hEvent); + return rc; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_CORE_DLL(void) KillObjectThreads(void* owner) +{ + if (owner == NULL) + return; + + WaitForSingleObject(hStackMutex, INFINITE); + + HANDLE* threadPool = (HANDLE*)alloca(threads.getCount()*sizeof(HANDLE)); + int threadCount = 0; + + for (int j = threads.getCount(); j--;) { + THREAD_WAIT_ENTRY* p = threads[j]; + if (p->pObject == owner) + threadPool[ threadCount++ ] = p->hThread; + } + ReleaseMutex(hStackMutex); + + // is there anything to kill? + if (threadCount > 0) { + if ( WaitForMultipleObjects(threadCount, threadPool, TRUE, 5000) == WAIT_TIMEOUT) { + // forcibly kill all remaining threads after 5 secs + WaitForSingleObject(hStackMutex, INFINITE); + for (int j = threads.getCount()-1; j >= 0; j--) { + THREAD_WAIT_ENTRY* p = threads[j]; + if (p->pObject == owner) { + TerminateThread(p->hThread, 9999); + CloseHandle(p->hThread); + threads.remove(j); + mir_free(p); + } + } + ReleaseMutex(hStackMutex); + } + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + +static void CALLBACK KillAllThreads(HWND, UINT, UINT_PTR, DWORD) +{ + if ( MirandaWaitForMutex(hStackMutex)) { + for (int j=0; j < threads.getCount(); j++) { + THREAD_WAIT_ENTRY* p = threads[j]; + char szModuleName[ MAX_PATH ]; + GetModuleFileNameA(p->hOwner, szModuleName, sizeof(szModuleName)); + TerminateThread(p->hThread, 9999); + CloseHandle(p->hThread); + mir_free(p); + } + + threads.destroy(); + + ReleaseMutex(hStackMutex); + SetEvent(hThreadQueueEmpty); + } +} + +MIR_CORE_DLL(void) Thread_Wait(void) +{ + // acquire the list and wake up any alertable threads + if ( MirandaWaitForMutex(hStackMutex)) { + for (int j=0; j < threads.getCount(); j++) + QueueUserAPC(DummyAPCFunc, threads[j]->hThread, 0); + ReleaseMutex(hStackMutex); + } + + // give all unclosed threads 5 seconds to close + SetTimer(NULL, 0, 5000, KillAllThreads); + + // wait til the thread list is empty + MirandaWaitForMutex(hThreadQueueEmpty); +} + +///////////////////////////////////////////////////////////////////////////////////////// + +typedef LONG (WINAPI *pNtQIT)(HANDLE, LONG, PVOID, ULONG, PULONG); +#define ThreadQuerySetWin32StartAddress 9 + +static void* GetCurrentThreadEntryPoint() +{ + LONG ntStatus; + HANDLE hDupHandle, hCurrentProcess; + DWORD_PTR dwStartAddress; + + pNtQIT NtQueryInformationThread = (pNtQIT)GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtQueryInformationThread" ); + if(NtQueryInformationThread == NULL) return 0; + + hCurrentProcess = GetCurrentProcess(); + if(!DuplicateHandle(hCurrentProcess, GetCurrentThread(), hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)){ + SetLastError(ERROR_ACCESS_DENIED); + return NULL; + } + ntStatus = NtQueryInformationThread(hDupHandle, ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD_PTR), NULL); + CloseHandle(hDupHandle); + + if(ntStatus != ERROR_SUCCESS) return 0; + return ( void* )dwStartAddress; +} + +MIR_CORE_DLL(INT_PTR) Thread_Push(HINSTANCE hInst, void* pOwner) +{ + ResetEvent(hThreadQueueEmpty); // thread list is not empty + if ( WaitForSingleObject(hStackMutex, INFINITE) == WAIT_OBJECT_0) { + THREAD_WAIT_ENTRY* p = (THREAD_WAIT_ENTRY*)mir_calloc(sizeof(THREAD_WAIT_ENTRY)); + + DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &p->hThread, 0, FALSE, DUPLICATE_SAME_ACCESS); + p->dwThreadId = GetCurrentThreadId(); + p->pObject = pOwner; + if (pluginListAddr.getIndex(hInst) != -1) + p->hOwner = hInst; + else + p->hOwner = GetInstByAddress(( hInst != NULL ) ? (PVOID)hInst : GetCurrentThreadEntryPoint()); + + threads.insert(p); + + ReleaseMutex(hStackMutex); + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +MIR_CORE_DLL(INT_PTR) Thread_Pop() +{ + if ( WaitForSingleObject(hStackMutex, INFINITE) == WAIT_OBJECT_0) { + DWORD dwThreadId = GetCurrentThreadId(); + for (int j=0; j < threads.getCount(); j++) { + THREAD_WAIT_ENTRY* p = threads[j]; + if (p->dwThreadId == dwThreadId) { + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); + CloseHandle(p->hThread); + threads.remove(j); + mir_free(p); + + if ( !threads.getCount()) { + threads.destroy(); + ReleaseMutex(hStackMutex); + SetEvent(hThreadQueueEmpty); // thread list is empty now + return 0; + } + + ReleaseMutex(hStackMutex); + return 0; + } + } + ReleaseMutex(hStackMutex); + } + return 1; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +const DWORD MS_VC_EXCEPTION=0x406D1388; + +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) + +MIR_CORE_DLL(void) Thread_SetName(const char *szThreadName) +{ + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = szThreadName; + info.dwThreadID = GetCurrentThreadId(); + info.dwFlags = 0; + + __try + { + RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } +} diff --git a/src/mir_core/utf.cpp b/src/mir_core/utf.cpp new file mode 100644 index 0000000000..ddf2d1ca9f --- /dev/null +++ b/src/mir_core/utf.cpp @@ -0,0 +1,406 @@ +/* + +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. + + Copyright 2000 Alexandre Julliard of Wine project + (UTF-8 conversion routines) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "commonheaders.h" + +/* number of following bytes in sequence based on first byte value (for bytes above 0x7f) */ +static const char utf8_length[128] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9f */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xaf */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0-0xbf */ + 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xc0-0xcf */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xd0-0xdf */ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xe0-0xef */ + 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0-0xff */ +}; + +/* first byte mask depending on UTF-8 sequence length */ +static const unsigned char utf8_mask[4] = { 0x7f, 0x1f, 0x0f, 0x07 }; + +/* minimum Unicode value depending on UTF-8 sequence length */ +static const unsigned int utf8_minval[4] = { 0x0, 0x80, 0x800, 0x10000 }; + +/* get the next char value taking surrogates into account */ +static unsigned int getSurrogateValue(const wchar_t *src, unsigned int srclen) +{ + if (src[0] >= 0xd800 && src[0] <= 0xdfff) { /* surrogate pair */ + if (src[0] > 0xdbff || /* invalid high surrogate */ + srclen <= 1 || /* missing low surrogate */ + src[1] < 0xdc00 || src[1] > 0xdfff) /* invalid low surrogate */ + return 0; + return 0x10000 + ((src[0] & 0x3ff) << 10) + (src[1] & 0x3ff); + } + return src[0]; +} + +/* query necessary dst length for src string */ +static int Ucs2toUtf8Len(const wchar_t *src, unsigned int srclen) +{ + int len; + unsigned int val; + + for (len = 0; srclen; srclen--, src++) { + if (*src < 0x80) { /* 0x00-0x7f: 1 byte */ + len++; + continue; + } + if (*src < 0x800) { /* 0x80-0x7ff: 2 bytes */ + len += 2; + continue; + } + if ( !(val = getSurrogateValue(src, srclen))) + return -2; + + if (val < 0x10000) /* 0x800-0xffff: 3 bytes */ + len += 3; + else { /* 0x10000-0x10ffff: 4 bytes */ + len += 4; + src++; + srclen--; + } + } + return len; +} + +MIR_CORE_DLL(int) Ucs2toUtf8Len(const wchar_t *src) +{ + if (src == 0) + return 0; + + return Ucs2toUtf8Len(src, (int)wcslen(src)); +} + +/* wide char to UTF-8 string conversion */ +/* return -1 on dst buffer overflow, -2 on invalid input char */ +int Ucs2toUtf8(const wchar_t *src, int srclen, char *dst, int dstlen) +{ + int len; + + for (len = dstlen; srclen; srclen--, src++) + { + WCHAR ch = *src; + unsigned int val; + + if (ch < 0x80) /* 0x00-0x7f: 1 byte */ + { + if ( !len--) return -1; /* overflow */ + *dst++ = ch; + continue; + } + + if (ch < 0x800) /* 0x80-0x7ff: 2 bytes */ + { + if ((len -= 2) < 0) return -1; /* overflow */ + dst[1] = 0x80 | (ch & 0x3f); + ch >>= 6; + dst[0] = 0xc0 | ch; + dst += 2; + continue; + } + + if ( !(val = getSurrogateValue(src, srclen))) + { + return -2; + } + + if (val < 0x10000) /* 0x800-0xffff: 3 bytes */ + { + if ((len -= 3) < 0) return -1; /* overflow */ + dst[2] = 0x80 | (val & 0x3f); + val >>= 6; + dst[1] = 0x80 | (val & 0x3f); + val >>= 6; + dst[0] = 0xe0 | val; + dst += 3; + } + else /* 0x10000-0x10ffff: 4 bytes */ + { + if ((len -= 4) < 0) return -1; /* overflow */ + dst[3] = 0x80 | (val & 0x3f); + val >>= 6; + dst[2] = 0x80 | (val & 0x3f); + val >>= 6; + dst[1] = 0x80 | (val & 0x3f); + val >>= 6; + dst[0] = 0xf0 | val; + dst += 4; + src++; + srclen--; + } + } + return dstlen - len; +} + +/* helper for the various utf8 mbstowcs functions */ +static unsigned int decodeUtf8Char(unsigned char ch, const char **str, const char *strend) +{ + unsigned int len = utf8_length[ch-0x80]; + unsigned int res = ch & utf8_mask[len]; + const char *end = *str + len; + + if (end > strend) return ~0; + switch(len) + { + case 3: + if ((ch = end[-3] ^ 0x80) >= 0x40) break; + res = (res << 6) | ch; + (*str)++; + case 2: + if ((ch = end[-2] ^ 0x80) >= 0x40) break; + res = (res << 6) | ch; + (*str)++; + case 1: + if ((ch = end[-1] ^ 0x80) >= 0x40) break; + res = (res << 6) | ch; + (*str)++; + if (res < utf8_minval[len]) break; + return res; + } + return ~0; +} + +/* query necessary dst length for src string */ +static inline int Utf8toUcs2Len(const char *src, int srclen) +{ + int ret = 0; + unsigned int res; + const char *srcend = src + srclen; + + while (src < srcend) + { + unsigned char ch = *src++; + if (ch < 0x80) /* special fast case for 7-bit ASCII */ + { + ret++; + continue; + } + if ((res = decodeUtf8Char(ch, &src, srcend)) <= 0x10ffff) + { + if (res > 0xffff) ret++; + ret++; + } + else return -2; /* bad char */ + /* otherwise ignore it */ + } + return ret; +} + +/* UTF-8 to wide char string conversion */ +/* return -1 on dst buffer overflow, -2 on invalid input char */ +int Utf8toUcs2(const char *src, int srclen, wchar_t *dst, int dstlen) +{ + unsigned int res; + const char *srcend = src + srclen; + wchar_t *dstend = dst + dstlen; + + while ((dst < dstend) && (src < srcend)) + { + unsigned char ch = *src++; + if (ch < 0x80) /* special fast case for 7-bit ASCII */ + { + *dst++ = ch; + continue; + } + if ((res = decodeUtf8Char(ch, &src, srcend)) <= 0xffff) + { + *dst++ = res; + } + else if (res <= 0x10ffff) /* we need surrogates */ + { + if (dst == dstend - 1) return -1; /* overflow */ + res -= 0x10000; + *dst++ = 0xd800 | (res >> 10); + *dst++ = 0xdc00 | (res & 0x3ff); + } + else return -2; /* bad char */ + /* otherwise ignore it */ + } + if (src < srcend) return -1; /* overflow */ + return dstlen - (dstend - dst); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Utf8Decode - converts UTF8-encoded string to the UCS2/MBCS format + +MIR_CORE_DLL(char*) Utf8DecodeCP(char* str, int codepage, wchar_t** ucs2) +{ + int len; + bool needs_free = false; + wchar_t* tempBuf = NULL; + if (ucs2) + *ucs2 = NULL; + + if (str == NULL) + return NULL; + + len = (int)strlen(str); + + if (len < 2) { + if (ucs2 != NULL) { + *ucs2 = tempBuf = (wchar_t*)mir_alloc((len + 1) * sizeof(wchar_t)); + MultiByteToWideChar(codepage, 0, str, len, tempBuf, len); + tempBuf[len] = 0; + } + return str; + } + + int destlen = Utf8toUcs2Len(str, len); + if (destlen < 0) + return NULL; + + if (ucs2 == NULL) { + __try + { + tempBuf = (wchar_t*)alloca((destlen + 1) * sizeof(wchar_t)); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + tempBuf = NULL; + needs_free = true; + } + } + + if (tempBuf == NULL) { + tempBuf = (wchar_t*)mir_alloc((destlen + 1) * sizeof(wchar_t)); + if (tempBuf == NULL) + return NULL; + } + + Utf8toUcs2(str, len, tempBuf, destlen); + tempBuf[destlen] = 0; + WideCharToMultiByte(codepage, 0, tempBuf, -1, str, len + 1, "?", NULL); + + if (ucs2) + *ucs2 = tempBuf; + else if (needs_free) + mir_free(tempBuf); + + return str; +} + +MIR_CORE_DLL(char*) Utf8Decode(char* str, wchar_t** ucs2) +{ + return Utf8DecodeCP(str, Langpack_GetDefaultCodePage(), ucs2); +} + +MIR_CORE_DLL(wchar_t*) Utf8DecodeW(const char* str) +{ + if (str == NULL) + return NULL; + + int len = (int)strlen(str); + + int destlen = Utf8toUcs2Len(str, len); + if (destlen < 0) return NULL; + + wchar_t* ucs2 = (wchar_t*)mir_alloc((destlen + 1) * sizeof(wchar_t)); + if (ucs2 == NULL) return NULL; + + if (Utf8toUcs2(str, len, ucs2, destlen) >= 0) + { + ucs2[destlen] = 0; + return ucs2; + } + + mir_free(ucs2); + + return NULL; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Utf8Encode - converts MBCS string to the UTF8-encoded format + +MIR_CORE_DLL(char*) Utf8EncodeCP(const char* src, int codepage) +{ + int len; + bool needs_free = false; + char* result = NULL; + wchar_t* tempBuf; + + if (src == NULL) + return NULL; + + len = (int)strlen(src); + + __try + { + tempBuf = (wchar_t*)alloca((len + 1) * sizeof(wchar_t)); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + tempBuf = (wchar_t*)mir_alloc((len + 1) * sizeof(wchar_t)); + if (tempBuf == NULL) return NULL; + needs_free = true; + } + + len = MultiByteToWideChar(codepage, 0, src, -1, tempBuf, len + 1); + + int destlen = Ucs2toUtf8Len(tempBuf, len); + if (destlen >= 0) + { + result = (char*)mir_alloc(destlen + 1); + if (result) + { + Ucs2toUtf8(tempBuf, len, result, destlen); + result[destlen] = 0; + } + } + + if (needs_free) + mir_free(tempBuf); + + return result; +} + +MIR_CORE_DLL(char*) Utf8Encode(const char* src) +{ + return Utf8EncodeCP(src, Langpack_GetDefaultCodePage()); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Utf8Encode - converts UCS2 string to the UTF8-encoded format + +MIR_CORE_DLL(char*) Utf8EncodeW(const wchar_t* src) +{ + if (src == NULL) + return NULL; + + int len = (int)wcslen(src); + + int destlen = Ucs2toUtf8Len(src, len); + if (destlen < 0) return NULL; + + char* result = (char*)mir_alloc(destlen + 1); + if (result == NULL) + return NULL; + + Ucs2toUtf8(src, len, result, destlen); + result[destlen] = 0; + + return result; +} diff --git a/src/mir_core/utils.cpp b/src/mir_core/utils.cpp new file mode 100644 index 0000000000..4ebba2f293 --- /dev/null +++ b/src/mir_core/utils.cpp @@ -0,0 +1,150 @@ +/* + +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. +*/ + +#include "commonheaders.h" + +MIR_CORE_DLL(char*) rtrim(char* str) +{ + if (str == NULL) + return NULL; + + char* p = strchr(str, 0); + while (--p >= str) { + switch (*p) { + case ' ': case '\t': case '\n': case '\r': + *p = 0; break; + default: + return str; + } + } + return str; +} + +MIR_CORE_DLL(WCHAR*) wrtrim(WCHAR *str) +{ + if (str == NULL) + return NULL; + + WCHAR* p = _tcschr(str, 0); + while (--p >= str) { + switch (*p) { + case ' ': case '\t': case '\n': case '\r': + *p = 0; break; + default: + return str; + } + } + return str; +} + +MIR_CORE_DLL(char*) ltrim(char* str) +{ + if (str == NULL) + return NULL; + + char* p = str; + for (;;) { + switch (*p) { + case ' ': case '\t': case '\n': case '\r': + ++p; break; + default: + memmove(str, p, strlen(p) + 1); + return str; + } + } +} + +MIR_CORE_DLL(char*) ltrimp(char* str) +{ + if (str == NULL) + return NULL; + + char* p = str; + for (;;) { + switch (*p) { + case ' ': case '\t': case '\n': case '\r': + ++p; break; + default: + return p; + } + } +} + +MIR_CORE_DLL(int) wildcmp(char * name, char * mask) +{ + char * last='\0'; + for (;; mask++, name++) { + if (*mask != '?' && *mask != *name) break; + if (*name == '\0') return ((BOOL)!*mask); + } + if (*mask != '*') return FALSE; + for (;; mask++, name++){ + while (*mask == '*') { + last = mask++; + if (*mask == '\0') return ((BOOL)!*mask); /* true */ + } + if (*name == '\0') return ((BOOL)!*mask); /* *mask == EOS */ + if (*mask != '?' && *mask != *name) name -= (size_t)(mask - last) - 1, mask = last; + } +} + +/////////////////////////////////////////////////////////////////////////////// + +static int sttComparePlugins(const HINSTANCE__* p1, const HINSTANCE__* p2) +{ + if (p1 == p2) + return 0; + + return (p1 < p2) ? -1 : 1; +} + +LIST pluginListAddr(10, sttComparePlugins); + +MIR_CORE_DLL(void) RegisterModule(HINSTANCE hInst) +{ + pluginListAddr.insert(hInst); +} + +MIR_CORE_DLL(void) UnregisterModule(HINSTANCE hInst) +{ + pluginListAddr.remove(hInst); +} + +MIR_CORE_DLL(HINSTANCE) GetInstByAddress(void* codePtr) +{ + if (pluginListAddr.getCount() == 0) + return NULL; + + int idx; + List_GetIndex((SortedList*)&pluginListAddr, codePtr, &idx); + if (idx > 0) + idx--; + + HINSTANCE result = pluginListAddr[idx]; + if (result < hInst && codePtr > hInst) + result = hInst; + else if (idx == 0 && codePtr < (void*)result) + result = NULL; + + return result; +} diff --git a/src/modules/icolib/extracticon.cpp b/src/modules/icolib/extracticon.cpp index 6a53f767cc..e5906045a1 100644 --- a/src/modules/icolib/extracticon.cpp +++ b/src/modules/icolib/extracticon.cpp @@ -57,7 +57,7 @@ void* _RelativeVirtualAddresstoPtr(IMAGE_DOS_HEADER* pDosHeader, DWORD rva) IMAGE_SECTION_HEADER* cSection = &pSection[i]; DWORD size = cSection->Misc.VirtualSize ? cSection->Misc.VirtualSize : cSection->SizeOfRawData; - if (rva >= cSection->VirtualAddress && rva < cSection->VirtualAddress + size) + if (rva >= cSection->VirtualAddress && rva < cSection->VirtualAddress + size) return (LPBYTE)pDosHeader + cSection->PointerToRawData + (rva - cSection->VirtualAddress); } diff --git a/src/modules/langpack/lpservices.cpp b/src/modules/langpack/lpservices.cpp index b7ae5ef563..36f9e3c40b 100644 --- a/src/modules/langpack/lpservices.cpp +++ b/src/modules/langpack/lpservices.cpp @@ -43,7 +43,9 @@ static INT_PTR srvTranslateMenu(WPARAM wParam, LPARAM lParam) static INT_PTR srvRegisterLP(WPARAM wParam, LPARAM lParam) { - *(int*)wParam = Langpack_MarkPluginLoaded((PLUGININFOEX*)lParam); + PLUGININFOEX* ppi = (PLUGININFOEX*)lParam; + if (wParam && ppi) + *( int* )wParam = GetPluginFakeId(ppi->uuid, Langpack_MarkPluginLoaded(ppi)); return 0; } diff --git a/src/modules/options/options.cpp b/src/modules/options/options.cpp index 4a4f79688b..1a9d855822 100644 --- a/src/modules/options/options.cpp +++ b/src/modules/options/options.cpp @@ -40,8 +40,6 @@ static int FilterPage = 0; static int FilterLoadProgress = 100; static int FilterTimerId = 0; -char* GetPluginNameByInstance(HINSTANCE hInstance); - struct OptionsPageInit { int pageCount; diff --git a/src/modules/plugins/newplugins.cpp b/src/modules/plugins/newplugins.cpp index a07f371e42..7bbcc57411 100644 --- a/src/modules/plugins/newplugins.cpp +++ b/src/modules/plugins/newplugins.cpp @@ -68,7 +68,7 @@ static BOOL bModuleInitialized = FALSE; TCHAR mirandabootini[MAX_PATH]; static DWORD mirandaVersion; -static int serviceModeIdx = -1; +static int serviceModeIdx = -1, sttFakeID = -100; static HANDLE hPluginListHeap = NULL; static int askAboutIgnoredPlugins; @@ -81,18 +81,8 @@ void UninitIni(void); int LoadDatabaseModule(void); -char* GetPluginNameByInstance(HINSTANCE hInstance) -{ - if (pluginList.getCount() == 0) - return NULL; - - for (int i=0; i < pluginList.getCount(); i++) { - pluginEntry* pe = pluginList[i]; - if (pe->bpi.pluginInfo && pe->bpi.hInst == hInstance) - return pe->bpi.pluginInfo->shortName; - } - return NULL; -} +///////////////////////////////////////////////////////////////////////////////////////// +// basic functions int equalUUID(const MUUID& u1, const MUUID& u2) { @@ -119,6 +109,37 @@ int getDefaultPluginIdx(const MUUID& muuid) return -1; } +///////////////////////////////////////////////////////////////////////////////////////// +// global functions + +char* GetPluginNameByInstance(HINSTANCE hInstance) +{ + if (pluginList.getCount() == 0) + return NULL; + + for (int i=0; i < pluginList.getCount(); i++) { + pluginEntry* p = pluginList[i]; + if (p->bpi.pluginInfo && p->bpi.hInst == hInstance) + return p->bpi.pluginInfo->shortName; + } + return NULL; +} + +int GetPluginFakeId(const MUUID &uuid, int hLangpack) +{ + for (int i=0; i < pluginList.getCount(); i++) { + pluginEntry* p = pluginList[i]; + if ( !p->bpi.hInst) + continue; + + if ( equalUUID(p->bpi.pluginInfo->uuid, uuid)) + return p->hLangpack = (hLangpack) ? hLangpack : --sttFakeID; + } + + return 0; +} + + MUUID miid_last = MIID_LAST; MUUID miid_chat = MIID_CHAT; MUUID miid_srmm = MIID_SRMM; @@ -264,11 +285,8 @@ LBL_Ok: } // perform any API related tasks to freeing -void Plugin_Uninit(pluginEntry* p, bool bDynamic) +void Plugin_Uninit(pluginEntry* p) { - if (bDynamic && p->bpi.hInst) - CallPluginEventHook(p->bpi.hInst, hOkToExitEvent, 0, 0); - // if it was an installed database plugin, call its unload if (p->pclass & PCLASS_DB) p->bpi.dblink->Unload(p->pclass & PCLASS_OK); @@ -283,24 +301,6 @@ void Plugin_Uninit(pluginEntry* p, bool bDynamic) KillModuleEventHooks(p->bpi.hInst); KillModuleServices(p->bpi.hInst); - if (bDynamic) { - int hLangpack = Langpack_GetPluginHandle(p->bpi.pluginInfo); - if (hLangpack != 0) { - KillModuleMenus(hLangpack); - KillModuleFonts(hLangpack); - KillModuleColours(hLangpack); - KillModuleEffects(hLangpack); - KillModuleIcons(hLangpack); - KillModuleHotkeys(hLangpack); - KillModuleSounds(hLangpack); - } - - // release default plugin - for (int i=0; i < SIZEOF(pluginDefault); i++) - if (pluginDefault[i].pImpl == p) - pluginDefault[i].pImpl = NULL; - } - FreeLibrary(p->bpi.hInst); ZeroMemory(&p->bpi, sizeof(p->bpi)); } @@ -310,15 +310,33 @@ void Plugin_Uninit(pluginEntry* p, bool bDynamic) int Plugin_UnloadDyn(pluginEntry* p) { - if (CallPluginEventHook(p->bpi.hInst, hOkToExitEvent, 0, 0) != 0) - return FALSE; + if (p->bpi.hInst) { + if (CallPluginEventHook(p->bpi.hInst, hOkToExitEvent, 0, 0) != 0) + return FALSE; - NotifyEventHooks(hevUnloadModule, (WPARAM)p->bpi.InfoEx, (LPARAM)p->bpi.hInst); + NotifyEventHooks(hevUnloadModule, (WPARAM)p->bpi.InfoEx, (LPARAM)p->bpi.hInst); - CallPluginEventHook(p->bpi.hInst, hPreShutdownEvent, 0, 0); - CallPluginEventHook(p->bpi.hInst, hShutdownEvent, 0, 0); + CallPluginEventHook(p->bpi.hInst, hPreShutdownEvent, 0, 0); + CallPluginEventHook(p->bpi.hInst, hShutdownEvent, 0, 0); + } + + int hLangpack = p->hLangpack; + if (hLangpack != 0) { + KillModuleMenus(hLangpack); + KillModuleFonts(hLangpack); + KillModuleColours(hLangpack); + KillModuleEffects(hLangpack); + KillModuleIcons(hLangpack); + KillModuleHotkeys(hLangpack); + KillModuleSounds(hLangpack); + } + + // release default plugin + for (int i=0; i < SIZEOF(pluginDefault); i++) + if (pluginDefault[i].pImpl == p) + pluginDefault[i].pImpl = NULL; - Plugin_Uninit(p, true); + Plugin_Uninit(p); return TRUE; } @@ -578,7 +596,7 @@ bool LoadCorePlugin(MuuidReplacement& mr) pluginEntry* pPlug = OpenPlugin(tszPlugName, _T("Core"), exe); if (pPlug->pclass & PCLASS_FAILED) { LBL_Error: - Plugin_Uninit(pPlug, true); + Plugin_UnloadDyn(pPlug); return FALSE; } diff --git a/src/modules/plugins/pluginopts.cpp b/src/modules/plugins/pluginopts.cpp index b8384ae593..15f9219192 100644 --- a/src/modules/plugins/pluginopts.cpp +++ b/src/modules/plugins/pluginopts.cpp @@ -167,7 +167,7 @@ static int LoadPluginDynamically(PluginListItemData* dat) pluginEntry* pPlug = OpenPlugin(dat->fileName, _T("Plugins"), exe); if (pPlug->pclass & PCLASS_FAILED) { LBL_Error: - Plugin_Uninit(pPlug, true); + Plugin_UnloadDyn(pPlug); return FALSE; } diff --git a/src/modules/plugins/plugins.h b/src/modules/plugins/plugins.h index 85922fcae8..4dcf76f439 100644 --- a/src/modules/plugins/plugins.h +++ b/src/modules/plugins/plugins.h @@ -48,6 +48,7 @@ struct pluginEntry { TCHAR pluginname[64]; unsigned int pclass; // PCLASS_* + int hLangpack; BASIC_PLUGIN_INFO bpi; pluginEntry* nextclass; }; @@ -70,7 +71,7 @@ int checkAPI(TCHAR* plugin, BASIC_PLUGIN_INFO* bpi, DWORD mirandaVersion, int ch pluginEntry* OpenPlugin(TCHAR *tszFileName, TCHAR *dir, TCHAR *path); bool TryLoadPlugin(pluginEntry *p, TCHAR *dir, bool bDynamic); -void Plugin_Uninit(pluginEntry* p, bool bDynamic = false); +void Plugin_Uninit(pluginEntry* p); int Plugin_UnloadDyn(pluginEntry* p); typedef BOOL (*SCAN_PLUGINS_CALLBACK) (WIN32_FIND_DATA * fd, TCHAR *path, WPARAM wParam, LPARAM lParam); -- cgit v1.2.3