summaryrefslogtreecommitdiff
path: root/plugins/folders
diff options
context:
space:
mode:
authorVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
committerVadim Dashevskiy <watcherhd@gmail.com>2012-05-15 10:38:20 +0000
commit48540940b6c28bb4378abfeb500ec45a625b37b6 (patch)
tree2ef294c0763e802f91d868bdef4229b6868527de /plugins/folders
parent5c350913f011e119127baeb32a6aedeb4f0d33bc (diff)
initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/folders')
-rw-r--r--plugins/folders/Folders.html11
-rw-r--r--plugins/folders/docs/folders_readme.txt226
-rw-r--r--plugins/folders/docs/m_folders.h292
-rw-r--r--plugins/folders/files_release.txt1
-rw-r--r--plugins/folders/files_releasex64.txt1
-rw-r--r--plugins/folders/files_source.txt5
-rw-r--r--plugins/folders/folders.sln26
-rw-r--r--plugins/folders/folders/commonheaders.h82
-rw-r--r--plugins/folders/folders/dlg_handlers.cpp413
-rw-r--r--plugins/folders/folders/dlg_handlers.h28
-rw-r--r--plugins/folders/folders/events.cpp41
-rw-r--r--plugins/folders/folders/events.h36
-rw-r--r--plugins/folders/folders/folderItem.cpp250
-rw-r--r--plugins/folders/folders/folderItem.h78
-rw-r--r--plugins/folders/folders/folders.cpp246
-rw-r--r--plugins/folders/folders/folders.rc129
-rw-r--r--plugins/folders/folders/folders.vcproj464
-rw-r--r--plugins/folders/folders/foldersList.cpp232
-rw-r--r--plugins/folders/folders/foldersList.h69
-rw-r--r--plugins/folders/folders/hooked_events.cpp86
-rw-r--r--plugins/folders/folders/hooked_events.h36
-rw-r--r--plugins/folders/folders/m_folders.h292
-rw-r--r--plugins/folders/folders/resource.h27
-rw-r--r--plugins/folders/folders/sdk/m_updater.h146
-rw-r--r--plugins/folders/folders/sdk/m_variables.h745
-rw-r--r--plugins/folders/folders/services.cpp242
-rw-r--r--plugins/folders/folders/services.h50
-rw-r--r--plugins/folders/folders/utils.cpp357
-rw-r--r--plugins/folders/folders/utils.h62
-rw-r--r--plugins/folders/folders/variablesHelp.inc32
-rw-r--r--plugins/folders/folders/version.h49
-rw-r--r--plugins/folders/folders/version.rc100
-rw-r--r--plugins/folders/pack source.bat8
-rw-r--r--plugins/folders/pack symbols.bat9
-rw-r--r--plugins/folders/pack x64.bat13
-rw-r--r--plugins/folders/pack.bat13
-rw-r--r--plugins/folders/rtf convert.bat1
-rw-r--r--plugins/folders/rtf converter.exebin0 -> 6656 bytes
-rw-r--r--plugins/folders/rtf converter/rtf converter.cpp103
-rw-r--r--plugins/folders/symbols_exclude.txt1
-rw-r--r--plugins/folders/variables help.docbin0 -> 2449 bytes
41 files changed, 5002 insertions, 0 deletions
diff --git a/plugins/folders/Folders.html b/plugins/folders/Folders.html
new file mode 100644
index 0000000000..5eb72d9d5e
--- /dev/null
+++ b/plugins/folders/Folders.html
@@ -0,0 +1,11 @@
+<html>
+ <head></head>
+ <body>
+ <center>
+ <h1>Custom profile folders Test Page</h1>
+
+ <p>Custom profile folders version 0.1.6.0</p>
+ <p><a href="Folders.zip">Folders.zip</a></p>
+ </center>
+ </body>
+</html>
diff --git a/plugins/folders/docs/folders_readme.txt b/plugins/folders/docs/folders_readme.txt
new file mode 100644
index 0000000000..fb81a7431b
--- /dev/null
+++ b/plugins/folders/docs/folders_readme.txt
@@ -0,0 +1,226 @@
+Custom profile folders v.0.1.6.0
+Copyright © 2005-2010 Cristian Libotean
+
+This plugin allows users to select the folders where plugins save their data.
+It's a service plugin, it adds no functionality on it's own.
+See the included m_folders.h for help on how to make use of these services in your own plugins.
+Don't forget to click apply to allow the plugin to create the folder structure.
+When you click apply it will try to delete the old path (all the empty folders) and
+then create the new structure.
+!!! Make sure you don't have any of those folders open in explorer or any other program.
+The plugin also allows environment variables to be used. Environment variables
+are expanded before any miranda variables are expanded so if you have, for example, %profile_path%
+defined as a system variable it will use that value instead expanding to miranda's profile path.
+
+Changes:
+
++ : new feature
+* : changed
+! : bufgix
+- : feature removed or disabled because of pending bugs
+
+version 0.1.6.0 - 2012/03/22
+ ! Fixed m_folders.h declarations in unicode mode - Thanks Freak_TheMighty
+
+version 0.1.5.8 - 2011/08/23
+ * Patch from Kirill Volinsky - updated m_folders.h header file
+
+version 0.1.5.7 - 2011/08/23
+ + made x64 version updater aware
+
+version 0.1.5.6 - 2011/08/22
+ * Patch from Kirill Volinsky - use mir_free() instead of calling the services manually
+
+version 0.1.5.5 - 2011/05/16
+ * Patch from Kirill Volinsky - added mir_a2u mir_u2a support
+
+version 0.1.5.4 - 2011/04/14
+ * Patch from Kirill Volinsky - Fixed Folders debug service (it's for testing purposes)
+
+Version 0.1.5.3 - 2010/11/01
+ * Applied patch from IG_Vasilich - unicode dialogs
+
+Version 0.1.5.2 - 2010/11/01
+ ! Attempt to fix crash with Utils_ReplaceVarsW function.
+
+Version 0.1.5.1 - 2010/08/02
+ ! Fixed path retrieval - the path will no longer contain any trailing \ (as the help file suggests)
+ ! In previous versions Folders plugin did not remove spaces and \ although the help file said it did, but now they are removed.
+
+Version 0.1.5.0 - 2010/05/19
+ + Added support for Variables plugin.
+ + Added support for Miranda core variables.
+ * Environment variables are no longer expanded by Folders plugin, instead it relies on the core to expand these variables.
+ + The fields defined in Variables plugin are the first to get parsed, then the core variables and only after all these have been expanded will
+ Folders plugin expand the fields it defines itself (if they still need to be expanded) (Variables plugin -> Core -> Folders -> result).
+
+Version 0.1.4.5 - 2009/11/13
+ + x64 support - thanks to Nightwish for patch
+
+Version 0.1.4.4 - 2008/05/14
+ ! Only try to delete folders if they're not reparse points
+
+Version 0.1.4.3 - 2008/01/24
+ * Changed beta versions server.
+
+Version 0.1.4.2 - 2007/06/26
+ ! Fixes for the help text.
+
+Version 0.1.4.1 - 2007/06/24
+ ! Translation support for help text.
+ * Enabled unicode flag since plugin is 2in1.
+
+Version 0.1.4.0 - 2007/04/23
+ *Translation support for help text.
+ +Expand environment variables. Environment variables are expanded before any miranda variables.
+ So if you have, for example, %profile_path% defined as a system variable it will expand to that value
+ instead of expanding to miranda's profile path.
+
+Version 0.1.3.0 - 2007/04/11
+ +Section names and item names are now translateable. Plugins should NOT translate the strings themselves, they should let Folders plugin do it.
+
+Version 0.1.2.1 - 2007/03/27
+ *Fix for database plugins returning non standard profile path (dbxSA).
+
+Version 0.1.2.0 - 2007/03/06
+ +Added UUID ( {2f129563-2c7d-4a9a-b948-97dfcc0afdd7} )
+ +Added FOLDERS interface.
+
+Version 0.1.1.1 - 2007/01/31
+ *Changed beta URL.
+
+Version 0.1.1.0 - 2007/01/28
+ !In case of empty format string use miranda's main path instead.
+
+Version 0.1.0.7 - 2007/01/11
+ !Show sections and items as unicode.
+
+Version 0.1.0.6 - 2007/01/07
+ +New version resource file.
+ *Options cleanup. :)
+ +New extended helper function.
+ *Don't show old folder if it isn't empty.
+
+Version 0.1.0.5 - 2006/11/26
+ +Added dll version info.
+ *Changed controls tab order.
+
+Version 0.1.0.4 - 2006/11/07
+ *Select first child item when a section is selected.
+
+Version 0.1.0.3 - 2006/10/23
+ !Unicows needed on Windows 98.
+ *Don't show explorer windows when folders are changed.
+
+Version 0.1.0.2 - 2006/09/10
+ !Rebased the dll (0x2F000000)
+ +Updater support (beta versions)
+
+Version 0.1.0.1 - 2006/08/15
+ *Modified m_folders.h so it compiles with C.
+ +Modified helper functions so they use PATH_TOABSOLUTE when folders plugin is not installed. This should make the helper functions always return an absolute path.
+
+Version 0.1.0.0 - 2006/5/17
+ !Fixed helper functions (now they return 0 on error instead of 1). Also, the register functions how return a HANDLE, like they should.
+ !Destroy services the proper way.
+
+Version 0.0.0.8 - 2006/3/27
+ !Made MS_FOLDERS_GET_SIZE service unicode aware.
+ *Changed the way the helper functions behave - they should now work even when encountering old versions of folders plugin.
+ +Added new TCHAR helper functions.
+ +Preview window updates on every key press.
+
+Version 0.0.0.7 - 2006/3/24
+ !Fixed stupid include file in m_folders.h
+ *Preview window is always unicode aware ... might cause problems on 98 systems.
+ +Added helper functions.
+ +Added unicode support - alpha stages.
+ +Added TCHAR variables to structures.
+ +Fixed a bug with register path service - i wasn't following my own doc
+
+Version 0.0.0.6 - 2006/2/14:
+ +Changed the api (again). Unicode paths are now possible. The unicode part doesn't work yet and maybe
+ it never will - there are no *unicode* services to get the current profile path.
+ *Removed support for API from version 0.0.0.3. Only 0.0.0.6 API works now ...
+ +Added an event ME_FOLDERS_PATH_CHANGED.
+ +If the old directory isn't empty when changing a path then 2 explorer
+ windows will be opened, one for the old path and one for the new one,
+ so the user can copy the data.
+
+Version 0.0.0.5 - 2006/1/19:
+ +Rebased the dll (0x2F010000)
+ +Added the changes made by pescuma
+
+Version 0.0.0.4 - 2005/12/19:
+ *Api changes (sorry). Every entry now belongs
+ to a section. The old api (from version 0.0.0.3)
+ still works and folders registered with the old
+ api will be put in section "Unknown".
+ +Plugin will try to delete old path structure when
+ a new one is entered.
+ +Plugin will try to create the new path structure if
+ it doesn't exist.
+ *Minor cosmetic fixes
+
+Version 0.0.0.3 - 2005/12/17:
+ *Path string is trimmed now.
+ *Now it removes the last \ from the input
+ edit (if there was one)
+ *Added more information about variables.
+
+Version 0.0.0.2 - 2005/12/17:
+ *Changed the api, no loger requires defines for common folders.
+ +Plugins can now register their folders using the new api.
+ +Added options page to allow users to modify the folders.
+
+ This plugin still needs testing; i've done some testing
+ myself but i'm not sure it won't bork the results on some
+ weird cases. Please report any bugs you find on miranda's forum.
+
+version 0.0.0.1 - 2005/12/16:
+ First release ...
+
+
+
+
+Translation strings (updated for version 0.1.4.2)
+
+"Don't forget to click on \\i Apply\\i0 to save the changes. If you don't then the changes won't\\par be saved to the database, they will only be valid for this session.\n"
+"\\ul\\b Variable string\\ulnone\\b0\t\t\\ul\\b What it expands to:\\ulnone\\b0\n"
+"%miranda_path%\t Expands to your miranda path (e.g: c:\\\\program files\\\\miranda im).\n"
+"%profile_path%\t\t Expands to your profile path - the value found in mirandaboot.ini,\n"
+"\t\t\t\\ul ProfileDir\\ulnone section (usually inside miranda's folder).\n"
+"%current_profile%\t Expands to your current profile name without the extenstion.\n"
+"\t\t\t (e.g.\\b default\\b0 if your your profile is \\i default.dat\\i0 ).\n"
+"\n"
+"\n"
+"\\ul\\b Environment variables\n"
+"\\ulnone\\b0 The plugin can also expand environment variables; the variables are specified like in any other\\par program that can use environment variables, i.e. %<env variable>%.\n"
+"\\b Note\\b0 : Environment variables are expanded before any Miranda variables. So if you have, for\\par example, %profile_path% defined as a system variable then it will be expanded to that value\\par instead of expanding to Miranda's profile path.\n"
+"\n"
+"\\ul\\b Examples:\n"
+"\\ulnone\\b0 If the value for the ProfileDir inside \\i mirandaboot.ini\\i0 , \\ul ProfileDir\\ulnone section is '.\\\\profiles', current\\par profile is 'default.dat' and miranda's path is 'c:\\\\program files\\\\miranda im' then:\n"
+"\\b %miranda_path%\\b0 \t\t\t will expand to 'c:\\\\program files\\\\miranda im'\n"
+"\\b %profile_path%\\b0 \t\t\t will expand to 'c:\\\\program files\\\\miranda im\\\\profiles'\n"
+"\\b %current_profile%\\b0\t\t\t will expand to 'default'\n"
+"\\b %temp%\\b0\t\t\t\t will expand to the temp folder of the current user.\n"
+"\\b %profile_path%\\\\%current_profile%\\b0 will expand to 'c:\\\\program files\\\\miranda im\\\\profiles\\\\default'\n"
+"\\b %miranda_path%\\\\plugins\\\\config\\b0\t will expand to 'c:\\\\program files\\\\miranda im\\\\plugins\\\\config'\n"
+"\\b ' %miranda_path%\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ '\\b0\t will expand to 'c:\\\\program files\\\\miranda im'\n"
+"notice that the spaces at the beginning and the end of the string are trimmed, as well as the last \\\\\n"
+
+
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
diff --git a/plugins/folders/docs/m_folders.h b/plugins/folders/docs/m_folders.h
new file mode 100644
index 0000000000..02d4d3564e
--- /dev/null
+++ b/plugins/folders/docs/m_folders.h
@@ -0,0 +1,292 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_CUSTOM_FOLDERS_H
+#define M_CUSTOM_FOLDERS_H
+
+#define FOLDERS_API 501 //dunno why it's here but it is :)
+
+#define PROFILE_PATH "%profile_path%"
+#define CURRENT_PROFILE "%current_profile%"
+#define MIRANDA_PATH "%miranda_path%"
+#define PLUGINS_PATH "%miranda_path%" "\\plugins"
+#define MIRANDA_USERDATA "%miranda_userdata%"
+
+#define PROFILE_PATHW L"%profile_path%"
+#define CURRENT_PROFILEW L"%current_profile%"
+#define MIRANDA_PATHW L"%miranda_path%"
+#define MIRANDA_USERDATAW L"%miranda_userdata%"
+
+#ifdef _UNICODE
+ #define PROFILE_PATHT PROFILE_PATHW
+ #define CURRENT_PROFILET CURRENT_PROFILEW
+ #define MIRANDA_PATHT MIRANDA_PATHW
+ #define MIRANDA_USERDATAT MIRANDA_USERDATAW
+#else
+ #define PROFILE_PATHT PROFILE_PATH
+ #define CURRENT_PROFILET CURRENT_PROFILE
+ #define MIRANDA_PATHT MIRANDA_PATH
+ #define MIRANDA_USERDATAT MIRANDA_USERDATA
+#endif
+
+#define FOLDER_AVATARS PROFILE_PATHT _T("\\") CURRENT_PROFILET _T("\\avatars")
+#define FOLDER_VCARDS PROFILE_PATHT _T("\\") CURRENT_PROFILET _T("\\vcards")
+#define FOLDER_LOGS PROFILE_PATHT _T("\\") CURRENT_PROFILET _T("\\logs")
+#define FOLDER_RECEIVED_FILES PROFILE_PATHT _T("\\") CURRENT_PROFILET _T("\\received files")
+#define FOLDER_DOCS MIRANDA_PATHT _T("\\") _T("docs")
+#define FOLDER_CONFIG PLUGINS_PATHT _T("\\") _T("config")
+#define FOLDER_SCRIPTS MIRANDA_PATHT _T("\\") _T("scripts")
+#define FOLDER_UPDATES MIRANDA_PATHT _T("\\") _T("updates")
+
+#define FOLDER_CUSTOMIZE MIRANDA_PATHT _T("\\") _T("customize")
+#define FOLDER_CUSTOMIZE_SOUNDS FOLDER_CUSTOMIZE _T("\\sounds")
+#define FOLDER_CUSTOMIZE_ICONS FOLDER_CUSTOMIZE _T("\\icons")
+#define FOLDER_CUSTOMIZE_SMILEYS FOLDER_CUSTOMIZE _T("\\smileys")
+#define FOLDER_CUSTOMIZE_SKINS FOLDER_CUSTOMIZE _T("\\skins")
+#define FOLDER_CUSTOMIZE_THEMES FOLDER_CUSTOMIZE _T("\\themes")
+
+#define TO_WIDE(x) L ## x
+
+#define FOLDERS_NAME_MAX_SIZE 64 //maximum name and section size
+
+#define FF_UNICODE 0x00000001
+
+#if defined (UNICODE)
+ #define FF_TCHAR FF_UNICODE
+#else
+ #define FF_TCHAR 0
+#endif
+
+typedef struct{
+ int cbSize; //size of struct
+ char szSection[FOLDERS_NAME_MAX_SIZE]; //section name, if it doesn't exist it will be created otherwise it will just add this entry to it
+ char szName[FOLDERS_NAME_MAX_SIZE]; //entry name - will be shown in options
+ union{
+ const char *szFormat; //default string format. Fallback string in case there's no entry in the database for this folder. This should be the initial value for the path, users will be able to change it later.
+ const wchar_t *szFormatW; //String is dup()'d so you can free it later. If you set the unicode string don't forget to set the flag accordingly.
+ const TCHAR *szFormatT;
+ };
+ DWORD flags; //FF_* flags
+} FOLDERSDATA;
+
+/*Folders/Register/Path service
+ wParam - not used, must be 0
+ lParam - (LPARAM) (const FOLDERDATA *) - Data structure filled with
+ the necessary information.
+ Returns a handle to the registered path or 0 on error.
+ You need to use this to call the other services.
+*/
+#define MS_FOLDERS_REGISTER_PATH "Folders/Register/Path"
+
+/*Folders/Get/PathSize service
+ wParam - (WPARAM) (int) - handle to registered path
+ lParam - (LPARAM) (int *) - pointer to the variable that receives the size of the path
+ string (not including the null character). Depending on the flags set when creating the path
+ it will either call strlen() or wcslen() to get the length of the string.
+ Returns the size of the buffer.
+*/
+#define MS_FOLDERS_GET_SIZE "Folders/Get/PathSize"
+
+typedef struct{
+ int cbSize;
+ int nMaxPathSize; //maximum size of buffer. This represents the number of characters that can be copied to it (so for unicode strings you don't send the number of bytes but the length of the string).
+ union{
+ char *szPath; //pointer to the buffer that receives the path without the last "\\"
+ wchar_t *szPathW; //unicode version of the buffer.
+ TCHAR *szPathT;
+ };
+} FOLDERSGETDATA;
+
+/*Folders/Get/Path service
+ wParam - (WPARAM) (int) - handle to registered path
+ lParam - (LPARAM) (FOLDERSGETDATA *) pointer to a FOLDERSGETDATA that has all the relevant fields filled.
+ Should return 0 on success, or nonzero otherwise.
+*/
+#define MS_FOLDERS_GET_PATH "Folders/Get/Path"
+
+typedef struct{
+ int cbSize;
+ union{
+ char **szPath; //address of a string variable (char *) or (wchar_t*) where the path should be stored (the last \ won't be copied).
+ wchar_t **szPathW; //unicode version of string.
+ TCHAR **szPathT;
+ };
+} FOLDERSGETALLOCDATA;
+
+/*Folders/GetRelativePath/Alloc service
+ wParam - (WPARAM) (int) - Handle to registered path
+ lParam - (LPARAM) (FOLDERSALLOCDATA *) data
+ This service is the same as MS_FOLDERS_GET_PATH with the difference that this service
+ allocates the needed space for the buffer. It uses miranda's memory functions for that and you need
+ to use those to free the resulting buffer.
+ Should return 0 on success, or nonzero otherwise. Currently it only returns 0.
+*/
+#define MS_FOLDERS_GET_PATH_ALLOC "Folders/Get/Path/Alloc"
+
+
+/*Folders/On/Path/Changed
+ wParam - (WPARAM) 0
+ lParam - (LPARAM) 0
+ Triggered when the folders change, you should reget the paths you registered.
+*/
+#define ME_FOLDERS_PATH_CHANGED "Folders/On/Path/Changed"
+
+#ifndef FOLDERS_NO_HELPER_FUNCTIONS
+
+#ifndef M_UTILS_H__
+#error The helper functions require that m_utils.h be included in the project. Please include that file if you want to use the helper functions. If you don''t want to use the functions just define FOLDERS_NO_HELPER_FUNCTIONS.
+#endif
+//#include "../../../include/newpluginapi.h"
+
+__inline static HANDLE FoldersRegisterCustomPath(const char *section, const char *name, const char *defaultPath)
+{
+ FOLDERSDATA fd = {0};
+ if (!ServiceExists(MS_FOLDERS_REGISTER_PATH)) return 0;
+ fd.cbSize = sizeof(FOLDERSDATA);
+ strncpy(fd.szSection, section, FOLDERS_NAME_MAX_SIZE);
+ fd.szSection[FOLDERS_NAME_MAX_SIZE - 1] = '\0';
+ strncpy(fd.szName, name, FOLDERS_NAME_MAX_SIZE);
+ fd.szName[FOLDERS_NAME_MAX_SIZE - 1] = '\0';
+ fd.szFormat = defaultPath;
+ return (HANDLE) CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &fd);
+}
+
+__inline static HANDLE FoldersRegisterCustomPathW(const char *section, const char *name, const wchar_t *defaultPathW)
+{
+ FOLDERSDATA fd = {0};
+ if (!ServiceExists(MS_FOLDERS_REGISTER_PATH)) return 0;
+ fd.cbSize = sizeof(FOLDERSDATA);
+ strncpy(fd.szSection, section, FOLDERS_NAME_MAX_SIZE);
+ fd.szSection[FOLDERS_NAME_MAX_SIZE - 1] = '\0'; //make sure it's NULL terminated
+ strncpy(fd.szName, name, FOLDERS_NAME_MAX_SIZE);
+ fd.szName[FOLDERS_NAME_MAX_SIZE - 1] = '\0'; //make sure it's NULL terminated
+ fd.szFormatW = defaultPathW;
+ fd.flags = FF_UNICODE;
+ return (HANDLE) CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &fd);
+}
+
+__inline static INT_PTR FoldersGetCustomPath(HANDLE hFolderEntry, char *path, const int size, const char *notFound)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = size;
+ fgd.szPath = path;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ char buffer[MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM) notFound, (LPARAM) buffer);
+ mir_snprintf(path, size, "%s", buffer);
+ }
+
+ return res;
+}
+
+__inline static INT_PTR FoldersGetCustomPathW(HANDLE hFolderEntry, wchar_t *pathW, const int count, const wchar_t *notFoundW)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = count;
+ fgd.szPathW = pathW;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ wcsncpy(pathW, notFoundW, count);
+ pathW[count - 1] = '\0';
+ }
+
+ return res;
+}
+
+__inline static INT_PTR FoldersGetCustomPathEx(HANDLE hFolderEntry, char *path, const int size, char *notFound, char *fileName)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = size;
+ fgd.szPath = path;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ char buffer[MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM) notFound, (LPARAM) buffer);
+ mir_snprintf(path, size, "%s", buffer);
+ }
+ if (strlen(path) > 0)
+ {
+ strcat(path, "\\");
+ }
+ else{
+ path[0] = '\0';
+ }
+
+ if (fileName)
+ {
+ strcat(path, fileName);
+ }
+
+ return res;
+}
+
+__inline static INT_PTR FoldersGetCustomPathExW(HANDLE hFolderEntry, wchar_t *pathW, const int count, wchar_t *notFoundW, wchar_t *fileNameW)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = count;
+ fgd.szPathW = pathW;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ wcsncpy(pathW, notFoundW, count);
+ pathW[count - 1] = '\0';
+ }
+
+ if (wcslen(pathW) > 0)
+ {
+ wcscat(pathW, L"\\");
+ }
+ else{
+ pathW[0] = L'\0';
+ }
+
+ if (fileNameW)
+ {
+ wcscat(pathW, fileNameW);
+ }
+
+ return res;
+}
+
+# ifdef _UNICODE
+# define FoldersGetCustomPathT FoldersGetCustomPathW
+# define FoldersGetCustomPathExT FoldersGetCustomPathExW
+# define FoldersRegisterCustomPathT FoldersRegisterCustomPathW
+#else
+# define FoldersGetCustomPathT FoldersGetCustomPath
+# define FoldersGetCustomPathExT FoldersGetCustomPath
+# define FoldersRegisterCustomPathT FoldersRegisterCustomPath
+#endif
+
+#endif
+
+#endif //M_CUSTOM_FOLDERS_H \ No newline at end of file
diff --git a/plugins/folders/files_release.txt b/plugins/folders/files_release.txt
new file mode 100644
index 0000000000..abc660e6b1
--- /dev/null
+++ b/plugins/folders/files_release.txt
@@ -0,0 +1 @@
+folders\win32\Release\folders.dll \ No newline at end of file
diff --git a/plugins/folders/files_releasex64.txt b/plugins/folders/files_releasex64.txt
new file mode 100644
index 0000000000..579757b872
--- /dev/null
+++ b/plugins/folders/files_releasex64.txt
@@ -0,0 +1 @@
+folders\x64\Release\folders.dll \ No newline at end of file
diff --git a/plugins/folders/files_source.txt b/plugins/folders/files_source.txt
new file mode 100644
index 0000000000..35cc4863ef
--- /dev/null
+++ b/plugins/folders/files_source.txt
@@ -0,0 +1,5 @@
+"rtf converter\*.*"
+folders\*.*
+folders\sdk\*.*
+docs\*.*
+*.*
diff --git a/plugins/folders/folders.sln b/plugins/folders/folders.sln
new file mode 100644
index 0000000000..1d1e0952d9
--- /dev/null
+++ b/plugins/folders/folders.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "folders", "folders\folders.vcproj", "{019FAEBD-BD7B-4470-A15B-A7DB1787E6BD}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {019FAEBD-BD7B-4470-A15B-A7DB1787E6BD}.Debug|Win32.ActiveCfg = Debug|Win32
+ {019FAEBD-BD7B-4470-A15B-A7DB1787E6BD}.Debug|Win32.Build.0 = Debug|Win32
+ {019FAEBD-BD7B-4470-A15B-A7DB1787E6BD}.Debug|x64.ActiveCfg = Debug|x64
+ {019FAEBD-BD7B-4470-A15B-A7DB1787E6BD}.Debug|x64.Build.0 = Debug|x64
+ {019FAEBD-BD7B-4470-A15B-A7DB1787E6BD}.Release|Win32.ActiveCfg = Release|Win32
+ {019FAEBD-BD7B-4470-A15B-A7DB1787E6BD}.Release|Win32.Build.0 = Release|Win32
+ {019FAEBD-BD7B-4470-A15B-A7DB1787E6BD}.Release|x64.ActiveCfg = Release|x64
+ {019FAEBD-BD7B-4470-A15B-A7DB1787E6BD}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/folders/folders/commonheaders.h b/plugins/folders/folders/commonheaders.h
new file mode 100644
index 0000000000..af2f0e3b9c
--- /dev/null
+++ b/plugins/folders/folders/commonheaders.h
@@ -0,0 +1,82 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_FOLDERS_COMMONHEADERS_H
+#define M_FOLDERS_COMMONHEADERS_H
+
+#define MIRANDA_CUSTOM_LP
+
+#define MAX_FOLDER_SIZE 2048
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windows.h>
+
+#include "newpluginapi.h"
+#include "m_utils.h"
+#include "m_folders.h"
+
+#include "version.h"
+#include "utils.h"
+#include "resource.h"
+#include "foldersList.h"
+#include "dlg_handlers.h"
+
+#include "m_database.h"
+#include "m_system.h"
+#include "m_skin.h"
+#include "m_options.h"
+#include "m_clist.h"
+#include "m_langpack.h"
+#include "m_history.h"
+#include "m_contacts.h"
+#include "m_popup.h"
+#include "m_fontservice.h"
+#include "sdk/m_updater.h"
+#include "sdk/m_variables.h"
+
+#ifndef MS_DB_GETPROFILEPATH_BASIC //db3xSA
+#define MS_DB_GETPROFILEPATH_BASIC "DB/GetProfilePathBasic"
+#endif
+
+extern char ModuleName[];
+extern HINSTANCE hInstance;
+extern CFoldersList &lstRegisteredFolders;
+
+#define OLD_MIRANDAPLUGININFO_SUPPORT PLUGININFO oldPluginInfo = { \
+ sizeof(PLUGININFO), \
+ pluginInfo.shortName, \
+ pluginInfo.version, \
+ pluginInfo.description, \
+ pluginInfo.author, \
+ pluginInfo.authorEmail, \
+ pluginInfo.copyright, \
+ pluginInfo.homepage, \
+ pluginInfo.flags, \
+ pluginInfo.replacesDefaultModule \
+}; \
+\
+extern "C" __declspec(dllexport) PLUGININFO *MirandaPluginInfo(DWORD mirandaVersion) \
+{ \
+ return &oldPluginInfo; \
+}
+
+#endif //FOLDERS_COMMONHEADERS_H \ No newline at end of file
diff --git a/plugins/folders/folders/dlg_handlers.cpp b/plugins/folders/folders/dlg_handlers.cpp
new file mode 100644
index 0000000000..74d3715835
--- /dev/null
+++ b/plugins/folders/folders/dlg_handlers.cpp
@@ -0,0 +1,413 @@
+#include "dlg_handlers.h"
+
+PFolderItem lastItem = NULL;
+
+static int bInitializing = 0;
+
+int GetCurrentItemSelection(HWND hWnd)
+{
+ return SendDlgItemMessageW(hWnd, IDC_FOLDERS_ITEMS_LIST, LB_GETCURSEL, 0, 0);
+}
+
+int GetCurrentSectionSelection(HWND hWnd)
+{
+ return SendDlgItemMessageW(hWnd, IDC_FOLDERS_SECTIONS_LIST, LB_GETCURSEL, 0, 0);
+}
+
+PFolderItem GetSelectedItem(HWND hWnd)
+{
+ WCHAR section[MAX_FOLDER_SIZE];
+ WCHAR item[MAX_FOLDER_SIZE];
+ GetCurrentItemText(hWnd, item, MAX_FOLDER_SIZE);
+ GetCurrentSectionText(hWnd, section, MAX_FOLDER_SIZE);
+ return lstRegisteredFolders.GetTranslated(section, item);
+}
+
+int GetCurrentItemText(HWND hWnd, WCHAR *buffer, int count)
+{
+ int index = GetCurrentItemSelection(hWnd);
+ if (index != LB_ERR)
+ {
+ SendDlgItemMessageW(hWnd, IDC_FOLDERS_ITEMS_LIST, LB_GETTEXT, index, (LPARAM) buffer);
+ return 1;
+ }
+ else{
+ buffer[0] = L'\0';
+ return 0;
+ }
+}
+
+int GetCurrentSectionText(HWND hWnd, WCHAR *buffer, int count)
+{
+ int index = GetCurrentSectionSelection(hWnd);
+ if (index != LB_ERR)
+ {
+ SendDlgItemMessageW(hWnd, IDC_FOLDERS_SECTIONS_LIST, LB_GETTEXT, index, (LPARAM) buffer);
+ return 1;
+ }
+ else{
+ buffer[0] = L'0';
+ return 0;
+ }
+}
+
+//void GetEditText(HWND hWnd, char *buffer, int size)
+//{
+// GetWindowText(GetDlgItem(hWnd, IDC_FOLDER_EDIT), buffer, size);
+// StrTrim(buffer, "\\\t \n");
+//}
+
+void GetEditTextW(HWND hWnd, wchar_t *buffer, int size)
+{
+ GetWindowTextW(GetDlgItem(hWnd, IDC_FOLDER_EDIT), buffer, size);
+}
+
+//void SetEditText(HWND hWnd, const char *buffer)
+//{
+// bInitializing = 1;
+// SetWindowText(GetDlgItem(hWnd, IDC_FOLDER_EDIT), buffer);
+// bInitializing = 0;
+//// SendDlgItemMessage(hWnd, IDC_FOLDER_EDIT, WM_SETTEXT, 0, (LPARAM) buffer);
+//}
+
+void SetEditTextW(HWND hWnd, const wchar_t *buffer)
+{
+ bInitializing = 1;
+ SetWindowTextW(GetDlgItem(hWnd, IDC_FOLDER_EDIT), buffer);
+ bInitializing = 0;
+}
+
+int ContainsSection(HWND hWnd, const WCHAR *section)
+{
+ int index = SendDlgItemMessageW(hWnd, IDC_FOLDERS_SECTIONS_LIST, LB_FINDSTRINGEXACT, -1, (LPARAM) section);
+ return (index != LB_ERR);
+}
+
+void LoadRegisteredFolderSections(HWND hWnd)
+{
+ for (int i = 0; i < lstRegisteredFolders.Count(); i++)
+ {
+ PFolderItem tmp = lstRegisteredFolders.Get(i + 1);
+ WCHAR *translated = mir_a2u(Translate(tmp->GetSection()));
+ if (!ContainsSection(hWnd, translated))
+ {
+ SendDlgItemMessageW(hWnd, IDC_FOLDERS_SECTIONS_LIST, LB_ADDSTRING, 0, (LPARAM) translated);
+ }
+ mir_free(translated);
+ }
+}
+
+void LoadRegisteredFolderItems(HWND hWnd)
+{
+ WCHAR buffer[MAX_FOLDER_SIZE];
+ GetCurrentSectionText(hWnd, buffer, MAX_FOLDER_SIZE);
+ SendDlgItemMessageW(hWnd, IDC_FOLDERS_ITEMS_LIST, LB_RESETCONTENT, 0, 0);
+ for (int i = 0; i < lstRegisteredFolders.Count(); i++)
+ {
+ PFolderItem item = lstRegisteredFolders.Get(i + 1);
+ WCHAR *wide = mir_a2u(Translate(item->GetSection()));
+ if (wcscmp(buffer, wide) == 0)
+ {
+ mir_free(wide);
+ wide = mir_a2u(Translate(item->GetName()));
+ SendDlgItemMessageW(hWnd, IDC_FOLDERS_ITEMS_LIST, LB_ADDSTRING, 0, (LPARAM) wide);
+ }
+ mir_free(wide);
+ }
+ SendDlgItemMessageW(hWnd, IDC_FOLDERS_ITEMS_LIST, LB_SETCURSEL, 0, 0); //select the first item
+ PostMessage(hWnd, WM_COMMAND, MAKEWPARAM(IDC_FOLDERS_ITEMS_LIST, LBN_SELCHANGE), 0); //tell the dialog to refresh the preview
+}
+
+void LoadItem(HWND hWnd, PFolderItem item)
+{
+ if (item)
+ {
+ if (item->IsUnicode())
+ {
+ SetEditTextW(hWnd, item->GetFormatW());
+ }
+ else{
+ WCHAR *buffer = mir_a2u(item->GetFormat());
+ SetEditTextW(hWnd, buffer);
+ mir_free(buffer);
+ }
+ RefreshPreview(hWnd);
+ }
+}
+
+void SaveItem(HWND hWnd, PFolderItem item, int bEnableApply)
+{
+ if (item)
+ {
+ if (item->IsUnicode())
+ {
+ wchar_t buffer[MAX_FOLDER_SIZE];
+ GetEditTextW(hWnd, buffer, MAX_FOLDER_SIZE);
+ item->SetFormatW(buffer);
+ }
+ else{
+ WCHAR buffer[MAX_FOLDER_SIZE];
+ char ansi[MAX_FOLDER_SIZE];
+ GetEditTextW(hWnd, buffer, MAX_FOLDER_SIZE);
+ WideCharToMultiByte(CallService(MS_LANGPACK_GETCODEPAGE, 0, 0), 0, buffer, -1, ansi, MAX_FOLDER_SIZE, NULL, NULL);
+ item->SetFormat(ansi);
+ }
+ if (bEnableApply)
+ {
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0);
+ }
+ }
+}
+
+int ChangesNotSaved(HWND hWnd, PFolderItem item)
+{
+ int res = 0;
+ if (item)
+ {
+ if (item->IsUnicode())
+ {
+ wchar_t buffer[MAX_FOLDER_SIZE];
+ GetEditTextW(hWnd, buffer, MAX_FOLDER_SIZE);
+ res = (wcscmp(item->GetFormatW(), buffer) != 0);
+ }
+ else{
+ WCHAR buffer[MAX_FOLDER_SIZE];
+ GetEditTextW(hWnd, buffer, MAX_FOLDER_SIZE);
+ char *ansi = mir_u2a(buffer);
+
+ res = (strcmp(item->GetFormat(), ansi) != 0);
+ mir_free(ansi);
+ }
+ }
+
+ return res;
+}
+
+void CheckForChanges(HWND hWnd, int bNeedConfirmation = 1)
+{
+ if (ChangesNotSaved(hWnd, lastItem))
+ {
+ if ((!bNeedConfirmation) || MessageBoxW(hWnd, TranslateW(L"Some changes weren't saved. Apply the changes now ?"), TranslateW(L"Changes not saved"), MB_YESNO | MB_ICONINFORMATION) == IDYES)
+ {
+ SaveItem(hWnd, lastItem);
+ }
+ }
+}
+
+void RefreshPreview(HWND hWnd)
+{
+ wchar_t tmp[MAX_FOLDER_SIZE];
+ wchar_t res[MAX_FOLDER_SIZE];
+ GetEditTextW(hWnd, tmp, MAX_FOLDER_SIZE);
+ ExpandPathW(res, tmp, MAX_FOLDER_SIZE);
+ SetWindowTextW(GetDlgItem(hWnd, IDC_PREVIEW_EDIT), res);
+ //SendDlgItemMessage(hWnd, IDC_PREVIEW_EDIT, WM_SETTEXT, 0, (LPARAM) res);
+}
+
+
+void LoadHelp(HWND hWnd)
+{
+ SETTEXTEX tmp = {0};
+ tmp.flags = ST_SELECTION;
+ tmp.codepage = CallService(MS_LANGPACK_GETCODEPAGE, 0, 0);
+ char *text =
+#include "variablesHelp.inc"
+;
+
+ char buffer[2048];
+ char line[2048];
+ int len;
+
+ char *p;
+ while ((p = strchr(text, '\n')))
+ {
+ len = p - text + 1;
+ memcpy(line, text, len);
+ line[len] = 0;
+
+ mir_snprintf(buffer, sizeof(buffer), "{\\rtf1\\ansi\\deff0\\pard\\li%u\\fi-%u\\ri%u\\tx%u\\fs19 %s\\par}", 60*15, 60*15, 5*15, 60*15, Translate(line));
+ text = p + 1;
+
+ SendDlgItemMessageW(hWnd, IDC_HELP_RICHEDIT, EM_SETTEXTEX, (WPARAM) &tmp, (LPARAM) buffer);
+ }
+
+
+}
+
+/************************************** DIALOG HANDLERS *************************************/
+#include "commctrl.h"
+
+INT_PTR CALLBACK DlgProcOpts(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ bInitializing = 1;
+ lastItem = NULL;
+ TranslateDialogDefault(hWnd);
+ LoadRegisteredFolderSections(hWnd);
+ bInitializing = 0;
+
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_FOLDER_EDIT:
+ {
+ switch (HIWORD(wParam))
+ {
+ case EN_CHANGE:
+ {
+ RefreshPreview(hWnd);
+ if (!bInitializing)
+ {
+ SendMessage(GetParent(hWnd), PSM_CHANGED, 0, 0); //show the apply button.
+ }
+
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case IDC_REFRESH_BUTTON:
+ {
+ RefreshPreview(hWnd);
+
+ break;
+ }
+
+ case IDC_HELP_BUTTON:
+ {
+ HWND helpDlg = CreateDialogW(hInstance, MAKEINTRESOURCEW(IDD_VARIABLES_HELP), hWnd, DlgProcVariables);
+ ShowWindow(helpDlg, SW_SHOW);
+
+ break;
+ }
+
+ case IDC_FOLDERS_SECTIONS_LIST:
+ {
+ switch (HIWORD(wParam))
+ {
+ case LBN_SELCHANGE:
+ {
+ CheckForChanges(hWnd);
+ LoadRegisteredFolderItems(hWnd);
+ lastItem = NULL;
+ SetEditTextW(hWnd, L"");
+ RefreshPreview(hWnd);
+
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case IDC_FOLDERS_ITEMS_LIST:
+ {
+ switch (HIWORD(wParam))
+ {
+ case LBN_SELCHANGE:
+ {
+ PFolderItem item = GetSelectedItem(hWnd);
+ if (item != NULL)
+ {
+ CheckForChanges(hWnd);
+ LoadItem(hWnd, item);
+ }
+ lastItem = item;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+// Log("WM_NOTIFY %d %d", wParam, lParam);
+ switch(((LPNMHDR)lParam)->idFrom)
+ {
+ case 0:
+ switch (((LPNMHDR)lParam)->code)
+ {
+ case PSN_APPLY:
+ {
+ PFolderItem item = GetSelectedItem(hWnd);
+ if (item)
+ {
+ SaveItem(hWnd, item, FALSE);
+ LoadItem(hWnd, item);
+ }
+
+ lstRegisteredFolders.Save();
+ CallPathChangedEvents();
+
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ break;
+
+ default:
+ {
+
+ break;
+ }
+ }
+
+ return 0;
+}
+
+INT_PTR CALLBACK DlgProcVariables(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hWnd);
+ LoadHelp(hWnd);
+
+ break;
+ }
+
+ case WM_CLOSE:
+ {
+ DestroyWindow(hWnd);
+
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDCLOSE:
+ {
+ DestroyWindow(hWnd);
+
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/plugins/folders/folders/dlg_handlers.h b/plugins/folders/folders/dlg_handlers.h
new file mode 100644
index 0000000000..4f3a4f15ca
--- /dev/null
+++ b/plugins/folders/folders/dlg_handlers.h
@@ -0,0 +1,28 @@
+#ifndef M_FOLDERS_DLG_HANDLERS_H
+#define M_FOLDERS_DLG_HANDLERS_H
+
+//#include "commonheaders.h"
+#include "services.h"
+#include "events.h"
+#include <richedit.h>
+
+INT_PTR CALLBACK DlgProcOpts(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK DlgProcVariables(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+int GetCurrentItemSelection(HWND hWnd);
+int GetCurrentSectionSelection(HWND hWnd);
+PFolderItem GetSelectedItem(HWND hWnd);
+int GetCurrentSectionText(HWND hWnd, WCHAR *buffer, int count);
+int GetCurrentItemText(HWND hWnd, WCHAR *buffer, int count);
+//void GetEditText(HWND hWnd, char *buffer, int size);
+void GetEditTextW(HWND hWnd, wchar_t *buffer, int size);
+//void SetEditText(HWND hWnd, const char *buffer);
+void SetEditTextW(HWND hWnd, const wchar_t *buffer);
+void LoadRegisteredFolderSections(HWND hWnd);
+void LoadRegisteredFolderItems(HWND hWnd);
+void LoadItem(HWND hWnd, PFolderItem item);
+void SaveItem(HWND hWnd, PFolderItem item, int bEnableApply = TRUE);
+int ChangesNotSaved(HWND hWnd);
+void RefreshPreview(HWND hWnd);
+
+#endif //M_FOLDERS_DLG_HANDLERS_H \ No newline at end of file
diff --git a/plugins/folders/folders/events.cpp b/plugins/folders/folders/events.cpp
new file mode 100644
index 0000000000..359ac81bf4
--- /dev/null
+++ b/plugins/folders/folders/events.cpp
@@ -0,0 +1,41 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "events.h"
+
+HANDLE hPathChanged;
+
+int InitEvents()
+{
+ hPathChanged = CreateHookableEvent(ME_FOLDERS_PATH_CHANGED);
+ return 0;
+}
+
+int DestroyEvents()
+{
+ DestroyHookableEvent(hPathChanged);
+ hPathChanged = 0;
+ return 0;
+}
+
+int CallPathChangedEvents()
+{
+ return NotifyEventHooks(hPathChanged, 0, 0);
+} \ No newline at end of file
diff --git a/plugins/folders/folders/events.h b/plugins/folders/folders/events.h
new file mode 100644
index 0000000000..8f73ee7cfe
--- /dev/null
+++ b/plugins/folders/folders/events.h
@@ -0,0 +1,36 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_FOLDERS_EVENTS_H
+#define M_FOLDERS_EVENTS_H
+
+#include "commonheaders.h"
+#include "m_folders.h"
+
+extern HANDLE hPathChanged;
+
+int InitEvents();
+int DestroyEvents();
+
+int CallPathChangedEvents();
+
+
+
+#endif //M_FOLDERS_EVENTS_H \ No newline at end of file
diff --git a/plugins/folders/folders/folderItem.cpp b/plugins/folders/folders/folderItem.cpp
new file mode 100644
index 0000000000..cf58e5feac
--- /dev/null
+++ b/plugins/folders/folders/folderItem.cpp
@@ -0,0 +1,250 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "folderItem.h"
+#include "commonheaders.h"
+#include "services.h"
+
+CFolderItem::CFolderItem(const char *sectionName, const char *name, const char *format, const DWORD flags)
+{
+ strncpy(szSection, sectionName, sizeof(szSection));
+ szFormat = NULL;
+ szOldFormat = NULL;
+ szFormatW = NULL;
+ szOldFormatW = NULL;
+ strncpy(szName, name, sizeof(szName));
+ this->flags = flags;
+ GetDataFromDatabase(format);
+ FolderCreateDirectory();
+}
+
+void MyFree(void *data)
+{
+ if (data)
+ {
+ free(data);
+ }
+}
+
+CFolderItem::~CFolderItem()
+{
+// WriteDataToDatabase();
+ if (IsUnicode())
+ {
+ MyFree(szFormatW);
+ MyFree(szOldFormatW);
+ }
+ else{
+ MyFree(szFormat);
+ MyFree(szOldFormat);
+ }
+}
+
+const char *CFolderItem::GetSection() const
+{
+ return szSection;
+}
+
+const char *CFolderItem::GetName() const
+{
+ return szName;
+}
+
+const char *CFolderItem::GetFormat() const
+{
+ return szFormat;
+}
+
+const wchar_t *CFolderItem::GetFormatW() const
+{
+ return szFormatW;
+}
+
+void CFolderItem::SetFormat(const char *newFormat)
+{
+ MyFree(szOldFormat);
+ szOldFormat = szFormat;
+ szFormat = _strdup((strlen(newFormat) > 0) ? newFormat : MIRANDA_PATH);
+}
+
+void CFolderItem::SetFormatW(const wchar_t *newFormat)
+{
+ MyFree(szOldFormatW);
+ szOldFormatW = szFormatW;
+ szFormatW = _wcsdup((wcslen(newFormat) > 0) ? newFormat : MIRANDA_PATHW);
+}
+
+int CFolderItem::IsUnicode() const
+{
+ return (flags & FF_UNICODE);
+}
+
+int CFolderItem::IsEqual(const CFolderItem *other)
+{
+ return (IsEqual(other->GetSection(), other->GetName()));
+}
+
+int CFolderItem::IsEqual(const char *section, const char *name)
+{
+ return ((strcmp(szName, name) == 0) && (strcmp(szSection, section) == 0));
+}
+
+int CFolderItem::IsEqualTranslated(const char *trSection, const char *trName)
+{
+ return ((strcmp(Translate(szName), trName) == 0) && (strcmp(Translate(szSection), trSection) == 0));
+}
+
+int CFolderItem::operator ==(const CFolderItem *other)
+{
+ return IsEqual(other);
+}
+
+void CFolderItem::Expand(char *buffer, int size)
+{
+ if (IsUnicode())
+ {
+ ExpandPathW((wchar_t *) buffer, szFormatW, size);
+ }
+ else{
+ ExpandPath(buffer, szFormat, size);
+ }
+}
+
+void CFolderItem::Save()
+{
+ int res = FolderDeleteOldDirectory(FALSE);
+ //FolderCreateDirectory(!res);
+ FolderCreateDirectory(FALSE);
+ WriteDataToDatabase();
+}
+
+int CFolderItem::FolderCreateDirectory(int showFolder)
+{
+ int res = FOLDER_SUCCESS;
+ if (IsUnicode())
+ {
+ wchar_t buffer[MAX_FOLDER_SIZE];
+ if (szFormatW)
+ {
+ ExpandPathW(buffer, szFormatW, MAX_FOLDER_SIZE);
+ CreateDirectories(buffer);
+ if (showFolder)
+ {
+ ShellExecuteW(NULL, L"explore", buffer, NULL, NULL, SW_SHOW);
+ }
+ res = (DirectoryExists(buffer)) ? FOLDER_SUCCESS : FOLDER_FAILURE;
+ }
+ }
+ else{
+ char buffer[MAX_FOLDER_SIZE];
+ if (szFormat)
+ {
+ ExpandPath(buffer, szFormat, MAX_FOLDER_SIZE);
+ CreateDirectories(buffer);
+ if (showFolder)
+ {
+ ShellExecuteA(NULL, "explore", buffer, NULL, NULL, SW_SHOW);
+ }
+ res = (DirectoryExists(buffer)) ? FOLDER_SUCCESS : FOLDER_FAILURE;
+ }
+ }
+ return res;
+}
+
+int CFolderItem::FolderDeleteOldDirectory(int showFolder)
+{
+ int res = FOLDER_SUCCESS;
+ if (IsUnicode())
+ {
+ wchar_t buffer[MAX_FOLDER_SIZE];
+ if (szOldFormatW)
+ {
+ if (wcscmp(szFormatW, szOldFormatW) == 0) //format wasn't changed
+ {
+ return res;
+ }
+ ExpandPathW(buffer, szOldFormatW, MAX_FOLDER_SIZE);
+ RemoveDirectories(buffer);
+ res = (DirectoryExists(buffer)) ? FOLDER_FAILURE : FOLDER_SUCCESS;
+ if ((res == FOLDER_FAILURE) && (showFolder))
+ {
+ ShellExecuteW(NULL, L"explore", buffer, NULL, NULL, SW_SHOW);
+ }
+ }
+ }
+ else{
+ char buffer[MAX_FOLDER_SIZE];
+ if (szOldFormat)
+ {
+ if (strcmp(szFormat, szOldFormat) == 0) //format wasn't changed
+ {
+ return res;
+ }
+ ExpandPath(buffer, szOldFormat, MAX_FOLDER_SIZE);
+ RemoveDirectories(buffer);
+ res = (DirectoryExists(buffer)) ? FOLDER_FAILURE : FOLDER_SUCCESS;
+ if ((res == FOLDER_FAILURE) && (showFolder))
+ {
+ ShellExecuteA(NULL, "explore", buffer, NULL, NULL, SW_SHOW);
+ }
+ }
+ }
+ return res;
+}
+
+void CFolderItem::GetDataFromDatabase(const char *szNotFound)
+{
+ char name[256];
+ strcpy(name, szSection);
+ strcat(name, szName);
+
+ if (IsUnicode())
+ {
+ wchar_t buffer[MAX_FOLDER_SIZE];
+ GetStringFromDatabase(name, (const wchar_t *) szNotFound, buffer, MAX_FOLDER_SIZE);
+ SetFormatW(buffer);
+ }
+ else{
+ char buffer[MAX_FOLDER_SIZE];
+ GetStringFromDatabase(name, szNotFound, buffer, MAX_FOLDER_SIZE);
+ SetFormat(buffer);
+ }
+}
+
+void CFolderItem::WriteDataToDatabase()
+{
+ char name[256];
+ strcpy(name, szSection);
+ strcat(name, szName);
+
+ if (IsUnicode())
+ {
+ if (szFormatW)
+ {
+ WriteStringToDatabase(name, szFormatW);
+ }
+ }
+ else{
+ if (szFormat)
+ {
+ WriteStringToDatabase(name, szFormat);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/folders/folders/folderItem.h b/plugins/folders/folders/folderItem.h
new file mode 100644
index 0000000000..b60891c2ff
--- /dev/null
+++ b/plugins/folders/folders/folderItem.h
@@ -0,0 +1,78 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_FOLDERS_FOLDER_ITEM_H
+#define M_FOLDERS_FOLDER_ITEM_H
+
+#include <string.h>
+#include <malloc.h>
+#include <windows.h>
+
+#define FOLDERS_NO_HELPER_FUNCTIONS
+#include "m_folders.h"
+#undef FOLDERS_NO_HELPER_FUNCTIONS
+
+
+#define FOLDER_SUCCESS 1
+#define FOLDER_FAILURE 0
+
+class CFolderItem{
+ protected:
+ char szSection[FOLDERS_NAME_MAX_SIZE];
+ char szName[FOLDERS_NAME_MAX_SIZE]; //don't forget to modify in m_folders.h
+ union{
+ char *szFormat;
+ wchar_t *szFormatW;
+ };
+ union{
+ char *szOldFormat;
+ wchar_t *szOldFormatW;
+ };
+ DWORD flags;
+
+ void GetDataFromDatabase(const char *szNotFound);
+ void WriteDataToDatabase();
+
+ int FolderCreateDirectory(int showFolder = 0);
+ int FolderDeleteOldDirectory(int showFolder = 0);
+
+ public:
+ CFolderItem(const char *sectionName, const char *name, const char *format, const DWORD flags);
+ virtual ~CFolderItem();
+ void Expand(char *buffer, int size);
+ void Save();
+
+ int IsUnicode() const;
+ int IsEqual(const CFolderItem *other);
+ int IsEqual(const char *section, const char *name);
+ int IsEqualTranslated(const char *trSection, const char *trName);
+ int operator ==(const CFolderItem *other);
+
+ const char *GetSection() const;
+ const char *GetName() const;
+ const char *GetFormat() const;
+ const wchar_t *GetFormatW() const;
+ void SetFormat(const char *newFormat);
+ void SetFormatW(const wchar_t *newFormat);
+};
+
+typedef CFolderItem *PFolderItem;
+
+#endif //M_FOLDERS_FOLDER_ITEM_H \ No newline at end of file
diff --git a/plugins/folders/folders/folders.cpp b/plugins/folders/folders/folders.cpp
new file mode 100644
index 0000000000..4628f2ffbc
--- /dev/null
+++ b/plugins/folders/folders/folders.cpp
@@ -0,0 +1,246 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "commonheaders.h"
+#include "hooked_events.h"
+#include "services.h"
+#include "events.h"
+
+#include "m_folders.h"
+
+#define MS_FOLDERS_TEST_PLUGIN "Folders/Test/Plugin"
+
+char ModuleName[] = "Folders";
+HINSTANCE hInstance;
+int hLangpack;
+struct MM_INTERFACE mmi;
+
+CFoldersList &lstRegisteredFolders = CFoldersList(10); //the list
+
+PLUGINLINK *pluginLink;
+
+PLUGININFOEX pluginInfo = {
+ sizeof(PLUGININFOEX),
+ __PLUGIN_DISPLAY_NAME,
+ VERSION,
+ __DESC,
+ __AUTHOR,
+ __AUTHOREMAIL,
+ __COPYRIGHT,
+ __AUTHORWEB,
+ 1,
+ 0,
+ {0x2f129563, 0x2c7d, 0x4a9a, {0xb9, 0x48, 0x97, 0xdf, 0xcc, 0x0a, 0xfd, 0xd7}} //{2f129563-2c7d-4a9a-b948-97dfcc0afdd7}
+}; //not used
+
+OLD_MIRANDAPLUGININFO_SUPPORT;
+
+#ifdef _DEBUG
+
+typedef struct{
+ int cbSize; //size of struct
+ int nUniqueID; //unique id for this path. This ID should be unique for your plugin.
+ char szName[FOLDERS_NAME_MAX_SIZE]; //name to show in options
+} FOLDERSDATA_OLD;
+
+INT_PTR TestPlugin(WPARAM wParam, LPARAM lParam)
+{
+ char temp[MAX_PATH];
+ const int MAX = 20;
+ int i;
+ HANDLE handles[MAX][2];
+/* FOLDERSDATA caca;
+ caca.cbSize = sizeof(caca);
+ caca.szFormat = FOLDER_LOGS;*/
+ char *section;
+ for (i = 0; i < MAX; i++)
+ {
+ switch (i % 4)
+ {
+ case 0:
+ section = "Section 1";
+ break;
+ case 1:
+ section = "Section 2";
+ break;
+ case 2:
+ section = "Yet another section";
+ break;
+ case 3:
+ section = "Section no 4";
+ break;
+ default:
+ section = "Uhh ohh";
+ break;
+ }
+ //strcpy(caca.szSection, section);
+ _itoa(i, temp, 10);
+ //strcpy(caca.szName, temp);
+
+ handles[i][0] = FoldersRegisterCustomPathT(section, temp, FOLDER_LOGS); //CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &caca);
+ }
+ //caca.szFormatW = L"%profile_path%\\%current_profile%\\Ø";
+ //caca.flags = FF_UNICODE;
+ FoldersRegisterCustomPath("Unicode stuff", "non unicode", " %profile_path%\\%current_profile%\\Ø\\\\\\");
+ for (i = 0; i < MAX; i++)
+ {
+ //strcpy(caca.szSection, "Unicode stuff");
+ sprintf(temp, "Value %d", i);
+ //strcpy(caca.szName, temp);
+ handles[i][1] = FoldersRegisterCustomPathW("Unicode stuff", temp, L"%profile_path%\\%current_profile%\\\u1FA6"); //CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &caca);
+ }
+/*
+ FOLDERSAPPENDDATA data;
+ data.hRegisteredPath = handles[0];
+ data.szAppendData = "just an appended string";
+ char *cacat;
+ CallService(MS_FOLDERS_GET_PATH_ALLOC_APPEND, (WPARAM) &data, (LPARAM) &cacat);
+ Log("Append function returned : %s", cacat); */
+ /*FOLDERSGETDATA data = {0};
+ data.cbSize = sizeof(data);
+ data.nMaxPathSize = sizeof(temp);
+ data.szPath = temp; */
+ for (i = 0; i < MAX; i++)
+ {
+ //CallService(MS_FOLDERS_GET_PATH, handles[i][0], (LPARAM) &data);
+ FoldersGetCustomPath((HANDLE) handles[i][0], temp, sizeof(temp), "<not found>");
+ Log("Path function[%d] returned : %s", i, temp);
+ }
+ wchar_t buffer[MAX_PATH];
+ //data.szPathW = buffer;
+ for (i = 0; i < MAX; i++)
+ {
+ //CallService(MS_FOLDERS_GET_PATH, handles[i][0], (LPARAM) &data);
+ FoldersGetCustomPathW((HANDLE) handles[i][1], buffer, MAX_PATH, L"<not found>");
+ Log("Unicode path function[%d] returned: %S", i, buffer);
+ }
+// GetPathService(CONFIGURATION_PATH, (LPARAM) temp);
+// GetPathAllocService(AVATARS_PATH, (LPARAM) &caca);
+
+
+ for (i = 0; i < MAX; i++)
+ {
+ FoldersGetCustomPathEx((HANDLE) handles[i][0], temp, sizeof(temp), "<not found>", "test");
+ Log("Path function Ex (test) [%d] returned : %s", i, temp);
+ FoldersGetCustomPathEx((HANDLE) handles[i][0], temp, sizeof(temp), "<not found>", "");
+ Log("Path function Ex () [%d] returned : %s", i, temp);
+ FoldersGetCustomPathEx((HANDLE) handles[i][0], temp, sizeof(temp), "<not found>", NULL);
+ Log("Path function Ex (NULL) [%d] returned : %s", i, temp);
+ }
+
+ for (i = 0; i < MAX; i++)
+ {
+ FoldersGetCustomPathExW((HANDLE) handles[i][1], buffer, MAX_PATH, L"<not found>", L"test");
+ Log("Unicode path function Ex (test) [%d] returned : %S", i, buffer);
+ FoldersGetCustomPathExW((HANDLE) handles[i][1], buffer, MAX_PATH, L"<not found>", L"");
+ Log("Unicode path function Ex () [%d] returned : %S", i, buffer);
+ FoldersGetCustomPathExW((HANDLE) handles[i][1], buffer, MAX_PATH, L"<not found>", NULL);
+ Log("Unicode path function Ex (NULL) [%d] returned : %S", i, buffer);
+ }
+
+ return 0;
+}
+
+HANDLE hTestPlugin;
+#endif
+
+extern "C" __declspec(dllexport) PLUGININFOEX *MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+#if _MSC_VER >= 1300
+ Log("%s", "Entering function " __FUNCTION__);
+ Log("%s", "Leaving function " __FUNCTION__);
+#endif
+ pluginInfo.cbSize = sizeof(PLUGININFOEX);
+ return &pluginInfo;
+}
+
+static const MUUID interfaces[] = {MIID_FOLDERS, MIID_LAST};
+
+extern "C" __declspec(dllexport) const MUUID *MirandaPluginInterfaces()
+{
+ return interfaces;
+}
+
+extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+#if _MSC_VER >= 1300
+ Log("%s", "Entering function " __FUNCTION__);
+#endif
+ pluginLink = link;
+ mir_getLP(&pluginInfo);
+ mir_getMMI(&mmi);
+
+ Log("%s", "Creating service functions ...");
+ InitServices();
+ InitEvents();
+
+#ifdef _DEBUG
+ hTestPlugin = CreateServiceFunction(MS_FOLDERS_TEST_PLUGIN, TestPlugin);
+ CLISTMENUITEM mi = {0};
+
+ mi.cbSize=sizeof(mi);
+ mi.position=300050000;
+ mi.flags=0;
+ mi.hIcon=0;
+ mi.pszName=Translate("Test folders");
+ mi.pszService=MS_FOLDERS_TEST_PLUGIN;
+ CallService(MS_CLIST_ADDMAINMENUITEM,0,(LPARAM)&mi);
+#endif
+#if _MSC_VER >= 1300
+ Log("%s", "Hooking events ...");
+#endif
+ HookEvents();
+#if _MSC_VER >= 1300
+ Log("%s", "Leaving function " __FUNCTION__);
+#endif
+ return 0;
+}
+
+extern "C" int __declspec(dllexport) Unload()
+{
+#if _MSC_VER >= 1300
+ Log("%s", "Entering function " __FUNCTION__);
+ Log("%s", "Unhooking events ...");
+
+ Log("%s", "Destroying service functions ...");
+#endif
+// DestroyServiceFunction(MS_HISTORY_SHOWCONTACTHISTORY);
+ DestroyServices();
+ DestroyEvents();
+ UnhookEvents();
+#ifdef _DEBUG
+ DestroyServiceFunction(hTestPlugin);
+#endif
+
+#if _MSC_VER >= 1300
+ Log("%s", "Leaving function " __FUNCTION__);
+#endif
+ return 0;
+}
+
+bool WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
+{
+ hInstance = hinstDLL;
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ {
+ DisableThreadLibraryCalls(hinstDLL);
+ }
+ return TRUE;
+} \ No newline at end of file
diff --git a/plugins/folders/folders/folders.rc b/plugins/folders/folders/folders.rc
new file mode 100644
index 0000000000..b87bcd9447
--- /dev/null
+++ b/plugins/folders/folders/folders.rc
@@ -0,0 +1,129 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPT_FOLDERS DIALOGEX 0, 0, 314, 254
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CONTROL | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Dialog"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ GROUPBOX "Custom folders",IDC_FOLDERS_GROUPBOX,0,1,313,250
+ LISTBOX IDC_FOLDERS_SECTIONS_LIST,14,12,77,116,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ LISTBOX IDC_FOLDERS_ITEMS_LIST,98,12,208,116,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Preview",IDC_PREVIEW_GROUPBOX,6,131,300,55
+ EDITTEXT IDC_PREVIEW_EDIT,14,143,284,35,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | NOT WS_TABSTOP
+ GROUPBOX "Edit",IDC_EDIT_FOLDER_GROUPBOX,6,189,300,58
+ EDITTEXT IDC_FOLDER_EDIT,14,202,284,14,ES_AUTOHSCROLL
+ PUSHBUTTON "Refresh preview",IDC_REFRESH_BUTTON,14,227,71,14
+ PUSHBUTTON "Variables help",IDC_HELP_BUTTON,231,227,67,14
+END
+
+IDD_VARIABLES_HELP DIALOGEX 0, 0, 449, 237
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Custom folders variables help"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "Close",IDCLOSE,392,216,50,14
+ CONTROL "",IDC_HELP_RICHEDIT,"RichEdit20A",ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,7,7,435,203
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_OPT_FOLDERS, DIALOG
+ BEGIN
+ RIGHTMARGIN, 313
+ VERTGUIDE, 6
+ VERTGUIDE, 14
+ VERTGUIDE, 298
+ VERTGUIDE, 306
+ TOPMARGIN, 1
+ BOTTOMMARGIN, 251
+ HORZGUIDE, 12
+ HORZGUIDE, 128
+ HORZGUIDE, 202
+ HORZGUIDE, 241
+ HORZGUIDE, 247
+ END
+
+ IDD_VARIABLES_HELP, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 442
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 230
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/folders/folders/folders.vcproj b/plugins/folders/folders/folders.vcproj
new file mode 100644
index 0000000000..fc62cb1496
--- /dev/null
+++ b/plugins/folders/folders/folders.vcproj
@@ -0,0 +1,464 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="folders"
+ ProjectGUID="{019FAEBD-BD7B-4470-A15B-A7DB1787E6BD}"
+ RootNamespace="folders"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="..\..\..\..\cvs\test miranda\Plugins"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../include/"
+ PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_WINDOWS;_USRDLL;FOLDERS_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ BrowseInformation="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ CompileAs="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="unicows.lib"
+ OutputFile="$(OutDir)\$(ProjectName).dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ GenerateMapFile="false"
+ SubSystem="2"
+ BaseAddress="0x2F000000"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../include/"
+ PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN64;_DEBUG;_WINDOWS;_USRDLL;FOLDERS_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ BrowseInformation="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ CompileAs="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName).dll"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ GenerateMapFile="false"
+ SubSystem="2"
+ BaseAddress="0x2F000000"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="0"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ FavorSizeOrSpeed="2"
+ AdditionalIncludeDirectories="../../../include/"
+ PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_WINDOWS;_USRDLL;FOLDERS_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ BrowseInformation="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="unicows.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ BaseAddress="0x2F000000"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="0"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ FavorSizeOrSpeed="2"
+ AdditionalIncludeDirectories="../../../include/"
+ PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN64;NDEBUG;_WINDOWS;_USRDLL;FOLDERS_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ BrowseInformation="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="true"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ BaseAddress="0x2F000000"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\dlg_handlers.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\events.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\folderItem.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\folders.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\foldersList.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\hooked_events.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\services.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\utils.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\commonheaders.h"
+ >
+ </File>
+ <File
+ RelativePath=".\dlg_handlers.h"
+ >
+ </File>
+ <File
+ RelativePath=".\events.h"
+ >
+ </File>
+ <File
+ RelativePath=".\folderItem.h"
+ >
+ </File>
+ <File
+ RelativePath=".\foldersList.h"
+ >
+ </File>
+ <File
+ RelativePath=".\hooked_events.h"
+ >
+ </File>
+ <File
+ RelativePath=".\m_folders.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\services.h"
+ >
+ </File>
+ <File
+ RelativePath=".\utils.h"
+ >
+ </File>
+ <File
+ RelativePath=".\version.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\folders.rc"
+ >
+ </File>
+ <File
+ RelativePath=".\variablesHelp.inc"
+ >
+ </File>
+ <File
+ RelativePath=".\version.rc"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="..\docs\folders_readme.txt"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/plugins/folders/folders/foldersList.cpp b/plugins/folders/folders/foldersList.cpp
new file mode 100644
index 0000000000..b13620fe71
--- /dev/null
+++ b/plugins/folders/folders/foldersList.cpp
@@ -0,0 +1,232 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "foldersList.h"
+
+CFoldersList::CFoldersList(int initialSize)
+{
+ capacity = 0;
+ count = 0;
+ list = NULL;
+ Enlarge(initialSize);
+}
+
+CFoldersList::~CFoldersList()
+{
+ Clear();
+ free(list);
+}
+
+void CFoldersList::Clear()
+{
+ int i;
+ for (i = 0; i < count; i++)
+ {
+ delete (list[i]);
+ }
+
+ count = 0;
+}
+
+int CFoldersList::Count()
+{
+ return count;
+}
+
+int CFoldersList::Capacity()
+{
+ return capacity;
+}
+
+void CFoldersList::Save()
+{
+ int i;
+ for (i = 0; i < count; i++)
+ {
+ list[i]->Save();
+ }
+}
+
+PFolderItem CFoldersList::Get(int index)
+{
+ index--;
+ if ((index < 0) || (index >= count))
+ {
+ return NULL;
+ }
+ return list[index];
+}
+
+PFolderItem CFoldersList::Get(const char *section, const char *name)
+{
+ int i;
+ for (i = 0; i < count; i++)
+ {
+ if (list[i]->IsEqual(section, name))
+ {
+ return list[i];
+ }
+ }
+ return NULL;
+}
+
+PFolderItem CFoldersList::Get(const WCHAR *section, const WCHAR *name)
+{
+ const int MAX_SIZE = 2048;
+ char aSection[MAX_SIZE];
+ char aName[MAX_SIZE];
+ UINT cp = static_cast<UINT>(CallService(MS_LANGPACK_GETCODEPAGE, 0, 0));
+
+ WideCharToMultiByte(cp, 0, section, -1, aSection, MAX_SIZE, NULL, NULL);
+ WideCharToMultiByte(cp, 0, name, -1, aName, MAX_SIZE, NULL, NULL);
+
+ return Get(aSection, aName);
+}
+
+PFolderItem CFoldersList::GetTranslated(const char *trSection, const char *trName)
+{
+ int i;
+ for (i = 0; i < count; i++)
+ {
+ if (list[i]->IsEqualTranslated(trSection, trName))
+ {
+ return list[i];
+ }
+ }
+
+ return NULL;
+}
+
+PFolderItem CFoldersList::GetTranslated(WCHAR *trSection, const WCHAR *trName)
+{
+ const int MAX_SIZE = 2048;
+ char aSection[MAX_SIZE];
+ char aName[MAX_SIZE];
+ UINT cp = static_cast<UINT>(CallService(MS_LANGPACK_GETCODEPAGE, 0, 0));
+
+ WideCharToMultiByte(cp, 0, trSection, -1, aSection, MAX_SIZE, NULL, NULL);
+ WideCharToMultiByte(cp, 0, trName, -1, aName, MAX_SIZE, NULL, NULL);
+
+ return GetTranslated(aSection, aName);
+}
+
+
+int CFoldersList::Expand(int index, char *szResult, int size)
+{
+ PFolderItem tmp = Get(index);
+ int res = 1;
+ if (tmp)
+ {
+ tmp->Expand(szResult, size);
+ res = 0;
+ }
+ else{
+ memset(szResult, 0, size);
+ }
+ return res;
+}
+
+int CFoldersList::Add(CFolderItem *item)
+{
+ EnsureCapacity();
+ int pos = Contains(item);
+ if (!pos)
+ {
+ list[count++] = item;
+ return count;
+ }
+ else{
+ delete item;
+ return pos;
+ }
+ return 0;
+}
+
+int CFoldersList::Add(FOLDERSDATA data)
+{
+ CFolderItem *item;
+ if (data.flags & FF_UNICODE)
+ {
+ item = new CFolderItem(data.szSection, data.szName, (char *) data.szFormatW, data.flags);
+ }
+ else{
+ item = new CFolderItem(data.szSection, data.szName, data.szFormat, data.flags);
+ }
+ return Add(item);
+}
+
+void CFoldersList::Remove(CFolderItem *item)
+{
+// Remove(item->GetUniqueID());
+}
+
+void CFoldersList::Remove(int uniqueID)
+{
+/* int i, j;
+ CFolderItem *tmp;
+ for (i = 0; i < count; i++)
+ {
+ if (list[i]->GetUniqueID() == uniqueID)
+ {
+ tmp = list[i];
+ for (j = i; j < count - 1; j++)
+ {
+ list[j] = list[j + 1];
+ }
+ count--;
+ delete tmp;
+ return;
+ }
+ }
+*/
+}
+
+int CFoldersList::Contains(CFolderItem *item)
+{
+ return Contains(item->GetSection(), item->GetName());
+}
+
+int CFoldersList::Contains(const char *section, const char *name)
+{
+ int i;
+ for (i = 0; i < count; i++)
+ {
+ if (list[i]->IsEqual(section, name))
+ {
+ return i + 1;
+ }
+ }
+ return 0;
+}
+
+void CFoldersList::EnsureCapacity()
+{
+ if (count >= capacity)
+ {
+ Enlarge(capacity / 2);
+ }
+}
+
+void CFoldersList::Enlarge(int increaseAmount)
+{
+ int newSize = capacity + increaseAmount;
+ list = (PFolderItem *) realloc(list, newSize * sizeof(PFolderItem));
+ capacity = newSize;
+} \ No newline at end of file
diff --git a/plugins/folders/folders/foldersList.h b/plugins/folders/folders/foldersList.h
new file mode 100644
index 0000000000..854249b3a3
--- /dev/null
+++ b/plugins/folders/folders/foldersList.h
@@ -0,0 +1,69 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_FOLDERS_LIST_H
+#define M_FOLDERS_LIST_H
+
+#include <string.h>
+#include <malloc.h>
+
+#include "folderItem.h"
+
+#define FOLDERS_NO_HELPER_FUNCTIONS
+#include "m_folders.h"
+#undef FOLDERS_NO_HELPER_FUNCTIONS
+#include "newpluginapi.h"
+#include "m_langpack.h"
+
+class CFoldersList{
+ protected:
+ PFolderItem *list; //the list
+ int count;
+ int capacity;
+
+ void Enlarge(int increaseAmount);
+ void EnsureCapacity();
+
+ public:
+ CFoldersList(int initialSize = 10);
+ virtual ~CFoldersList();
+
+ void Clear();
+ int Add(CFolderItem *item);
+ int Add(FOLDERSDATA data);
+ void Remove(CFolderItem *item);
+ void Remove(int uniqueID);
+ int Contains(CFolderItem *item);
+ int Contains(const char *section, const char *name);
+
+ int Count();
+ int Capacity();
+
+ PFolderItem Get(int index);
+ PFolderItem Get(const char *section, const char *name);
+ PFolderItem Get(const WCHAR *section, const WCHAR *name);
+ PFolderItem GetTranslated(const char *trSection, const char *trName);
+ PFolderItem GetTranslated(WCHAR *trSection, const WCHAR *trName);
+ int Expand(int index, char *szResult, int size);
+ void Save();
+};
+
+
+#endif \ No newline at end of file
diff --git a/plugins/folders/folders/hooked_events.cpp b/plugins/folders/folders/hooked_events.cpp
new file mode 100644
index 0000000000..78439bb3da
--- /dev/null
+++ b/plugins/folders/folders/hooked_events.cpp
@@ -0,0 +1,86 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "hooked_events.h"
+#include "events.h"
+
+#define HOST "http://eblis.tla.ro/projects"
+
+#if defined(WIN64) || defined(_WIN64)
+#define FOLDERS_VERSION_URL HOST "/miranda/Folders/updater/x64/Folders.html"
+#define FOLDERS_UPDATE_URL HOST "/miranda/Folders/updater/x64/Folders.zip"
+#else
+#define FOLDERS_VERSION_URL HOST "/miranda/Folders/updater/Folders.html"
+#define FOLDERS_UPDATE_URL HOST "/miranda/Folders/updater/Folders.zip"
+#endif
+#define FOLDERS_VERSION_PREFIX "Custom profile folders version "
+
+HANDLE hModulesLoaded;
+HANDLE hOptionsInitialize;
+
+int HookEvents()
+{
+ hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded);
+ hOptionsInitialize = HookEvent(ME_OPT_INITIALISE, OnOptionsInitialize);
+ return 0;
+}
+
+int UnhookEvents()
+{
+ UnhookEvent(hModulesLoaded);
+ UnhookEvent(hOptionsInitialize);
+ return 0;
+}
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ char buffer[1024];
+ Update update = {0};
+ update.cbSize = sizeof(Update);
+ update.szComponentName = __PLUGIN_DISPLAY_NAME;
+ update.pbVersion = (BYTE *) CreateVersionString(VERSION, buffer);
+ update.cpbVersion = (int)strlen((char *) update.pbVersion);
+ update.szUpdateURL = UPDATER_AUTOREGISTER;
+ update.szBetaVersionURL = FOLDERS_VERSION_URL;
+ update.szBetaUpdateURL = FOLDERS_UPDATE_URL;
+ update.pbBetaVersionPrefix = (BYTE *) FOLDERS_VERSION_PREFIX;
+ update.cpbBetaVersionPrefix = (int)strlen(FOLDERS_VERSION_PREFIX);
+ CallService(MS_UPDATE_REGISTER, 0, (LPARAM) &update);
+
+ return 0;
+}
+
+int OnOptionsInitialize(WPARAM wParam, LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp = { 0 };
+
+ odp.cbSize = sizeof(odp);
+ odp.position = 100000000;
+ odp.hInstance = hInstance;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_FOLDERS);
+ odp.pszTitle = Translate("Folders");
+ odp.pszGroup = Translate("Customize");
+ odp.groupPosition = 910000000;
+ odp.flags=ODPF_BOLDGROUPS;
+ odp.pfnDlgProc = DlgProcOpts;
+ CallService(MS_OPT_ADDPAGE, wParam, (LPARAM)&odp);
+
+ return 0;
+} \ No newline at end of file
diff --git a/plugins/folders/folders/hooked_events.h b/plugins/folders/folders/hooked_events.h
new file mode 100644
index 0000000000..92401e9850
--- /dev/null
+++ b/plugins/folders/folders/hooked_events.h
@@ -0,0 +1,36 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_FOLDERS_HOOKED_EVENTS_H
+#define M_FOLDERS_HOOKED_EVENTS_H
+
+#include "commonheaders.h"
+#include "services.h"
+
+extern HANDLE hModulesLoaded;
+extern HANDLE hOptionsInitialize;
+
+int UnhookEvents();
+int HookEvents();
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam);
+int OnOptionsInitialize(WPARAM wParam, LPARAM lParam);
+
+#endif \ No newline at end of file
diff --git a/plugins/folders/folders/m_folders.h b/plugins/folders/folders/m_folders.h
new file mode 100644
index 0000000000..02d4d3564e
--- /dev/null
+++ b/plugins/folders/folders/m_folders.h
@@ -0,0 +1,292 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_CUSTOM_FOLDERS_H
+#define M_CUSTOM_FOLDERS_H
+
+#define FOLDERS_API 501 //dunno why it's here but it is :)
+
+#define PROFILE_PATH "%profile_path%"
+#define CURRENT_PROFILE "%current_profile%"
+#define MIRANDA_PATH "%miranda_path%"
+#define PLUGINS_PATH "%miranda_path%" "\\plugins"
+#define MIRANDA_USERDATA "%miranda_userdata%"
+
+#define PROFILE_PATHW L"%profile_path%"
+#define CURRENT_PROFILEW L"%current_profile%"
+#define MIRANDA_PATHW L"%miranda_path%"
+#define MIRANDA_USERDATAW L"%miranda_userdata%"
+
+#ifdef _UNICODE
+ #define PROFILE_PATHT PROFILE_PATHW
+ #define CURRENT_PROFILET CURRENT_PROFILEW
+ #define MIRANDA_PATHT MIRANDA_PATHW
+ #define MIRANDA_USERDATAT MIRANDA_USERDATAW
+#else
+ #define PROFILE_PATHT PROFILE_PATH
+ #define CURRENT_PROFILET CURRENT_PROFILE
+ #define MIRANDA_PATHT MIRANDA_PATH
+ #define MIRANDA_USERDATAT MIRANDA_USERDATA
+#endif
+
+#define FOLDER_AVATARS PROFILE_PATHT _T("\\") CURRENT_PROFILET _T("\\avatars")
+#define FOLDER_VCARDS PROFILE_PATHT _T("\\") CURRENT_PROFILET _T("\\vcards")
+#define FOLDER_LOGS PROFILE_PATHT _T("\\") CURRENT_PROFILET _T("\\logs")
+#define FOLDER_RECEIVED_FILES PROFILE_PATHT _T("\\") CURRENT_PROFILET _T("\\received files")
+#define FOLDER_DOCS MIRANDA_PATHT _T("\\") _T("docs")
+#define FOLDER_CONFIG PLUGINS_PATHT _T("\\") _T("config")
+#define FOLDER_SCRIPTS MIRANDA_PATHT _T("\\") _T("scripts")
+#define FOLDER_UPDATES MIRANDA_PATHT _T("\\") _T("updates")
+
+#define FOLDER_CUSTOMIZE MIRANDA_PATHT _T("\\") _T("customize")
+#define FOLDER_CUSTOMIZE_SOUNDS FOLDER_CUSTOMIZE _T("\\sounds")
+#define FOLDER_CUSTOMIZE_ICONS FOLDER_CUSTOMIZE _T("\\icons")
+#define FOLDER_CUSTOMIZE_SMILEYS FOLDER_CUSTOMIZE _T("\\smileys")
+#define FOLDER_CUSTOMIZE_SKINS FOLDER_CUSTOMIZE _T("\\skins")
+#define FOLDER_CUSTOMIZE_THEMES FOLDER_CUSTOMIZE _T("\\themes")
+
+#define TO_WIDE(x) L ## x
+
+#define FOLDERS_NAME_MAX_SIZE 64 //maximum name and section size
+
+#define FF_UNICODE 0x00000001
+
+#if defined (UNICODE)
+ #define FF_TCHAR FF_UNICODE
+#else
+ #define FF_TCHAR 0
+#endif
+
+typedef struct{
+ int cbSize; //size of struct
+ char szSection[FOLDERS_NAME_MAX_SIZE]; //section name, if it doesn't exist it will be created otherwise it will just add this entry to it
+ char szName[FOLDERS_NAME_MAX_SIZE]; //entry name - will be shown in options
+ union{
+ const char *szFormat; //default string format. Fallback string in case there's no entry in the database for this folder. This should be the initial value for the path, users will be able to change it later.
+ const wchar_t *szFormatW; //String is dup()'d so you can free it later. If you set the unicode string don't forget to set the flag accordingly.
+ const TCHAR *szFormatT;
+ };
+ DWORD flags; //FF_* flags
+} FOLDERSDATA;
+
+/*Folders/Register/Path service
+ wParam - not used, must be 0
+ lParam - (LPARAM) (const FOLDERDATA *) - Data structure filled with
+ the necessary information.
+ Returns a handle to the registered path or 0 on error.
+ You need to use this to call the other services.
+*/
+#define MS_FOLDERS_REGISTER_PATH "Folders/Register/Path"
+
+/*Folders/Get/PathSize service
+ wParam - (WPARAM) (int) - handle to registered path
+ lParam - (LPARAM) (int *) - pointer to the variable that receives the size of the path
+ string (not including the null character). Depending on the flags set when creating the path
+ it will either call strlen() or wcslen() to get the length of the string.
+ Returns the size of the buffer.
+*/
+#define MS_FOLDERS_GET_SIZE "Folders/Get/PathSize"
+
+typedef struct{
+ int cbSize;
+ int nMaxPathSize; //maximum size of buffer. This represents the number of characters that can be copied to it (so for unicode strings you don't send the number of bytes but the length of the string).
+ union{
+ char *szPath; //pointer to the buffer that receives the path without the last "\\"
+ wchar_t *szPathW; //unicode version of the buffer.
+ TCHAR *szPathT;
+ };
+} FOLDERSGETDATA;
+
+/*Folders/Get/Path service
+ wParam - (WPARAM) (int) - handle to registered path
+ lParam - (LPARAM) (FOLDERSGETDATA *) pointer to a FOLDERSGETDATA that has all the relevant fields filled.
+ Should return 0 on success, or nonzero otherwise.
+*/
+#define MS_FOLDERS_GET_PATH "Folders/Get/Path"
+
+typedef struct{
+ int cbSize;
+ union{
+ char **szPath; //address of a string variable (char *) or (wchar_t*) where the path should be stored (the last \ won't be copied).
+ wchar_t **szPathW; //unicode version of string.
+ TCHAR **szPathT;
+ };
+} FOLDERSGETALLOCDATA;
+
+/*Folders/GetRelativePath/Alloc service
+ wParam - (WPARAM) (int) - Handle to registered path
+ lParam - (LPARAM) (FOLDERSALLOCDATA *) data
+ This service is the same as MS_FOLDERS_GET_PATH with the difference that this service
+ allocates the needed space for the buffer. It uses miranda's memory functions for that and you need
+ to use those to free the resulting buffer.
+ Should return 0 on success, or nonzero otherwise. Currently it only returns 0.
+*/
+#define MS_FOLDERS_GET_PATH_ALLOC "Folders/Get/Path/Alloc"
+
+
+/*Folders/On/Path/Changed
+ wParam - (WPARAM) 0
+ lParam - (LPARAM) 0
+ Triggered when the folders change, you should reget the paths you registered.
+*/
+#define ME_FOLDERS_PATH_CHANGED "Folders/On/Path/Changed"
+
+#ifndef FOLDERS_NO_HELPER_FUNCTIONS
+
+#ifndef M_UTILS_H__
+#error The helper functions require that m_utils.h be included in the project. Please include that file if you want to use the helper functions. If you don''t want to use the functions just define FOLDERS_NO_HELPER_FUNCTIONS.
+#endif
+//#include "../../../include/newpluginapi.h"
+
+__inline static HANDLE FoldersRegisterCustomPath(const char *section, const char *name, const char *defaultPath)
+{
+ FOLDERSDATA fd = {0};
+ if (!ServiceExists(MS_FOLDERS_REGISTER_PATH)) return 0;
+ fd.cbSize = sizeof(FOLDERSDATA);
+ strncpy(fd.szSection, section, FOLDERS_NAME_MAX_SIZE);
+ fd.szSection[FOLDERS_NAME_MAX_SIZE - 1] = '\0';
+ strncpy(fd.szName, name, FOLDERS_NAME_MAX_SIZE);
+ fd.szName[FOLDERS_NAME_MAX_SIZE - 1] = '\0';
+ fd.szFormat = defaultPath;
+ return (HANDLE) CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &fd);
+}
+
+__inline static HANDLE FoldersRegisterCustomPathW(const char *section, const char *name, const wchar_t *defaultPathW)
+{
+ FOLDERSDATA fd = {0};
+ if (!ServiceExists(MS_FOLDERS_REGISTER_PATH)) return 0;
+ fd.cbSize = sizeof(FOLDERSDATA);
+ strncpy(fd.szSection, section, FOLDERS_NAME_MAX_SIZE);
+ fd.szSection[FOLDERS_NAME_MAX_SIZE - 1] = '\0'; //make sure it's NULL terminated
+ strncpy(fd.szName, name, FOLDERS_NAME_MAX_SIZE);
+ fd.szName[FOLDERS_NAME_MAX_SIZE - 1] = '\0'; //make sure it's NULL terminated
+ fd.szFormatW = defaultPathW;
+ fd.flags = FF_UNICODE;
+ return (HANDLE) CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &fd);
+}
+
+__inline static INT_PTR FoldersGetCustomPath(HANDLE hFolderEntry, char *path, const int size, const char *notFound)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = size;
+ fgd.szPath = path;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ char buffer[MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM) notFound, (LPARAM) buffer);
+ mir_snprintf(path, size, "%s", buffer);
+ }
+
+ return res;
+}
+
+__inline static INT_PTR FoldersGetCustomPathW(HANDLE hFolderEntry, wchar_t *pathW, const int count, const wchar_t *notFoundW)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = count;
+ fgd.szPathW = pathW;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ wcsncpy(pathW, notFoundW, count);
+ pathW[count - 1] = '\0';
+ }
+
+ return res;
+}
+
+__inline static INT_PTR FoldersGetCustomPathEx(HANDLE hFolderEntry, char *path, const int size, char *notFound, char *fileName)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = size;
+ fgd.szPath = path;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ char buffer[MAX_PATH];
+ CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM) notFound, (LPARAM) buffer);
+ mir_snprintf(path, size, "%s", buffer);
+ }
+ if (strlen(path) > 0)
+ {
+ strcat(path, "\\");
+ }
+ else{
+ path[0] = '\0';
+ }
+
+ if (fileName)
+ {
+ strcat(path, fileName);
+ }
+
+ return res;
+}
+
+__inline static INT_PTR FoldersGetCustomPathExW(HANDLE hFolderEntry, wchar_t *pathW, const int count, wchar_t *notFoundW, wchar_t *fileNameW)
+{
+ FOLDERSGETDATA fgd = {0};
+ INT_PTR res;
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = count;
+ fgd.szPathW = pathW;
+ res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ wcsncpy(pathW, notFoundW, count);
+ pathW[count - 1] = '\0';
+ }
+
+ if (wcslen(pathW) > 0)
+ {
+ wcscat(pathW, L"\\");
+ }
+ else{
+ pathW[0] = L'\0';
+ }
+
+ if (fileNameW)
+ {
+ wcscat(pathW, fileNameW);
+ }
+
+ return res;
+}
+
+# ifdef _UNICODE
+# define FoldersGetCustomPathT FoldersGetCustomPathW
+# define FoldersGetCustomPathExT FoldersGetCustomPathExW
+# define FoldersRegisterCustomPathT FoldersRegisterCustomPathW
+#else
+# define FoldersGetCustomPathT FoldersGetCustomPath
+# define FoldersGetCustomPathExT FoldersGetCustomPath
+# define FoldersRegisterCustomPathT FoldersRegisterCustomPath
+#endif
+
+#endif
+
+#endif //M_CUSTOM_FOLDERS_H \ No newline at end of file
diff --git a/plugins/folders/folders/resource.h b/plugins/folders/folders/resource.h
new file mode 100644
index 0000000000..e8ff0247cf
--- /dev/null
+++ b/plugins/folders/folders/resource.h
@@ -0,0 +1,27 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by folders.rc
+//
+#define IDD_OPT_FOLDERS 101
+#define IDD_VARIABLES_HELP 102
+#define IDC_FOLDERS_ITEMS_LIST 1002
+#define IDC_FOLDERS_GROUPBOX 1003
+#define IDC_EDIT_FOLDER_GROUPBOX 1004
+#define IDC_FOLDER_EDIT 1005
+#define IDC_REFRESH_BUTTON 1008
+#define IDC_PREVIEW_GROUPBOX 1009
+#define IDC_PREVIEW_EDIT 1010
+#define IDC_HELP_BUTTON 1011
+#define IDC_HELP_RICHEDIT 1012
+#define IDC_FOLDERS_SECTIONS_LIST 1013
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 105
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1014
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/plugins/folders/folders/sdk/m_updater.h b/plugins/folders/folders/sdk/m_updater.h
new file mode 100644
index 0000000000..371b7437a0
--- /dev/null
+++ b/plugins/folders/folders/sdk/m_updater.h
@@ -0,0 +1,146 @@
+#ifndef _M_UPDATER_H
+#define _M_UPDATER_H
+
+// NOTES:
+// - For langpack updates, include a string of the following format in the langpack text file:
+// ";FLID: <file listing name> <version>"
+// version must be four numbers seperated by '.', in the range 0-255 inclusive
+// - Updater will disable plugins that are downloaded but were not active prior to the update (this is so that, if an archive contains e.g. ansi and
+// unicode versions, the correct plugin will be the only one active after the new version is installed)...so if you add a support plugin, you may need
+// to install an ini file to make the plugin activate when miranda restarts after the update
+// - Updater will replace all dlls that have the same internal shortName as a downloaded update dll (this is so that msn1.dll and msn2.dll, for example,
+// will both be updated) - so if you have a unicode and a non-unicode version of a plugin in your archive, you should make the internal names different (which will break automatic
+// updates from the file listing if there is only one file listing entry for both versions, unless you use the 'MS_UPDATE_REGISTER' service below)
+// - Updater will install all files in the root of the archive into the plugins folder, except for langpack files that contain the FLID string which go into the root folder (same
+// folder as miranda32.exe)...all folders in the archive will also be copied to miranda's root folder, and their contents transferred into the new folders. The only exception is a
+// special folder called 'root_files' - if there is a folder by that name in the archive, it's contents will also be copied into miranda's root folder - this is intended to be used
+// to install additional dlls etc that a plugin may require)
+
+// if you set Update.szUpdateURL to the following value when registering, as well as setting your beta site and version data,
+// Updater will ignore szVersionURL and pbVersionPrefix, and attempt to find the file listing URL's from the backend XML data.
+// for this to work, the plugin name in pluginInfo.shortName must match the file listing exactly (except for case)
+#define UPDATER_AUTOREGISTER "UpdaterAUTOREGISTER"
+// Updater will also use the backend xml data if you provide URL's that reference the miranda file listing for updates (so you can use that method
+// if e.g. your plugin shortName does not match the file listing) - it will grab the file listing id from the end of these URLs
+
+typedef struct Update_tag {
+ int cbSize;
+ char *szComponentName; // component name as it will appear in the UI (will be translated before displaying)
+
+ char *szVersionURL; // URL where the current version can be found (NULL to disable)
+ BYTE *pbVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ // (note that this URL could point at a binary file - dunno why, but it could :)
+ int cpbVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szUpdateURL; // URL where dll/zip is located
+ // set to UPDATER_AUTOREGISTER if you want Updater to find the file listing URLs (ensure plugin shortName matches file listing!)
+
+ char *szBetaVersionURL; // URL where the beta version can be found (NULL to disable betas)
+ BYTE *pbBetaVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ int cpbBetaVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szBetaUpdateURL; // URL where dll/zip is located
+
+ BYTE *pbVersion; // bytes of current version, used for comparison with those in VersionURL
+ int cpbVersion; // number of bytes pointed to by pbVersion
+
+ char *szBetaChangelogURL; // url for displaying changelog for beta versions
+} Update;
+
+// register a comonent with Updater
+//
+// wparam = 0
+// lparam = (LPARAM)&Update
+#define MS_UPDATE_REGISTER "Update/Register"
+
+// utility functions to create a version string from a DWORD or from pluginInfo
+// point buf at a buffer at least 16 chars wide - but note the version string returned may be shorter
+//
+__inline static char *CreateVersionString(DWORD version, char *buf) {
+ mir_snprintf(buf, 16, "%d.%d.%d.%d", (version >> 24) & 0xFF, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);
+ return buf;
+}
+
+__inline static char *CreateVersionStringPlugin(PLUGININFO *pluginInfo, char *buf) {
+ return CreateVersionString(pluginInfo->version, buf);
+}
+
+
+// register the 'easy' way - use this method if you have no beta URL and the plugin is on the miranda file listing
+// NOTE: the plugin version string on the file listing must be the string version of the version in pluginInfo (i.e. 0.0.0.1,
+// four numbers between 0 and 255 inclusivem, so no letters, brackets, etc.)
+//
+// wParam = (int)fileID - this is the file ID from the file listing (i.e. the number at the end of the download link)
+// lParam = (PLUGININFO*)&pluginInfo
+#define MS_UPDATE_REGISTERFL "Update/RegisterFL"
+
+// this function can be used to 'unregister' components - useful for plugins that register non-plugin/langpack components and
+// may need to change those components on the fly
+// lParam = (char *)szComponentName
+#define MS_UPDATE_UNREGISTER "Update/Unregister"
+
+// this event is fired when the startup process is complete, but NOT if a restart is imminent
+// it is designed for status managment plugins to use as a trigger for beggining their own startup process
+// wParam = lParam = 0 (unused)
+// (added in version 0.1.6.0)
+#define ME_UPDATE_STARTUPDONE "Update/StartupDone"
+
+// this service can be used to enable/disable Updater's global status control
+// it can be called from the StartupDone event handler
+// wParam = (BOOL)enable
+// lParam = 0
+// (added in version 0.1.6.0)
+#define MS_UPDATE_ENABLESTATUSCONTROL "Update/EnableStatusControl"
+
+// An description of usage of the above service and event:
+// Say you are a status control plugin that normally sets protocol or global statuses in your ModulesLoaded event handler.
+// In order to make yourself 'Updater compatible', you would move the status control code from ModulesLoaded to another function,
+// say DoStartup. Then, in ModulesLoaded you would check for the existence of the MS_UPDATE_ENABLESTATUSCONTROL service.
+// If it does not exist, call DoStartup. If it does exist, hook the ME_UPDATE_STARTUPDONE event and call DoStartup from there. You may
+// also wish to call MS_UPDATE_ENABLESTATUSCONTROL with wParam == FALSE at this time, to disable Updater's own status control feature.
+
+// this service can be used to determine whether updates are possible for a component with the given name
+// wParam = 0
+// lParam = (char *)szComponentName
+// returns TRUE if updates are supported, FALSE otherwise
+#define MS_UPDATE_ISUPDATESUPPORTED "Update/IsUpdateSupported"
+
+#endif
+
+
+/////////////// Usage Example ///////////////
+
+#ifdef EXAMPLE_CODE
+
+// you need to #include "m_updater.h" and HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded) in your Load function...
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam) {
+
+ Update update = {0}; // for c you'd use memset or ZeroMemory...
+ char szVersion[16];
+
+ update.cbSize = sizeof(Update);
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionString(&pluginInfo, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+
+ // these are the three lines that matter - the archive, the page containing the version string, and the text (or data)
+ // before the version that we use to locate it on the page
+ // (note that if the update URL and the version URL point to standard file listing entries, the backend xml
+ // data will be used to check for updates rather than the actual web page - this is not true for beta urls)
+ update.szUpdateURL = "http://scottellis.com.au:81/test/updater.zip";
+ update.szVersionURL = "http://scottellis.com.au:81/test/updater_test.html";
+ update.pbVersionPrefix = (BYTE *)"Updater version ";
+
+ update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix);
+
+ // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+
+ // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing...
+ // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo);
+
+ return 0;
+}
+
+#endif
diff --git a/plugins/folders/folders/sdk/m_variables.h b/plugins/folders/folders/sdk/m_variables.h
new file mode 100644
index 0000000000..5ac463fe4b
--- /dev/null
+++ b/plugins/folders/folders/sdk/m_variables.h
@@ -0,0 +1,745 @@
+/*
+ Variables Plugin for Miranda-IM (www.miranda-im.org)
+ Copyright 2003-2006 P. Boon
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __M_VARS
+#define __M_VARS
+
+#if !defined(_TCHAR_DEFINED)
+#include <tchar.h>
+#endif
+
+#ifndef VARIABLES_NOHELPER
+#include "../../../include/m_button.h"
+#endif
+
+#ifndef SIZEOF
+#include "../../../include/win2k.h"
+#endif
+
+// --------------------------------------------------------------------------
+// Memory management
+// --------------------------------------------------------------------------
+
+// Release memory that was allocated by the Variables plugin, e.g. returned
+// strings.
+
+#define MS_VARS_FREEMEMORY "Vars/FreeMemory"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(void *)pntr
+// Pointer to memory that was allocated by the Variables plugin (e.g. a
+// returned string) (can be NULL).
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Does return 0 on success, nozero otherwise.
+
+// Note: Do only use this service to free memory that was *explicitliy*
+// stated that it should be free with this service.
+
+
+
+#define MS_VARS_GET_MMI "Vars/GetMMI"
+
+// Get Variable's RTL/CRT function poiners to malloc(), free() and
+// realloc().
+
+// Parameters:
+// ------------------------
+// wParam = 0
+// lParam = (LPARAM) &MM_INTERFACE
+// Pointer to a memory manager interface struct (see m_system.h).
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nozero otherwise
+
+// Note: Works exactly the same as the MS_SYSTEM_GET_MMI service
+// service of m_system.h.
+
+// Helper function for easy using:
+#ifndef VARIABLES_NOHELPER
+__inline static void variables_free(void *pntr) {
+
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)pntr, 0);
+}
+#endif
+
+
+
+// --------------------------------------------------------------------------
+// String formatting
+// --------------------------------------------------------------------------
+
+#define MS_VARS_FORMATSTRING "Vars/FormatString"
+
+// This service can be used to parse tokens in a text. The tokens will be
+// replaced by their resolved values. A token can either be a field or a
+// function. A field takes no arguments and is represented between
+// %-characters, e.g. "%winampsong%". A function can take any number of
+// arguments and is represented by a ? or !-character followed by the name
+// of the function and a list of arguments, e.g. "?add(1,2)".
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(FORMATINFO *)&fi
+// See below.
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Returns a pointer to the resolved string or NULL in case of an error.
+
+// Note: The returned pointer needs to be freed using MS_VARS_FREEMEMORY.
+
+typedef struct {
+ int cbSize; // Set this to sizeof(FORMATINFO).
+ int flags; // Flags to use (see FIF_* below).
+ union {
+ char *szFormat; // Text in which the tokens will be replaced (can't be
+ // NULL).
+ WCHAR *wszFormat;
+ TCHAR *tszFormat;
+ };
+ union {
+ char *szExtraText; // Extra, context-specific string (can be NULL) ->
+ // The field "extratext" will be replaced by this
+ // string. (Previously szSource).
+ WCHAR *wszExtraText;
+ TCHAR *tszExtraText;
+ };
+ HANDLE hContact; // Handle to contact (can be NULL) -> The field "subject"
+ // represents this contact.
+ int pCount; // (output) Number of succesful parsed tokens, needs to be set
+ // to 0 before the call
+ int eCount; // (output) Number of failed tokens, needs to be set to 0
+ // before the call
+ union {
+ char **szaTemporaryVars; // Temporary variables valid only in the duration of the format call
+ TCHAR **tszaTemporaryVars; // By pos: [i] is var name, [i + 1] is var value
+ WCHAR **wszaTemporaryVars;
+ };
+ int cbTemporaryVarsSize; // Number of elements in szaTemporaryVars array
+
+} FORMATINFO;
+
+#define FORMATINFOV2_SIZE 28
+
+// Possible flags:
+#define FIF_UNICODE 0x01 // Expects and returns unicode text (WCHAR*).
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define FIF_TCHAR FIF_UNICODE // Strings in structure are TCHAR*.
+#else
+#define FIF_TCHAR 0
+#endif
+
+// Helper functions for easy using:
+
+// Helper #1: variables_parse
+// ------------------------
+// The returned string needs to be freed using MS_VARS_FREEMEMORY.
+
+#ifndef VARIABLES_NOHELPER
+__inline static TCHAR *variables_parse(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact) {
+
+ FORMATINFO fi;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags = FIF_TCHAR;
+
+ return (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+}
+
+__inline static char *variables_parse_char(char *szFormat, char *szExtraText, HANDLE hContact)
+{
+ FORMATINFO fi = {0};
+
+ fi.cbSize = sizeof(fi);
+ fi.szFormat = szFormat;
+ fi.szExtraText = szExtraText;
+ fi.hContact = hContact;
+ fi.flags = 0;
+
+ return (char *) CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+}
+__inline static wchar_t *variables_parse_wchar(wchar_t *wszFormat, wchar_t *wszExtraText, HANDLE hContact)
+{
+ FORMATINFO fi = {0};
+
+ fi.cbSize = sizeof(fi);
+ fi.wszFormat = wszFormat;
+ fi.wszExtraText = wszExtraText;
+ fi.hContact = hContact;
+ fi.flags = FIF_UNICODE;
+
+ return (wchar_t *) CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+}
+
+#endif
+
+__inline static TCHAR *variables_parse_ex(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact,
+ TCHAR **tszaTemporaryVars, int cbTemporaryVarsSize) {
+
+ FORMATINFO fi;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags = FIF_TCHAR;
+ fi.tszaTemporaryVars = tszaTemporaryVars;
+ fi.cbTemporaryVarsSize = cbTemporaryVarsSize;
+
+ return (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+}
+// Helper #2: variables_parsedup
+// ------------------------
+// Returns a _strdup()'ed copy of the unparsed string when Variables is not
+// installed, returns a strdup()'ed copy of the parsed result otherwise.
+
+// Note: The returned pointer needs to be released using your own free().
+
+#ifndef VARIABLES_NOHELPER
+__inline static TCHAR *variables_parsedup(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact) {
+
+ if (ServiceExists(MS_VARS_FORMATSTRING)) {
+ FORMATINFO fi;
+ TCHAR *tszParsed, *tszResult;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags |= FIF_TCHAR;
+ tszParsed = (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+ if (tszParsed) {
+ tszResult = _tcsdup(tszParsed);
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)tszParsed, 0);
+ return tszResult;
+ }
+ }
+ return tszFormat?_tcsdup(tszFormat):tszFormat;
+}
+
+__inline static TCHAR *variables_parsedup_ex(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact,
+ TCHAR **tszaTemporaryVars, int cbTemporaryVarsSize) {
+
+ if (ServiceExists(MS_VARS_FORMATSTRING)) {
+ FORMATINFO fi;
+ TCHAR *tszParsed, *tszResult;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags |= FIF_TCHAR;
+ fi.tszaTemporaryVars = tszaTemporaryVars;
+ fi.cbTemporaryVarsSize = cbTemporaryVarsSize;
+ tszParsed = (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+ if (tszParsed) {
+ tszResult = _tcsdup(tszParsed);
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)tszParsed, 0);
+ return tszResult;
+ }
+ }
+ return tszFormat?_tcsdup(tszFormat):tszFormat;
+}
+#endif
+
+
+
+// --------------------------------------------------------------------------
+// Register tokens
+// --------------------------------------------------------------------------
+
+// Plugins can define tokens which will be parsed by the Variables plugin.
+
+#define MS_VARS_REGISTERTOKEN "Vars/RegisterToken"
+
+// With this service you can define your own token. The newly added tokens
+// using this service are taken into account on every call to
+// MS_VARS_FORMATSTRING.
+
+// Parameters:
+// ------------------------
+// wParam = 0
+// lParam = (LPARAM)(TOKENREGISTER*)&tr
+// See below.
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nonzero otherwise. Existing tokens will be
+// 'overwritten' if registered twice.
+
+// Needed for szService and parseFunction:
+typedef struct {
+ int cbSize; // You need to check if this is >=sizeof(ARGUMENTSINFO)
+ // (already filled in).
+ FORMATINFO *fi; // Arguments passed to MS_VARS_FORMATSTRING.
+ unsigned int argc; // Number of elements in the argv array.
+ union {
+ char **argv; // Argv[0] will be the token name, the following elements
+ // are the additional arguments.
+ WCHAR **wargv; // If the registered token was registered as a unicode
+ // token, wargv should be accessed.
+ TCHAR **targv;
+ };
+ int flags; // (output) You can set flags here (initially 0), use the
+ // AIF_* flags (see below).
+} ARGUMENTSINFO;
+
+// Available flags for ARGUMENTSINFO:
+// Set the flags of the ARGUMENTSINFO struct to any of these to influence
+// further parsing.
+#define AIF_DONTPARSE 0x01 // Don't parse the result of this function,
+ // usually the result of a token is parsed
+ // again, if the `?` is used as a function
+ // character.
+#define AIF_FALSE 0x02 // The function returned logical false.
+
+// Definition of parse/cleanup functions:
+typedef char* (*VARPARSEFUNCA)(ARGUMENTSINFO *ai);
+typedef WCHAR* (*VARPARSEFUNCW)(ARGUMENTSINFO *ai);
+typedef void (*VARCLEANUPFUNCA)(char *szReturn);
+typedef void (*VARCLEANUPFUNCW)(WCHAR *wszReturn);
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define VARPARSEFUNC VARPARSEFUNCW
+#define VARCLEANUPFUNC VARCLEANUPFUNCW
+#else
+#define VARPARSEFUNC VARPARSEFUNCA
+#define VARCLEANUPFUNC VARCLEANUPFUNCA
+#endif
+
+typedef struct {
+ int cbSize; // Set this to sizeof(TOKENREGISTER).
+ union {
+ char *szTokenString; // Name of the new token to be created, without %,
+ // ?, ! etc. signs (can't be NULL).
+ WCHAR *wszTokenString;
+ TCHAR *tszTokenString;
+ };
+ union {
+ char *szService; // Name of a service that is used to request the
+ // token's value, if no service is used, a function
+ // and TRF_PARSEFUNC must be used.
+ VARPARSEFUNCA parseFunction; // See above, use with TRF_PARSEFUNC.
+ VARPARSEFUNCW parseFunctionW;
+ VARPARSEFUNC parseFunctionT;
+ };
+ union {
+ char *szCleanupService; // Name of a service to be called when the
+ // memory allocated in szService can be freed
+ // (only used when flag VRF_CLEANUP is set,
+ // else set this to NULL).
+ VARCLEANUPFUNCA cleanupFunction; // See above, use with TRF_CLEANUPFUNC.
+ VARCLEANUPFUNCW cleanupFunctionW;
+ VARCLEANUPFUNC cleanupFunctionT;
+ };
+ char *szHelpText; // Help info shown in help dialog (can be NULL). Has to
+ // be in the following format:
+ // "subject\targuments\tdescription"
+ // (Example: "math\t(x, y ,...)\tx + y + ..."), or:
+ // "subject\tdescription"
+ // (Example: "miranda\tPath to the Miranda-IM
+ // executable").
+ // Note: subject and description are translated by
+ // Variables.
+ int memType; // Describes which method Varibale's plugin needs to use to
+ // free the returned buffer, use one of the VR_MEM_* values
+ // (see below). Only valid if the flag VRF_FREEMEM is set,
+ // use TR_MEM_OWNER otherwise).
+ int flags; // Flags to use (see below), one of TRF_* (see below).
+} TOKENREGISTER;
+
+// Available Memory Storage Types:
+// These values describe which method Variables Plugin will use to free the
+// buffer returned by the parse function or service
+#define TR_MEM_VARIABLES 1 // Memory is allocated using the functions
+ // retrieved by MS_VARS_GET_MMI.
+#define TR_MEM_MIRANDA 2 // Memory is allocated using Miranda's Memory
+ // Manager Interface (using the functions
+ // returned by MS_SYSTEM_GET_MMI), if
+ // VRF_FREEMEM is set, the memory will be
+ // freed by Variables.
+#define TR_MEM_OWNER 3 // Memory is owned by the calling plugin
+ // (can't be freed by Variables Plugin
+ // automatically). This should be used if
+ // VRF_FREEMEM is not specified in the flags.
+
+// Available Flags for TOKENREGISTER:
+#define TRF_FREEMEM 0x01 // Variables Plugin will automatically free the
+ // pointer returned by the parse function or
+ // service (which method it will us is
+ // specified in memType -> see above).
+#define TRF_CLEANUP 0x02 // Call cleanup service or function, notifying
+ // that the returned buffer can be freed.
+ // Normally you should use either TRF_FREEMEM
+ // or TRF_CLEANUP.
+#define TRF_PARSEFUNC 0x40 // parseFunction will be used instead of a
+ // service.
+#define TRF_CLEANUPFUNC 0x80 // cleanupFunction will be used instead of a
+ // service.
+#define TRF_USEFUNCS TRF_PARSEFUNC|TRF_CLEANUPFUNC
+#define TRF_UNPARSEDARGS 0x04 // Provide the arguments for the parse
+ // function in their raw (unparsed) form.
+ // By default, arguments are parsed before
+ // presenting them to the parse function.
+#define TRF_FIELD 0x08 // The token can be used as a %field%.
+#define TRF_FUNCTION 0x10 // The token can be used as a ?function().
+ // Normally you should use either TRF_FIELD or
+ // TRF_FUNCTION.
+#define TRF_UNICODE 0x20 // Strings in structure are unicode (WCHAR*).
+ // In this case, the strings pointing to the
+ // arguments in the ARGUMENTS struct are
+ // unicode also. The returned buffer is
+ // expected to be unicode also, and the
+ // unicode parse and cleanup functions are
+ // called.
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define TRF_TCHAR TRF_UNICODE // Strings in structure are TCHAR*.
+#else
+#define TRF_TCHAR 0
+#endif
+
+// Deprecated:
+#define TRF_CALLSVC TRF_CLEANUP
+
+// Callback Service (szService) / parseFunction:
+// ------------------------
+// Service that is called automatically by the Variable's Plugin to resolve a
+// registered variable.
+
+// Parameters:
+// wParam = 0
+// lParam = (LPARAM)(ARGUMENTSINFO *)&ai
+// see above
+
+// Return Value:
+// Needs to return the pointer to a dynamically allocacated string or NULL.
+// A return value of NULL is regarded as an error (eCount will be increaded).
+// Flags in the ARGUMENTSINFO struct can be set (see above).
+
+// Callback Service (szCallbackService) / cleanupFunction:
+// ------------------------
+// This service is called when the memory that was allocated by the parse
+// function or service can be freed. Note: It will only be called when the
+// flag VRF_CLEANUP of TOKENREGISTER is set.
+
+// Parameters:
+// wParam = 0
+// lParam = (LPARAM)(char *)&res
+// Result from parse function or service (pointer to a string).
+
+// Return Value:
+// Should return 0 on success.
+
+
+
+// --------------------------------------------------------------------------
+// Show the help dialog
+// --------------------------------------------------------------------------
+
+// Plugins can invoke Variables' help dialog which can be used for easy input
+// by users.
+
+#define MS_VARS_SHOWHELPEX "Vars/ShowHelpEx"
+
+// This service can be used to open the help dialog of Variables. This dialog
+// provides easy input for the user and/or information about the available
+// tokens.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(HWND)hwndParent
+// lParam = (LPARAM)(VARHELPINFO)&vhi
+// See below.
+
+// Return Value:
+// ------------------------
+// Returns 0 on succes, any other value on error.
+
+typedef struct {
+ int cbSize; // Set to sizeof(VARHELPINFO).
+ FORMATINFO *fi; // Used for both input and output. If this pointer is not
+ // NULL, the information is used as the initial values for
+ // the dialog.
+ HWND hwndCtrl; // Used for both input and output. The window text of this
+ // window will be read and used as the initial input of the
+ // input dialog. If the user presses the OK button the window
+ // text of this window will be set to the text of the input
+ // field and a EN_CHANGE message via WM_COMMAND is send to
+ // this window. (Can be NULL).
+ char *szSubjectDesc; // The description of the %subject% token will be set
+ // to this text, if not NULL. This is translated
+ // automatically.
+ char *szExtraTextDesc; // The description of the %extratext% token will be
+ // set to this text, if not NULL. This is translated
+ // automatically.
+ int flags; // Flags, see below.
+} VARHELPINFO;
+
+
+// Flags for VARHELPINFO
+#define VHF_TOKENS 0x00000001 // Create a dialog with the list of
+ // tokens
+#define VHF_INPUT 0x00000002 // Create a dialog with an input
+ // field (this contains the list of
+ // tokens as well).
+#define VHF_SUBJECT 0x00000004 // Create a dialog to select a
+ // contact for the %subject% token.
+#define VHF_EXTRATEXT 0x00000008 // Create a dialog to enter a text
+ // for the %extratext% token.
+#define VHF_HELP 0x00000010 // Create a dialog with help info.
+#define VHF_HIDESUBJECTTOKEN 0x00000020 // Hide the %subject% token in the
+ // list of tokens.
+#define VHF_HIDEEXTRATEXTTOKEN 0x00000040 // Hide the %extratext% token in
+ // the list of tokens.
+#define VHF_DONTFILLSTRUCT 0x00000080 // Don't fill the struct with the
+ // new information if OK is pressed
+#define VHF_FULLFILLSTRUCT 0x00000100 // Fill all members of the struct
+ // when OK is pressed. By default
+ // only szFormat is set. With this
+ // flag on, hContact and
+ // szExtraText are also set.
+#define VHF_SETLASTSUBJECT 0x00000200 // Set the last contact that was
+ // used in the %subject% dialog in
+ // case fi.hContact is NULL.
+
+// Predefined flags
+#define VHF_FULLDLG VHF_INPUT|VHF_SUBJECT|VHF_EXTRATEXT|VHF_HELP
+#define VHF_SIMPLEDLG VHF_INPUT|VHF_HELP
+#define VHF_NOINPUTDLG VHF_TOKENS|VHF_HELP
+
+// If the service fills information in the struct for szFormat or szExtraText,
+// these members must be free'd using the free function of Variables.
+// If wParam==NULL, the dialog is created modeless. Only one dialog can be
+// shown at the time.
+// If both hwndCtrl and fi are NULL, the user input will not be retrievable.
+// In this case, the dialog is created with only a "Close" button, instead of
+// the "OK" and "Cancel" buttons.
+// In case of modeless dialog and fi != NULL, please make sure this pointer
+// stays valid while the dialog is open.
+
+// Helper function for easy use in standard case:
+#ifndef VARIABLES_NOHELPER
+__inline static int variables_showhelp(HWND hwndDlg, UINT uIDEdit, int flags, char *szSubjectDesc, char *szExtraDesc) {
+
+ VARHELPINFO vhi;
+
+ ZeroMemory(&vhi, sizeof(VARHELPINFO));
+ vhi.cbSize = sizeof(VARHELPINFO);
+ if (flags == 0) {
+ flags = VHF_SIMPLEDLG;
+ }
+ vhi.flags = flags;
+ vhi.hwndCtrl = GetDlgItem(hwndDlg, uIDEdit);
+ vhi.szSubjectDesc = szSubjectDesc;
+ vhi.szExtraTextDesc = szExtraDesc;
+
+ return CallService(MS_VARS_SHOWHELPEX, (WPARAM)hwndDlg, (LPARAM)&vhi);
+}
+#endif
+
+
+#define MS_VARS_GETSKINITEM "Vars/GetSkinItem"
+
+// This service can be used to get the icon you can use for example on the
+// Variables help button in your options screen. You can also get the tooltip
+// text to use with such a button. If icon library is available the icon will
+// be retrieved from icon library manager, otherwise the default is returned.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)0
+// lParam = (LPARAM)VSI_* (see below)
+
+// Return Value:
+// ------------------------
+// Depends on the information to retrieve (see below).
+
+// VSI_ constants
+#define VSI_HELPICON 1 // Can be used on the button accessing the
+ // Variables help dialog. Returns (HICON)hIcon on
+ // success or NULL on failure;
+#define VSI_HELPTIPTEXT 2 // Returns the tooltip text you can use for the
+ // help button. Returns (char *)szTipText, a
+ // static, translated buffer containing the help
+ // text or NULL on error.
+
+// Helper to set the icon on a button accessing the help dialog.
+// Preferably a 16x14 MButtonClass control, but it works on a standard
+// button control as well. If no icon is availble (because of old version of
+// Variables) the string "V" is shown on the button. If Variables is not
+// available, the button will be hidden.
+#ifndef VARIABLES_NOHELPER
+__inline static int variables_skin_helpbutton(HWND hwndDlg, UINT uIDButton) {
+
+ int res;
+ HICON hIcon;
+ TCHAR tszClass[32];
+
+ hIcon = NULL;
+ res = 0;
+ if (ServiceExists(MS_VARS_GETSKINITEM))
+ hIcon = (HICON)CallService(MS_VARS_GETSKINITEM, 0, (LPARAM)VSI_HELPICON);
+
+ GetClassName(GetDlgItem(hwndDlg, uIDButton), tszClass, SIZEOF(tszClass));
+ if (!_tcscmp(tszClass, _T("Button"))) {
+ if (hIcon != NULL) {
+ SetWindowLongPtr(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE)|BS_ICON);
+ SendMessage(GetDlgItem(hwndDlg, uIDButton), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon);
+ }
+ else {
+ SetWindowLongPtr(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE)&~BS_ICON);
+ SetDlgItemText(hwndDlg, uIDButton, _T("V"));
+ }
+ }
+ else if (!_tcscmp(tszClass, MIRANDABUTTONCLASS)) {
+ if (hIcon != NULL) {
+ char *szTipInfo = NULL;
+
+ SendMessage(GetDlgItem(hwndDlg, uIDButton), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon);
+ if (ServiceExists(MS_VARS_GETSKINITEM))
+ szTipInfo = (char *)CallService(MS_VARS_GETSKINITEM, 0, (LPARAM)VSI_HELPTIPTEXT);
+
+ if (szTipInfo == NULL)
+ szTipInfo = Translate("Open String Formatting Help");
+
+ SendMessage(GetDlgItem(hwndDlg, uIDButton), BUTTONADDTOOLTIP, (WPARAM)szTipInfo, 0);
+ SendDlgItemMessage(hwndDlg, uIDButton, BUTTONSETASFLATBTN, 0, 0);
+ }
+ else SetDlgItemText(hwndDlg, uIDButton, _T("V"));
+ }
+ else res = -1;
+
+ ShowWindow(GetDlgItem(hwndDlg, uIDButton), ServiceExists(MS_VARS_FORMATSTRING));
+
+ return res;
+}
+#endif
+
+
+#define MS_VARS_SHOWHELP "Vars/ShowHelp"
+
+// WARNING: This service is obsolete, please use MS_VARS_SHOWHELPEX
+
+// Shows a help dialog where all possible tokens are displayed. The tokens
+// are explained on the dialog, too. The user can edit the initial string and
+// insert as many tokens as he likes.
+
+// Parameters:
+// ------------------------
+// wParam = (HWND)hwndEdit
+// Handle to an edit control in which the modified string
+// should be inserted (When the user clicks OK in the dialog the edited
+// string will be set to hwndEdit) (can be NULL).
+// lParam = (char *)pszInitialString
+// String that the user is provided with initially when
+// the dialog gets opened (If this is NULL then the current text in the
+// hwndEdit edit control will be used) (can be NULL).
+
+// Return Value:
+// ------------------------
+// Returns the handle to the help dialog (HWND).
+
+// Note: Only one help dialog can be opened at a time. When the dialog gets
+// closed an EN_CHANGE of the edit controll will be triggered because the
+// contents were updated. (Only when user selected OK).
+
+// Example:
+// CallService(MS_VARS_SHOWHELP, (WPARAM)hwndEdit, (LPARAM)"some initial text");
+
+// --------------------------------------------------------------------------
+// Retrieve a contact's HANDLE given a string
+// --------------------------------------------------------------------------
+
+#define MS_VARS_GETCONTACTFROMSTRING "Vars/GetContactFromString"
+
+// Searching for contacts in the database. You can find contacts in db by
+// searching for their name, e.g first name.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(CONTACTSINFO *)&ci
+// See below.
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Returns number of contacts found matching the given string representation.
+// The hContacts array of CONTACTSINFO struct contains these hContacts after
+// the call.
+
+// Note: The hContacts array needs to be freed after use using
+// MS_VARS_FREEMEMORY.
+
+typedef struct {
+ int cbSize; // Set this to sizeof(CONTACTSINFO).
+ union {
+ char *szContact; // String to search for, e.g. last name (can't be NULL).
+ WCHAR *wszContact;
+ TCHAR *tszContact;
+ };
+ HANDLE *hContacts; // (output) Array of contacts found.
+ DWORD flags; // Contact details that will be matched with the search
+ // string (flags can be combined).
+} CONTACTSINFO;
+
+// Possible flags:
+#define CI_PROTOID 0x00000001 // The contact in the string is encoded
+ // in the format <PROTOID:UNIQUEID>, e.g.
+ // <ICQ:12345678>.
+#define CI_NICK 0x00000002 // Search nick names.
+#define CI_LISTNAME 0x00000004 // Search custom names shown in contact
+ // list.
+#define CI_FIRSTNAME 0x00000008 // Search contact's first names (contact
+ // details).
+#define CI_LASTNAME 0x00000010 // Search contact's last names (contact
+ // details).
+#define CI_EMAIL 0x00000020 // Search contact's email adresses
+ // (contact details).
+#define CI_UNIQUEID 0x00000040 // Search unique ids of the contac, e.g.
+ // UIN.
+#define CI_CNFINFO 0x40000000 // Searches one of the CNF_* flags (set
+ // flags to CI_CNFINFO|CNF_X), only one
+ // CNF_ type possible
+#define CI_UNICODE 0x80000000 // tszContact is a unicode string
+ // (WCHAR*).
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define CI_TCHAR CI_UNICODE // Strings in structure are TCHAR*.
+#else
+#define CI_TCHAR 0
+#endif
+
+
+
+#endif //__M_VARS
diff --git a/plugins/folders/folders/services.cpp b/plugins/folders/folders/services.cpp
new file mode 100644
index 0000000000..5fa423aab7
--- /dev/null
+++ b/plugins/folders/folders/services.cpp
@@ -0,0 +1,242 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "services.h"
+
+#define DEFAULT_SECTION "Unknown"
+
+char szCurrentProfilePath[MAX_FOLDERS_PATH] = {0};
+char szCurrentProfile[MAX_FOLDERS_PATH] = {0};
+char szMirandaPath[MAX_FOLDERS_PATH] = {0};
+char szUserDataPath[MAX_FOLDERS_PATH] = {0};
+
+wchar_t szCurrentProfilePathW[MAX_FOLDERS_PATH] = {0};
+wchar_t szCurrentProfileW[MAX_FOLDERS_PATH] = {0};
+wchar_t szMirandaPathW[MAX_FOLDERS_PATH] = {0};
+wchar_t szUserDataPathW[MAX_FOLDERS_PATH] = {0};
+
+HANDLE hsFoldersGetPath;
+HANDLE hsFoldersGetSize;
+HANDLE hsFoldersGetPathAlloc;
+HANDLE hsFoldersRegisterPath;
+
+int InitServices()
+{
+ ServiceExists(MS_DB_GETPROFILEPATH_BASIC) ? CallService(MS_DB_GETPROFILEPATH_BASIC, sizeof(szCurrentProfilePath), (LPARAM) szCurrentProfilePath) : CallService(MS_DB_GETPROFILEPATH, sizeof(szCurrentProfilePath), (LPARAM) szCurrentProfilePath);
+ CallService(MS_DB_GETPROFILENAME, sizeof(szCurrentProfile), (LPARAM) szCurrentProfile);
+ char *pos = strrchr(szCurrentProfile, '.');
+ szCurrentProfile[pos - szCurrentProfile] = '\0'; //remove the extension (.dat)
+ GetModuleFileNameA(GetModuleHandleA(NULL), szMirandaPath, sizeof(szMirandaPath));
+ pos = strrchr(szMirandaPath, '\\');
+ szMirandaPath[pos - szMirandaPath] = '\0'; //remove '\miranda32.exe'
+
+ char *szTemp = Utils_ReplaceVars("%miranda_userdata%");
+ mir_snprintf(szUserDataPath, MAX_FOLDERS_PATH, szTemp);
+ mir_free(szTemp);
+
+ MultiByteToWideChar(CP_ACP, 0, szCurrentProfilePath, -1, szCurrentProfilePathW, MAX_FOLDERS_PATH);
+ MultiByteToWideChar(CP_ACP, 0, szCurrentProfile, -1, szCurrentProfileW, MAX_FOLDERS_PATH);
+ MultiByteToWideChar(CP_ACP, 0, szMirandaPath, -1, szMirandaPathW, MAX_FOLDERS_PATH);
+ MultiByteToWideChar(CP_ACP, 0, szUserDataPath, -1, szUserDataPathW, MAX_FOLDERS_PATH);
+
+ hsFoldersGetPath = CreateServiceFunction(MS_FOLDERS_GET_PATH, GetPathService);
+// CreateServiceFunction(MS_FOLDERS_GET_PATH_APPEND, GetPathAppendService);
+ hsFoldersGetSize = CreateServiceFunction(MS_FOLDERS_GET_SIZE, GetPathSizeService);
+ hsFoldersGetPathAlloc = CreateServiceFunction(MS_FOLDERS_GET_PATH_ALLOC, GetPathAllocService);
+// CreateServiceFunction(MS_FOLDERS_GET_PATH_ALLOC_APPEND, GetPathAllocAppendService);
+ hsFoldersRegisterPath = CreateServiceFunction(MS_FOLDERS_REGISTER_PATH, RegisterPathService);
+
+ return 0;
+}
+
+int DestroyServices()
+{
+ DestroyServiceFunction(hsFoldersGetPath);
+// DestroyServiceFunction(MS_FOLDERS_GET_PATH_APPEND);
+ DestroyServiceFunction(hsFoldersGetSize);
+ DestroyServiceFunction(hsFoldersGetPathAlloc);
+// DestroyServiceFunction(MS_FOLDERS_GET_PATH_ALLOC_APPEND);
+ DestroyServiceFunction(hsFoldersRegisterPath);
+ return 0;
+}
+
+INT_PTR ExpandPath(char *szResult, char *format, int size)
+{
+ szResult[0] = '\0';
+ char *input = NULL;
+
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ {
+ char *vars_result = variables_parse_char(format, NULL, NULL);
+
+ if (vars_result != NULL)
+ {
+ input = _strdup(vars_result);
+
+ variables_free(vars_result);
+ }
+ }
+
+ if (input == NULL)
+ {
+ input = _strdup(format);
+ }
+
+ char *core_result = Utils_ReplaceVars(input);
+ strncpy(szResult, core_result, size);
+
+ mir_free(core_result);
+
+ StrReplace(szResult, PROFILE_PATH, szCurrentProfilePath);
+ StrReplace(szResult, CURRENT_PROFILE, szCurrentProfile);
+ StrReplace(szResult, MIRANDA_PATH, szMirandaPath);
+ StrReplace(szResult, MIRANDA_USERDATA, szUserDataPath);
+
+ StrTrim(szResult, "\t \\");
+
+ free(input);
+
+ return strlen(szResult);
+}
+
+INT_PTR ExpandPathW(wchar_t *szResult, wchar_t *format, int size)
+{
+ szResult[0] = '\0';
+ wchar_t *input = NULL;
+
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ {
+ wchar_t *vars_result = variables_parse_wchar(format, NULL, NULL);
+
+ if (vars_result != NULL)
+ {
+ input = _wcsdup(vars_result);
+
+ variables_free(vars_result);
+ }
+ }
+
+ if (input == NULL)
+ {
+ input = _wcsdup(format);
+ }
+
+ wchar_t *core_result = Utils_ReplaceVarsW(input);
+ if (core_result)
+ {
+ wcsncpy(szResult, core_result, size);
+ }
+ else {
+ wcsncpy(szResult, input, size);
+ }
+
+ mir_free(core_result);
+
+ StrReplace(szResult, PROFILE_PATHW, szCurrentProfilePathW);
+ StrReplace(szResult, CURRENT_PROFILEW, szCurrentProfileW);
+ StrReplace(szResult, MIRANDA_PATHW, szMirandaPathW);
+ StrReplace(szResult, MIRANDA_USERDATAW, szUserDataPathW);
+
+ StrTrim(szResult, L"\t \\");
+
+ free(input);
+
+ return wcslen(szResult);
+}
+
+INT_PTR GetPath(int hRegisteredFolder, char *szResult, int size)
+{
+ return lstRegisteredFolders.Expand(hRegisteredFolder, szResult, size);
+ //return 0;
+}
+
+INT_PTR RegisterPathService(WPARAM wParam, LPARAM lParam)
+{
+ FOLDERSDATA tmp = *(FOLDERSDATA *) lParam;
+ int res = 0;
+ if (tmp.cbSize == sizeof(FOLDERSDATA))
+ {
+ res = lstRegisteredFolders.Add(tmp); //returns 1..n or 0 on error
+ }
+ return res;
+}
+
+INT_PTR GetPathSizeService(WPARAM wParam, LPARAM lParam)
+{
+ char tmp[MAX_FOLDER_SIZE * 4]; //dumb
+ int res = lstRegisteredFolders.Expand(wParam, tmp, sizeof(tmp));
+ size_t len = 0;
+ if ((lstRegisteredFolders.Get(wParam)) && (lstRegisteredFolders.Get(wParam)->IsUnicode()))
+ {
+ len = wcslen((wchar_t *)tmp);
+ }
+ else{
+ len = strlen(tmp);
+ }
+ if (lParam != NULL)
+ {
+ *((size_t *) lParam) = len;
+ }
+ return len;
+}
+
+INT_PTR GetPathService(WPARAM wParam, LPARAM lParam)
+{
+ FOLDERSGETDATA data = *(FOLDERSGETDATA *) lParam;
+ size_t res = 1;
+ if (data.cbSize == sizeof(FOLDERSGETDATA))
+ {
+ res = GetPath(wParam, data.szPath, data.nMaxPathSize); //dumb ...
+ }
+ return res;
+}
+
+INT_PTR GetPathAllocService(WPARAM wParam, LPARAM lParam)
+{
+ int size;
+ int res = 1;
+ FOLDERSGETALLOCDATA data = *(FOLDERSGETALLOCDATA *) lParam;
+ if (data.cbSize == sizeof(FOLDERSGETALLOCDATA))
+ {
+ size = GetPathSizeService(wParam, (LPARAM) &size);
+ char **buffer = data.szPath;
+ *buffer = (char *) mir_alloc(size + 1);
+ res = GetPath(wParam, *buffer, size);
+ }
+ return res;
+}
+/*
+int GetPathAppendService(WPARAM wParam, LPARAM lParam)
+{
+ FOLDERSAPPENDDATA data = *(FOLDERSAPPENDDATA *) wParam;
+ int res = GetPathService(data.hRegisteredPath, lParam);
+ strcat((char *) lParam, data.szAppendData);
+ return res;
+}
+*/
+/*
+int GetPathAllocAppendService(WPARAM wParam, LPARAM lParam)
+{
+ FOLDERSAPPENDDATA data = *(FOLDERSAPPENDDATA *) wParam;
+ int res = GetPathAllocService(data.hRegisteredPath, lParam);
+ strcat(*(char **) lParam, data.szAppendData);
+ return res;
+}
+*/ \ No newline at end of file
diff --git a/plugins/folders/folders/services.h b/plugins/folders/folders/services.h
new file mode 100644
index 0000000000..3a2ee1aa9f
--- /dev/null
+++ b/plugins/folders/folders/services.h
@@ -0,0 +1,50 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_FOLDERS_PROVIDED_SERVICES_H
+#define M_FOLDERS_PROVIDED_SERVICES_H
+
+#include "commonheaders.h"
+#include "m_folders.h"
+
+#define MAX_FOLDERS_PATH 512
+
+extern char szCurrentProfilePath[MAX_FOLDERS_PATH];
+extern char szCurrentProfile[MAX_FOLDERS_PATH];
+extern char szMirandaPath[MAX_FOLDERS_PATH];
+
+extern wchar_t szCurrentProfilePathW[MAX_FOLDERS_PATH];
+extern wchar_t szCurrentProfileW[MAX_FOLDERS_PATH];
+extern wchar_t szMirandaPathW[MAX_FOLDERS_PATH];
+
+int InitServices();
+int DestroyServices();
+INT_PTR ExpandPath(char *szResult, char *format, int size);
+INT_PTR ExpandPathW(wchar_t *szResult, wchar_t *format, int size);
+INT_PTR GetPath(int hRegisteredFolder, char *szResult, int size);
+
+INT_PTR RegisterPathService(WPARAM wParam, LPARAM lParam);
+INT_PTR GetPathSizeService(WPARAM wParam, LPARAM lParam);
+INT_PTR GetPathService(WPARAM wParam, LPARAM lParam);
+INT_PTR GetPathAllocService(WPARAM wParam, LPARAM lParam);
+//int GetPathAppendService(WPARAM wParam, LPARAM lParam);
+//int GetPathAllocAppendService(WPARAM wParam, LPARAM lParam);
+
+#endif //M_FOLDERS_PROVIDED_SERVICES_H \ No newline at end of file
diff --git a/plugins/folders/folders/utils.cpp b/plugins/folders/folders/utils.cpp
new file mode 100644
index 0000000000..64623b63f1
--- /dev/null
+++ b/plugins/folders/folders/utils.cpp
@@ -0,0 +1,357 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "utils.h"
+
+int Log(char *format, ...)
+{
+#ifdef _DEBUG
+ char str[4096];
+ va_list vararg;
+ int tBytes;
+ FILE *fout = fopen("folders.log", "at");
+
+ va_start(vararg, format);
+
+ tBytes = _vsnprintf(str, sizeof(str), format, vararg);
+ if (tBytes > 0)
+ {
+ str[tBytes] = 0;
+ }
+
+ va_end(vararg);
+ if (str[strlen(str) - 1] != '\n')
+ {
+ strcat(str, "\n");
+ }
+ fputs(str, fout);
+ fclose(fout);
+#endif
+ return 0;
+}
+
+char *StrCopy(char *source, size_t index, const char *what, size_t count)
+{
+ size_t i;
+ for (i = 0; i < count; i++)
+ {
+ source[index + i] = what[i];
+ }
+ return source;
+}
+
+wchar_t *StrCopy(wchar_t *source, size_t index, const wchar_t *what, size_t count)
+{
+ size_t i;
+ for (i = 0; i < count; i++)
+ {
+ source[index + i] = what[i];
+ }
+ return source;
+}
+
+char *StrDelete(char *source, size_t index, size_t count)
+{
+ size_t len = strlen(source);
+ size_t i;
+ count = (count + index > len) ? len - index : count;
+ for (i = index; i + count <= len; i++)
+ {
+ source[i] = source[i + count];
+ }
+ return source;
+}
+
+wchar_t *StrDelete(wchar_t *source, size_t index, size_t count)
+{
+ size_t len = wcslen(source);
+ size_t i;
+ count = (count + index > len) ? len - index : count;
+ for (i = index; i + count <= len; i++)
+ {
+ source[i] = source[i + count];
+ }
+ return source;
+}
+
+
+char *StrInsert(char *source, size_t index, const char *what)
+{
+ size_t whatLen = strlen(what);
+ size_t sourceLen = strlen(source);
+ size_t i;
+ for (i = sourceLen; i >= index; i--)
+ {
+ source[i + whatLen] = source[i];
+ }
+ for (i = 0; i < whatLen; i++)
+ {
+ source[index + i] = what[i];
+ }
+ return source;
+}
+
+wchar_t *StrInsert(wchar_t *source, size_t index, const wchar_t *what)
+{
+ size_t whatLen = wcslen(what);
+ size_t sourceLen = wcslen(source);
+ size_t i;
+ for (i = sourceLen; i >= index; i--)
+ {
+ source[i + whatLen] = source[i];
+ }
+ for (i = 0; i < whatLen; i++)
+ {
+ source[index + i] = what[i];
+ }
+ return source;
+}
+
+
+char *StrReplace(char *source, const char *what, const char *withWhat)
+{
+ char *pos;
+ size_t whatLen = strlen(what);
+ size_t withWhatLen = strlen(withWhat);
+ size_t minLen;
+ size_t index;
+
+ while ((pos = strstr(source, what)))
+ {
+ minLen = min(whatLen, withWhatLen);
+ StrCopy(source, pos - source, withWhat, minLen);
+ index = pos - source + minLen;
+ if (whatLen > withWhatLen)
+ {
+ StrDelete(source, index, whatLen - withWhatLen);
+ }
+ else{
+ if (whatLen < withWhatLen)
+ {
+ StrInsert(source, index, withWhat + minLen);
+ }
+ }
+ }
+ return source;
+}
+
+wchar_t *StrReplace(wchar_t *source, const wchar_t *what, const wchar_t *withWhat)
+{
+ wchar_t *pos;
+ size_t whatLen = wcslen(what);
+ size_t withWhatLen = wcslen(withWhat);
+ size_t minLen;
+ size_t index;
+
+ while ((pos = wcsstr(source, what)))
+ {
+ minLen = min(whatLen, withWhatLen);
+ StrCopy(source, pos - source, withWhat, minLen);
+ index = pos - source + minLen;
+ if (whatLen > withWhatLen)
+ {
+ StrDelete(source, index, whatLen - withWhatLen);
+ }
+ else{
+ if (whatLen < withWhatLen)
+ {
+ StrInsert(source, index, withWhat + minLen);
+ }
+ }
+ }
+ return source;
+}
+
+char *StrTrim(char *szText, const char *szTrimChars)
+{
+ size_t i = strlen(szText) - 1;
+ while ((i >= 0) && (strchr(szTrimChars, szText[i])))
+ {
+ szText[i--] = '\0';
+ }
+ i = 0;
+ while ((i < strlen(szText)) && (strchr(szTrimChars, szText[i])))
+ {
+ i++;
+ }
+ if (i)
+ {
+ StrDelete(szText, 0, i);
+ }
+ return szText;
+}
+
+wchar_t *StrTrim(wchar_t *szText, const wchar_t *szTrimChars)
+{
+ size_t i = wcslen(szText) - 1;
+ while ((i >= 0) && (wcschr(szTrimChars, szText[i])))
+ {
+ szText[i--] = '\0';
+ }
+ i = 0;
+ while ((i < wcslen(szText)) && (wcschr(szTrimChars, szText[i])))
+ {
+ i++;
+ }
+ if (i)
+ {
+ StrDelete(szText, 0, i);
+ }
+ return szText;
+}
+
+void CreateDirectories(char *path)
+{
+ char *pos = path;
+ char tmp;
+ while (pos = strchr(pos, '\\'))
+ {
+ tmp = pos[0];
+ pos[0] = '\0';
+ CreateDirectoryA(path, NULL);
+ pos[0] = tmp;
+ pos++;
+ }
+ CreateDirectoryA(path, NULL);
+ GetLastError();
+}
+
+void CreateDirectories(wchar_t *path)
+{
+ wchar_t *pos = path;
+ wchar_t tmp;
+ while (pos = wcschr(pos, '\\'))
+ {
+ tmp = pos[0];
+ pos[0] = '\0';
+ CreateDirectoryW(path, NULL);
+ pos[0] = tmp;
+ pos++;
+ }
+ CreateDirectoryW(path, NULL);
+ GetLastError();
+}
+
+void RemoveDirectories(char *path)
+{
+ char *pos;
+ char *buffer = _strdup(path);
+ if (!(GetFileAttributesA(buffer) & FILE_ATTRIBUTE_REPARSE_POINT)) { RemoveDirectoryA(buffer); }
+ while (pos = strrchr(buffer, '\\'))
+ {
+ pos[0] = '\0';
+ if (!(GetFileAttributesA(buffer) & FILE_ATTRIBUTE_REPARSE_POINT)) { RemoveDirectoryA(buffer); }
+ }
+ free(buffer);
+}
+
+void RemoveDirectories(wchar_t *path)
+{
+ wchar_t *pos;
+ wchar_t *buffer = _wcsdup(path);
+ if (!(GetFileAttributesW(buffer) & FILE_ATTRIBUTE_REPARSE_POINT)) { RemoveDirectoryW(buffer); }
+ while (pos = wcsrchr(buffer, '\\'))
+ {
+ pos[0] = '\0';
+ if (!(GetFileAttributesW(buffer) & FILE_ATTRIBUTE_REPARSE_POINT)) { RemoveDirectoryW(buffer); }
+ }
+ free(buffer);
+}
+
+int DirectoryExists(char *path)
+{
+ char buffer[4096];
+ GetCurrentDirectoryA(sizeof(buffer), buffer);
+ int res = SetCurrentDirectoryA(path);
+ SetCurrentDirectoryA(buffer);
+ return res;
+}
+
+int DirectoryExists(wchar_t *path)
+{
+ wchar_t buffer[4096];
+ GetCurrentDirectoryW(sizeof(buffer), buffer);
+ int res = SetCurrentDirectoryW(path);
+ SetCurrentDirectoryW(buffer);
+ return res;
+}
+
+
+int GetStringFromDatabase(char *szSettingName, const char *szError, char *szResult, size_t size)
+{
+ DBVARIANT dbv = {0};
+ int res = 1;
+ size_t len;
+ dbv.type = DBVT_ASCIIZ;
+ if (DBGetContactSetting(NULL, ModuleName, szSettingName, &dbv) == 0)
+ {
+ res = 0;
+ size_t tmp = strlen(dbv.pszVal);
+ len = (tmp < size - 1) ? tmp : size - 1;
+ strncpy(szResult, dbv.pszVal, len);
+ szResult[len] = '\0';
+ mir_free(dbv.pszVal);
+ }
+ else{
+ res = 1;
+ size_t tmp = strlen(szError);
+ len = (tmp < size - 1) ? tmp : size - 1;
+ strncpy(szResult, szError, len);
+ szResult[len] = '\0';
+ }
+ return res;
+}
+
+int GetStringFromDatabase(char *szSettingName, const wchar_t *szError, wchar_t *szResult, size_t size)
+{
+ DBVARIANT dbv = {0};
+ int res = 1;
+ size_t len;
+ dbv.type = DBVT_WCHAR;
+ if (DBGetContactSettingWString(NULL, ModuleName, szSettingName, &dbv) == 0)
+ //if (DBGetContactSetting(NULL, ModuleName, szSettingName, &dbv) == 0)
+ {
+ res = 0;
+ size_t tmp = wcslen(dbv.pwszVal);
+ len = (tmp < size - 1) ? tmp : size - 1;
+ wcsncpy(szResult, dbv.pwszVal, len);
+ szResult[len] = '\0';
+ mir_free(dbv.pwszVal);
+ }
+ else{
+ res = 1;
+ size_t tmp = wcslen(szError);
+ len = (tmp < size - 1) ? tmp : size - 1;
+ wcsncpy(szResult, szError, len);
+ szResult[len] = '\0';
+ }
+ return res;
+}
+
+
+int WriteStringToDatabase(char *szSettingName, const char *szValue)
+{
+ return DBWriteContactSettingString(NULL, ModuleName, szSettingName, szValue);
+}
+
+int WriteStringToDatabase(char *szSettingName, const wchar_t *szValue)
+{
+ return DBWriteContactSettingWString(NULL, ModuleName, szSettingName, szValue);
+} \ No newline at end of file
diff --git a/plugins/folders/folders/utils.h b/plugins/folders/folders/utils.h
new file mode 100644
index 0000000000..066c822900
--- /dev/null
+++ b/plugins/folders/folders/utils.h
@@ -0,0 +1,62 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_FOLDERS_UTILS_H
+#define M_FOLDERS_UTILS_H
+
+#include <stdarg.h>
+#include "commonheaders.h"
+
+int Log(char *format, ...);
+
+char *StrReplace(char *source, const char *what, const char *withWhat);
+char *StrCopy(char *source, size_t index, const char *what, size_t count);
+char *StrDelete(char *source, size_t index, size_t count);
+char *StrInsert(char *source, size_t index, const char *what);
+char *StrTrim(char *szText, const char *szTrimChars);
+
+wchar_t *StrReplace(wchar_t *source, const wchar_t *what, const wchar_t *withWhat);
+wchar_t *StrCopy(wchar_t *source, size_t index, const wchar_t *what, size_t count);
+wchar_t *StrDelete(wchar_t *source, size_t index, size_t count);
+wchar_t *StrInsert(wchar_t *source, size_t index, const wchar_t *what);
+wchar_t *StrTrim(wchar_t *szText, const wchar_t *szTrimChars);
+
+void CreateDirectories(char *szPath);
+void RemoveDirectories(char *szPath);
+int DirectoryExists(char *szPath);
+
+void CreateDirectories(wchar_t *szPath);
+void RemoveDirectories(wchar_t *szPath);
+int DirectoryExists(wchar_t *szPath);
+
+int GetStringFromDatabase(char *szSettingName, const char *szError, char *szResult, size_t size);
+int WriteStringToDatabase(char *szSettingName, const char *szValue);
+
+int GetStringFromDatabase(char *szSettingName, const wchar_t *szError, wchar_t *szResult, size_t size);
+int WriteStringToDatabase(char *szSettingName, const wchar_t *szValue);
+
+__inline static wchar_t *Utils_ReplaceVarsW(wchar_t *szData) {
+ REPLACEVARSDATA dat = {0};
+ dat.cbSize = sizeof(dat);
+ dat.dwFlags = RVF_UNICODE;
+ return (wchar_t *) CallService(MS_UTILS_REPLACEVARS, (WPARAM) szData, (LPARAM) &dat);
+}
+
+#endif \ No newline at end of file
diff --git a/plugins/folders/folders/variablesHelp.inc b/plugins/folders/folders/variablesHelp.inc
new file mode 100644
index 0000000000..bdc79692e6
--- /dev/null
+++ b/plugins/folders/folders/variablesHelp.inc
@@ -0,0 +1,32 @@
+"{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033\\deflangfe1033{\\fonttbl{\\f0\\fswiss\\fprq2\\fcharset0 Arial;}}\n"
+"{\\*\\generator Msftedit 5.41.21.2500;}\\viewkind4\\uc1\\pard\\nowidctlpar\\ri-1686\\f0\\fs20 Don't forget to click on \\i Apply\\i0 to save the changes. If you don't then the changes won't\n"
+"be saved to the database, they will only be valid for this session.\\par"
+"\\pard\\nowidctlpar\\ul\\b\\par\n"
+"Variable string\\ulnone\\b0\\tab\\tab\\ul\\b What it expands to:\\ulnone\\b0\\par\n"
+"%miranda_userdata%\\tab Expands to the private profile data directory.\\par"
+"%miranda_path%\\tab Expands to your miranda path (e.g: c:\\\\program files\\\\miranda im).\\par"
+"%profile_path%\\tab\\tab Expands to your profile path - the value found in mirandaboot.ini,\\par"
+"\\tab\\tab\\tab\\ul ProfileDir\\ulnone section (usually inside miranda's folder).\\par"
+"\\pard\\nowidctlpar\\ri-696 %current_profile%\\tab Expands to your current profile name without the extenstion.\\par"
+"\\tab\\tab\\tab (e.g.\\b default\\b0 if your your profile is \\i default.dat\\i0 ).\\par"
+"\\par\n"
+"\\ul\\b Environment variables\\par\n"
+"\\ulnone\\b0 The plugin can also expand environment variables; the variables are specified like in any other\n"
+"program that can use environment variables, i.e. %<env variable>%.\n\n"
+"\\b Note\\b0 : Environment variables are expanded before any Miranda variables. So if you have, for\n"
+"example, %profile_path% defined as a system variable then it will be expanded to that value\\n"
+"instead of expanding to Miranda\\rquote s profile path.\\par\n"
+"\\ul\\b Examples:\\par\n"
+"\\ulnone\\b0 If the value for the ProfileDir inside \\i mirandaboot.ini\\i0 , \\ul ProfileDir\\ulnone section is '.\\\\profiles', current\n"
+"profile is 'default.dat' and miranda's path is 'c:\\\\program files\\\\miranda im' then:\\par\n"
+"\\b %miranda_path%\\b0 \\tab\\tab\\tab will expand to 'c:\\\\program files\\\\miranda im'\\par"
+"\\b %profile_path%\\b0 \\tab\\tab\\tab will expand to 'c:\\\\program files\\\\miranda im\\\\profiles'\\par"
+"\\b %current_profile%\\b0\\tab\\tab\\tab will expand to 'default'\\par"
+"\\b %temp%\\b0\\tab\\tab\\tab\\tab will expand to the temp folder of the current user.\\par"
+"\\b %profile_path%\\\\%current_profile%\\tab\\b0 will expand to 'c:\\\\program files\\\\miranda im\\\\profiles\\\\default'\\par"
+"\\b %miranda_path%\\\\plugins\\\\config\\b0\\tab will expand to 'c:\\\\program files\\\\miranda im\\\\plugins\\\\config'\\par"
+"\\b ' %miranda_path%\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ '\\b0\\tab will expand to 'c:\\\\program files\\\\miranda im'\\par\n"
+"notice that the spaces at the beginning and the end of the string are trimmed, as well as the last \\\\\\par\n"
+"}\n"
+"\n"
+"\n"
diff --git a/plugins/folders/folders/version.h b/plugins/folders/folders/version.h
new file mode 100644
index 0000000000..77f4d886fa
--- /dev/null
+++ b/plugins/folders/folders/version.h
@@ -0,0 +1,49 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005-2012 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_FOLDERS_VERSION_H
+#define M_FOLDERS_VERSION_H
+
+#define __MAJOR_VERSION 0
+#define __MINOR_VERSION 1
+#define __RELEASE_NUM 6
+#define __BUILD_NUM 0
+
+#define VERSION PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM)
+
+#define __PLUGINVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM
+#define __PLUGINVERSION_STRING_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM
+#define __STRINGIFY_(x) #x
+#define __STRINGIFY(x) __STRINGIFY_(x)
+#define __VERSION_STRING __STRINGIFY(__PLUGINVERSION_STRING_DOTS)
+
+#define __DESC "Service plugin. Allows plugins to save their data to user selected folders; supports variables."
+#define __AUTHOR "Cristian Libotean"
+#define __AUTHOREMAIL "eblis102@yahoo.com"
+#define __COPYRIGHT "© 2005-2012 Cristian Libotean"
+#define __AUTHORWEB "http://www.miranda-im.org/"
+
+#if defined(WIN64) || defined(_WIN64)
+#define __PLUGIN_DISPLAY_NAME "Custom profile folders (x64)"
+#else
+#define __PLUGIN_DISPLAY_NAME "Custom profile folders"
+#endif
+
+#endif //M_FOLDERS_VERSION_H
diff --git a/plugins/folders/folders/version.rc b/plugins/folders/folders/version.rc
new file mode 100644
index 0000000000..0f8fea03fc
--- /dev/null
+++ b/plugins/folders/folders/version.rc
@@ -0,0 +1,100 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+#include "version.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource1.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION __PLUGINVERSION_STRING
+ PRODUCTVERSION __PLUGINVERSION_STRING
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Author", __AUTHOR
+ VALUE "FileDescription", __DESC
+ VALUE "FileVersion", __VERSION_STRING
+ VALUE "InternalName", __PLUGIN_DISPLAY_NAME
+ VALUE "LegalCopyright", __COPYRIGHT
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/folders/pack source.bat b/plugins/folders/pack source.bat
new file mode 100644
index 0000000000..3c501be7dc
--- /dev/null
+++ b/plugins/folders/pack source.bat
@@ -0,0 +1,8 @@
+for /F "tokens=5-9* delims=. " %%i in (docs\folders_readme.txt) do (call :Pack %%i %%j %%k %%l; exit)
+
+:Pack
+d:\usr\7z\7za.exe a -i@files_source.txt -xr!*.zip -xr!*.ncb -xr!*.user -xr!*.sdf "Folders src %1.%2.%3.%4.zip" @files_source.txt
+exit
+
+error:
+echo "Error packing Folders"
diff --git a/plugins/folders/pack symbols.bat b/plugins/folders/pack symbols.bat
new file mode 100644
index 0000000000..49cdec46c7
--- /dev/null
+++ b/plugins/folders/pack symbols.bat
@@ -0,0 +1,9 @@
+@echo off
+if NOT EXIST "symbols\%1 - %3" (
+ mkdir "symbols\%1 - %3"
+)
+xcopy "%2\win32\Release\*.pdb" "symbols\%1 - %3\win32\*" /EXCLUDE:symbols_exclude.txt /Y
+xcopy "%2\x64\Release\*.pdb" "symbols\%1 - %3\x64\*" /EXCLUDE:symbols_exclude.txt /Y
+
+d:\usr\7z\7za.exe u -i!symbols\*.* "symbols - %1.zip"
+rmdir "symbols\" /Q /S \ No newline at end of file
diff --git a/plugins/folders/pack x64.bat b/plugins/folders/pack x64.bat
new file mode 100644
index 0000000000..befc247b4b
--- /dev/null
+++ b/plugins/folders/pack x64.bat
@@ -0,0 +1,13 @@
+copy folders\m_folders.h docs /y
+for /F "tokens=5-9* delims=. " %%i in (docs\folders_readme.txt) do (call :Pack %%i %%j %%k %%l; exit)
+
+:Pack
+xcopy folders\x64\release\folders.dll . /y
+xcopy folders\m_folders.h docs\m_folders.h /y
+d:\usr\7z\7za.exe a -i!docs\*.* -i!Folders.dll "Folders %1.%2.%3.%4 x64.zip"
+del folders.dll
+call "pack symbols.bat" Folders Folders %1.%2.%3.%4
+exit
+
+error:
+echo "Error packing Folders" \ No newline at end of file
diff --git a/plugins/folders/pack.bat b/plugins/folders/pack.bat
new file mode 100644
index 0000000000..a0bb14ed37
--- /dev/null
+++ b/plugins/folders/pack.bat
@@ -0,0 +1,13 @@
+copy folders\m_folders.h docs /y
+for /F "tokens=5-9* delims=. " %%i in (docs\folders_readme.txt) do (call :Pack %%i %%j %%k %%l; exit)
+
+:Pack
+xcopy folders\win32\release\folders.dll . /y
+xcopy folders\m_folders.h docs\m_folders.h /y
+d:\usr\7z\7za.exe a -i!docs\*.* -i!Folders.dll "Folders %1.%2.%3.%4 x32.zip"
+del folders.dll
+call "pack symbols.bat" Folders Folders %1.%2.%3.%4
+exit
+
+error:
+echo "Error packing Folders" \ No newline at end of file
diff --git a/plugins/folders/rtf convert.bat b/plugins/folders/rtf convert.bat
new file mode 100644
index 0000000000..6a301622ab
--- /dev/null
+++ b/plugins/folders/rtf convert.bat
@@ -0,0 +1 @@
+"rtf converter.exe" "variables help.doc" ".\folders\variablesHelp.inc" \ No newline at end of file
diff --git a/plugins/folders/rtf converter.exe b/plugins/folders/rtf converter.exe
new file mode 100644
index 0000000000..f932bbca43
--- /dev/null
+++ b/plugins/folders/rtf converter.exe
Binary files differ
diff --git a/plugins/folders/rtf converter/rtf converter.cpp b/plugins/folders/rtf converter/rtf converter.cpp
new file mode 100644
index 0000000000..8d51c0d79a
--- /dev/null
+++ b/plugins/folders/rtf converter/rtf converter.cpp
@@ -0,0 +1,103 @@
+#define _CRT_SECURE_NO_DEPRECATE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MAX_PATH 260
+#define DEFAULT_OUTPUT "output.inc"
+
+void PrintUsage(char *programPath)
+{
+ printf("Usage\n");
+ printf("%s input.doc [output.inc]\n", programPath);
+ printf("\nConverts a rtf text found in input.doc to a string that contains the rtf text and stores it in output.inc");
+}
+
+void Add(char *result, char *what)
+{
+ strcat(result, what);
+}
+
+void Add(char *result, char chr)
+{
+ int len = strlen(result);
+ result[len++] = chr;
+ result[len] = '\0';
+}
+
+void Convert(char *input, char *output)
+{
+ int len = strlen(input);
+ int i;
+ output[0] = '\0';
+ Add(output, '\"');
+ for (i = 0; i < len; i++)
+ {
+ switch (input[i])
+ {
+ case '\"':
+ Add(output, "\"\"");
+ break;
+ case '\\':
+ Add(output, "\\\\");
+ break;
+ case '\n':
+ Add(output, "\\n");
+ break;
+ default:
+ Add(output, input[i]);
+ }
+ }
+ Add(output, "\"\n");
+}
+
+void DoConversion(char *inFile, char *outFile)
+{
+ FILE *fin = fopen(inFile, "rt");
+ FILE *fout = fopen(outFile, "wt");
+ char buffer[2048];
+ char out[4096];
+ if ((fin) && (fout))
+ {
+ while (!feof(fin))
+ {
+ fgets(buffer, sizeof(buffer), fin);
+ if (strlen(buffer) > 0)
+ {
+ Convert(buffer, out);
+ fputs(out, fout);
+ }
+ }
+ }
+ if (fin)
+ {
+ fclose(fin);
+ }
+ if (fout)
+ {
+ fclose(fout);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ char input[MAX_PATH];
+ char output[MAX_PATH];
+ if ((argc < 2) || (argc > 3))
+ {
+ PrintUsage(argv[0]);
+ return 0;
+ }
+ strcpy(input, argv[1]);
+ if (argc == 3)
+ {
+ strcpy(output, argv[2]);
+ }
+ else{
+ strcpy(output, DEFAULT_OUTPUT);
+ }
+ DoConversion(input, output);
+ return 0;
+}
+
diff --git a/plugins/folders/symbols_exclude.txt b/plugins/folders/symbols_exclude.txt
new file mode 100644
index 0000000000..361cf2448b
--- /dev/null
+++ b/plugins/folders/symbols_exclude.txt
@@ -0,0 +1 @@
+vc80.pdb \ No newline at end of file
diff --git a/plugins/folders/variables help.doc b/plugins/folders/variables help.doc
new file mode 100644
index 0000000000..5b9ba27a62
--- /dev/null
+++ b/plugins/folders/variables help.doc
Binary files differ