diff options
-rw-r--r-- | Plugins/utils/MemoryModule.c | 540 | ||||
-rw-r--r-- | Plugins/utils/MemoryModule.h | 48 | ||||
-rw-r--r-- | Plugins/utils/mir_dblists.cpp | 149 | ||||
-rw-r--r-- | Plugins/utils/mir_dblists.h | 62 | ||||
-rw-r--r-- | Plugins/utils/mir_dbutils.h | 70 | ||||
-rw-r--r-- | Plugins/utils/mir_icons.cpp | 8 | ||||
-rw-r--r-- | Plugins/utils/mir_icons.h | 3 | ||||
-rw-r--r-- | Plugins/utils/mir_log.cpp | 2 | ||||
-rw-r--r-- | Plugins/utils/mir_log.h | 2 | ||||
-rw-r--r-- | Plugins/utils/mir_memory.h | 39 | ||||
-rw-r--r-- | Plugins/utils/mir_options.cpp | 183 | ||||
-rw-r--r-- | Plugins/utils/mir_options.h | 1 | ||||
-rw-r--r-- | Plugins/utils/mir_profiler.cpp | 178 | ||||
-rw-r--r-- | Plugins/utils/mir_profiler.h | 77 | ||||
-rw-r--r-- | Plugins/utils/mir_scope.h | 2 | ||||
-rw-r--r-- | Plugins/utils/mir_smileys.cpp | 53 | ||||
-rw-r--r-- | Plugins/utils/mir_smileys.h | 4 | ||||
-rw-r--r-- | Plugins/utils/templates.cpp | 476 | ||||
-rw-r--r-- | Plugins/utils/templates.h | 102 | ||||
-rw-r--r-- | Plugins/utils/utf8_helpers.h | 27 |
20 files changed, 1905 insertions, 121 deletions
diff --git a/Plugins/utils/MemoryModule.c b/Plugins/utils/MemoryModule.c new file mode 100644 index 0000000..1e7ac0a --- /dev/null +++ b/Plugins/utils/MemoryModule.c @@ -0,0 +1,540 @@ +/*
+ * Memory DLL loading code
+ * Version 0.0.2 with additions from Thomas Heller
+ *
+ * Copyright (c) 2004-2005 by Joachim Bauch / mail@joachim-bauch.de
+ * http://www.joachim-bauch.de
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is MemoryModule.c
+ *
+ * The Initial Developer of the Original Code is Joachim Bauch.
+ *
+ * Portions created by Joachim Bauch are Copyright (C) 2004-2005
+ * Joachim Bauch. All Rights Reserved.
+ *
+ * Portions Copyright (C) 2005 Thomas Heller.
+ *
+ */
+
+// disable warnings about pointer <-> DWORD conversions
+#pragma warning( disable : 4311 4312 )
+
+#include <Windows.h>
+#include <winnt.h>
+#ifdef DEBUG_OUTPUT
+#include <stdio.h>
+#endif
+
+#ifndef IMAGE_SIZEOF_BASE_RELOCATION
+// Vista SDKs no longer define IMAGE_SIZEOF_BASE_RELOCATION!?
+# define IMAGE_SIZEOF_BASE_RELOCATION (sizeof(IMAGE_BASE_RELOCATION))
+#endif
+#include "MemoryModule.h"
+
+
+struct NAME_TABLE {
+ char *name;
+ DWORD ordinal;
+};
+
+typedef struct tagMEMORYMODULE {
+ PIMAGE_NT_HEADERS headers;
+ unsigned char *codeBase;
+ HMODULE *modules;
+ int numModules;
+ int initialized;
+
+ struct NAME_TABLE *name_table;
+} MEMORYMODULE, *PMEMORYMODULE;
+
+typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
+
+#define GET_HEADER_DICTIONARY(module, idx) &(module)->headers->OptionalHeader.DataDirectory[idx]
+
+#ifdef DEBUG_OUTPUT
+static void
+OutputLastError(const char *msg)
+{
+ LPVOID tmp;
+ char *tmpmsg;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&tmp, 0, NULL);
+ tmpmsg = (char *)LocalAlloc(LPTR, strlen(msg) + strlen(tmp) + 3);
+ sprintf(tmpmsg, "%s: %s", msg, tmp);
+ OutputDebugString(tmpmsg);
+ LocalFree(tmpmsg);
+ LocalFree(tmp);
+}
+#endif
+
+static void
+CopySections(const unsigned char *data, PIMAGE_NT_HEADERS old_headers, PMEMORYMODULE module)
+{
+ int i, size;
+ unsigned char *codeBase = module->codeBase;
+ unsigned char *dest;
+ PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
+ for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++)
+ {
+ if (section->SizeOfRawData == 0)
+ {
+ // section doesn't contain data in the dll itself, but may define
+ // uninitialized data
+ size = old_headers->OptionalHeader.SectionAlignment;
+ if (size > 0)
+ {
+ dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress,
+ size,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+
+ section->Misc.PhysicalAddress = (DWORD)dest;
+ memset(dest, 0, size);
+ }
+
+ // section is empty
+ continue;
+ }
+
+ // commit memory block and copy data from dll
+ dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress,
+ section->SizeOfRawData,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+ memcpy(dest, data + section->PointerToRawData, section->SizeOfRawData);
+ section->Misc.PhysicalAddress = (DWORD)dest;
+ }
+}
+
+// Protection flags for memory pages (Executable, Readable, Writeable)
+static int ProtectionFlags[2][2][2] = {
+ {
+ // not executable
+ {PAGE_NOACCESS, PAGE_WRITECOPY},
+ {PAGE_READONLY, PAGE_READWRITE},
+ }, {
+ // executable
+ {PAGE_EXECUTE, PAGE_EXECUTE_WRITECOPY},
+ {PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE},
+ },
+};
+
+static void
+FinalizeSections(PMEMORYMODULE module)
+{
+ int i;
+ PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(module->headers);
+
+ // loop through all sections and change access flags
+ for (i=0; i<module->headers->FileHeader.NumberOfSections; i++, section++)
+ {
+ DWORD protect, oldProtect, size;
+ int executable = (section->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0;
+ int readable = (section->Characteristics & IMAGE_SCN_MEM_READ) != 0;
+ int writeable = (section->Characteristics & IMAGE_SCN_MEM_WRITE) != 0;
+
+ if (section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
+ {
+ // section is not needed any more and can safely be freed
+ VirtualFree((LPVOID)section->Misc.PhysicalAddress, section->SizeOfRawData, MEM_DECOMMIT);
+ continue;
+ }
+
+ // determine protection flags based on characteristics
+ protect = ProtectionFlags[executable][readable][writeable];
+ if (section->Characteristics & IMAGE_SCN_MEM_NOT_CACHED)
+ protect |= PAGE_NOCACHE;
+
+ // determine size of region
+ size = section->SizeOfRawData;
+ if (size == 0)
+ {
+ if (section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
+ size = module->headers->OptionalHeader.SizeOfInitializedData;
+ else if (section->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+ size = module->headers->OptionalHeader.SizeOfUninitializedData;
+ }
+
+ if (size > 0)
+ {
+ // change memory access flags
+ if (VirtualProtect((LPVOID)section->Misc.PhysicalAddress, size, protect, &oldProtect) == 0)
+#ifdef DEBUG_OUTPUT
+ OutputLastError("Error protecting memory page")
+#endif
+ ;
+ }
+ }
+}
+
+static void
+PerformBaseRelocation(PMEMORYMODULE module, DWORD delta)
+{
+ DWORD i;
+ unsigned char *codeBase = module->codeBase;
+
+ PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_BASERELOC);
+ if (directory->Size > 0)
+ {
+ PIMAGE_BASE_RELOCATION relocation = (PIMAGE_BASE_RELOCATION)(codeBase + directory->VirtualAddress);
+ for (; relocation->VirtualAddress > 0; )
+ {
+ unsigned char *dest = (unsigned char *)(codeBase + relocation->VirtualAddress);
+ unsigned short *relInfo = (unsigned short *)((unsigned char *)relocation + IMAGE_SIZEOF_BASE_RELOCATION);
+ for (i=0; i<((relocation->SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relInfo++)
+ {
+ DWORD *patchAddrHL;
+ int type, offset;
+
+ // the upper 4 bits define the type of relocation
+ type = *relInfo >> 12;
+ // the lower 12 bits define the offset
+ offset = *relInfo & 0xfff;
+
+ switch (type)
+ {
+ case IMAGE_REL_BASED_ABSOLUTE:
+ // skip relocation
+ break;
+
+ case IMAGE_REL_BASED_HIGHLOW:
+ // change complete 32 bit address
+ patchAddrHL = (DWORD *)(dest + offset);
+ *patchAddrHL += delta;
+ break;
+
+ default:
+ //printf("Unknown relocation: %d\n", type);
+ break;
+ }
+ }
+
+ // advance to next relocation block
+ relocation = (PIMAGE_BASE_RELOCATION)(((DWORD)relocation) + relocation->SizeOfBlock);
+ }
+ }
+}
+
+static int
+BuildImportTable(PMEMORYMODULE module)
+{
+ int result=1;
+ unsigned char *codeBase = module->codeBase;
+
+ PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT);
+ if (directory->Size > 0)
+ {
+ PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR)(codeBase + directory->VirtualAddress);
+ for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++)
+ {
+ DWORD *thunkRef, *funcRef;
+ HMODULE handle = LoadLibraryA((LPCSTR)(codeBase + importDesc->Name));
+ if (handle == INVALID_HANDLE_VALUE || handle == NULL)
+ {
+ //LastError should already be set
+#if DEBUG_OUTPUT
+ OutputLastError("Can't load library");
+#endif
+ result = 0;
+ break;
+ }
+
+ module->modules = (HMODULE *)realloc(module->modules, (module->numModules+1)*(sizeof(HMODULE)));
+ if (module->modules == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ result = 0;
+ break;
+ }
+
+ module->modules[module->numModules++] = handle;
+ if (importDesc->OriginalFirstThunk)
+ {
+ thunkRef = (DWORD *)(codeBase + importDesc->OriginalFirstThunk);
+ funcRef = (DWORD *)(codeBase + importDesc->FirstThunk);
+ } else {
+ // no hint table
+ thunkRef = (DWORD *)(codeBase + importDesc->FirstThunk);
+ funcRef = (DWORD *)(codeBase + importDesc->FirstThunk);
+ }
+ for (; *thunkRef; thunkRef++, funcRef++)
+ {
+ if IMAGE_SNAP_BY_ORDINAL(*thunkRef)
+ *funcRef = (DWORD)GetProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef));
+ else {
+ PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)(codeBase + *thunkRef);
+ *funcRef = (DWORD)GetProcAddress(handle, (LPCSTR)&thunkData->Name);
+ }
+ if (*funcRef == 0)
+ {
+ SetLastError(ERROR_PROC_NOT_FOUND);
+ result = 0;
+ break;
+ }
+ }
+
+ if (!result)
+ break;
+ }
+ }
+
+ return result;
+}
+
+HMEMORYMODULE MemoryLoadLibrary(const void *data)
+{
+ PMEMORYMODULE result;
+ PIMAGE_DOS_HEADER dos_header;
+ PIMAGE_NT_HEADERS old_header;
+ unsigned char *code, *headers;
+ DWORD locationDelta;
+ DllEntryProc DllEntry;
+ BOOL successfull;
+
+ dos_header = (PIMAGE_DOS_HEADER)data;
+ if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
+ {
+ SetLastError(ERROR_BAD_FORMAT);
+#if DEBUG_OUTPUT
+ OutputDebugString("Not a valid executable file.\n");
+#endif
+ return NULL;
+ }
+
+ old_header = (PIMAGE_NT_HEADERS)&((const unsigned char *)(data))[dos_header->e_lfanew];
+ if (old_header->Signature != IMAGE_NT_SIGNATURE)
+ {
+ SetLastError(ERROR_BAD_FORMAT);
+#if DEBUG_OUTPUT
+ OutputDebugString("No PE header found.\n");
+#endif
+ return NULL;
+ }
+
+ // reserve memory for image of library
+ code = (unsigned char *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase),
+ old_header->OptionalHeader.SizeOfImage,
+ MEM_RESERVE,
+ PAGE_READWRITE);
+
+ if (code == NULL)
+ // try to allocate memory at arbitrary position
+ code = (unsigned char *)VirtualAlloc(NULL,
+ old_header->OptionalHeader.SizeOfImage,
+ MEM_RESERVE,
+ PAGE_READWRITE);
+
+ if (code == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+#if DEBUG_OUTPUT
+ OutputLastError("Can't reserve memory");
+#endif
+ return NULL;
+ }
+
+ result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), 0, sizeof(MEMORYMODULE));
+ result->codeBase = code;
+ result->numModules = 0;
+ result->modules = NULL;
+ result->initialized = 0;
+ result->name_table = NULL;
+
+ // XXX: is it correct to commit the complete memory region at once?
+ // calling DllEntry raises an exception if we don't...
+ VirtualAlloc(code,
+ old_header->OptionalHeader.SizeOfImage,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+
+ // commit memory for headers
+ headers = (unsigned char *)VirtualAlloc(code,
+ old_header->OptionalHeader.SizeOfHeaders,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+
+ // copy PE header to code
+ memcpy(headers, dos_header, dos_header->e_lfanew + old_header->OptionalHeader.SizeOfHeaders);
+ result->headers = (PIMAGE_NT_HEADERS)&((const unsigned char *)(headers))[dos_header->e_lfanew];
+
+ // update position
+ result->headers->OptionalHeader.ImageBase = (DWORD)code;
+
+ // copy sections from DLL file block to new memory location
+ CopySections(data, old_header, result);
+
+ // adjust base address of imported data
+ locationDelta = (DWORD)(code - old_header->OptionalHeader.ImageBase);
+ if (locationDelta != 0)
+ PerformBaseRelocation(result, locationDelta);
+
+ // load required dlls and adjust function table of imports
+ if (!BuildImportTable(result))
+ goto error;
+
+ // mark memory pages depending on section headers and release
+ // sections that are marked as "discardable"
+ FinalizeSections(result);
+
+ // get entry point of loaded library
+ if (result->headers->OptionalHeader.AddressOfEntryPoint != 0)
+ {
+ DllEntry = (DllEntryProc)(code + result->headers->OptionalHeader.AddressOfEntryPoint);
+ if (DllEntry == 0)
+ {
+ SetLastError(ERROR_BAD_FORMAT); /* XXX ? */
+#if DEBUG_OUTPUT
+ OutputDebugString("Library has no entry point.\n");
+#endif
+ goto error;
+ }
+
+ // notify library about attaching to process
+ successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0);
+ if (!successfull)
+ {
+#if DEBUG_OUTPUT
+ OutputDebugString("Can't attach library.\n");
+#endif
+ goto error;
+ }
+ result->initialized = 1;
+ }
+
+ return (HMEMORYMODULE)result;
+
+error:
+ // cleanup
+ MemoryFreeLibrary(result);
+ return NULL;
+}
+
+int _compare(const struct NAME_TABLE *p1, const struct NAME_TABLE *p2)
+{
+ return stricmp(p1->name, p2->name);
+}
+
+int _find(const char **name, const struct NAME_TABLE *p)
+{
+ return stricmp(*name, p->name);
+}
+
+struct NAME_TABLE *GetNameTable(PMEMORYMODULE module)
+{
+ unsigned char *codeBase;
+ PIMAGE_EXPORT_DIRECTORY exports;
+ PIMAGE_DATA_DIRECTORY directory;
+ DWORD i, *nameRef;
+ WORD *ordinal;
+ struct NAME_TABLE *p, *ptab;
+
+ if (module->name_table)
+ return module->name_table;
+
+ codeBase = module->codeBase;
+ directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_EXPORT);
+ exports = (PIMAGE_EXPORT_DIRECTORY)(codeBase + directory->VirtualAddress);
+
+ nameRef = (DWORD *)(codeBase + exports->AddressOfNames);
+ ordinal = (WORD *)(codeBase + exports->AddressOfNameOrdinals);
+
+ p = ((PMEMORYMODULE)module)->name_table = (struct NAME_TABLE *)malloc(sizeof(struct NAME_TABLE)
+ * exports->NumberOfNames);
+ if (p == NULL)
+ return NULL;
+ ptab = p;
+ for (i=0; i<exports->NumberOfNames; ++i) {
+ p->name = (char *)(codeBase + *nameRef++);
+ p->ordinal = *ordinal++;
+ ++p;
+ }
+ qsort(ptab, exports->NumberOfNames, sizeof(struct NAME_TABLE), _compare);
+ return ptab;
+}
+
+FARPROC MemoryGetProcAddress(HMEMORYMODULE module, const char *name)
+{
+ unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase;
+ int idx=-1;
+ PIMAGE_EXPORT_DIRECTORY exports;
+ PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT);
+
+ if (directory->Size == 0)
+ // no export table found
+ return NULL;
+
+ exports = (PIMAGE_EXPORT_DIRECTORY)(codeBase + directory->VirtualAddress);
+ if (exports->NumberOfNames == 0 || exports->NumberOfFunctions == 0)
+ // DLL doesn't export anything
+ return NULL;
+
+ if (HIWORD(name)) {
+ struct NAME_TABLE *ptab;
+ struct NAME_TABLE *found;
+ ptab = GetNameTable((PMEMORYMODULE)module);
+ if (ptab == NULL)
+ // some failure
+ return NULL;
+ found = bsearch(&name, ptab, exports->NumberOfNames, sizeof(struct NAME_TABLE), _find);
+ if (found == NULL)
+ // exported symbol not found
+ return NULL;
+
+ idx = found->ordinal;
+ }
+ else
+ idx = LOWORD(name) - exports->Base;
+
+ if ((DWORD)idx > exports->NumberOfFunctions)
+ // name <-> ordinal number don't match
+ return NULL;
+
+ // AddressOfFunctions contains the RVAs to the "real" functions
+ return (FARPROC)(codeBase + *(DWORD *)(codeBase + exports->AddressOfFunctions + (idx*4)));
+}
+
+void MemoryFreeLibrary(HMEMORYMODULE mod)
+{
+ int i;
+ PMEMORYMODULE module = (PMEMORYMODULE)mod;
+
+ if (module != NULL)
+ {
+ if (module->initialized != 0)
+ {
+ // notify library about detaching from process
+ DllEntryProc DllEntry = (DllEntryProc)(module->codeBase + module->headers->OptionalHeader.AddressOfEntryPoint);
+ (*DllEntry)((HINSTANCE)module->codeBase, DLL_PROCESS_DETACH, 0);
+ module->initialized = 0;
+ }
+
+ if (module->modules != NULL)
+ {
+ // free previously opened libraries
+ for (i=0; i<module->numModules; i++)
+ if (module->modules[i] != INVALID_HANDLE_VALUE)
+ FreeLibrary(module->modules[i]);
+
+ free(module->modules);
+ }
+
+ if (module->codeBase != NULL)
+ // release memory of library
+ VirtualFree(module->codeBase, 0, MEM_RELEASE);
+
+ if (module->name_table != NULL)
+ free(module->name_table);
+
+ HeapFree(GetProcessHeap(), 0, module);
+ }
+}
diff --git a/Plugins/utils/MemoryModule.h b/Plugins/utils/MemoryModule.h new file mode 100644 index 0000000..f314e5d --- /dev/null +++ b/Plugins/utils/MemoryModule.h @@ -0,0 +1,48 @@ +/*
+ * Memory DLL loading code
+ * Version 0.0.2
+ *
+ * Copyright (c) 2004-2005 by Joachim Bauch / mail@joachim-bauch.de
+ * http://www.joachim-bauch.de
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is MemoryModule.h
+ *
+ * The Initial Developer of the Original Code is Joachim Bauch.
+ *
+ * Portions created by Joachim Bauch are Copyright (C) 2004-2005
+ * Joachim Bauch. All Rights Reserved.
+ *
+ */
+
+#ifndef __MEMORY_MODULE_HEADER
+#define __MEMORY_MODULE_HEADER
+
+#include <Windows.h>
+
+typedef void *HMEMORYMODULE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+HMEMORYMODULE MemoryLoadLibrary(const void *);
+
+FARPROC MemoryGetProcAddress(HMEMORYMODULE, const char *);
+
+void MemoryFreeLibrary(HMEMORYMODULE);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __MEMORY_MODULE_HEADER
diff --git a/Plugins/utils/mir_dblists.cpp b/Plugins/utils/mir_dblists.cpp new file mode 100644 index 0000000..a1711ed --- /dev/null +++ b/Plugins/utils/mir_dblists.cpp @@ -0,0 +1,149 @@ +/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "mir_dblists.h"
+#include "mir_memory.h"
+
+#include <stdio.h>
+
+#include <newpluginapi.h>
+#include <m_system.h>
+
+
+struct LIST_INTERFACE list_interface = {0};
+
+
+void init_list_interface()
+{
+ list_interface.cbSize = sizeof(list_interface);
+ CallService(MS_SYSTEM_GET_LI, 0, (LPARAM)&list_interface);
+}
+
+
+void List_DestroyFreeContents( SortedList* p_list ) +{ + if ( p_list == NULL ) + return; + + if ( p_list->items != NULL ) + { + int i; + for ( i = 0 ; i < p_list->realCount ; i++ ) + { + if ( p_list->items[i] != NULL ) + { + mir_free( p_list->items[i] ); + } + } + } + + List_Destroy( p_list ); +} + +
+int List_Append( SortedList* p_list, void* p_value ) +{ + return List_Insert( p_list, p_value, p_list->realCount ); +} + +
+int List_InsertOrdered( SortedList* p_list, void* p_value )
+{
+ int index;
+
+ List_GetIndex( p_list, p_value, &index );
+ List_Insert( p_list, p_value, index );
+
+ return index;
+}
+
+
+int List_RemoveByValue( SortedList* p_list, void* p_value )
+{
+ int ret = 0;
+
+ if ( p_list->items != NULL )
+ {
+ int i;
+ for ( i = p_list->realCount - 1 ; i >= 0 ; i-- )
+ {
+ if ( p_list->items[ i ] == p_value )
+ ret += List_Remove( p_list, i );
+ }
+ }
+
+ return ret;
+} +
+
+int List_RemoveByValueFreeContents( SortedList* p_list, void* p_value )
+{
+ int ret = 0;
+
+ if ( p_list->items != NULL )
+ {
+ int i;
+ for ( i = p_list->realCount - 1 ; i >= 0 ; i-- )
+ {
+ if ( p_list->items[ i ] == p_value )
+ {
+ mir_free( p_list->items[ i ] );
+ ret += List_Remove( p_list, i );
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+void List_Push( SortedList* p_list, void* p_value )
+{
+ List_Insert( p_list, p_value, p_list->realCount );
+}
+
+
+void* List_Pop( SortedList* p_list )
+{
+ void *ret;
+
+ if ( p_list->realCount <= 0 )
+ return NULL;
+
+ ret = p_list->items[ p_list->realCount - 1 ];
+ List_Remove( p_list, p_list->realCount - 1 );
+
+ return ret;
+}
+
+
+void* List_Peek( SortedList* p_list )
+{
+ if ( p_list->realCount <= 0 )
+ return NULL;
+
+ return p_list->items[ p_list->realCount - 1 ];
+}
+
+
+BOOL List_HasItens( SortedList* p_list )
+{
+ return p_list->realCount > 0;
+}
\ No newline at end of file diff --git a/Plugins/utils/mir_dblists.h b/Plugins/utils/mir_dblists.h new file mode 100644 index 0000000..4d4552b --- /dev/null +++ b/Plugins/utils/mir_dblists.h @@ -0,0 +1,62 @@ +/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __MIR_DBLISTS_H__
+# define __MIR_DBLISTS_H__
+
+#include <windows.h>
+#include <newpluginapi.h>
+#include <m_system.h>
+
+
+
+extern struct LIST_INTERFACE list_interface;
+
+
+// Need to be called on ME_SYSTEM_MODULESLOADED
+void init_list_interface();
+
+
+#define List_Create(x,y) (list_interface.List_Create(x,y))
+#define List_Destroy(x) (list_interface.List_Destroy(x))
+#define List_Find(x,y) (list_interface.List_Find(x,y))
+#define List_GetIndex(x,y,z) (list_interface.List_GetIndex(x,y,z))
+#define List_Insert(x,y,z) (list_interface.List_Insert(x,y,z))
+#define List_Remove(x,y) (list_interface.List_Remove(x,y))
+#define List_IndexOf(x,y) (list_interface.List_IndexOf(x,y))
+
+
+BOOL List_HasItens( SortedList* p_list );
+
+void List_DestroyFreeContents( SortedList* );
+int List_RemoveByValue( SortedList*, void* );
+int List_RemoveByValueFreeContents( SortedList*, void* );
+
+int List_Append( SortedList*, void* );
+int List_InsertOrdered( SortedList*, void* );
+
+// Theese work on the end of the list
+void List_Push( SortedList* p_list, void* p_value );
+void* List_Pop( SortedList* p_list );
+void* List_Peek( SortedList* p_list );
+
+
+
+#endif // __MIR_DBLISTS_H__
diff --git a/Plugins/utils/mir_dbutils.h b/Plugins/utils/mir_dbutils.h new file mode 100644 index 0000000..cb7400a --- /dev/null +++ b/Plugins/utils/mir_dbutils.h @@ -0,0 +1,70 @@ +/*
+Copyright (C) 2009 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+#ifndef __DBUTILS_H__
+# define __DBUTILS_H__
+
+
+class DBTString
+{
+ DBVARIANT dbv;
+ bool exists;
+
+public:
+ DBTString(HANDLE hContact, char *module, char *setting)
+ {
+ ZeroMemory(&dbv, sizeof(dbv));
+ exists = (DBGetContactSettingTString(hContact, module, setting, &dbv) == 0);
+ }
+
+ ~DBTString()
+ {
+ if (exists)
+ DBFreeVariant(&dbv);
+ }
+
+ const TCHAR * get() const
+ {
+ if (!exists)
+ return NULL;
+ else
+ return dbv.ptszVal;
+ }
+
+ const bool operator==(const TCHAR *other)
+ {
+ return get() == other;
+ }
+
+ const bool operator!=(const TCHAR *other)
+ {
+ return get() != other;
+ }
+
+ operator const TCHAR *() const
+ {
+ return get();
+ }
+};
+
+
+
+
+
+
+#endif // __DBUTILS_H__
diff --git a/Plugins/utils/mir_icons.cpp b/Plugins/utils/mir_icons.cpp index f55d1c2..1fb2c0e 100644 --- a/Plugins/utils/mir_icons.cpp +++ b/Plugins/utils/mir_icons.cpp @@ -40,11 +40,17 @@ HICON IcoLib_LoadIcon(const char *iconName, BOOL copy) if (copy && hIcon != NULL)
{
hIcon = CopyIcon(hIcon);
- CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM) iconName);
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM) hIcon, 0);
}
return hIcon;
}
+void IcoLib_ReleaseIcon(const char *iconName)
+{
+ if (ServiceExists(MS_SKIN2_RELEASEICON))
+ CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM) iconName);
+}
+
void IcoLib_ReleaseIcon(HICON hIcon)
{
diff --git a/Plugins/utils/mir_icons.h b/Plugins/utils/mir_icons.h index a6fcb53..65b99d5 100644 --- a/Plugins/utils/mir_icons.h +++ b/Plugins/utils/mir_icons.h @@ -1,5 +1,5 @@ /*
-Copyright (C) 2005 Ricardo Pescuma Domenecci
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. void IcoLib_Register(char *name, TCHAR *section, TCHAR *description, int id);
HICON IcoLib_LoadIcon(const char *iconName, BOOL copy = FALSE);
+void IcoLib_ReleaseIcon(const char *iconName);
void IcoLib_ReleaseIcon(HICON hIcon);
diff --git a/Plugins/utils/mir_log.cpp b/Plugins/utils/mir_log.cpp index 1a133e9..5a5a180 100644 --- a/Plugins/utils/mir_log.cpp +++ b/Plugins/utils/mir_log.cpp @@ -1,5 +1,5 @@ /*
-Copyright (C) 2005 Ricardo Pescuma Domenecci
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/Plugins/utils/mir_log.h b/Plugins/utils/mir_log.h index 2efaed2..5785e19 100644 --- a/Plugins/utils/mir_log.h +++ b/Plugins/utils/mir_log.h @@ -1,5 +1,5 @@ /*
-Copyright (C) 2005 Ricardo Pescuma Domenecci
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
This is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/Plugins/utils/mir_memory.h b/Plugins/utils/mir_memory.h index a976dc9..b7ed17b 100644 --- a/Plugins/utils/mir_memory.h +++ b/Plugins/utils/mir_memory.h @@ -1,21 +1,21 @@ /*
- Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
+Copyright (C) 2005-2009 Ricardo Pescuma Domenecci
- This is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
- This is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this file; see the file license.txt. If
- not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
- */
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
#ifndef __MIR_MEMORY_H__
# define __MIR_MEMORY_H__
@@ -27,9 +27,14 @@ static BOOL mir_is_unicode()
{
- char ver[1024];
- CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM) sizeof(ver), (LPARAM) ver);
- return strstr(ver, "Unicode") != NULL;
+ static int is_unicode = -1;
+ if (is_unicode == -1)
+ {
+ char ver[1024];
+ CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM) sizeof(ver), (LPARAM) ver);
+ is_unicode = (strstr(ver, "Unicode") != NULL ? 1 : 0);
+ }
+ return is_unicode;
}
diff --git a/Plugins/utils/mir_options.cpp b/Plugins/utils/mir_options.cpp index 7f1f267..11af0c6 100644 --- a/Plugins/utils/mir_options.cpp +++ b/Plugins/utils/mir_options.cpp @@ -143,92 +143,95 @@ static void PathToAbsolute(TCHAR *pOut, size_t outSize, const TCHAR *pSrc) }
-void LoadOpts(OptPageControl *controls, int controlsSize, char *module)
+static void LoadOpt(OptPageControl *ctrl, char *module)
{
- for (int i = 0 ; i < controlsSize ; i++)
+ if (ctrl->var == NULL)
+ return;
+
+ switch(ctrl->type)
{
- OptPageControl *ctrl = &controls[i];
-
- if (ctrl->var != NULL)
+ case CONTROL_CHECKBOX:
{
- switch(ctrl->type)
- {
- case CONTROL_CHECKBOX:
- {
- *((BYTE *) ctrl->var) = DBGetContactSettingByte(NULL, module, ctrl->setting, ctrl->dwDefValue);
- break;
- }
- case CONTROL_SPIN:
- {
- *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
- break;
- }
- case CONTROL_COLOR:
- {
- *((COLORREF *) ctrl->var) = (COLORREF) DBGetContactSettingDword(NULL, module, ctrl->setting, ctrl->dwDefValue);
- break;
- }
- case CONTROL_RADIO:
- {
- *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
- break;
- }
- case CONTROL_COMBO:
- {
- *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
- break;
- }
- case CONTROL_PROTOCOL_LIST:
- {
- break;
- }
- case CONTROL_TEXT:
- {
- MyDBGetContactSettingTString(NULL, module, ctrl->setting, ((TCHAR *) ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
- break;
- }
- case CONTROL_PASSWORD:
- {
- char tmp[1024];
- tmp[0]=0;
+ *((BYTE *) ctrl->var) = DBGetContactSettingByte(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_SPIN:
+ {
+ *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_COLOR:
+ {
+ *((COLORREF *) ctrl->var) = (COLORREF) DBGetContactSettingDword(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_RADIO:
+ {
+ *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_COMBO:
+ {
+ *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_PROTOCOL_LIST:
+ {
+ break;
+ }
+ case CONTROL_TEXT:
+ {
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, ((TCHAR *) ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ break;
+ }
+ case CONTROL_PASSWORD:
+ {
+ char tmp[1024];
+ tmp[0]=0;
- DBVARIANT dbv = {0};
- if (!DBGetContactSettingString(NULL, module, ctrl->setting, &dbv))
- {
- lstrcpynA(tmp, dbv.pszVal, MAX_REGS(tmp));
- DBFreeVariant(&dbv);
- }
+ DBVARIANT dbv = {0};
+ if (!DBGetContactSettingString(NULL, module, ctrl->setting, &dbv))
+ {
+ lstrcpynA(tmp, dbv.pszVal, MAX_REGS(tmp));
+ DBFreeVariant(&dbv);
+ }
- if (tmp[0] != 0)
- CallService(MS_DB_CRYPT_DECODESTRING, MAX_REGS(tmp), (LPARAM) tmp);
- else if (ctrl->szDefValue != NULL)
- lstrcpynA(tmp, ctrl->szDefValue, MAX_REGS(tmp));
+ if (tmp[0] != 0)
+ CallService(MS_DB_CRYPT_DECODESTRING, MAX_REGS(tmp), (LPARAM) tmp);
+ else if (ctrl->szDefValue != NULL)
+ lstrcpynA(tmp, ctrl->szDefValue, MAX_REGS(tmp));
- char *var = (char *) ctrl->var;
- int size = min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024);
- lstrcpynA(var, tmp, size);
- break;
- }
- case CONTROL_INT:
- {
- *((int *) ctrl->var) = (int) DBGetContactSettingDword(NULL, module, ctrl->setting, ctrl->dwDefValue);
- break;
- }
- case CONTROL_FILE:
- {
- TCHAR tmp[1024];
- MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : ctrl->tszDefValue);
- PathToAbsolute(((TCHAR *) ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), tmp);
- break;
- }
- case CONTROL_COMBO_TEXT:
- case CONTROL_COMBO_ITEMDATA:
- {
- MyDBGetContactSettingTString(NULL, module, ctrl->setting, ((TCHAR *) ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
- break;
- }
- }
+ char *var = (char *) ctrl->var;
+ int size = min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024);
+ lstrcpynA(var, tmp, size);
+ break;
+ }
+ case CONTROL_INT:
+ {
+ *((int *) ctrl->var) = (int) DBGetContactSettingDword(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
}
+ case CONTROL_FILE:
+ {
+ TCHAR tmp[1024];
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : ctrl->tszDefValue);
+ PathToAbsolute(((TCHAR *) ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), tmp);
+ break;
+ }
+ case CONTROL_COMBO_TEXT:
+ case CONTROL_COMBO_ITEMDATA:
+ {
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, ((TCHAR *) ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ break;
+ }
+ }
+}
+
+void LoadOpts(OptPageControl *controls, int controlsSize, char *module)
+{
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ LoadOpt(&controls[i], module);
}
}
@@ -528,9 +531,25 @@ BOOL CALLBACK SaveOptsDlgProc(OptPageControl *controls, int controlsSize, char * {
char tmp[1024];
GetDlgItemTextA(hwndDlg, ctrl->nID, tmp, MAX_REGS(tmp));
+
+ if (ctrl->var != NULL)
+ {
+ char *var = (char *) ctrl->var;
+ int size = min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024);
+ lstrcpynA(var, tmp, size);
+ }
+
+ if (ctrl->checkboxID != 0 && !IsDlgButtonChecked(hwndDlg, ctrl->checkboxID))
+ {
+ DBDeleteContactSetting(NULL, module, ctrl->setting);
+ continue;
+ }
+
CallService(MS_DB_CRYPT_ENCODESTRING, MAX_REGS(tmp), (LPARAM) tmp);
DBWriteContactSettingString(NULL, module, ctrl->setting, tmp);
- break;
+
+ // Don't load from DB
+ continue;
}
case CONTROL_INT:
{
@@ -568,10 +587,10 @@ BOOL CALLBACK SaveOptsDlgProc(OptPageControl *controls, int controlsSize, char * break;
}
}
+
+ LoadOpt(ctrl, module);
}
- LoadOpts(controls, controlsSize, module);
-
return TRUE;
}
else if (lpnmhdr->idFrom != 0 && lpnmhdr->code == LVN_ITEMCHANGED)
diff --git a/Plugins/utils/mir_options.h b/Plugins/utils/mir_options.h index 31b757b..34b9c4c 100644 --- a/Plugins/utils/mir_options.h +++ b/Plugins/utils/mir_options.h @@ -54,6 +54,7 @@ typedef struct { int nIDSpin;
int value;
FPAllowProtocol allowProtocol;
+ unsigned int checkboxID;
};
WORD min;
WORD max;
diff --git a/Plugins/utils/mir_profiler.cpp b/Plugins/utils/mir_profiler.cpp new file mode 100644 index 0000000..b788fd2 --- /dev/null +++ b/Plugins/utils/mir_profiler.cpp @@ -0,0 +1,178 @@ +/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+// Disable "...truncated to '255' characters in the debug information" warnings
+#pragma warning(disable: 4786)
+
+
+#include "mir_profiler.h"
+#include "mir_log.h"
+
+#include <stdio.h>
+
+
+MProfiler::Block MProfiler::root;
+MProfiler::Block * MProfiler::current = &MProfiler::root;
+
+
+MProfiler::Block::Block()
+{
+ parent = NULL;
+ memset(&total, 0, sizeof(total));
+ started = false;
+}
+
+
+MProfiler::Block::~Block()
+{
+ Reset();
+}
+
+
+void MProfiler::Block::Reset()
+{
+ for(std::map<std::string, MProfiler::Block *>::iterator it = children.begin();
+ it != children.end(); ++it)
+ delete it->second;
+ children.clear();
+
+ memset(&total, 0, sizeof(total));
+ started = false;
+}
+
+
+void MProfiler::Block::Start()
+{
+ if (started)
+ return;
+
+ QueryPerformanceCounter(&start);
+ last_step = start;
+ started = true;
+}
+
+
+void MProfiler::Block::Step(const char *name)
+{
+ if (!started)
+ return;
+
+ LARGE_INTEGER end;
+ QueryPerformanceCounter(&end);
+
+ GetChild(name)->total.QuadPart += end.QuadPart - last_step.QuadPart;
+
+ last_step = end;
+}
+
+
+void MProfiler::Block::Stop()
+{
+ if (!started)
+ return;
+
+ LARGE_INTEGER end;
+ QueryPerformanceCounter(&end);
+
+ total.QuadPart += end.QuadPart - start.QuadPart;
+
+ started = false;
+}
+
+
+double MProfiler::Block::GetTimeMS() const
+{
+ LARGE_INTEGER frequency;
+ QueryPerformanceFrequency(&frequency);
+
+ return total.QuadPart * 1000. / frequency.QuadPart;
+}
+
+
+MProfiler::Block * MProfiler::Block::GetChild(const char *name)
+{
+ MProfiler::Block *ret = children[name];
+ if (ret == NULL)
+ {
+ ret = new MProfiler::Block();
+ ret->name = name;
+ ret->parent = this;
+ children[name] = ret;
+ }
+ return ret;
+}
+
+
+void MProfiler::Reset()
+{
+ root.Reset();
+}
+
+void MProfiler::Start(const char *name)
+{
+ current = current->GetChild(name);
+ current->Start();
+}
+
+void MProfiler::Step(const char *name)
+{
+ current->Step(name);
+}
+
+void MProfiler::End()
+{
+ current->Stop();
+
+ if (current->parent != NULL)
+ {
+ current = current->parent;
+ QueryPerformanceCounter(¤t->last_step);
+ }
+}
+
+void MProfiler::Dump(const char *module)
+{
+ Dump(module, "", &root, -1, -1);
+}
+
+
+void MProfiler::Dump(const char *module, std::string prefix, Block *block, double parent, double total)
+{
+ for(std::map<std::string, MProfiler::Block *>::iterator it = block->children.begin();
+ it != block->children.end(); ++it)
+ {
+ Block *child = it->second;
+ double elapsed = child->GetTimeMS();
+
+ if (total > 0)
+ {
+ mlog(module, "Profiler", "%s%-20s\t%5.1lf\t[%3.0lf%%]\t[%3.0lf%%]", prefix.c_str(), it->first.c_str(),
+ elapsed, elapsed / parent * 100, elapsed / total * 100);
+ }
+ else
+ {
+ mlog(module, "Profiler", "%s%-20s\t%5.1lf", prefix.c_str(), it->first.c_str(),
+ elapsed);
+ }
+
+ Dump(module, prefix + " ", child, elapsed, total > 0 ? total : elapsed);
+ }
+}
+
diff --git a/Plugins/utils/mir_profiler.h b/Plugins/utils/mir_profiler.h new file mode 100644 index 0000000..92d776f --- /dev/null +++ b/Plugins/utils/mir_profiler.h @@ -0,0 +1,77 @@ +/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __PROFILER_H__
+# define __PROFILER_H__
+
+#include <windows.h>
+#include <string>
+#include <map>
+
+
+
+class MProfiler
+{
+public:
+
+ static void Reset();
+ static void Start(const char *name);
+ static void Step(const char *name);
+ static void End();
+ static void Dump(const char *module);
+
+
+
+ static struct Block
+ {
+ std::string name;
+ Block *parent;
+ std::map<std::string, Block *> children;
+ bool started;
+ LARGE_INTEGER start;
+ LARGE_INTEGER last_step;
+ LARGE_INTEGER total;
+
+ Block();
+ ~Block();
+
+ void Reset();
+ void Start();
+ void Step(const char *name);
+ void Stop();
+ double GetTimeMS() const;
+
+ Block * GetChild(const char *name);
+ };
+
+
+private:
+
+ static Block root;
+ static Block *current;
+
+ static void Dump(const char *module, std::string prefix, Block *block, double parent, double total);
+
+};
+
+
+
+
+#endif // __PROFILER_H__
diff --git a/Plugins/utils/mir_scope.h b/Plugins/utils/mir_scope.h index a18bf55..2f54044 100644 --- a/Plugins/utils/mir_scope.h +++ b/Plugins/utils/mir_scope.h @@ -7,7 +7,7 @@ class scope {
public:
scope(T t) : p(t) {}
- ~scope() { free(); }
+ ~scope() { mir_free(); }
void free()
{
diff --git a/Plugins/utils/mir_smileys.cpp b/Plugins/utils/mir_smileys.cpp index 50c9169..241b315 100644 --- a/Plugins/utils/mir_smileys.cpp +++ b/Plugins/utils/mir_smileys.cpp @@ -18,13 +18,19 @@ Boston, MA 02111-1307, USA. */
+#define MIRANDA_VER 0x0700
#include "mir_smileys.h"
#include "mir_memory.h"
+#include "utf8_helpers.h"
#include <richedit.h>
#include <m_smileyadd.h>
#include <newpluginapi.h>
#include <m_langpack.h>
+#include <m_clui.h>
+#include <m_database.h>
+#include <commctrl.h>
+#include <m_skin_eng.h>
#include <tchar.h>
@@ -100,6 +106,39 @@ void Smileys_FreeParse(SmileysParseInfo parseInfo) }
}
+int skin_DrawText(HDC hDC, LPCSTR lpString, int nCount, LPRECT lpRect, UINT uFormat)
+{
+ if ((uFormat & DT_CALCRECT) == 0 && ServiceExists(MS_SKINENG_ALPHATEXTOUT))
+ {
+ COLORREF color = SetTextColor(hDC, 0);
+ SetTextColor(hDC, color);
+
+ if (mir_is_unicode())
+ {
+ return AlphaText(hDC, (char *) (const WCHAR *) CharToWchar(lpString), nCount, lpRect, uFormat, color);
+ }
+ else
+ {
+ return AlphaText(hDC, lpString, nCount, lpRect, uFormat, color);
+ }
+ }
+ else
+ {
+ return DrawText(hDC, lpString, nCount, lpRect, uFormat);
+ }
+}
+
+int skin_DrawIconEx(HDC hdc, int xLeft, int yTop, HICON hIcon, int cxWidth, int cyWidth,
+ UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags)
+{
+ if (ServiceExists(MS_SKINENG_DRAWICONEXFIX))
+ return mod_DrawIconEx_helper(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth, istepIfAniCur, hbrFlickerFreeDraw, diFlags);
+ else
+ return DrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth, istepIfAniCur, hbrFlickerFreeDraw, diFlags);
+}
+
+
+
// Similar to DrawText win32 api function
// Pass uFormat | DT_CALCRECT to calc rectangle to be returned by lpRect
// parseInfo is optional (pass NULL and it will be calculated and deleted inside function
@@ -149,7 +188,7 @@ int Smileys_DrawText(HDC hDC, LPCSTR lpString, int nCount, LPRECT lpRect, UINT u // Draw
if (info->pieces == NULL)
{
- ret = DrawText(hDC, lpString, nCount, lpRect, uFormat);
+ ret = skin_DrawText(hDC, lpString, nCount, lpRect, uFormat);
}
else
{
@@ -269,7 +308,7 @@ void DrawTextSmiley(HDC hdcMem, RECT free_rc, const char *szText, int len, Sorte i = 0;
// Get real height of the line
- text_height = DrawText(hdcMem, "A", 1, &tmp_rc, DT_CALCRECT | uTextFormat);
+ text_height = skin_DrawText(hdcMem, "A", 1, &tmp_rc, DT_CALCRECT | uTextFormat);
if (uTextFormat & DT_RESIZE_SMILEYS)
row_height = text_height;
else
@@ -278,7 +317,7 @@ void DrawTextSmiley(HDC hdcMem, RECT free_rc, const char *szText, int len, Sorte // Just draw ellipsis
if (free_rc.right <= free_rc.left)
{
- DrawText(hdcMem, "...", 3, &free_rc, uTextFormat & ~DT_END_ELLIPSIS);
+ skin_DrawText(hdcMem, "...", 3, &free_rc, uTextFormat & ~DT_END_ELLIPSIS);
}
else
{
@@ -299,13 +338,13 @@ void DrawTextSmiley(HDC hdcMem, RECT free_rc, const char *szText, int len, Sorte tmp_rc = text_rc;
tmp_rc.right += 50;
- DrawText(hdcMem, &szText[piece->start_pos], min(len, piece->len), &tmp_rc, DT_CALCRECT | (uTextFormat & ~DT_END_ELLIPSIS));
+ skin_DrawText(hdcMem, &szText[piece->start_pos], min(len, piece->len), &tmp_rc, DT_CALCRECT | (uTextFormat & ~DT_END_ELLIPSIS));
pos_x += tmp_rc.right - tmp_rc.left;
if (uTextFormat & DT_RTLREADING)
text_rc.left = max(text_rc.left, text_rc.right - (tmp_rc.right - tmp_rc.left));
- DrawText(hdcMem, &szText[piece->start_pos], min(len, piece->len), &text_rc, uTextFormat);
+ skin_DrawText(hdcMem, &szText[piece->start_pos], min(len, piece->len), &text_rc, uTextFormat);
len -= piece->len;
}
else
@@ -336,13 +375,13 @@ void DrawTextSmiley(HDC hdcMem, RECT free_rc, const char *szText, int len, Sorte {
text_rc.top += (row_height - (LONG)(piece->smiley_height * factor)) >> 1;
- DrawIconEx(hdcMem, text_rc.left, text_rc.top, piece->smiley,
+ skin_DrawIconEx(hdcMem, text_rc.left, text_rc.top, piece->smiley,
(LONG)(piece->smiley_width * factor), (LONG)(piece->smiley_height * factor), 0, NULL, DI_NORMAL);
}
else
{
text_rc.top += (row_height - text_height) >> 1;
- DrawText(hdcMem, "...", 3, &text_rc, uTextFormat);
+ skin_DrawText(hdcMem, "...", 3, &text_rc, uTextFormat);
}
pos_x += (LONG)(piece->smiley_width * factor);
diff --git a/Plugins/utils/mir_smileys.h b/Plugins/utils/mir_smileys.h index fe9997b..cfbebb8 100644 --- a/Plugins/utils/mir_smileys.h +++ b/Plugins/utils/mir_smileys.h @@ -61,5 +61,9 @@ int Smileys_DrawText(HDC hDC, LPCSTR lpString, int nCount, LPRECT lpRect, UINT u // int Smileys_DrawTextW(HDC hDC, LPCWSTR lpString, int nCount, LPRECT lpRect, UINT uFormat, const char *protocol, SmileysParseInfo parseInfo);
+int skin_DrawText(HDC hDC, LPCSTR lpString, int nCount, LPRECT lpRect, UINT uFormat);
+int skin_DrawIconEx(HDC hdc, int xLeft, int yTop, HICON hIcon, int cxWidth, int cyWidth, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags);
+
+
#endif // __MIR_SMILEYS_H__
diff --git a/Plugins/utils/templates.cpp b/Plugins/utils/templates.cpp new file mode 100644 index 0000000..11a81d8 --- /dev/null +++ b/Plugins/utils/templates.cpp @@ -0,0 +1,476 @@ +#include "templates.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <tchar.h>
+
+extern "C"
+{
+#include <newpluginapi.h>
+#include <time.h>
+#include <win2k.h>
+#include <m_system.h>
+#include <m_plugins.h>
+#include <m_options.h>
+#include <m_langpack.h>
+#include <m_database.h>
+#include <m_utils.h>
+#include <m_protocols.h>
+
+#include <m_notify.h>
+
+#include "../utils/mir_memory.h"
+}
+
+
+const char *defaultVariables[] = { "%title%", "%text%" };
+const WCHAR *defaultVariablesW[] = { L"%title%", L"%text%" };
+
+const char *defaultVariableDescriptions[] = { "Notification Title", "Notification Text" };
+const WCHAR *defaultVariableDescriptionsW[] = { L"Notification Title", L"Notification Text" };
+
+
+#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) )
+
+
+#define DATA_BLOCK 128
+
+
+// ASCII VERSIONS ///////////////////////////////////////////////////////////////////////
+
+struct StringHelper
+{
+ char *text;
+ size_t allocated;
+ size_t used;
+};
+
+
+int CopyData(StringHelper *str, const char *text, size_t len)
+{
+ if (len == 0)
+ return 0;
+
+ if (text == NULL)
+ return 0;
+
+ size_t totalSize = str->used + len + 1;
+
+ if (totalSize > str->allocated)
+ {
+ totalSize += DATA_BLOCK - (totalSize % DATA_BLOCK);
+
+ if (str->text != NULL)
+ {
+ char *tmp = (char *) mir_realloc(str->text, sizeof(char) * totalSize);
+
+ if (tmp == NULL)
+ {
+ mir_free(str->text);
+ return -1;
+ }
+
+ str->text = tmp;
+ }
+ else
+ {
+ str->text = (char *) mir_alloc(sizeof(char) * totalSize);
+
+ if (str->text == NULL)
+ {
+ return -2;
+ }
+ }
+
+ str->allocated = totalSize;
+ }
+
+ memmove(&str->text[str->used], text, sizeof(char) * len);
+ str->used += len;
+ str->text[str->used] = '\0';
+
+ return 0;
+}
+
+
+char * ParseText(const char *text,
+ const char **variables, size_t variablesSize,
+ const char **data, size_t dataSize)
+{
+ size_t length = strlen(text);
+ size_t nextPos = 0;
+ StringHelper ret = {0};
+
+ // length - 1 because a % in last char will be a % and point
+ for (size_t i = 0 ; i < length - 1 ; i++)
+ {
+ if (text[i] == '%')
+ {
+ bool found = false;
+
+ if (CopyData(&ret, &text[nextPos], i - nextPos))
+ return NULL;
+
+ if (text[i + 1] == '%')
+ {
+ if (CopyData(&ret, "%", 1))
+ return NULL;
+
+ i++;
+
+ found = true;
+ }
+ else
+ {
+ size_t size = min(variablesSize, dataSize);
+
+ // See if can find it
+ for(size_t j = 0 ; j < size ; j++)
+ {
+ size_t vlen = strlen(variables[j]);
+
+ if (strnicmp(&text[i], variables[j], vlen) == 0)
+ {
+ if (CopyData(&ret, data[j], strlen(data[j])))
+ return NULL;
+
+ i += vlen - 1;
+
+ found = true;
+
+ break;
+ }
+ }
+ }
+
+
+ if (found)
+ nextPos = i + 1;
+ else
+ nextPos = i;
+ }
+ }
+
+ if (nextPos < length)
+ if (CopyData(&ret, &text[nextPos], length - nextPos))
+ return NULL;
+
+ return ret.text;
+}
+
+
+// UNICODE VERSIONS /////////////////////////////////////////////////////////////////////
+
+struct StringHelperW
+{
+ WCHAR *text;
+ size_t allocated;
+ size_t used;
+};
+
+
+int CopyDataW(StringHelperW *str, const WCHAR *text, size_t len)
+{
+ if (len == 0)
+ return 0;
+
+ if (text == NULL)
+ return 0;
+
+ size_t totalSize = str->used + len + 1;
+
+ if (totalSize > str->allocated)
+ {
+ totalSize += DATA_BLOCK - (totalSize % DATA_BLOCK);
+
+ if (str->text != NULL)
+ {
+ WCHAR *tmp = (WCHAR *) mir_realloc(str->text, sizeof(WCHAR) * totalSize);
+
+ if (tmp == NULL)
+ {
+ mir_free(str->text);
+ return -1;
+ }
+
+ str->text = tmp;
+ }
+ else
+ {
+ str->text = (WCHAR *) mir_alloc(sizeof(WCHAR) * totalSize);
+
+ if (str->text == NULL)
+ {
+ return -2;
+ }
+ }
+
+ str->allocated = totalSize;
+ }
+
+ memmove(&str->text[str->used], text, sizeof(WCHAR) * len);
+ str->used += len;
+ str->text[str->used] = '\0';
+
+ return 0;
+}
+
+
+WCHAR * ParseTextW(const WCHAR *text,
+ const WCHAR **variables, size_t variablesSize,
+ const WCHAR **data, size_t dataSize)
+{
+ size_t length = lstrlenW(text);
+ size_t nextPos = 0;
+ StringHelperW ret = {0};
+
+ // length - 1 because a % in last char will be a % and point
+ for (size_t i = 0 ; i < length - 1 ; i++)
+ {
+ if (text[i] == L'%')
+ {
+ bool found = false;
+
+ if (CopyDataW(&ret, &text[nextPos], i - nextPos))
+ return NULL;
+
+ if (text[i + 1] == L'%')
+ {
+ if (CopyDataW(&ret, L"%", 1))
+ return NULL;
+
+ i++;
+
+ found = true;
+ }
+ else
+ {
+ size_t size = min(variablesSize, dataSize);
+
+ // See if can find it
+ for(size_t j = 0 ; j < size ; j++)
+ {
+ size_t vlen = lstrlenW(variables[j]);
+
+ if (_wcsnicmp(&text[i], variables[j], vlen) == 0)
+ {
+ if (CopyDataW(&ret, data[j], lstrlenW(data[j])))
+ return NULL;
+
+ i += vlen - 1;
+
+ found = true;
+
+ break;
+ }
+ }
+ }
+
+ if (found)
+ nextPos = i + 1;
+ else
+ nextPos = i;
+ }
+ }
+
+ if (nextPos < length)
+ if (CopyDataW(&ret, &text[nextPos], length - nextPos))
+ return NULL;
+
+ return ret.text;
+}
+
+
+// INTERFACE ////////////////////////////////////////////////////////////////////////////
+
+// In future maybe pre-parse here
+void MNotifySetTemplate(HANDLE notifyORtype, const char *name, const char *value)
+{
+ MNotifySetString(notifyORtype, name, value);
+}
+void MNotifySetWTemplate(HANDLE notifyORtype, const char *name, const WCHAR *value)
+{
+ MNotifySetWString(notifyORtype, name, value);
+}
+
+// Well, why not?
+const char *MNotifyGetTemplate(HANDLE notifyORtype, const char *name, const char *defValue)
+{
+ return MNotifyGetString(notifyORtype, name, defValue);
+}
+const WCHAR *MNotifyGetWTemplate(HANDLE notifyORtype, const char *name, const WCHAR *defValue)
+{
+ return MNotifyGetWString(notifyORtype, name, defValue);
+}
+
+// You must free the return with mir_sys_free
+char *MNotifyGetParsedTemplate(HANDLE notifyORtype, const char *name, const char *defValue)
+{
+ const char *temp = MNotifyGetString(notifyORtype, name, defValue);
+
+ if (MNotifyHasVariables(notifyORtype))
+ {
+ const char ** vars = (const char **) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_STRS, NULL);
+ size_t varsSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_SIZE, 0);
+
+ const char ** data = (const char **) MNotifyGetDWord(notifyORtype, NFOPT_DATA_STRS, NULL);
+ size_t dataSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_DATA_SIZE, 0);
+
+ return ParseText(temp, vars, varsSize, data, dataSize);
+ }
+ else
+ {
+ // Default values
+ const char * data[MAX_REGS(defaultVariables)];
+ data[0] = MNotifyGetString(notifyORtype, NFOPT_TITLE, NULL);
+ data[1] = MNotifyGetString(notifyORtype, NFOPT_TEXT, NULL);
+
+ return ParseText(temp, defaultVariables, MAX_REGS(defaultVariables), data, MAX_REGS(defaultVariables));
+ }
+}
+WCHAR *MNotifyGetWParsedTemplate(HANDLE notifyORtype, const char *name, const WCHAR *defValue)
+{
+ const WCHAR *temp = MNotifyGetWString(notifyORtype, name, defValue);
+
+ if (MNotifyHasWVariables(notifyORtype))
+ {
+ const WCHAR ** vars = (const WCHAR **) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_STRSW, NULL);
+ size_t varsSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_SIZE, 0);
+
+ const WCHAR ** data = (const WCHAR **) MNotifyGetDWord(notifyORtype, NFOPT_DATA_STRSW, NULL);
+ size_t dataSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_DATA_SIZE, 0);
+
+ return ParseTextW(temp, vars, varsSize, data, dataSize);
+ }
+ else
+ {
+ // Default values
+ const WCHAR * data[MAX_REGS(defaultVariablesW)];
+ data[0] = MNotifyGetWString(notifyORtype, NFOPT_TITLEW, NULL);
+ data[1] = MNotifyGetWString(notifyORtype, NFOPT_TEXTW, NULL);
+
+ return ParseTextW(temp, defaultVariablesW, MAX_REGS(defaultVariablesW), data, MAX_REGS(defaultVariablesW));
+ }
+}
+
+
+BOOL MNotifyHasVariables(HANDLE notifyORtype)
+{
+ return MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_STRS, NULL) != NULL &&
+ MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_SIZE, 0) != 0;
+}
+
+BOOL MNotifyHasWVariables(HANDLE notifyORtype)
+{
+ return MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_STRSW, NULL) != NULL &&
+ MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_SIZE, 0) != 0;
+}
+
+
+
+
+void MNotifyShowVariables(HANDLE notifyORtype)
+{
+ StringHelper ret = {0};
+
+ const char ** vars;
+ size_t varsSize;
+ const char ** descs;
+ size_t descsSize;
+
+ if (MNotifyHasVariables(notifyORtype))
+ {
+ vars = (const char **) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_STRS, NULL);
+ varsSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_SIZE, 0);
+
+ descs = (const char **) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_DESCRIPTIONS_STRS, NULL);
+ descsSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_DESCRIPTIONS_SIZE, 0);
+ }
+ else
+ {
+ // Default values
+ vars = defaultVariables;
+ varsSize = MAX_REGS(defaultVariables);
+
+ descs = defaultVariableDescriptions;
+ descsSize = MAX_REGS(defaultVariableDescriptions);
+ }
+
+ for(size_t i = 0 ; i < varsSize ; i++)
+ {
+ if (vars[i] != NULL)
+ {
+ if (CopyData(&ret, vars[i], strlen(vars[i])))
+ return;
+
+ if (i < descsSize && descs[i] != NULL && descs[i] != L'\0')
+ {
+ if (CopyData(&ret, " -> ", 4))
+ return;
+ if (CopyData(&ret, descs[i], strlen(descs[i])))
+ return;
+ }
+
+ if (CopyData(&ret, "\r\n", 2))
+ return;
+ }
+ }
+
+ MessageBoxA(NULL, ret.text, "Variables", MB_OK);
+
+ mir_free(ret.text);
+}
+
+void MNotifyShowWVariables(HANDLE notifyORtype)
+{
+ StringHelperW ret = {0};
+
+ const WCHAR ** vars;
+ size_t varsSize;
+ const WCHAR ** descs;
+ size_t descsSize;
+
+ if (MNotifyHasWVariables(notifyORtype))
+ {
+ vars = (const WCHAR **) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_STRSW, NULL);
+ varsSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_SIZE, 0);
+
+ descs = (const WCHAR **) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_DESCRIPTIONS_STRSW, NULL);
+ descsSize = (size_t) MNotifyGetDWord(notifyORtype, NFOPT_VARIABLES_DESCRIPTIONS_SIZE, 0);
+ }
+ else
+ {
+ // Default values
+ vars = defaultVariablesW;
+ varsSize = MAX_REGS(defaultVariablesW);
+
+ descs = defaultVariableDescriptionsW;
+ descsSize = MAX_REGS(defaultVariableDescriptionsW);
+ }
+
+ for(size_t i = 0 ; i < varsSize ; i++)
+ {
+ if (vars[i] != NULL)
+ {
+ if (CopyDataW(&ret, vars[i], lstrlenW(vars[i])))
+ return;
+
+ if (i < descsSize && descs[i] != NULL && descs[i] != L'\0')
+ {
+ if (CopyDataW(&ret, L" -> ", 3))
+ return;
+ if (CopyDataW(&ret, descs[i], lstrlenW(descs[i])))
+ return;
+ }
+
+ if (CopyDataW(&ret, L"\r\n", 2))
+ return;
+ }
+ }
+
+ MessageBoxW(NULL, ret.text, L"Variables", MB_OK);
+
+ mir_free(ret.text);
+}
+
+
diff --git a/Plugins/utils/templates.h b/Plugins/utils/templates.h new file mode 100644 index 0000000..e55fb7a --- /dev/null +++ b/Plugins/utils/templates.h @@ -0,0 +1,102 @@ +#ifndef __TEMPLATES_H__
+# define __TEMPLATES_H__
+
+
+#include <windows.h>
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+// Default templates to be set by using notifiers
+
+#define NFOPT_DEFTEMPL_TEXT "General/DefaultTemplate/Text"
+#define NFOPT_DEFTEMPL_TEXTW "General/DefaultTemplate/TextW"
+#define NFOPT_DEFTEMPL_TITLE "General/DefaultTemplate/Title"
+#define NFOPT_DEFTEMPL_TITLEW "General/DefaultTemplate/TitleW"
+
+
+
+
+// All of theese have to be stored as DWORDs
+
+#define NFOPT_VARIABLES_STRS "Variables/Strings" // char ** (each has to start and end with %)
+#define NFOPT_VARIABLES_DESCRIPTIONS_STRS "VariablesDescriptions/Strings" // char **
+#define NFOPT_DATA_STRS "Data/Strings" // char **
+
+#define NFOPT_VARIABLES_STRSW "Variables/StringsW" // WCHAR ** (each has to start and end with %)
+#define NFOPT_VARIABLES_DESCRIPTIONS_STRSW "VariablesDescriptions/StringsW"// WCHAR **
+#define NFOPT_DATA_STRSW "Data/StringsW" // WCHAR **
+
+#define NFOPT_VARIABLES_SIZE "Variables/Size" // size_t
+#define NFOPT_VARIABLES_DESCRIPTIONS_SIZE "VariablesDescriptions/Size" // size_t
+#define NFOPT_DATA_SIZE "Data/Size" // size_t
+
+
+// Default variables if none is provided by the plugin calling the notification
+// char *defaultVariables[] = { "%title%", "%text%" };
+
+
+void MNotifySetTemplate(HANDLE notifyORtype, const char *name, const char *value);
+void MNotifySetWTemplate(HANDLE notifyORtype, const char *name, const WCHAR *value);
+
+const char *MNotifyGetTemplate(HANDLE notifyORtype, const char *name, const char *defValue);
+const WCHAR *MNotifyGetWTemplate(HANDLE notifyORtype, const char *name, const WCHAR *defValue);
+
+// You must free the return with mir_sys_free
+char *MNotifyGetParsedTemplate(HANDLE notifyORtype, const char *name, const char *defValue);
+WCHAR *MNotifyGetWParsedTemplate(HANDLE notifyORtype, const char *name, const WCHAR *defValue);
+
+
+BOOL MNotifyHasVariables(HANDLE notifyORtype);
+BOOL MNotifyHasWVariables(HANDLE notifyORtype);
+
+void MNotifyShowVariables(HANDLE notifyORtype);
+void MNotifyShowWVariables(HANDLE notifyORtype);
+
+
+#ifdef _UNICODE
+
+# define MNotifyGetTString MNotifyGetWString
+# define MNotifyGetTTemplate MNotifyGetWTemplate
+# define MNotifySetTString MNotifySetWString
+# define MNotifySetTTemplate MNotifyGetWTemplate
+# define MNotifyGetTParsedTemplate MNotifyGetWParsedTemplate
+# define MNotifyHasTVariables MNotifyHasWVariables
+# define MNotifyShowTVariables MNotifyShowWVariables
+
+# define NFOPT_DEFTEMPL_TEXTT NFOPT_DEFTEMPL_TEXTW
+# define NFOPT_DEFTEMPL_TITLET NFOPT_DEFTEMPL_TITLEW
+
+# define NFOPT_VARIABLES_STRST NFOPT_VARIABLES_STRSW
+# define NFOPT_VARIABLES_DESCRIPTIONS_STRST NFOPT_VARIABLES_DESCRIPTIONS_STRSW
+# define NFOPT_DATA_STRST NFOPT_DATA_STRSW
+
+
+#else
+
+# define MNotifyGetTString MNotifyGetString
+# define MNotifyGetTTemplate MNotifyGetTemplate
+# define MNotifySetTString MNotifySetString
+# define MNotifySetTTemplate MNotifySetTemplate
+# define MNotifyGetTParsedTemplate MNotifyGetParsedTemplate
+# define MNotifyHasTVariables MNotifyHasVariables
+# define MNotifyShowTVariables MNotifyShowVariables
+
+# define NFOPT_DEFTEMPL_TEXTT NFOPT_DEFTEMPL_TEXT
+# define NFOPT_DEFTEMPL_TITLET NFOPT_DEFTEMPL_TITLE
+
+# define NFOPT_VARIABLES_STRST NFOPT_VARIABLES_STRS
+# define NFOPT_VARIABLES_DESCRIPTIONS_STRST NFOPT_VARIABLES_DESCRIPTIONS_STRS
+# define NFOPT_DATA_STRST NFOPT_DATA_STRS
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __TEMPLATES_H__
diff --git a/Plugins/utils/utf8_helpers.h b/Plugins/utils/utf8_helpers.h index c48eb67..3eaf0f4 100644 --- a/Plugins/utils/utf8_helpers.h +++ b/Plugins/utils/utf8_helpers.h @@ -59,17 +59,24 @@ public: mir_free(utf8);
}
- char * get() const
+ char *detach()
+ {
+ char *ret = utf8;
+ utf8 = NULL;
+ return ret;
+ }
+
+ const char * get() const
{
return utf8;
}
- operator char *() const
+ operator const char *() const
{
return utf8;
}
- char operator[](int pos) const
+ const char & operator[](int pos) const
{
return utf8[pos];
}
@@ -161,7 +168,7 @@ public: return tchar;
}
- TCHAR operator[](int pos) const
+ TCHAR & operator[](int pos)
{
return tchar[pos];
}
@@ -221,7 +228,7 @@ public: return tchar;
}
- TCHAR operator[](int pos) const
+ const TCHAR & operator[](int pos) const
{
return tchar[pos];
}
@@ -285,7 +292,7 @@ public: return tchar;
}
- TCHAR operator[](int pos) const
+ const TCHAR & operator[](int pos) const
{
return tchar[pos];
}
@@ -336,7 +343,7 @@ public: return wchar;
}
- WCHAR operator[](int pos) const
+ const WCHAR & operator[](int pos) const
{
return wchar[pos];
}
@@ -397,7 +404,7 @@ public: return val;
}
- char operator[](int pos) const
+ const char & operator[](int pos) const
{
return val[pos];
}
@@ -461,7 +468,7 @@ public: return val;
}
- WCHAR operator[](int pos) const
+ const WCHAR & operator[](int pos) const
{
return val[pos];
}
@@ -543,7 +550,7 @@ public: #endif
}
- operator const BSTR()
+ operator const BSTR() const
{
return bstr;
}
|