From 1ca120b165c2f2d9f521a04bfc31c7956d2ce422 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 17 Jul 2012 06:57:55 +0000 Subject: ContactsPlus, CountryFlags, CrashDumper: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@1000 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/ContactsPlus/contacts.cpp | 31 - plugins/ContactsPlus/contacts.h | 77 - plugins/ContactsPlus/contacts.rc | 191 - plugins/ContactsPlus/contacts.vcxproj | 22 +- plugins/ContactsPlus/contacts.vcxproj.filters | 22 +- plugins/ContactsPlus/contactsplus-translation.txt | 30 - .../ContactsPlus/docs/contactsplus-translation.txt | 30 + plugins/ContactsPlus/docs/readme_contacts.txt | 158 + plugins/ContactsPlus/main.cpp | 317 -- plugins/ContactsPlus/readme_contacts.txt | 158 - plugins/ContactsPlus/receive.cpp | 522 --- plugins/ContactsPlus/receive.h | 65 - plugins/ContactsPlus/res/contacts.rc | 191 + plugins/ContactsPlus/resource.h | 44 - plugins/ContactsPlus/send.cpp | 609 --- plugins/ContactsPlus/send.h | 110 - plugins/ContactsPlus/src/contacts.cpp | 31 + plugins/ContactsPlus/src/contacts.h | 77 + plugins/ContactsPlus/src/main.cpp | 317 ++ plugins/ContactsPlus/src/receive.cpp | 522 +++ plugins/ContactsPlus/src/receive.h | 65 + plugins/ContactsPlus/src/resource.h | 44 + plugins/ContactsPlus/src/send.cpp | 609 +++ plugins/ContactsPlus/src/send.h | 110 + plugins/ContactsPlus/src/utils.cpp | 832 ++++ plugins/ContactsPlus/src/utils.h | 86 + plugins/ContactsPlus/utils.cpp | 832 ---- plugins/ContactsPlus/utils.h | 86 - plugins/CountryFlags/countryflags-translation.txt | 17 - plugins/CountryFlags/countrylistext.cpp | 345 -- .../CountryFlags/docs/countryflags-translation.txt | 17 + plugins/CountryFlags/extraimg.cpp | 494 --- plugins/CountryFlags/flags.h | 90 - plugins/CountryFlags/flags.vcxproj | 31 +- plugins/CountryFlags/flags.vcxproj.filters | 25 +- plugins/CountryFlags/huffman.cpp | 506 --- plugins/CountryFlags/icons.cpp | 282 -- plugins/CountryFlags/ip2country.cpp | 327 -- plugins/CountryFlags/main.cpp | 122 - plugins/CountryFlags/res/resource.rc | 117 + plugins/CountryFlags/res/version.rc | 43 + plugins/CountryFlags/resource.h | 25 - plugins/CountryFlags/resource.rc | 128 - plugins/CountryFlags/src/countrylistext.cpp | 345 ++ plugins/CountryFlags/src/extraimg.cpp | 494 +++ plugins/CountryFlags/src/flags.h | 90 + plugins/CountryFlags/src/huffman.cpp | 506 +++ plugins/CountryFlags/src/icons.cpp | 282 ++ plugins/CountryFlags/src/ip2country.cpp | 327 ++ plugins/CountryFlags/src/main.cpp | 122 + plugins/CountryFlags/src/resource.h | 25 + plugins/CountryFlags/src/utils.cpp | 162 + plugins/CountryFlags/src/version.h | 31 + plugins/CountryFlags/utils.cpp | 162 - plugins/CountryFlags/version.h | 31 - plugins/CountryFlags/version.rc | 51 - plugins/CrashDumper/Vi show.ico | Bin 2550 -> 0 bytes plugins/CrashDumper/Vi to clipboard.ico | Bin 2550 -> 0 bytes plugins/CrashDumper/Vi to file.ico | Bin 2550 -> 0 bytes plugins/CrashDumper/Vi upload.ico | Bin 2550 -> 0 bytes plugins/CrashDumper/Vi.ico | Bin 6830 -> 0 bytes plugins/CrashDumper/bkstring.cpp | 188 - plugins/CrashDumper/bkstring.h | 276 -- plugins/CrashDumper/crshdmp.cpp | 434 -- plugins/CrashDumper/crshdmp.rc | 192 - plugins/CrashDumper/crshdmp_10.vcxproj | 37 +- plugins/CrashDumper/crshdmp_icons.cpp | 88 - plugins/CrashDumper/crshdmp_readme.txt | 379 -- plugins/CrashDumper/docs/crshdmp_readme.txt | 379 ++ .../CrashDumper/docs/svc_crshdmp-translation.txt | 54 + plugins/CrashDumper/dumper.cpp | 745 ---- plugins/CrashDumper/exhndlr.cpp | 207 - plugins/CrashDumper/res/Version.rc | 45 + plugins/CrashDumper/res/Vi show.ico | Bin 0 -> 2550 bytes plugins/CrashDumper/res/Vi to clipboard.ico | Bin 0 -> 2550 bytes plugins/CrashDumper/res/Vi to file.ico | Bin 0 -> 2550 bytes plugins/CrashDumper/res/Vi upload.ico | Bin 0 -> 2550 bytes plugins/CrashDumper/res/Vi.ico | Bin 0 -> 6830 bytes plugins/CrashDumper/res/crshdmp.rc | 151 + plugins/CrashDumper/resource.h | 34 - plugins/CrashDumper/sdkstuff.h | 124 - plugins/CrashDumper/src/bkstring.cpp | 188 + plugins/CrashDumper/src/bkstring.h | 278 ++ plugins/CrashDumper/src/crshdmp.cpp | 434 ++ plugins/CrashDumper/src/crshdmp_icons.cpp | 88 + plugins/CrashDumper/src/dumper.cpp | 745 ++++ plugins/CrashDumper/src/exhndlr.cpp | 207 + plugins/CrashDumper/src/resource.h | 34 + plugins/CrashDumper/src/sdkstuff.h | 124 + plugins/CrashDumper/src/ui.cpp | 327 ++ plugins/CrashDumper/src/upload.cpp | 292 ++ plugins/CrashDumper/src/utils.cpp | 836 ++++ plugins/CrashDumper/src/utils.h | 177 + plugins/CrashDumper/src/vc6/dbghelp.h | 4532 ++++++++++++++++++++ plugins/CrashDumper/src/vc6/dbghelp.lib | Bin 0 -> 48054 bytes plugins/CrashDumper/src/version.h | 3 + plugins/CrashDumper/svc_crshdmp-translation.txt | 54 - plugins/CrashDumper/ui.cpp | 327 -- plugins/CrashDumper/upload.cpp | 292 -- plugins/CrashDumper/utils.cpp | 836 ---- plugins/CrashDumper/utils.h | 177 - plugins/CrashDumper/vc6/dbghelp.h | 4532 -------------------- plugins/CrashDumper/vc6/dbghelp.lib | Bin 48054 -> 0 bytes plugins/CrashDumper/version.h | 3 - 104 files changed, 14594 insertions(+), 14610 deletions(-) delete mode 100644 plugins/ContactsPlus/contacts.cpp delete mode 100644 plugins/ContactsPlus/contacts.h delete mode 100644 plugins/ContactsPlus/contacts.rc delete mode 100644 plugins/ContactsPlus/contactsplus-translation.txt create mode 100644 plugins/ContactsPlus/docs/contactsplus-translation.txt create mode 100644 plugins/ContactsPlus/docs/readme_contacts.txt delete mode 100644 plugins/ContactsPlus/main.cpp delete mode 100644 plugins/ContactsPlus/readme_contacts.txt delete mode 100644 plugins/ContactsPlus/receive.cpp delete mode 100644 plugins/ContactsPlus/receive.h create mode 100644 plugins/ContactsPlus/res/contacts.rc delete mode 100644 plugins/ContactsPlus/resource.h delete mode 100644 plugins/ContactsPlus/send.cpp delete mode 100644 plugins/ContactsPlus/send.h create mode 100644 plugins/ContactsPlus/src/contacts.cpp create mode 100644 plugins/ContactsPlus/src/contacts.h create mode 100644 plugins/ContactsPlus/src/main.cpp create mode 100644 plugins/ContactsPlus/src/receive.cpp create mode 100644 plugins/ContactsPlus/src/receive.h create mode 100644 plugins/ContactsPlus/src/resource.h create mode 100644 plugins/ContactsPlus/src/send.cpp create mode 100644 plugins/ContactsPlus/src/send.h create mode 100644 plugins/ContactsPlus/src/utils.cpp create mode 100644 plugins/ContactsPlus/src/utils.h delete mode 100644 plugins/ContactsPlus/utils.cpp delete mode 100644 plugins/ContactsPlus/utils.h delete mode 100644 plugins/CountryFlags/countryflags-translation.txt delete mode 100644 plugins/CountryFlags/countrylistext.cpp create mode 100644 plugins/CountryFlags/docs/countryflags-translation.txt delete mode 100644 plugins/CountryFlags/extraimg.cpp delete mode 100644 plugins/CountryFlags/flags.h delete mode 100644 plugins/CountryFlags/huffman.cpp delete mode 100644 plugins/CountryFlags/icons.cpp delete mode 100644 plugins/CountryFlags/ip2country.cpp delete mode 100644 plugins/CountryFlags/main.cpp create mode 100644 plugins/CountryFlags/res/resource.rc create mode 100644 plugins/CountryFlags/res/version.rc delete mode 100644 plugins/CountryFlags/resource.h delete mode 100644 plugins/CountryFlags/resource.rc create mode 100644 plugins/CountryFlags/src/countrylistext.cpp create mode 100644 plugins/CountryFlags/src/extraimg.cpp create mode 100644 plugins/CountryFlags/src/flags.h create mode 100644 plugins/CountryFlags/src/huffman.cpp create mode 100644 plugins/CountryFlags/src/icons.cpp create mode 100644 plugins/CountryFlags/src/ip2country.cpp create mode 100644 plugins/CountryFlags/src/main.cpp create mode 100644 plugins/CountryFlags/src/resource.h create mode 100644 plugins/CountryFlags/src/utils.cpp create mode 100644 plugins/CountryFlags/src/version.h delete mode 100644 plugins/CountryFlags/utils.cpp delete mode 100644 plugins/CountryFlags/version.h delete mode 100644 plugins/CountryFlags/version.rc delete mode 100644 plugins/CrashDumper/Vi show.ico delete mode 100644 plugins/CrashDumper/Vi to clipboard.ico delete mode 100644 plugins/CrashDumper/Vi to file.ico delete mode 100644 plugins/CrashDumper/Vi upload.ico delete mode 100644 plugins/CrashDumper/Vi.ico delete mode 100644 plugins/CrashDumper/bkstring.cpp delete mode 100644 plugins/CrashDumper/bkstring.h delete mode 100644 plugins/CrashDumper/crshdmp.cpp delete mode 100644 plugins/CrashDumper/crshdmp.rc delete mode 100644 plugins/CrashDumper/crshdmp_icons.cpp delete mode 100644 plugins/CrashDumper/crshdmp_readme.txt create mode 100644 plugins/CrashDumper/docs/crshdmp_readme.txt create mode 100644 plugins/CrashDumper/docs/svc_crshdmp-translation.txt delete mode 100644 plugins/CrashDumper/dumper.cpp delete mode 100644 plugins/CrashDumper/exhndlr.cpp create mode 100644 plugins/CrashDumper/res/Version.rc create mode 100644 plugins/CrashDumper/res/Vi show.ico create mode 100644 plugins/CrashDumper/res/Vi to clipboard.ico create mode 100644 plugins/CrashDumper/res/Vi to file.ico create mode 100644 plugins/CrashDumper/res/Vi upload.ico create mode 100644 plugins/CrashDumper/res/Vi.ico create mode 100644 plugins/CrashDumper/res/crshdmp.rc delete mode 100644 plugins/CrashDumper/resource.h delete mode 100644 plugins/CrashDumper/sdkstuff.h create mode 100644 plugins/CrashDumper/src/bkstring.cpp create mode 100644 plugins/CrashDumper/src/bkstring.h create mode 100644 plugins/CrashDumper/src/crshdmp.cpp create mode 100644 plugins/CrashDumper/src/crshdmp_icons.cpp create mode 100644 plugins/CrashDumper/src/dumper.cpp create mode 100644 plugins/CrashDumper/src/exhndlr.cpp create mode 100644 plugins/CrashDumper/src/resource.h create mode 100644 plugins/CrashDumper/src/sdkstuff.h create mode 100644 plugins/CrashDumper/src/ui.cpp create mode 100644 plugins/CrashDumper/src/upload.cpp create mode 100644 plugins/CrashDumper/src/utils.cpp create mode 100644 plugins/CrashDumper/src/utils.h create mode 100644 plugins/CrashDumper/src/vc6/dbghelp.h create mode 100644 plugins/CrashDumper/src/vc6/dbghelp.lib create mode 100644 plugins/CrashDumper/src/version.h delete mode 100644 plugins/CrashDumper/svc_crshdmp-translation.txt delete mode 100644 plugins/CrashDumper/ui.cpp delete mode 100644 plugins/CrashDumper/upload.cpp delete mode 100644 plugins/CrashDumper/utils.cpp delete mode 100644 plugins/CrashDumper/utils.h delete mode 100644 plugins/CrashDumper/vc6/dbghelp.h delete mode 100644 plugins/CrashDumper/vc6/dbghelp.lib delete mode 100644 plugins/CrashDumper/version.h diff --git a/plugins/ContactsPlus/contacts.cpp b/plugins/ContactsPlus/contacts.cpp deleted file mode 100644 index a7ba2cdfbb..0000000000 --- a/plugins/ContactsPlus/contacts.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// -------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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 "contacts.h" - - -bool WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - hInst = hinstDLL; - return TRUE; -} diff --git a/plugins/ContactsPlus/contacts.h b/plugins/ContactsPlus/contacts.h deleted file mode 100644 index 742f577924..0000000000 --- a/plugins/ContactsPlus/contacts.h +++ /dev/null @@ -1,77 +0,0 @@ -// --------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -// --------------------------------------------------------------------------- - -#define _CRT_SECURE_NO_WARNINGS -#define _CRT_NONSTDC_NO_WARNINGS - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -//!!this is fake - this plugin maintains backward compatibility internally -#define MIRANDA_VER 0x0A00 - -#include "newpluginapi.h" -#include "m_system.h" -#include "m_protocols.h" -#include "m_protosvc.h" -#include "m_database.h" -#include "m_utils.h" -#include "m_langpack.h" -#include "m_skin.h" -#include "m_clist.h" -#include "m_clc.h" -#include "m_clui.h" -#include "m_addcontact.h" -#include "m_history.h" -#include "m_userinfo.h" -#include "m_button.h" -#include "m_contacts.h" -#include "m_message.h" -#include "statusmodes.h" -#include "win2k.h" - -#include "resource.h" - -#include "utils.h" -#include "send.h" -#include "receive.h" - -#define MODULENAME "SendReceiveContacts" - - -#define MS_CONTACTS_SEND "ContactsTransfer/SendContacts" -#define MS_CONTACTS_RECEIVE "ContactsTransfer/ReceiveContacts" - -// Global Variables -extern int g_UnicodeCore; -extern int g_NewProtoAPI; -extern int g_SendAckSupported; -extern int g_Utf8EventsSupported; diff --git a/plugins/ContactsPlus/contacts.rc b/plugins/ContactsPlus/contacts.rc deleted file mode 100644 index 3edfca49c4..0000000000 --- a/plugins/ContactsPlus/contacts.rc +++ /dev/null @@ -1,191 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -// Neutral resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) -#ifdef _WIN32 -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL -#pragma code_page(1250) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_SEND DIALOGEX 0, 0, 308, 242 -STYLE DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_VISIBLE | WS_CAPTION | - WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Send contacts" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - CONTROL "",IDC_PROTOCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,5,7, - 12,12 - LTEXT "",IDC_NAME,19,7,118,9,SS_NOPREFIX | SS_CENTERIMAGE - CONTROL "&A",IDC_ADD,"MButtonClass",WS_TABSTOP,231,5,16,14, - 0x18000000L - CONTROL "6",IDC_USERMENU,"MButtonClass",WS_TABSTOP,249,5,16,14, - 0x18000000L - CONTROL "&D",IDC_DETAILS,"MButtonClass",WS_TABSTOP,267,5,16,14, - 0x18000000L - CONTROL "&H",IDC_HISTORY,"MButtonClass",WS_TABSTOP,285,5,16,14, - 0x18000000L - CONTROL "Choose contacts to be send:",IDC_STATIC,"Static", - SS_SIMPLE | WS_GROUP,5,20,300,10,WS_EX_TRANSPARENT - DEFPUSHBUTTON "&Send",IDOK,195,220,50,14 - PUSHBUTTON "Cancel",IDCANCEL,249,220,50,14 - CONTROL "",IDC_LIST,"CListControl",WS_TABSTOP | 0x3da,5,30,298, - 185,WS_EX_CLIENTEDGE - PUSHBUTTON "&Select All",ID_SELECTALL,5,220,50,14 -END - -IDD_RECEIVE DIALOGEX 0, 0, 320, 225 -STYLE DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | - WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | - WS_SYSMENU | WS_THICKFRAME -CAPTION "Received contacts" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "",IDC_PROTOCOL,"Button",BS_OWNERDRAW | WS_TABSTOP,5,7, - 12,12 - LTEXT "",IDC_NAME,19,7,118,9,SS_NOPREFIX | SS_CENTERIMAGE - CONTROL "&A",IDC_ADD,"MButtonClass",WS_TABSTOP,243,5,16,14, - 0x18000000L - CONTROL "6",IDC_USERMENU,"MButtonClass",WS_TABSTOP,261,5,16,14, - 0x18000000L - CONTROL "&D",IDC_DETAILS,"MButtonClass",WS_TABSTOP,279,5,16,14, - 0x18000000L - CONTROL "&H",IDC_HISTORY,"MButtonClass",WS_TABSTOP,297,5,16,14, - 0x18000000L - CONTROL "",IDC_CONTACTS,"SysListView32",LVS_REPORT | - LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | - WS_BORDER | WS_TABSTOP,5,22,310,178 - CONTROL "Add to &group:",IDC_ENABLEGROUPS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,205,80,12 - COMBOBOX IDC_GROUPS,90,205,72,140,CBS_DROPDOWNLIST | CBS_SORT | - WS_VSCROLL | WS_TABSTOP | 0x8000 - PUSHBUTTON "&Add",IDOK,169,204,46,14,WS_DISABLED - PUSHBUTTON "&Details",IDDETAILS,215,204,46,14,WS_DISABLED - PUSHBUTTON "Close",IDCANCEL,261,204,52,14 -END - -IDD_MSGSENDERROR DIALOGEX 0, 0, 187, 97 -STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | WS_POPUP | - WS_VISIBLE | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_CONTROLPARENT -CAPTION "Contacts send error" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "An error has occured. The protocol reported the following error:", - IDC_STATIC,5,5,177,28 - DEFPUSHBUTTON "Try again",IDOK,22,78,63,14 - PUSHBUTTON "Cancel",IDCANCEL,104,78,61,14 - EDITTEXT IDC_ERRORTEXT,5,37,177,35,ES_MULTILINE | ES_READONLY | - WS_VSCROLL -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO MOVEABLE PURE -BEGIN - IDD_SEND, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 300 - TOPMARGIN, 7 - BOTTOMMARGIN, 235 - END - - IDD_RECEIVE, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 313 - TOPMARGIN, 7 - BOTTOMMARGIN, 218 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_CONTACTMENU MENUEX DISCARDABLE -BEGIN - POPUP "Popup", 0,MFT_STRING,MFS_ENABLED - BEGIN - MENUITEM "Add to List", 111,MFT_STRING,MFS_ENABLED - MENUITEM "User Details", 113,MFT_STRING, - MFS_ENABLED | MFS_UNCHECKED | MFS_UNHILITE | MFS_DEFAULT - MENUITEM MFT_SEPARATOR - MENUITEM "Send Message", 112,MFT_STRING,MFS_ENABLED - END -END - - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,2,0 - PRODUCTVERSION 0,8,0,0 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "Requires Miranda 0.3+; Recommended Miranda 0.4+\0" - VALUE "CompanyName", "Jokusoftware, Dusk Horizon\0" - VALUE "FileDescription", "Send/Receive Contacts plugin for Miranda (Unicode 2in1)\0" - VALUE "FileVersion", "1, 5, 2, 0\0" - VALUE "InternalName", "contacts+\0" - VALUE "LegalCopyright", "Copyright (C) 2004-2008 Jokusoftware, Original code (C) 2002 Dominus Procellarum\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "contacts.dll\0" - VALUE "ProductName", "Send/Receive Contacts plugin for Miranda\0" - VALUE "ProductVersion", "0, 8, 0, 0\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // !_MAC - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_CONTACTS ICON DISCARDABLE "res\\SendContacts.ico" -#endif // Neutral resources -///////////////////////////////////////////////////////////////////////////// diff --git a/plugins/ContactsPlus/contacts.vcxproj b/plugins/ContactsPlus/contacts.vcxproj index 57d0cfbacb..1ebfa955a2 100644 --- a/plugins/ContactsPlus/contacts.vcxproj +++ b/plugins/ContactsPlus/contacts.vcxproj @@ -173,23 +173,23 @@ - - + + Create - - - + + + - - - - - + + + + + - + diff --git a/plugins/ContactsPlus/contacts.vcxproj.filters b/plugins/ContactsPlus/contacts.vcxproj.filters index 8270d92a72..f0fb5d4da0 100644 --- a/plugins/ContactsPlus/contacts.vcxproj.filters +++ b/plugins/ContactsPlus/contacts.vcxproj.filters @@ -15,41 +15,41 @@ - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Resource Files diff --git a/plugins/ContactsPlus/contactsplus-translation.txt b/plugins/ContactsPlus/contactsplus-translation.txt deleted file mode 100644 index 373fe04d50..0000000000 --- a/plugins/ContactsPlus/contactsplus-translation.txt +++ /dev/null @@ -1,30 +0,0 @@ -; Common strings that belong to many files -;[] - -; ../../plugins/ContactsPlus/contacts.rc -;[&A] -;[&Add] -;[&D] -;[&Details] -;[&H] -;[&Select All] -;[&Send] -;[Add to &group:] -;[Add to List] -;[An error has occured. The protocol reported the following error:] -;[Cancel] -;[Choose contacts to be send:] -;[Close] -;[Contacts send error] -;[Popup] -;[Received contacts] -;[Send Message] -;[Send contacts] -;[Try again] -;[User Details] - -; ../../plugins/ContactsPlus/main.cpp -;[Contacts] -;[Contacts received from] -;[Incoming Contacts] -;[Outgoing Contacts] diff --git a/plugins/ContactsPlus/docs/contactsplus-translation.txt b/plugins/ContactsPlus/docs/contactsplus-translation.txt new file mode 100644 index 0000000000..373fe04d50 --- /dev/null +++ b/plugins/ContactsPlus/docs/contactsplus-translation.txt @@ -0,0 +1,30 @@ +; Common strings that belong to many files +;[] + +; ../../plugins/ContactsPlus/contacts.rc +;[&A] +;[&Add] +;[&D] +;[&Details] +;[&H] +;[&Select All] +;[&Send] +;[Add to &group:] +;[Add to List] +;[An error has occured. The protocol reported the following error:] +;[Cancel] +;[Choose contacts to be send:] +;[Close] +;[Contacts send error] +;[Popup] +;[Received contacts] +;[Send Message] +;[Send contacts] +;[Try again] +;[User Details] + +; ../../plugins/ContactsPlus/main.cpp +;[Contacts] +;[Contacts received from] +;[Incoming Contacts] +;[Outgoing Contacts] diff --git a/plugins/ContactsPlus/docs/readme_contacts.txt b/plugins/ContactsPlus/docs/readme_contacts.txt new file mode 100644 index 0000000000..f3ae933be3 --- /dev/null +++ b/plugins/ContactsPlus/docs/readme_contacts.txt @@ -0,0 +1,158 @@ +About +----- + +Send and receive contacts ui +Version 1.5.2.0 +by Joe Kucera aka Jokusoftware +Original Code by Todor Totev aka Dominus Procellarum +for use with Miranda IM 0.3.3+ +Best for Miranda IM 0.4+ + + +Description +----------- + +This plugin allows you to send and receive contacts. +It is protocol independent, although currently the only +protocol supporting contacts transfer is ICQ. + + +Installation +------------ + +For the contactsp.zip zip archive - + Extract contacts.dll to Miranda plugin folder - + usually this is C:\Program Files\Miranda\Plugins. + All other files are not mandatory and can go to Miranda folder. + + +Source +------ + +The source code for this plugin can be downloaded from Miranda IM +website http://addons.miranda-im.org. + + +License +------- + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. +3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. +4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +For more information, e-mail jokusoftware@miranda-im.org + + +Version history +--------------- +1.0.11.0 + initial release - working ui, but M is still crashing +1.0.12.0 + 20-may night build of M - underlying code is OK, so i can continue this plugin + remove inverse logic in MirandaPluginInfo() + removed #include "win2k.h" for cleaner build + attempt to show more user info on receive contacts +1.0.13.0 + cleaned main.cpp + added icon to dialogue windows +1.0.14.0 + Nick / UIN swapped upon showing received contacts /silly me/ + bigger size of nick string allowed to accomodate non-english nicks /cyrrilic letters requires 2 times more bytes/ + added icon for menu item +1.0.15.0 + list columns default size is more convinient + save restore window position / size +1.0.16.0 + receive dlg is resizable one /thanks to WTL there was virtually no code to write/ +1.0.17.0 + add button is enabled only when at least one item in the list view is checked-in +1.0.18.0 + more translate()-friendly + at last contacts are permanently added to DB +1.0.19.0 + receive window is now being put on top + lots of big-fixes +1.1.0.0 + source beautify + receive user iface and internal dependancies re-design + now only contacts which details are requested are being added to the DB + std::vector is used instead of std::deque for 10KB smaller dll + this should be the official release build + you can get detailed info about contacts being sent to you + more bug fixes +1.2.0.0 + bugfix - contacts are always being added outside any group /forget actually writing to the DB/ + sending contacts is now a Miranda service, accessible via m_contacts.h + implemented contactlist event, no more popup windows + NOTE: the langpack is modified, because my english is at least questionable and some items are now obsolete + +1.4.0.0 (New developer: Joe @ Whale, jokusoftware@miranda-im.org) + now fully protocol independent + made sending with full acknowledgement (needs miranda 0.3.4alpha) & improved Send Dialog + now sent contacts are added to history (can be viewed by e.g. History++) + improved Receive Dialog - added popup & some convenient functions, display more info (like ICQ) + many fixes +1.4.1.3 + fixed multipacket sending (if 15 contacts, do not try to send empty packet) + optimisations (reimplemented many structures, size cut by 20kB) + when contact gets deleted close his send window + redesigned Send dialog - more nice & effective (show only contacts of the same protocol + many more) + grouplist on receive dialog now gets updated +1.4.1.7 + redesigned and improved Received dialog (get rid of WTL & MFC) + empty groups in send dialog are hidden according to clui setting + fixed multi-packet error handling + fixed crashes on exit (thanks to Ghazan) + small fixes +1.4.1.8 + fixed received dialog not showed on some systems + other small fixes +1.4.2.0 + fixed memory leak on any event received (thx to Ghazan) + fixed other small memory leaks + popup menu on Received dialog gets translated now + added DBE3++ Known Modules support +1.5.0.0 + many internal optimisations + added Unicode 2in1 support + added support for Unicode ready DB contacts events + added Updater plug-in support +1.5.1.0 + added support for per-contact contacts API capabilities + improved compatibility with unicode database API + added support for new clist groups API + several internal fixes & improvements +1.5.2.0 + fixed possible crash during contacts send (with older Miranda IM) + fixed compatibility with the new Account API introduced in Miranda IM 0.8 + + +Translation +----------- + +Contacts plugin can be translated via the Miranda language files. +The required strings are provided in langpack_contacts.txt file. diff --git a/plugins/ContactsPlus/main.cpp b/plugins/ContactsPlus/main.cpp deleted file mode 100644 index da43554c29..0000000000 --- a/plugins/ContactsPlus/main.cpp +++ /dev/null @@ -1,317 +0,0 @@ -// -------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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 "contacts.h" - - -HINSTANCE hInst; - -int hLangpack; - -int g_NewProtoAPI = TRUE; - -int g_SendAckSupported = TRUE; -int g_Utf8EventsSupported = TRUE; - -HANDLE ghSendWindowList; -HANDLE ghRecvWindowList; -gAckList gaAckData; - -HANDLE hServiceSend; -HANDLE hServiceReceive; - -HANDLE hHookModulesLoaded = NULL; -HANDLE hHookDBEventAdded = NULL; -HANDLE hHookContactDeleted = NULL; -HANDLE hHookContactSettingChanged = NULL; -HANDLE hHookPreBuildContactMenu = NULL; - -HANDLE hContactMenuItem = NULL; - -int g_UnicodeCore; - -PLUGININFOEX pluginInfo = { - sizeof(PLUGININFOEX), - "Send/Receive Contacts+", - PLUGIN_MAKE_VERSION(1,5,2,0), - "Allows you to send and receive contacts", - "Joe Kucera, Todor Totev", - "jokusoftware@miranda-im.org", - "(C) 2004-2008 Joe Kucera, Original Code (C) 2002 Dominus Procellarum", - "http://addons.miranda-im.org/details.php?action=viewfile&id=1253", - UNICODE_AWARE, - {0x0324785E, 0x74CE, 0x4600, {0xB7, 0x81, 0x85, 0x17, 0x73, 0xB3, 0xEF, 0xC5 } } // {0324785E-74CE-4600-B781-851773B3EFC5} -}; - - -static int HookDBEventAdded(WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact = (HANDLE)wParam; - HANDLE hDbEvent = (HANDLE)lParam; - //process the event - DBEVENTINFO dbe = {0}; - - dbe.cbSize = sizeof(DBEVENTINFO); - //get event details - CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe); - //check if we should process the event - if (dbe.flags & (DBEF_SENT|DBEF_READ) || dbe.eventType != EVENTTYPE_CONTACTS) return 0; - //get event contents - dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0); - if (dbe.cbBlob != -1) - dbe.pBlob = (PBYTE)_alloca(dbe.cbBlob); - CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe); - //play received sound - SkinPlaySound("RecvContacts"); - { //add event to the contact list - CLISTEVENT cle = {0}; - TCHAR caToolTip[128]; - - cle.cbSize = sizeof(cle); - cle.hContact = hContact; - cle.hDbEvent = hDbEvent; - cle.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS)); - cle.pszService = MS_CONTACTS_RECEIVE; - - WCHAR tmp[MAX_PATH]; - _snprintfT(caToolTip, 64, "%s %s", SRCTranslateT("Contacts received from", tmp), (TCHAR*)GetContactDisplayNameT(hContact)); - - cle.ptszTooltip = caToolTip; - if (g_UnicodeCore) - cle.flags |= CLEF_UNICODE; - CallService(MS_CLIST_ADDEVENT, 0, (LPARAM)&cle); - } - return 0; //continue processing by other hooks -} - - -static void ProcessUnreadEvents(void) -{ - DBEVENTINFO dbei = {0}; - HANDLE hDbEvent,hContact; - - dbei.cbSize = sizeof(dbei); - - hContact = SRCFindFirstContact(); - while (hContact) - { - hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDFIRSTUNREAD,(WPARAM)hContact,0); - - while (hDbEvent) - { - dbei.cbBlob=0; - CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei); - if (!(dbei.flags&(DBEF_SENT|DBEF_READ)) && dbei.eventType==EVENTTYPE_CONTACTS) - { //process the event - HookDBEventAdded((WPARAM)hContact, (LPARAM)hDbEvent); - } - hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0); - } - hContact = SRCFindNextContact(hContact); - } -} - - -static bool CheckContactsServiceSupport(const char* szProto) -{ - if (g_NewProtoAPI) - { // there is no way to determine if the service exists (only proto_interface call is supported by 0.8+) - if (CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_CONTACTSEND) - return true; - } - else - { // check the real send service (only 0.7.x and older) - char serstr[MAX_PATH+30]; - - strcpy(serstr, szProto); - strcat(serstr, PSS_CONTACTS); - if (ServiceExists(serstr)) - return true; - } - return false; -} - - -static int HookPreBuildContactMenu(WPARAM wParam, LPARAM lParam) -{ - HANDLE hContact = (HANDLE)wParam; - char* szProto = GetContactProto(hContact); - int bVisible = FALSE; - - if (szProto && CheckContactsServiceSupport(szProto)) - { // known protocol, protocol supports contacts sending - // check the selected contact if it supports contacts receive - if (CallProtoService(szProto, PS_GETCAPS, PFLAG_MAXCONTACTSPERPACKET, (LPARAM)hContact)) - bVisible = TRUE; - } - - { // update contact menu item's visibility - CLISTMENUITEM mi = {0}; - - mi.cbSize = sizeof(mi); - if (bVisible) - mi.flags = CMIM_FLAGS; - else - mi.flags = CMIM_FLAGS | CMIF_HIDDEN; - - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hContactMenuItem, (LPARAM)&mi); - } - - return 0; -} - - -static int HookModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - char* modules[2] = {0}; - WCHAR tmp[MAX_PATH]; - - modules[0] = MODULENAME; - CallService("DBEditorpp/RegisterModule",(WPARAM)modules,(LPARAM)1); - - CLISTMENUITEM mi = {0}; - mi.cbSize = sizeof(mi); - mi.ptszName = SRCTranslateT("Contacts", tmp); - mi.position = -2000009990; //position in menu - mi.flags = CMIF_KEEPUNTRANSLATED; - if (g_UnicodeCore) - mi.flags |= CMIF_UNICODE; - mi.pszService = MS_CONTACTS_SEND; - mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS)); - hContactMenuItem = Menu_AddContactMenuItem(&mi); - - hHookPreBuildContactMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, HookPreBuildContactMenu); - - ghSendWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); // no need to destroy this - ghRecvWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); // no need to destroy this - - - ProcessUnreadEvents(); - return 0; -} - - -static int HookContactSettingChanged(WPARAM wParam, LPARAM lParam) -{ - DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam; - char *szProto = GetContactProto((HANDLE)wParam); - - if (strcmpnull(cws->szModule,"CList") && strcmpnull(cws->szModule, szProto)) return 0; - - WindowList_Broadcast(ghSendWindowList,DM_UPDATETITLE,0,0); - WindowList_Broadcast(ghRecvWindowList,DM_UPDATETITLE,0,0); - - return 0; -} - - -static int HookContactDeleted(WPARAM wParam, LPARAM lParam) -{ // if our contact gets deleted close his window - HWND h = WindowList_Find(ghSendWindowList,(HANDLE)wParam); - - if (h) - { - SendMessageT(h,WM_CLOSE,0,0); - } - - while (h = WindowList_Find(ghRecvWindowList, (HANDLE)wParam)) - { // since we hack the window list - more windows for one contact, we need to close them all - SendMessageT(h, WM_CLOSE,0,0); - } - return 0; -} - - -static INT_PTR ServiceSendCommand(WPARAM wParam, LPARAM lParam) -{ - HWND hWnd; - //find window for hContact - hWnd = WindowList_Find(ghSendWindowList, (HANDLE)wParam); - - if (!hWnd) - CreateDialogParamT(hInst, MAKEINTRESOURCE(IDD_SEND), NULL, SendDlgProc, (LPARAM)(HANDLE)wParam); - else - { - SetForegroundWindow(hWnd); - SetFocus(hWnd); - } - return 0; -} - -static INT_PTR ServiceReceiveCommand(WPARAM wParam, LPARAM lParam) -{ - CLISTEVENT* pcle = (CLISTEVENT*)lParam; - - CreateDialogParamT(hInst, MAKEINTRESOURCE(IDD_RECEIVE), NULL, RecvDlgProc, (LPARAM)pcle); - - return 0; -} - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_SRCONTACTS, MIID_LAST}; - -extern "C" __declspec(dllexport) int Load(void) -{ - mir_getLP(&pluginInfo); - InitCommonControls(); - InitI18N(); - - { // Are we running under unicode Miranda core ? - char szVer[MAX_PATH]; - - CallService(MS_SYSTEM_GETVERSIONTEXT, MAX_PATH, (LPARAM)szVer); - _strlwr(szVer); - g_UnicodeCore = (strstr(szVer, "unicode") != NULL); - } - //init hooks - hHookModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, HookModulesLoaded); - hHookDBEventAdded = HookEvent(ME_DB_EVENT_ADDED, HookDBEventAdded); - hHookContactDeleted = HookEvent(ME_DB_CONTACT_DELETED, HookContactDeleted); - hHookContactSettingChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, HookContactSettingChanged); - //create services - hServiceSend = CreateServiceFunction(MS_CONTACTS_SEND, ServiceSendCommand); - hServiceReceive = CreateServiceFunction(MS_CONTACTS_RECEIVE, ServiceReceiveCommand); - //define event sounds - SkinAddNewSound("RecvContacts", LPGEN("Incoming Contacts"), "contacts.wav"); - SkinAddNewSound("SentContacts", LPGEN("Outgoing Contacts"), "ocontacts.wav"); - - return 0; -} - -extern "C" __declspec(dllexport) int Unload(void) -{ - UnhookEvent(hHookModulesLoaded); - UnhookEvent(hHookDBEventAdded); - UnhookEvent(hHookContactDeleted); - UnhookEvent(hHookContactSettingChanged); - UnhookEvent(hHookPreBuildContactMenu); - - DestroyServiceFunction(hServiceSend); - DestroyServiceFunction(hServiceReceive); - - return 0; -} diff --git a/plugins/ContactsPlus/readme_contacts.txt b/plugins/ContactsPlus/readme_contacts.txt deleted file mode 100644 index f3ae933be3..0000000000 --- a/plugins/ContactsPlus/readme_contacts.txt +++ /dev/null @@ -1,158 +0,0 @@ -About ------ - -Send and receive contacts ui -Version 1.5.2.0 -by Joe Kucera aka Jokusoftware -Original Code by Todor Totev aka Dominus Procellarum -for use with Miranda IM 0.3.3+ -Best for Miranda IM 0.4+ - - -Description ------------ - -This plugin allows you to send and receive contacts. -It is protocol independent, although currently the only -protocol supporting contacts transfer is ICQ. - - -Installation ------------- - -For the contactsp.zip zip archive - - Extract contacts.dll to Miranda plugin folder - - usually this is C:\Program Files\Miranda\Plugins. - All other files are not mandatory and can go to Miranda folder. - - -Source ------- - -The source code for this plugin can be downloaded from Miranda IM -website http://addons.miranda-im.org. - - -License -------- - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the copyright - notice, this list of conditions and the following disclaimer. -2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. -3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. -4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS -OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -For more information, e-mail jokusoftware@miranda-im.org - - -Version history ---------------- -1.0.11.0 - initial release - working ui, but M is still crashing -1.0.12.0 - 20-may night build of M - underlying code is OK, so i can continue this plugin - remove inverse logic in MirandaPluginInfo() - removed #include "win2k.h" for cleaner build - attempt to show more user info on receive contacts -1.0.13.0 - cleaned main.cpp - added icon to dialogue windows -1.0.14.0 - Nick / UIN swapped upon showing received contacts /silly me/ - bigger size of nick string allowed to accomodate non-english nicks /cyrrilic letters requires 2 times more bytes/ - added icon for menu item -1.0.15.0 - list columns default size is more convinient - save restore window position / size -1.0.16.0 - receive dlg is resizable one /thanks to WTL there was virtually no code to write/ -1.0.17.0 - add button is enabled only when at least one item in the list view is checked-in -1.0.18.0 - more translate()-friendly - at last contacts are permanently added to DB -1.0.19.0 - receive window is now being put on top - lots of big-fixes -1.1.0.0 - source beautify - receive user iface and internal dependancies re-design - now only contacts which details are requested are being added to the DB - std::vector is used instead of std::deque for 10KB smaller dll - this should be the official release build - you can get detailed info about contacts being sent to you - more bug fixes -1.2.0.0 - bugfix - contacts are always being added outside any group /forget actually writing to the DB/ - sending contacts is now a Miranda service, accessible via m_contacts.h - implemented contactlist event, no more popup windows - NOTE: the langpack is modified, because my english is at least questionable and some items are now obsolete - -1.4.0.0 (New developer: Joe @ Whale, jokusoftware@miranda-im.org) - now fully protocol independent - made sending with full acknowledgement (needs miranda 0.3.4alpha) & improved Send Dialog - now sent contacts are added to history (can be viewed by e.g. History++) - improved Receive Dialog - added popup & some convenient functions, display more info (like ICQ) - many fixes -1.4.1.3 - fixed multipacket sending (if 15 contacts, do not try to send empty packet) - optimisations (reimplemented many structures, size cut by 20kB) - when contact gets deleted close his send window - redesigned Send dialog - more nice & effective (show only contacts of the same protocol + many more) - grouplist on receive dialog now gets updated -1.4.1.7 - redesigned and improved Received dialog (get rid of WTL & MFC) - empty groups in send dialog are hidden according to clui setting - fixed multi-packet error handling - fixed crashes on exit (thanks to Ghazan) - small fixes -1.4.1.8 - fixed received dialog not showed on some systems - other small fixes -1.4.2.0 - fixed memory leak on any event received (thx to Ghazan) - fixed other small memory leaks - popup menu on Received dialog gets translated now - added DBE3++ Known Modules support -1.5.0.0 - many internal optimisations - added Unicode 2in1 support - added support for Unicode ready DB contacts events - added Updater plug-in support -1.5.1.0 - added support for per-contact contacts API capabilities - improved compatibility with unicode database API - added support for new clist groups API - several internal fixes & improvements -1.5.2.0 - fixed possible crash during contacts send (with older Miranda IM) - fixed compatibility with the new Account API introduced in Miranda IM 0.8 - - -Translation ------------ - -Contacts plugin can be translated via the Miranda language files. -The required strings are provided in langpack_contacts.txt file. diff --git a/plugins/ContactsPlus/receive.cpp b/plugins/ContactsPlus/receive.cpp deleted file mode 100644 index 3d3fb2f773..0000000000 --- a/plugins/ContactsPlus/receive.cpp +++ /dev/null @@ -1,522 +0,0 @@ -// -------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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 "contacts.h" - - -/* TRecvContactsData */ - -TReceivedItem* TRecvContactsData::AddReceivedItem() { - int iItem = cbReceived; - - cbReceived++; - maReceived = (TReceivedItem**)realloc(maReceived, cbReceived*sizeof(TReceivedItem*)); - maReceived[iItem] = new TReceivedItem(); - - return maReceived[iItem]; -} - - -static int RecvDlg_Resize(HWND hwndDlg,LPARAM lParam,UTILRESIZECONTROL *urc) -{ - switch (urc->wId) - { - case IDC_CONTACTS: - return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; - break; - case IDOK: - case IDDETAILS: - case IDC_ENABLEGROUPS: - case IDC_GROUPS: - return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; - break; - case IDC_ADD: - case IDC_HISTORY: - case IDC_USERMENU: - case IDC_DETAILS: - return RD_ANCHORX_RIGHT | RD_ANCHORY_TOP; - break; - case IDCANCEL: - return RD_ANCHORY_BOTTOM | RD_ANCHORX_RIGHT; - break; - } - return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; // default -} - - -static char* ListView_GetItemTextEx(HWND hLV, int iItem, int iSubItem) -{ - LVITEM lvi = {0}; - - lvi.mask = LVIF_TEXT; - lvi.iSubItem = iSubItem; - lvi.cchTextMax = 64; - lvi.pszText = (char*)malloc(lvi.cchTextMax); - while (SendMessageT(hLV, LVM_GETITEMTEXT, iItem, (LPARAM)&lvi) == lvi.cchTextMax - 1) - { // loop until the returned size is smaller than buffer size - SAFE_FREE((void**)&lvi.pszText); - lvi.cchTextMax += 64; - lvi.pszText = (char*)malloc(lvi.cchTextMax); - } - return lvi.pszText; -} - - -static void EnableGroupCombo(HWND hwndDlg) -{ - EnableDlgItem(hwndDlg, IDC_GROUPS, SendMessageT(GetDlgItem(hwndDlg, IDC_ENABLEGROUPS), BM_GETCHECK, 0, 0)); -} - - -static void RebuildGroupCombo(HWND hwndDlg) -{ - DBVARIANT dbv = {0}; - char caGroupId[33]; - int bHasGroups = !DBGetContactSettingT(NULL, "CListGroups", "0", &dbv); - HWND hGroupsCombo = GetDlgItem(hwndDlg, IDC_GROUPS); - - DBFreeVariant(&dbv); - if (bHasGroups) - { - int curs = SendMessageT(hGroupsCombo, CB_GETCURSEL, 0, 0); - TCHAR* curst; - - EnableDlgItem(hwndDlg, IDC_ENABLEGROUPS, TRUE); - EnableGroupCombo(hwndDlg); - - if (curs != CB_ERR) - { - curst = (char*)_alloca((SendMessageT(hGroupsCombo, CB_GETLBTEXTLEN, curs, 0) + 1) * sizeof(WCHAR)); - SendMessageT(hGroupsCombo, CB_GETLBTEXT, curs, (LPARAM)curst); - } - SendMessageT(hGroupsCombo, CB_RESETCONTENT, 0, 0); - - for (int groupId=0; ; groupId++) - { - itoa(groupId, caGroupId, 10); - TCHAR* szGroup = DBGetContactSettingStringT(NULL, "CListGroups", caGroupId, NULL); - int nPrefix = g_UnicodeCore ? sizeof(WCHAR) : sizeof(char); - if (!szGroup) break; - int nIndex = SendMessageT(hGroupsCombo, CB_ADDSTRING, 0, (LPARAM)szGroup + nPrefix); - SendMessageT(hGroupsCombo, CB_SETITEMDATA, nIndex, groupId+1); - SAFE_FREE((void**)&szGroup); - } - if (curs != CB_ERR) - SendMessageT(hGroupsCombo, CB_SELECTSTRING, -1, (LPARAM)curst); - else - SendMessageT(hGroupsCombo, CB_SETCURSEL, 0, 0); - } - else - { // no groups available - EnableDlgItem(hwndDlg, IDC_ENABLEGROUPS, FALSE); - EnableDlgItem(hwndDlg, IDC_GROUPS, FALSE); - } -} - - -static HANDLE CreateTemporaryContactForItem(HWND hwndDlg, TRecvContactsData* wndData, int iItem) -{ - char* caUIN = ListView_GetItemTextEx(GetDlgItem(hwndDlg, IDC_CONTACTS), iItem, 0); - char* szProto = GetContactProto(wndData->mhContact); - wndData->rhSearch = (HANDLE)CallProtoService(szProto, PS_BASICSEARCH, 0, (LPARAM)caUIN); // find it - SAFE_FREE((void**)&wndData->haUin); - wndData->haUin = caUIN; - for (int j = 0; j < wndData->cbReceived; j++) - if (!strcmpnull(wndData->maReceived[j]->mcaUIN, caUIN)) - return (HANDLE)CallProtoService(szProto, PS_ADDTOLISTBYEVENT, MAKEWPARAM(PALF_TEMPORARY, j), (LPARAM)wndData->mhDbEvent); - return NULL; -} - - -void RecvListView_AddColumn(HWND hList, int nWidth, const char* szTitle, int nTranslate, int nItem) { - LVCOLUMN col; - WCHAR tmp[MAX_PATH]; - - - col.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; - col.fmt = LVCFMT_LEFT; - col.cx = nWidth; - if (nTranslate) { - col.pszText = SRCTranslateT(szTitle, tmp); - } - else { - if (!szTitle) szTitle = "UID"; - col.pszText = ansi_to_tchar(szTitle, CallService(MS_LANGPACK_GETCODEPAGE, 0, 0)); - } - col.iSubItem = nItem; - ListView_InsertColumnT(hList, nItem, &col); - if (!nTranslate) - SAFE_FREE((void**)&col.pszText); -} - - -INT_PTR CALLBACK RecvDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TRecvContactsData* wndData = (TRecvContactsData*)GetWindowLongPtr(hwndDlg, DWLP_USER); - - switch (msg) - { - case WM_INITDIALOG: - { - CLISTEVENT* pcle = (CLISTEVENT*)lParam; /// got it - - TranslateDialogDefault(hwndDlg); - WindowList_Add(ghRecvWindowList, hwndDlg, pcle->hContact); - SendMessageT(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); - EnableDlgItem(hwndDlg, IDOK, FALSE); - EnableDlgItem(hwndDlg, IDDETAILS, FALSE); - wndData = new TRecvContactsData(pcle->hContact); - SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)wndData); - wndData->mhDbEvent = pcle->hDbEvent; /// initialized, pcle not needed anymore - wndData->mhListIcon = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLORDDB|ILC_MASK, 0, 1); - wndData->mhPopup = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTACTMENU)); - TranslateMenu(wndData->mhPopup); - wndData->hHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_EVENTSENT); - - char *szProto = GetContactProto(wndData->mhContact); - - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); - ListView_SetExtendedListViewStyle(hLV, LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT); - // add columns - RecvListView_AddColumn(hLV, 120, (char*)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDTEXT, 0), FALSE, 0); - RecvListView_AddColumn(hLV, 100, "Nick", TRUE, 1); - RecvListView_AddColumn(hLV, 100, "First Name", TRUE, 2); - RecvListView_AddColumn(hLV, 100, "Last Name", TRUE, 3); - - // fill in groups - SendMessageT(GetDlgItem(hwndDlg, IDC_ENABLEGROUPS), BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); - RebuildGroupCombo(hwndDlg); - - { // fill listview with received contacts - DBEVENTINFO dbe = {0}; - - dbe.cbSize = sizeof(DBEVENTINFO); - dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)wndData->mhDbEvent, 0); - if (dbe.cbBlob != -1) // this marks an invalid hDbEvent - all smashed anyway... - dbe.pBlob = (PBYTE)_alloca(dbe.cbBlob); - CallService(MS_DB_EVENT_GET, (WPARAM)wndData->mhDbEvent, (LPARAM)&dbe); - char* pcBlob = (char*)dbe.pBlob; - char* pcEnd = (char*)dbe.pBlob + dbe.cbBlob; - - HICON hiProto = LoadContactProtoIcon(wndData->mhContact); - ImageList_AddIcon(wndData->mhListIcon, hiProto); - DestroyIcon(hiProto); // imagelist copied the resource - ListView_SetImageList(hLV, wndData->mhListIcon, LVSIL_SMALL); - LVITEM lvi = {0}; - lvi.iImage = 0; - lvi.mask = LVIF_TEXT | LVIF_IMAGE; - - for (int nItem = 0; ; nItem++) - { // Nick - int strsize = (int)strlennull(pcBlob); - TReceivedItem* pItem = wndData->AddReceivedItem(); - - if (dbe.flags & DBEF_UTF) - pItem->mcaNick = utf8_to_tchar((unsigned char*)pcBlob); - else - pItem->mcaNick = ansi_to_tchar(pcBlob); - pcBlob += strsize + 1; - // UIN - strsize = (int)strlennull(pcBlob); - pItem->mcaUIN = null_strdup(pcBlob); - pcBlob += strsize + 1; - // add to listview - lvi.iItem = nItem; - lvi.pszText = pItem->mcaUIN; - ListView_InsertItem(hLV, &lvi); // with image - ListView_SetItemTextT(hLV, nItem, 1, pItem->mcaNick); - // check for end of contacts - if (pcBlob >= pcEnd) - break; - } - } - // new dlg init - wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), "Add Contact Permanently to List"); - wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), "View User's Details"); - wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), "View User's History"); - wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), "User Menu"); - - SendMessageT(hwndDlg,DM_UPDATETITLE,0,0); - // new dialog init done - Utils_RestoreWindowPosition(hwndDlg, NULL, MODULENAME, ""); - return TRUE; - } - case WM_NOTIFY: - if (((LPNMHDR)lParam)->idFrom == IDC_CONTACTS) - { - switch (((LPNMHDR)lParam)->code) - { - case NM_DBLCLK: - { - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); - if (ListView_GetSelectedCount(hLV) != 1) break; // if not clicking on item, bye - wndData->iPopupItem = ListView_GetNextItem(hLV, -1, LVNI_ALL|LVNI_SELECTED); - if (wndData->iPopupItem == -1) break; // if no item selected no user details available - return SendMessageT(hwndDlg, WM_COMMAND, ID_POPUP_USERDETAILS, 0); // show user details - } - case LVN_ITEMCHANGED: - { - LPNMLISTVIEW pNMLV = (LPNMLISTVIEW)lParam; - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); // optimisation, for FOR-Cycle - bool bExistsCheckedItem = false; // there must be no checked items to disable "Add" button - - if (ListView_GetCheckState(hLV, pNMLV->iItem)) - { // the user has checked this item - bExistsCheckedItem = true; // enable "Add" button - } - else - { // loop thru items and check if at least one is checked - for (int i = 0; i < ListView_GetItemCount(hLV); i++) - if (ListView_GetCheckState(hLV, i)) - { // we found checked item, enable add, exit loop - bExistsCheckedItem = true; - break; - } - } - EnableDlgItem(hwndDlg, IDOK, bExistsCheckedItem); - EnableDlgItem(hwndDlg, IDDETAILS, ListView_GetSelectedCount(hLV) > 0); - break; - } - } - } - break; - - case WM_COMMAND: - { - if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->mhContact)) - break; - - switch(LOWORD(wParam)) - { - case IDOK: // "Add Selected" button click - { // for each selected item, find its index in the hDbEvent - // and after that add this item to the DB permanently - char* caUIN; - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); - HWND hGroupsCombo = GetDlgItem(hwndDlg, IDC_GROUPS); - HWND hGroupsCheck = GetDlgItem(hwndDlg, IDC_ENABLEGROUPS); - int curs = SendMessageT(hGroupsCombo, CB_GETCURSEL, 0, 0); - TCHAR* caGroup = NULL; - int nGroupId = -1; - if (curs != CB_ERR && IsWindowEnabled(hGroupsCheck) && SendMessageT(hGroupsCheck, BM_GETCHECK, 0, 0)) - { //got groups, get the one selected in combo - TCHAR* caGroup = (TCHAR*)_alloca((SendMessageT(hGroupsCombo, CB_GETLBTEXTLEN, curs, 0) + 1) * sizeof(WCHAR)); - SendMessageT(hGroupsCombo, CB_GETLBTEXT, curs, (LPARAM)caGroup); - nGroupId = SendMessageT(hGroupsCombo, CB_GETITEMDATA, curs, 0); - } - - for (int i = 0; i < ListView_GetItemCount(hLV); i++) - if (ListView_GetCheckState(hLV, i)) - { // found checked contact item, add it - caUIN = ListView_GetItemTextEx(hLV, i, 0); - for (int j = 0; j < wndData->cbReceived; j++) // determine item index in packet - if (!strcmpnull(wndData->maReceived[j]->mcaUIN, caUIN)) - { - char* szProto = GetContactProto(wndData->mhContact); - HANDLE hContact = (HANDLE)CallProtoService(szProto, PS_ADDTOLISTBYEVENT, MAKEWPARAM(0, j), (LPARAM)wndData->mhDbEvent); - if (hContact && caGroup) - { // use newest group API if available - if (ServiceExists(MS_CLIST_CONTACTCHANGEGROUP)) - CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)hContact, (LPARAM)nGroupId); - else - DBWriteContactSettingStringT(hContact, "CList", "Group", caGroup); - } - break; - } - SAFE_FREE((void**)&caUIN); - } // move to next item - break; - } - case IDDETAILS: - { // for each selected item, find its index in the hDbEvent - // and after that add this item to the DB - // finally, request Details window for this hContact - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); - for (int i = 0; i < ListView_GetItemCount(hLV); i++) - if (ListView_GetItemState(hLV, i, LVIS_SELECTED)) - { - HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, i); - if (hContact) - CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0); - } - break; - } - case IDCANCEL: - { - SendMessageT(hwndDlg, WM_CLOSE, 0, 0); - break; - } - case IDC_ENABLEGROUPS: - { - EnableGroupCombo(hwndDlg); - break; - } - case IDC_GROUPS: - { // rebuild group list on popup - if (HIWORD(wParam) == CBN_DROPDOWN) - RebuildGroupCombo(hwndDlg); - break; - } - case ID_POPUP_ADDUSER: - { - HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); - - if (hContact) - DialogAddContactExecute(hwndDlg, hContact); - break; - } - case ID_POPUP_USERDETAILS: - { - HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); - - if (hContact) - CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0 ); - break; - } - case ID_POPUP_SENDMESSAGE: - { - HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); - - if (hContact) - CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0); - break; - } - case IDC_USERMENU: - { - RECT rc; - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)wndData->mhContact, 0); - GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU), &rc); - TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); - DestroyMenu(hMenu); - break; - } - case IDC_HISTORY: - CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->mhContact,0); - break; - case IDC_DETAILS: - CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->mhContact,0); - break; - case IDC_ADD: - DialogAddContactExecute(hwndDlg, wndData->mhContact); - break; - } - break; - } - case WM_CONTEXTMENU: - { - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); - LVHITTESTINFO lvh; - RECT rt; - - wndData->iPopupItem = -1; - if ((HWND)wParam != hLV) break; // if not our ListView go away - lvh.pt.x = LOWORD(lParam); - lvh.pt.y = HIWORD(lParam); - if (GetWindowRect(hLV, &rt)==0) return FALSE; // ?? why this, some check ?? - ScreenToClient(hLV, &lvh.pt); // convert to ListView local coordinates - int ci = ListView_HitTest(hLV, &lvh); - if (ci==-1) break; // mouse is not over any item - wndData->iPopupItem = ci; - TrackPopupMenu(GetSubMenu(wndData->mhPopup, 0), TPM_LEFTALIGN|TPM_TOPALIGN, LOWORD(lParam), HIWORD(lParam), 0, hwndDlg, NULL); - break; - } - case HM_EVENTSENT: - { - ACKDATA *ack=(ACKDATA*)lParam; - if (ack->type!=ACKTYPE_SEARCH) break; // not search ack, go away - if (ack->hProcess!=wndData->rhSearch) break; //not our search, go away - if (ack->result==ACKRESULT_DATA) - { - HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); - PROTOSEARCHRESULT* psr = (PROTOSEARCHRESULT*)ack->lParam; - LVFINDINFO fi; - fi.flags = LVFI_STRING; - fi.psz = wndData->haUin; - int iLPos = ListView_FindItem(hLV, -1, &fi); - if (iLPos==-1) iLPos=0; -// ListView_SetItemText(hLV, iLPos, 0, psr->email); // not sent by ICQ, and currently unsupported either - if (strcmpnull(psr->nick, "") && psr->nick) ListView_SetItemText(hLV, iLPos, 1, psr->nick); - ListView_SetItemText(hLV, iLPos, 2, psr->firstName); - ListView_SetItemText(hLV, iLPos, 3, psr->lastName); - break; - } - SAFE_FREE((void**)&wndData->haUin); - break; - } - case WM_CLOSE: // user closed window, so destroy it - { - WindowList_Remove(ghRecvWindowList, hwndDlg); - DestroyWindow(hwndDlg); - break; - } - case WM_DESTROY: // last message received by this dialog, cleanup - { - CallService(MS_DB_EVENT_MARKREAD, (WPARAM)wndData->mhContact, (LPARAM)wndData->mhDbEvent); - Utils_SaveWindowPosition(hwndDlg, NULL, MODULENAME, ""); - ImageList_Destroy(wndData->mhListIcon); - UnhookEvent(wndData->hHook); - DestroyMenu(wndData->mhPopup); - for (int i=0; i < SIZEOF(wndData->hIcons); i++) - DestroyIcon(wndData->hIcons[i]); - delete wndData; // automatically calls destructor - break; - } - case WM_MEASUREITEM: - return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); - - case WM_DRAWITEM: - { - DrawProtocolIcon(hwndDlg, lParam, wndData->mhContact); - return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); - } - case WM_SIZE: - { // make the dlg resizeable - UTILRESIZEDIALOG urd = {0}; - - if (IsIconic(hwndDlg)) break; - urd.cbSize = sizeof(urd); - urd.hInstance = hInst; - urd.hwndDlg = hwndDlg; - urd.lParam = 0; // user-defined - urd.lpTemplate = MAKEINTRESOURCEA(IDD_RECEIVE); - urd.pfnResizer = RecvDlg_Resize; - CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM) & urd); - break; - } - case WM_GETMINMAXINFO: - { - MINMAXINFO* mmi=(MINMAXINFO*)lParam; - mmi->ptMinTrackSize.x = 480+2*GetSystemMetrics(SM_CXSIZEFRAME); - mmi->ptMinTrackSize.y = 130+2*GetSystemMetrics(SM_CYSIZEFRAME); - break; - } - case DM_UPDATETITLE: - { - UpdateDialogTitle(hwndDlg, wndData?wndData->mhContact:NULL, "Contacts from"); - if (wndData) - UpdateDialogAddButton(hwndDlg, wndData->mhContact); - break; - } - } - return FALSE; -} diff --git a/plugins/ContactsPlus/receive.h b/plugins/ContactsPlus/receive.h deleted file mode 100644 index fe35d94be6..0000000000 --- a/plugins/ContactsPlus/receive.h +++ /dev/null @@ -1,65 +0,0 @@ -// --------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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 __RECEIVE_H -#define __RECEIVE_H - - -#define HM_EVENTSENT (WM_USER+10) - -#define DM_UPDATETITLE (WM_USER+11) - -#define IDI_ADDCONTACT 210 -#define IDI_USERDETAILS 160 -#define IDI_HISTORY 174 -#define IDI_DOWNARROW 264 - -struct TReceivedItem { - char* mcaUIN; - TCHAR* mcaNick; - ~TReceivedItem() { SAFE_FREE((void**)&mcaUIN); SAFE_FREE((void**)&mcaNick); } - TReceivedItem() { mcaUIN = NULL; mcaNick = NULL; } -}; - -struct TRecvContactsData { - HANDLE mhDbEvent; // handle to recv DB event - HANDLE mhContact; // from whom we received this - HIMAGELIST mhListIcon;// icons for listview - HMENU mhPopup; // popup menu for listview - HANDLE hHook; // hook to event - HANDLE rhSearch; // handle to uin-search - char* haUin; - int iPopupItem; - TReceivedItem** maReceived;// received contacts - int cbReceived; - TReceivedItem* AddReceivedItem(); - HICON hIcons[4]; // icons for dialog - TRecvContactsData(HANDLE contact) { mhContact = contact; hHook = NULL; cbReceived = 0; maReceived = NULL; haUin = NULL; }; - ~TRecvContactsData() { if (cbReceived) { for(int i=0;inContacts = nContacts; - ackData->aContacts = (HANDLE*)malloc(nContacts*sizeof(HANDLE)); - memmove(ackData->aContacts, phContacts, nContacts*sizeof(HANDLE)); // copy the array of hContact for ack array - EnableDlgItem(hwndDlg, IDOK, FALSE); - EnableDlgItem(hwndDlg, IDC_LIST, FALSE); - - return TRUE; // Success -} - - -int TSendContactsData::SendContacts(HWND hwndDlg) { - char* szProto = GetContactProto(hContact); - int nMaxContacts = CallProtoService(szProto, PS_GETCAPS, PFLAG_MAXCONTACTSPERPACKET, (LPARAM)hContact); - - if (!nMaxContacts) { - ShowErrorDlg(hwndDlg, "The selected contact does not support receiving contacts.", FALSE); - return FALSE; - } - // hook event - we want to receive protocol acknowledgements - HookProtoAck(hwndDlg); - - for (int j = 0; j < nContacts / nMaxContacts; j++ ) - { // send in packets, each of nMaxContacts contacts - if (!SendContactsPacket(hwndDlg, aContacts + j*nMaxContacts, nMaxContacts)) - return FALSE; - } - if (nContacts%nMaxContacts!=0) - { - if (!SendContactsPacket(hwndDlg, aContacts + nContacts/nMaxContacts*nMaxContacts, nContacts%nMaxContacts)) - return FALSE; - } - return TRUE; -} - - -/* Send Dialog Implementation */ - -static void ResetListOptions(HWND hwndList) -{ - COLORREF bgColour,fgColour; - - SendMessageT(hwndList,CLM_SETBKBITMAP,0,(LPARAM)(HBITMAP)NULL); - bgColour=GetSysColor(COLOR_WINDOW); - SendMessageT(hwndList,CLM_SETBKCOLOR,bgColour,0); - SendMessageT(hwndList,CLM_SETGREYOUTFLAGS,0,0); - SendMessageT(hwndList,CLM_SETLEFTMARGIN,4,0); - SendMessageT(hwndList,CLM_SETINDENT,10,0); - for(int i=0; i<=FONTID_MAX; i++) - { - fgColour=(COLORREF)SendMessageT(hwndList,CLM_GETTEXTCOLOR,i,0); - if(abs(GetRValue(fgColour)-GetRValue(bgColour))<10 && - abs(GetGValue(fgColour)-GetGValue(bgColour))<10 && - abs(GetBValue(fgColour)-GetBValue(bgColour))<10) - SendMessageT(hwndList,CLM_SETTEXTCOLOR,i,GetSysColor(COLOR_WINDOWTEXT)); - } -} - - -static HANDLE FindNextClistContact(HWND hList, HANDLE hContact, HANDLE *phItem) -{ - HANDLE hNextContact = SRCFindNextContact(hContact); - HANDLE hNextItem = NULL; - - while (hNextContact && !(hNextItem = (HANDLE)SendMessageT(hList, CLM_FINDCONTACT, (WPARAM)hNextContact,0))) - hNextContact = SRCFindNextContact(hNextContact); - - if (phItem) - *phItem = hNextItem; - - return hNextContact; -} - - -static HANDLE FindFirstClistContact(HWND hList, HANDLE *phItem) -{ - HANDLE hContact = SRCFindFirstContact(); - HANDLE hItem = (HANDLE)SendMessageT(hList, CLM_FINDCONTACT, (WPARAM)hContact, 0); - - if (hContact && !hItem) - return FindNextClistContact(hList, hContact, phItem); - - if (phItem) - *phItem = hItem; - - return hContact; -} - - -bool binListEvent = FALSE; - -static void SetAllContactChecks(HWND hwndList, HANDLE hReceiver) // doubtful name -{ - HANDLE hContact, hItem; - - if (binListEvent) return; - binListEvent = TRUE; - char* szProto = GetContactProto(hReceiver); - if (szProto == NULL) return; - - if (CallService(MS_CLUI_GETCAPS, 0, 0) & CLUIF_HIDEEMPTYGROUPS && DBGetContactSettingByte(NULL, "CList", "HideEmptyGroups", SETTING_USEGROUPS_DEFAULT)) - SendMessageT(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM) TRUE, 0); - else - SendMessageT(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM) FALSE, 0); - - hContact = FindFirstClistContact(hwndList, &hItem); - while (hContact) - { - char* szProto2 = GetContactProto(hContact); - - if (strcmpnull(szProto, szProto2)) - { // different protocols or protocol undefined, remove contact, useless anyway - SendMessageT(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0); - } - else // otherwise uncheck - SendMessageT(hwndList, CLM_SETCHECKMARK,(WPARAM)hItem, 0); - - hContact = FindNextClistContact(hwndList, hContact, &hItem); - } - - binListEvent = FALSE; -} - - -INT_PTR CALLBACK SendDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TSendContactsData* wndData = (TSendContactsData*)GetWindowLongPtr(hwndDlg, DWLP_USER); - - switch (msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - SendMessageT(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); - ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST)); - SetAllContactChecks(GetDlgItem(hwndDlg,IDC_LIST), (HANDLE)lParam); - WindowList_Add(ghSendWindowList, hwndDlg, (HANDLE)lParam); - wndData = new TSendContactsData((HANDLE)lParam); - SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)wndData); - // new dlg init - wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), "Add Contact Permanently to List"); - wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), "View User's Details"); - wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), "View User's History"); - wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), "User Menu"); - - SendMessageT(hwndDlg,DM_UPDATETITLE,0,0); - // new dialog init done - return TRUE; - } - - case WM_SETFOCUS: - SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->idFrom == IDC_LIST) - { - switch (((LPNMHDR)lParam)->code) - { - case CLN_NEWCONTACT: - case CLN_LISTREBUILT: // rebuild list - if (wndData) SetAllContactChecks(GetDlgItem(hwndDlg,IDC_LIST), wndData->hContact); - case CLN_OPTIONSCHANGED: - ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST)); - break; - } - } - break; - - case WM_TIMER: - if (wParam == TIMERID_MSGSEND) - { - if (!g_SendAckSupported) - { // old Miranda has this ack unimplemented, we need to send it by ourselves - ACKDATA ack = {0}; - - ack.cbSize = sizeof(ACKDATA); - ack.type = ACKTYPE_CONTACTS; - ack.result = ACKRESULT_SUCCESS; - ack.hContact = wndData->hContact; - while (wndData->uacklist.Count) - { // the uack gets empty after processing all messages :) - ack.hProcess = wndData->uacklist.Items[0]; - SendMessageT(hwndDlg, HM_EVENTSENT, NULL, (WPARAM)&ack); // this removes the ack from our array - } - break; - } - KillTimer(hwndDlg,wParam); - wndData->ShowErrorDlg(hwndDlg, "The contacts send timed out.", TRUE); - } - break; - - case DM_ERRORDECIDED: - { - EnableWindow(hwndDlg,TRUE); - wndData->hError = NULL; - switch(wParam) - { - case MSGERROR_CANCEL: - { - wndData->UnhookProtoAck(); - if (wndData->uacklist.Count) - { - for (int i=0; iuacklist.Count; i++) - { - delete gaAckData.Remove(wndData->uacklist.Items[i]); // remove our ackdata & release structure - } - SAFE_FREE((void**)&wndData->uacklist.Items); - wndData->uacklist.Count = 0; - } - EnableDlgItem(hwndDlg,IDOK,TRUE); - EnableDlgItem(hwndDlg,IDC_LIST,TRUE); - ShowWindow(hwndDlg,SW_SHOWNORMAL); - SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); - break; - } - case MSGERROR_DONE: - // contacts were delivered succesfully after timeout - SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); - wndData->UnhookProtoAck(); - break; - - case MSGERROR_RETRY:// resend timeouted packets - - for (int i=0; iuacklist.Count; i++) - { - TAckData* lla = gaAckData.Remove(wndData->uacklist.Items[i]); - HANDLE hProcc = (HANDLE)CallContactService(wndData->hContact, PSS_CONTACTS, MAKEWPARAM(0, lla->nContacts), (LPARAM)lla->aContacts); - - if (!hProcc) // if fatal do not include - { - wndData->uacklist.Remove(wndData->uacklist.Items[i]); - delete lla; // release the structure - continue; - } - else - { // update process code - wndData->uacklist.Items[i] = hProcc; - gaAckData.Add(hProcc, lla); - } - }// collect TAckData for our window, resend - break; - } - break; - } - - case WM_COMMAND: - { - if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->hContact)) - break; - - switch(LOWORD(wParam)) - { - case IDOK: - { - if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDOK))) break; - HANDLE hContact, hItem; - wndData->ClearContacts(); // do not include contacts twice - - HWND hList = GetDlgItem(hwndDlg, IDC_LIST); - hContact = FindFirstClistContact(hList, &hItem); - while (hContact) - { - if (SendMessageT(hList, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) - { // build list of contacts to send - wndData->AddContact(hContact); - } - hContact = FindNextClistContact(hList, hContact, &hItem); - } - /* send contacts */ - if (!wndData->SendContacts(hwndDlg)) - break; - - if (g_SendAckSupported) - SetTimer(hwndDlg,TIMERID_MSGSEND,DBGetContactSettingDword(NULL,"SRMsg","MessageTimeout",TIMEOUT_MSGSEND),NULL); - else - SetTimer(hwndDlg,TIMERID_MSGSEND,1000,NULL); // wait one second - if no error occures - - break; - } - case IDCANCEL: - { - DestroyWindow(hwndDlg); - break; - } - case ID_SELECTALL: - { // select all contacts - HANDLE hContact, hItem; - HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST); - - hContact = FindFirstClistContact(hwndList, &hItem); - while (hContact) { - SendMessageT(hwndList,CLM_SETCHECKMARK,(WPARAM)hItem, 1); - hContact = FindNextClistContact(hwndList, hContact, &hItem); - }; - break; - } - case IDC_USERMENU: - { - RECT rc; - HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)wndData->hContact,0); - - GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU),&rc); - TrackPopupMenu(hMenu,0,rc.left,rc.bottom,0,hwndDlg,NULL); - DestroyMenu(hMenu); - break; - } - case IDC_HISTORY: - CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->hContact,0); - break; - - case IDC_DETAILS: - CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->hContact,0); - break; - - case IDC_ADD: - DialogAddContactExecute(hwndDlg, wndData->hContact); - break; - } - break; - } - case HM_EVENTSENT: - { - ACKDATA *ack=(ACKDATA*)lParam; - DBEVENTINFO dbei={0}; - - if (ack->type != ACKTYPE_CONTACTS) break; - - TAckData* ackData = gaAckData.Get(ack->hProcess); - - if (ackData == NULL) break; // on unknown hprocc go away - - if (ackData->hContact != ack->hContact) break; // this is not ours, strange - - if (ack->result == ACKRESULT_FAILED) - { // some process failed, show error dialog - KillTimer(hwndDlg, TIMERID_MSGSEND); - wndData->ShowErrorDlg(hwndDlg, (char *)ack->lParam, TRUE); - // ackData get used in error handling, released there - break; - } - - dbei.cbSize = sizeof(dbei); - dbei.szModule = GetContactProto(ackData->hContact); - dbei.eventType = EVENTTYPE_CONTACTS; - dbei.flags = DBEF_SENT; - if (g_UnicodeCore && g_Utf8EventsSupported) - dbei.flags |= DBEF_UTF; - dbei.timestamp = time(NULL); - //make blob - TCTSend* maSend = (TCTSend*)_alloca(ackData->nContacts*sizeof(TCTSend)); - ZeroMemory(maSend, ackData->nContacts*sizeof(TCTSend)); - dbei.cbBlob=0; - char* pBlob; - int i; - for (i=0; inContacts; i++) - { // prepare data & count size - if (g_UnicodeCore && g_Utf8EventsSupported) - maSend[i].mcaNick = make_utf8_string((WCHAR*)GetContactDisplayNameT(ackData->aContacts[i])); - else - maSend[i].mcaNick = (unsigned char*)null_strdup((char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ackData->aContacts[i], 0)); - maSend[i].mcaUIN = GetContactUID(ackData->aContacts[i], FALSE); - dbei.cbBlob += (DWORD)strlennull(maSend[i].mcaUIN) + (DWORD)strlennull((char*)maSend[i].mcaNick) + 2; - } - dbei.pBlob = (PBYTE)_alloca(dbei.cbBlob); - for (i=0, pBlob=(char*)dbei.pBlob; i < ackData->nContacts; i++) - { - strcpy(pBlob, (char*)maSend[i].mcaNick); - pBlob += strlennull(pBlob) + 1; - strcpy(pBlob, maSend[i].mcaUIN); - pBlob += strlennull(pBlob) + 1; - } - CallService(MS_DB_EVENT_ADD, (WPARAM)ackData->hContact,(LPARAM)&dbei); - gaAckData.Remove(ack->hProcess); // do not release here, still needed - wndData->uacklist.Remove(ack->hProcess); // packet confirmed - for (i=0; inContacts; i++) - { - SAFE_FREE((void**)&maSend[i].mcaUIN); - SAFE_FREE((void**)&maSend[i].mcaNick); - } - delete ackData; // all done, release structure - if (!wndData->uacklist.Count) - { - SkinPlaySound("SentContacts"); - KillTimer(hwndDlg, TIMERID_MSGSEND); - - if (wndData->hError) - SendMessageT(wndData->hError, DM_ERRORDECIDED, MSGERROR_DONE, 0); - - SendMessageT(hwndDlg, WM_CLOSE, 0, 0); // all packets confirmed, close the dialog - } - break; - } - - case WM_CLOSE: - { - wndData->UnhookProtoAck(); - DestroyWindow(hwndDlg); - break; - } - case WM_DESTROY: - { - int i; - for (i = 0; i < SIZEOF(wndData->hIcons); i++) - DestroyIcon(wndData->hIcons[i]); - WindowList_Remove(ghSendWindowList, hwndDlg); - delete wndData; - break; - } - case WM_MEASUREITEM: - return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam); - - case WM_DRAWITEM: - { - DrawProtocolIcon(hwndDlg, lParam, wndData->hContact); - return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam); - } - case DM_UPDATETITLE: - { - UpdateDialogTitle(hwndDlg, wndData?wndData->hContact:NULL, "Send Contacts to"); - if (wndData) - UpdateDialogAddButton(hwndDlg, wndData->hContact); - break; - } - } - - return FALSE; -} - - -// Error Dialog - -INT_PTR CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_INITDIALOG: - { - RECT rc, rcParent; - - TranslateDialogDefault(hwndDlg); - - if (lParam) - { - WCHAR tmp[MAX_PATH]; - - SetDlgItemTextT(hwndDlg, IDC_ERRORTEXT, SRCTranslateT((char*)lParam, tmp)); - } - GetWindowRect(hwndDlg, &rc); - GetWindowRect(GetParent(hwndDlg), &rcParent); - SetWindowPos(hwndDlg, 0, - (rcParent.left+rcParent.right-(rc.right-rc.left))/2, - (rcParent.top+rcParent.bottom-(rc.bottom-rc.top))/2, - 0, 0, SWP_NOZORDER|SWP_NOSIZE); - } - return TRUE; - - case WM_COMMAND: - switch(LOWORD(wParam)) - { - case IDOK: - SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_RETRY, 0); - DestroyWindow(hwndDlg); - break; - - case IDCANCEL: - SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_CANCEL, 0); - DestroyWindow(hwndDlg); - break; - } - break; - case DM_ERRORDECIDED: - if (wParam!=MSGERROR_DONE) break; - SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_DONE, 0); - DestroyWindow(hwndDlg); - break; - } - - return FALSE; -} diff --git a/plugins/ContactsPlus/send.h b/plugins/ContactsPlus/send.h deleted file mode 100644 index c8580a4eb1..0000000000 --- a/plugins/ContactsPlus/send.h +++ /dev/null @@ -1,110 +0,0 @@ -// --------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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 __SEND_H -#define __SEND_H - - -#define TIMERID_MSGSEND 1024 -#define TIMEOUT_MSGSEND 9000 //ms -#define HM_EVENTSENT (WM_USER+10) -#define DM_ERRORDECIDED (WM_USER+18) -#define DM_UPDATETITLE (WM_USER+11) -#define MSGERROR_CANCEL 0 -#define MSGERROR_RETRY 1 -#define MSGERROR_DONE 2 - -#define IDI_ADDCONTACT 210 -#define IDI_USERDETAILS 160 -#define IDI_HISTORY 174 -#define IDI_DOWNARROW 264 - -struct TSendProcessList { - int Count; - HANDLE* Items; - CRITICAL_SECTION lock; - void Add(HANDLE hProcc); - void Remove(HANDLE hProcc); - TSendProcessList(); - ~TSendProcessList(); -}; - -struct TSendContactsData { // hope uack is released automaticly, static property - HANDLE hHook; // hook to event - void HookProtoAck(HWND hwndDlg); - void UnhookProtoAck(); - HANDLE* aContacts; // contacts to be sent - int nContacts; // now many UIDs shall we send? - void ClearContacts(); - void AddContact(HANDLE hContact); - HANDLE hContact; // to whom shall we send? - TSendProcessList uacklist;// ackdata - necessary for errorbox - HWND hError; // handle of error box, if any - void ShowErrorDlg(HWND hwndDlg, char* szMsg, bool bAllowRetry); - int SendContactsPacket(HWND hwndDlg, HANDLE *phContacts, int nContacts); - int SendContacts(HWND hwndDlg); - HICON hIcons[4]; // icons for dialog - TSendContactsData(HANDLE contact); - ~TSendContactsData(); -}; - -struct TAckData { - HANDLE hContact; // to whom was it sent - HANDLE* aContacts; // obj - int nContacts; // how many - TAckData(HANDLE contact) { hContact = contact; aContacts = NULL; nContacts = 0;}; - ~TAckData() { if (nContacts) SAFE_FREE((void**)&aContacts); } -}; - -typedef TAckData* PAckData; - -struct TCTSend { - char* mcaUIN; - unsigned char* mcaNick; -}; - -struct gAckItem { // some shit here - HANDLE hProcc; - PAckData ackData; - gAckItem(HANDLE procC, PAckData aData) { ackData=aData; hProcc=procC; }; - ~gAckItem() { /*delete ackData;*/ }; -}; - -struct gAckList { - gAckItem** Items; - int Count; - TAckData* Get(HANDLE hProcc) { for (int i=0; ihProcc==hProcc) { return Items[i]->ackData; }; return NULL; }; - TAckData* Add(HANDLE hProcc, TAckData* ackData) { Items=(gAckItem**)realloc(Items, (Count+1)*sizeof(gAckItem*)); Items[Count]=new gAckItem(hProcc, ackData); Count++; return ackData; }; - TAckData* Remove(HANDLE hProcc) { for (int i=0; ihProcc==hProcc) { TAckData* data=Items[i]->ackData; delete Items[i]; memmove(Items+i, Items+i+1, (Count-i-1)*sizeof(gAckItem*)); Count--; return data; }; return NULL; }; - gAckList() { Count = 0; Items = NULL; } - ~gAckList() { if (Count) { for (int i=0; i +#include + +#include +#include +#include +#include +#include +#include +#include + +//!!this is fake - this plugin maintains backward compatibility internally +#define MIRANDA_VER 0x0A00 + +#include "newpluginapi.h" +#include "m_system.h" +#include "m_protocols.h" +#include "m_protosvc.h" +#include "m_database.h" +#include "m_utils.h" +#include "m_langpack.h" +#include "m_skin.h" +#include "m_clist.h" +#include "m_clc.h" +#include "m_clui.h" +#include "m_addcontact.h" +#include "m_history.h" +#include "m_userinfo.h" +#include "m_button.h" +#include "m_contacts.h" +#include "m_message.h" +#include "statusmodes.h" +#include "win2k.h" + +#include "resource.h" + +#include "utils.h" +#include "send.h" +#include "receive.h" + +#define MODULENAME "SendReceiveContacts" + + +#define MS_CONTACTS_SEND "ContactsTransfer/SendContacts" +#define MS_CONTACTS_RECEIVE "ContactsTransfer/ReceiveContacts" + +// Global Variables +extern int g_UnicodeCore; +extern int g_NewProtoAPI; +extern int g_SendAckSupported; +extern int g_Utf8EventsSupported; diff --git a/plugins/ContactsPlus/src/main.cpp b/plugins/ContactsPlus/src/main.cpp new file mode 100644 index 0000000000..da43554c29 --- /dev/null +++ b/plugins/ContactsPlus/src/main.cpp @@ -0,0 +1,317 @@ +// -------------------------------------------------------------------------- +// Contacts+ for Miranda Instant Messenger +// _______________________________________ +// +// Copyright © 2002 Dominus Procellarum +// Copyright © 2004-2008 Joe Kucera +// +// 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 "contacts.h" + + +HINSTANCE hInst; + +int hLangpack; + +int g_NewProtoAPI = TRUE; + +int g_SendAckSupported = TRUE; +int g_Utf8EventsSupported = TRUE; + +HANDLE ghSendWindowList; +HANDLE ghRecvWindowList; +gAckList gaAckData; + +HANDLE hServiceSend; +HANDLE hServiceReceive; + +HANDLE hHookModulesLoaded = NULL; +HANDLE hHookDBEventAdded = NULL; +HANDLE hHookContactDeleted = NULL; +HANDLE hHookContactSettingChanged = NULL; +HANDLE hHookPreBuildContactMenu = NULL; + +HANDLE hContactMenuItem = NULL; + +int g_UnicodeCore; + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + "Send/Receive Contacts+", + PLUGIN_MAKE_VERSION(1,5,2,0), + "Allows you to send and receive contacts", + "Joe Kucera, Todor Totev", + "jokusoftware@miranda-im.org", + "(C) 2004-2008 Joe Kucera, Original Code (C) 2002 Dominus Procellarum", + "http://addons.miranda-im.org/details.php?action=viewfile&id=1253", + UNICODE_AWARE, + {0x0324785E, 0x74CE, 0x4600, {0xB7, 0x81, 0x85, 0x17, 0x73, 0xB3, 0xEF, 0xC5 } } // {0324785E-74CE-4600-B781-851773B3EFC5} +}; + + +static int HookDBEventAdded(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + HANDLE hDbEvent = (HANDLE)lParam; + //process the event + DBEVENTINFO dbe = {0}; + + dbe.cbSize = sizeof(DBEVENTINFO); + //get event details + CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe); + //check if we should process the event + if (dbe.flags & (DBEF_SENT|DBEF_READ) || dbe.eventType != EVENTTYPE_CONTACTS) return 0; + //get event contents + dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0); + if (dbe.cbBlob != -1) + dbe.pBlob = (PBYTE)_alloca(dbe.cbBlob); + CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbe); + //play received sound + SkinPlaySound("RecvContacts"); + { //add event to the contact list + CLISTEVENT cle = {0}; + TCHAR caToolTip[128]; + + cle.cbSize = sizeof(cle); + cle.hContact = hContact; + cle.hDbEvent = hDbEvent; + cle.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS)); + cle.pszService = MS_CONTACTS_RECEIVE; + + WCHAR tmp[MAX_PATH]; + _snprintfT(caToolTip, 64, "%s %s", SRCTranslateT("Contacts received from", tmp), (TCHAR*)GetContactDisplayNameT(hContact)); + + cle.ptszTooltip = caToolTip; + if (g_UnicodeCore) + cle.flags |= CLEF_UNICODE; + CallService(MS_CLIST_ADDEVENT, 0, (LPARAM)&cle); + } + return 0; //continue processing by other hooks +} + + +static void ProcessUnreadEvents(void) +{ + DBEVENTINFO dbei = {0}; + HANDLE hDbEvent,hContact; + + dbei.cbSize = sizeof(dbei); + + hContact = SRCFindFirstContact(); + while (hContact) + { + hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDFIRSTUNREAD,(WPARAM)hContact,0); + + while (hDbEvent) + { + dbei.cbBlob=0; + CallService(MS_DB_EVENT_GET,(WPARAM)hDbEvent,(LPARAM)&dbei); + if (!(dbei.flags&(DBEF_SENT|DBEF_READ)) && dbei.eventType==EVENTTYPE_CONTACTS) + { //process the event + HookDBEventAdded((WPARAM)hContact, (LPARAM)hDbEvent); + } + hDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT,(WPARAM)hDbEvent,0); + } + hContact = SRCFindNextContact(hContact); + } +} + + +static bool CheckContactsServiceSupport(const char* szProto) +{ + if (g_NewProtoAPI) + { // there is no way to determine if the service exists (only proto_interface call is supported by 0.8+) + if (CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_CONTACTSEND) + return true; + } + else + { // check the real send service (only 0.7.x and older) + char serstr[MAX_PATH+30]; + + strcpy(serstr, szProto); + strcat(serstr, PSS_CONTACTS); + if (ServiceExists(serstr)) + return true; + } + return false; +} + + +static int HookPreBuildContactMenu(WPARAM wParam, LPARAM lParam) +{ + HANDLE hContact = (HANDLE)wParam; + char* szProto = GetContactProto(hContact); + int bVisible = FALSE; + + if (szProto && CheckContactsServiceSupport(szProto)) + { // known protocol, protocol supports contacts sending + // check the selected contact if it supports contacts receive + if (CallProtoService(szProto, PS_GETCAPS, PFLAG_MAXCONTACTSPERPACKET, (LPARAM)hContact)) + bVisible = TRUE; + } + + { // update contact menu item's visibility + CLISTMENUITEM mi = {0}; + + mi.cbSize = sizeof(mi); + if (bVisible) + mi.flags = CMIM_FLAGS; + else + mi.flags = CMIM_FLAGS | CMIF_HIDDEN; + + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM)hContactMenuItem, (LPARAM)&mi); + } + + return 0; +} + + +static int HookModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + char* modules[2] = {0}; + WCHAR tmp[MAX_PATH]; + + modules[0] = MODULENAME; + CallService("DBEditorpp/RegisterModule",(WPARAM)modules,(LPARAM)1); + + CLISTMENUITEM mi = {0}; + mi.cbSize = sizeof(mi); + mi.ptszName = SRCTranslateT("Contacts", tmp); + mi.position = -2000009990; //position in menu + mi.flags = CMIF_KEEPUNTRANSLATED; + if (g_UnicodeCore) + mi.flags |= CMIF_UNICODE; + mi.pszService = MS_CONTACTS_SEND; + mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS)); + hContactMenuItem = Menu_AddContactMenuItem(&mi); + + hHookPreBuildContactMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, HookPreBuildContactMenu); + + ghSendWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); // no need to destroy this + ghRecvWindowList = (HANDLE)CallService(MS_UTILS_ALLOCWINDOWLIST, 0, 0); // no need to destroy this + + + ProcessUnreadEvents(); + return 0; +} + + +static int HookContactSettingChanged(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTWRITESETTING *cws = (DBCONTACTWRITESETTING*)lParam; + char *szProto = GetContactProto((HANDLE)wParam); + + if (strcmpnull(cws->szModule,"CList") && strcmpnull(cws->szModule, szProto)) return 0; + + WindowList_Broadcast(ghSendWindowList,DM_UPDATETITLE,0,0); + WindowList_Broadcast(ghRecvWindowList,DM_UPDATETITLE,0,0); + + return 0; +} + + +static int HookContactDeleted(WPARAM wParam, LPARAM lParam) +{ // if our contact gets deleted close his window + HWND h = WindowList_Find(ghSendWindowList,(HANDLE)wParam); + + if (h) + { + SendMessageT(h,WM_CLOSE,0,0); + } + + while (h = WindowList_Find(ghRecvWindowList, (HANDLE)wParam)) + { // since we hack the window list - more windows for one contact, we need to close them all + SendMessageT(h, WM_CLOSE,0,0); + } + return 0; +} + + +static INT_PTR ServiceSendCommand(WPARAM wParam, LPARAM lParam) +{ + HWND hWnd; + //find window for hContact + hWnd = WindowList_Find(ghSendWindowList, (HANDLE)wParam); + + if (!hWnd) + CreateDialogParamT(hInst, MAKEINTRESOURCE(IDD_SEND), NULL, SendDlgProc, (LPARAM)(HANDLE)wParam); + else + { + SetForegroundWindow(hWnd); + SetFocus(hWnd); + } + return 0; +} + +static INT_PTR ServiceReceiveCommand(WPARAM wParam, LPARAM lParam) +{ + CLISTEVENT* pcle = (CLISTEVENT*)lParam; + + CreateDialogParamT(hInst, MAKEINTRESOURCE(IDD_RECEIVE), NULL, RecvDlgProc, (LPARAM)pcle); + + return 0; +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_SRCONTACTS, MIID_LAST}; + +extern "C" __declspec(dllexport) int Load(void) +{ + mir_getLP(&pluginInfo); + InitCommonControls(); + InitI18N(); + + { // Are we running under unicode Miranda core ? + char szVer[MAX_PATH]; + + CallService(MS_SYSTEM_GETVERSIONTEXT, MAX_PATH, (LPARAM)szVer); + _strlwr(szVer); + g_UnicodeCore = (strstr(szVer, "unicode") != NULL); + } + //init hooks + hHookModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, HookModulesLoaded); + hHookDBEventAdded = HookEvent(ME_DB_EVENT_ADDED, HookDBEventAdded); + hHookContactDeleted = HookEvent(ME_DB_CONTACT_DELETED, HookContactDeleted); + hHookContactSettingChanged = HookEvent(ME_DB_CONTACT_SETTINGCHANGED, HookContactSettingChanged); + //create services + hServiceSend = CreateServiceFunction(MS_CONTACTS_SEND, ServiceSendCommand); + hServiceReceive = CreateServiceFunction(MS_CONTACTS_RECEIVE, ServiceReceiveCommand); + //define event sounds + SkinAddNewSound("RecvContacts", LPGEN("Incoming Contacts"), "contacts.wav"); + SkinAddNewSound("SentContacts", LPGEN("Outgoing Contacts"), "ocontacts.wav"); + + return 0; +} + +extern "C" __declspec(dllexport) int Unload(void) +{ + UnhookEvent(hHookModulesLoaded); + UnhookEvent(hHookDBEventAdded); + UnhookEvent(hHookContactDeleted); + UnhookEvent(hHookContactSettingChanged); + UnhookEvent(hHookPreBuildContactMenu); + + DestroyServiceFunction(hServiceSend); + DestroyServiceFunction(hServiceReceive); + + return 0; +} diff --git a/plugins/ContactsPlus/src/receive.cpp b/plugins/ContactsPlus/src/receive.cpp new file mode 100644 index 0000000000..3d3fb2f773 --- /dev/null +++ b/plugins/ContactsPlus/src/receive.cpp @@ -0,0 +1,522 @@ +// -------------------------------------------------------------------------- +// Contacts+ for Miranda Instant Messenger +// _______________________________________ +// +// Copyright © 2002 Dominus Procellarum +// Copyright © 2004-2008 Joe Kucera +// +// 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 "contacts.h" + + +/* TRecvContactsData */ + +TReceivedItem* TRecvContactsData::AddReceivedItem() { + int iItem = cbReceived; + + cbReceived++; + maReceived = (TReceivedItem**)realloc(maReceived, cbReceived*sizeof(TReceivedItem*)); + maReceived[iItem] = new TReceivedItem(); + + return maReceived[iItem]; +} + + +static int RecvDlg_Resize(HWND hwndDlg,LPARAM lParam,UTILRESIZECONTROL *urc) +{ + switch (urc->wId) + { + case IDC_CONTACTS: + return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT; + break; + case IDOK: + case IDDETAILS: + case IDC_ENABLEGROUPS: + case IDC_GROUPS: + return RD_ANCHORX_LEFT | RD_ANCHORY_BOTTOM; + break; + case IDC_ADD: + case IDC_HISTORY: + case IDC_USERMENU: + case IDC_DETAILS: + return RD_ANCHORX_RIGHT | RD_ANCHORY_TOP; + break; + case IDCANCEL: + return RD_ANCHORY_BOTTOM | RD_ANCHORX_RIGHT; + break; + } + return RD_ANCHORX_LEFT | RD_ANCHORY_TOP; // default +} + + +static char* ListView_GetItemTextEx(HWND hLV, int iItem, int iSubItem) +{ + LVITEM lvi = {0}; + + lvi.mask = LVIF_TEXT; + lvi.iSubItem = iSubItem; + lvi.cchTextMax = 64; + lvi.pszText = (char*)malloc(lvi.cchTextMax); + while (SendMessageT(hLV, LVM_GETITEMTEXT, iItem, (LPARAM)&lvi) == lvi.cchTextMax - 1) + { // loop until the returned size is smaller than buffer size + SAFE_FREE((void**)&lvi.pszText); + lvi.cchTextMax += 64; + lvi.pszText = (char*)malloc(lvi.cchTextMax); + } + return lvi.pszText; +} + + +static void EnableGroupCombo(HWND hwndDlg) +{ + EnableDlgItem(hwndDlg, IDC_GROUPS, SendMessageT(GetDlgItem(hwndDlg, IDC_ENABLEGROUPS), BM_GETCHECK, 0, 0)); +} + + +static void RebuildGroupCombo(HWND hwndDlg) +{ + DBVARIANT dbv = {0}; + char caGroupId[33]; + int bHasGroups = !DBGetContactSettingT(NULL, "CListGroups", "0", &dbv); + HWND hGroupsCombo = GetDlgItem(hwndDlg, IDC_GROUPS); + + DBFreeVariant(&dbv); + if (bHasGroups) + { + int curs = SendMessageT(hGroupsCombo, CB_GETCURSEL, 0, 0); + TCHAR* curst; + + EnableDlgItem(hwndDlg, IDC_ENABLEGROUPS, TRUE); + EnableGroupCombo(hwndDlg); + + if (curs != CB_ERR) + { + curst = (char*)_alloca((SendMessageT(hGroupsCombo, CB_GETLBTEXTLEN, curs, 0) + 1) * sizeof(WCHAR)); + SendMessageT(hGroupsCombo, CB_GETLBTEXT, curs, (LPARAM)curst); + } + SendMessageT(hGroupsCombo, CB_RESETCONTENT, 0, 0); + + for (int groupId=0; ; groupId++) + { + itoa(groupId, caGroupId, 10); + TCHAR* szGroup = DBGetContactSettingStringT(NULL, "CListGroups", caGroupId, NULL); + int nPrefix = g_UnicodeCore ? sizeof(WCHAR) : sizeof(char); + if (!szGroup) break; + int nIndex = SendMessageT(hGroupsCombo, CB_ADDSTRING, 0, (LPARAM)szGroup + nPrefix); + SendMessageT(hGroupsCombo, CB_SETITEMDATA, nIndex, groupId+1); + SAFE_FREE((void**)&szGroup); + } + if (curs != CB_ERR) + SendMessageT(hGroupsCombo, CB_SELECTSTRING, -1, (LPARAM)curst); + else + SendMessageT(hGroupsCombo, CB_SETCURSEL, 0, 0); + } + else + { // no groups available + EnableDlgItem(hwndDlg, IDC_ENABLEGROUPS, FALSE); + EnableDlgItem(hwndDlg, IDC_GROUPS, FALSE); + } +} + + +static HANDLE CreateTemporaryContactForItem(HWND hwndDlg, TRecvContactsData* wndData, int iItem) +{ + char* caUIN = ListView_GetItemTextEx(GetDlgItem(hwndDlg, IDC_CONTACTS), iItem, 0); + char* szProto = GetContactProto(wndData->mhContact); + wndData->rhSearch = (HANDLE)CallProtoService(szProto, PS_BASICSEARCH, 0, (LPARAM)caUIN); // find it + SAFE_FREE((void**)&wndData->haUin); + wndData->haUin = caUIN; + for (int j = 0; j < wndData->cbReceived; j++) + if (!strcmpnull(wndData->maReceived[j]->mcaUIN, caUIN)) + return (HANDLE)CallProtoService(szProto, PS_ADDTOLISTBYEVENT, MAKEWPARAM(PALF_TEMPORARY, j), (LPARAM)wndData->mhDbEvent); + return NULL; +} + + +void RecvListView_AddColumn(HWND hList, int nWidth, const char* szTitle, int nTranslate, int nItem) { + LVCOLUMN col; + WCHAR tmp[MAX_PATH]; + + + col.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; + col.fmt = LVCFMT_LEFT; + col.cx = nWidth; + if (nTranslate) { + col.pszText = SRCTranslateT(szTitle, tmp); + } + else { + if (!szTitle) szTitle = "UID"; + col.pszText = ansi_to_tchar(szTitle, CallService(MS_LANGPACK_GETCODEPAGE, 0, 0)); + } + col.iSubItem = nItem; + ListView_InsertColumnT(hList, nItem, &col); + if (!nTranslate) + SAFE_FREE((void**)&col.pszText); +} + + +INT_PTR CALLBACK RecvDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TRecvContactsData* wndData = (TRecvContactsData*)GetWindowLongPtr(hwndDlg, DWLP_USER); + + switch (msg) + { + case WM_INITDIALOG: + { + CLISTEVENT* pcle = (CLISTEVENT*)lParam; /// got it + + TranslateDialogDefault(hwndDlg); + WindowList_Add(ghRecvWindowList, hwndDlg, pcle->hContact); + SendMessageT(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); + EnableDlgItem(hwndDlg, IDOK, FALSE); + EnableDlgItem(hwndDlg, IDDETAILS, FALSE); + wndData = new TRecvContactsData(pcle->hContact); + SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)wndData); + wndData->mhDbEvent = pcle->hDbEvent; /// initialized, pcle not needed anymore + wndData->mhListIcon = ImageList_Create(GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),ILC_COLORDDB|ILC_MASK, 0, 1); + wndData->mhPopup = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTACTMENU)); + TranslateMenu(wndData->mhPopup); + wndData->hHook = HookEventMessage(ME_PROTO_ACK, hwndDlg, HM_EVENTSENT); + + char *szProto = GetContactProto(wndData->mhContact); + + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); + ListView_SetExtendedListViewStyle(hLV, LVS_EX_CHECKBOXES|LVS_EX_FULLROWSELECT); + // add columns + RecvListView_AddColumn(hLV, 120, (char*)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDTEXT, 0), FALSE, 0); + RecvListView_AddColumn(hLV, 100, "Nick", TRUE, 1); + RecvListView_AddColumn(hLV, 100, "First Name", TRUE, 2); + RecvListView_AddColumn(hLV, 100, "Last Name", TRUE, 3); + + // fill in groups + SendMessageT(GetDlgItem(hwndDlg, IDC_ENABLEGROUPS), BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0); + RebuildGroupCombo(hwndDlg); + + { // fill listview with received contacts + DBEVENTINFO dbe = {0}; + + dbe.cbSize = sizeof(DBEVENTINFO); + dbe.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)wndData->mhDbEvent, 0); + if (dbe.cbBlob != -1) // this marks an invalid hDbEvent - all smashed anyway... + dbe.pBlob = (PBYTE)_alloca(dbe.cbBlob); + CallService(MS_DB_EVENT_GET, (WPARAM)wndData->mhDbEvent, (LPARAM)&dbe); + char* pcBlob = (char*)dbe.pBlob; + char* pcEnd = (char*)dbe.pBlob + dbe.cbBlob; + + HICON hiProto = LoadContactProtoIcon(wndData->mhContact); + ImageList_AddIcon(wndData->mhListIcon, hiProto); + DestroyIcon(hiProto); // imagelist copied the resource + ListView_SetImageList(hLV, wndData->mhListIcon, LVSIL_SMALL); + LVITEM lvi = {0}; + lvi.iImage = 0; + lvi.mask = LVIF_TEXT | LVIF_IMAGE; + + for (int nItem = 0; ; nItem++) + { // Nick + int strsize = (int)strlennull(pcBlob); + TReceivedItem* pItem = wndData->AddReceivedItem(); + + if (dbe.flags & DBEF_UTF) + pItem->mcaNick = utf8_to_tchar((unsigned char*)pcBlob); + else + pItem->mcaNick = ansi_to_tchar(pcBlob); + pcBlob += strsize + 1; + // UIN + strsize = (int)strlennull(pcBlob); + pItem->mcaUIN = null_strdup(pcBlob); + pcBlob += strsize + 1; + // add to listview + lvi.iItem = nItem; + lvi.pszText = pItem->mcaUIN; + ListView_InsertItem(hLV, &lvi); // with image + ListView_SetItemTextT(hLV, nItem, 1, pItem->mcaNick); + // check for end of contacts + if (pcBlob >= pcEnd) + break; + } + } + // new dlg init + wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), "Add Contact Permanently to List"); + wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), "View User's Details"); + wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), "View User's History"); + wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), "User Menu"); + + SendMessageT(hwndDlg,DM_UPDATETITLE,0,0); + // new dialog init done + Utils_RestoreWindowPosition(hwndDlg, NULL, MODULENAME, ""); + return TRUE; + } + case WM_NOTIFY: + if (((LPNMHDR)lParam)->idFrom == IDC_CONTACTS) + { + switch (((LPNMHDR)lParam)->code) + { + case NM_DBLCLK: + { + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); + if (ListView_GetSelectedCount(hLV) != 1) break; // if not clicking on item, bye + wndData->iPopupItem = ListView_GetNextItem(hLV, -1, LVNI_ALL|LVNI_SELECTED); + if (wndData->iPopupItem == -1) break; // if no item selected no user details available + return SendMessageT(hwndDlg, WM_COMMAND, ID_POPUP_USERDETAILS, 0); // show user details + } + case LVN_ITEMCHANGED: + { + LPNMLISTVIEW pNMLV = (LPNMLISTVIEW)lParam; + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); // optimisation, for FOR-Cycle + bool bExistsCheckedItem = false; // there must be no checked items to disable "Add" button + + if (ListView_GetCheckState(hLV, pNMLV->iItem)) + { // the user has checked this item + bExistsCheckedItem = true; // enable "Add" button + } + else + { // loop thru items and check if at least one is checked + for (int i = 0; i < ListView_GetItemCount(hLV); i++) + if (ListView_GetCheckState(hLV, i)) + { // we found checked item, enable add, exit loop + bExistsCheckedItem = true; + break; + } + } + EnableDlgItem(hwndDlg, IDOK, bExistsCheckedItem); + EnableDlgItem(hwndDlg, IDDETAILS, ListView_GetSelectedCount(hLV) > 0); + break; + } + } + } + break; + + case WM_COMMAND: + { + if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND, MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->mhContact)) + break; + + switch(LOWORD(wParam)) + { + case IDOK: // "Add Selected" button click + { // for each selected item, find its index in the hDbEvent + // and after that add this item to the DB permanently + char* caUIN; + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); + HWND hGroupsCombo = GetDlgItem(hwndDlg, IDC_GROUPS); + HWND hGroupsCheck = GetDlgItem(hwndDlg, IDC_ENABLEGROUPS); + int curs = SendMessageT(hGroupsCombo, CB_GETCURSEL, 0, 0); + TCHAR* caGroup = NULL; + int nGroupId = -1; + if (curs != CB_ERR && IsWindowEnabled(hGroupsCheck) && SendMessageT(hGroupsCheck, BM_GETCHECK, 0, 0)) + { //got groups, get the one selected in combo + TCHAR* caGroup = (TCHAR*)_alloca((SendMessageT(hGroupsCombo, CB_GETLBTEXTLEN, curs, 0) + 1) * sizeof(WCHAR)); + SendMessageT(hGroupsCombo, CB_GETLBTEXT, curs, (LPARAM)caGroup); + nGroupId = SendMessageT(hGroupsCombo, CB_GETITEMDATA, curs, 0); + } + + for (int i = 0; i < ListView_GetItemCount(hLV); i++) + if (ListView_GetCheckState(hLV, i)) + { // found checked contact item, add it + caUIN = ListView_GetItemTextEx(hLV, i, 0); + for (int j = 0; j < wndData->cbReceived; j++) // determine item index in packet + if (!strcmpnull(wndData->maReceived[j]->mcaUIN, caUIN)) + { + char* szProto = GetContactProto(wndData->mhContact); + HANDLE hContact = (HANDLE)CallProtoService(szProto, PS_ADDTOLISTBYEVENT, MAKEWPARAM(0, j), (LPARAM)wndData->mhDbEvent); + if (hContact && caGroup) + { // use newest group API if available + if (ServiceExists(MS_CLIST_CONTACTCHANGEGROUP)) + CallService(MS_CLIST_CONTACTCHANGEGROUP, (WPARAM)hContact, (LPARAM)nGroupId); + else + DBWriteContactSettingStringT(hContact, "CList", "Group", caGroup); + } + break; + } + SAFE_FREE((void**)&caUIN); + } // move to next item + break; + } + case IDDETAILS: + { // for each selected item, find its index in the hDbEvent + // and after that add this item to the DB + // finally, request Details window for this hContact + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); + for (int i = 0; i < ListView_GetItemCount(hLV); i++) + if (ListView_GetItemState(hLV, i, LVIS_SELECTED)) + { + HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, i); + if (hContact) + CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0); + } + break; + } + case IDCANCEL: + { + SendMessageT(hwndDlg, WM_CLOSE, 0, 0); + break; + } + case IDC_ENABLEGROUPS: + { + EnableGroupCombo(hwndDlg); + break; + } + case IDC_GROUPS: + { // rebuild group list on popup + if (HIWORD(wParam) == CBN_DROPDOWN) + RebuildGroupCombo(hwndDlg); + break; + } + case ID_POPUP_ADDUSER: + { + HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); + + if (hContact) + DialogAddContactExecute(hwndDlg, hContact); + break; + } + case ID_POPUP_USERDETAILS: + { + HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); + + if (hContact) + CallService(MS_USERINFO_SHOWDIALOG, (WPARAM)hContact, 0 ); + break; + } + case ID_POPUP_SENDMESSAGE: + { + HANDLE hContact = CreateTemporaryContactForItem(hwndDlg, wndData, wndData->iPopupItem); + + if (hContact) + CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, 0); + break; + } + case IDC_USERMENU: + { + RECT rc; + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT, (WPARAM)wndData->mhContact, 0); + GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU), &rc); + TrackPopupMenu(hMenu, 0, rc.left, rc.bottom, 0, hwndDlg, NULL); + DestroyMenu(hMenu); + break; + } + case IDC_HISTORY: + CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->mhContact,0); + break; + case IDC_DETAILS: + CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->mhContact,0); + break; + case IDC_ADD: + DialogAddContactExecute(hwndDlg, wndData->mhContact); + break; + } + break; + } + case WM_CONTEXTMENU: + { + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); + LVHITTESTINFO lvh; + RECT rt; + + wndData->iPopupItem = -1; + if ((HWND)wParam != hLV) break; // if not our ListView go away + lvh.pt.x = LOWORD(lParam); + lvh.pt.y = HIWORD(lParam); + if (GetWindowRect(hLV, &rt)==0) return FALSE; // ?? why this, some check ?? + ScreenToClient(hLV, &lvh.pt); // convert to ListView local coordinates + int ci = ListView_HitTest(hLV, &lvh); + if (ci==-1) break; // mouse is not over any item + wndData->iPopupItem = ci; + TrackPopupMenu(GetSubMenu(wndData->mhPopup, 0), TPM_LEFTALIGN|TPM_TOPALIGN, LOWORD(lParam), HIWORD(lParam), 0, hwndDlg, NULL); + break; + } + case HM_EVENTSENT: + { + ACKDATA *ack=(ACKDATA*)lParam; + if (ack->type!=ACKTYPE_SEARCH) break; // not search ack, go away + if (ack->hProcess!=wndData->rhSearch) break; //not our search, go away + if (ack->result==ACKRESULT_DATA) + { + HWND hLV = GetDlgItem(hwndDlg, IDC_CONTACTS); + PROTOSEARCHRESULT* psr = (PROTOSEARCHRESULT*)ack->lParam; + LVFINDINFO fi; + fi.flags = LVFI_STRING; + fi.psz = wndData->haUin; + int iLPos = ListView_FindItem(hLV, -1, &fi); + if (iLPos==-1) iLPos=0; +// ListView_SetItemText(hLV, iLPos, 0, psr->email); // not sent by ICQ, and currently unsupported either + if (strcmpnull(psr->nick, "") && psr->nick) ListView_SetItemText(hLV, iLPos, 1, psr->nick); + ListView_SetItemText(hLV, iLPos, 2, psr->firstName); + ListView_SetItemText(hLV, iLPos, 3, psr->lastName); + break; + } + SAFE_FREE((void**)&wndData->haUin); + break; + } + case WM_CLOSE: // user closed window, so destroy it + { + WindowList_Remove(ghRecvWindowList, hwndDlg); + DestroyWindow(hwndDlg); + break; + } + case WM_DESTROY: // last message received by this dialog, cleanup + { + CallService(MS_DB_EVENT_MARKREAD, (WPARAM)wndData->mhContact, (LPARAM)wndData->mhDbEvent); + Utils_SaveWindowPosition(hwndDlg, NULL, MODULENAME, ""); + ImageList_Destroy(wndData->mhListIcon); + UnhookEvent(wndData->hHook); + DestroyMenu(wndData->mhPopup); + for (int i=0; i < SIZEOF(wndData->hIcons); i++) + DestroyIcon(wndData->hIcons[i]); + delete wndData; // automatically calls destructor + break; + } + case WM_MEASUREITEM: + return CallService(MS_CLIST_MENUMEASUREITEM, wParam, lParam); + + case WM_DRAWITEM: + { + DrawProtocolIcon(hwndDlg, lParam, wndData->mhContact); + return CallService(MS_CLIST_MENUDRAWITEM, wParam, lParam); + } + case WM_SIZE: + { // make the dlg resizeable + UTILRESIZEDIALOG urd = {0}; + + if (IsIconic(hwndDlg)) break; + urd.cbSize = sizeof(urd); + urd.hInstance = hInst; + urd.hwndDlg = hwndDlg; + urd.lParam = 0; // user-defined + urd.lpTemplate = MAKEINTRESOURCEA(IDD_RECEIVE); + urd.pfnResizer = RecvDlg_Resize; + CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM) & urd); + break; + } + case WM_GETMINMAXINFO: + { + MINMAXINFO* mmi=(MINMAXINFO*)lParam; + mmi->ptMinTrackSize.x = 480+2*GetSystemMetrics(SM_CXSIZEFRAME); + mmi->ptMinTrackSize.y = 130+2*GetSystemMetrics(SM_CYSIZEFRAME); + break; + } + case DM_UPDATETITLE: + { + UpdateDialogTitle(hwndDlg, wndData?wndData->mhContact:NULL, "Contacts from"); + if (wndData) + UpdateDialogAddButton(hwndDlg, wndData->mhContact); + break; + } + } + return FALSE; +} diff --git a/plugins/ContactsPlus/src/receive.h b/plugins/ContactsPlus/src/receive.h new file mode 100644 index 0000000000..fe35d94be6 --- /dev/null +++ b/plugins/ContactsPlus/src/receive.h @@ -0,0 +1,65 @@ +// --------------------------------------------------------------------------- +// Contacts+ for Miranda Instant Messenger +// _______________________________________ +// +// Copyright © 2002 Dominus Procellarum +// Copyright © 2004-2008 Joe Kucera +// +// 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 __RECEIVE_H +#define __RECEIVE_H + + +#define HM_EVENTSENT (WM_USER+10) + +#define DM_UPDATETITLE (WM_USER+11) + +#define IDI_ADDCONTACT 210 +#define IDI_USERDETAILS 160 +#define IDI_HISTORY 174 +#define IDI_DOWNARROW 264 + +struct TReceivedItem { + char* mcaUIN; + TCHAR* mcaNick; + ~TReceivedItem() { SAFE_FREE((void**)&mcaUIN); SAFE_FREE((void**)&mcaNick); } + TReceivedItem() { mcaUIN = NULL; mcaNick = NULL; } +}; + +struct TRecvContactsData { + HANDLE mhDbEvent; // handle to recv DB event + HANDLE mhContact; // from whom we received this + HIMAGELIST mhListIcon;// icons for listview + HMENU mhPopup; // popup menu for listview + HANDLE hHook; // hook to event + HANDLE rhSearch; // handle to uin-search + char* haUin; + int iPopupItem; + TReceivedItem** maReceived;// received contacts + int cbReceived; + TReceivedItem* AddReceivedItem(); + HICON hIcons[4]; // icons for dialog + TRecvContactsData(HANDLE contact) { mhContact = contact; hHook = NULL; cbReceived = 0; maReceived = NULL; haUin = NULL; }; + ~TRecvContactsData() { if (cbReceived) { for(int i=0;inContacts = nContacts; + ackData->aContacts = (HANDLE*)malloc(nContacts*sizeof(HANDLE)); + memmove(ackData->aContacts, phContacts, nContacts*sizeof(HANDLE)); // copy the array of hContact for ack array + EnableDlgItem(hwndDlg, IDOK, FALSE); + EnableDlgItem(hwndDlg, IDC_LIST, FALSE); + + return TRUE; // Success +} + + +int TSendContactsData::SendContacts(HWND hwndDlg) { + char* szProto = GetContactProto(hContact); + int nMaxContacts = CallProtoService(szProto, PS_GETCAPS, PFLAG_MAXCONTACTSPERPACKET, (LPARAM)hContact); + + if (!nMaxContacts) { + ShowErrorDlg(hwndDlg, "The selected contact does not support receiving contacts.", FALSE); + return FALSE; + } + // hook event - we want to receive protocol acknowledgements + HookProtoAck(hwndDlg); + + for (int j = 0; j < nContacts / nMaxContacts; j++ ) + { // send in packets, each of nMaxContacts contacts + if (!SendContactsPacket(hwndDlg, aContacts + j*nMaxContacts, nMaxContacts)) + return FALSE; + } + if (nContacts%nMaxContacts!=0) + { + if (!SendContactsPacket(hwndDlg, aContacts + nContacts/nMaxContacts*nMaxContacts, nContacts%nMaxContacts)) + return FALSE; + } + return TRUE; +} + + +/* Send Dialog Implementation */ + +static void ResetListOptions(HWND hwndList) +{ + COLORREF bgColour,fgColour; + + SendMessageT(hwndList,CLM_SETBKBITMAP,0,(LPARAM)(HBITMAP)NULL); + bgColour=GetSysColor(COLOR_WINDOW); + SendMessageT(hwndList,CLM_SETBKCOLOR,bgColour,0); + SendMessageT(hwndList,CLM_SETGREYOUTFLAGS,0,0); + SendMessageT(hwndList,CLM_SETLEFTMARGIN,4,0); + SendMessageT(hwndList,CLM_SETINDENT,10,0); + for(int i=0; i<=FONTID_MAX; i++) + { + fgColour=(COLORREF)SendMessageT(hwndList,CLM_GETTEXTCOLOR,i,0); + if(abs(GetRValue(fgColour)-GetRValue(bgColour))<10 && + abs(GetGValue(fgColour)-GetGValue(bgColour))<10 && + abs(GetBValue(fgColour)-GetBValue(bgColour))<10) + SendMessageT(hwndList,CLM_SETTEXTCOLOR,i,GetSysColor(COLOR_WINDOWTEXT)); + } +} + + +static HANDLE FindNextClistContact(HWND hList, HANDLE hContact, HANDLE *phItem) +{ + HANDLE hNextContact = SRCFindNextContact(hContact); + HANDLE hNextItem = NULL; + + while (hNextContact && !(hNextItem = (HANDLE)SendMessageT(hList, CLM_FINDCONTACT, (WPARAM)hNextContact,0))) + hNextContact = SRCFindNextContact(hNextContact); + + if (phItem) + *phItem = hNextItem; + + return hNextContact; +} + + +static HANDLE FindFirstClistContact(HWND hList, HANDLE *phItem) +{ + HANDLE hContact = SRCFindFirstContact(); + HANDLE hItem = (HANDLE)SendMessageT(hList, CLM_FINDCONTACT, (WPARAM)hContact, 0); + + if (hContact && !hItem) + return FindNextClistContact(hList, hContact, phItem); + + if (phItem) + *phItem = hItem; + + return hContact; +} + + +bool binListEvent = FALSE; + +static void SetAllContactChecks(HWND hwndList, HANDLE hReceiver) // doubtful name +{ + HANDLE hContact, hItem; + + if (binListEvent) return; + binListEvent = TRUE; + char* szProto = GetContactProto(hReceiver); + if (szProto == NULL) return; + + if (CallService(MS_CLUI_GETCAPS, 0, 0) & CLUIF_HIDEEMPTYGROUPS && DBGetContactSettingByte(NULL, "CList", "HideEmptyGroups", SETTING_USEGROUPS_DEFAULT)) + SendMessageT(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM) TRUE, 0); + else + SendMessageT(hwndList, CLM_SETHIDEEMPTYGROUPS, (WPARAM) FALSE, 0); + + hContact = FindFirstClistContact(hwndList, &hItem); + while (hContact) + { + char* szProto2 = GetContactProto(hContact); + + if (strcmpnull(szProto, szProto2)) + { // different protocols or protocol undefined, remove contact, useless anyway + SendMessageT(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0); + } + else // otherwise uncheck + SendMessageT(hwndList, CLM_SETCHECKMARK,(WPARAM)hItem, 0); + + hContact = FindNextClistContact(hwndList, hContact, &hItem); + } + + binListEvent = FALSE; +} + + +INT_PTR CALLBACK SendDlgProc( HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TSendContactsData* wndData = (TSendContactsData*)GetWindowLongPtr(hwndDlg, DWLP_USER); + + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + SendMessageT(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(hInst, MAKEINTRESOURCE(IDI_CONTACTS))); + ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST)); + SetAllContactChecks(GetDlgItem(hwndDlg,IDC_LIST), (HANDLE)lParam); + WindowList_Add(ghSendWindowList, hwndDlg, (HANDLE)lParam); + wndData = new TSendContactsData((HANDLE)lParam); + SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)wndData); + // new dlg init + wndData->hIcons[0] = InitMButton(hwndDlg, IDC_ADD, MAKEINTRESOURCEA(IDI_ADDCONTACT), "Add Contact Permanently to List"); + wndData->hIcons[1] = InitMButton(hwndDlg, IDC_DETAILS, MAKEINTRESOURCEA(IDI_USERDETAILS), "View User's Details"); + wndData->hIcons[2] = InitMButton(hwndDlg, IDC_HISTORY, MAKEINTRESOURCEA(IDI_HISTORY), "View User's History"); + wndData->hIcons[3] = InitMButton(hwndDlg, IDC_USERMENU, MAKEINTRESOURCEA(IDI_DOWNARROW), "User Menu"); + + SendMessageT(hwndDlg,DM_UPDATETITLE,0,0); + // new dialog init done + return TRUE; + } + + case WM_SETFOCUS: + SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->idFrom == IDC_LIST) + { + switch (((LPNMHDR)lParam)->code) + { + case CLN_NEWCONTACT: + case CLN_LISTREBUILT: // rebuild list + if (wndData) SetAllContactChecks(GetDlgItem(hwndDlg,IDC_LIST), wndData->hContact); + case CLN_OPTIONSCHANGED: + ResetListOptions(GetDlgItem(hwndDlg,IDC_LIST)); + break; + } + } + break; + + case WM_TIMER: + if (wParam == TIMERID_MSGSEND) + { + if (!g_SendAckSupported) + { // old Miranda has this ack unimplemented, we need to send it by ourselves + ACKDATA ack = {0}; + + ack.cbSize = sizeof(ACKDATA); + ack.type = ACKTYPE_CONTACTS; + ack.result = ACKRESULT_SUCCESS; + ack.hContact = wndData->hContact; + while (wndData->uacklist.Count) + { // the uack gets empty after processing all messages :) + ack.hProcess = wndData->uacklist.Items[0]; + SendMessageT(hwndDlg, HM_EVENTSENT, NULL, (WPARAM)&ack); // this removes the ack from our array + } + break; + } + KillTimer(hwndDlg,wParam); + wndData->ShowErrorDlg(hwndDlg, "The contacts send timed out.", TRUE); + } + break; + + case DM_ERRORDECIDED: + { + EnableWindow(hwndDlg,TRUE); + wndData->hError = NULL; + switch(wParam) + { + case MSGERROR_CANCEL: + { + wndData->UnhookProtoAck(); + if (wndData->uacklist.Count) + { + for (int i=0; iuacklist.Count; i++) + { + delete gaAckData.Remove(wndData->uacklist.Items[i]); // remove our ackdata & release structure + } + SAFE_FREE((void**)&wndData->uacklist.Items); + wndData->uacklist.Count = 0; + } + EnableDlgItem(hwndDlg,IDOK,TRUE); + EnableDlgItem(hwndDlg,IDC_LIST,TRUE); + ShowWindow(hwndDlg,SW_SHOWNORMAL); + SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); + break; + } + case MSGERROR_DONE: + // contacts were delivered succesfully after timeout + SetFocus(GetDlgItem(hwndDlg,IDC_LIST)); + wndData->UnhookProtoAck(); + break; + + case MSGERROR_RETRY:// resend timeouted packets + + for (int i=0; iuacklist.Count; i++) + { + TAckData* lla = gaAckData.Remove(wndData->uacklist.Items[i]); + HANDLE hProcc = (HANDLE)CallContactService(wndData->hContact, PSS_CONTACTS, MAKEWPARAM(0, lla->nContacts), (LPARAM)lla->aContacts); + + if (!hProcc) // if fatal do not include + { + wndData->uacklist.Remove(wndData->uacklist.Items[i]); + delete lla; // release the structure + continue; + } + else + { // update process code + wndData->uacklist.Items[i] = hProcc; + gaAckData.Add(hProcc, lla); + } + }// collect TAckData for our window, resend + break; + } + break; + } + + case WM_COMMAND: + { + if (!lParam && CallService(MS_CLIST_MENUPROCESSCOMMAND,MAKEWPARAM(LOWORD(wParam), MPCF_CONTACTMENU), (LPARAM)wndData->hContact)) + break; + + switch(LOWORD(wParam)) + { + case IDOK: + { + if (!IsWindowEnabled(GetDlgItem(hwndDlg,IDOK))) break; + HANDLE hContact, hItem; + wndData->ClearContacts(); // do not include contacts twice + + HWND hList = GetDlgItem(hwndDlg, IDC_LIST); + hContact = FindFirstClistContact(hList, &hItem); + while (hContact) + { + if (SendMessageT(hList, CLM_GETCHECKMARK, (WPARAM)hItem, 0)) + { // build list of contacts to send + wndData->AddContact(hContact); + } + hContact = FindNextClistContact(hList, hContact, &hItem); + } + /* send contacts */ + if (!wndData->SendContacts(hwndDlg)) + break; + + if (g_SendAckSupported) + SetTimer(hwndDlg,TIMERID_MSGSEND,DBGetContactSettingDword(NULL,"SRMsg","MessageTimeout",TIMEOUT_MSGSEND),NULL); + else + SetTimer(hwndDlg,TIMERID_MSGSEND,1000,NULL); // wait one second - if no error occures + + break; + } + case IDCANCEL: + { + DestroyWindow(hwndDlg); + break; + } + case ID_SELECTALL: + { // select all contacts + HANDLE hContact, hItem; + HWND hwndList = GetDlgItem(hwndDlg, IDC_LIST); + + hContact = FindFirstClistContact(hwndList, &hItem); + while (hContact) { + SendMessageT(hwndList,CLM_SETCHECKMARK,(WPARAM)hItem, 1); + hContact = FindNextClistContact(hwndList, hContact, &hItem); + }; + break; + } + case IDC_USERMENU: + { + RECT rc; + HMENU hMenu = (HMENU)CallService(MS_CLIST_MENUBUILDCONTACT,(WPARAM)wndData->hContact,0); + + GetWindowRect(GetDlgItem(hwndDlg,IDC_USERMENU),&rc); + TrackPopupMenu(hMenu,0,rc.left,rc.bottom,0,hwndDlg,NULL); + DestroyMenu(hMenu); + break; + } + case IDC_HISTORY: + CallService(MS_HISTORY_SHOWCONTACTHISTORY,(WPARAM)wndData->hContact,0); + break; + + case IDC_DETAILS: + CallService(MS_USERINFO_SHOWDIALOG,(WPARAM)wndData->hContact,0); + break; + + case IDC_ADD: + DialogAddContactExecute(hwndDlg, wndData->hContact); + break; + } + break; + } + case HM_EVENTSENT: + { + ACKDATA *ack=(ACKDATA*)lParam; + DBEVENTINFO dbei={0}; + + if (ack->type != ACKTYPE_CONTACTS) break; + + TAckData* ackData = gaAckData.Get(ack->hProcess); + + if (ackData == NULL) break; // on unknown hprocc go away + + if (ackData->hContact != ack->hContact) break; // this is not ours, strange + + if (ack->result == ACKRESULT_FAILED) + { // some process failed, show error dialog + KillTimer(hwndDlg, TIMERID_MSGSEND); + wndData->ShowErrorDlg(hwndDlg, (char *)ack->lParam, TRUE); + // ackData get used in error handling, released there + break; + } + + dbei.cbSize = sizeof(dbei); + dbei.szModule = GetContactProto(ackData->hContact); + dbei.eventType = EVENTTYPE_CONTACTS; + dbei.flags = DBEF_SENT; + if (g_UnicodeCore && g_Utf8EventsSupported) + dbei.flags |= DBEF_UTF; + dbei.timestamp = time(NULL); + //make blob + TCTSend* maSend = (TCTSend*)_alloca(ackData->nContacts*sizeof(TCTSend)); + ZeroMemory(maSend, ackData->nContacts*sizeof(TCTSend)); + dbei.cbBlob=0; + char* pBlob; + int i; + for (i=0; inContacts; i++) + { // prepare data & count size + if (g_UnicodeCore && g_Utf8EventsSupported) + maSend[i].mcaNick = make_utf8_string((WCHAR*)GetContactDisplayNameT(ackData->aContacts[i])); + else + maSend[i].mcaNick = (unsigned char*)null_strdup((char*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)ackData->aContacts[i], 0)); + maSend[i].mcaUIN = GetContactUID(ackData->aContacts[i], FALSE); + dbei.cbBlob += (DWORD)strlennull(maSend[i].mcaUIN) + (DWORD)strlennull((char*)maSend[i].mcaNick) + 2; + } + dbei.pBlob = (PBYTE)_alloca(dbei.cbBlob); + for (i=0, pBlob=(char*)dbei.pBlob; i < ackData->nContacts; i++) + { + strcpy(pBlob, (char*)maSend[i].mcaNick); + pBlob += strlennull(pBlob) + 1; + strcpy(pBlob, maSend[i].mcaUIN); + pBlob += strlennull(pBlob) + 1; + } + CallService(MS_DB_EVENT_ADD, (WPARAM)ackData->hContact,(LPARAM)&dbei); + gaAckData.Remove(ack->hProcess); // do not release here, still needed + wndData->uacklist.Remove(ack->hProcess); // packet confirmed + for (i=0; inContacts; i++) + { + SAFE_FREE((void**)&maSend[i].mcaUIN); + SAFE_FREE((void**)&maSend[i].mcaNick); + } + delete ackData; // all done, release structure + if (!wndData->uacklist.Count) + { + SkinPlaySound("SentContacts"); + KillTimer(hwndDlg, TIMERID_MSGSEND); + + if (wndData->hError) + SendMessageT(wndData->hError, DM_ERRORDECIDED, MSGERROR_DONE, 0); + + SendMessageT(hwndDlg, WM_CLOSE, 0, 0); // all packets confirmed, close the dialog + } + break; + } + + case WM_CLOSE: + { + wndData->UnhookProtoAck(); + DestroyWindow(hwndDlg); + break; + } + case WM_DESTROY: + { + int i; + for (i = 0; i < SIZEOF(wndData->hIcons); i++) + DestroyIcon(wndData->hIcons[i]); + WindowList_Remove(ghSendWindowList, hwndDlg); + delete wndData; + break; + } + case WM_MEASUREITEM: + return CallService(MS_CLIST_MENUMEASUREITEM,wParam,lParam); + + case WM_DRAWITEM: + { + DrawProtocolIcon(hwndDlg, lParam, wndData->hContact); + return CallService(MS_CLIST_MENUDRAWITEM,wParam,lParam); + } + case DM_UPDATETITLE: + { + UpdateDialogTitle(hwndDlg, wndData?wndData->hContact:NULL, "Send Contacts to"); + if (wndData) + UpdateDialogAddButton(hwndDlg, wndData->hContact); + break; + } + } + + return FALSE; +} + + +// Error Dialog + +INT_PTR CALLBACK ErrorDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_INITDIALOG: + { + RECT rc, rcParent; + + TranslateDialogDefault(hwndDlg); + + if (lParam) + { + WCHAR tmp[MAX_PATH]; + + SetDlgItemTextT(hwndDlg, IDC_ERRORTEXT, SRCTranslateT((char*)lParam, tmp)); + } + GetWindowRect(hwndDlg, &rc); + GetWindowRect(GetParent(hwndDlg), &rcParent); + SetWindowPos(hwndDlg, 0, + (rcParent.left+rcParent.right-(rc.right-rc.left))/2, + (rcParent.top+rcParent.bottom-(rc.bottom-rc.top))/2, + 0, 0, SWP_NOZORDER|SWP_NOSIZE); + } + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDOK: + SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_RETRY, 0); + DestroyWindow(hwndDlg); + break; + + case IDCANCEL: + SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_CANCEL, 0); + DestroyWindow(hwndDlg); + break; + } + break; + case DM_ERRORDECIDED: + if (wParam!=MSGERROR_DONE) break; + SendMessageT(GetParent(hwndDlg), DM_ERRORDECIDED, MSGERROR_DONE, 0); + DestroyWindow(hwndDlg); + break; + } + + return FALSE; +} diff --git a/plugins/ContactsPlus/src/send.h b/plugins/ContactsPlus/src/send.h new file mode 100644 index 0000000000..c8580a4eb1 --- /dev/null +++ b/plugins/ContactsPlus/src/send.h @@ -0,0 +1,110 @@ +// --------------------------------------------------------------------------- +// Contacts+ for Miranda Instant Messenger +// _______________________________________ +// +// Copyright © 2002 Dominus Procellarum +// Copyright © 2004-2008 Joe Kucera +// +// 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 __SEND_H +#define __SEND_H + + +#define TIMERID_MSGSEND 1024 +#define TIMEOUT_MSGSEND 9000 //ms +#define HM_EVENTSENT (WM_USER+10) +#define DM_ERRORDECIDED (WM_USER+18) +#define DM_UPDATETITLE (WM_USER+11) +#define MSGERROR_CANCEL 0 +#define MSGERROR_RETRY 1 +#define MSGERROR_DONE 2 + +#define IDI_ADDCONTACT 210 +#define IDI_USERDETAILS 160 +#define IDI_HISTORY 174 +#define IDI_DOWNARROW 264 + +struct TSendProcessList { + int Count; + HANDLE* Items; + CRITICAL_SECTION lock; + void Add(HANDLE hProcc); + void Remove(HANDLE hProcc); + TSendProcessList(); + ~TSendProcessList(); +}; + +struct TSendContactsData { // hope uack is released automaticly, static property + HANDLE hHook; // hook to event + void HookProtoAck(HWND hwndDlg); + void UnhookProtoAck(); + HANDLE* aContacts; // contacts to be sent + int nContacts; // now many UIDs shall we send? + void ClearContacts(); + void AddContact(HANDLE hContact); + HANDLE hContact; // to whom shall we send? + TSendProcessList uacklist;// ackdata - necessary for errorbox + HWND hError; // handle of error box, if any + void ShowErrorDlg(HWND hwndDlg, char* szMsg, bool bAllowRetry); + int SendContactsPacket(HWND hwndDlg, HANDLE *phContacts, int nContacts); + int SendContacts(HWND hwndDlg); + HICON hIcons[4]; // icons for dialog + TSendContactsData(HANDLE contact); + ~TSendContactsData(); +}; + +struct TAckData { + HANDLE hContact; // to whom was it sent + HANDLE* aContacts; // obj + int nContacts; // how many + TAckData(HANDLE contact) { hContact = contact; aContacts = NULL; nContacts = 0;}; + ~TAckData() { if (nContacts) SAFE_FREE((void**)&aContacts); } +}; + +typedef TAckData* PAckData; + +struct TCTSend { + char* mcaUIN; + unsigned char* mcaNick; +}; + +struct gAckItem { // some shit here + HANDLE hProcc; + PAckData ackData; + gAckItem(HANDLE procC, PAckData aData) { ackData=aData; hProcc=procC; }; + ~gAckItem() { /*delete ackData;*/ }; +}; + +struct gAckList { + gAckItem** Items; + int Count; + TAckData* Get(HANDLE hProcc) { for (int i=0; ihProcc==hProcc) { return Items[i]->ackData; }; return NULL; }; + TAckData* Add(HANDLE hProcc, TAckData* ackData) { Items=(gAckItem**)realloc(Items, (Count+1)*sizeof(gAckItem*)); Items[Count]=new gAckItem(hProcc, ackData); Count++; return ackData; }; + TAckData* Remove(HANDLE hProcc) { for (int i=0; ihProcc==hProcc) { TAckData* data=Items[i]->ackData; delete Items[i]; memmove(Items+i, Items+i+1, (Count-i-1)*sizeof(gAckItem*)); Count--; return data; }; return NULL; }; + gAckList() { Count = 0; Items = NULL; } + ~gAckList() { if (Count) { for (int i=0; ihwndItem==GetDlgItem(hwndDlg, IDC_PROTOCOL)) + { + HICON hIcon = LoadContactProtoIcon(hContact); + if (hIcon) + { + DrawIconEx(dis->hDC,dis->rcItem.left,dis->rcItem.top,hIcon,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL); + DestroyIcon(hIcon); + } + } +} + + +void UpdateDialogTitle(HWND hwndDlg, HANDLE hContact, char* pszTitleStart) +{ + TCHAR newtitle[512]; + WCHAR str[MAX_PATH]; + TCHAR *oldTitle; + TCHAR *szStatus; + char *szProto; + + if (hContact) + { + szProto = GetContactProto(hContact); + if (szProto) + { + TCHAR *uid = GetContactUID(hContact, TRUE); + TCHAR *contactName = GetContactDisplayNameT(hContact); + + oldTitle = GetDlgItemTextT(hwndDlg, IDC_NAME); + + if (strcmpT(uid?uid:contactName, oldTitle)) + SetDlgItemTextT(hwndDlg, IDC_NAME, uid?uid:contactName); + + szStatus = MirandaStatusToStringT(szProto==NULL ? ID_STATUS_OFFLINE:DBGetContactSettingWord(hContact,szProto,"Status",ID_STATUS_OFFLINE)); + _snprintfT(newtitle, 256, "%s %s (%s)", SRCTranslateT(pszTitleStart, str), contactName, szStatus); + + SAFE_FREE((void**)&uid); + SAFE_FREE((void**)&oldTitle); + } + else + strncpyT(newtitle, SRCTranslateT(pszTitleStart, str), 256); + } + else + strncpyT(newtitle, SRCTranslateT(pszTitleStart, str), 256); + + oldTitle = GetWindowTextT(hwndDlg); + + if (strcmpT(newtitle, oldTitle)) + SetWindowTextT(hwndDlg, newtitle); + + SAFE_FREE((void**)&oldTitle); +} + + +void UpdateDialogAddButton(HWND hwndDlg, HANDLE hContact) +{ + int bVisible = DBGetContactSettingByte(hContact,"CList","NotOnList",0); + + ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), bVisible?SW_SHOW:SW_HIDE); +} + + +HICON InitMButton(HWND hDlg, int idButton, LPCSTR szIcon, char* szTip) +{ + HWND hButton = GetDlgItem(hDlg, idButton); + HICON hIcon = (HICON)LoadImage(GetModuleHandle(NULL),szIcon,IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0); + + SendMessageT(hButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); + SendMessageT(hButton, BUTTONSETASFLATBTN, TRUE, 0); + SendMessageT(hButton, BUTTONADDTOOLTIP, (WPARAM)Translate(szTip), 0); + + return hIcon; +} + + +HICON LoadContactProtoIcon(HANDLE hContact) +{ + char* szProto = GetContactProto(hContact); + if (szProto) + return (HICON)CallProtoService(szProto, PS_LOADICON, PLI_PROTOCOL|PLIF_SMALL, 0); + return NULL; +} + + +void EnableDlgItem(HWND hwndDlg, UINT control, int state) +{ + EnableWindow(GetDlgItem(hwndDlg, control), state); +} + + +LRESULT SendMessageT(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + if (g_UnicodeCore) + return SendMessageW(hWnd, Msg, wParam, lParam); + else + return SendMessageA(hWnd, Msg, wParam, lParam); +} + +TCHAR* GetWindowTextT(HWND hWnd) +{ + if (g_UnicodeCore) + { + int len = GetWindowTextLengthW(hWnd) + 1; + WCHAR* txt = (WCHAR*)malloc(len * sizeof(WCHAR)); + if (txt) { + txt[0] = 0; + GetWindowTextW(hWnd, txt, len); + } + return (TCHAR*)txt; + } + else + { + int len = GetWindowTextLengthA(hWnd) + 1; + char* txt = (char*)malloc(len * sizeof(char)); + if (txt) { + txt[0] = 0; + GetWindowTextA(hWnd, txt, len); + } + return (TCHAR*)txt; + } +} + +BOOL SetWindowTextT(HWND hWnd, TCHAR* lpString) +{ + if (g_UnicodeCore) + return SetWindowTextW(hWnd, (WCHAR*)lpString); + else + return SetWindowTextA(hWnd, lpString); +} + +TCHAR* GetDlgItemTextT(HWND hDlg, int nIDDlgItem) +{ + return GetWindowTextT(GetDlgItem(hDlg, nIDDlgItem)); +} + +BOOL SetDlgItemTextT(HWND hDlg, int nIDDlgItem, TCHAR* lpString) +{ + return SetWindowTextT(GetDlgItem(hDlg, nIDDlgItem), lpString); +} + +HWND CreateDialogParamT(HINSTANCE hInstance, const char* szTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) +{ + if (g_UnicodeCore) + return CreateDialogParamW(hInstance, (LPCWSTR)szTemplate, hWndParent, lpDialogFunc, dwInitParam); + else + return CreateDialogParamA(hInstance, szTemplate, hWndParent, lpDialogFunc, dwInitParam); +} + +int ListView_InsertColumnT(HWND hwnd, int iCol, const LPLVCOLUMN pcol) +{ + return SendMessageT(hwnd, g_UnicodeCore ? LVM_INSERTCOLUMNW : LVM_INSERTCOLUMNA, (WPARAM)iCol, (LPARAM)pcol); +} + +void ListView_SetItemTextT(HWND hwnd, int i, int iSubItem, TCHAR* pszText) +{ + LV_ITEM lvi = {0}; + + lvi.iSubItem = iSubItem; + lvi.pszText = pszText; + SendMessageT(hwnd, g_UnicodeCore ? LVM_SETITEMTEXTW : LVM_SETITEMTEXTA, (WPARAM)i, (LPARAM)&lvi); +} + + + +size_t __fastcall strlenT(const TCHAR *string) +{ + if (string) + { + if (g_UnicodeCore) + return wcslen((WCHAR*)string); + else + return strlen((char*)string); + } + return 0; +} + +TCHAR* __fastcall strdupT(const TCHAR *string) +{ + if (string) + { + if (g_UnicodeCore) + return (TCHAR*)wcsdup((WCHAR*)string); + else + return (TCHAR*)strdup((char*)string); + } + return NULL; +} + +int __fastcall strcmpT(const TCHAR *string1, const TCHAR *string2) +{ + if (!string1 || !string2) return 1; + + if (g_UnicodeCore) + return wcscmp((WCHAR*)string1, (WCHAR*)string2); + else + return strcmp((char*)string1, (char*)string2); +} + +TCHAR* __fastcall strcpyT(TCHAR* dest, const TCHAR* src) +{ + if (src) + { + if (g_UnicodeCore) + return (TCHAR*)wcscpy((WCHAR*)dest, (WCHAR*)src); + else + return (TCHAR*)strcpy((char*)dest, (char*)src); + } + return dest; +} + +TCHAR* __fastcall strncpyT(TCHAR* dest, const TCHAR* src, size_t len) +{ + if (src) + { + if (g_UnicodeCore) + return (TCHAR*)wcsncpy((WCHAR*)dest, (WCHAR*)src, len); + else + return (TCHAR*)strncpy((char*)dest, (char*)src, len); + } + return dest; +} + +TCHAR* __fastcall strcatT(TCHAR* dest, const TCHAR* src) +{ + if (src) + { + if (g_UnicodeCore) + return (TCHAR*)wcscat((WCHAR*)dest, (WCHAR*)src); + else + return (TCHAR*)strcat((char*)dest, (char*)src); + } + return dest; +} + +int _snprintfT(TCHAR *buffer, size_t count, const char* fmt, ...) +{ + va_list va; + int len; + + va_start(va, fmt); + if (g_UnicodeCore) + { + TCHAR* wfmt = ansi_to_tchar(fmt); + + len = _vsnwprintf((WCHAR*)buffer, count-1, (WCHAR*)wfmt, va); + ((WCHAR*)buffer)[count-1] = 0; + SAFE_FREE((void**)&wfmt); + } + else + { + len = _vsnprintf((char*)buffer, count-1, fmt, va); + ((char*)buffer)[count-1] = 0; + } + va_end(va); + return len; +} + +TCHAR* __fastcall SRCTranslateT(const char* src, const WCHAR* unibuf) +{ // this takes Ascii strings only!!! + char* szRes = NULL; + + if (!strlennull(src)) + { // for the case of empty strings + return ""; + } + + if (g_UnicodeCore) + { // we give WCHAR + WCHAR *unicode; + int wchars, err; + + wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, + (int)strlennull(src), NULL, 0); + + if (wchars == 0) return NULL; // Failure + + unicode = (WCHAR*)unibuf; + if (!unicode) + unicode = (WCHAR*)malloc((wchars + 1) * sizeof(WCHAR)); + + unicode[wchars] = 0; + + err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, + (int)strlennull(src), unicode, wchars); + if (err != wchars) return NULL; // Failure + + return (TCHAR*)TranslateW(unicode); + } + else + return (TCHAR*)Translate(src); +} + +static BOOL bHasCP_UTF8 = FALSE; + + +void InitI18N(void) +{ + CPINFO CPInfo; + + + bHasCP_UTF8 = GetCPInfo(CP_UTF8, &CPInfo); +} + + +// Scans a string encoded in UTF-8 to verify that it contains +// only valid sequences. It will return 1 if the string contains +// only legitimate encoding sequences; otherwise it will return 0; +// From 'Secure Programming Cookbook', John Viega & Matt Messier, 2003 +int UTF8_IsValid(const unsigned char* pszInput) +{ + int nb, i; + const unsigned char* c = pszInput; + + if (!pszInput) return 0; + + for (c = pszInput; *c; c += (nb + 1)) + { + if (!(*c & 0x80)) + nb = 0; + else if ((*c & 0xc0) == 0x80) return 0; + else if ((*c & 0xe0) == 0xc0) nb = 1; + else if ((*c & 0xf0) == 0xe0) nb = 2; + else if ((*c & 0xf8) == 0xf0) nb = 3; + else if ((*c & 0xfc) == 0xf8) nb = 4; + else if ((*c & 0xfe) == 0xfc) nb = 5; + + for (i = 1; i<=nb; i++) // we this forward, do not cross end of string + if ((*(c + i) & 0xc0) != 0x80) + return 0; + } + + return 1; +} + + +/* + * The following UTF8 routines are + * + * Copyright (C) 2001 Peter Harris + * Copyright (C) 2001 Edmund Grimley Evans + * + * under a GPL license + * + * -------------------------------------------------------------- + * Convert a string between UTF-8 and the locale's charset. + * Invalid bytes are replaced by '#', and characters that are + * not available in the target encoding are replaced by '?'. + * + * If the locale's charset is not set explicitly then it is + * obtained using nl_langinfo(CODESET), where available, the + * environment variable CHARSET, or assumed to be US-ASCII. + * + * Return value of conversion functions: + * + * -1 : memory allocation failed + * 0 : data was converted exactly + * 1 : valid data was converted approximately (using '?') + * 2 : input was invalid (but still converted, using '#') + * 3 : unknown encoding (but still converted, using '?') + */ + + + +/* + * Convert a string between UTF-8 and the locale's charset. + */ +unsigned char *make_utf8_string(const wchar_t *unicode) +{ + int size = 0; + int index = 0; + int out_index = 0; + unsigned char* out; + unsigned short c; + + if (!unicode) return NULL; + + /* first calculate the size of the target string */ + c = unicode[index++]; + while (c) + { + if (c < 0x0080) + size += 1; + else if (c < 0x0800) + size += 2; + else + size += 3; + c = unicode[index++]; + } + + out = (unsigned char*)malloc(size + 1); + if (out == NULL) + return NULL; + index = 0; + + c = unicode[index++]; + while (c) + { + if (c < 0x080) + { + out[out_index++] = (unsigned char)c; + } + else if (c < 0x800) + { + out[out_index++] = 0xc0 | (c >> 6); + out[out_index++] = 0x80 | (c & 0x3f); + } + else + { + out[out_index++] = 0xe0 | (c >> 12); + out[out_index++] = 0x80 | ((c >> 6) & 0x3f); + out[out_index++] = 0x80 | (c & 0x3f); + } + c = unicode[index++]; + } + out[out_index] = 0x00; + + return out; +} + + + +WCHAR *make_unicode_string(const unsigned char *utf8) +{ + int size = 0, index = 0, out_index = 0; + wchar_t *out; + unsigned char c; + + if (!utf8) return NULL; + + /* first calculate the size of the target string */ + c = utf8[index++]; + while (c) + { + if ((c & 0x80) == 0) + { + index += 0; + } + else if ((c & 0xe0) == 0xe0) + { + index += 2; + } + else + { + index += 1; + } + size += 1; + c = utf8[index++]; + } + + out = (wchar_t*)malloc((size + 1) * sizeof(wchar_t)); + if (out == NULL) + return NULL; + index = 0; + + c = utf8[index++]; + while (c) + { + if ((c & 0x80) == 0) + { + out[out_index++] = c; + } + else if ((c & 0xe0) == 0xe0) + { + out[out_index] = (c & 0x1F) << 12; + c = utf8[index++]; + out[out_index] |= (c & 0x3F) << 6; + c = utf8[index++]; + out[out_index++] |= (c & 0x3F); + } + else + { + out[out_index] = (c & 0x3F) << 6; + c = utf8[index++]; + out[out_index++] |= (c & 0x3F); + } + c = utf8[index++]; + } + out[out_index] = 0; + + return out; +} + + +// Returns 0 on error, 1 on success +static int utf8_decode(const unsigned char *from, char **to) +{ + int nResult = 0; + +// _ASSERTE(!(*to)); // You passed a non-zero pointer, make sure it doesnt point to unfreed memory + + // Validate the string + if (!UTF8_IsValid(from)) + return 0; + + // Use the native conversion routines when available + if (bHasCP_UTF8) + { + WCHAR *wszTemp = NULL; + int inlen = (int)strlennull((char*)from); + + wszTemp = (WCHAR *)_alloca(sizeof(WCHAR) * (inlen + 1)); + + // Convert the UTF-8 string to UCS + if (MultiByteToWideChar(CP_UTF8, 0, (char*)from, -1, wszTemp, inlen + 1)) + { + // Convert the UCS string to local ANSI codepage + *to = (char*)malloc(inlen+1); + if (WideCharToMultiByte(CP_ACP, 0, wszTemp, -1, *to, inlen+1, NULL, NULL)) + { + nResult = 1; + } + else + { + SAFE_FREE((void**)to); + } + } + } + else + { + wchar_t *unicode; + int chars; + int err; + + unicode = make_unicode_string(from); + if (unicode == NULL) + { +// fprintf(stderr, "Out of memory processing string from UTF8 to UNICODE16\n"); + return 0; + } + + chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); + + if(chars == 0) + { +// fprintf(stderr, "Unicode translation error %d\n", GetLastError()); + SAFE_FREE((void**)&unicode); + return 0; + } + + *to = (char*)malloc((chars + 1)*sizeof(unsigned char)); + if (*to == NULL) + { +// fprintf(stderr, "Out of memory processing string to local charset\n"); + SAFE_FREE((void**)&unicode); + return 0; + } + + err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); + if (err != chars) + { +// fprintf(stderr, "Unicode translation error %d\n", GetLastError()); + SAFE_FREE((void**)&unicode); + SAFE_FREE((void**)to); + return 0; + } + + SAFE_FREE((void**)&unicode); + + nResult = 1; + } + + return nResult; +} + + + +TCHAR* ansi_to_tchar(const char* src, int codepage) +{ + if (g_UnicodeCore) + { + WCHAR *unicode; + int wchars, err; + + wchars = MultiByteToWideChar(codepage, MB_PRECOMPOSED, src, (int)strlennull(src), NULL, 0); + + if (wchars == 0) return NULL; // Failure + + unicode = (WCHAR*)malloc((wchars + 1) * sizeof(WCHAR)); + unicode[wchars] = 0; + + err = MultiByteToWideChar(codepage, MB_PRECOMPOSED, src, (int)strlennull(src), unicode, wchars); + if (err != wchars) + { + SAFE_FREE((void**)&unicode); + return NULL; // Failure + } + + return (TCHAR*)unicode; + } + else + return strdupT((TCHAR*)src); +} + +char* tchar_to_ansi(const TCHAR* src) +{ + if (g_UnicodeCore) + { + char *ansi; + int chars; + int err; + + chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (WCHAR*)src, -1, NULL, 0, NULL, NULL); + + if (chars == 0) return NULL; // Failure + + ansi = (char*)malloc((chars + 1)*sizeof(char)); + if (ansi == NULL) return NULL; // Failure + + err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (WCHAR*)src, -1, ansi, chars, NULL, NULL); + if (err != chars) + { + SAFE_FREE((void**)&ansi); + return NULL; + } + return ansi; + } + else + return (char*)strdupT(src); +} + +TCHAR* utf8_to_tchar(const unsigned char* utf) +{ + if (g_UnicodeCore) + return (TCHAR*)make_unicode_string(utf); + else + { + char* szAnsi = NULL; + + if (utf8_decode(utf, &szAnsi)) + return (TCHAR*)szAnsi; + else + return NULL; // Failure + } +} \ No newline at end of file diff --git a/plugins/ContactsPlus/src/utils.h b/plugins/ContactsPlus/src/utils.h new file mode 100644 index 0000000000..3bc2d8e00d --- /dev/null +++ b/plugins/ContactsPlus/src/utils.h @@ -0,0 +1,86 @@ +// --------------------------------------------------------------------------- +// Contacts+ for Miranda Instant Messenger +// _______________________________________ +// +// Copyright © 2002 Dominus Procellarum +// Copyright © 2004-2008 Joe Kucera +// +// 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 __UTILS_H +#define __UTILS_H + + +extern HINSTANCE hInst; + +// utils.cpp +void __fastcall SAFE_FREE(void** p); +size_t __fastcall strlennull(const char *string); +int __fastcall strcmpnull(const char *str1, const char *str2); +char* __fastcall null_strdup(const char *string); + +char *GetContactProto(HANDLE hContact); +char *GetContactUID(HANDLE hContact, int bTchar); +TCHAR *GetContactDisplayNameT(HANDLE hContact); +TCHAR* MirandaStatusToStringT(int mirandaStatus); + +HANDLE __fastcall SRCFindFirstContact(); +HANDLE __fastcall SRCFindNextContact(HANDLE hContact); +int DBGetContactSettingT(HANDLE hContact, const char *szModule, const char* szSetting, DBVARIANT *dbv); +TCHAR* DBGetContactSettingStringT(HANDLE hContact, const char *szModule,const char* szSetting, TCHAR* szDef); +int DBWriteContactSettingStringT(HANDLE hContact, const char *szModule, const char* szSetting, TCHAR* szValue); + +void DrawProtocolIcon(HWND hwndDlg, LPARAM lParam, HANDLE hContact); +void UpdateDialogTitle(HWND hwndDlg, HANDLE hContact, char* pszTitleStart); +void UpdateDialogAddButton(HWND hwndDlg, HANDLE hContact); + +HICON InitMButton(HWND hDlg, int idButton, LPCSTR szIcon, char* szTip); + +void DialogAddContactExecute(HWND hwndDlg, HANDLE hNewContact); + +HICON LoadContactProtoIcon(HANDLE hContact); + +void EnableDlgItem(HWND hwndDlg, UINT control, int state); + +/// Unicode 2 in 1 Framework +size_t __fastcall strlenT(const TCHAR *string); +TCHAR* __fastcall strdupT(const TCHAR *string); +int __fastcall strcmpT(const TCHAR *string1, const TCHAR *string2); +TCHAR* __fastcall strcpyT(TCHAR* dest, const TCHAR* src); +TCHAR* __fastcall strncpyT(TCHAR* dest, const TCHAR* src, size_t len); +TCHAR* __fastcall strcatT(TCHAR* dest, const TCHAR* src); +int _snprintfT(TCHAR *buffer, size_t count, const char* fmt, ...); + +LRESULT SendMessageT(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +TCHAR* GetWindowTextT(HWND hWnd); +BOOL SetWindowTextT(HWND hWnd, TCHAR* lpString); +TCHAR* GetDlgItemTextT(HWND hDlg, int nIDDlgItem); +BOOL SetDlgItemTextT(HWND hDlg, int nIDDlgItem, TCHAR* lpString); +HWND CreateDialogParamT(HINSTANCE hInstance, const char* szTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam); +int ListView_InsertColumnT(HWND hwnd, int iCol, const LPLVCOLUMN pcol); +void ListView_SetItemTextT(HWND hwnd, int i, int iSubItem, TCHAR* pszText); + +TCHAR* __fastcall SRCTranslateT(const char* src, const WCHAR* unibuf); + +void InitI18N(void); +TCHAR* ansi_to_tchar(const char* string, int codepage = CP_ACP); +char* tchar_to_ansi(const TCHAR* src); +TCHAR* utf8_to_tchar(const unsigned char* utf); +unsigned char *make_utf8_string(const wchar_t *unicode); + + +#endif /* __UTILS_H */ \ No newline at end of file diff --git a/plugins/ContactsPlus/utils.cpp b/plugins/ContactsPlus/utils.cpp deleted file mode 100644 index 1838b3bea8..0000000000 --- a/plugins/ContactsPlus/utils.cpp +++ /dev/null @@ -1,832 +0,0 @@ -// --------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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 "contacts.h" - -int utf8_decode(const unsigned char *from, char **to); - -/* a strlennull() that likes NULL */ -size_t __fastcall strlennull(const char *string) -{ - if (string) - return strlen(string); - - return 0; -} - - -int __fastcall strcmpnull(const char *str1, const char *str2) -{ - if (!str1 || !str2) return 1; - - return strcmp(str1, str2); -} - - -char* __fastcall null_strdup(const char *string) -{ - if (string) - return strdup(string); - - return NULL; -} - - -void __fastcall SAFE_FREE(void** p) -{ - if (*p) - { - free(*p); - *p = NULL; - } -} - - -char *GetContactProto(HANDLE hContact) -{ - return (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,(WPARAM)hContact,0); -} - - -TCHAR *GetContactDisplayNameT(HANDLE hContact) -{ - return (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, g_UnicodeCore ? GCDNF_UNICODE : 0); -} - - -char *GetContactUID(HANDLE hContact, int bTchar) -{ - DBVARIANT vrUid; - char *szUid = NULL; - - char *szProto = GetContactProto(hContact); - char *uid = (char*)CallProtoService(szProto, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); // v0.3+ only - - if (((int)uid != CALLSERVICE_NOTFOUND) && uid) - { // it worked, yeah :) - if (!DBGetContactSettingT(hContact, szProto, uid, &vrUid)) - { - if (vrUid.type == DBVT_DWORD) - { - szUid = (char*)_alloca(17); - szUid[0] = 0; // empty string - _itoa(vrUid.dVal, szUid, 10); - } - else if (vrUid.type == DBVT_ASCIIZ) - { - szUid = (char*)_alloca(strlennull(vrUid.pszVal) + 1); - strcpy(szUid, vrUid.pszVal); - } - else if (vrUid.type == DBVT_UTF8) - { // yeah, jabber gives this! - char *szAnsi = NULL; - - if (utf8_decode((unsigned char*)vrUid.pszVal, &szAnsi)) - { - szUid = (char*)_alloca(strlennull(szAnsi) + 1); - strcpy(szUid, szAnsi); - SAFE_FREE((void**)&szAnsi); - } - } - DBFreeVariant(&vrUid); - } - } - if (bTchar) - return ansi_to_tchar(szUid); - else - return null_strdup(szUid); -} - - -TCHAR* MirandaStatusToStringT(int mirandaStatus) -{ - return (TCHAR *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, mirandaStatus, g_UnicodeCore ? GSMDF_UNICODE : 0); -} - -HANDLE __fastcall SRCFindFirstContact() -{ - return (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); -} - -HANDLE __fastcall SRCFindNextContact(HANDLE hContact) -{ - return (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); -} - -int DBGetContactSettingT(HANDLE hContact, const char *szModule, const char* szSetting, DBVARIANT *dbv) -{ - if (ServiceExists(MS_DB_CONTACT_GETSETTING_STR)) - return DBGetContactSettingW(hContact, szModule, szSetting, dbv); - else - return DBGetContactSetting(hContact, szModule, szSetting, dbv); -} - - -TCHAR* DBGetContactSettingStringT(HANDLE hContact, const char *szModule, const char* szSetting, TCHAR* szDef) -{ - DBVARIANT dbv = {DBVT_DELETED}; - TCHAR* szRes; - - if (g_UnicodeCore) - { - if (DBGetContactSettingWString(hContact, szModule, szSetting, &dbv)) - return strdupT(szDef); - - szRes = strdupT(dbv.ptszVal); - DBFreeVariant(&dbv); - } - else - { - if (DBGetContactSettingT(hContact, szModule, szSetting, &dbv)) - return strdupT(szDef); - - if (dbv.type == DBVT_ASCIIZ) - szRes = ansi_to_tchar(dbv.pszVal); - else if (dbv.type == DBVT_UTF8) - szRes = utf8_to_tchar((unsigned char*)dbv.pszVal); - else - szRes = strdupT(szDef); - DBFreeVariant(&dbv); - } - return szRes; -} - -int DBWriteContactSettingStringT(HANDLE hContact, const char *szModule, const char* szSetting, TCHAR* szValue) -{ - if (g_UnicodeCore) - return DBWriteContactSettingWString(hContact, szModule, szSetting, (WCHAR*)szValue); - else - return DBWriteContactSettingString(hContact, szModule, szSetting, (char*)szValue); -} - - - -void DialogAddContactExecute(HWND hwndDlg, HANDLE hNewContact) -{ - ADDCONTACTSTRUCT acs={0}; - - acs.handle = hNewContact; - acs.handleType = HANDLE_CONTACT; - - CallService(MS_ADDCONTACT_SHOW, (WPARAM)hwndDlg, (LPARAM)&acs); -} - - -void DrawProtocolIcon(HWND hwndDlg, LPARAM lParam, HANDLE hContact) -{ - LPDRAWITEMSTRUCT dis=(LPDRAWITEMSTRUCT)lParam; - - if (dis->hwndItem==GetDlgItem(hwndDlg, IDC_PROTOCOL)) - { - HICON hIcon = LoadContactProtoIcon(hContact); - if (hIcon) - { - DrawIconEx(dis->hDC,dis->rcItem.left,dis->rcItem.top,hIcon,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0,NULL,DI_NORMAL); - DestroyIcon(hIcon); - } - } -} - - -void UpdateDialogTitle(HWND hwndDlg, HANDLE hContact, char* pszTitleStart) -{ - TCHAR newtitle[512]; - WCHAR str[MAX_PATH]; - TCHAR *oldTitle; - TCHAR *szStatus; - char *szProto; - - if (hContact) - { - szProto = GetContactProto(hContact); - if (szProto) - { - TCHAR *uid = GetContactUID(hContact, TRUE); - TCHAR *contactName = GetContactDisplayNameT(hContact); - - oldTitle = GetDlgItemTextT(hwndDlg, IDC_NAME); - - if (strcmpT(uid?uid:contactName, oldTitle)) - SetDlgItemTextT(hwndDlg, IDC_NAME, uid?uid:contactName); - - szStatus = MirandaStatusToStringT(szProto==NULL ? ID_STATUS_OFFLINE:DBGetContactSettingWord(hContact,szProto,"Status",ID_STATUS_OFFLINE)); - _snprintfT(newtitle, 256, "%s %s (%s)", SRCTranslateT(pszTitleStart, str), contactName, szStatus); - - SAFE_FREE((void**)&uid); - SAFE_FREE((void**)&oldTitle); - } - else - strncpyT(newtitle, SRCTranslateT(pszTitleStart, str), 256); - } - else - strncpyT(newtitle, SRCTranslateT(pszTitleStart, str), 256); - - oldTitle = GetWindowTextT(hwndDlg); - - if (strcmpT(newtitle, oldTitle)) - SetWindowTextT(hwndDlg, newtitle); - - SAFE_FREE((void**)&oldTitle); -} - - -void UpdateDialogAddButton(HWND hwndDlg, HANDLE hContact) -{ - int bVisible = DBGetContactSettingByte(hContact,"CList","NotOnList",0); - - ShowWindow(GetDlgItem(hwndDlg, IDC_ADD), bVisible?SW_SHOW:SW_HIDE); -} - - -HICON InitMButton(HWND hDlg, int idButton, LPCSTR szIcon, char* szTip) -{ - HWND hButton = GetDlgItem(hDlg, idButton); - HICON hIcon = (HICON)LoadImage(GetModuleHandle(NULL),szIcon,IMAGE_ICON,GetSystemMetrics(SM_CXSMICON),GetSystemMetrics(SM_CYSMICON),0); - - SendMessageT(hButton, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hIcon); - SendMessageT(hButton, BUTTONSETASFLATBTN, TRUE, 0); - SendMessageT(hButton, BUTTONADDTOOLTIP, (WPARAM)Translate(szTip), 0); - - return hIcon; -} - - -HICON LoadContactProtoIcon(HANDLE hContact) -{ - char* szProto = GetContactProto(hContact); - if (szProto) - return (HICON)CallProtoService(szProto, PS_LOADICON, PLI_PROTOCOL|PLIF_SMALL, 0); - return NULL; -} - - -void EnableDlgItem(HWND hwndDlg, UINT control, int state) -{ - EnableWindow(GetDlgItem(hwndDlg, control), state); -} - - -LRESULT SendMessageT(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - if (g_UnicodeCore) - return SendMessageW(hWnd, Msg, wParam, lParam); - else - return SendMessageA(hWnd, Msg, wParam, lParam); -} - -TCHAR* GetWindowTextT(HWND hWnd) -{ - if (g_UnicodeCore) - { - int len = GetWindowTextLengthW(hWnd) + 1; - WCHAR* txt = (WCHAR*)malloc(len * sizeof(WCHAR)); - if (txt) { - txt[0] = 0; - GetWindowTextW(hWnd, txt, len); - } - return (TCHAR*)txt; - } - else - { - int len = GetWindowTextLengthA(hWnd) + 1; - char* txt = (char*)malloc(len * sizeof(char)); - if (txt) { - txt[0] = 0; - GetWindowTextA(hWnd, txt, len); - } - return (TCHAR*)txt; - } -} - -BOOL SetWindowTextT(HWND hWnd, TCHAR* lpString) -{ - if (g_UnicodeCore) - return SetWindowTextW(hWnd, (WCHAR*)lpString); - else - return SetWindowTextA(hWnd, lpString); -} - -TCHAR* GetDlgItemTextT(HWND hDlg, int nIDDlgItem) -{ - return GetWindowTextT(GetDlgItem(hDlg, nIDDlgItem)); -} - -BOOL SetDlgItemTextT(HWND hDlg, int nIDDlgItem, TCHAR* lpString) -{ - return SetWindowTextT(GetDlgItem(hDlg, nIDDlgItem), lpString); -} - -HWND CreateDialogParamT(HINSTANCE hInstance, const char* szTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) -{ - if (g_UnicodeCore) - return CreateDialogParamW(hInstance, (LPCWSTR)szTemplate, hWndParent, lpDialogFunc, dwInitParam); - else - return CreateDialogParamA(hInstance, szTemplate, hWndParent, lpDialogFunc, dwInitParam); -} - -int ListView_InsertColumnT(HWND hwnd, int iCol, const LPLVCOLUMN pcol) -{ - return SendMessageT(hwnd, g_UnicodeCore ? LVM_INSERTCOLUMNW : LVM_INSERTCOLUMNA, (WPARAM)iCol, (LPARAM)pcol); -} - -void ListView_SetItemTextT(HWND hwnd, int i, int iSubItem, TCHAR* pszText) -{ - LV_ITEM lvi = {0}; - - lvi.iSubItem = iSubItem; - lvi.pszText = pszText; - SendMessageT(hwnd, g_UnicodeCore ? LVM_SETITEMTEXTW : LVM_SETITEMTEXTA, (WPARAM)i, (LPARAM)&lvi); -} - - - -size_t __fastcall strlenT(const TCHAR *string) -{ - if (string) - { - if (g_UnicodeCore) - return wcslen((WCHAR*)string); - else - return strlen((char*)string); - } - return 0; -} - -TCHAR* __fastcall strdupT(const TCHAR *string) -{ - if (string) - { - if (g_UnicodeCore) - return (TCHAR*)wcsdup((WCHAR*)string); - else - return (TCHAR*)strdup((char*)string); - } - return NULL; -} - -int __fastcall strcmpT(const TCHAR *string1, const TCHAR *string2) -{ - if (!string1 || !string2) return 1; - - if (g_UnicodeCore) - return wcscmp((WCHAR*)string1, (WCHAR*)string2); - else - return strcmp((char*)string1, (char*)string2); -} - -TCHAR* __fastcall strcpyT(TCHAR* dest, const TCHAR* src) -{ - if (src) - { - if (g_UnicodeCore) - return (TCHAR*)wcscpy((WCHAR*)dest, (WCHAR*)src); - else - return (TCHAR*)strcpy((char*)dest, (char*)src); - } - return dest; -} - -TCHAR* __fastcall strncpyT(TCHAR* dest, const TCHAR* src, size_t len) -{ - if (src) - { - if (g_UnicodeCore) - return (TCHAR*)wcsncpy((WCHAR*)dest, (WCHAR*)src, len); - else - return (TCHAR*)strncpy((char*)dest, (char*)src, len); - } - return dest; -} - -TCHAR* __fastcall strcatT(TCHAR* dest, const TCHAR* src) -{ - if (src) - { - if (g_UnicodeCore) - return (TCHAR*)wcscat((WCHAR*)dest, (WCHAR*)src); - else - return (TCHAR*)strcat((char*)dest, (char*)src); - } - return dest; -} - -int _snprintfT(TCHAR *buffer, size_t count, const char* fmt, ...) -{ - va_list va; - int len; - - va_start(va, fmt); - if (g_UnicodeCore) - { - TCHAR* wfmt = ansi_to_tchar(fmt); - - len = _vsnwprintf((WCHAR*)buffer, count-1, (WCHAR*)wfmt, va); - ((WCHAR*)buffer)[count-1] = 0; - SAFE_FREE((void**)&wfmt); - } - else - { - len = _vsnprintf((char*)buffer, count-1, fmt, va); - ((char*)buffer)[count-1] = 0; - } - va_end(va); - return len; -} - -TCHAR* __fastcall SRCTranslateT(const char* src, const WCHAR* unibuf) -{ // this takes Ascii strings only!!! - char* szRes = NULL; - - if (!strlennull(src)) - { // for the case of empty strings - return ""; - } - - if (g_UnicodeCore) - { // we give WCHAR - WCHAR *unicode; - int wchars, err; - - wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, - (int)strlennull(src), NULL, 0); - - if (wchars == 0) return NULL; // Failure - - unicode = (WCHAR*)unibuf; - if (!unicode) - unicode = (WCHAR*)malloc((wchars + 1) * sizeof(WCHAR)); - - unicode[wchars] = 0; - - err = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, src, - (int)strlennull(src), unicode, wchars); - if (err != wchars) return NULL; // Failure - - return (TCHAR*)TranslateW(unicode); - } - else - return (TCHAR*)Translate(src); -} - -static BOOL bHasCP_UTF8 = FALSE; - - -void InitI18N(void) -{ - CPINFO CPInfo; - - - bHasCP_UTF8 = GetCPInfo(CP_UTF8, &CPInfo); -} - - -// Scans a string encoded in UTF-8 to verify that it contains -// only valid sequences. It will return 1 if the string contains -// only legitimate encoding sequences; otherwise it will return 0; -// From 'Secure Programming Cookbook', John Viega & Matt Messier, 2003 -int UTF8_IsValid(const unsigned char* pszInput) -{ - int nb, i; - const unsigned char* c = pszInput; - - if (!pszInput) return 0; - - for (c = pszInput; *c; c += (nb + 1)) - { - if (!(*c & 0x80)) - nb = 0; - else if ((*c & 0xc0) == 0x80) return 0; - else if ((*c & 0xe0) == 0xc0) nb = 1; - else if ((*c & 0xf0) == 0xe0) nb = 2; - else if ((*c & 0xf8) == 0xf0) nb = 3; - else if ((*c & 0xfc) == 0xf8) nb = 4; - else if ((*c & 0xfe) == 0xfc) nb = 5; - - for (i = 1; i<=nb; i++) // we this forward, do not cross end of string - if ((*(c + i) & 0xc0) != 0x80) - return 0; - } - - return 1; -} - - -/* - * The following UTF8 routines are - * - * Copyright (C) 2001 Peter Harris - * Copyright (C) 2001 Edmund Grimley Evans - * - * under a GPL license - * - * -------------------------------------------------------------- - * Convert a string between UTF-8 and the locale's charset. - * Invalid bytes are replaced by '#', and characters that are - * not available in the target encoding are replaced by '?'. - * - * If the locale's charset is not set explicitly then it is - * obtained using nl_langinfo(CODESET), where available, the - * environment variable CHARSET, or assumed to be US-ASCII. - * - * Return value of conversion functions: - * - * -1 : memory allocation failed - * 0 : data was converted exactly - * 1 : valid data was converted approximately (using '?') - * 2 : input was invalid (but still converted, using '#') - * 3 : unknown encoding (but still converted, using '?') - */ - - - -/* - * Convert a string between UTF-8 and the locale's charset. - */ -unsigned char *make_utf8_string(const wchar_t *unicode) -{ - int size = 0; - int index = 0; - int out_index = 0; - unsigned char* out; - unsigned short c; - - if (!unicode) return NULL; - - /* first calculate the size of the target string */ - c = unicode[index++]; - while (c) - { - if (c < 0x0080) - size += 1; - else if (c < 0x0800) - size += 2; - else - size += 3; - c = unicode[index++]; - } - - out = (unsigned char*)malloc(size + 1); - if (out == NULL) - return NULL; - index = 0; - - c = unicode[index++]; - while (c) - { - if (c < 0x080) - { - out[out_index++] = (unsigned char)c; - } - else if (c < 0x800) - { - out[out_index++] = 0xc0 | (c >> 6); - out[out_index++] = 0x80 | (c & 0x3f); - } - else - { - out[out_index++] = 0xe0 | (c >> 12); - out[out_index++] = 0x80 | ((c >> 6) & 0x3f); - out[out_index++] = 0x80 | (c & 0x3f); - } - c = unicode[index++]; - } - out[out_index] = 0x00; - - return out; -} - - - -WCHAR *make_unicode_string(const unsigned char *utf8) -{ - int size = 0, index = 0, out_index = 0; - wchar_t *out; - unsigned char c; - - if (!utf8) return NULL; - - /* first calculate the size of the target string */ - c = utf8[index++]; - while (c) - { - if ((c & 0x80) == 0) - { - index += 0; - } - else if ((c & 0xe0) == 0xe0) - { - index += 2; - } - else - { - index += 1; - } - size += 1; - c = utf8[index++]; - } - - out = (wchar_t*)malloc((size + 1) * sizeof(wchar_t)); - if (out == NULL) - return NULL; - index = 0; - - c = utf8[index++]; - while (c) - { - if ((c & 0x80) == 0) - { - out[out_index++] = c; - } - else if ((c & 0xe0) == 0xe0) - { - out[out_index] = (c & 0x1F) << 12; - c = utf8[index++]; - out[out_index] |= (c & 0x3F) << 6; - c = utf8[index++]; - out[out_index++] |= (c & 0x3F); - } - else - { - out[out_index] = (c & 0x3F) << 6; - c = utf8[index++]; - out[out_index++] |= (c & 0x3F); - } - c = utf8[index++]; - } - out[out_index] = 0; - - return out; -} - - -// Returns 0 on error, 1 on success -static int utf8_decode(const unsigned char *from, char **to) -{ - int nResult = 0; - -// _ASSERTE(!(*to)); // You passed a non-zero pointer, make sure it doesnt point to unfreed memory - - // Validate the string - if (!UTF8_IsValid(from)) - return 0; - - // Use the native conversion routines when available - if (bHasCP_UTF8) - { - WCHAR *wszTemp = NULL; - int inlen = (int)strlennull((char*)from); - - wszTemp = (WCHAR *)_alloca(sizeof(WCHAR) * (inlen + 1)); - - // Convert the UTF-8 string to UCS - if (MultiByteToWideChar(CP_UTF8, 0, (char*)from, -1, wszTemp, inlen + 1)) - { - // Convert the UCS string to local ANSI codepage - *to = (char*)malloc(inlen+1); - if (WideCharToMultiByte(CP_ACP, 0, wszTemp, -1, *to, inlen+1, NULL, NULL)) - { - nResult = 1; - } - else - { - SAFE_FREE((void**)to); - } - } - } - else - { - wchar_t *unicode; - int chars; - int err; - - unicode = make_unicode_string(from); - if (unicode == NULL) - { -// fprintf(stderr, "Out of memory processing string from UTF8 to UNICODE16\n"); - return 0; - } - - chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, NULL, 0, NULL, NULL); - - if(chars == 0) - { -// fprintf(stderr, "Unicode translation error %d\n", GetLastError()); - SAFE_FREE((void**)&unicode); - return 0; - } - - *to = (char*)malloc((chars + 1)*sizeof(unsigned char)); - if (*to == NULL) - { -// fprintf(stderr, "Out of memory processing string to local charset\n"); - SAFE_FREE((void**)&unicode); - return 0; - } - - err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, unicode, -1, *to, chars, NULL, NULL); - if (err != chars) - { -// fprintf(stderr, "Unicode translation error %d\n", GetLastError()); - SAFE_FREE((void**)&unicode); - SAFE_FREE((void**)to); - return 0; - } - - SAFE_FREE((void**)&unicode); - - nResult = 1; - } - - return nResult; -} - - - -TCHAR* ansi_to_tchar(const char* src, int codepage) -{ - if (g_UnicodeCore) - { - WCHAR *unicode; - int wchars, err; - - wchars = MultiByteToWideChar(codepage, MB_PRECOMPOSED, src, (int)strlennull(src), NULL, 0); - - if (wchars == 0) return NULL; // Failure - - unicode = (WCHAR*)malloc((wchars + 1) * sizeof(WCHAR)); - unicode[wchars] = 0; - - err = MultiByteToWideChar(codepage, MB_PRECOMPOSED, src, (int)strlennull(src), unicode, wchars); - if (err != wchars) - { - SAFE_FREE((void**)&unicode); - return NULL; // Failure - } - - return (TCHAR*)unicode; - } - else - return strdupT((TCHAR*)src); -} - -char* tchar_to_ansi(const TCHAR* src) -{ - if (g_UnicodeCore) - { - char *ansi; - int chars; - int err; - - chars = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (WCHAR*)src, -1, NULL, 0, NULL, NULL); - - if (chars == 0) return NULL; // Failure - - ansi = (char*)malloc((chars + 1)*sizeof(char)); - if (ansi == NULL) return NULL; // Failure - - err = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, (WCHAR*)src, -1, ansi, chars, NULL, NULL); - if (err != chars) - { - SAFE_FREE((void**)&ansi); - return NULL; - } - return ansi; - } - else - return (char*)strdupT(src); -} - -TCHAR* utf8_to_tchar(const unsigned char* utf) -{ - if (g_UnicodeCore) - return (TCHAR*)make_unicode_string(utf); - else - { - char* szAnsi = NULL; - - if (utf8_decode(utf, &szAnsi)) - return (TCHAR*)szAnsi; - else - return NULL; // Failure - } -} \ No newline at end of file diff --git a/plugins/ContactsPlus/utils.h b/plugins/ContactsPlus/utils.h deleted file mode 100644 index 3bc2d8e00d..0000000000 --- a/plugins/ContactsPlus/utils.h +++ /dev/null @@ -1,86 +0,0 @@ -// --------------------------------------------------------------------------- -// Contacts+ for Miranda Instant Messenger -// _______________________________________ -// -// Copyright © 2002 Dominus Procellarum -// Copyright © 2004-2008 Joe Kucera -// -// 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 __UTILS_H -#define __UTILS_H - - -extern HINSTANCE hInst; - -// utils.cpp -void __fastcall SAFE_FREE(void** p); -size_t __fastcall strlennull(const char *string); -int __fastcall strcmpnull(const char *str1, const char *str2); -char* __fastcall null_strdup(const char *string); - -char *GetContactProto(HANDLE hContact); -char *GetContactUID(HANDLE hContact, int bTchar); -TCHAR *GetContactDisplayNameT(HANDLE hContact); -TCHAR* MirandaStatusToStringT(int mirandaStatus); - -HANDLE __fastcall SRCFindFirstContact(); -HANDLE __fastcall SRCFindNextContact(HANDLE hContact); -int DBGetContactSettingT(HANDLE hContact, const char *szModule, const char* szSetting, DBVARIANT *dbv); -TCHAR* DBGetContactSettingStringT(HANDLE hContact, const char *szModule,const char* szSetting, TCHAR* szDef); -int DBWriteContactSettingStringT(HANDLE hContact, const char *szModule, const char* szSetting, TCHAR* szValue); - -void DrawProtocolIcon(HWND hwndDlg, LPARAM lParam, HANDLE hContact); -void UpdateDialogTitle(HWND hwndDlg, HANDLE hContact, char* pszTitleStart); -void UpdateDialogAddButton(HWND hwndDlg, HANDLE hContact); - -HICON InitMButton(HWND hDlg, int idButton, LPCSTR szIcon, char* szTip); - -void DialogAddContactExecute(HWND hwndDlg, HANDLE hNewContact); - -HICON LoadContactProtoIcon(HANDLE hContact); - -void EnableDlgItem(HWND hwndDlg, UINT control, int state); - -/// Unicode 2 in 1 Framework -size_t __fastcall strlenT(const TCHAR *string); -TCHAR* __fastcall strdupT(const TCHAR *string); -int __fastcall strcmpT(const TCHAR *string1, const TCHAR *string2); -TCHAR* __fastcall strcpyT(TCHAR* dest, const TCHAR* src); -TCHAR* __fastcall strncpyT(TCHAR* dest, const TCHAR* src, size_t len); -TCHAR* __fastcall strcatT(TCHAR* dest, const TCHAR* src); -int _snprintfT(TCHAR *buffer, size_t count, const char* fmt, ...); - -LRESULT SendMessageT(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); -TCHAR* GetWindowTextT(HWND hWnd); -BOOL SetWindowTextT(HWND hWnd, TCHAR* lpString); -TCHAR* GetDlgItemTextT(HWND hDlg, int nIDDlgItem); -BOOL SetDlgItemTextT(HWND hDlg, int nIDDlgItem, TCHAR* lpString); -HWND CreateDialogParamT(HINSTANCE hInstance, const char* szTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam); -int ListView_InsertColumnT(HWND hwnd, int iCol, const LPLVCOLUMN pcol); -void ListView_SetItemTextT(HWND hwnd, int i, int iSubItem, TCHAR* pszText); - -TCHAR* __fastcall SRCTranslateT(const char* src, const WCHAR* unibuf); - -void InitI18N(void); -TCHAR* ansi_to_tchar(const char* string, int codepage = CP_ACP); -char* tchar_to_ansi(const TCHAR* src); -TCHAR* utf8_to_tchar(const unsigned char* utf); -unsigned char *make_utf8_string(const wchar_t *unicode); - - -#endif /* __UTILS_H */ \ No newline at end of file diff --git a/plugins/CountryFlags/countryflags-translation.txt b/plugins/CountryFlags/countryflags-translation.txt deleted file mode 100644 index 6643235c2a..0000000000 --- a/plugins/CountryFlags/countryflags-translation.txt +++ /dev/null @@ -1,17 +0,0 @@ -; Common strings that belong to many files -;[Country Flags] - -; ../../plugins/CountryFlags/extraimg.cpp -;[Advanced #%u] -;[Contact List] - -; ../../plugins/CountryFlags/main.cpp -;[Country Flags Plugin] -;[The Country Flags Plugin can not be loaded. It requires Miranda IM %hs or later.] - -; ../../plugins/CountryFlags/resource.rc -;[In following contact list &column:] -;[Show country flag as &extra image on contact list] -;[Show country flag as &status icon on message window] -;[Use &IP-to-country database for country detection] -;[Use &unknown flag if the country can not be determined] diff --git a/plugins/CountryFlags/countrylistext.cpp b/plugins/CountryFlags/countrylistext.cpp deleted file mode 100644 index 95f692b30b..0000000000 --- a/plugins/CountryFlags/countrylistext.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* -Miranda IM Country Flags Plugin -Copyright (C) 2006-2007 H. Herkenrath - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program (Flags-License.txt); if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "flags.h" - -static HANDLE hServiceGetList,hServiceGetByNumber; - -/************************* Services *******************************/ - -static struct CountryListEntry countries[]={ - {0 ,"Unspecified"}, - {9999,"Other"}, - {0xFFFF,"Unknown"}, - {93 ,"Afghanistan"}, - {355 ,"Albania"}, - {213 ,"Algeria"}, - {684 ,"American Samoa"}, - {376 ,"Andorra"}, - {244 ,"Angola"}, - {101 ,"Anguilla"}, - {102 ,"Antigua and Barbuda"}, - //{5902,"Antilles"}, /* removed */ - {54 ,"Argentina"}, - {374 ,"Armenia"}, - {297 ,"Aruba"}, - {247 ,"Ascension Island"}, - {61 ,"Australia"}, - {6721,"Australian Antarctic Territory"}, /* was missing */ - {43 ,"Austria"}, - {994 ,"Azerbaijan"}, - {103 ,"Bahamas"}, - {973 ,"Bahrain"}, - {880 ,"Bangladesh"}, - {104 ,"Barbados"}, - {120 ,"Barbuda"}, - {375 ,"Belarus"}, - {32 ,"Belgium"}, - {501 ,"Belize"}, - {229 ,"Benin"}, - {105 ,"Bermuda"}, - {975 ,"Bhutan"}, - {591 ,"Bolivia"}, - {387 ,"Bosnia and Herzegovina"}, - {267 ,"Botswana"}, - {55 ,"Brazil"}, - {106 ,"British Virgin Islands"}, - {673 ,"Brunei"}, - {359 ,"Bulgaria"}, - {226 ,"Burkina Faso"}, - {257 ,"Burundi"}, - {855 ,"Cambodia"}, - {237 ,"Cameroon"}, - {107 ,"Canada"}, - {178 ,"Canary Islands"}, - {238 ,"Cape Verde Islands"}, - {108 ,"Cayman Islands"}, - {236 ,"Central African Republic"}, - {235 ,"Chad"}, - {56 ,"Chile, Republic of"}, - {86 ,"China"}, - {672 ,"Christmas Island"}, - {6101,"Cocos-Keeling Islands"}, - //{6102,"Cocos (Keeling) Islands"}, /* removed */ - {57 ,"Colombia"}, - {2691,"Comoros"}, - {243 ,"Congo, Democratic Republic of (Zaire)"}, - {242 ,"Congo, Republic of the"}, - {682 ,"Cook Islands"}, - {506 ,"Costa Rica"}, - {225 ,"Cote d'Ivoire (Ivory Coast)"}, - {385 ,"Croatia"}, - {53 ,"Cuba"}, - {357 ,"Cyprus"}, - {420 ,"Czech Republic"}, - {45 ,"Denmark"}, - {246 ,"Diego Garcia"}, - {253 ,"Djibouti"}, - {109 ,"Dominica"}, - {110 ,"Dominican Republic"}, - {593 ,"Ecuador"}, - {20 ,"Egypt"}, - {503 ,"El Salvador"}, - {240 ,"Equatorial Guinea"}, - {291 ,"Eritrea"}, - {372 ,"Estonia"}, - {251 ,"Ethiopia"}, - {500 ,"Falkland Islands (Malvinas)"}, /* was "Falkland Islands" */ - {298 ,"Faroe Islands"}, /* was "Faeroe Islands" */ - {679 ,"Fiji"}, - {358 ,"Finland"}, - {33 ,"France"}, - {5901,"French Antilles"}, - {594 ,"French Guiana"}, - {689 ,"French Polynesia"}, - {241 ,"Gabon"}, - {220 ,"Gambia"}, - {995 ,"Georgia"}, - {49 ,"Germany"}, - {233 ,"Ghana"}, - {350 ,"Gibraltar"}, - {30 ,"Greece"}, - {299 ,"Greenland"}, - {111 ,"Grenada"}, - {590 ,"Guadeloupe"}, - {671 ,"Guam, US Territory of"}, - {5399,"Guantanamo Bay"}, /* was missing */ - {502 ,"Guatemala"}, - {224 ,"Guinea"}, - {245 ,"Guinea-Bissau"}, - {592 ,"Guyana"}, - {509 ,"Haiti"}, - {504 ,"Honduras"}, - {852 ,"Hong Kong"}, - {36 ,"Hungary"}, - {354 ,"Iceland"}, - {91 ,"India"}, - {62 ,"Indonesia"}, - {98 ,"Iran (Islamic Republic of)"}, - {964 ,"Iraq"}, - {353 ,"Ireland"}, - {972 ,"Israel"}, - {39 ,"Italy"}, - {112 ,"Jamaica"}, - {81 ,"Japan"}, - {962 ,"Jordan"}, - {705 ,"Kazakhstan"}, - {254 ,"Kenya"}, - {686 ,"Kiribati"}, - {850 ,"Korea, North"}, - {82 ,"Korea, South"}, - {965 ,"Kuwait"}, - {706 ,"Kyrgyzstan"}, - {856 ,"Laos"}, - {371 ,"Latvia"}, - {961 ,"Lebanon"}, - {266 ,"Lesotho"}, - {231 ,"Liberia"}, - {218 ,"Libyan Arab Jamahiriya"}, - {4101,"Liechtenstein"}, - {370 ,"Lithuania"}, - {352 ,"Luxembourg"}, - {853 ,"Macau"}, - {389 ,"Macedonia (F.Y.R.O.M.)"}, - {261 ,"Madagascar"}, - {265 ,"Malawi"}, - {60 ,"Malaysia"}, - {960 ,"Maldives"}, - {223 ,"Mali"}, - {356 ,"Malta"}, - {692 ,"Marshall Islands"}, - {596 ,"Martinique"}, - {222 ,"Mauritania"}, - {230 ,"Mauritius"}, - {269 ,"Mayotte Island"}, - {52 ,"Mexico"}, - {691 ,"Micronesia, Federated States of"}, - {373 ,"Moldova, Republic of"}, - {377 ,"Monaco"}, - {976 ,"Mongolia"}, - {382 ,"Montenegro, Republic of"}, /* was "Yugoslavia - Montenegro" */ - {113 ,"Montserrat"}, - {212 ,"Morocco"}, - {258 ,"Mozambique"}, - {95 ,"Myanmar"}, - {264 ,"Namibia"}, - {674 ,"Nauru"}, - {977 ,"Nepal"}, - {31 ,"Netherlands"}, - {599 ,"Netherlands Antilles"}, - {114 ,"Nevis"}, - {687 ,"New Caledonia"}, - {64 ,"New Zealand"}, - {505 ,"Nicaragua"}, - {227 ,"Niger"}, - {234 ,"Nigeria"}, - {683 ,"Niue"}, - {6722,"Norfolk Island"}, - {47 ,"Norway"}, - {968 ,"Oman"}, - {92 ,"Pakistan"}, - {680 ,"Palau"}, - {507 ,"Panama"}, - {675 ,"Papua New Guinea"}, - {595 ,"Paraguay"}, - {51 ,"Peru"}, - {63 ,"Philippines"}, - {48 ,"Poland"}, - {351 ,"Portugal"}, - {121 ,"Puerto Rico"}, - {974 ,"Qatar"}, - {262 ,"Reunion Island"}, - {40 ,"Romania"}, - {6701,"Rota Island"}, - {7 ,"Russia"}, - {250 ,"Rwanda"}, - {290 ,"Saint Helena"}, - {115 ,"Saint Kitts"}, - {1141,"Saint Kitts and Nevis"}, - {122 ,"Saint Lucia"}, - {508 ,"Saint Pierre and Miquelon"}, - {116 ,"Saint Vincent and the Grenadines"}, - {670 ,"Saipan Island (Northern Mariana Islands)"}, /* was "Saipan Island" */ - {685 ,"Samoa"}, /* was "Western Samoa" */ - {378 ,"San Marino"}, - {239 ,"Sao Tome and Principe"}, - {966 ,"Saudi Arabia"}, - {442 ,"Scotland"}, - {221 ,"Senegal"}, - {381 ,"Serbia, Republic of"}, /* was "Yugoslavia" */ - {248 ,"Seychelles"}, - {232 ,"Sierra Leone"}, - {65 ,"Singapore"}, - {421 ,"Slovakia"}, - {386 ,"Slovenia"}, - {677 ,"Solomon Islands"}, - {252 ,"Somalia"}, - {27 ,"South Africa"}, - {34 ,"Spain"}, - {94 ,"Sri Lanka"}, - {249 ,"Sudan"}, - {597 ,"Suriname"}, - {268 ,"Swaziland"}, - {46 ,"Sweden"}, - {41 ,"Switzerland"}, - {963 ,"Syrian Arab Republic"}, - {886 ,"Taiwan"}, - {708 ,"Tajikistan"}, - {255 ,"Tanzania"}, - {66 ,"Thailand"}, - {6702,"Tinian Island"}, - {228 ,"Togo"}, - {690 ,"Tokelau"}, - {676 ,"Tonga"}, - {117 ,"Trinidad and Tobago"}, - {216 ,"Tunisia"}, - {90 ,"Turkey"}, - {709 ,"Turkmenistan"}, - {118 ,"Turks and Caicos Islands"}, - {688 ,"Tuvalu"}, - {256 ,"Uganda"}, - {380 ,"Ukraine"}, - {971 ,"United Arab Emirates"}, - {44 ,"United Kingdom"}, - {598 ,"Uruguay"}, - {1 ,"USA"}, - {711 ,"Uzbekistan"}, - {678 ,"Vanuatu"}, - {379 ,"Vatican City"}, - {58 ,"Venezuela"}, - {84 ,"Vietnam"}, - {123 ,"Virgin Islands (USA)"}, - {441 ,"Wales"}, - {681 ,"Wallis and Futuna Islands"}, - {967 ,"Yemen"}, - //{3811,"Yugoslavia - Serbia"}, /* removed */ - {260 ,"Zambia"}, - {263 ,"Zimbabwe"}, -}; - -static INT_PTR ServiceGetCountryByNumber(WPARAM wParam,LPARAM lParam) -{ - int i; - UNREFERENCED_PARAMETER(lParam); - for(i=0; i24) hash^=(szStr[i]>>(32-shift))&0x7F; - shift=(shift+5)&0x1F; - } - return hash; -#endif -} - -void InitCountryListExt(void) -{ - /* hack to replace built-in country list */ - DestroyServiceFunction((HANDLE)NameHashFunction(MS_UTILS_GETCOUNTRYLIST)); - DestroyServiceFunction((HANDLE)NameHashFunction(MS_UTILS_GETCOUNTRYBYNUMBER)); - hServiceGetList=CreateServiceFunction(MS_UTILS_GETCOUNTRYLIST,ServiceGetCountryList); - hServiceGetByNumber=CreateServiceFunction(MS_UTILS_GETCOUNTRYBYNUMBER,ServiceGetCountryByNumber); -} - -void UninitCountryListExt(void) -{ - DestroyServiceFunction(hServiceGetList); - DestroyServiceFunction(hServiceGetByNumber); -} diff --git a/plugins/CountryFlags/docs/countryflags-translation.txt b/plugins/CountryFlags/docs/countryflags-translation.txt new file mode 100644 index 0000000000..6643235c2a --- /dev/null +++ b/plugins/CountryFlags/docs/countryflags-translation.txt @@ -0,0 +1,17 @@ +; Common strings that belong to many files +;[Country Flags] + +; ../../plugins/CountryFlags/extraimg.cpp +;[Advanced #%u] +;[Contact List] + +; ../../plugins/CountryFlags/main.cpp +;[Country Flags Plugin] +;[The Country Flags Plugin can not be loaded. It requires Miranda IM %hs or later.] + +; ../../plugins/CountryFlags/resource.rc +;[In following contact list &column:] +;[Show country flag as &extra image on contact list] +;[Show country flag as &status icon on message window] +;[Use &IP-to-country database for country detection] +;[Use &unknown flag if the country can not be determined] diff --git a/plugins/CountryFlags/extraimg.cpp b/plugins/CountryFlags/extraimg.cpp deleted file mode 100644 index f019827e21..0000000000 --- a/plugins/CountryFlags/extraimg.cpp +++ /dev/null @@ -1,494 +0,0 @@ -/* -Miranda IM Country Flags Plugin -Copyright (C) 2006-1007 H. Herkenrath - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program (Flags-License.txt); if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "flags.h" - -/* Services */ -static HANDLE hServiceDetectContactOrigin; -/* Extra Image */ -static HANDLE hHookExtraRebuild,hHookExtraApply; -/* Status Icon */ -static HANDLE hHookMsgWndEvent,hHookIconsChanged; -/* Options */ -static HANDLE hHookOptInit,hHookSettingChanged; -/* Misc */ -extern HINSTANCE hInst; -extern int nCountriesCount; -extern struct CountryListEntry *countries; -static HANDLE hHookModulesLoaded; - -/************************* Services *******************************/ - -static INT_PTR ServiceDetectContactOriginCountry(WPARAM wParam,LPARAM lParam) -{ - int countryNumber=0xFFFF; - char *pszProto; - UNREFERENCED_PARAMETER(lParam); - pszProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,wParam,0); - /* ip detect */ - if(DBGetContactSettingByte(NULL,"Flags","UseIpToCountry",SETTING_USEIPTOCOUNTRY_DEFAULT)) - countryNumber=ServiceIpToCountry(DBGetContactSettingDword((HANDLE)wParam,pszProto,"RealIP",0),0); - /* fallback */ - if(countryNumber==0xFFFF) - countryNumber=DBGetContactSettingWord((HANDLE)wParam,pszProto,"Country",0); - if(countryNumber==0 || countryNumber==0xFFFF) - countryNumber=DBGetContactSettingWord((HANDLE)wParam,pszProto,"CompanyCountry",0); - return (countryNumber==0)?0xFFFF:countryNumber; -} - -/************************* Extra Image ****************************/ - -#define EXTRAIMAGE_REFRESHDELAY 100 /* time for which setting changes are buffered */ - -static HANDLE *phExtraImages; -static BYTE idExtraColumn; - -static void CALLBACK SetExtraImage(LPARAM lParam) -{ - IconExtraColumn iec; - int countryNumber,index; - if(DBGetContactSettingByte(NULL,"Flags","ShowExtraImgFlag",SETTING_SHOWEXTRAIMGFLAG_DEFAULT)) { - /* get contact's country */ - iec.hImage=INVALID_HANDLE_VALUE; - countryNumber=ServiceDetectContactOriginCountry((WPARAM)lParam,0); - /* get icon */ - if(phExtraImages!=NULL) /* too early? */ - if(countryNumber!=0xFFFF || DBGetContactSettingByte(NULL,"Flags","UseUnknownFlag",SETTING_USEUNKNOWNFLAG_DEFAULT)) { - index=CountryNumberToIndex(countryNumber); - /* icon not yet loaded? */ - if(phExtraImages[index]==INVALID_HANDLE_VALUE) { - HICON hIcon; - hIcon=LoadFlagIcon(countryNumber); - if(hIcon!=NULL) phExtraImages[index]=(HANDLE)CallService(MS_CLIST_EXTRA_ADD_ICON,(WPARAM)hIcon,0); - CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon,0); /* does NULL check */ - } - iec.hImage=phExtraImages[index]; - } - /* choose column */ - iec.cbSize=sizeof(iec); - iec.ColumnType=idExtraColumn; - CallService(MS_CLIST_EXTRA_SET_ICON,(WPARAM)lParam,(LPARAM)&iec); - } -} - -// always call in context of main thread -static void RemoveExtraImages(void) -{ - IconExtraColumn iec; - register HANDLE hContact; - /* choose column */ - iec.cbSize=sizeof(iec); - iec.ColumnType=idExtraColumn; - iec.hImage=INVALID_HANDLE_VALUE; - /* enum all contacts */ - hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); - while(hContact!=NULL) { - /* invalidate icon */ - CallService(MS_CLIST_EXTRA_SET_ICON,(WPARAM)hContact,(LPARAM)&iec); - hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0); - } -} - -// always call in context of main thread -static void EnsureExtraImages(void) -{ - register HANDLE hContact; - BYTE idMaxExtraCol,idExtraColumnNew; - /* choose column */ - idMaxExtraCol=(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_EXTRACOLUMNCOUNT); /* 1-based count */ - if(idMaxExtraCol==(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_USEREXTRASTART)) /* same flags if not present */ - idMaxExtraCol=EXTRA_ICON_ADV2; /* zero if not present */ - idExtraColumnNew=DBGetContactSettingRangedByte(NULL,"Flags","ExtraImgFlagColumn",SETTING_EXTRAIMGFLAGCOLUMN_DEFAULT,1,idMaxExtraCol); - /* clear previous column */ - if(idExtraColumnNew!=idExtraColumn) RemoveExtraImages(); - idExtraColumn=idExtraColumnNew; - /* enum all contacts */ - hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); - while(hContact!=NULL) { - CallFunctionBuffered(SetExtraImage,(LPARAM)hContact,TRUE,EXTRAIMAGE_REFRESHDELAY); - hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0); - } -} - -static void CALLBACK UpdateExtraImages(LPARAM lParam) -{ - UNREFERENCED_PARAMETER(lParam); - if(DBGetContactSettingByte(NULL,"Flags","ShowExtraImgFlag",SETTING_SHOWEXTRAIMGFLAG_DEFAULT)) - EnsureExtraImages(); - else RemoveExtraImages(); -} - -static int ExtraListRebuild(WPARAM wParam,LPARAM lParam) -{ - BYTE idMaxExtraCol; - int i; - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - OutputDebugStringA("REBUILD EXTRA\n"); - /* invalidate icons */ - if(phExtraImages!=NULL) - for(i=0;iuType) { - case MSG_WINDOW_EVT_OPENING: - case MSG_WINDOW_EVT_CLOSE: - { int countryNumber; - if(msgwe->hContact==NULL || !ServiceExists(MS_MSG_ADDICON)) break; /* sanity check */ - countryNumber=ServiceDetectContactOriginCountry((WPARAM)msgwe->hContact,0); - if(DBGetContactSettingByte(NULL,"Flags","ShowStatusIconFlag",SETTING_SHOWSTATUSICONFLAG_DEFAULT)) { - if(msgwe->uType==MSG_WINDOW_EVT_OPENING) SetStatusIcon(msgwe->hContact,countryNumber); - else UnsetStatusIcon(msgwe->hContact,countryNumber); - } - /* ensure it is hidden, RemoveStatusIcons() only enums currently opened ones */ - else UnsetStatusIcon(msgwe->hContact,countryNumber); - } - } - return 0; -} - -static void CALLBACK UpdateStatusIcons(LPARAM lParam) -{ - MessageWindowInputData msgwi; /* input */ - MessageWindowData msgw; /* output */ - BOOL fShow; - int countryNumber; - UNREFERENCED_PARAMETER(lParam); - - msgwi.cbSize=sizeof(msgwi); - msgw.cbSize=sizeof(msgw); - msgwi.uFlags=MSG_WINDOW_UFLAG_MSG_BOTH; - /* enum all opened message windows */ - fShow=DBGetContactSettingByte(NULL,"Flags","ShowStatusIconFlag",SETTING_SHOWSTATUSICONFLAG_DEFAULT); - msgwi.hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); - while(msgwi.hContact!=NULL) { - /* is a message window opened for this contact? */ - if (!CallService(MS_MSG_GETWINDOWDATA,(WPARAM)&msgwi,(LPARAM)&msgw) && msgw.uState&MSG_WINDOW_STATE_EXISTS) { - countryNumber=ServiceDetectContactOriginCountry((WPARAM)msgwi.hContact,0); - if(fShow) SetStatusIcon(msgwi.hContact,countryNumber); - else UnsetStatusIcon(msgwi.hContact,countryNumber); - } - msgwi.hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)msgw.hContact,0); - } -} - -static int StatusIconsChanged(WPARAM wParam,LPARAM lParam) -{ - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - if(ServiceExists(MS_MSG_ADDICON)) - if(DBGetContactSettingByte(NULL,"Flags","ShowStatusIconFlag",SETTING_SHOWSTATUSICONFLAG_DEFAULT)) - CallFunctionBuffered(UpdateStatusIcons,0,FALSE,STATUSICON_REFRESHDELAY); - return 0; -} - -/************************* Options ************************************/ - -#define M_ENABLE_SUBCTLS (WM_APP+1) - -static INT_PTR CALLBACK ExtraImgOptDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) -{ - UNREFERENCED_PARAMETER(wParam); - switch(msg) { - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - /* init checkboxes */ - { BOOL val; - /* Status Icon */ - if(ServiceExists(MS_MSG_ADDICON)) val=DBGetContactSettingByte(NULL,"Flags","ShowStatusIconFlag",SETTING_SHOWSTATUSICONFLAG_DEFAULT)!=0; - else EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG),val=FALSE); - CheckDlgButton(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG,val); - /* Extra Image */ - if(ServiceExists(MS_CLIST_EXTRA_ADD_ICON)) val=DBGetContactSettingByte(NULL,"Flags","ShowExtraImgFlag",SETTING_SHOWEXTRAIMGFLAG_DEFAULT)!=0; - else EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG),val=FALSE); - CheckDlgButton(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG,val); - /* Unknown Flag */ - val=DBGetContactSettingByte(NULL,"Flags","UseUnknownFlag",SETTING_USEUNKNOWNFLAG_DEFAULT)!=0; - CheckDlgButton(hwndDlg,IDC_CHECK_USEUNKNOWNFLAG,val); - /* IP-to-country */ - val=DBGetContactSettingByte(NULL,"Flags","UseIpToCountry",SETTING_USEIPTOCOUNTRY_DEFAULT)!=0; - CheckDlgButton(hwndDlg,IDC_CHECK_USEIPTOCOUNTRY,val); - } - /* init combobox */ - { HWND hwndCombo; - TCHAR szItem[64]; - BYTE idColumn,idSavedColumn; - BYTE idMaxExtraCol,idAdvExtraColStart; - int index; - hwndCombo=GetDlgItem(hwndDlg,IDC_COMBO_EXTRAIMGFLAGCOLUMN); - idSavedColumn=DBGetContactSettingByte(NULL,"Flags","ExtraImgFlagColumn",SETTING_EXTRAIMGFLAGCOLUMN_DEFAULT); - idMaxExtraCol=(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_EXTRACOLUMNCOUNT); /* 1-based count */ - idAdvExtraColStart=(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_USEREXTRASTART); /* 1-based id */ - /* init */ - SendMessage(hwndCombo,CB_SETLOCALE,(LCID)CallService(MS_LANGPACK_GETLOCALE,0,0),0); /* for sort order */ - SendMessage(hwndCombo,CB_INITSTORAGE,idMaxExtraCol-idAdvExtraColStart+3,(idMaxExtraCol-idAdvExtraColStart+3)*SIZEOF(szItem)); - /* Advanced #1,#2 */ - { const BYTE columnIds[]={EXTRA_ICON_ADV1,EXTRA_ICON_ADV2}; - for(idColumn=0;idColumncode) { - case PSN_APPLY: /* setting change hook will pick these up */ - DBWriteContactSettingByte(NULL,"Flags","UseUnknownFlag",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_USEUNKNOWNFLAG)!=0)); - DBWriteContactSettingByte(NULL,"Flags","UseIpToCountry",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_USEIPTOCOUNTRY)!=0)); - /* Status Icon */ - if(IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG))) - DBWriteContactSettingByte(NULL,"Flags","ShowStatusIconFlag",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG)!=0)); - /* Extra Image */ - if(IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG))) - DBWriteContactSettingByte(NULL,"Flags","ShowExtraImgFlag",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG)!=0)); - { int index; - index=SendDlgItemMessage(hwndDlg,IDC_COMBO_EXTRAIMGFLAGCOLUMN,CB_GETCURSEL,0,0); - if(index!=LB_ERR) DBWriteContactSettingByte(NULL,"Flags","ExtraImgFlagColumn",(BYTE)SendDlgItemMessage(hwndDlg,IDC_COMBO_EXTRAIMGFLAGCOLUMN,CB_GETITEMDATA,index,0)); - } - return TRUE; - } - break; - } - return FALSE; -} - -static UINT expertOnlyControls[]={IDC_CHECK_USEIPTOCOUNTRY}; -static int ExtraImgOptInit(WPARAM wParam,LPARAM lParam) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - UNREFERENCED_PARAMETER(lParam); - odp.cbSize = sizeof(odp); - odp.hInstance = hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_EXTRAIMG); - odp.position = 900000002; - odp.pszGroup = LPGEN("Contact List"); /* autotranslated */ - odp.pszTitle = LPGEN("Country Flags"); /* autotranslated */ - odp.pszTab = LPGEN("Country Flags"); /* autotranslated, can be made a tab */ - odp.flags = ODPF_BOLDGROUPS; - odp.pfnDlgProc = ExtraImgOptDlgProc; - odp.expertOnlyControls = expertOnlyControls; - odp.nExpertOnlyControls = SIZEOF(expertOnlyControls); - Options_AddPage(wParam, &odp); - return 0; -} - -static int ExtraImgSettingChanged(WPARAM wParam,LPARAM lParam) -{ - DBCONTACTWRITESETTING *dbcws=(DBCONTACTWRITESETTING*)lParam; - if ((HANDLE)wParam==NULL) { - if (!lstrcmpA(dbcws->szModule,"Flags")) { - /* Extra Image */ - if (!lstrcmpA(dbcws->szSetting,"ShowExtraImgFlag") || - !lstrcmpA(dbcws->szSetting,"ExtraImgFlagColumn") || - !lstrcmpA(dbcws->szSetting,"UseUnknownFlag") || - !lstrcmpA(dbcws->szSetting,"UseIpToCountry")) - if(ServiceExists(MS_CLIST_EXTRA_SET_ICON)) - CallFunctionBuffered(UpdateExtraImages,0,FALSE,EXTRAIMAGE_REFRESHDELAY); - /* Status Icon */ - if (!lstrcmpA(dbcws->szSetting,"ShowStatusIconFlag") || - !lstrcmpA(dbcws->szSetting,"UseUnknownFlag") || - !lstrcmpA(dbcws->szSetting,"UseIpToCountry")) - if(ServiceExists(MS_MSG_ADDICON)) - CallFunctionBuffered(UpdateStatusIcons,0,FALSE,STATUSICON_REFRESHDELAY); - } - } - /* user details update */ - else if (!lstrcmpA(dbcws->szSetting,"RealIP") || - !lstrcmpA(dbcws->szSetting,"Country") || - !lstrcmpA(dbcws->szSetting,"CompanyCountry")) { - /* Extra Image */ - if(ServiceExists(MS_CLIST_EXTRA_SET_ICON)) - CallFunctionBuffered(SetExtraImage,(LPARAM)wParam,TRUE,EXTRAIMAGE_REFRESHDELAY); - /* Status Icon */ - if(ServiceExists(MS_MSG_ADDICON)) - CallFunctionBuffered(UpdateStatusIcons,0,FALSE,STATUSICON_REFRESHDELAY); - } - return 0; -} - -/************************* Misc ***********************************/ - -static int ExtraImgModulesLoaded(WPARAM wParam,LPARAM lParam) -{ - UNREFERENCED_PARAMETER(wParam); - UNREFERENCED_PARAMETER(lParam); - /* Options */ - if(ServiceExists("DBEditorpp/RegisterSingleModule")) - CallService("DBEditorpp/RegisterSingleModule",(WPARAM)"Flags",0); - /* Extra Image */ - if(ServiceExists(MS_CLIST_EXTRA_SET_ICON)) { - int i; - BYTE idMaxExtraCol; - phExtraImages=(HANDLE*)mir_alloc(nCountriesCount*sizeof(HANDLE)); - /* invalidate icons */ - if(phExtraImages!=NULL) - for(i=0;i -#define NONAMELESSUNION -#include /* for ImageList functions */ -#define NOWIN2K -#include -#define MIRANDA_VER 0x0A00 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define FLAGS_NOHELPERFUNCTIONS -#include "m_flags.h" -#include "resource.h" - -#if defined(_MSC_VER) && !defined(FASTCALL) - #define FASTCALL __fastcall -#else - #define FASTCALL -#endif -#if defined(_DEBUG) - #undef FASTCALL - #define FASTCALL -#endif - -/* countrylistext.c */ -void InitCountryListExt(void); -void UninitCountryListExt(void); - -/* huffman.c */ -#ifdef HUFFMAN_ENCODE - int Huffman_Compress(unsigned char *in,unsigned char *out,unsigned int insize ); -#endif -void Huffman_Uncompress(unsigned char *in,unsigned char *out,unsigned int insize,unsigned int outsize); - -/* icons.c */ -HICON FASTCALL LoadFlagIcon(int countryNumber); -int FASTCALL CountryNumberToIndex(int countryNumber); -void InitIcons(void); -void UninitIcons(void); - -/* ip2country.c */ -INT_PTR ServiceIpToCountry(WPARAM wParam,LPARAM lParam); -void InitIpToCountry(void); -void UninitIpToCountry(void); - -/* extraimg.c */ -void InitExtraImg(void); -void UninitExtraImg(void); - -/* utils.c */ -typedef void (CALLBACK *BUFFEREDPROC)(LPARAM lParam); -#ifdef _DEBUG - void _CallFunctionBuffered(BUFFEREDPROC pfnBuffProc,const char *pszProcName,LPARAM lParam,BOOL fAccumulateSameParam,UINT uElapse); - #define CallFunctionBuffered(proc,param,acc,elapse) _CallFunctionBuffered(proc,#proc,param,acc,elapse) -#else - void _CallFunctionBuffered(BUFFEREDPROC pfnBuffProc,LPARAM lParam,BOOL fAccumulateSameParam,UINT uElapse); - #define CallFunctionBuffered(proc,param,acc,elapse) _CallFunctionBuffered(proc,param,acc,elapse) -#endif -void PrepareBufferedFunctions(void); -void KillBufferedFunctions(void); diff --git a/plugins/CountryFlags/flags.vcxproj b/plugins/CountryFlags/flags.vcxproj index 62dd7df548..ef1c334390 100644 --- a/plugins/CountryFlags/flags.vcxproj +++ b/plugins/CountryFlags/flags.vcxproj @@ -82,7 +82,7 @@ ..\..\include\msapi - _DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _DEBUG;%(PreprocessorDefinitions) true @@ -107,7 +107,7 @@ ..\..\include\msapi - _DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _DEBUG;%(PreprocessorDefinitions) true @@ -133,7 +133,7 @@ ..\..\include\msapi - NDEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NDEBUG;%(PreprocessorDefinitions) true @@ -161,7 +161,7 @@ ..\..\include\msapi - NDEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) + NDEBUG;%(PreprocessorDefinitions) true @@ -177,18 +177,18 @@ - - - - - - - + + + + + + + - - - + + + @@ -203,7 +203,8 @@ - + + diff --git a/plugins/CountryFlags/flags.vcxproj.filters b/plugins/CountryFlags/flags.vcxproj.filters index 1d3dd91efb..9d5d5b9f0f 100644 --- a/plugins/CountryFlags/flags.vcxproj.filters +++ b/plugins/CountryFlags/flags.vcxproj.filters @@ -19,41 +19,44 @@ - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Header Files - + Resource Files - + Resource Files - + + Resource Files + + Resource Files diff --git a/plugins/CountryFlags/huffman.cpp b/plugins/CountryFlags/huffman.cpp deleted file mode 100644 index c460e9a66e..0000000000 --- a/plugins/CountryFlags/huffman.cpp +++ /dev/null @@ -1,506 +0,0 @@ -/************************************************************************* -* Name: huffman.c -* Author: Marcus Geelnard -* Description: Huffman coder/decoder implementation. -* Reentrant: Yes -* -* This is a very straight forward implementation of a Huffman coder and -* decoder. -* -* Primary flaws with this primitive implementation are: -* - Slow bit stream implementation -* - Maximum tree depth of 32 (the coder aborts if any code exceeds a -* size of 32 bits). If I'm not mistaking, this should not be possible -* unless the input buffer is larger than 2^32 bytes, which is not -* supported by the coder anyway (max 2^32-1 bytes can be specified with -* an unsigned 32-bit integer). -* -* On the other hand, there are a few advantages of this implementation: -* - The Huffman tree is stored in a very compact form, requiring only -* 10 bits per symbol (for 8 bit symbols), meaning a maximum of 320 -* bytes overhead. -* - The code should be fairly easy to follow, if you are familiar with -* how the Huffman compression algorithm works. -* -* Possible improvements (probably not worth it): -* - Partition the input data stream into blocks, where each block has -* its own Huffman tree. With variable block sizes, it should be -* possible to find locally optimal Huffman trees, which in turn could -* reduce the total size. -* - Allow for a few different predefined Huffman trees, which could -* reduce the size of a block even further. -*------------------------------------------------------------------------- -* Copyright (c) 2003-2006 Marcus Geelnard -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would -* be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not -* be misrepresented as being the original software. -* -* 3. This notice may not be removed or altered from any source -* distribution. -* -* Marcus Geelnard -* marcus.geelnard at home.se -*************************************************************************/ - - -/************************************************************************* -* Types used for Huffman coding -*************************************************************************/ - -typedef struct { - unsigned char *BytePtr; - unsigned int BitPos; -} huff_bitstream_t; - -typedef struct { - int Symbol; - unsigned int Count; - unsigned int Code; - unsigned int Bits; -} huff_sym_t; - -typedef struct huff_encodenode_struct huff_encodenode_t; - -struct huff_encodenode_struct { - huff_encodenode_t *ChildA, *ChildB; - int Count; - int Symbol; -}; - -typedef struct huff_decodenode_struct huff_decodenode_t; - -struct huff_decodenode_struct { - huff_decodenode_t *ChildA, *ChildB; - int Symbol; -}; - - -/************************************************************************* -* Constants for Huffman decoding -*************************************************************************/ - -/* The maximum number of nodes in the Huffman tree is 2^(8+1)-1 = 511 */ -#define MAX_TREE_NODES 511 - - -/************************************************************************* -* _Huffman_InitBitstream() - Initialize a bitstream. -*************************************************************************/ - -static void _Huffman_InitBitstream( huff_bitstream_t *stream, - unsigned char *buf ) -{ - stream->BytePtr = buf; - stream->BitPos = 0; -} - - -/************************************************************************* -* _Huffman_ReadBit() - Read one bit from a bitstream. -*************************************************************************/ - -static unsigned int _Huffman_ReadBit( huff_bitstream_t *stream ) -{ - unsigned int x, bit; - unsigned char *buf; - - /* Get current stream state */ - buf = stream->BytePtr; - bit = stream->BitPos; - - /* Extract bit */ - x = (*buf & (1<<(7-bit))) ? 1 : 0; - bit = (bit+1) & 7; - if ( !bit ) - { - ++ buf; - } - - /* Store new stream state */ - stream->BitPos = bit; - stream->BytePtr = buf; - - return x; -} - - -/************************************************************************* -* _Huffman_Read8Bits() - Read eight bits from a bitstream. -*************************************************************************/ - -static unsigned int _Huffman_Read8Bits( huff_bitstream_t *stream ) -{ - unsigned int x, bit; - unsigned char *buf; - - /* Get current stream state */ - buf = stream->BytePtr; - bit = stream->BitPos; - - /* Extract byte */ - x = (*buf << bit) | (buf[1] >> (8-bit)); - ++ buf; - - /* Store new stream state */ - stream->BytePtr = buf; - - return x; -} - - -/************************************************************************* -* _Huffman_WriteBits() - Write bits to a bitstream. -*************************************************************************/ - -#ifdef HUFFMAN_ENCODE -static void _Huffman_WriteBits( huff_bitstream_t *stream, unsigned int x, - unsigned int bits ) -{ - unsigned int bit, count; - unsigned char *buf; - unsigned int mask; - - /* Get current stream state */ - buf = stream->BytePtr; - bit = stream->BitPos; - - /* Append bits */ - mask = 1 << (bits-1); - for ( count = 0; count < bits; ++ count ) - { - *buf = (unsigned char)((*buf & (0xff^(1<<(7-bit)))) + - ((x & mask ? 1 : 0) << (7-bit))); - x <<= 1; - bit = (bit+1) & 7; - if ( !bit ) - { - ++ buf; - } - } - - /* Store new stream state */ - stream->BytePtr = buf; - stream->BitPos = bit; -} -#endif - - -/************************************************************************* -* _Huffman_Hist() - Calculate (sorted) histogram for a block of data. -*************************************************************************/ - -#ifdef HUFFMAN_ENCODE -static void _Huffman_Hist( unsigned char *in, huff_sym_t *sym, - unsigned int size ) -{ - int k; - - /* Clear/init histogram */ - for ( k = 0; k < 256; ++ k ) - { - sym[k].Symbol = k; - sym[k].Count = 0; - sym[k].Code = 0; - sym[k].Bits = 0; - } - - /* Build histogram */ - for ( k = size; k; -- k ) - { - sym[*in ++].Count ++; - } -} -#endif - - -/************************************************************************* -* _Huffman_StoreTree() - Store a Huffman tree in the output stream and -* in a look-up-table (a symbol array). -*************************************************************************/ - -#ifdef HUFFMAN_ENCODE -static void _Huffman_StoreTree( huff_encodenode_t *node, huff_sym_t *sym, - huff_bitstream_t *stream, unsigned int code, unsigned int bits ) -{ - unsigned int sym_idx; - - /* Is this a leaf node? */ - if ( node->Symbol >= 0 ) - { - /* Append symbol to tree description */ - _Huffman_WriteBits( stream, 1, 1 ); - _Huffman_WriteBits( stream, node->Symbol, 8 ); - - /* Find symbol index */ - for ( sym_idx = 0; sym_idx < 256; ++ sym_idx ) - { - if ( sym[sym_idx].Symbol == node->Symbol ) break; - } - - /* Store code info in symbol array */ - sym[sym_idx].Code = code; - sym[sym_idx].Bits = bits; - return; - } - else - { - /* This was not a leaf node */ - _Huffman_WriteBits( stream, 0, 1 ); - } - - /* Branch A */ - _Huffman_StoreTree( node->ChildA, sym, stream, (code<<1)+0, bits+1 ); - - /* Branch B */ - _Huffman_StoreTree( node->ChildB, sym, stream, (code<<1)+1, bits+1 ); -} -#endif - - -/************************************************************************* -* _Huffman_MakeTree() - Generate a Huffman tree. -*************************************************************************/ - -#ifdef HUFFMAN_ENCODE -static void _Huffman_MakeTree( huff_sym_t *sym, huff_bitstream_t *stream ) -{ - huff_encodenode_t nodes[MAX_TREE_NODES], *node_1, *node_2, *root; - unsigned int k, num_symbols, nodes_left, next_idx; - - /* Initialize all leaf nodes */ - num_symbols = 0; - for ( k = 0; k < 256; ++ k ) - { - if ( sym[k].Count > 0 ) - { - nodes[num_symbols].Symbol = sym[k].Symbol; - nodes[num_symbols].Count = sym[k].Count; - nodes[num_symbols].ChildA = (huff_encodenode_t *) 0; - nodes[num_symbols].ChildB = (huff_encodenode_t *) 0; - ++ num_symbols; - } - } - - /* Build tree by joining the lightest nodes until there is only - one node left (the root node). */ - root = (huff_encodenode_t *) 0; - nodes_left = num_symbols; - next_idx = num_symbols; - while( nodes_left > 1 ) - { - /* Find the two lightest nodes */ - node_1 = (huff_encodenode_t *) 0; - node_2 = (huff_encodenode_t *) 0; - for ( k = 0; k < next_idx; ++ k ) - { - if ( nodes[k].Count > 0 ) - { - if ( !node_1 || (nodes[k].Count <= node_1->Count)) - { - node_2 = node_1; - node_1 = &nodes[k]; - } - else if ( !node_2 || (nodes[k].Count <= node_2->Count)) - { - node_2 = &nodes[k]; - } - } - } - - /* Join the two nodes into a new parent node */ - root = &nodes[next_idx]; - root->ChildA = node_1; - root->ChildB = node_2; - root->Count = node_1->Count + node_2->Count; - root->Symbol = -1; - node_1->Count = 0; - node_2->Count = 0; - ++ next_idx; - -- nodes_left; - } - - /* Store the tree in the output stream, and in the sym[] array (the - latter is used as a look-up-table for faster encoding) */ - if ( root ) - { - _Huffman_StoreTree( root, sym, stream, 0, 0 ); - } - else - { - /* Special case: only one symbol => no binary tree */ - root = &nodes[0]; - _Huffman_StoreTree( root, sym, stream, 0, 1 ); - } -} -#endif - - -/************************************************************************* -* _Huffman_RecoverTree() - Recover a Huffman tree from a bitstream. -*************************************************************************/ - -static huff_decodenode_t * _Huffman_RecoverTree( huff_decodenode_t *nodes, - huff_bitstream_t *stream, unsigned int *nodenum ) -{ - huff_decodenode_t * this_node; - - /* Pick a node from the node array */ - this_node = &nodes[*nodenum]; - *nodenum = *nodenum + 1; - - /* Clear the node */ - this_node->Symbol = -1; - this_node->ChildA = (huff_decodenode_t *) 0; - this_node->ChildB = (huff_decodenode_t *) 0; - - /* Is this a leaf node? */ - if ( _Huffman_ReadBit( stream )) - { - /* Get symbol from tree description and store in lead node */ - this_node->Symbol = _Huffman_Read8Bits( stream ); - - return this_node; - } - - /* Get branch A */ - this_node->ChildA = _Huffman_RecoverTree( nodes, stream, nodenum ); - - /* Get branch B */ - this_node->ChildB = _Huffman_RecoverTree( nodes, stream, nodenum ); - - return this_node; -} - - - -/************************************************************************* -* PUBLIC FUNCTIONS * -*************************************************************************/ - - -/************************************************************************* -* Huffman_Compress() - Compress a block of data using a Huffman coder. -* in - Input (uncompressed) buffer. -* out - Output (compressed) buffer. This buffer must be 384 bytes -* larger than the input buffer. -* insize - Number of input bytes. -* The function returns the size of the compressed data. -*************************************************************************/ - -#ifdef HUFFMAN_ENCODE -int Huffman_Compress( unsigned char *in, unsigned char *out, - unsigned int insize ) -{ - huff_sym_t sym[256], tmp; - huff_bitstream_t stream; - unsigned int k, total_bytes, swaps, symbol; - - /* Do we have anything to compress? */ - if ( insize < 1 ) return 0; - - /* Initialize bitstream */ - _Huffman_InitBitstream( &stream, out ); - - /* Calculate and sort histogram for input data */ - _Huffman_Hist( in, sym, insize ); - - /* Build Huffman tree */ - _Huffman_MakeTree( sym, &stream ); - - /* Sort histogram - first symbol first (bubble sort) */ - do - { - swaps = 0; - for ( k = 0; k < 255; ++ k ) - { - if ( sym[k].Symbol > sym[k+1].Symbol ) - { - tmp = sym[k]; - sym[k] = sym[k+1]; - sym[k+1] = tmp; - swaps = 1; - } - } - } - while( swaps ); - - /* Encode input stream */ - for ( k = 0; k < insize; ++ k ) - { - symbol = in[k]; - _Huffman_WriteBits( &stream, sym[symbol].Code, - sym[symbol].Bits ); - } - - /* Calculate size of output data */ - total_bytes = (int)(stream.BytePtr - out); - if ( stream.BitPos > 0 ) - { - ++ total_bytes; - } - - return total_bytes; -} -#endif - - -/************************************************************************* -* Huffman_Uncompress() - Uncompress a block of data using a Huffman -* decoder. -* in - Input (compressed) buffer. -* out - Output (uncompressed) buffer. This buffer must be large -* enough to hold the uncompressed data. -* insize - Number of input bytes. -* outsize - Number of output bytes. -*************************************************************************/ - -void Huffman_Uncompress( unsigned char *in, unsigned char *out, - unsigned int insize, unsigned int outsize ) -{ - huff_decodenode_t nodes[MAX_TREE_NODES], *root, *node; - huff_bitstream_t stream; - unsigned int k, node_count; - unsigned char *buf; - - /* Do we have anything to decompress? */ - if ( insize < 1 ) return; - - /* Initialize bitstream */ - _Huffman_InitBitstream( &stream, in ); - - /* Recover Huffman tree */ - node_count = 0; - root = _Huffman_RecoverTree( nodes, &stream, &node_count ); - - /* Decode input stream */ - buf = out; - for ( k = 0; k < outsize; ++ k ) - { - /* Traverse tree until we find a matching leaf node */ - node = root; - while( node->Symbol < 0 ) - { - /* Get next node */ - if ( _Huffman_ReadBit( &stream )) - node = node->ChildB; - else - node = node->ChildA; - } - - /* We found the matching leaf node and have the symbol */ - *buf ++ = (unsigned char) node->Symbol; - } -} diff --git a/plugins/CountryFlags/icons.cpp b/plugins/CountryFlags/icons.cpp deleted file mode 100644 index 3b456a4d11..0000000000 --- a/plugins/CountryFlags/icons.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* -Miranda IM Country Flags Plugin -Copyright (C) 2006-1007 H. Herkenrath - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program (Flags-License.txt); if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "flags.h" - -extern HINSTANCE hInst; -extern int nCountriesCount; -extern struct CountryListEntry *countries; -static HANDLE hServiceLoadIcon,hServiceCreateMergedIcon; - -/************************* Bitmap Access **************************/ - -static HANDLE *phIconHandles; - -static int FASTCALL CountryNumberToBitmapIndex(int countryNumber) -{ - /* country number indices (same order as in flags.bmp) */ - const int BitmapIndexMap[232]={ - 0, 1, 7, 20, 27, 30, 31, 32, 33, 34, 36, 39, 40, 41, 43, 44, 45, 46, 47, 48, - 49, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 63, 64, 65, 66, 81, 82, 84, 86, - 90, 91, 92, 93, 94, 95, 98, 101, 102, 103, 104, 105, 106, 107, 178, 108, 109, 110, 111, 112, - 113, 116, 117, 118, 121, 122, 123, 212, 213, 216, 218, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 260, 261, 263, 264, 265, 266, 267, 268, 269, 290, 291, - 297, 298, 299, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, 381, 382, 385, 386, 387, 389, 420, 421, 441, 442, 500, 501, 502, 503, 504, 505, - 506, 507, 508, 509, 590, 591, 592, 593, 595, 596, 597, 598, 599, 670, 671, 672, 673, 674, 675, 676, - 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 705, 706, 708, 709, - 711, 850, 852, 853, 855, 856, 880, 886, 960, 961, 962, 963, 964, 965, 966, 967, 968, 971, 972, 973, - 974, 975, 976, 977, 994, 995,1141,2691,3811,4101,6101,6722 - }; - /* shared flags by multiple countries */ - switch(countryNumber) { - case 262: /* Reunion Island */ - case 594: /* French Guiana */ - case 5901: /* French Antilles */ - countryNumber=33; /* France */ - break; - case 120: /* Barbuda */ - countryNumber=102; /* Antigua and Barbuda */ - break; - case 6702: /* Tinian Island */ - case 6701: /* Rota Island */ - countryNumber=670; /* Saipan Island (Northern Mariana Islands) */ - break; - case 115: /* Saint Kitts */ - case 114: /* Nevis */ - countryNumber=1141; /* Saint Kitts and Nevis */ - break; - case 247: /* Ascension Island */ - countryNumber=44; /* United Kingdom */ - break; - case 6721: /* Australian Antarctic Territory */ - countryNumber=61; /* Australia */ - break; - case 5399: /* Guantanamo Bay */ - countryNumber=1; /* USA */ - } - /* binary search in index array */ - { int low=0,i,high; - high=SIZEOF(BitmapIndexMap)-1; - if(countryNumber<=BitmapIndexMap[high]) - while(low<=high) { - i=low+((high-low)/2); - /* never happens */ - if(i<0 || i>=SIZEOF(BitmapIndexMap)) DebugBreak(); - if(BitmapIndexMap[i]==countryNumber) return i; - if(countryNumber>BitmapIndexMap[i]) low=i+1; - else high=i-1; - } - } - /* Other,Unknown,Unspecified */ - return 0; -} - -// return value needs to be released using DestroyIcon() -// only operates on color icons, which isn't a problem here -static HICON FASTCALL ResizeIconCentered(HICON hIcon,int cx,int cy) -{ - HICON hResIcon=NULL; - ICONINFO icoi; - BITMAP bm; - register HDC hdc; - HBITMAP hbmPrev,hbm; - POINT pt; - hdc=CreateCompatibleDC(NULL); - if(hdc!=NULL) { - if(GetIconInfo(hIcon,&icoi)) { - if(GetObject(icoi.hbmColor,sizeof(bm),&bm) && bm.bmWidth<=cx && bm.bmHeight<=cy) { - pt.x=(cx-bm.bmWidth)/2; - pt.y=(cy-bm.bmHeight)/2; - hbmPrev = (HBITMAP)SelectObject(hdc, icoi.hbmColor); - if(hbmPrev!=NULL) { /* error on select? */ - hbm=icoi.hbmColor; - icoi.hbmColor=CreateCompatibleBitmap(hdc,cx,cy); - if(icoi.hbmColor!=NULL) - if(SelectObject(hdc,icoi.hbmColor)!=NULL) { /* error on select? */ - DeleteObject(hbm); /* delete prev color (XOR) */ - if(BitBlt(hdc,0,0,cx,cy,NULL,0,0,BLACKNESS)) /* transparency: AND=0, XOR=1 */ - if(DrawIconEx(hdc,pt.x,pt.y,hIcon,bm.bmWidth,bm.bmHeight,0,NULL,DI_IMAGE|DI_NOMIRROR)) { - if(SelectObject(hdc,icoi.hbmMask)!=NULL) { /* error on select? */ - hbm=icoi.hbmMask; - icoi.hbmMask=CreateBitmap(cx,cy,1,1,NULL); /* mono */ - if(icoi.hbmMask!=NULL) - if(SelectObject(hdc,icoi.hbmMask)!=NULL) { /* error on select? */ - DeleteObject(hbm); /* delete prev mask (AND) */ - if(BitBlt(hdc,0,0,cx,cy,NULL,0,0,WHITENESS)) /* transparency: AND=0, XOR=1 */ - if(DrawIconEx(hdc,pt.x,pt.y,hIcon,0,0,0,NULL,DI_MASK|DI_NOMIRROR)) { - SelectObject(hdc,hbmPrev); - hResIcon=CreateIconIndirect(&icoi); /* bitmaps must not be selected */ - } - } - } - } - } - SelectObject(hdc,hbmPrev); - } - } - DeleteObject(icoi.hbmColor); - DeleteObject(icoi.hbmMask); - } - DeleteDC(hdc); - } - return hResIcon; -} - -/************************* Utils **********************************/ - -HICON FASTCALL LoadFlagIcon(int countryNumber) -{ - char szId[20],*szCountry; - /* create identifier */ - szCountry=(char*)CallService(MS_UTILS_GETCOUNTRYBYNUMBER,countryNumber,0); - if(szCountry==NULL) szCountry=(char*)CallService(MS_UTILS_GETCOUNTRYBYNUMBER,countryNumber=0xFFFF,0); - wsprintfA(szId,(countryNumber==0xFFFF)?"%s0x%X":"%s%i","flags_",countryNumber); /* buffer safe */ - return (HICON)CallService(MS_SKIN2_GETICON,0,(LPARAM)szId); -} - -int FASTCALL CountryNumberToIndex(int countryNumber) -{ - int i,nf=0; - for(i=0;i=dwFrom) /* only search if wParam valid */ - while(low<=high) { - i=low+((high-low)/2); - /* never happens */ - if(i<0) DebugBreak(); - /* analyze record */ - id=GetDataRecord(data,i,&dwFrom,&dwTo); - if(dwFrom<=wParam && dwTo>=wParam) { LeaveRecordCache(); return id; } - if(wParam>dwTo) low=i+1; - else high=i-1; - } - LeaveRecordCache(); - } - return 0xFFFF; /* Unknown */ -} - -/************************* Bin Converter **************************/ - -#ifdef BINCONV -#include -#include - -struct { - const char *szMir; - const char *szCSV; -} static const differentCountryNames[]={ - {"British Virgin Islands","VIRGIN ISLANDS, BRITISH"}, - {"Brunei","BRUNEI DARUSSALAM"}, - {"Cape Verde Islands","CAPE VERDE"}, - {"Cocos-Keeling Islands","COCOS (KEELING) ISLANDS"}, - {"Chile, Republic of","CHILE"}, - {"Congo, Democratic Republic of (Zaire)","THE DEMOCRATIC REPUBLIC OF THE CONGO"}, - {"Congo, Republic of the","CONGO"}, - {"Cote d'Ivoire (Ivory Coast)","COTE D'IVOIRE"}, - {"Diego Garcia","BRITISH INDIAN OCEAN TERRITORY"}, - {"Guam, US Territory of","GUAM"}, - {"Iran (Islamic Republic of)","ISLAMIC REPUBLIC OF IRAN"}, - {"Korea, North","REPUBLIC OF KOREA"}, - {"Laos","LAO PEOPLE'S DEMOCRATIC REPUBLIC"}, - {"Reunion Island","REUNION"}, - {"Russia","RUSSIAN FEDERATION"}, - {"Saipan Island (Northern Mariana Islands)","NORTHERN MARIANA ISLANDS"}, - {"Tanzania","UNITED REPUBLIC OF TANZANIA"}, - {"USA","UNITED STATES"}, - {"Macau","MACAO"}, - {"Macedonia (F.Y.R.O.M.)","THE FORMER YUGOSLAV REPUBLIC OF MACEDONIA"}, - {"Micronesia, Federated States of","FEDERATED STATES OF MICRONESIA"}, - {"Mayotte Island","MAYOTTE"}, - {"Moldova, Republic of","REPUBLIC OF MOLDOVA"}, - {"Vietnam","VIET NAM"}, - {"Virgin Islands (USA)","VIRGIN ISLANDS, U.S."}, - {"Vatican City","HOLY SEE (VATICAN CITY STATE)"}, - {"Serbia, Republic of","SERBIA"}, - {"Montenegro, Republic of","MONTENEGRO"}, -}; - -#define ALLOC_STEP (800*1024) /* approx. size of data output */ - -struct ResizableByteBuffer { - BYTE *buf; - DWORD cbLength,cbAlloced; -}; - -static void AppendToByteBuffer(struct ResizableByteBuffer *buffer,const void *append,DWORD cbAppendSize) -{ - if(buffer->cbAlloced<=buffer->cbLength+cbAppendSize) { - BYTE* buf=(BYTE*)mir_realloc(buffer->buf,buffer->cbAlloced+ALLOC_STEP+cbAppendSize); - if(buf==NULL) return; - buffer->buf=buf; - buffer->cbAlloced+=ALLOC_STEP+cbAppendSize; - OutputDebugStringA("reallocating memory...\n"); /* all ascii */ - } - CopyMemory(&buffer->buf[buffer->cbLength],append,cbAppendSize); - buffer->cbLength+=cbAppendSize; -} - -static int EnumIpDataLines(const char *pszFileCSV,const char *pszFileOut) -{ - FILE *fp; - char line[1024],out[512],*pszFrom,*pszTo,*pszTwo,*pszCountry,*buf; - int i,j; - DWORD dwOut; - WORD wOut; - struct ResizableByteBuffer buffer; - - ZeroMemory(&buffer,sizeof(buffer)); - fp=fopen(pszFileCSV,"rt"); - if(fp!=NULL) { - OutputDebugStringA("Running IP data convert...\n"); /* all ascii */ - while(!feof(fp)) { - if(fgets(line,sizeof(line),fp)==NULL) break; - /* get line data */ - pszFrom=line+1; - pszTo=strchr(pszFrom,','); - *(pszTo-1)='\0'; pszTo+=2; - pszTwo=strchr(pszTo,','); - *(pszTwo-1)='\0'; pszTwo+=2; - pszCountry=strchr(pszTwo,',')+1; - pszCountry=strchr(pszCountry,',')+2; - buf=strchr(pszCountry,'"'); - *buf=pszTwo[2]='\0'; - /* corrections */ - if (!lstrcmpi(pszCountry,"ANTARCTICA")) continue; - if (!lstrcmpi(pszCountry,"TIMOR-LESTE")) continue; - if (!lstrcmpi(pszCountry,"PALESTINIAN TERRITORY, OCCUPIED")) - lstrcpy(pszCountry,"ISRAEL"); - else if (!lstrcmpi(pszCountry,"UNITED STATES MINOR OUTLYING ISLANDS")) - lstrcpy(pszCountry,"UNITED STATES"); - else if (!lstrcmpi(pszCountry,"SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS")) - lstrcpy(pszCountry,"UNITED KINGDOM"); - else if (!lstrcmpi(pszTwo,"JE")) /* map error */ - lstrcpy(pszCountry,"UNITED KINGDOM"); - else if (!lstrcmpi(pszTwo,"AX")) /* Åland Island belongs to Finland */ - lstrcpy(pszCountry,"FINLAND"); - else if (!lstrcmpi(pszTwo,"ME")) - lstrcpy(pszCountry,"MONTENEGRO"); - else if (!lstrcmpi(pszTwo,"RS") || !lstrcmpi(pszTwo,"CS")) - lstrcpy(pszCountry,"SERBIA"); - /* convert */ - for(i=0;i + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Englisch (GB) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE MOVEABLE PURE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE MOVEABLE PURE +BEGIN + "#include \r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_FLAGS BITMAP "flags.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// BIN +// + +IDR_IPTOCOUNTRY BIN "ip-to-country.bin" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPT_EXTRAIMG DIALOGEX 0, 0, 223, 93 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "Country Flags",-1,3,0,220,93 + CONTROL "Show country flag as &status icon on message window", + IDC_CHECK_SHOWSTATUSICONFLAG,"Button",BS_AUTOCHECKBOX | + WS_GROUP | WS_TABSTOP,12,14,206,10 + CONTROL "Show country flag as &extra image on contact list", + IDC_CHECK_SHOWEXTRAIMGFLAG,"Button",BS_AUTOCHECKBOX | + WS_GROUP | WS_TABSTOP,12,27,206,10 + LTEXT "In following contact list &column:", + IDC_TEXT_EXTRAIMGFLAGCOLUMN,24,42,110,8 + COMBOBOX IDC_COMBO_EXTRAIMGFLAGCOLUMN,135,40,77,117, + CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "Use &unknown flag if the country can not be determined", + IDC_CHECK_USEUNKNOWNFLAG,"Button",BS_AUTOCHECKBOX | + WS_GROUP | WS_TABSTOP,12,77,206,10 + CONTROL "Use &IP-to-country database for country detection", + IDC_CHECK_USEIPTOCOUNTRY,"Button",BS_AUTOCHECKBOX | + WS_GROUP | WS_TABSTOP,12,64,206,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_OPT_EXTRAIMG, DIALOG + BEGIN + VERTGUIDE, 3 + VERTGUIDE, 12 + VERTGUIDE, 24 + VERTGUIDE, 218 + HORZGUIDE, 42 + HORZGUIDE, 52 + END +END +#endif // APSTUDIO_INVOKED + +#endif // Englisch (GB) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/CountryFlags/res/version.rc b/plugins/CountryFlags/res/version.rc new file mode 100644 index 0000000000..73ff5ab9ea --- /dev/null +++ b/plugins/CountryFlags/res/version.rc @@ -0,0 +1,43 @@ +#ifdef APSTUDIO_INVOKED +#error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + +#include <..\src\version.h> + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION FILE_VERSION + PRODUCTVERSION FILE_VERSION + FILEFLAGSMASK 0x0L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", "Licensed under the terms of the GNU General Public License" + VALUE "FileDescription", "Country Flags Plugin for Miranda IM" + VALUE "FileVersion", FILE_VERSION_STR + VALUE "InternalName", "CountryUtils" + VALUE "LegalCopyright", "Copyright © 2006-2007 H. Herkenrath" + VALUE "OriginalFilename", "flags.dll" + VALUE "ProductName", "Country Flags" + VALUE "ProductVersion", FILE_VERSION_STR + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END diff --git a/plugins/CountryFlags/resource.h b/plugins/CountryFlags/resource.h deleted file mode 100644 index a2cd0496d8..0000000000 --- a/plugins/CountryFlags/resource.h +++ /dev/null @@ -1,25 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by resource.rc -// -#define IDB_FLAGS 101 -#define IDR_IPTOCOUNTRY 102 -#define IDD_OPT_EXTRAIMG 103 -#define IDC_CHECK_SHOWSTATUSICONFLAG 1001 -#define IDC_CHECK_SHOWEXTRAIMGFLAG 1002 -#define IDC_TEXT_EXTRAIMGFLAGCOLUMN 1003 -#define IDC_COMBO_EXTRAIMGFLAGCOLUMN 1004 -#define IDC_CHECK_USEUNKNOWNFLAG 1005 -#define IDC_CHECK_USEIPTOCOUNTRY 1006 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 104 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1007 -#define _APS_NEXT_SYMED_VALUE 2001 -#endif -#endif diff --git a/plugins/CountryFlags/resource.rc b/plugins/CountryFlags/resource.rc deleted file mode 100644 index eba35cb8e3..0000000000 --- a/plugins/CountryFlags/resource.rc +++ /dev/null @@ -1,128 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Englisch (GB) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE MOVEABLE PURE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE MOVEABLE PURE -BEGIN - "#include \r\n" - "\0" -END - -3 TEXTINCLUDE MOVEABLE PURE -BEGIN - "#include ""version.rc""\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_FLAGS BITMAP DISCARDABLE "res/flags.bmp" - -///////////////////////////////////////////////////////////////////////////// -// -// BIN -// - -IDR_IPTOCOUNTRY BIN DISCARDABLE "res/ip-to-country.bin" - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_OPT_EXTRAIMG DIALOGEX 0, 0, 223, 93 -STYLE DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg" -BEGIN - GROUPBOX "Country Flags",-1,3,0,220,93 - CONTROL "Show country flag as &status icon on message window", - IDC_CHECK_SHOWSTATUSICONFLAG,"Button",BS_AUTOCHECKBOX | - WS_GROUP | WS_TABSTOP,12,14,206,10 - CONTROL "Show country flag as &extra image on contact list", - IDC_CHECK_SHOWEXTRAIMGFLAG,"Button",BS_AUTOCHECKBOX | - WS_GROUP | WS_TABSTOP,12,27,206,10 - LTEXT "In following contact list &column:", - IDC_TEXT_EXTRAIMGFLAGCOLUMN,24,42,110,8 - COMBOBOX IDC_COMBO_EXTRAIMGFLAGCOLUMN,135,40,77,117, - CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - CONTROL "Use &unknown flag if the country can not be determined", - IDC_CHECK_USEUNKNOWNFLAG,"Button",BS_AUTOCHECKBOX | - WS_GROUP | WS_TABSTOP,12,77,206,10 - CONTROL "Use &IP-to-country database for country detection", - IDC_CHECK_USEIPTOCOUNTRY,"Button",BS_AUTOCHECKBOX | - WS_GROUP | WS_TABSTOP,12,64,206,10 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - IDD_OPT_EXTRAIMG, DIALOG - BEGIN - VERTGUIDE, 3 - VERTGUIDE, 12 - VERTGUIDE, 24 - VERTGUIDE, 218 - HORZGUIDE, 42 - HORZGUIDE, 52 - END -END -#endif // APSTUDIO_INVOKED - -#endif // Englisch (GB) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// -#include "version.rc" - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/plugins/CountryFlags/src/countrylistext.cpp b/plugins/CountryFlags/src/countrylistext.cpp new file mode 100644 index 0000000000..95f692b30b --- /dev/null +++ b/plugins/CountryFlags/src/countrylistext.cpp @@ -0,0 +1,345 @@ +/* +Miranda IM Country Flags Plugin +Copyright (C) 2006-2007 H. Herkenrath + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (Flags-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "flags.h" + +static HANDLE hServiceGetList,hServiceGetByNumber; + +/************************* Services *******************************/ + +static struct CountryListEntry countries[]={ + {0 ,"Unspecified"}, + {9999,"Other"}, + {0xFFFF,"Unknown"}, + {93 ,"Afghanistan"}, + {355 ,"Albania"}, + {213 ,"Algeria"}, + {684 ,"American Samoa"}, + {376 ,"Andorra"}, + {244 ,"Angola"}, + {101 ,"Anguilla"}, + {102 ,"Antigua and Barbuda"}, + //{5902,"Antilles"}, /* removed */ + {54 ,"Argentina"}, + {374 ,"Armenia"}, + {297 ,"Aruba"}, + {247 ,"Ascension Island"}, + {61 ,"Australia"}, + {6721,"Australian Antarctic Territory"}, /* was missing */ + {43 ,"Austria"}, + {994 ,"Azerbaijan"}, + {103 ,"Bahamas"}, + {973 ,"Bahrain"}, + {880 ,"Bangladesh"}, + {104 ,"Barbados"}, + {120 ,"Barbuda"}, + {375 ,"Belarus"}, + {32 ,"Belgium"}, + {501 ,"Belize"}, + {229 ,"Benin"}, + {105 ,"Bermuda"}, + {975 ,"Bhutan"}, + {591 ,"Bolivia"}, + {387 ,"Bosnia and Herzegovina"}, + {267 ,"Botswana"}, + {55 ,"Brazil"}, + {106 ,"British Virgin Islands"}, + {673 ,"Brunei"}, + {359 ,"Bulgaria"}, + {226 ,"Burkina Faso"}, + {257 ,"Burundi"}, + {855 ,"Cambodia"}, + {237 ,"Cameroon"}, + {107 ,"Canada"}, + {178 ,"Canary Islands"}, + {238 ,"Cape Verde Islands"}, + {108 ,"Cayman Islands"}, + {236 ,"Central African Republic"}, + {235 ,"Chad"}, + {56 ,"Chile, Republic of"}, + {86 ,"China"}, + {672 ,"Christmas Island"}, + {6101,"Cocos-Keeling Islands"}, + //{6102,"Cocos (Keeling) Islands"}, /* removed */ + {57 ,"Colombia"}, + {2691,"Comoros"}, + {243 ,"Congo, Democratic Republic of (Zaire)"}, + {242 ,"Congo, Republic of the"}, + {682 ,"Cook Islands"}, + {506 ,"Costa Rica"}, + {225 ,"Cote d'Ivoire (Ivory Coast)"}, + {385 ,"Croatia"}, + {53 ,"Cuba"}, + {357 ,"Cyprus"}, + {420 ,"Czech Republic"}, + {45 ,"Denmark"}, + {246 ,"Diego Garcia"}, + {253 ,"Djibouti"}, + {109 ,"Dominica"}, + {110 ,"Dominican Republic"}, + {593 ,"Ecuador"}, + {20 ,"Egypt"}, + {503 ,"El Salvador"}, + {240 ,"Equatorial Guinea"}, + {291 ,"Eritrea"}, + {372 ,"Estonia"}, + {251 ,"Ethiopia"}, + {500 ,"Falkland Islands (Malvinas)"}, /* was "Falkland Islands" */ + {298 ,"Faroe Islands"}, /* was "Faeroe Islands" */ + {679 ,"Fiji"}, + {358 ,"Finland"}, + {33 ,"France"}, + {5901,"French Antilles"}, + {594 ,"French Guiana"}, + {689 ,"French Polynesia"}, + {241 ,"Gabon"}, + {220 ,"Gambia"}, + {995 ,"Georgia"}, + {49 ,"Germany"}, + {233 ,"Ghana"}, + {350 ,"Gibraltar"}, + {30 ,"Greece"}, + {299 ,"Greenland"}, + {111 ,"Grenada"}, + {590 ,"Guadeloupe"}, + {671 ,"Guam, US Territory of"}, + {5399,"Guantanamo Bay"}, /* was missing */ + {502 ,"Guatemala"}, + {224 ,"Guinea"}, + {245 ,"Guinea-Bissau"}, + {592 ,"Guyana"}, + {509 ,"Haiti"}, + {504 ,"Honduras"}, + {852 ,"Hong Kong"}, + {36 ,"Hungary"}, + {354 ,"Iceland"}, + {91 ,"India"}, + {62 ,"Indonesia"}, + {98 ,"Iran (Islamic Republic of)"}, + {964 ,"Iraq"}, + {353 ,"Ireland"}, + {972 ,"Israel"}, + {39 ,"Italy"}, + {112 ,"Jamaica"}, + {81 ,"Japan"}, + {962 ,"Jordan"}, + {705 ,"Kazakhstan"}, + {254 ,"Kenya"}, + {686 ,"Kiribati"}, + {850 ,"Korea, North"}, + {82 ,"Korea, South"}, + {965 ,"Kuwait"}, + {706 ,"Kyrgyzstan"}, + {856 ,"Laos"}, + {371 ,"Latvia"}, + {961 ,"Lebanon"}, + {266 ,"Lesotho"}, + {231 ,"Liberia"}, + {218 ,"Libyan Arab Jamahiriya"}, + {4101,"Liechtenstein"}, + {370 ,"Lithuania"}, + {352 ,"Luxembourg"}, + {853 ,"Macau"}, + {389 ,"Macedonia (F.Y.R.O.M.)"}, + {261 ,"Madagascar"}, + {265 ,"Malawi"}, + {60 ,"Malaysia"}, + {960 ,"Maldives"}, + {223 ,"Mali"}, + {356 ,"Malta"}, + {692 ,"Marshall Islands"}, + {596 ,"Martinique"}, + {222 ,"Mauritania"}, + {230 ,"Mauritius"}, + {269 ,"Mayotte Island"}, + {52 ,"Mexico"}, + {691 ,"Micronesia, Federated States of"}, + {373 ,"Moldova, Republic of"}, + {377 ,"Monaco"}, + {976 ,"Mongolia"}, + {382 ,"Montenegro, Republic of"}, /* was "Yugoslavia - Montenegro" */ + {113 ,"Montserrat"}, + {212 ,"Morocco"}, + {258 ,"Mozambique"}, + {95 ,"Myanmar"}, + {264 ,"Namibia"}, + {674 ,"Nauru"}, + {977 ,"Nepal"}, + {31 ,"Netherlands"}, + {599 ,"Netherlands Antilles"}, + {114 ,"Nevis"}, + {687 ,"New Caledonia"}, + {64 ,"New Zealand"}, + {505 ,"Nicaragua"}, + {227 ,"Niger"}, + {234 ,"Nigeria"}, + {683 ,"Niue"}, + {6722,"Norfolk Island"}, + {47 ,"Norway"}, + {968 ,"Oman"}, + {92 ,"Pakistan"}, + {680 ,"Palau"}, + {507 ,"Panama"}, + {675 ,"Papua New Guinea"}, + {595 ,"Paraguay"}, + {51 ,"Peru"}, + {63 ,"Philippines"}, + {48 ,"Poland"}, + {351 ,"Portugal"}, + {121 ,"Puerto Rico"}, + {974 ,"Qatar"}, + {262 ,"Reunion Island"}, + {40 ,"Romania"}, + {6701,"Rota Island"}, + {7 ,"Russia"}, + {250 ,"Rwanda"}, + {290 ,"Saint Helena"}, + {115 ,"Saint Kitts"}, + {1141,"Saint Kitts and Nevis"}, + {122 ,"Saint Lucia"}, + {508 ,"Saint Pierre and Miquelon"}, + {116 ,"Saint Vincent and the Grenadines"}, + {670 ,"Saipan Island (Northern Mariana Islands)"}, /* was "Saipan Island" */ + {685 ,"Samoa"}, /* was "Western Samoa" */ + {378 ,"San Marino"}, + {239 ,"Sao Tome and Principe"}, + {966 ,"Saudi Arabia"}, + {442 ,"Scotland"}, + {221 ,"Senegal"}, + {381 ,"Serbia, Republic of"}, /* was "Yugoslavia" */ + {248 ,"Seychelles"}, + {232 ,"Sierra Leone"}, + {65 ,"Singapore"}, + {421 ,"Slovakia"}, + {386 ,"Slovenia"}, + {677 ,"Solomon Islands"}, + {252 ,"Somalia"}, + {27 ,"South Africa"}, + {34 ,"Spain"}, + {94 ,"Sri Lanka"}, + {249 ,"Sudan"}, + {597 ,"Suriname"}, + {268 ,"Swaziland"}, + {46 ,"Sweden"}, + {41 ,"Switzerland"}, + {963 ,"Syrian Arab Republic"}, + {886 ,"Taiwan"}, + {708 ,"Tajikistan"}, + {255 ,"Tanzania"}, + {66 ,"Thailand"}, + {6702,"Tinian Island"}, + {228 ,"Togo"}, + {690 ,"Tokelau"}, + {676 ,"Tonga"}, + {117 ,"Trinidad and Tobago"}, + {216 ,"Tunisia"}, + {90 ,"Turkey"}, + {709 ,"Turkmenistan"}, + {118 ,"Turks and Caicos Islands"}, + {688 ,"Tuvalu"}, + {256 ,"Uganda"}, + {380 ,"Ukraine"}, + {971 ,"United Arab Emirates"}, + {44 ,"United Kingdom"}, + {598 ,"Uruguay"}, + {1 ,"USA"}, + {711 ,"Uzbekistan"}, + {678 ,"Vanuatu"}, + {379 ,"Vatican City"}, + {58 ,"Venezuela"}, + {84 ,"Vietnam"}, + {123 ,"Virgin Islands (USA)"}, + {441 ,"Wales"}, + {681 ,"Wallis and Futuna Islands"}, + {967 ,"Yemen"}, + //{3811,"Yugoslavia - Serbia"}, /* removed */ + {260 ,"Zambia"}, + {263 ,"Zimbabwe"}, +}; + +static INT_PTR ServiceGetCountryByNumber(WPARAM wParam,LPARAM lParam) +{ + int i; + UNREFERENCED_PARAMETER(lParam); + for(i=0; i24) hash^=(szStr[i]>>(32-shift))&0x7F; + shift=(shift+5)&0x1F; + } + return hash; +#endif +} + +void InitCountryListExt(void) +{ + /* hack to replace built-in country list */ + DestroyServiceFunction((HANDLE)NameHashFunction(MS_UTILS_GETCOUNTRYLIST)); + DestroyServiceFunction((HANDLE)NameHashFunction(MS_UTILS_GETCOUNTRYBYNUMBER)); + hServiceGetList=CreateServiceFunction(MS_UTILS_GETCOUNTRYLIST,ServiceGetCountryList); + hServiceGetByNumber=CreateServiceFunction(MS_UTILS_GETCOUNTRYBYNUMBER,ServiceGetCountryByNumber); +} + +void UninitCountryListExt(void) +{ + DestroyServiceFunction(hServiceGetList); + DestroyServiceFunction(hServiceGetByNumber); +} diff --git a/plugins/CountryFlags/src/extraimg.cpp b/plugins/CountryFlags/src/extraimg.cpp new file mode 100644 index 0000000000..f019827e21 --- /dev/null +++ b/plugins/CountryFlags/src/extraimg.cpp @@ -0,0 +1,494 @@ +/* +Miranda IM Country Flags Plugin +Copyright (C) 2006-1007 H. Herkenrath + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (Flags-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "flags.h" + +/* Services */ +static HANDLE hServiceDetectContactOrigin; +/* Extra Image */ +static HANDLE hHookExtraRebuild,hHookExtraApply; +/* Status Icon */ +static HANDLE hHookMsgWndEvent,hHookIconsChanged; +/* Options */ +static HANDLE hHookOptInit,hHookSettingChanged; +/* Misc */ +extern HINSTANCE hInst; +extern int nCountriesCount; +extern struct CountryListEntry *countries; +static HANDLE hHookModulesLoaded; + +/************************* Services *******************************/ + +static INT_PTR ServiceDetectContactOriginCountry(WPARAM wParam,LPARAM lParam) +{ + int countryNumber=0xFFFF; + char *pszProto; + UNREFERENCED_PARAMETER(lParam); + pszProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,wParam,0); + /* ip detect */ + if(DBGetContactSettingByte(NULL,"Flags","UseIpToCountry",SETTING_USEIPTOCOUNTRY_DEFAULT)) + countryNumber=ServiceIpToCountry(DBGetContactSettingDword((HANDLE)wParam,pszProto,"RealIP",0),0); + /* fallback */ + if(countryNumber==0xFFFF) + countryNumber=DBGetContactSettingWord((HANDLE)wParam,pszProto,"Country",0); + if(countryNumber==0 || countryNumber==0xFFFF) + countryNumber=DBGetContactSettingWord((HANDLE)wParam,pszProto,"CompanyCountry",0); + return (countryNumber==0)?0xFFFF:countryNumber; +} + +/************************* Extra Image ****************************/ + +#define EXTRAIMAGE_REFRESHDELAY 100 /* time for which setting changes are buffered */ + +static HANDLE *phExtraImages; +static BYTE idExtraColumn; + +static void CALLBACK SetExtraImage(LPARAM lParam) +{ + IconExtraColumn iec; + int countryNumber,index; + if(DBGetContactSettingByte(NULL,"Flags","ShowExtraImgFlag",SETTING_SHOWEXTRAIMGFLAG_DEFAULT)) { + /* get contact's country */ + iec.hImage=INVALID_HANDLE_VALUE; + countryNumber=ServiceDetectContactOriginCountry((WPARAM)lParam,0); + /* get icon */ + if(phExtraImages!=NULL) /* too early? */ + if(countryNumber!=0xFFFF || DBGetContactSettingByte(NULL,"Flags","UseUnknownFlag",SETTING_USEUNKNOWNFLAG_DEFAULT)) { + index=CountryNumberToIndex(countryNumber); + /* icon not yet loaded? */ + if(phExtraImages[index]==INVALID_HANDLE_VALUE) { + HICON hIcon; + hIcon=LoadFlagIcon(countryNumber); + if(hIcon!=NULL) phExtraImages[index]=(HANDLE)CallService(MS_CLIST_EXTRA_ADD_ICON,(WPARAM)hIcon,0); + CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon,0); /* does NULL check */ + } + iec.hImage=phExtraImages[index]; + } + /* choose column */ + iec.cbSize=sizeof(iec); + iec.ColumnType=idExtraColumn; + CallService(MS_CLIST_EXTRA_SET_ICON,(WPARAM)lParam,(LPARAM)&iec); + } +} + +// always call in context of main thread +static void RemoveExtraImages(void) +{ + IconExtraColumn iec; + register HANDLE hContact; + /* choose column */ + iec.cbSize=sizeof(iec); + iec.ColumnType=idExtraColumn; + iec.hImage=INVALID_HANDLE_VALUE; + /* enum all contacts */ + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + while(hContact!=NULL) { + /* invalidate icon */ + CallService(MS_CLIST_EXTRA_SET_ICON,(WPARAM)hContact,(LPARAM)&iec); + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0); + } +} + +// always call in context of main thread +static void EnsureExtraImages(void) +{ + register HANDLE hContact; + BYTE idMaxExtraCol,idExtraColumnNew; + /* choose column */ + idMaxExtraCol=(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_EXTRACOLUMNCOUNT); /* 1-based count */ + if(idMaxExtraCol==(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_USEREXTRASTART)) /* same flags if not present */ + idMaxExtraCol=EXTRA_ICON_ADV2; /* zero if not present */ + idExtraColumnNew=DBGetContactSettingRangedByte(NULL,"Flags","ExtraImgFlagColumn",SETTING_EXTRAIMGFLAGCOLUMN_DEFAULT,1,idMaxExtraCol); + /* clear previous column */ + if(idExtraColumnNew!=idExtraColumn) RemoveExtraImages(); + idExtraColumn=idExtraColumnNew; + /* enum all contacts */ + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + while(hContact!=NULL) { + CallFunctionBuffered(SetExtraImage,(LPARAM)hContact,TRUE,EXTRAIMAGE_REFRESHDELAY); + hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0); + } +} + +static void CALLBACK UpdateExtraImages(LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + if(DBGetContactSettingByte(NULL,"Flags","ShowExtraImgFlag",SETTING_SHOWEXTRAIMGFLAG_DEFAULT)) + EnsureExtraImages(); + else RemoveExtraImages(); +} + +static int ExtraListRebuild(WPARAM wParam,LPARAM lParam) +{ + BYTE idMaxExtraCol; + int i; + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + OutputDebugStringA("REBUILD EXTRA\n"); + /* invalidate icons */ + if(phExtraImages!=NULL) + for(i=0;iuType) { + case MSG_WINDOW_EVT_OPENING: + case MSG_WINDOW_EVT_CLOSE: + { int countryNumber; + if(msgwe->hContact==NULL || !ServiceExists(MS_MSG_ADDICON)) break; /* sanity check */ + countryNumber=ServiceDetectContactOriginCountry((WPARAM)msgwe->hContact,0); + if(DBGetContactSettingByte(NULL,"Flags","ShowStatusIconFlag",SETTING_SHOWSTATUSICONFLAG_DEFAULT)) { + if(msgwe->uType==MSG_WINDOW_EVT_OPENING) SetStatusIcon(msgwe->hContact,countryNumber); + else UnsetStatusIcon(msgwe->hContact,countryNumber); + } + /* ensure it is hidden, RemoveStatusIcons() only enums currently opened ones */ + else UnsetStatusIcon(msgwe->hContact,countryNumber); + } + } + return 0; +} + +static void CALLBACK UpdateStatusIcons(LPARAM lParam) +{ + MessageWindowInputData msgwi; /* input */ + MessageWindowData msgw; /* output */ + BOOL fShow; + int countryNumber; + UNREFERENCED_PARAMETER(lParam); + + msgwi.cbSize=sizeof(msgwi); + msgw.cbSize=sizeof(msgw); + msgwi.uFlags=MSG_WINDOW_UFLAG_MSG_BOTH; + /* enum all opened message windows */ + fShow=DBGetContactSettingByte(NULL,"Flags","ShowStatusIconFlag",SETTING_SHOWSTATUSICONFLAG_DEFAULT); + msgwi.hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0); + while(msgwi.hContact!=NULL) { + /* is a message window opened for this contact? */ + if (!CallService(MS_MSG_GETWINDOWDATA,(WPARAM)&msgwi,(LPARAM)&msgw) && msgw.uState&MSG_WINDOW_STATE_EXISTS) { + countryNumber=ServiceDetectContactOriginCountry((WPARAM)msgwi.hContact,0); + if(fShow) SetStatusIcon(msgwi.hContact,countryNumber); + else UnsetStatusIcon(msgwi.hContact,countryNumber); + } + msgwi.hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)msgw.hContact,0); + } +} + +static int StatusIconsChanged(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + if(ServiceExists(MS_MSG_ADDICON)) + if(DBGetContactSettingByte(NULL,"Flags","ShowStatusIconFlag",SETTING_SHOWSTATUSICONFLAG_DEFAULT)) + CallFunctionBuffered(UpdateStatusIcons,0,FALSE,STATUSICON_REFRESHDELAY); + return 0; +} + +/************************* Options ************************************/ + +#define M_ENABLE_SUBCTLS (WM_APP+1) + +static INT_PTR CALLBACK ExtraImgOptDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + switch(msg) { + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + /* init checkboxes */ + { BOOL val; + /* Status Icon */ + if(ServiceExists(MS_MSG_ADDICON)) val=DBGetContactSettingByte(NULL,"Flags","ShowStatusIconFlag",SETTING_SHOWSTATUSICONFLAG_DEFAULT)!=0; + else EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG),val=FALSE); + CheckDlgButton(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG,val); + /* Extra Image */ + if(ServiceExists(MS_CLIST_EXTRA_ADD_ICON)) val=DBGetContactSettingByte(NULL,"Flags","ShowExtraImgFlag",SETTING_SHOWEXTRAIMGFLAG_DEFAULT)!=0; + else EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG),val=FALSE); + CheckDlgButton(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG,val); + /* Unknown Flag */ + val=DBGetContactSettingByte(NULL,"Flags","UseUnknownFlag",SETTING_USEUNKNOWNFLAG_DEFAULT)!=0; + CheckDlgButton(hwndDlg,IDC_CHECK_USEUNKNOWNFLAG,val); + /* IP-to-country */ + val=DBGetContactSettingByte(NULL,"Flags","UseIpToCountry",SETTING_USEIPTOCOUNTRY_DEFAULT)!=0; + CheckDlgButton(hwndDlg,IDC_CHECK_USEIPTOCOUNTRY,val); + } + /* init combobox */ + { HWND hwndCombo; + TCHAR szItem[64]; + BYTE idColumn,idSavedColumn; + BYTE idMaxExtraCol,idAdvExtraColStart; + int index; + hwndCombo=GetDlgItem(hwndDlg,IDC_COMBO_EXTRAIMGFLAGCOLUMN); + idSavedColumn=DBGetContactSettingByte(NULL,"Flags","ExtraImgFlagColumn",SETTING_EXTRAIMGFLAGCOLUMN_DEFAULT); + idMaxExtraCol=(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_EXTRACOLUMNCOUNT); /* 1-based count */ + idAdvExtraColStart=(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_USEREXTRASTART); /* 1-based id */ + /* init */ + SendMessage(hwndCombo,CB_SETLOCALE,(LCID)CallService(MS_LANGPACK_GETLOCALE,0,0),0); /* for sort order */ + SendMessage(hwndCombo,CB_INITSTORAGE,idMaxExtraCol-idAdvExtraColStart+3,(idMaxExtraCol-idAdvExtraColStart+3)*SIZEOF(szItem)); + /* Advanced #1,#2 */ + { const BYTE columnIds[]={EXTRA_ICON_ADV1,EXTRA_ICON_ADV2}; + for(idColumn=0;idColumncode) { + case PSN_APPLY: /* setting change hook will pick these up */ + DBWriteContactSettingByte(NULL,"Flags","UseUnknownFlag",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_USEUNKNOWNFLAG)!=0)); + DBWriteContactSettingByte(NULL,"Flags","UseIpToCountry",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_USEIPTOCOUNTRY)!=0)); + /* Status Icon */ + if(IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG))) + DBWriteContactSettingByte(NULL,"Flags","ShowStatusIconFlag",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG)!=0)); + /* Extra Image */ + if(IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG))) + DBWriteContactSettingByte(NULL,"Flags","ShowExtraImgFlag",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG)!=0)); + { int index; + index=SendDlgItemMessage(hwndDlg,IDC_COMBO_EXTRAIMGFLAGCOLUMN,CB_GETCURSEL,0,0); + if(index!=LB_ERR) DBWriteContactSettingByte(NULL,"Flags","ExtraImgFlagColumn",(BYTE)SendDlgItemMessage(hwndDlg,IDC_COMBO_EXTRAIMGFLAGCOLUMN,CB_GETITEMDATA,index,0)); + } + return TRUE; + } + break; + } + return FALSE; +} + +static UINT expertOnlyControls[]={IDC_CHECK_USEIPTOCOUNTRY}; +static int ExtraImgOptInit(WPARAM wParam,LPARAM lParam) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + UNREFERENCED_PARAMETER(lParam); + odp.cbSize = sizeof(odp); + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_EXTRAIMG); + odp.position = 900000002; + odp.pszGroup = LPGEN("Contact List"); /* autotranslated */ + odp.pszTitle = LPGEN("Country Flags"); /* autotranslated */ + odp.pszTab = LPGEN("Country Flags"); /* autotranslated, can be made a tab */ + odp.flags = ODPF_BOLDGROUPS; + odp.pfnDlgProc = ExtraImgOptDlgProc; + odp.expertOnlyControls = expertOnlyControls; + odp.nExpertOnlyControls = SIZEOF(expertOnlyControls); + Options_AddPage(wParam, &odp); + return 0; +} + +static int ExtraImgSettingChanged(WPARAM wParam,LPARAM lParam) +{ + DBCONTACTWRITESETTING *dbcws=(DBCONTACTWRITESETTING*)lParam; + if ((HANDLE)wParam==NULL) { + if (!lstrcmpA(dbcws->szModule,"Flags")) { + /* Extra Image */ + if (!lstrcmpA(dbcws->szSetting,"ShowExtraImgFlag") || + !lstrcmpA(dbcws->szSetting,"ExtraImgFlagColumn") || + !lstrcmpA(dbcws->szSetting,"UseUnknownFlag") || + !lstrcmpA(dbcws->szSetting,"UseIpToCountry")) + if(ServiceExists(MS_CLIST_EXTRA_SET_ICON)) + CallFunctionBuffered(UpdateExtraImages,0,FALSE,EXTRAIMAGE_REFRESHDELAY); + /* Status Icon */ + if (!lstrcmpA(dbcws->szSetting,"ShowStatusIconFlag") || + !lstrcmpA(dbcws->szSetting,"UseUnknownFlag") || + !lstrcmpA(dbcws->szSetting,"UseIpToCountry")) + if(ServiceExists(MS_MSG_ADDICON)) + CallFunctionBuffered(UpdateStatusIcons,0,FALSE,STATUSICON_REFRESHDELAY); + } + } + /* user details update */ + else if (!lstrcmpA(dbcws->szSetting,"RealIP") || + !lstrcmpA(dbcws->szSetting,"Country") || + !lstrcmpA(dbcws->szSetting,"CompanyCountry")) { + /* Extra Image */ + if(ServiceExists(MS_CLIST_EXTRA_SET_ICON)) + CallFunctionBuffered(SetExtraImage,(LPARAM)wParam,TRUE,EXTRAIMAGE_REFRESHDELAY); + /* Status Icon */ + if(ServiceExists(MS_MSG_ADDICON)) + CallFunctionBuffered(UpdateStatusIcons,0,FALSE,STATUSICON_REFRESHDELAY); + } + return 0; +} + +/************************* Misc ***********************************/ + +static int ExtraImgModulesLoaded(WPARAM wParam,LPARAM lParam) +{ + UNREFERENCED_PARAMETER(wParam); + UNREFERENCED_PARAMETER(lParam); + /* Options */ + if(ServiceExists("DBEditorpp/RegisterSingleModule")) + CallService("DBEditorpp/RegisterSingleModule",(WPARAM)"Flags",0); + /* Extra Image */ + if(ServiceExists(MS_CLIST_EXTRA_SET_ICON)) { + int i; + BYTE idMaxExtraCol; + phExtraImages=(HANDLE*)mir_alloc(nCountriesCount*sizeof(HANDLE)); + /* invalidate icons */ + if(phExtraImages!=NULL) + for(i=0;i +#define NONAMELESSUNION +#include /* for ImageList functions */ +#define NOWIN2K +#include +#define MIRANDA_VER 0x0A00 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define FLAGS_NOHELPERFUNCTIONS +#include "m_flags.h" +#include "resource.h" + +#if defined(_MSC_VER) && !defined(FASTCALL) + #define FASTCALL __fastcall +#else + #define FASTCALL +#endif +#if defined(_DEBUG) + #undef FASTCALL + #define FASTCALL +#endif + +/* countrylistext.c */ +void InitCountryListExt(void); +void UninitCountryListExt(void); + +/* huffman.c */ +#ifdef HUFFMAN_ENCODE + int Huffman_Compress(unsigned char *in,unsigned char *out,unsigned int insize ); +#endif +void Huffman_Uncompress(unsigned char *in,unsigned char *out,unsigned int insize,unsigned int outsize); + +/* icons.c */ +HICON FASTCALL LoadFlagIcon(int countryNumber); +int FASTCALL CountryNumberToIndex(int countryNumber); +void InitIcons(void); +void UninitIcons(void); + +/* ip2country.c */ +INT_PTR ServiceIpToCountry(WPARAM wParam,LPARAM lParam); +void InitIpToCountry(void); +void UninitIpToCountry(void); + +/* extraimg.c */ +void InitExtraImg(void); +void UninitExtraImg(void); + +/* utils.c */ +typedef void (CALLBACK *BUFFEREDPROC)(LPARAM lParam); +#ifdef _DEBUG + void _CallFunctionBuffered(BUFFEREDPROC pfnBuffProc,const char *pszProcName,LPARAM lParam,BOOL fAccumulateSameParam,UINT uElapse); + #define CallFunctionBuffered(proc,param,acc,elapse) _CallFunctionBuffered(proc,#proc,param,acc,elapse) +#else + void _CallFunctionBuffered(BUFFEREDPROC pfnBuffProc,LPARAM lParam,BOOL fAccumulateSameParam,UINT uElapse); + #define CallFunctionBuffered(proc,param,acc,elapse) _CallFunctionBuffered(proc,param,acc,elapse) +#endif +void PrepareBufferedFunctions(void); +void KillBufferedFunctions(void); diff --git a/plugins/CountryFlags/src/huffman.cpp b/plugins/CountryFlags/src/huffman.cpp new file mode 100644 index 0000000000..c460e9a66e --- /dev/null +++ b/plugins/CountryFlags/src/huffman.cpp @@ -0,0 +1,506 @@ +/************************************************************************* +* Name: huffman.c +* Author: Marcus Geelnard +* Description: Huffman coder/decoder implementation. +* Reentrant: Yes +* +* This is a very straight forward implementation of a Huffman coder and +* decoder. +* +* Primary flaws with this primitive implementation are: +* - Slow bit stream implementation +* - Maximum tree depth of 32 (the coder aborts if any code exceeds a +* size of 32 bits). If I'm not mistaking, this should not be possible +* unless the input buffer is larger than 2^32 bytes, which is not +* supported by the coder anyway (max 2^32-1 bytes can be specified with +* an unsigned 32-bit integer). +* +* On the other hand, there are a few advantages of this implementation: +* - The Huffman tree is stored in a very compact form, requiring only +* 10 bits per symbol (for 8 bit symbols), meaning a maximum of 320 +* bytes overhead. +* - The code should be fairly easy to follow, if you are familiar with +* how the Huffman compression algorithm works. +* +* Possible improvements (probably not worth it): +* - Partition the input data stream into blocks, where each block has +* its own Huffman tree. With variable block sizes, it should be +* possible to find locally optimal Huffman trees, which in turn could +* reduce the total size. +* - Allow for a few different predefined Huffman trees, which could +* reduce the size of a block even further. +*------------------------------------------------------------------------- +* Copyright (c) 2003-2006 Marcus Geelnard +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would +* be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not +* be misrepresented as being the original software. +* +* 3. This notice may not be removed or altered from any source +* distribution. +* +* Marcus Geelnard +* marcus.geelnard at home.se +*************************************************************************/ + + +/************************************************************************* +* Types used for Huffman coding +*************************************************************************/ + +typedef struct { + unsigned char *BytePtr; + unsigned int BitPos; +} huff_bitstream_t; + +typedef struct { + int Symbol; + unsigned int Count; + unsigned int Code; + unsigned int Bits; +} huff_sym_t; + +typedef struct huff_encodenode_struct huff_encodenode_t; + +struct huff_encodenode_struct { + huff_encodenode_t *ChildA, *ChildB; + int Count; + int Symbol; +}; + +typedef struct huff_decodenode_struct huff_decodenode_t; + +struct huff_decodenode_struct { + huff_decodenode_t *ChildA, *ChildB; + int Symbol; +}; + + +/************************************************************************* +* Constants for Huffman decoding +*************************************************************************/ + +/* The maximum number of nodes in the Huffman tree is 2^(8+1)-1 = 511 */ +#define MAX_TREE_NODES 511 + + +/************************************************************************* +* _Huffman_InitBitstream() - Initialize a bitstream. +*************************************************************************/ + +static void _Huffman_InitBitstream( huff_bitstream_t *stream, + unsigned char *buf ) +{ + stream->BytePtr = buf; + stream->BitPos = 0; +} + + +/************************************************************************* +* _Huffman_ReadBit() - Read one bit from a bitstream. +*************************************************************************/ + +static unsigned int _Huffman_ReadBit( huff_bitstream_t *stream ) +{ + unsigned int x, bit; + unsigned char *buf; + + /* Get current stream state */ + buf = stream->BytePtr; + bit = stream->BitPos; + + /* Extract bit */ + x = (*buf & (1<<(7-bit))) ? 1 : 0; + bit = (bit+1) & 7; + if ( !bit ) + { + ++ buf; + } + + /* Store new stream state */ + stream->BitPos = bit; + stream->BytePtr = buf; + + return x; +} + + +/************************************************************************* +* _Huffman_Read8Bits() - Read eight bits from a bitstream. +*************************************************************************/ + +static unsigned int _Huffman_Read8Bits( huff_bitstream_t *stream ) +{ + unsigned int x, bit; + unsigned char *buf; + + /* Get current stream state */ + buf = stream->BytePtr; + bit = stream->BitPos; + + /* Extract byte */ + x = (*buf << bit) | (buf[1] >> (8-bit)); + ++ buf; + + /* Store new stream state */ + stream->BytePtr = buf; + + return x; +} + + +/************************************************************************* +* _Huffman_WriteBits() - Write bits to a bitstream. +*************************************************************************/ + +#ifdef HUFFMAN_ENCODE +static void _Huffman_WriteBits( huff_bitstream_t *stream, unsigned int x, + unsigned int bits ) +{ + unsigned int bit, count; + unsigned char *buf; + unsigned int mask; + + /* Get current stream state */ + buf = stream->BytePtr; + bit = stream->BitPos; + + /* Append bits */ + mask = 1 << (bits-1); + for ( count = 0; count < bits; ++ count ) + { + *buf = (unsigned char)((*buf & (0xff^(1<<(7-bit)))) + + ((x & mask ? 1 : 0) << (7-bit))); + x <<= 1; + bit = (bit+1) & 7; + if ( !bit ) + { + ++ buf; + } + } + + /* Store new stream state */ + stream->BytePtr = buf; + stream->BitPos = bit; +} +#endif + + +/************************************************************************* +* _Huffman_Hist() - Calculate (sorted) histogram for a block of data. +*************************************************************************/ + +#ifdef HUFFMAN_ENCODE +static void _Huffman_Hist( unsigned char *in, huff_sym_t *sym, + unsigned int size ) +{ + int k; + + /* Clear/init histogram */ + for ( k = 0; k < 256; ++ k ) + { + sym[k].Symbol = k; + sym[k].Count = 0; + sym[k].Code = 0; + sym[k].Bits = 0; + } + + /* Build histogram */ + for ( k = size; k; -- k ) + { + sym[*in ++].Count ++; + } +} +#endif + + +/************************************************************************* +* _Huffman_StoreTree() - Store a Huffman tree in the output stream and +* in a look-up-table (a symbol array). +*************************************************************************/ + +#ifdef HUFFMAN_ENCODE +static void _Huffman_StoreTree( huff_encodenode_t *node, huff_sym_t *sym, + huff_bitstream_t *stream, unsigned int code, unsigned int bits ) +{ + unsigned int sym_idx; + + /* Is this a leaf node? */ + if ( node->Symbol >= 0 ) + { + /* Append symbol to tree description */ + _Huffman_WriteBits( stream, 1, 1 ); + _Huffman_WriteBits( stream, node->Symbol, 8 ); + + /* Find symbol index */ + for ( sym_idx = 0; sym_idx < 256; ++ sym_idx ) + { + if ( sym[sym_idx].Symbol == node->Symbol ) break; + } + + /* Store code info in symbol array */ + sym[sym_idx].Code = code; + sym[sym_idx].Bits = bits; + return; + } + else + { + /* This was not a leaf node */ + _Huffman_WriteBits( stream, 0, 1 ); + } + + /* Branch A */ + _Huffman_StoreTree( node->ChildA, sym, stream, (code<<1)+0, bits+1 ); + + /* Branch B */ + _Huffman_StoreTree( node->ChildB, sym, stream, (code<<1)+1, bits+1 ); +} +#endif + + +/************************************************************************* +* _Huffman_MakeTree() - Generate a Huffman tree. +*************************************************************************/ + +#ifdef HUFFMAN_ENCODE +static void _Huffman_MakeTree( huff_sym_t *sym, huff_bitstream_t *stream ) +{ + huff_encodenode_t nodes[MAX_TREE_NODES], *node_1, *node_2, *root; + unsigned int k, num_symbols, nodes_left, next_idx; + + /* Initialize all leaf nodes */ + num_symbols = 0; + for ( k = 0; k < 256; ++ k ) + { + if ( sym[k].Count > 0 ) + { + nodes[num_symbols].Symbol = sym[k].Symbol; + nodes[num_symbols].Count = sym[k].Count; + nodes[num_symbols].ChildA = (huff_encodenode_t *) 0; + nodes[num_symbols].ChildB = (huff_encodenode_t *) 0; + ++ num_symbols; + } + } + + /* Build tree by joining the lightest nodes until there is only + one node left (the root node). */ + root = (huff_encodenode_t *) 0; + nodes_left = num_symbols; + next_idx = num_symbols; + while( nodes_left > 1 ) + { + /* Find the two lightest nodes */ + node_1 = (huff_encodenode_t *) 0; + node_2 = (huff_encodenode_t *) 0; + for ( k = 0; k < next_idx; ++ k ) + { + if ( nodes[k].Count > 0 ) + { + if ( !node_1 || (nodes[k].Count <= node_1->Count)) + { + node_2 = node_1; + node_1 = &nodes[k]; + } + else if ( !node_2 || (nodes[k].Count <= node_2->Count)) + { + node_2 = &nodes[k]; + } + } + } + + /* Join the two nodes into a new parent node */ + root = &nodes[next_idx]; + root->ChildA = node_1; + root->ChildB = node_2; + root->Count = node_1->Count + node_2->Count; + root->Symbol = -1; + node_1->Count = 0; + node_2->Count = 0; + ++ next_idx; + -- nodes_left; + } + + /* Store the tree in the output stream, and in the sym[] array (the + latter is used as a look-up-table for faster encoding) */ + if ( root ) + { + _Huffman_StoreTree( root, sym, stream, 0, 0 ); + } + else + { + /* Special case: only one symbol => no binary tree */ + root = &nodes[0]; + _Huffman_StoreTree( root, sym, stream, 0, 1 ); + } +} +#endif + + +/************************************************************************* +* _Huffman_RecoverTree() - Recover a Huffman tree from a bitstream. +*************************************************************************/ + +static huff_decodenode_t * _Huffman_RecoverTree( huff_decodenode_t *nodes, + huff_bitstream_t *stream, unsigned int *nodenum ) +{ + huff_decodenode_t * this_node; + + /* Pick a node from the node array */ + this_node = &nodes[*nodenum]; + *nodenum = *nodenum + 1; + + /* Clear the node */ + this_node->Symbol = -1; + this_node->ChildA = (huff_decodenode_t *) 0; + this_node->ChildB = (huff_decodenode_t *) 0; + + /* Is this a leaf node? */ + if ( _Huffman_ReadBit( stream )) + { + /* Get symbol from tree description and store in lead node */ + this_node->Symbol = _Huffman_Read8Bits( stream ); + + return this_node; + } + + /* Get branch A */ + this_node->ChildA = _Huffman_RecoverTree( nodes, stream, nodenum ); + + /* Get branch B */ + this_node->ChildB = _Huffman_RecoverTree( nodes, stream, nodenum ); + + return this_node; +} + + + +/************************************************************************* +* PUBLIC FUNCTIONS * +*************************************************************************/ + + +/************************************************************************* +* Huffman_Compress() - Compress a block of data using a Huffman coder. +* in - Input (uncompressed) buffer. +* out - Output (compressed) buffer. This buffer must be 384 bytes +* larger than the input buffer. +* insize - Number of input bytes. +* The function returns the size of the compressed data. +*************************************************************************/ + +#ifdef HUFFMAN_ENCODE +int Huffman_Compress( unsigned char *in, unsigned char *out, + unsigned int insize ) +{ + huff_sym_t sym[256], tmp; + huff_bitstream_t stream; + unsigned int k, total_bytes, swaps, symbol; + + /* Do we have anything to compress? */ + if ( insize < 1 ) return 0; + + /* Initialize bitstream */ + _Huffman_InitBitstream( &stream, out ); + + /* Calculate and sort histogram for input data */ + _Huffman_Hist( in, sym, insize ); + + /* Build Huffman tree */ + _Huffman_MakeTree( sym, &stream ); + + /* Sort histogram - first symbol first (bubble sort) */ + do + { + swaps = 0; + for ( k = 0; k < 255; ++ k ) + { + if ( sym[k].Symbol > sym[k+1].Symbol ) + { + tmp = sym[k]; + sym[k] = sym[k+1]; + sym[k+1] = tmp; + swaps = 1; + } + } + } + while( swaps ); + + /* Encode input stream */ + for ( k = 0; k < insize; ++ k ) + { + symbol = in[k]; + _Huffman_WriteBits( &stream, sym[symbol].Code, + sym[symbol].Bits ); + } + + /* Calculate size of output data */ + total_bytes = (int)(stream.BytePtr - out); + if ( stream.BitPos > 0 ) + { + ++ total_bytes; + } + + return total_bytes; +} +#endif + + +/************************************************************************* +* Huffman_Uncompress() - Uncompress a block of data using a Huffman +* decoder. +* in - Input (compressed) buffer. +* out - Output (uncompressed) buffer. This buffer must be large +* enough to hold the uncompressed data. +* insize - Number of input bytes. +* outsize - Number of output bytes. +*************************************************************************/ + +void Huffman_Uncompress( unsigned char *in, unsigned char *out, + unsigned int insize, unsigned int outsize ) +{ + huff_decodenode_t nodes[MAX_TREE_NODES], *root, *node; + huff_bitstream_t stream; + unsigned int k, node_count; + unsigned char *buf; + + /* Do we have anything to decompress? */ + if ( insize < 1 ) return; + + /* Initialize bitstream */ + _Huffman_InitBitstream( &stream, in ); + + /* Recover Huffman tree */ + node_count = 0; + root = _Huffman_RecoverTree( nodes, &stream, &node_count ); + + /* Decode input stream */ + buf = out; + for ( k = 0; k < outsize; ++ k ) + { + /* Traverse tree until we find a matching leaf node */ + node = root; + while( node->Symbol < 0 ) + { + /* Get next node */ + if ( _Huffman_ReadBit( &stream )) + node = node->ChildB; + else + node = node->ChildA; + } + + /* We found the matching leaf node and have the symbol */ + *buf ++ = (unsigned char) node->Symbol; + } +} diff --git a/plugins/CountryFlags/src/icons.cpp b/plugins/CountryFlags/src/icons.cpp new file mode 100644 index 0000000000..3b456a4d11 --- /dev/null +++ b/plugins/CountryFlags/src/icons.cpp @@ -0,0 +1,282 @@ +/* +Miranda IM Country Flags Plugin +Copyright (C) 2006-1007 H. Herkenrath + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (Flags-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "flags.h" + +extern HINSTANCE hInst; +extern int nCountriesCount; +extern struct CountryListEntry *countries; +static HANDLE hServiceLoadIcon,hServiceCreateMergedIcon; + +/************************* Bitmap Access **************************/ + +static HANDLE *phIconHandles; + +static int FASTCALL CountryNumberToBitmapIndex(int countryNumber) +{ + /* country number indices (same order as in flags.bmp) */ + const int BitmapIndexMap[232]={ + 0, 1, 7, 20, 27, 30, 31, 32, 33, 34, 36, 39, 40, 41, 43, 44, 45, 46, 47, 48, + 49, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 63, 64, 65, 66, 81, 82, 84, 86, + 90, 91, 92, 93, 94, 95, 98, 101, 102, 103, 104, 105, 106, 107, 178, 108, 109, 110, 111, 112, + 113, 116, 117, 118, 121, 122, 123, 212, 213, 216, 218, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 260, 261, 263, 264, 265, 266, 267, 268, 269, 290, 291, + 297, 298, 299, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 380, 381, 382, 385, 386, 387, 389, 420, 421, 441, 442, 500, 501, 502, 503, 504, 505, + 506, 507, 508, 509, 590, 591, 592, 593, 595, 596, 597, 598, 599, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 705, 706, 708, 709, + 711, 850, 852, 853, 855, 856, 880, 886, 960, 961, 962, 963, 964, 965, 966, 967, 968, 971, 972, 973, + 974, 975, 976, 977, 994, 995,1141,2691,3811,4101,6101,6722 + }; + /* shared flags by multiple countries */ + switch(countryNumber) { + case 262: /* Reunion Island */ + case 594: /* French Guiana */ + case 5901: /* French Antilles */ + countryNumber=33; /* France */ + break; + case 120: /* Barbuda */ + countryNumber=102; /* Antigua and Barbuda */ + break; + case 6702: /* Tinian Island */ + case 6701: /* Rota Island */ + countryNumber=670; /* Saipan Island (Northern Mariana Islands) */ + break; + case 115: /* Saint Kitts */ + case 114: /* Nevis */ + countryNumber=1141; /* Saint Kitts and Nevis */ + break; + case 247: /* Ascension Island */ + countryNumber=44; /* United Kingdom */ + break; + case 6721: /* Australian Antarctic Territory */ + countryNumber=61; /* Australia */ + break; + case 5399: /* Guantanamo Bay */ + countryNumber=1; /* USA */ + } + /* binary search in index array */ + { int low=0,i,high; + high=SIZEOF(BitmapIndexMap)-1; + if(countryNumber<=BitmapIndexMap[high]) + while(low<=high) { + i=low+((high-low)/2); + /* never happens */ + if(i<0 || i>=SIZEOF(BitmapIndexMap)) DebugBreak(); + if(BitmapIndexMap[i]==countryNumber) return i; + if(countryNumber>BitmapIndexMap[i]) low=i+1; + else high=i-1; + } + } + /* Other,Unknown,Unspecified */ + return 0; +} + +// return value needs to be released using DestroyIcon() +// only operates on color icons, which isn't a problem here +static HICON FASTCALL ResizeIconCentered(HICON hIcon,int cx,int cy) +{ + HICON hResIcon=NULL; + ICONINFO icoi; + BITMAP bm; + register HDC hdc; + HBITMAP hbmPrev,hbm; + POINT pt; + hdc=CreateCompatibleDC(NULL); + if(hdc!=NULL) { + if(GetIconInfo(hIcon,&icoi)) { + if(GetObject(icoi.hbmColor,sizeof(bm),&bm) && bm.bmWidth<=cx && bm.bmHeight<=cy) { + pt.x=(cx-bm.bmWidth)/2; + pt.y=(cy-bm.bmHeight)/2; + hbmPrev = (HBITMAP)SelectObject(hdc, icoi.hbmColor); + if(hbmPrev!=NULL) { /* error on select? */ + hbm=icoi.hbmColor; + icoi.hbmColor=CreateCompatibleBitmap(hdc,cx,cy); + if(icoi.hbmColor!=NULL) + if(SelectObject(hdc,icoi.hbmColor)!=NULL) { /* error on select? */ + DeleteObject(hbm); /* delete prev color (XOR) */ + if(BitBlt(hdc,0,0,cx,cy,NULL,0,0,BLACKNESS)) /* transparency: AND=0, XOR=1 */ + if(DrawIconEx(hdc,pt.x,pt.y,hIcon,bm.bmWidth,bm.bmHeight,0,NULL,DI_IMAGE|DI_NOMIRROR)) { + if(SelectObject(hdc,icoi.hbmMask)!=NULL) { /* error on select? */ + hbm=icoi.hbmMask; + icoi.hbmMask=CreateBitmap(cx,cy,1,1,NULL); /* mono */ + if(icoi.hbmMask!=NULL) + if(SelectObject(hdc,icoi.hbmMask)!=NULL) { /* error on select? */ + DeleteObject(hbm); /* delete prev mask (AND) */ + if(BitBlt(hdc,0,0,cx,cy,NULL,0,0,WHITENESS)) /* transparency: AND=0, XOR=1 */ + if(DrawIconEx(hdc,pt.x,pt.y,hIcon,0,0,0,NULL,DI_MASK|DI_NOMIRROR)) { + SelectObject(hdc,hbmPrev); + hResIcon=CreateIconIndirect(&icoi); /* bitmaps must not be selected */ + } + } + } + } + } + SelectObject(hdc,hbmPrev); + } + } + DeleteObject(icoi.hbmColor); + DeleteObject(icoi.hbmMask); + } + DeleteDC(hdc); + } + return hResIcon; +} + +/************************* Utils **********************************/ + +HICON FASTCALL LoadFlagIcon(int countryNumber) +{ + char szId[20],*szCountry; + /* create identifier */ + szCountry=(char*)CallService(MS_UTILS_GETCOUNTRYBYNUMBER,countryNumber,0); + if(szCountry==NULL) szCountry=(char*)CallService(MS_UTILS_GETCOUNTRYBYNUMBER,countryNumber=0xFFFF,0); + wsprintfA(szId,(countryNumber==0xFFFF)?"%s0x%X":"%s%i","flags_",countryNumber); /* buffer safe */ + return (HICON)CallService(MS_SKIN2_GETICON,0,(LPARAM)szId); +} + +int FASTCALL CountryNumberToIndex(int countryNumber) +{ + int i,nf=0; + for(i=0;i=dwFrom) /* only search if wParam valid */ + while(low<=high) { + i=low+((high-low)/2); + /* never happens */ + if(i<0) DebugBreak(); + /* analyze record */ + id=GetDataRecord(data,i,&dwFrom,&dwTo); + if(dwFrom<=wParam && dwTo>=wParam) { LeaveRecordCache(); return id; } + if(wParam>dwTo) low=i+1; + else high=i-1; + } + LeaveRecordCache(); + } + return 0xFFFF; /* Unknown */ +} + +/************************* Bin Converter **************************/ + +#ifdef BINCONV +#include +#include + +struct { + const char *szMir; + const char *szCSV; +} static const differentCountryNames[]={ + {"British Virgin Islands","VIRGIN ISLANDS, BRITISH"}, + {"Brunei","BRUNEI DARUSSALAM"}, + {"Cape Verde Islands","CAPE VERDE"}, + {"Cocos-Keeling Islands","COCOS (KEELING) ISLANDS"}, + {"Chile, Republic of","CHILE"}, + {"Congo, Democratic Republic of (Zaire)","THE DEMOCRATIC REPUBLIC OF THE CONGO"}, + {"Congo, Republic of the","CONGO"}, + {"Cote d'Ivoire (Ivory Coast)","COTE D'IVOIRE"}, + {"Diego Garcia","BRITISH INDIAN OCEAN TERRITORY"}, + {"Guam, US Territory of","GUAM"}, + {"Iran (Islamic Republic of)","ISLAMIC REPUBLIC OF IRAN"}, + {"Korea, North","REPUBLIC OF KOREA"}, + {"Laos","LAO PEOPLE'S DEMOCRATIC REPUBLIC"}, + {"Reunion Island","REUNION"}, + {"Russia","RUSSIAN FEDERATION"}, + {"Saipan Island (Northern Mariana Islands)","NORTHERN MARIANA ISLANDS"}, + {"Tanzania","UNITED REPUBLIC OF TANZANIA"}, + {"USA","UNITED STATES"}, + {"Macau","MACAO"}, + {"Macedonia (F.Y.R.O.M.)","THE FORMER YUGOSLAV REPUBLIC OF MACEDONIA"}, + {"Micronesia, Federated States of","FEDERATED STATES OF MICRONESIA"}, + {"Mayotte Island","MAYOTTE"}, + {"Moldova, Republic of","REPUBLIC OF MOLDOVA"}, + {"Vietnam","VIET NAM"}, + {"Virgin Islands (USA)","VIRGIN ISLANDS, U.S."}, + {"Vatican City","HOLY SEE (VATICAN CITY STATE)"}, + {"Serbia, Republic of","SERBIA"}, + {"Montenegro, Republic of","MONTENEGRO"}, +}; + +#define ALLOC_STEP (800*1024) /* approx. size of data output */ + +struct ResizableByteBuffer { + BYTE *buf; + DWORD cbLength,cbAlloced; +}; + +static void AppendToByteBuffer(struct ResizableByteBuffer *buffer,const void *append,DWORD cbAppendSize) +{ + if(buffer->cbAlloced<=buffer->cbLength+cbAppendSize) { + BYTE* buf=(BYTE*)mir_realloc(buffer->buf,buffer->cbAlloced+ALLOC_STEP+cbAppendSize); + if(buf==NULL) return; + buffer->buf=buf; + buffer->cbAlloced+=ALLOC_STEP+cbAppendSize; + OutputDebugStringA("reallocating memory...\n"); /* all ascii */ + } + CopyMemory(&buffer->buf[buffer->cbLength],append,cbAppendSize); + buffer->cbLength+=cbAppendSize; +} + +static int EnumIpDataLines(const char *pszFileCSV,const char *pszFileOut) +{ + FILE *fp; + char line[1024],out[512],*pszFrom,*pszTo,*pszTwo,*pszCountry,*buf; + int i,j; + DWORD dwOut; + WORD wOut; + struct ResizableByteBuffer buffer; + + ZeroMemory(&buffer,sizeof(buffer)); + fp=fopen(pszFileCSV,"rt"); + if(fp!=NULL) { + OutputDebugStringA("Running IP data convert...\n"); /* all ascii */ + while(!feof(fp)) { + if(fgets(line,sizeof(line),fp)==NULL) break; + /* get line data */ + pszFrom=line+1; + pszTo=strchr(pszFrom,','); + *(pszTo-1)='\0'; pszTo+=2; + pszTwo=strchr(pszTo,','); + *(pszTwo-1)='\0'; pszTwo+=2; + pszCountry=strchr(pszTwo,',')+1; + pszCountry=strchr(pszCountry,',')+2; + buf=strchr(pszCountry,'"'); + *buf=pszTwo[2]='\0'; + /* corrections */ + if (!lstrcmpi(pszCountry,"ANTARCTICA")) continue; + if (!lstrcmpi(pszCountry,"TIMOR-LESTE")) continue; + if (!lstrcmpi(pszCountry,"PALESTINIAN TERRITORY, OCCUPIED")) + lstrcpy(pszCountry,"ISRAEL"); + else if (!lstrcmpi(pszCountry,"UNITED STATES MINOR OUTLYING ISLANDS")) + lstrcpy(pszCountry,"UNITED STATES"); + else if (!lstrcmpi(pszCountry,"SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS")) + lstrcpy(pszCountry,"UNITED KINGDOM"); + else if (!lstrcmpi(pszTwo,"JE")) /* map error */ + lstrcpy(pszCountry,"UNITED KINGDOM"); + else if (!lstrcmpi(pszTwo,"AX")) /* Åland Island belongs to Finland */ + lstrcpy(pszCountry,"FINLAND"); + else if (!lstrcmpi(pszTwo,"ME")) + lstrcpy(pszCountry,"MONTENEGRO"); + else if (!lstrcmpi(pszTwo,"RS") || !lstrcmpi(pszTwo,"CS")) + lstrcpy(pszCountry,"SERBIA"); + /* convert */ + for(i=0;i=callList[i].uElapse) { + /* call elapsed proc */ + pfnBuffProc=callList[i].pfnBuffProc; + lParam=callList[i].lParam; + #ifdef _DEBUG + pszProcName=callList[i].pszProcName; + #endif + /* resize storage array */ + if ((i+1)startTick=GetTickCount(); + data->uElapse=uElapse; + data->lParam=lParam; + data->pfnBuffProc=pfnBuffProc; + #ifdef _DEBUG + { char szDbgLine[256]; + data->pszProcName=pszProcName; + mir_snprintf(szDbgLine,sizeof(szDbgLine),"buffered queue: %s(0x%X)\n",pszProcName,lParam); /* all ascii */ + OutputDebugStringA(szDbgLine); + if (!idBufferedTimer) { + mir_snprintf(szDbgLine,sizeof(szDbgLine),"next buffered timeout: %ums\n",uElapse); /* all ascii */ + OutputDebugStringA(szDbgLine); + } + } + #endif + /* set next timer */ + if(idBufferedTimer) uElapse=USER_TIMER_MINIMUM; /* will get recalculated */ + idBufferedTimer=SetTimer(NULL,idBufferedTimer,uElapse,BufferedProcTimer); +} + +// assumes to be called in context of main thread +void PrepareBufferedFunctions(void) +{ + idBufferedTimer=0; + nCallListCount=0; + callList=NULL; +} + +// assumes to be called in context of main thread +void KillBufferedFunctions(void) +{ + if(idBufferedTimer) KillTimer(NULL,idBufferedTimer); + nCallListCount=0; + mir_free(callList); /* does NULL check */ +} diff --git a/plugins/CountryFlags/src/version.h b/plugins/CountryFlags/src/version.h new file mode 100644 index 0000000000..a778ed0026 --- /dev/null +++ b/plugins/CountryFlags/src/version.h @@ -0,0 +1,31 @@ +/* +Miranda IM Country Flags Plugin +Copyright (C) 2006-2007 H. Herkenrath + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program (Flags-License.txt); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#define NEEDED_MIRANDA_VERSION PLUGIN_MAKE_VERSION(0,7,0,10) +#define NEEDED_MIRANDA_VERSION_STR "0.7 alpha build #10" +#define PLUGIN_VERSION PLUGIN_MAKE_VERSION(0,1,0,3) +#define FILE_VERSION 0,1,0,3 + +#ifdef _DEBUG + #define FILE_VERSION_STR "0.1.0.4 alpha" +#else + #define FILE_VERSION_STR "0.1.0.3" +#endif + +#define PLUGIN_WEBSITE "http://addons.miranda-im.org/details.php?action=viewfile&id=3463" diff --git a/plugins/CountryFlags/utils.cpp b/plugins/CountryFlags/utils.cpp deleted file mode 100644 index b55e52e5cf..0000000000 --- a/plugins/CountryFlags/utils.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* -Miranda IM Country Flags Plugin -Copyright (C) 2006-1007 H. Herkenrath - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program (Flags-License.txt); if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "flags.h" - -/************************* Buffered Functions *********************/ - -struct BufferedCallData { - DWORD startTick; - UINT uElapse; - BUFFEREDPROC pfnBuffProc; - LPARAM lParam; - #ifdef _DEBUG - const char *pszProcName; - #endif -}; - -static UINT idBufferedTimer; -static struct BufferedCallData *callList; -static int nCallListCount; - -// always gets called in main message loop -static void CALLBACK BufferedProcTimer(HWND hwnd,UINT msg,UINT_PTR idTimer,DWORD currentTick) -{ - int i; - struct BufferedCallData *buf; - UINT uElapsed,uElapseNext=USER_TIMER_MAXIMUM; - BUFFEREDPROC pfnBuffProc; - LPARAM lParam; - #ifdef _DEBUG - char szDbgLine[256]; - const char *pszProcName; - #endif - UNREFERENCED_PARAMETER(msg); - - for(i=0;i=callList[i].uElapse) { - /* call elapsed proc */ - pfnBuffProc=callList[i].pfnBuffProc; - lParam=callList[i].lParam; - #ifdef _DEBUG - pszProcName=callList[i].pszProcName; - #endif - /* resize storage array */ - if ((i+1)startTick=GetTickCount(); - data->uElapse=uElapse; - data->lParam=lParam; - data->pfnBuffProc=pfnBuffProc; - #ifdef _DEBUG - { char szDbgLine[256]; - data->pszProcName=pszProcName; - mir_snprintf(szDbgLine,sizeof(szDbgLine),"buffered queue: %s(0x%X)\n",pszProcName,lParam); /* all ascii */ - OutputDebugStringA(szDbgLine); - if (!idBufferedTimer) { - mir_snprintf(szDbgLine,sizeof(szDbgLine),"next buffered timeout: %ums\n",uElapse); /* all ascii */ - OutputDebugStringA(szDbgLine); - } - } - #endif - /* set next timer */ - if(idBufferedTimer) uElapse=USER_TIMER_MINIMUM; /* will get recalculated */ - idBufferedTimer=SetTimer(NULL,idBufferedTimer,uElapse,BufferedProcTimer); -} - -// assumes to be called in context of main thread -void PrepareBufferedFunctions(void) -{ - idBufferedTimer=0; - nCallListCount=0; - callList=NULL; -} - -// assumes to be called in context of main thread -void KillBufferedFunctions(void) -{ - if(idBufferedTimer) KillTimer(NULL,idBufferedTimer); - nCallListCount=0; - mir_free(callList); /* does NULL check */ -} diff --git a/plugins/CountryFlags/version.h b/plugins/CountryFlags/version.h deleted file mode 100644 index a778ed0026..0000000000 --- a/plugins/CountryFlags/version.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -Miranda IM Country Flags Plugin -Copyright (C) 2006-2007 H. Herkenrath - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program (Flags-License.txt); if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#define NEEDED_MIRANDA_VERSION PLUGIN_MAKE_VERSION(0,7,0,10) -#define NEEDED_MIRANDA_VERSION_STR "0.7 alpha build #10" -#define PLUGIN_VERSION PLUGIN_MAKE_VERSION(0,1,0,3) -#define FILE_VERSION 0,1,0,3 - -#ifdef _DEBUG - #define FILE_VERSION_STR "0.1.0.4 alpha" -#else - #define FILE_VERSION_STR "0.1.0.3" -#endif - -#define PLUGIN_WEBSITE "http://addons.miranda-im.org/details.php?action=viewfile&id=3463" diff --git a/plugins/CountryFlags/version.rc b/plugins/CountryFlags/version.rc deleted file mode 100644 index a381dfefd2..0000000000 --- a/plugins/CountryFlags/version.rc +++ /dev/null @@ -1,51 +0,0 @@ -#ifdef APSTUDIO_INVOKED -#error this file is not editable by Microsoft Visual C++ -#endif //APSTUDIO_INVOKED - -#ifndef _MAC - -#include - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION FILE_VERSION - PRODUCTVERSION FILE_VERSION - FILEFLAGSMASK 0x0L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "Comments", "Licensed under the terms of the GNU General Public License" - VALUE "FileDescription", "Country Flags Plugin for Miranda IM" - VALUE "FileVersion", FILE_VERSION_STR - VALUE "InternalName", "CountryUtils" - VALUE "LegalCopyright", "Copyright © 2006-2007 H. Herkenrath" - VALUE "OriginalFilename", "flags.dll" - VALUE "ProductName", "Country Flags" - VALUE "ProductVersion", FILE_VERSION_STR - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0, 1200 - END -END - -#endif // !_MAC - - - - diff --git a/plugins/CrashDumper/Vi show.ico b/plugins/CrashDumper/Vi show.ico deleted file mode 100644 index 55556862f3..0000000000 Binary files a/plugins/CrashDumper/Vi show.ico and /dev/null differ diff --git a/plugins/CrashDumper/Vi to clipboard.ico b/plugins/CrashDumper/Vi to clipboard.ico deleted file mode 100644 index 6f095b59b1..0000000000 Binary files a/plugins/CrashDumper/Vi to clipboard.ico and /dev/null differ diff --git a/plugins/CrashDumper/Vi to file.ico b/plugins/CrashDumper/Vi to file.ico deleted file mode 100644 index abfc196437..0000000000 Binary files a/plugins/CrashDumper/Vi to file.ico and /dev/null differ diff --git a/plugins/CrashDumper/Vi upload.ico b/plugins/CrashDumper/Vi upload.ico deleted file mode 100644 index 4c562b02b8..0000000000 Binary files a/plugins/CrashDumper/Vi upload.ico and /dev/null differ diff --git a/plugins/CrashDumper/Vi.ico b/plugins/CrashDumper/Vi.ico deleted file mode 100644 index 371aeb345e..0000000000 Binary files a/plugins/CrashDumper/Vi.ico and /dev/null differ diff --git a/plugins/CrashDumper/bkstring.cpp b/plugins/CrashDumper/bkstring.cpp deleted file mode 100644 index 418cb0bd83..0000000000 --- a/plugins/CrashDumper/bkstring.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* -Miranda Crash Dumper Plugin -Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "bkstring.h" - -bkstring::~bkstring() { if (sizeAlloced) free(buf); } - - -void bkstring::reserve(size_type len) -{ - if (len >= sizeAlloced || sizeAlloced == 0) - { - if (sizeAlloced == 0) buf = NULL; - buf = (value_type*)realloc(buf, (len+1) * sizeof(value_type)); - if (sizeAlloced == 0) buf[0] = 0; - sizeAlloced = len+1; - } -} - -void bkstring::appendfmt(const value_type *fmt, ...) -{ - areserve(_tcslen(fmt)*2); - - va_list vararg; - va_start(vararg, fmt); - for (;;) - { - int len = _vsntprintf(buf + lenBuf, sizeAlloced - lenBuf - 1, fmt, vararg); - if (len < 0) - reserve(sizeAlloced + 256); - else - { - lenBuf += len; - buf[lenBuf] = 0; - break; - } - } - va_end(vararg); -} - -bkstring& bkstring::append(const value_type* _Ptr) -{ - size_type len = _tcslen(_Ptr); - areserve(len); - memcpy(buf+lenBuf, _Ptr, (len+1)*sizeof(value_type)); - lenBuf += len; - return *this; -} - -bkstring& bkstring::append(const value_type* _Ptr, size_type _Count) -{ - size_type len = min(_tcslen(_Ptr), _Count); - areserve(len); - memcpy(buf+lenBuf, _Ptr, len*sizeof(value_type)); - lenBuf += len; - buf[lenBuf] = 0; - return *this; -} - -bkstring& bkstring::append(const bkstring& _Str, size_type _Off, size_type _Count) -{ - size_type len = min(_Count, _Str.size() - _Off); - areserve(len); - memcpy(buf+lenBuf, _Str.c_str()+_Off, len*sizeof(value_type)); - lenBuf += len; - buf[lenBuf] = 0; - return *this; -} - -bkstring& bkstring::append(const bkstring& _Str) -{ - size_type len = _Str.size(); - areserve(len); - memcpy(buf+lenBuf, _Str.c_str(), len*sizeof(value_type)); - lenBuf += len; - buf[lenBuf] = 0; - return *this; -} - -bkstring& bkstring::append(size_type _Count, value_type _Ch) -{ - areserve(_Count); - for(size_type i=0; i<_Count; ++i) buf[lenBuf+i] = _Ch; - lenBuf += _Count; - buf[lenBuf] = 0; - return *this; -} - - -bkstring& bkstring::assign(const value_type* _Ptr, size_type _Count) -{ - reserve(_Count); - memcpy(buf, _Ptr, _Count*sizeof(value_type)); - buf[_Count] = 0; - lenBuf = _Count; - return *this; -} - -bkstring& bkstring::assign(const bkstring& _Str, size_type _Off, size_type _Count) -{ - size_type len = min(_Count, _Str.size() - _Off); - reserve(len); - memcpy(buf, _Str.c_str() + _Off, len*sizeof(value_type)); - lenBuf = len; - buf[len] = 0; - return *this; -} - -bkstring& bkstring::assign(size_type _Count, value_type _Ch) -{ - reserve(_Count); - for(size_type i=0; i<_Count; ++i) buf[i] = _Ch; - buf[_Count] = 0; - lenBuf = _Count; - return *this; -} - -bkstring::size_type bkstring::find(value_type _Ch, size_type _Off) const -{ - for (size_type i=_Off; i<=lenBuf; ++i) - if (buf[i] == _Ch) return i; - return (size_type)npos; -} - -bkstring::size_type bkstring::find(const value_type* _Ptr, size_type _Off) const -{ - if (_Off > lenBuf) return (size_type)npos; - - value_type* pstr = _tcsstr(buf+_Off, _Ptr); - return pstr ? pstr - buf : npos; -} - -bkstring::size_type bkstring::find_last_of(value_type _Ch, size_type _Off) const -{ - for (size_type i=(_Off == npos ? lenBuf : _Off); i--;) - if (buf[i] == _Ch) return i; - return (size_type)npos; -} - -bkstring& bkstring::insert(size_type _P0, const value_type* _Ptr, size_type _Count) -{ - size_type len = _tcslen(_Ptr); - if (_Count < len) len = _Count; - areserve(len); - value_type *p = buf + _P0; - memmove(p+len, p, (lenBuf-_P0+1)*sizeof(value_type)); - memcpy(p, _Ptr, _Count*sizeof(value_type)); - lenBuf += len; - return *this; -} - -bkstring& bkstring::insert(size_type _P0, size_type _Count, value_type _Ch) -{ - areserve(_Count); - value_type *p = buf + _P0; - memmove(p+_Count, p, (lenBuf-_P0+1)*sizeof(value_type)); - for(size_type i=0; i<_Count; ++i) p[i] = _Ch; - lenBuf += _Count; - return *this; -} - -bkstring& bkstring::erase(size_type _Pos, size_type _Count) -{ - if (_Pos < lenBuf) - { - const size_type len = min(lenBuf - _Pos, _Count); - value_type *p = buf + _Pos; - lenBuf -= len; - memmove(p, p+len, (lenBuf - _Pos)*sizeof(value_type)); - buf[lenBuf] = 0; - } - return *this; -} diff --git a/plugins/CrashDumper/bkstring.h b/plugins/CrashDumper/bkstring.h deleted file mode 100644 index a546bb8bc8..0000000000 --- a/plugins/CrashDumper/bkstring.h +++ /dev/null @@ -1,276 +0,0 @@ -/* -Miranda Crash Dumper Plugin -Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#ifndef _BKSTRING_H_ -#define _BKSTRING_H_ - -#include -#include -#include -#include -#include - -#ifndef min -#define min(A, B) ((A) < (B) ? (A) : (B)) -#endif - -class bkstring -{ -public: - typedef size_t size_type; - typedef TCHAR value_type; - typedef value_type* iterator; - typedef const value_type* const_iterator; - -#if defined(_MSC_VER) && _MSC_VER > 1200 - static const size_type npos = size_type(-1); -#else - enum { npos = -1 }; -#endif - -private: - value_type* buf; - size_type sizeAlloced; - size_type lenBuf; - - void areserve(size_type len) { reserve(lenBuf + len); } - -public: - - explicit bkstring() : buf((TCHAR*)_T("")), sizeAlloced(0), lenBuf(0) - {} - - bkstring(const value_type* _Ptr, size_type _Count) : sizeAlloced(0), lenBuf(0) - { assign(_Ptr, _Count); } - - bkstring(const value_type* _Ptr) : sizeAlloced(0), lenBuf(0) - { assign(_Ptr); } - - bkstring(size_type _Count, value_type _Ch) : sizeAlloced(0), lenBuf(0) - { assign(_Count, _Ch); } - - bkstring(const bkstring& _Str) : sizeAlloced(0), lenBuf(0) - { assign(_Str); } - - bkstring(const bkstring& _Str, size_type _Off, size_type _Count) : sizeAlloced(0), lenBuf(0) - { assign(_Str, _Off, _Count); } - - ~bkstring(); - - size_type size(void) const { return lenBuf; } - const value_type* c_str(void) const { return buf; } - - void clear(void) { if (lenBuf) { lenBuf = 0; buf[0] = 0; } } - void insert(const value_type *txt); - void reserve(size_type len); - - bkstring& assign(const value_type* _Ptr) - { return assign(_Ptr, _tcslen(_Ptr)); } - - bkstring& assign(const bkstring& _Str) - { return assign(_Str, 0, (size_type)npos); } - - bkstring& assign(const value_type* _Ptr, size_type _Count); - bkstring& assign(const bkstring& _Str, size_type off, size_type _Count); - bkstring& assign(size_type _Count, value_type _Ch); - - bkstring& append(const value_type* _Ptr); - bkstring& append(const value_type* _Ptr, size_type _Count); - bkstring& append(const bkstring& _Str, size_type _Off, size_type _Count); - bkstring& append(const bkstring& _Str); - bkstring& append(size_type _Count, value_type _Ch); - - int compare(const bkstring& _Str) const - { return _tcscmp(buf, _Str.c_str()); } - - int compare(size_type _Pos1, size_type _Num1, const bkstring& _Str) const - { return _tcsncmp(&buf[_Pos1], _Str.c_str(), _Num1); } - - int compare(size_type _Pos1, size_type _Num1, const bkstring& _Str, size_type _Off, size_type _Count) const - { return _tcsncmp(&buf[_Pos1], _Str.c_str()+_Off, min(_Num1, _Count)); } - - int compare(const value_type* _Ptr) const - { return _tcscmp(buf, _Ptr); } - - int compare(size_type _Pos1, size_type _Num1, const value_type* _Ptr) const - { return _tcsncmp(&buf[_Pos1], _Ptr, _Num1); } - - int compare(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2) const - { return _tcsncmp(&buf[_Pos1], _Ptr, min(_Num1, _Num2)); } - - int comparei(const bkstring& _Str) const - { return _tcsicmp(buf, _Str.c_str()); } - - int comparei(size_type _Pos1, size_type _Num1, const bkstring& _Str) const - { return _tcsnicmp(&buf[_Pos1], _Str.c_str(), _Num1); } - - int comparei(size_type _Pos1, size_type _Num1, const bkstring& _Str, size_type _Off, size_type _Count) const - { return _tcsnicmp(&buf[_Pos1], _Str.c_str()+_Off, min(_Num1, _Count)); } - - int comparei(const value_type* _Ptr) const - { return _tcsicmp(buf, _Ptr); } - - int comparei(size_type _Pos1, size_type _Num1, const value_type* _Ptr) const - { return _tcsnicmp(&buf[_Pos1], _Ptr, _Num1); } - - int comparei(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2) const - { return _tcsnicmp(&buf[_Pos1], _Ptr, min(_Num1, _Num2)); } - - bool empty(void) const { return lenBuf == 0; }; - bkstring& erase(size_type _Pos = 0, size_type _Count = npos); - - size_type find(value_type _Ch, size_type _Off = 0) const; - size_type find(const value_type* _Ptr, size_type _Off = 0) const; - size_type find(bkstring& _Str, size_type _Off = 0) const - { return find(_Str.c_str(), _Off); } - - size_type find_last_of(value_type _Ch, size_type _Off = npos) const; - - bkstring& insert(size_type _P0, const value_type* _Ptr) - { return insert(_P0, _Ptr, _tcslen(_Ptr)); } - - bkstring& insert(size_type _P0, const bkstring& _Str) - { return insert(_P0, _Str.c_str(), _Str.size()); }; - - bkstring& insert(size_type _P0, const value_type* _Ptr, size_type _Count); - bkstring& insert(size_type _P0, size_type _Count, value_type _Ch); - - bkstring substr(size_type _Off = 0, size_type _Count = npos) const - { return bkstring(*this, _Off, _Count); } - - bkstring& operator = (const bkstring& _Str) - { return assign(_Str); } - - bkstring& operator =(const value_type* _Ptr) - { return assign(_Ptr); } - - bkstring& operator = (const value_type _Ch) - { return assign(1, _Ch); } - - bkstring& operator +=(const bkstring& _Str) - { return append(_Str); } - - bkstring& operator += (const value_type* _Ptr) - { return append(_Ptr); } - - bkstring& operator += (const value_type _Ch) - { return append(1, _Ch); } - - value_type& operator[] (int ind) const - { return buf[ind]; } - - friend bkstring operator+ (const bkstring& _Str1, const bkstring& _Str2) - { bkstring s(_Str1); return s.append(_Str2); } - - friend bkstring operator+ (const bkstring& _Str1, const value_type* _Ptr2) - { bkstring s(_Str1); return s.append(_Ptr2); } - - friend bkstring operator+(const value_type* _Ptr1, const bkstring& _Str2) - { bkstring s(_Ptr1); return s.append(_Str2); } - - friend bkstring operator+ (const bkstring& _Str1, const value_type _Ch) - { bkstring s(_Str1); return s.append(1, _Ch); } - - friend bool operator==(const bkstring& _Str1, const bkstring& _Str2) - { return _Str1.compare(_Str2) == 0; } - - friend bool operator==(const bkstring& _Str1, const value_type* _Ptr2) - { return _Str1.compare(_Ptr2) == 0; } - - friend bool operator==(const value_type* _Ptr1, const bkstring& _Str2) - { return _Str2.compare(_Ptr1) == 0; } - - friend bool operator!=(const bkstring& _Str1, const bkstring& _Str2) - { return _Str1.compare(_Str2) != 0; } - - friend bool operator!=(const bkstring& _Str1, const value_type* _Ptr2) - { return _Str1.compare(_Ptr2) != 0; } - - friend bool operator!=(const value_type* _Ptr1, const bkstring& _Str2) - { return _Str2.compare(_Ptr1) != 0; } - - friend bool operator<(const bkstring& _Str1, const bkstring& _Str2) - { return _Str1.compare(_Str2) < 0; } - - friend bool operator<(const bkstring& _Str1, const value_type* _Ptr2) - { return _Str1.compare(_Ptr2) < 0; } - - friend bool operator<(const value_type* _Ptr1, const bkstring& _Str2) - { return _Str2.compare(_Ptr1) > 0; } - - friend bool operator>(const bkstring& _Str1, const bkstring& _Str2) - { return _Str1.compare(_Str2) > 0; } - - friend bool operator>(const bkstring& _Str1, const value_type* _Ptr2) - { return _Str1.compare(_Ptr2) > 0; } - - friend bool operator>(const value_type* _Ptr1, const bkstring& _Str2) - { return _Str2.compare(_Ptr1) < 0; } - - friend bool operator<=(const bkstring& _Str1, const bkstring& _Str2) - { return _Str1.compare(_Str2) <= 0; } - - friend bool operator<=(const bkstring& _Str1, const value_type* _Ptr2) - { return _Str1.compare(_Ptr2) <= 0; } - - friend bool operator<=(const value_type* _Ptr1, const bkstring& _Str2) - { return _Str2.compare(_Ptr1) >= 0; } - - friend bool operator>=(const bkstring& _Str1, const bkstring& _Str2) - { return _Str1.compare(_Str2) >= 0; } - - friend bool operator>=(const bkstring& _Str1, const value_type* _Ptr2) - { return _Str1.compare(_Ptr2) >= 0; } - - friend bool operator>=(const value_type* _Ptr1, const bkstring& _Str2) - { return _Str2.compare(_Ptr1) <= 0; } - - friend bool operator==(const value_type _Ch1, const bkstring& _Str2) - { return (_Str2.size() == 1) && (_Str2[0] == _Ch1); } - - friend bool operator==(const bkstring& _Str1, const value_type _Ch2) - { return (_Str1.size() == 1) && (_Str1[0] == _Ch2); } - - friend bool operator!=(const value_type _Ch1, const bkstring& _Str2) - { return (_Str2.size() != 1) || (_Str2[0] != _Ch1); } - - friend bool operator!=(const bkstring& _Str1, const value_type _Ch2) - { return (_Str1.size() != 1) || (_Str1[0] != _Ch2); } - - iterator begin(void) - { return buf; } - - const_iterator begin(void) const - { return buf; } - - iterator end(void) - { return buf + lenBuf; } - - const_iterator end(void) const - { return buf + lenBuf; } - - // Custom extentions - - void appendfmt(const value_type *fmt, ...); - - size_type sizebytes(void) const { return lenBuf * sizeof(value_type); } -}; - -//const bkstring::size_type bkstring::npos = -1; - -#endif diff --git a/plugins/CrashDumper/crshdmp.cpp b/plugins/CrashDumper/crshdmp.cpp deleted file mode 100644 index 72ffac7f44..0000000000 --- a/plugins/CrashDumper/crshdmp.cpp +++ /dev/null @@ -1,434 +0,0 @@ -/* -Miranda Crash Dumper Plugin -Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "utils.h" -#include -#include "m_folders.h" -#include "m_toptoolbar.h" -#include "version.h" - -int hLangpack; - -HINSTANCE hInst; -DWORD mirandaVersion; -LCID packlcid; -HANDLE hCrashLogFolder, hVerInfoFolder; -HMODULE hRichModule; - -TCHAR* vertxt; -TCHAR* profname; -TCHAR* profpath; - -TCHAR CrashLogFolder[MAX_PATH]; -TCHAR VersionInfoFolder[MAX_PATH]; - -bool servicemode; -bool clsdates; -bool dtsubfldr; - -static const PLUGININFOEX pluginInfoEx = -{ - sizeof(PLUGININFOEX), - "Crash Dumper", - __VERSION_DWORD, - "Crash Dumper for Miranda IM.", - "borkra", - "borkra@miranda-im.org", - "Copyright© 2008 - 2012 Boris Krasnovskiy All Rights Reserved", - "http://code.google.com/p/mirandaimplugins/downloads/list", - UNICODE_AWARE, - // {F62C1D7A-FFA4-4065-A251-4C9DD9101CC8} - { 0xf62c1d7a, 0xffa4, 0x4065, { 0xa2, 0x51, 0x4c, 0x9d, 0xd9, 0x10, 0x1c, 0xc8 } } -}; - -const PLUGININFOEX* GetPluginInfoEx(void) { return &pluginInfoEx; } - - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirVersion) -{ - ::mirandaVersion = mirVersion; - return (PLUGININFOEX*)&pluginInfoEx; -} - -#define MIID_CRASHDUMP { 0x36a31a50, 0xcb55, 0x46d0, { 0xab, 0x9c, 0x1e, 0xac, 0xfb, 0x24, 0x0, 0x2a } } - -// MirandaInterfaces - returns the protocol interface to the core -extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_SERVICEMODE, MIID_CRASHDUMP, MIID_LAST }; - -HANDLE hHooks[5]; -HANDLE hServices[6]; - - -INT_PTR StoreVersionInfoToFile(WPARAM, LPARAM lParam) -{ - CreateDirectoryTree(VersionInfoFolder); - - TCHAR path[MAX_PATH]; - crs_sntprintf(path, MAX_PATH, TEXT("%s\\VersionInfo.txt"), VersionInfoFolder); - - HANDLE hDumpFile = CreateFile(path, GENERIC_WRITE, 0, NULL, - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - - if (hDumpFile != INVALID_HANDLE_VALUE) - { - bkstring buffer; - - buffer.reserve(0x1800); - PrintVersionInfo(buffer, (unsigned int)lParam | VI_FLAG_PRNVAR); - - char* bufu = mir_utf8encodeT(buffer.c_str()); - WriteUtfFile(hDumpFile, bufu); - mir_free(bufu); - - CloseHandle(hDumpFile); - - ShowMessage(3, TranslateT("VersionInfo stored into file %s"), path); - } - else - ShowMessage(2, TranslateT("VersionInfo file %s is inaccessible"), path); - - return 0; -} - -INT_PTR StoreVersionInfoToClipboard(WPARAM, LPARAM lParam) -{ - bkstring buffer; - buffer.reserve(0x1800); - - WriteBBFile(buffer, true); - PrintVersionInfo(buffer, (unsigned int)lParam | VI_FLAG_PRNVAR | VI_FLAG_FORMAT); - WriteBBFile(buffer, false); - - StoreStringToClip(buffer); - - return 0; -} - -INT_PTR UploadVersionInfo(WPARAM, LPARAM lParam) -{ - bkstring buffer; - buffer.reserve(0x1800); - PrintVersionInfo(buffer); - - VerTrnsfr *trn = (VerTrnsfr*)mir_alloc(sizeof(VerTrnsfr)); - trn->buf = mir_utf8encodeT(buffer.c_str()); - trn->autot = lParam == 0xa1; - - mir_forkthread(VersionInfoUploadThread, trn); - - return 0; -} - - -INT_PTR ViewVersionInfo(WPARAM wParam, LPARAM) -{ - // unsigned *p = (unsigned*)0x15; - // *p = 324; - - if (hRichModule == NULL && GetModuleHandle(TEXT("Riched20.dll")) == NULL) - hRichModule = LoadLibrary(TEXT("Riched20.dll")); - - CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_VIEWVERSION), NULL, - DlgProcView, wParam ? (VI_FLAG_PRNVAR | VI_FLAG_PRNDLL) : VI_FLAG_PRNVAR); - - return 0; -} - -INT_PTR OpenUrl(WPARAM wParam, LPARAM) -{ - switch (wParam) - { - case 0: - ShellExecute(NULL, TEXT("explore"), CrashLogFolder, NULL, NULL, SW_SHOW); - break; - - case 1: - OpenAuthUrl("http://%s.miranda-vi.org"); - break; - } - return 0; -} - -INT_PTR ServiceModeLaunch(WPARAM, LPARAM) -{ - servicemode = true; - return 0; -} - - -static int FoldersPathChanged(WPARAM, LPARAM) -{ - FOLDERSGETDATA fgd = {0}; - fgd.cbSize = sizeof(FOLDERSGETDATA); - fgd.nMaxPathSize = MAX_PATH; - fgd.szPathT = CrashLogFolder; - CallService(MS_FOLDERS_GET_PATH, (WPARAM) hCrashLogFolder, (LPARAM) &fgd); - - fgd.szPathT = VersionInfoFolder; - CallService(MS_FOLDERS_GET_PATH, (WPARAM) hVerInfoFolder, (LPARAM) &fgd); - return 0; -} - -int OptionsInit(WPARAM wParam, LPARAM) -{ - OPTIONSDIALOGPAGE odp = { 0 }; - - odp.cbSize = sizeof(odp); - odp.position = -790000000; - odp.hInstance = hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); - odp.pszTitle = (char*)PluginName; - odp.pszGroup = LPGEN("Services"); - odp.flags = ODPF_BOLDGROUPS; - odp.pfnDlgProc = DlgProcOptions; - Options_AddPage(wParam, &odp); - - return 0; -} - -static int ToolbarModulesLoaded(WPARAM, LPARAM) -{ - TTBButton tbb = {0}; - tbb.cbSize = sizeof(TTBButton); - - tbb.pszService = MS_CRASHDUMPER_STORETOCLIP; - tbb.name = tbb.pszTooltipUp = LPGEN("Version Information To Clipboard"); - tbb.hIconHandleUp = GetIconHandle("storeToClip"); - tbb.dwFlags = TTBBF_VISIBLE; - TopToolbar_AddButton(&tbb); - - tbb.pszService = MS_CRASHDUMPER_STORETOFILE; - tbb.name = tbb.pszTooltipUp = LPGEN("Version Information To File"); - tbb.hIconHandleUp = GetIconHandle("storeToFile"); - tbb.dwFlags = 0; - TopToolbar_AddButton(&tbb); - - tbb.pszService = MS_CRASHDUMPER_VIEWINFO; - tbb.name = tbb.pszTooltipUp = LPGEN("Show Version Information"); - tbb.hIconHandleUp = GetIconHandle("showInfo"); - TopToolbar_AddButton(&tbb); - - tbb.pszService = MS_CRASHDUMPER_UPLOAD; - tbb.name = tbb.pszTooltipUp = LPGEN("Upload Version Information"); - tbb.hIconHandleUp = GetIconHandle("uploadInfo"); - TopToolbar_AddButton(&tbb); - return 0; -} - -static int ModulesLoaded(WPARAM, LPARAM) -{ - char temp[MAX_PATH]; - CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM)SIZEOF(temp), (LPARAM)temp); - crs_a2t(vertxt, temp); - - profname = Utils_ReplaceVarsT(_T("%miranda_profilename%.dat")); - if (ServiceExists(MS_FOLDERS_REGISTER_PATH)) - { - profpath = _T("%miranda_userdata%"); - } - else - { - profpath = Utils_ReplaceVarsT(_T("%miranda_userdata%")); - } - - crs_sntprintf(CrashLogFolder, MAX_PATH, TEXT("%s\\CrashLog"), profpath); - crs_sntprintf(VersionInfoFolder, MAX_PATH, TEXT("%s"), profpath); - - SetExceptionHandler(); - - hCrashLogFolder = FoldersRegisterCustomPathT(PluginName, "Crash Reports", CrashLogFolder); - hVerInfoFolder = FoldersRegisterCustomPathT(PluginName, "Version Information", VersionInfoFolder); - - FoldersPathChanged(0, 0); - - - - hHooks[2] = HookEvent(ME_FOLDERS_PATH_CHANGED, FoldersPathChanged); - if (hHooks[3] == NULL) hHooks[3] = HookEvent(ME_TTB_MODULELOADED, ToolbarModulesLoaded); - - UploadInit(); - - CLISTMENUITEM mi = { 0 }; - - mi.cbSize = sizeof(mi); - - mi.popupPosition = 2000089999; - mi.position = 2000089999; - mi.flags = CMIF_ROOTPOPUP | CMIF_ICONFROMICOLIB | CMIF_TCHAR; - mi.icolibItem = GetIconHandle("versionInfo"); - mi.ptszName = LPGENT("Version Information"); - mi.pszPopupName = (char *)-1; - HANDLE hMenuRoot = Menu_AddMainMenuItem(&mi); - - mi.flags = CMIF_CHILDPOPUP | CMIF_ICONFROMICOLIB | CMIF_TCHAR; - mi.pszPopupName = (char *)hMenuRoot; - mi.popupPosition = 0; - - mi.position = 2000089995; - mi.ptszName = LPGENT("Copy to clipboard"); - mi.icolibItem = GetIconHandle("storeToClip"); - mi.pszService = MS_CRASHDUMPER_STORETOCLIP; - Menu_AddMainMenuItem(&mi); - - mi.position = 2000089996; - mi.ptszName = LPGENT("Store to file"); - mi.icolibItem = GetIconHandle("storeToFile"); - mi.pszService = MS_CRASHDUMPER_STORETOFILE; - Menu_AddMainMenuItem(&mi); - - mi.position = 2000089997; - mi.ptszName = LPGENT("Show"); - mi.icolibItem = GetIconHandle("showInfo"); - mi.pszService = MS_CRASHDUMPER_VIEWINFO; - Menu_AddMainMenuItem(&mi); - - mi.popupPosition = 1; - mi.position = 2000089998; - mi.ptszName = LPGENT("Show with DLLs"); - mi.icolibItem = GetIconHandle("showInfo"); - mi.pszService = MS_CRASHDUMPER_VIEWINFO; - Menu_AddMainMenuItem(&mi); - - mi.popupPosition = 0; - mi.position = 2000089999; - mi.ptszName = LPGENT("Upload"); - mi.icolibItem = GetIconHandle("uploadInfo"); - mi.pszService = MS_CRASHDUMPER_UPLOAD; - Menu_AddMainMenuItem(&mi); - - mi.position = 2000099990; - mi.ptszName = LPGENT("Open crash report directory"); - mi.icolibItem = LoadSkinnedIconHandle(SKINICON_EVENT_FILE); - mi.pszService = MS_CRASHDUMPER_URL; - Menu_AddMainMenuItem(&mi); - - mi.popupPosition = 1; - mi.position = 2000099991; - mi.ptszName = LPGENT("Open miranda-vi.org"); - mi.icolibItem = LoadSkinnedIconHandle(SKINICON_EVENT_URL); - mi.pszService = MS_CRASHDUMPER_URL; - Menu_AddMainMenuItem(&mi); - - HOTKEYDESC hk = {0}; - hk.cbSize = sizeof(hk); - hk.pszSection = PluginName; - - hk.pszDescription = LPGEN("Copy Version Info to clipboard"); - hk.pszName = "CopyVerInfo"; - hk.pszService = MS_CRASHDUMPER_STORETOCLIP; - Hotkey_Register(&hk); - - hk.pszDescription = LPGEN("Show Version Info"); - hk.pszName = "ShowVerInfo"; - hk.pszService = MS_CRASHDUMPER_VIEWINFO; - Hotkey_Register(&hk); - - if (servicemode) ViewVersionInfo(0, 0); - else - { - if (DBGetContactSettingByte(NULL, PluginName, "UploadChanged", 0) && !ProcessVIHash(false)) - UploadVersionInfo(0, 0xa1); - } - - CheckForOtherCrashReportingPlugins(); - return 0; -} - -static int PreShutdown(WPARAM, LPARAM) -{ - unsigned i; - - DestroyAllWindows(); - UploadClose(); - - for (i=0; i - - - - - - - - + + + + + + + + - - - - - + + + + + - - - - - - - - - + + diff --git a/plugins/CrashDumper/crshdmp_icons.cpp b/plugins/CrashDumper/crshdmp_icons.cpp deleted file mode 100644 index 1f7106303f..0000000000 --- a/plugins/CrashDumper/crshdmp_icons.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* -Miranda Crash Dumper Plugin -Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "utils.h" -#include - -struct _tag_iconList -{ - const char* szDescr; - const char* szName; - int defIconID; -} -static const iconList[] = -{ - { "Version Information", "versionInfo", IDI_VI }, - { "Copy To Clipboard", "storeToClip", IDI_VITOCLIP }, - { "Store to file", "storeToFile", IDI_VITOFILE }, - { "Show", "showInfo", IDI_VISHOW }, - { "Upload", "uploadInfo", IDI_VIUPLOAD }, -}; - -static HANDLE hIconLibItem[SIZEOF(iconList)]; - -void InitIcons(void) -{ - char szFile[MAX_PATH]; - char szSettingName[100]; - SKINICONDESC sid = {0}; - - sid.cbSize = sizeof(SKINICONDESC); - sid.pszDefaultFile = szFile; - sid.pszName = szSettingName; - sid.pszSection = (char*)PluginName; - - GetModuleFileNameA(hInst, szFile, MAX_PATH); - - for (unsigned i = 0; i < SIZEOF(iconList); i++) - { - mir_snprintf(szSettingName, sizeof(szSettingName), "%s_%s", PluginName, iconList[i].szName); - - sid.pszDescription = (char*)iconList[i].szDescr; - sid.iDefaultIndex = -iconList[i].defIconID; - hIconLibItem[i] = Skin_AddIcon(&sid); - } -} - -HICON LoadIconEx(const char* name, bool big) -{ - char szSettingName[100]; - mir_snprintf(szSettingName, sizeof(szSettingName), "%s_%s", PluginName, name); - return (HICON)CallService(MS_SKIN2_GETICON, big, (LPARAM)szSettingName); -} - -HANDLE GetIconHandle(const char* name) -{ - unsigned i; - for (i=0; i < SIZEOF(iconList); i++) - if (strcmp(iconList[i].szName, name) == 0) - return hIconLibItem[i]; - return NULL; -} - -void ReleaseIconEx(const char* name) -{ - char szSettingName[100]; - mir_snprintf(szSettingName, sizeof(szSettingName), "%s_%s", PluginName, name); - CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM)szSettingName); -} - -void ReleaseIconEx(HICON hIcon) -{ - CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0); -} diff --git a/plugins/CrashDumper/crshdmp_readme.txt b/plugins/CrashDumper/crshdmp_readme.txt deleted file mode 100644 index f4e1ff92ac..0000000000 --- a/plugins/CrashDumper/crshdmp_readme.txt +++ /dev/null @@ -1,379 +0,0 @@ -Crash Dumper plugin for Miranda IM -===================================================================== -Plugin creates usable Crash Report and Version Information for Miranda IM - -When Miranda crashes plugin ptrovides: -- text representation of crash report -- MiniDump representation of crash report - -On demand plugin provides Version Information report -On demand uploads VersionInfo report to www.miranda-vi.org - -VersionInfo report includes: - -- OS Version information -- Internet Explorer version information -- Miranda version information with build date -- Miranda profile used -- Loaded Miranda plugin list with versions -- Loaded language pack version -- Loaded weather ini files -- Created protocols accounts - -Files stored in {Miranda Profile}\CrashLog directory - -Text version of crash report includes: - -- Guess for plugin responsible for the crash (it printed in the report) -- Stack trace for exception (with function names, source file names - and line numbers, if possible) -- Version Information (see above) -- Loaded modules (dlls) list -- Plugin lists all information you need to submit crash report for Miranda -- Loaded weather ini files - -Plugin works with all current Operating Systems. - -It could be downloaded here: -ANSI: http://addons.miranda-im.org/details.php?action=viewfile&id=3695 -Unicode: http://addons.miranda-im.org/details.php?action=viewfile&id=3806 -x64: http://addons.miranda-im.org/details.php?action=viewfile&id=4114 -All: http://code.google.com/p/mirandaimplugins/downloads/list - -Win9x, WinNT users required to install dbghelp.dll v 5.0 or later. -dbghelp.dll v 5.0 is available here: -http://www.microsoft.com/downloads/details.aspx?FamilyID=cd1fc4b2-0885-47f4-af45-7fd5e14db6c0&DisplayLang=en - - -Author: Boris Krasnovskiy (borkra) - -Licensing terms could be found below. - -Change Log -========== - -0.0.4.20 --------- -Added Windows 8 detection - -0.0.4.19 --------- -Improved reporting for MS RTL failures -Fixes for translation - -0.0.4.18 --------- -Renamed Hotkeys, added Hotkey to open message window -Added support for 32x32 icons -Added proper display of Miranda 0.9 profile path - -0.0.4.17 --------- -Removed option to ignore crashes that do not cause Miranda to close -Improved protocol reporting -Fixed TopToolbar buttons no show -Added proper handling of Crash Dumper late exit in Miranda 0.9 - -0.0.4.16 --------- -Added icon pack reporting -Fixed toolbar button for storing to file - -0.0.4.14 --------- -Fixed options dialog -Changed bug reporting message to popup - -0.0.4.13 --------- -Changed option to notify only about crashes that stop Miranda -Fixed bug reporting menu - -0.0.4.12 --------- -Improved accounts reporting -Fixed error messages about inability to store crash report -Added option to disable crash reporting function -Added coping VI into clipboard on Report Bug menu item - -0.0.4.11 --------- -Allow creating crash report with dbghelp.dll v5.0 -(this adds support for creating crash reports on Windows 95 with extra dbghelp.dll -and on Windows 2000 with built-in dbghelp.dll) - -0.0.4.10 --------- -Fixed bbcodes for Weather ini -x64 portability -Windows 95 compatibility -Fixed crash in service mode - -0.0.4.9 --------- -Printing weather only if weather plugin present -Changed alternative date format -Fixed langpack display when non ANSI chars used in the description -Fixed crash in debug version -Fixed langpack display when locale id is bogus -Changed stored file format to UTF-8 -Added opening generated version info file on popup click - -0.0.4.8 --------- -Changed upload to miranda-vi.org to unicode -Added Windows 7 & Windows Server 2008 R2 detection -Added Weather ini files reporting -Changed Accounts reporting to list enabled and disabled accounts -Changed VI display font to Courier New - -0.0.4.7 --------- -Made message boxes the topmost window -Added Protocols and Accounts printout - -0.0.4.6 --------- -Attempt to reduce no-report conditions - -0.0.4.5 --------- -Added icons to menu items -Added storing crash report in clipboard only by request -Added base address display to VI with DLLs -Fixed buttons in VI view when show VI with DLL - -0.0.4.4 --------- -Added menu item to open crash log folder in explorer -Added menu item to open miranda-vi.org in web browser -Added automatic login into miranda-vi when open in web browser through Miranda -Added option to display date and time in "traditional" format for all reports - -0.0.4.3 --------- -Removed Trap all exceptions option - -0.0.4.2 --------- -Added caution note to Trap All Exceptions option -Restored compatibility of Crash Dumper Unicode with dbghelp.dll distributed with XP -Disabled on startup Trap All Exceptions option on pre Vista OSes - -0.0.4.1 --------- -Fixed crash in Trap all possible exceptions mode - -0.0.4.0 --------- -Fixed crash on VI upload -Modified unicode handling -Fixed memory leak -Added option to trap all possible exceptions -Added ability to provide crash reports for crashes in Miranda threads in 0.8 #19 and higher -Added Unicode version distribution - -0.0.3.4 --------- -Added storing version Information to file to top toolbar -Added storing crash report to clipboard -Attempt to resolve crashes with no report - -0.0.3.3 --------- -Fix for crash while generating crash report - -0.0.3.2 --------- -Added VersionInfo buttons to clist_modern toolbar -Fixed crash when dbghelp not installed or wrong version - -0.0.3.0 --------- -Added option to printout all loaded DLLs as VI -Added printout of dll version and date to dll list - -0.0.2.8 --------- -Fixed crash with Wine -Added MessageBox with location of Crash Report after every crash - -0.0.2.7 --------- -Fixed crash with debughlp.dll not available -Fixed unloadable dll diagnostics -Fixed Show VersionInfo under Win9x - -0.0.2.6 --------- -Fixed translation - -0.0.2.5 --------- -Improved diagnostics for unloadable dlls -Fixed unloading dbghelp when not needed -Fixed spelling - -0.0.2.4 --------- -Improved chances of getting crash report for some crashes - -0.0.2.3 --------- -Fixed unloadable plugin display -Improvements in notifications - -0.0.2.2 --------- -Added unloadable plugin display in VI -Fixed VI Show under Windows 9x - -0.0.2.1 --------- -Clarification in options text -Open global compare url on popup click after successful upload -Added outdated plugin indication after successful upload -Moved all db settings onto one group - -0.0.2.0 --------- -Fixed icolib support -Added new icons by Angeli-Ka -Added printout for profile creation date and size -Added VersionInfo uploading to www.miranda-vi.org -Removed interface to VIUploader plugin - -0.0.1.4 --------- -Fixed BBCode for uploaded VI - -0.0.1.3 --------- -Fixed BBCode formatting -Added BBCode to uploaded VI -Added country code to language pack info -Added possibility to add icons for menu items through icolib - -0.0.1.2 --------- -Fixed Folders support - -0.0.1.1 --------- -More robustness updates - -0.0.1.0 --------- -Fixed crashes during VersionInfo reporting -More lang pack info -Moved plugin causing crash reporting earlier - -0.0.0.13 --------- -More fixes to plugin sorting - -0.0.0.12 --------- -Made plugin sorting case insensitive - -0.0.0.11 --------- -Added WOW64 printout -Fixed VIUploader interface -Added explicit plugin sorting - -0.0.0.10 --------- -Changed printed timestamp -Merged profilename and path -Capturing only unhandled crashes - -0.0.0.9 -------- -Added protection against infinite exception loops -Fixed printing VersionInfo to file -Added context menu for VersionInfo window - -0.0.0.8 -------- -Fixed operation in service mode -Fixed inability to create crash report -Added ability to provide reports when multiple crash report plugins installed (only on XP or later) -Added notification when multiple crash reporting plugins installed -(as this causes conflict among plugins and inability to create crash reports) - -0.0.0.7 -------- -Changed all timestamps to ISO 8061:2004 format -Added keeping of window sizing & position -Changed preview window color -VersionInfo stored in profile directory by default -Added more formatting to VersionInfo -Added service mode support (dll name changed) - -0.0.0.6 -------- -Fixed storing VersionInfo to file -Added ui to show VersionInfo -Added service to retrieve VersionInfo - -0.0.0.5 -------- -Fixed crash reports with older dbghelp.dll -Added Folders plugin support -Added more VersionInfo reporting -Added VersionInfo storage (to file and clipboard) -Improved report formatting -Added ability to get VersionInfo by hotkey - -0.0.0.4 -------- -Added human readable exception code -Added complete description for access violation -Updated sources to compile with older PSDK -More VersionInfo related stuff - -0.0.0.3 -------- -Added reporting for Internet Explorer version -Added reporting for plugin Unicode capability -Added reporting for Miranda profile path and name -Added reporting for miranda.exe build date - -0.0.0.2 -------- -Reduced resource utilization -Allow Unicode compilation - -0.0.0.1 -------- -Initial release of the plugin - - -Miranda IM -========== -Miranda IM is an open source instant messenger framework that -support plugins for many different networks; ICQ, MSN, YAHOO -AIM to mention a few (but not all). Get it at: -http://www.miranda-im.org/ - - -Copyright and license -===================== - -Software: - -Copyright (C) 2008 - 2010 Boris Krasnovskiy All Rights Reserved - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . diff --git a/plugins/CrashDumper/docs/crshdmp_readme.txt b/plugins/CrashDumper/docs/crshdmp_readme.txt new file mode 100644 index 0000000000..f4e1ff92ac --- /dev/null +++ b/plugins/CrashDumper/docs/crshdmp_readme.txt @@ -0,0 +1,379 @@ +Crash Dumper plugin for Miranda IM +===================================================================== +Plugin creates usable Crash Report and Version Information for Miranda IM + +When Miranda crashes plugin ptrovides: +- text representation of crash report +- MiniDump representation of crash report + +On demand plugin provides Version Information report +On demand uploads VersionInfo report to www.miranda-vi.org + +VersionInfo report includes: + +- OS Version information +- Internet Explorer version information +- Miranda version information with build date +- Miranda profile used +- Loaded Miranda plugin list with versions +- Loaded language pack version +- Loaded weather ini files +- Created protocols accounts + +Files stored in {Miranda Profile}\CrashLog directory + +Text version of crash report includes: + +- Guess for plugin responsible for the crash (it printed in the report) +- Stack trace for exception (with function names, source file names + and line numbers, if possible) +- Version Information (see above) +- Loaded modules (dlls) list +- Plugin lists all information you need to submit crash report for Miranda +- Loaded weather ini files + +Plugin works with all current Operating Systems. + +It could be downloaded here: +ANSI: http://addons.miranda-im.org/details.php?action=viewfile&id=3695 +Unicode: http://addons.miranda-im.org/details.php?action=viewfile&id=3806 +x64: http://addons.miranda-im.org/details.php?action=viewfile&id=4114 +All: http://code.google.com/p/mirandaimplugins/downloads/list + +Win9x, WinNT users required to install dbghelp.dll v 5.0 or later. +dbghelp.dll v 5.0 is available here: +http://www.microsoft.com/downloads/details.aspx?FamilyID=cd1fc4b2-0885-47f4-af45-7fd5e14db6c0&DisplayLang=en + + +Author: Boris Krasnovskiy (borkra) + +Licensing terms could be found below. + +Change Log +========== + +0.0.4.20 +-------- +Added Windows 8 detection + +0.0.4.19 +-------- +Improved reporting for MS RTL failures +Fixes for translation + +0.0.4.18 +-------- +Renamed Hotkeys, added Hotkey to open message window +Added support for 32x32 icons +Added proper display of Miranda 0.9 profile path + +0.0.4.17 +-------- +Removed option to ignore crashes that do not cause Miranda to close +Improved protocol reporting +Fixed TopToolbar buttons no show +Added proper handling of Crash Dumper late exit in Miranda 0.9 + +0.0.4.16 +-------- +Added icon pack reporting +Fixed toolbar button for storing to file + +0.0.4.14 +-------- +Fixed options dialog +Changed bug reporting message to popup + +0.0.4.13 +-------- +Changed option to notify only about crashes that stop Miranda +Fixed bug reporting menu + +0.0.4.12 +-------- +Improved accounts reporting +Fixed error messages about inability to store crash report +Added option to disable crash reporting function +Added coping VI into clipboard on Report Bug menu item + +0.0.4.11 +-------- +Allow creating crash report with dbghelp.dll v5.0 +(this adds support for creating crash reports on Windows 95 with extra dbghelp.dll +and on Windows 2000 with built-in dbghelp.dll) + +0.0.4.10 +-------- +Fixed bbcodes for Weather ini +x64 portability +Windows 95 compatibility +Fixed crash in service mode + +0.0.4.9 +-------- +Printing weather only if weather plugin present +Changed alternative date format +Fixed langpack display when non ANSI chars used in the description +Fixed crash in debug version +Fixed langpack display when locale id is bogus +Changed stored file format to UTF-8 +Added opening generated version info file on popup click + +0.0.4.8 +-------- +Changed upload to miranda-vi.org to unicode +Added Windows 7 & Windows Server 2008 R2 detection +Added Weather ini files reporting +Changed Accounts reporting to list enabled and disabled accounts +Changed VI display font to Courier New + +0.0.4.7 +-------- +Made message boxes the topmost window +Added Protocols and Accounts printout + +0.0.4.6 +-------- +Attempt to reduce no-report conditions + +0.0.4.5 +-------- +Added icons to menu items +Added storing crash report in clipboard only by request +Added base address display to VI with DLLs +Fixed buttons in VI view when show VI with DLL + +0.0.4.4 +-------- +Added menu item to open crash log folder in explorer +Added menu item to open miranda-vi.org in web browser +Added automatic login into miranda-vi when open in web browser through Miranda +Added option to display date and time in "traditional" format for all reports + +0.0.4.3 +-------- +Removed Trap all exceptions option + +0.0.4.2 +-------- +Added caution note to Trap All Exceptions option +Restored compatibility of Crash Dumper Unicode with dbghelp.dll distributed with XP +Disabled on startup Trap All Exceptions option on pre Vista OSes + +0.0.4.1 +-------- +Fixed crash in Trap all possible exceptions mode + +0.0.4.0 +-------- +Fixed crash on VI upload +Modified unicode handling +Fixed memory leak +Added option to trap all possible exceptions +Added ability to provide crash reports for crashes in Miranda threads in 0.8 #19 and higher +Added Unicode version distribution + +0.0.3.4 +-------- +Added storing version Information to file to top toolbar +Added storing crash report to clipboard +Attempt to resolve crashes with no report + +0.0.3.3 +-------- +Fix for crash while generating crash report + +0.0.3.2 +-------- +Added VersionInfo buttons to clist_modern toolbar +Fixed crash when dbghelp not installed or wrong version + +0.0.3.0 +-------- +Added option to printout all loaded DLLs as VI +Added printout of dll version and date to dll list + +0.0.2.8 +-------- +Fixed crash with Wine +Added MessageBox with location of Crash Report after every crash + +0.0.2.7 +-------- +Fixed crash with debughlp.dll not available +Fixed unloadable dll diagnostics +Fixed Show VersionInfo under Win9x + +0.0.2.6 +-------- +Fixed translation + +0.0.2.5 +-------- +Improved diagnostics for unloadable dlls +Fixed unloading dbghelp when not needed +Fixed spelling + +0.0.2.4 +-------- +Improved chances of getting crash report for some crashes + +0.0.2.3 +-------- +Fixed unloadable plugin display +Improvements in notifications + +0.0.2.2 +-------- +Added unloadable plugin display in VI +Fixed VI Show under Windows 9x + +0.0.2.1 +-------- +Clarification in options text +Open global compare url on popup click after successful upload +Added outdated plugin indication after successful upload +Moved all db settings onto one group + +0.0.2.0 +-------- +Fixed icolib support +Added new icons by Angeli-Ka +Added printout for profile creation date and size +Added VersionInfo uploading to www.miranda-vi.org +Removed interface to VIUploader plugin + +0.0.1.4 +-------- +Fixed BBCode for uploaded VI + +0.0.1.3 +-------- +Fixed BBCode formatting +Added BBCode to uploaded VI +Added country code to language pack info +Added possibility to add icons for menu items through icolib + +0.0.1.2 +-------- +Fixed Folders support + +0.0.1.1 +-------- +More robustness updates + +0.0.1.0 +-------- +Fixed crashes during VersionInfo reporting +More lang pack info +Moved plugin causing crash reporting earlier + +0.0.0.13 +-------- +More fixes to plugin sorting + +0.0.0.12 +-------- +Made plugin sorting case insensitive + +0.0.0.11 +-------- +Added WOW64 printout +Fixed VIUploader interface +Added explicit plugin sorting + +0.0.0.10 +-------- +Changed printed timestamp +Merged profilename and path +Capturing only unhandled crashes + +0.0.0.9 +------- +Added protection against infinite exception loops +Fixed printing VersionInfo to file +Added context menu for VersionInfo window + +0.0.0.8 +------- +Fixed operation in service mode +Fixed inability to create crash report +Added ability to provide reports when multiple crash report plugins installed (only on XP or later) +Added notification when multiple crash reporting plugins installed +(as this causes conflict among plugins and inability to create crash reports) + +0.0.0.7 +------- +Changed all timestamps to ISO 8061:2004 format +Added keeping of window sizing & position +Changed preview window color +VersionInfo stored in profile directory by default +Added more formatting to VersionInfo +Added service mode support (dll name changed) + +0.0.0.6 +------- +Fixed storing VersionInfo to file +Added ui to show VersionInfo +Added service to retrieve VersionInfo + +0.0.0.5 +------- +Fixed crash reports with older dbghelp.dll +Added Folders plugin support +Added more VersionInfo reporting +Added VersionInfo storage (to file and clipboard) +Improved report formatting +Added ability to get VersionInfo by hotkey + +0.0.0.4 +------- +Added human readable exception code +Added complete description for access violation +Updated sources to compile with older PSDK +More VersionInfo related stuff + +0.0.0.3 +------- +Added reporting for Internet Explorer version +Added reporting for plugin Unicode capability +Added reporting for Miranda profile path and name +Added reporting for miranda.exe build date + +0.0.0.2 +------- +Reduced resource utilization +Allow Unicode compilation + +0.0.0.1 +------- +Initial release of the plugin + + +Miranda IM +========== +Miranda IM is an open source instant messenger framework that +support plugins for many different networks; ICQ, MSN, YAHOO +AIM to mention a few (but not all). Get it at: +http://www.miranda-im.org/ + + +Copyright and license +===================== + +Software: + +Copyright (C) 2008 - 2010 Boris Krasnovskiy All Rights Reserved + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/plugins/CrashDumper/docs/svc_crshdmp-translation.txt b/plugins/CrashDumper/docs/svc_crshdmp-translation.txt new file mode 100644 index 0000000000..18d251f699 --- /dev/null +++ b/plugins/CrashDumper/docs/svc_crshdmp-translation.txt @@ -0,0 +1,54 @@ +; Common strings that belong to many files +;[] + +; ../../plugins/Svc_crshdmp/crshdmp.cpp +;[Copy Version Info to clipboard] +;[Copy to clipboard] +;[Open crash report directory] +;[Open miranda-vi.org] +;[Services] +;[Show] +;[Show Version Info] +;[Show Version Information] +;[Show with DLLs] +;[Store to file] +;[Upload] +;[Upload Version Information] +;[Version Information] +;[Version Information To Clipboard] +;[Version Information To File] +;[VersionInfo file %s is inaccessible] +;[VersionInfo stored into file %s] + +; ../../plugins/Svc_crshdmp/crshdmp.rc +;[&Copy] +;[Close] +;[Co&py All] +;[Copy To Clipboard] +;[Create reports in subfolders naming as current date] +;[General] +;[Password] +;[Select &All] +;[Support for miranda-vi.org] +;[To File] +;[Upload automatically when changed] +;[Use classic dates] +;[Username] +;[View] +;[View Version Information ] + +; ../../plugins/Svc_crshdmp/exhndlr.cpp +;[Crash Report write location is inaccesible] +;[Miranda crashed. Crash report stored in the folder:\n %s\n\n Would you like store it in the clipboard as well?] + +; ../../plugins/Svc_crshdmp/upload.cpp +;[Cannot upload VersionInfo. Daily upload limit exceeded] +;[Cannot upload VersionInfo. Host unreachable.] +;[Cannot upload VersionInfo. Incorrect username or password] +;[Cannot upload VersionInfo. Unknown error] +;[Cannot upload VersionInfo. User is banned] +;[Crash Dumper HTTP connections] +;[VersionInfo upload successful,\n %d old plugins] + +; ../../plugins/Svc_crshdmp/utils.cpp +;[More then one crash reporting plugin installed. This will result in inability of creating crash reports] diff --git a/plugins/CrashDumper/dumper.cpp b/plugins/CrashDumper/dumper.cpp deleted file mode 100644 index bae091a023..0000000000 --- a/plugins/CrashDumper/dumper.cpp +++ /dev/null @@ -1,745 +0,0 @@ -/* -Miranda Crash Dumper Plugin -Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "utils.h" - -extern TCHAR* vertxt; -extern TCHAR* profname; -extern TCHAR* profpath; - - -void CreateMiniDump(HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr) -{ - MINIDUMP_EXCEPTION_INFORMATION exceptionInfo; - exceptionInfo.ThreadId = GetCurrentThreadId(); - exceptionInfo.ExceptionPointers = exc_ptr; - exceptionInfo.ClientPointers = false; - - MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), - hDumpFile, MiniDumpNormal, &exceptionInfo, NULL, NULL); -} - - -void WriteBBFile(bkstring& buffer, bool hdr) -{ - static const TCHAR header[] = TEXT("[quote][size=1]"); - static const TCHAR footer[] = TEXT("[/size][/quote]"); - - buffer.append(hdr ? header : footer); -} - - -void WriteUtfFile(HANDLE hDumpFile, char* bufu) -{ - DWORD bytes; - - static const unsigned char bytemark[] = { 0xEF, 0xBB, 0xBF }; - WriteFile(hDumpFile, bytemark, 3, &bytes, NULL); - WriteFile(hDumpFile, bufu, (DWORD)strlen(bufu), &bytes, NULL); -} - - -BOOL CALLBACK LoadedModules64(LPCSTR, DWORD64 ModuleBase, ULONG ModuleSize, PVOID UserContext) -{ - bkstring& buffer = *(bkstring*)UserContext; - - const HMODULE hModule = (HMODULE)ModuleBase; - - TCHAR path[MAX_PATH]; - GetModuleFileName(hModule, path, MAX_PATH); - - buffer.appendfmt(TEXT("%s %p - %p"), path, (LPVOID)ModuleBase, (LPVOID)(ModuleBase + ModuleSize)); - - GetVersionInfo(hModule, buffer); - - TCHAR timebuf[30] = TEXT(""); - GetLastWriteTime(path, timebuf, 30); - - buffer.appendfmt(TEXT(" [%s]\r\n"), timebuf); - - return TRUE; -} - -typedef struct _FindData -{ - DWORD64 Offset; IMAGEHLP_MODULE64* pModule; -} FindData; - - -BOOL CALLBACK LoadedModulesFind64(LPCSTR ModuleName, DWORD64 ModuleBase, ULONG ModuleSize, PVOID UserContext) -{ - FindData* data = (FindData*)UserContext; - - if ((DWORD)(data->Offset - ModuleBase) < ModuleSize) - { - const size_t len = SIZEOF(data->pModule->ModuleName); - strncpy(data->pModule->ModuleName, ModuleName, len); - data->pModule->ModuleName[len-1] = 0; - - data->pModule->BaseOfImage = ModuleBase; - - const HMODULE hModule = (HMODULE)ModuleBase; - GetModuleFileNameA(hModule, data->pModule->LoadedImageName, SIZEOF(data->pModule->LoadedImageName)); - - return FALSE; - } - return TRUE; -} - - -void GetLinkedModulesInfo(TCHAR *moduleName, bkstring &buffer) -{ - HANDLE hDllFile = CreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (hDllFile == INVALID_HANDLE_VALUE) return; - - HANDLE hDllMapping = CreateFileMapping(hDllFile, NULL, PAGE_READONLY, 0, 0, NULL); - if (hDllMapping == INVALID_HANDLE_VALUE) - { - CloseHandle(hDllFile); - return; - } - - LPVOID dllAddr = MapViewOfFile(hDllMapping, FILE_MAP_READ, 0, 0, 0); - - - static const TCHAR format[] = TEXT(" Plugin statically linked to missing module: %S\r\n"); - - - __try - { - PIMAGE_NT_HEADERS nthdrs = ImageNtHeader(dllAddr); - - ULONG tableSize; - PIMAGE_IMPORT_DESCRIPTOR importData = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(dllAddr, FALSE, - IMAGE_DIRECTORY_ENTRY_IMPORT, &tableSize); - if (importData) - { - while (importData->Name) - { - char* moduleName = (char*)ImageRvaToVa(nthdrs, dllAddr, importData->Name, NULL); - if (!SearchPathA(NULL, moduleName, NULL, NULL, 0, NULL)) - { - buffer.appendfmt(format, moduleName); - } - importData++; //go to next record - } - } - - bool found = false; - PIMAGE_EXPORT_DIRECTORY exportData = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(dllAddr, FALSE, - IMAGE_DIRECTORY_ENTRY_EXPORT, &tableSize); - if (exportData) - { - ULONG* funcAddr = (ULONG*)ImageRvaToVa(nthdrs, dllAddr, exportData->AddressOfNames, NULL); - for(unsigned i=0; iNumberOfNames && !found; ++i) - { - char* funcName = (char*)ImageRvaToVa(nthdrs, dllAddr, funcAddr[i], NULL); - found = strcmp(funcName, "MirandaPluginInfoEx") == 0 || strcmp(funcName, "MirandaPluginInfo") == 0; - if (strcmp(funcName, "DatabasePluginInfo") == 0) - { - buffer.append(TEXT(" This dll is a Miranda database plugin, another database is active right now\r\n")); - found = true; - } - } - } - if (!found) - buffer.append(TEXT(" This dll is not a Miranda plugin and should be removed from plugins directory\r\n")); - } - __except(EXCEPTION_EXECUTE_HANDLER) {} - - UnmapViewOfFile(dllAddr); - CloseHandle(hDllMapping); - CloseHandle(hDllFile); -} - - -struct ListItem -{ - ListItem() : str(), next(NULL) {} - - bkstring str; - ListItem *next; -}; - -static void GetPluginsString(bkstring& buffer, unsigned& flags) -{ - buffer.appendfmt(TEXT("Service Mode: %s\r\n"), servicemode ? TEXT("Yes") : TEXT("No")); - - TCHAR path[MAX_PATH]; - GetModuleFileName(NULL, path, MAX_PATH); - - LPTSTR fname = _tcsrchr(path, TEXT('\\')); - if (fname == NULL) fname = path; - crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\plugins\\*.dll")); - - WIN32_FIND_DATA FindFileData; - HANDLE hFind = FindFirstFile(path, &FindFileData); - if (hFind == INVALID_HANDLE_VALUE) return; - - size_t count = 0, ucount = 0; - - bkstring ubuffer; - ListItem* dlllist = NULL; - - - static const TCHAR format[] = TEXT("%c %s v.%s%d.%d.%d.%d%s [%s] - %S %s\r\n"); - - - do - { - bool loaded = false; - crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\plugins\\%s"), FindFileData.cFileName); - HMODULE hModule = GetModuleHandle(path); - if (hModule == NULL && servicemode) - { - hModule = LoadLibrary(path); - loaded = true; - } - if (hModule == NULL) - { - if ((flags & VI_FLAG_PRNVAR) && IsPluginEnabled(FindFileData.cFileName)) - { - TCHAR timebuf[30] = TEXT(""); - GetLastWriteTime(&FindFileData.ftLastWriteTime, timebuf, 30); - - ubuffer.appendfmt(format, TEXT(' '), FindFileData.cFileName, - (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), - 0, 0, 0, 0, - (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""), - timebuf, "", TEXT("")); - - GetLinkedModulesInfo(path, ubuffer); - ubuffer.append(TEXT("\r\n")); - - ++ucount; - } - continue; - } - - PLUGININFOEX* pi = GetMirInfo(hModule); - if (pi != NULL) - { - TCHAR timebuf[30] = TEXT(""); - GetLastWriteTime(&FindFileData.ftLastWriteTime, timebuf, 30); - - bool ep = (size_t)pi->cbSize > sizeof(PLUGININFOEX); - const TCHAR *unica = (ep && ((PLUGININFOEX*)pi)->flags & 1) ? TEXT("|Unicode aware|") : TEXT(""); - - ListItem* lst = new ListItem; - DWORD ver = pi->version; - lst->str.appendfmt(format, ep ? TEXT('\xa4') : TEXT(' '), FindFileData.cFileName, - (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), - HIBYTE(HIWORD(ver)), LOBYTE(HIWORD(ver)), HIBYTE(LOWORD(ver)), LOBYTE(LOWORD(ver)), - (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""), - timebuf, pi->shortName ? pi->shortName : "", unica); - - ListItem* lsttmp = dlllist; - ListItem* lsttmppv = NULL; - while (lsttmp != NULL) - { - size_t sz = min(lsttmp->str.size(), lst->str.size()) - 2; - if (lsttmp->str.comparei(2, sz, lst->str, 2, sz) > 0) break; - lsttmppv = lsttmp; - lsttmp = lsttmp->next; - } - lst->next = lsttmp; - if (lsttmppv == NULL) - dlllist = lst; - else - lsttmppv->next = lst; - - if (_tcsicmp(FindFileData.cFileName, TEXT("weather.dll")) == 0) - flags |= VI_FLAG_WEATHER; - - ++count; - } - if (loaded) FreeLibrary(hModule); - } - while (FindNextFile(hFind, &FindFileData)); - FindClose(hFind); - - buffer.appendfmt(TEXT("\r\n%sActive Plugins (%u):%s\r\n"), - (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), count, (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT("")); - - ListItem* lsttmp = dlllist; - while (lsttmp != NULL) - { - buffer.append(lsttmp->str); - ListItem* lsttmp1 = lsttmp->next; - delete lsttmp; - lsttmp = lsttmp1; - } - - if (ucount) - { - buffer.appendfmt(TEXT("\r\n%sUnloadable Plugins (%u):%s\r\n"), - (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), ucount, (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT("")); - buffer.append(ubuffer); - } -} - - -struct ProtoCount -{ - char countse; - char countsd; - bool nloaded; -}; - -static void GetProtocolStrings(bkstring& buffer) -{ - PROTOACCOUNT **accList; - int accCount, protoCount; - int i, j; - - PROTOCOLDESCRIPTOR **protoList; - if (ProtoEnumAccounts(&accCount, &accList) == CALLSERVICE_NOTFOUND || (accCount > 0 && accList[0]->cbSize == 0)) - { - CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&protoCount, (LPARAM)&protoList); - for (i = 0; i < protoCount; i++) - { - if (protoList[i]->type != PROTOTYPE_PROTOCOL) continue; - - TCHAR* nm; - crsi_a2t(nm, protoList[i]->szName); - buffer.appendfmt(TEXT(" 1 - %s\r\n"), nm); - } - } - else - { - CallService(MS_PROTO_ENUMPROTOS, (WPARAM)&protoCount, (LPARAM)&protoList); - - int protoCountMy = 0; - char** protoListMy = (char**)alloca((protoCount + accCount) * sizeof(char*)); - - for (i = 0; i < protoCount; i++) - { - if (protoList[i]->type != PROTOTYPE_PROTOCOL) continue; - protoListMy[protoCountMy++] = protoList[i]->szName; - } - - for (j = 0; j < accCount; j++) - { - for (i = 0; i < protoCountMy; i++) - { - if (strcmp(protoListMy[i], accList[j]->szProtoName) == 0) - break; - } - if (i == protoCountMy) - protoListMy[protoCountMy++] = accList[j]->szProtoName; - } - - ProtoCount *protos = (ProtoCount*)alloca(sizeof(ProtoCount) * protoCountMy); - memset(protos, 0, sizeof(ProtoCount) * protoCountMy); - - for (j = 0; j < accCount; j++) - { - for (i = 0; i < protoCountMy; i++) - { - if (strcmp(protoListMy[i], accList[j]->szProtoName) == 0) - { - protos[i].nloaded = accList[j]->bDynDisabled != 0; - if (IsAccountEnabled(accList[j])) - ++protos[i].countse; - else - ++protos[i].countsd; - break; - } - } - } - for (i = 0; i < protoCountMy; i++) - { - TCHAR* nm; - crsi_a2t(nm, protoListMy[i]); - buffer.appendfmt(TEXT("%-24s %d - Enabled %d - Disabled %sLoaded\r\n"), nm, protos[i].countse, - protos[i].countsd, protos[i].nloaded ? _T("Not ") : _T("")); - } - } -} - - -static void GetWeatherStrings(bkstring& buffer, unsigned flags) -{ - TCHAR path[MAX_PATH]; - GetModuleFileName(NULL, path, MAX_PATH); - - LPTSTR fname = _tcsrchr(path, TEXT('\\')); - if (fname == NULL) fname = path; - crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\plugins\\weather\\*.ini")); - - WIN32_FIND_DATA FindFileData; - HANDLE hFind = FindFirstFile(path, &FindFileData); - if (hFind == INVALID_HANDLE_VALUE) return; - - do - { - if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; - - crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\plugins\\weather\\%s"), FindFileData.cFileName); - HANDLE hDumpFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (hDumpFile != INVALID_HANDLE_VALUE) - { - char buf[8192]; - - DWORD bytes = 0; - ReadFile(hDumpFile, buf, 8190, &bytes, NULL); - buf[bytes] = 0; - - char* ver = strstr(buf, "Version="); - if (ver != NULL) - { - char *endid = strchr(ver, '\r'); - if (endid != NULL) *endid = 0; - else - { - endid = strchr(ver, '\n'); - if (endid != NULL) *endid = 0; - } - ver += 8; - } - - char *id = strstr(buf, "Name="); - if (id != NULL) - { - char *endid = strchr(id, '\r'); - if (endid != NULL) *endid = 0; - else - { - endid = strchr(id, '\n'); - if (endid != NULL) *endid = 0; - } - id += 5; - } - - TCHAR timebuf[30] = TEXT(""); - GetLastWriteTime(&FindFileData.ftLastWriteTime, timebuf, 30); - - - static const TCHAR format[] = TEXT(" %s v.%s%S%s [%s] - %S\r\n"); - - buffer.appendfmt(format, FindFileData.cFileName, - (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), - ver, - (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""), - timebuf, id); - CloseHandle(hDumpFile); - } - } - while (FindNextFile(hFind, &FindFileData)); - FindClose(hFind); -} - - -static void GetIconStrings(bkstring& buffer) -{ - TCHAR path[MAX_PATH]; - GetModuleFileName(NULL, path, MAX_PATH); - - LPTSTR fname = _tcsrchr(path, TEXT('\\')); - if (fname == NULL) fname = path; - crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\Icons\\*.*")); - - WIN32_FIND_DATA FindFileData; - HANDLE hFind = FindFirstFile(path, &FindFileData); - if (hFind == INVALID_HANDLE_VALUE) return; - - do - { - if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; - - TCHAR timebuf[30] = TEXT(""); - GetLastWriteTime(&FindFileData.ftLastWriteTime, timebuf, 30); - - buffer.appendfmt(TEXT(" %s [%s]\r\n"), FindFileData.cFileName, timebuf); - } - while (FindNextFile(hFind, &FindFileData)); - FindClose(hFind); -} - - -void PrintVersionInfo(bkstring& buffer, unsigned flags) -{ - GetProcessorString(buffer); - buffer.append(TEXT("\r\n")); - - GetFreeMemoryString(buffer); - buffer.append(TEXT("\r\n")); - - GetOSDisplayString(buffer); - buffer.append(TEXT("\r\n")); - - GetInternetExplorerVersion(buffer); - buffer.append(TEXT("\r\n")); - - GetAdminString(buffer); - buffer.append(TEXT("\r\n")); - - GetLanguageString(buffer); - buffer.append(TEXT("\r\n")); - - TCHAR *profpathfull = Utils_ReplaceVarsT(profpath); - if (flags & VI_FLAG_PRNVAR) - { - GetFreeDiskString(profpathfull, buffer); - buffer.append(TEXT("\r\n")); - } - - buffer.appendfmt(TEXT("\r\nMiranda IM Version: %s"), vertxt); - GetWow64String(buffer); - buffer.append(TEXT("\r\n")); - - TCHAR path[MAX_PATH], mirtime[30]; - GetModuleFileName(NULL, path, MAX_PATH); - GetLastWriteTime(path, mirtime, 30); - buffer.appendfmt(TEXT("Build time: %s\r\n"), mirtime); - - TCHAR profpn[MAX_PATH]; - crs_sntprintf(profpn, SIZEOF(profpn), TEXT("%s\\%s"), profpathfull, profname); - - buffer.appendfmt(TEXT("Profile: %s\r\n"), profpn); - - if (flags & VI_FLAG_PRNVAR) - { - WIN32_FIND_DATA FindFileData; - - HANDLE hFind = FindFirstFile(profpn, &FindFileData); - if (hFind != INVALID_HANDLE_VALUE) - { - FindClose(hFind); - - unsigned __int64 fsize = (unsigned __int64)FindFileData.nFileSizeHigh << 32 | FindFileData.nFileSizeLow; - buffer.appendfmt(TEXT("Profile size: %I64u Bytes\r\n"), fsize), - - GetLastWriteTime(&FindFileData.ftCreationTime, mirtime, 30); - buffer.appendfmt(TEXT("Profile creation date: %s\r\n"), mirtime); - } - } - mir_free(profpathfull); - - GetLanguagePackString(buffer); - buffer.append(TEXT("\r\n")); - - buffer.appendfmt(TEXT("Nightly: %s\r\n"), _tcsstr(vertxt, TEXT("alpha")) ? TEXT("Yes") : TEXT("No")); - buffer.appendfmt(TEXT("Unicode: %s\r\n"), _tcsstr(vertxt, TEXT("Unicode")) ? TEXT("Yes") : TEXT("No")); - - GetPluginsString(buffer, flags); - - if (flags & VI_FLAG_WEATHER) - { - buffer.appendfmt(TEXT("\r\n%sWeather ini files:%s\r\n-------------------------------------------------------------------------------\r\n"), - (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), - (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT("")); - GetWeatherStrings(buffer, flags); - } - - if (flags & VI_FLAG_PRNVAR && !servicemode) - { - buffer.appendfmt(TEXT("\r\n%sProtocols and Accounts:%s\r\n-------------------------------------------------------------------------------\r\n"), - (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), - (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT("")); - GetProtocolStrings(buffer); - } - - if (flags & VI_FLAG_PRNVAR) - { - buffer.appendfmt(TEXT("\r\n%sIcon Packs:%s\r\n-------------------------------------------------------------------------------\r\n"), - (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), - (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT("")); - GetIconStrings(buffer); - } - - if (flags & VI_FLAG_PRNDLL) - { - __try - { - buffer.append(TEXT("\r\nLoaded Modules:\r\n-------------------------------------------------------------------------------\r\n")); - EnumerateLoadedModules64(GetCurrentProcess(), LoadedModules64, &buffer); - } - __except(EXCEPTION_EXECUTE_HANDLER) {} - } - - if (flags & (VI_FLAG_PRNVAR | VI_FLAG_PRNDLL)) UnloadDbgHlp(); -} - - -void CreateCrashReport(HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr, const TCHAR* msg) -{ - if (exc_ptr->ContextRecord == NULL || (exc_ptr->ContextRecord->ContextFlags & CONTEXT_CONTROL) == 0) - return; - - CONTEXT context = *exc_ptr->ContextRecord; - - STACKFRAME64 frame = {0}; - -#if defined(_AMD64_) -#define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_AMD64 - frame.AddrPC.Offset = context.Rip; - frame.AddrFrame.Offset = context.Rbp; - frame.AddrStack.Offset = context.Rsp; -#elif defined(_IA64_) -#define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_IA64 - frame.AddrPC.Offset = context.StIIP; - frame.AddrFrame.Offset = context.AddrBStore; - frame.AddrStack.Offset = context.SP; -#else -#define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_I386 - frame.AddrPC.Offset = context.Eip; - frame.AddrFrame.Offset = context.Ebp; - frame.AddrStack.Offset = context.Esp; -#endif - - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrFrame.Mode = AddrModeFlat; - frame.AddrStack.Mode = AddrModeFlat; - - const PLUGININFOEX *pluginInfoEx = GetPluginInfoEx(); - - bkstring buffer; - buffer.reserve(0x5000); - - TCHAR curtime[30]; - GetISO8061Time(NULL, curtime, 30); - - buffer.appendfmt(TEXT("Miranda Crash Report from %s. Crash Dumper v.%d.%d.%d.%d\r\n"), - curtime, - HIBYTE(HIWORD(pluginInfoEx->version)), LOBYTE(HIWORD(pluginInfoEx->version)), - HIBYTE(LOWORD(pluginInfoEx->version)), LOBYTE(LOWORD(pluginInfoEx->version))); - - size_t crashpos = buffer.size(); - - ReadableExceptionInfo(exc_ptr->ExceptionRecord, buffer); - buffer.append(TEXT("\r\n")); - - const HANDLE hProcess = GetCurrentProcess(); - - if (&SymSetOptions) - SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES); - SymInitialize(hProcess, NULL, TRUE); - - buffer.append(TEXT("\r\nStack Trace:\r\n---------------------------------------------------------------\r\n")); - - for (int i=81; --i;) - { - /* - char symbuf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + 4] = {0}; - PSYMBOL_INFO pSym = (PSYMBOL_INFO)symbuf; - pSym->SizeOfStruct = sizeof(SYMBOL_INFO); - pSym->MaxNameLen = MAX_SYM_NAME; - */ - - char symbuf[sizeof(IMAGEHLP_SYMBOL64) + MAX_SYM_NAME * sizeof(TCHAR) + 4] = {0}; - PIMAGEHLP_SYMBOL64 pSym = (PIMAGEHLP_SYMBOL64)symbuf; - pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); - pSym->MaxNameLength = MAX_SYM_NAME; - - IMAGEHLP_LINE64 Line = {0}; - Line.SizeOfStruct = sizeof(Line); - - IMAGEHLP_MODULE64 Module = {0}; - Module.SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); - - char undName[MAX_SYM_NAME] = ""; - char undFullName[MAX_SYM_NAME] = ""; - - DWORD64 offsetFromSmybol = 0; - DWORD offsetFromLine = 0; - - if (!StackWalk64(IMAGE_FILE_MACHINE, hProcess, GetCurrentThread(), &frame, &context, - NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) break; - - if (frame.AddrPC.Offset == frame.AddrReturn.Offset) break; - - if (frame.AddrPC.Offset != 0) - { - if (SymGetSymFromAddr64(hProcess, frame.AddrPC.Offset, &offsetFromSmybol, pSym)) - // if (SymFromAddr(hProcess, frame.AddrPC.Offset, &offsetFromSmybol, pSym)) - { - UnDecorateSymbolName(pSym->Name, undName, MAX_SYM_NAME, UNDNAME_NAME_ONLY); - UnDecorateSymbolName(pSym->Name, undFullName, MAX_SYM_NAME, UNDNAME_COMPLETE); - } - - SymGetLineFromAddr64(hProcess, frame.AddrPC.Offset, &offsetFromLine, &Line); - SymGetModuleInfo64(hProcess, frame.AddrPC.Offset, &Module); - if (Module.ModuleName[0] == 0) - { - FindData data; - data.Offset = frame.AddrPC.Offset; - data.pModule = &Module; - EnumerateLoadedModules64(hProcess, LoadedModulesFind64, &data); - } - } - - const char* name; - if (undFullName[0] != 0) - name = undFullName; - else if (undName[0] != 0) - name = undName; - else if (pSym->Name[0] != 0) - name = pSym->Name; - else - name = "(function-name not available)"; - - const char *lineFileName = Line.FileName ? Line.FileName : "(filename not available)"; - const char *moduleName = Module.ModuleName[0] ? Module.ModuleName : "(module-name not available)"; - - if (crashpos != 0) - { - HMODULE hModule = (HMODULE)Module.BaseOfImage; - PLUGININFOEX *pi = GetMirInfo(hModule); - if (pi != NULL) - { - - static const TCHAR formatc[] = TEXT("\r\nLikely cause of the crash plugin: %S\r\n\r\n"); - - if (pi->shortName) - { - bkstring crashcause; - crashcause.appendfmt(formatc, pi->shortName); - buffer.insert(crashpos, crashcause); - } - crashpos = 0; - } - } - - - static const TCHAR formatd[] = TEXT("%p (%S %p): %S (%d): %S\r\n"); - - buffer.appendfmt(formatd, - (LPVOID)frame.AddrPC.Offset, moduleName, (LPVOID)Module.BaseOfImage, - lineFileName, Line.LineNumber, name); - } - SymCleanup(hProcess); - buffer.append(TEXT("\r\n")); - - PrintVersionInfo(buffer, VI_FLAG_PRNDLL); - - - int len = WideCharToMultiByte(CP_UTF8, 0, buffer.c_str(), -1, NULL, 0, NULL, NULL); - char* dst = (char*)(len > 8192 ? malloc(len) : alloca(len)); - WideCharToMultiByte(CP_UTF8, 0, buffer.c_str(), -1, dst, len, NULL, NULL); - - WriteUtfFile(hDumpFile, dst); - - if (len > 8192) free(dst); - - - if (msg && MessageBox(NULL, msg, TEXT("Miranda Crash Dumper"), MB_YESNO | MB_ICONERROR | MB_TASKMODAL | MB_DEFBUTTON2 | MB_TOPMOST) == IDYES) - StoreStringToClip(buffer); -} diff --git a/plugins/CrashDumper/exhndlr.cpp b/plugins/CrashDumper/exhndlr.cpp deleted file mode 100644 index 93406efaa8..0000000000 --- a/plugins/CrashDumper/exhndlr.cpp +++ /dev/null @@ -1,207 +0,0 @@ -#include "utils.h" -#include "crtdbg.h" - -static PVOID exchndlr, exchndlrv; -static pfnExceptionFilter threadfltr; -static PEXCEPTION_POINTERS lastptr; - -static HMODULE hKernel = GetModuleHandle(TEXT("kernel32.dll")); - -tAddVectoredExceptionHandler pAddVectoredExceptionHandler = (tAddVectoredExceptionHandler)GetProcAddress(hKernel, "AddVectoredExceptionHandler"); -tRemoveVectoredExceptionHandler pRemoveVectoredExceptionHandler = (tRemoveVectoredExceptionHandler)GetProcAddress(hKernel, "RemoveVectoredExceptionHandler"); -tRtlCaptureContext pRtlCaptureContext = (tRtlCaptureContext)GetProcAddress(hKernel, "RtlCaptureContext"); - -void SetExceptionHandler(void) -{ - // if (pAddVectoredExceptionHandler && !exchndlrv) - // exchndlrv = pAddVectoredExceptionHandler(0, myfilterv); - /*exchndlr = */ SetUnhandledExceptionFilter(myfilter); -} - -void RemoveExceptionHandler(void) -{ - if (pRemoveVectoredExceptionHandler && exchndlrv) - pRemoveVectoredExceptionHandler(exchndlrv); - SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)exchndlr); - exchndlr = NULL; - exchndlrv = NULL; -} - -void UnloadDbgHlp(void) -{ -#ifdef _MSC_VER -#if _MSC_VER > 1200 - __FUnloadDelayLoadedDLL2("dbghelp.dll"); -#else - __FUnloadDelayLoadedDLL("dbghelp.dll"); -#endif -#endif -} - -int myDebugFilter(unsigned int code, PEXCEPTION_POINTERS ep) -{ - if (code == VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND) || - code == VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND)) - { - PDelayLoadInfo dlld = (PDelayLoadInfo)ep->ExceptionRecord->ExceptionInformation[0]; - - char str[256]; - int off = mir_snprintf(str, SIZEOF(str), "dbghelp.dll v.5.0 or later required to provide a crash report\n"); - off += mir_snprintf(str+off, SIZEOF(str)-off, "Missing Module: %s ", dlld->szDll); - - if (dlld->dlp.fImportByName) - mir_snprintf(str+off, SIZEOF(str)-off, "Function: %s ", dlld->dlp.szProcName); - else - mir_snprintf(str+off, SIZEOF(str)-off, "Ordinal: %x ", dlld->dlp.dwOrdinal); - - MessageBoxA(NULL, str, "Miranda Crash Dumper", MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_TOPMOST); - } - - return EXCEPTION_EXECUTE_HANDLER; -} - - -void myfilterWorker(PEXCEPTION_POINTERS exc_ptr, bool notify) -{ - TCHAR path[MAX_PATH]; - SYSTEMTIME st; - HANDLE hDumpFile = NULL; - - GetLocalTime(&st); - CreateDirectoryTree(CrashLogFolder); - - __try - { - if (dtsubfldr) - { - crs_sntprintf(path, MAX_PATH, TEXT("%s\\%02d.%02d.%02d"), CrashLogFolder, st.wYear, st.wMonth, st.wDay); - CreateDirectory(path, NULL); - crs_sntprintf(path, MAX_PATH, TEXT("%s\\%02d.%02d.%02d\\crash%02d%02d%02d%02d%02d%02d.mdmp"), CrashLogFolder, - st.wYear, st.wMonth, st.wDay, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); - } - else - { - crs_sntprintf(path, MAX_PATH, TEXT("%s\\crash%02d%02d%02d%02d%02d%02d.mdmp"), CrashLogFolder, - st.wYear, st.wMonth, st.wDay, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); - } - hDumpFile = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); - if (hDumpFile != INVALID_HANDLE_VALUE) - CreateMiniDump(hDumpFile, exc_ptr); - else if (GetLastError() != ERROR_ALREADY_EXISTS) - MessageBox(NULL, TranslateT("Crash Report write location is inaccesible"), - TEXT("Miranda Crash Dumper"), MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_TOPMOST); - - } - __except(EXCEPTION_EXECUTE_HANDLER) {} - - bool empty = GetFileSize(hDumpFile, NULL) == 0; - CloseHandle(hDumpFile); - if (empty) DeleteFile(path); - - __try - { - if (dtsubfldr) - { - crs_sntprintf(path, MAX_PATH, TEXT("%s\\%02d.%02d.%02d"), CrashLogFolder, st.wYear, st.wMonth, st.wDay); - CreateDirectory(path, NULL); - crs_sntprintf(path, MAX_PATH, TEXT("%s\\%02d.%02d.%02d\\crash%02d%02d%02d%02d%02d%02d.txt"), CrashLogFolder, - st.wYear, st.wMonth, st.wDay, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); - } - else - { - crs_sntprintf(path, MAX_PATH, TEXT("%s\\crash%02d%02d%02d%02d%02d%02d.txt"), CrashLogFolder, - st.wYear, st.wMonth, st.wDay, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); - } - hDumpFile = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); - - crs_sntprintf(path, MAX_PATH, TranslateT("Miranda crashed. Crash report stored in the folder:\n %s\n\n Would you like store it in the clipboard as well?"), CrashLogFolder); - - if (hDumpFile != INVALID_HANDLE_VALUE) - CreateCrashReport(hDumpFile, exc_ptr, notify ? path : NULL); - } - __except(myDebugFilter(GetExceptionCode(), GetExceptionInformation())) {} - - bool empty1 = GetFileSize(hDumpFile, NULL) == 0; - CloseHandle(hDumpFile); - if (empty1) DeleteFile(path); - - UnloadDbgHlp(); -} - -LONG WINAPI myfilter(PEXCEPTION_POINTERS exc_ptr) -{ - if (exc_ptr == lastptr) return EXCEPTION_EXECUTE_HANDLER; - lastptr = exc_ptr; - - myfilterWorker(exc_ptr, true); - - return exchndlr ? ((LPTOP_LEVEL_EXCEPTION_FILTER)exchndlr)(exc_ptr) : EXCEPTION_CONTINUE_SEARCH; -} - -LONG WINAPI myfilterv(PEXCEPTION_POINTERS exc_ptr) -{ - if (0xC0000000L <= exc_ptr->ExceptionRecord->ExceptionCode && 0xC0000500L >= exc_ptr->ExceptionRecord->ExceptionCode) - { - if (exc_ptr == lastptr) return EXCEPTION_EXECUTE_HANDLER; - lastptr = exc_ptr; - - myfilterWorker(exc_ptr, true); - } - return EXCEPTION_CONTINUE_SEARCH; -} - -DWORD MirandaThreadFilter(DWORD code, EXCEPTION_POINTERS* info) -{ - if (info != lastptr) - { - lastptr = info; - myfilterWorker(info, true); - } - return threadfltr(code, info); -} - -#if _MSC_VER >= 1400 -void InvalidParameterHandler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, UINT_PTR) -{ - EXCEPTION_RECORD ExceptionRecord = {0}; - CONTEXT ContextRecord = {0}; - EXCEPTION_POINTERS info = { &ExceptionRecord, &ContextRecord }; - - if (pRtlCaptureContext) - pRtlCaptureContext(&ContextRecord); - else - { - ContextRecord.ContextFlags = CONTEXT_ALL; - GetThreadContext(GetCurrentThread(), &ContextRecord); - } - -#if defined(_AMD64_) - ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.Rip; -#elif defined(_IA64_) - ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.BrRp; -#else - ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.Eip; -#endif - - ExceptionRecord.ExceptionCode = STATUS_INVALID_CRUNTIME_PARAMETER; - ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; - - myfilterWorker(&info, true); -} -#endif - -void InitExceptionHandler(void) -{ -#if _MSC_VER >= 1400 - _set_invalid_parameter_handler(InvalidParameterHandler); -#endif - threadfltr = Miranda_SetExceptFilter(MirandaThreadFilter); - SetExceptionHandler(); -} - -void DestroyExceptionHandler(void) -{ - Miranda_SetExceptFilter(threadfltr); - RemoveExceptionHandler(); -} - diff --git a/plugins/CrashDumper/res/Version.rc b/plugins/CrashDumper/res/Version.rc new file mode 100644 index 0000000000..c3c4f27aa3 --- /dev/null +++ b/plugins/CrashDumper/res/Version.rc @@ -0,0 +1,45 @@ +// Microsoft Visual C++ generated resource script. +// +#ifdef APSTUDIO_INVOKED +#error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + +#include "afxres.h" +#include "..\src\version.h" + +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#endif //_WIN32 + +VS_VERSION_INFO VERSIONINFO + FILEVERSION __FILEVERSION_STRING + PRODUCTVERSION __FILEVERSION_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 "CompanyName", "Boris Krasnovskiy" + VALUE "FileDescription", "Crash Dumper plugin for Miranda IM." + VALUE "FileVersion", __VERSION_STRING + VALUE "InternalName", "svc_crshdmp" + VALUE "LegalCopyright", "Copyright© 2008 - 2012 Boris Krasnovskiy All Rights Reserved" + VALUE "OriginalFilename", "svc_crshdmp.dll" + VALUE "ProductName", "Crash Dumper" + VALUE "ProductVersion", __VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/plugins/CrashDumper/res/Vi show.ico b/plugins/CrashDumper/res/Vi show.ico new file mode 100644 index 0000000000..55556862f3 Binary files /dev/null and b/plugins/CrashDumper/res/Vi show.ico differ diff --git a/plugins/CrashDumper/res/Vi to clipboard.ico b/plugins/CrashDumper/res/Vi to clipboard.ico new file mode 100644 index 0000000000..6f095b59b1 Binary files /dev/null and b/plugins/CrashDumper/res/Vi to clipboard.ico differ diff --git a/plugins/CrashDumper/res/Vi to file.ico b/plugins/CrashDumper/res/Vi to file.ico new file mode 100644 index 0000000000..abfc196437 Binary files /dev/null and b/plugins/CrashDumper/res/Vi to file.ico differ diff --git a/plugins/CrashDumper/res/Vi upload.ico b/plugins/CrashDumper/res/Vi upload.ico new file mode 100644 index 0000000000..4c562b02b8 Binary files /dev/null and b/plugins/CrashDumper/res/Vi upload.ico differ diff --git a/plugins/CrashDumper/res/Vi.ico b/plugins/CrashDumper/res/Vi.ico new file mode 100644 index 0000000000..371aeb345e Binary files /dev/null and b/plugins/CrashDumper/res/Vi.ico differ diff --git a/plugins/CrashDumper/res/crshdmp.rc b/plugins/CrashDumper/res/crshdmp.rc new file mode 100644 index 0000000000..5b5e024260 --- /dev/null +++ b/plugins/CrashDumper/res/crshdmp.rc @@ -0,0 +1,151 @@ +// Microsoft Visual C++ generated resource script. +// +#include "..\src\resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" +#include "richedit.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" + "#include ""richedit.h""\r\n" +END + +3 TEXTINCLUDE +BEGIN + "\r\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_VIEWVERSION DIALOGEX 0, 0, 375, 236 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "View Version Information " +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + PUSHBUTTON "Close",IDCANCEL,302,215,66,14 + PUSHBUTTON "Copy To Clipboard",IDC_CLIPVER,142,215,95,14 + PUSHBUTTON "To File",IDC_FILEVER,6,215,66,14 + CONTROL "",IDC_VIEWVERSIONINFO,RICHEDIT_CLASS,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,7,7,361,203,WS_EX_CLIENTEDGE +END + +IDD_OPTIONS DIALOGEX 0, 0, 209, 163 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "Support for miranda-vi.org",IDC_STATIC,7,7,195,94 + LTEXT "Username",IDC_STATIC,14,20,107,8 + EDITTEXT IDC_USERNAME,14,33,108,14,ES_AUTOHSCROLL + LTEXT "Password",IDC_STATIC,14,52,107,8 + EDITTEXT IDC_PASSWORD,14,65,107,14,ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "Upload automatically when changed",IDC_UPLOADCHN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,84,161,10 + GROUPBOX "General",IDC_STATIC,7,104,195,42 + CONTROL "Use classic dates",IDC_CLASSICDATES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,118,157,10 + CONTROL "Create reports in subfolders naming as current date",IDC_DATESUBFOLDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,132,180,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_VIEWVERSION, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 368 + TOPMARGIN, 7 + BOTTOMMARGIN, 229 + END + + IDD_OPTIONS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 202 + TOPMARGIN, 7 + BOTTOMMARGIN, 147 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_CONTEXT MENU +BEGIN + POPUP "View" + BEGIN + MENUITEM "&Copy", IDM_COPY + MENUITEM "Co&py All", IDM_COPYALL + MENUITEM SEPARATOR + MENUITEM "Select &All", IDM_SELECTALL + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_VI ICON "Vi.ico" +IDI_VISHOW ICON "Vi show.ico" +IDI_VITOCLIP ICON "Vi to clipboard.ico" +IDI_VITOFILE ICON "Vi to file.ico" +IDI_VIUPLOAD ICON "Vi upload.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/CrashDumper/resource.h b/plugins/CrashDumper/resource.h deleted file mode 100644 index 83d8a491e4..0000000000 --- a/plugins/CrashDumper/resource.h +++ /dev/null @@ -1,34 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by crshdmp.rc -// -#define IDD_VIEWVERSION 101 -#define IDR_CONTEXT 102 -#define IDI_VI 104 -#define IDI_VISHOW 105 -#define IDI_VITOCLIP 106 -#define IDI_VITOFILE 107 -#define IDI_VIUPLOAD 108 -#define IDD_OPTIONS 109 -#define IDC_VIEWVERSIONINFO 1001 -#define IDC_FILEVER 1003 -#define IDC_CLIPVER 1004 -#define IDC_USERNAME 1006 -#define IDC_PASSWORD 1007 -#define IDC_UPLOADCHN 1008 -#define IDC_CLASSICDATES 1009 -#define IDC_DATESUBFOLDER 1010 -#define IDM_COPY 40002 -#define IDM_COPYALL 40003 -#define IDM_SELECTALL 40004 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 110 -#define _APS_NEXT_COMMAND_VALUE 40005 -#define _APS_NEXT_CONTROL_VALUE 1011 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/plugins/CrashDumper/sdkstuff.h b/plugins/CrashDumper/sdkstuff.h deleted file mode 100644 index 536a00bc40..0000000000 --- a/plugins/CrashDumper/sdkstuff.h +++ /dev/null @@ -1,124 +0,0 @@ -/* -Miranda Crash Dumper Plugin -Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include - - -//#define DBGHELP_TRANSLATE_TCHAR - - -#ifndef __in_bcount_opt -#define __in_bcount_opt(x) -#endif - -#ifndef __out_bcount_opt -#define __out_bcount_opt(x) -#endif - -#include "dbghelp.h" - - -#ifndef PRODUCT_ULTIMATE - -#define PRODUCT_UNDEFINED 0x00000000 - -#define PRODUCT_ULTIMATE 0x00000001 -#define PRODUCT_HOME_BASIC 0x00000002 -#define PRODUCT_HOME_PREMIUM 0x00000003 -#define PRODUCT_ENTERPRISE 0x00000004 -#define PRODUCT_HOME_BASIC_N 0x00000005 -#define PRODUCT_BUSINESS 0x00000006 -#define PRODUCT_STANDARD_SERVER 0x00000007 -#define PRODUCT_DATACENTER_SERVER 0x00000008 -#define PRODUCT_SMALLBUSINESS_SERVER 0x00000009 -#define PRODUCT_ENTERPRISE_SERVER 0x0000000A -#define PRODUCT_STARTER 0x0000000B -#define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C -#define PRODUCT_STANDARD_SERVER_CORE 0x0000000D -#define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E -#define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F -#define PRODUCT_BUSINESS_N 0x00000010 -#define PRODUCT_WEB_SERVER 0x00000011 -#define PRODUCT_CLUSTER_SERVER 0x00000012 -#define PRODUCT_HOME_SERVER 0x00000013 -#define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014 -#define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015 -#define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016 -#define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017 -#define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018 -#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019 - -#define PRODUCT_UNLICENSED 0xABCDABCD - -#define SM_TABLETPC 86 -#define SM_MEDIACENTER 87 -#define SM_STARTER 88 -#define SM_SERVERR2 89 - -#endif - -#ifndef VER_SUITE_STORAGE_SERVER -#define VER_SUITE_STORAGE_SERVER 0x00002000 -#define VER_SUITE_COMPUTE_SERVER 0x00004000 -#endif - -#ifndef PF_NX_ENABLED -#define PF_NX_ENABLED 12 -#endif - -typedef struct _IMAGEHLP_MODULE64_V2 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) - DWORD64 BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - CHAR ModuleName[32]; // module name - CHAR ImageName[256]; // image name - CHAR LoadedImageName[256]; // symbol file name -} IMAGEHLP_MODULE64_V2; - -typedef struct _IMAGEHLP_MODULEW64_V2 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) - DWORD64 BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - WCHAR ModuleName[32]; // module name - WCHAR ImageName[256]; // image name - WCHAR LoadedImageName[256]; // symbol file name -} IMAGEHLP_MODULEW64_V2; - -#ifdef DBGHELP_TRANSLATE_TCHAR -#define IMAGEHLP_MODULE64_V2 IMAGEHLP_MODULEW64_V2 -#endif - -typedef void (WINAPI *tGetNativeSystemInfo)(LPSYSTEM_INFO); -typedef BOOL (WINAPI *tGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD); -typedef BOOL (WINAPI *tGlobalMemoryStatusEx)(LPMEMORYSTATUSEX lpBuffer); -typedef BOOL (WINAPI *tGetDiskFreeSpaceEx)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); -typedef LANGID (WINAPI *tGetUserDefaultUILanguage)(void); -typedef LANGID (WINAPI *tGetSystemDefaultUILanguage)(void); -typedef BOOL (WINAPI *tIsWow64Process)(HANDLE, PBOOL); -typedef PVOID (WINAPI *tAddVectoredExceptionHandler)(ULONG FirstHandler, PVECTORED_EXCEPTION_HANDLER VectoredHandler); -typedef ULONG (WINAPI *tRemoveVectoredExceptionHandler)(PVOID Handler); -typedef BOOL (WINAPI *tIsProcessorFeaturePresent)(DWORD ProcessorFeature); -typedef VOID (WINAPI *tRtlCaptureContext)(PCONTEXT ContextRecord); diff --git a/plugins/CrashDumper/src/bkstring.cpp b/plugins/CrashDumper/src/bkstring.cpp new file mode 100644 index 0000000000..418cb0bd83 --- /dev/null +++ b/plugins/CrashDumper/src/bkstring.cpp @@ -0,0 +1,188 @@ +/* +Miranda Crash Dumper Plugin +Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "bkstring.h" + +bkstring::~bkstring() { if (sizeAlloced) free(buf); } + + +void bkstring::reserve(size_type len) +{ + if (len >= sizeAlloced || sizeAlloced == 0) + { + if (sizeAlloced == 0) buf = NULL; + buf = (value_type*)realloc(buf, (len+1) * sizeof(value_type)); + if (sizeAlloced == 0) buf[0] = 0; + sizeAlloced = len+1; + } +} + +void bkstring::appendfmt(const value_type *fmt, ...) +{ + areserve(_tcslen(fmt)*2); + + va_list vararg; + va_start(vararg, fmt); + for (;;) + { + int len = _vsntprintf(buf + lenBuf, sizeAlloced - lenBuf - 1, fmt, vararg); + if (len < 0) + reserve(sizeAlloced + 256); + else + { + lenBuf += len; + buf[lenBuf] = 0; + break; + } + } + va_end(vararg); +} + +bkstring& bkstring::append(const value_type* _Ptr) +{ + size_type len = _tcslen(_Ptr); + areserve(len); + memcpy(buf+lenBuf, _Ptr, (len+1)*sizeof(value_type)); + lenBuf += len; + return *this; +} + +bkstring& bkstring::append(const value_type* _Ptr, size_type _Count) +{ + size_type len = min(_tcslen(_Ptr), _Count); + areserve(len); + memcpy(buf+lenBuf, _Ptr, len*sizeof(value_type)); + lenBuf += len; + buf[lenBuf] = 0; + return *this; +} + +bkstring& bkstring::append(const bkstring& _Str, size_type _Off, size_type _Count) +{ + size_type len = min(_Count, _Str.size() - _Off); + areserve(len); + memcpy(buf+lenBuf, _Str.c_str()+_Off, len*sizeof(value_type)); + lenBuf += len; + buf[lenBuf] = 0; + return *this; +} + +bkstring& bkstring::append(const bkstring& _Str) +{ + size_type len = _Str.size(); + areserve(len); + memcpy(buf+lenBuf, _Str.c_str(), len*sizeof(value_type)); + lenBuf += len; + buf[lenBuf] = 0; + return *this; +} + +bkstring& bkstring::append(size_type _Count, value_type _Ch) +{ + areserve(_Count); + for(size_type i=0; i<_Count; ++i) buf[lenBuf+i] = _Ch; + lenBuf += _Count; + buf[lenBuf] = 0; + return *this; +} + + +bkstring& bkstring::assign(const value_type* _Ptr, size_type _Count) +{ + reserve(_Count); + memcpy(buf, _Ptr, _Count*sizeof(value_type)); + buf[_Count] = 0; + lenBuf = _Count; + return *this; +} + +bkstring& bkstring::assign(const bkstring& _Str, size_type _Off, size_type _Count) +{ + size_type len = min(_Count, _Str.size() - _Off); + reserve(len); + memcpy(buf, _Str.c_str() + _Off, len*sizeof(value_type)); + lenBuf = len; + buf[len] = 0; + return *this; +} + +bkstring& bkstring::assign(size_type _Count, value_type _Ch) +{ + reserve(_Count); + for(size_type i=0; i<_Count; ++i) buf[i] = _Ch; + buf[_Count] = 0; + lenBuf = _Count; + return *this; +} + +bkstring::size_type bkstring::find(value_type _Ch, size_type _Off) const +{ + for (size_type i=_Off; i<=lenBuf; ++i) + if (buf[i] == _Ch) return i; + return (size_type)npos; +} + +bkstring::size_type bkstring::find(const value_type* _Ptr, size_type _Off) const +{ + if (_Off > lenBuf) return (size_type)npos; + + value_type* pstr = _tcsstr(buf+_Off, _Ptr); + return pstr ? pstr - buf : npos; +} + +bkstring::size_type bkstring::find_last_of(value_type _Ch, size_type _Off) const +{ + for (size_type i=(_Off == npos ? lenBuf : _Off); i--;) + if (buf[i] == _Ch) return i; + return (size_type)npos; +} + +bkstring& bkstring::insert(size_type _P0, const value_type* _Ptr, size_type _Count) +{ + size_type len = _tcslen(_Ptr); + if (_Count < len) len = _Count; + areserve(len); + value_type *p = buf + _P0; + memmove(p+len, p, (lenBuf-_P0+1)*sizeof(value_type)); + memcpy(p, _Ptr, _Count*sizeof(value_type)); + lenBuf += len; + return *this; +} + +bkstring& bkstring::insert(size_type _P0, size_type _Count, value_type _Ch) +{ + areserve(_Count); + value_type *p = buf + _P0; + memmove(p+_Count, p, (lenBuf-_P0+1)*sizeof(value_type)); + for(size_type i=0; i<_Count; ++i) p[i] = _Ch; + lenBuf += _Count; + return *this; +} + +bkstring& bkstring::erase(size_type _Pos, size_type _Count) +{ + if (_Pos < lenBuf) + { + const size_type len = min(lenBuf - _Pos, _Count); + value_type *p = buf + _Pos; + lenBuf -= len; + memmove(p, p+len, (lenBuf - _Pos)*sizeof(value_type)); + buf[lenBuf] = 0; + } + return *this; +} diff --git a/plugins/CrashDumper/src/bkstring.h b/plugins/CrashDumper/src/bkstring.h new file mode 100644 index 0000000000..88cb3bdfc4 --- /dev/null +++ b/plugins/CrashDumper/src/bkstring.h @@ -0,0 +1,278 @@ +/* +Miranda Crash Dumper Plugin +Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#define _CRT_SECURE_NO_WARNINGS + +#ifndef _BKSTRING_H_ +#define _BKSTRING_H_ + +#include +#include +#include +#include +#include + +#ifndef min +#define min(A, B) ((A) < (B) ? (A) : (B)) +#endif + +class bkstring +{ +public: + typedef size_t size_type; + typedef TCHAR value_type; + typedef value_type* iterator; + typedef const value_type* const_iterator; + +#if defined(_MSC_VER) && _MSC_VER > 1200 + static const size_type npos = size_type(-1); +#else + enum { npos = -1 }; +#endif + +private: + value_type* buf; + size_type sizeAlloced; + size_type lenBuf; + + void areserve(size_type len) { reserve(lenBuf + len); } + +public: + + explicit bkstring() : buf((TCHAR*)_T("")), sizeAlloced(0), lenBuf(0) + {} + + bkstring(const value_type* _Ptr, size_type _Count) : sizeAlloced(0), lenBuf(0) + { assign(_Ptr, _Count); } + + bkstring(const value_type* _Ptr) : sizeAlloced(0), lenBuf(0) + { assign(_Ptr); } + + bkstring(size_type _Count, value_type _Ch) : sizeAlloced(0), lenBuf(0) + { assign(_Count, _Ch); } + + bkstring(const bkstring& _Str) : sizeAlloced(0), lenBuf(0) + { assign(_Str); } + + bkstring(const bkstring& _Str, size_type _Off, size_type _Count) : sizeAlloced(0), lenBuf(0) + { assign(_Str, _Off, _Count); } + + ~bkstring(); + + size_type size(void) const { return lenBuf; } + const value_type* c_str(void) const { return buf; } + + void clear(void) { if (lenBuf) { lenBuf = 0; buf[0] = 0; } } + void insert(const value_type *txt); + void reserve(size_type len); + + bkstring& assign(const value_type* _Ptr) + { return assign(_Ptr, _tcslen(_Ptr)); } + + bkstring& assign(const bkstring& _Str) + { return assign(_Str, 0, (size_type)npos); } + + bkstring& assign(const value_type* _Ptr, size_type _Count); + bkstring& assign(const bkstring& _Str, size_type off, size_type _Count); + bkstring& assign(size_type _Count, value_type _Ch); + + bkstring& append(const value_type* _Ptr); + bkstring& append(const value_type* _Ptr, size_type _Count); + bkstring& append(const bkstring& _Str, size_type _Off, size_type _Count); + bkstring& append(const bkstring& _Str); + bkstring& append(size_type _Count, value_type _Ch); + + int compare(const bkstring& _Str) const + { return _tcscmp(buf, _Str.c_str()); } + + int compare(size_type _Pos1, size_type _Num1, const bkstring& _Str) const + { return _tcsncmp(&buf[_Pos1], _Str.c_str(), _Num1); } + + int compare(size_type _Pos1, size_type _Num1, const bkstring& _Str, size_type _Off, size_type _Count) const + { return _tcsncmp(&buf[_Pos1], _Str.c_str()+_Off, min(_Num1, _Count)); } + + int compare(const value_type* _Ptr) const + { return _tcscmp(buf, _Ptr); } + + int compare(size_type _Pos1, size_type _Num1, const value_type* _Ptr) const + { return _tcsncmp(&buf[_Pos1], _Ptr, _Num1); } + + int compare(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2) const + { return _tcsncmp(&buf[_Pos1], _Ptr, min(_Num1, _Num2)); } + + int comparei(const bkstring& _Str) const + { return _tcsicmp(buf, _Str.c_str()); } + + int comparei(size_type _Pos1, size_type _Num1, const bkstring& _Str) const + { return _tcsnicmp(&buf[_Pos1], _Str.c_str(), _Num1); } + + int comparei(size_type _Pos1, size_type _Num1, const bkstring& _Str, size_type _Off, size_type _Count) const + { return _tcsnicmp(&buf[_Pos1], _Str.c_str()+_Off, min(_Num1, _Count)); } + + int comparei(const value_type* _Ptr) const + { return _tcsicmp(buf, _Ptr); } + + int comparei(size_type _Pos1, size_type _Num1, const value_type* _Ptr) const + { return _tcsnicmp(&buf[_Pos1], _Ptr, _Num1); } + + int comparei(size_type _Pos1, size_type _Num1, const value_type* _Ptr, size_type _Num2) const + { return _tcsnicmp(&buf[_Pos1], _Ptr, min(_Num1, _Num2)); } + + bool empty(void) const { return lenBuf == 0; }; + bkstring& erase(size_type _Pos = 0, size_type _Count = npos); + + size_type find(value_type _Ch, size_type _Off = 0) const; + size_type find(const value_type* _Ptr, size_type _Off = 0) const; + size_type find(bkstring& _Str, size_type _Off = 0) const + { return find(_Str.c_str(), _Off); } + + size_type find_last_of(value_type _Ch, size_type _Off = npos) const; + + bkstring& insert(size_type _P0, const value_type* _Ptr) + { return insert(_P0, _Ptr, _tcslen(_Ptr)); } + + bkstring& insert(size_type _P0, const bkstring& _Str) + { return insert(_P0, _Str.c_str(), _Str.size()); }; + + bkstring& insert(size_type _P0, const value_type* _Ptr, size_type _Count); + bkstring& insert(size_type _P0, size_type _Count, value_type _Ch); + + bkstring substr(size_type _Off = 0, size_type _Count = npos) const + { return bkstring(*this, _Off, _Count); } + + bkstring& operator = (const bkstring& _Str) + { return assign(_Str); } + + bkstring& operator =(const value_type* _Ptr) + { return assign(_Ptr); } + + bkstring& operator = (const value_type _Ch) + { return assign(1, _Ch); } + + bkstring& operator +=(const bkstring& _Str) + { return append(_Str); } + + bkstring& operator += (const value_type* _Ptr) + { return append(_Ptr); } + + bkstring& operator += (const value_type _Ch) + { return append(1, _Ch); } + + value_type& operator[] (int ind) const + { return buf[ind]; } + + friend bkstring operator+ (const bkstring& _Str1, const bkstring& _Str2) + { bkstring s(_Str1); return s.append(_Str2); } + + friend bkstring operator+ (const bkstring& _Str1, const value_type* _Ptr2) + { bkstring s(_Str1); return s.append(_Ptr2); } + + friend bkstring operator+(const value_type* _Ptr1, const bkstring& _Str2) + { bkstring s(_Ptr1); return s.append(_Str2); } + + friend bkstring operator+ (const bkstring& _Str1, const value_type _Ch) + { bkstring s(_Str1); return s.append(1, _Ch); } + + friend bool operator==(const bkstring& _Str1, const bkstring& _Str2) + { return _Str1.compare(_Str2) == 0; } + + friend bool operator==(const bkstring& _Str1, const value_type* _Ptr2) + { return _Str1.compare(_Ptr2) == 0; } + + friend bool operator==(const value_type* _Ptr1, const bkstring& _Str2) + { return _Str2.compare(_Ptr1) == 0; } + + friend bool operator!=(const bkstring& _Str1, const bkstring& _Str2) + { return _Str1.compare(_Str2) != 0; } + + friend bool operator!=(const bkstring& _Str1, const value_type* _Ptr2) + { return _Str1.compare(_Ptr2) != 0; } + + friend bool operator!=(const value_type* _Ptr1, const bkstring& _Str2) + { return _Str2.compare(_Ptr1) != 0; } + + friend bool operator<(const bkstring& _Str1, const bkstring& _Str2) + { return _Str1.compare(_Str2) < 0; } + + friend bool operator<(const bkstring& _Str1, const value_type* _Ptr2) + { return _Str1.compare(_Ptr2) < 0; } + + friend bool operator<(const value_type* _Ptr1, const bkstring& _Str2) + { return _Str2.compare(_Ptr1) > 0; } + + friend bool operator>(const bkstring& _Str1, const bkstring& _Str2) + { return _Str1.compare(_Str2) > 0; } + + friend bool operator>(const bkstring& _Str1, const value_type* _Ptr2) + { return _Str1.compare(_Ptr2) > 0; } + + friend bool operator>(const value_type* _Ptr1, const bkstring& _Str2) + { return _Str2.compare(_Ptr1) < 0; } + + friend bool operator<=(const bkstring& _Str1, const bkstring& _Str2) + { return _Str1.compare(_Str2) <= 0; } + + friend bool operator<=(const bkstring& _Str1, const value_type* _Ptr2) + { return _Str1.compare(_Ptr2) <= 0; } + + friend bool operator<=(const value_type* _Ptr1, const bkstring& _Str2) + { return _Str2.compare(_Ptr1) >= 0; } + + friend bool operator>=(const bkstring& _Str1, const bkstring& _Str2) + { return _Str1.compare(_Str2) >= 0; } + + friend bool operator>=(const bkstring& _Str1, const value_type* _Ptr2) + { return _Str1.compare(_Ptr2) >= 0; } + + friend bool operator>=(const value_type* _Ptr1, const bkstring& _Str2) + { return _Str2.compare(_Ptr1) <= 0; } + + friend bool operator==(const value_type _Ch1, const bkstring& _Str2) + { return (_Str2.size() == 1) && (_Str2[0] == _Ch1); } + + friend bool operator==(const bkstring& _Str1, const value_type _Ch2) + { return (_Str1.size() == 1) && (_Str1[0] == _Ch2); } + + friend bool operator!=(const value_type _Ch1, const bkstring& _Str2) + { return (_Str2.size() != 1) || (_Str2[0] != _Ch1); } + + friend bool operator!=(const bkstring& _Str1, const value_type _Ch2) + { return (_Str1.size() != 1) || (_Str1[0] != _Ch2); } + + iterator begin(void) + { return buf; } + + const_iterator begin(void) const + { return buf; } + + iterator end(void) + { return buf + lenBuf; } + + const_iterator end(void) const + { return buf + lenBuf; } + + // Custom extentions + + void appendfmt(const value_type *fmt, ...); + + size_type sizebytes(void) const { return lenBuf * sizeof(value_type); } +}; + +//const bkstring::size_type bkstring::npos = -1; + +#endif diff --git a/plugins/CrashDumper/src/crshdmp.cpp b/plugins/CrashDumper/src/crshdmp.cpp new file mode 100644 index 0000000000..72ffac7f44 --- /dev/null +++ b/plugins/CrashDumper/src/crshdmp.cpp @@ -0,0 +1,434 @@ +/* +Miranda Crash Dumper Plugin +Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "utils.h" +#include +#include "m_folders.h" +#include "m_toptoolbar.h" +#include "version.h" + +int hLangpack; + +HINSTANCE hInst; +DWORD mirandaVersion; +LCID packlcid; +HANDLE hCrashLogFolder, hVerInfoFolder; +HMODULE hRichModule; + +TCHAR* vertxt; +TCHAR* profname; +TCHAR* profpath; + +TCHAR CrashLogFolder[MAX_PATH]; +TCHAR VersionInfoFolder[MAX_PATH]; + +bool servicemode; +bool clsdates; +bool dtsubfldr; + +static const PLUGININFOEX pluginInfoEx = +{ + sizeof(PLUGININFOEX), + "Crash Dumper", + __VERSION_DWORD, + "Crash Dumper for Miranda IM.", + "borkra", + "borkra@miranda-im.org", + "Copyright© 2008 - 2012 Boris Krasnovskiy All Rights Reserved", + "http://code.google.com/p/mirandaimplugins/downloads/list", + UNICODE_AWARE, + // {F62C1D7A-FFA4-4065-A251-4C9DD9101CC8} + { 0xf62c1d7a, 0xffa4, 0x4065, { 0xa2, 0x51, 0x4c, 0x9d, 0xd9, 0x10, 0x1c, 0xc8 } } +}; + +const PLUGININFOEX* GetPluginInfoEx(void) { return &pluginInfoEx; } + + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirVersion) +{ + ::mirandaVersion = mirVersion; + return (PLUGININFOEX*)&pluginInfoEx; +} + +#define MIID_CRASHDUMP { 0x36a31a50, 0xcb55, 0x46d0, { 0xab, 0x9c, 0x1e, 0xac, 0xfb, 0x24, 0x0, 0x2a } } + +// MirandaInterfaces - returns the protocol interface to the core +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_SERVICEMODE, MIID_CRASHDUMP, MIID_LAST }; + +HANDLE hHooks[5]; +HANDLE hServices[6]; + + +INT_PTR StoreVersionInfoToFile(WPARAM, LPARAM lParam) +{ + CreateDirectoryTree(VersionInfoFolder); + + TCHAR path[MAX_PATH]; + crs_sntprintf(path, MAX_PATH, TEXT("%s\\VersionInfo.txt"), VersionInfoFolder); + + HANDLE hDumpFile = CreateFile(path, GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hDumpFile != INVALID_HANDLE_VALUE) + { + bkstring buffer; + + buffer.reserve(0x1800); + PrintVersionInfo(buffer, (unsigned int)lParam | VI_FLAG_PRNVAR); + + char* bufu = mir_utf8encodeT(buffer.c_str()); + WriteUtfFile(hDumpFile, bufu); + mir_free(bufu); + + CloseHandle(hDumpFile); + + ShowMessage(3, TranslateT("VersionInfo stored into file %s"), path); + } + else + ShowMessage(2, TranslateT("VersionInfo file %s is inaccessible"), path); + + return 0; +} + +INT_PTR StoreVersionInfoToClipboard(WPARAM, LPARAM lParam) +{ + bkstring buffer; + buffer.reserve(0x1800); + + WriteBBFile(buffer, true); + PrintVersionInfo(buffer, (unsigned int)lParam | VI_FLAG_PRNVAR | VI_FLAG_FORMAT); + WriteBBFile(buffer, false); + + StoreStringToClip(buffer); + + return 0; +} + +INT_PTR UploadVersionInfo(WPARAM, LPARAM lParam) +{ + bkstring buffer; + buffer.reserve(0x1800); + PrintVersionInfo(buffer); + + VerTrnsfr *trn = (VerTrnsfr*)mir_alloc(sizeof(VerTrnsfr)); + trn->buf = mir_utf8encodeT(buffer.c_str()); + trn->autot = lParam == 0xa1; + + mir_forkthread(VersionInfoUploadThread, trn); + + return 0; +} + + +INT_PTR ViewVersionInfo(WPARAM wParam, LPARAM) +{ + // unsigned *p = (unsigned*)0x15; + // *p = 324; + + if (hRichModule == NULL && GetModuleHandle(TEXT("Riched20.dll")) == NULL) + hRichModule = LoadLibrary(TEXT("Riched20.dll")); + + CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_VIEWVERSION), NULL, + DlgProcView, wParam ? (VI_FLAG_PRNVAR | VI_FLAG_PRNDLL) : VI_FLAG_PRNVAR); + + return 0; +} + +INT_PTR OpenUrl(WPARAM wParam, LPARAM) +{ + switch (wParam) + { + case 0: + ShellExecute(NULL, TEXT("explore"), CrashLogFolder, NULL, NULL, SW_SHOW); + break; + + case 1: + OpenAuthUrl("http://%s.miranda-vi.org"); + break; + } + return 0; +} + +INT_PTR ServiceModeLaunch(WPARAM, LPARAM) +{ + servicemode = true; + return 0; +} + + +static int FoldersPathChanged(WPARAM, LPARAM) +{ + FOLDERSGETDATA fgd = {0}; + fgd.cbSize = sizeof(FOLDERSGETDATA); + fgd.nMaxPathSize = MAX_PATH; + fgd.szPathT = CrashLogFolder; + CallService(MS_FOLDERS_GET_PATH, (WPARAM) hCrashLogFolder, (LPARAM) &fgd); + + fgd.szPathT = VersionInfoFolder; + CallService(MS_FOLDERS_GET_PATH, (WPARAM) hVerInfoFolder, (LPARAM) &fgd); + return 0; +} + +int OptionsInit(WPARAM wParam, LPARAM) +{ + OPTIONSDIALOGPAGE odp = { 0 }; + + odp.cbSize = sizeof(odp); + odp.position = -790000000; + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.pszTitle = (char*)PluginName; + odp.pszGroup = LPGEN("Services"); + odp.flags = ODPF_BOLDGROUPS; + odp.pfnDlgProc = DlgProcOptions; + Options_AddPage(wParam, &odp); + + return 0; +} + +static int ToolbarModulesLoaded(WPARAM, LPARAM) +{ + TTBButton tbb = {0}; + tbb.cbSize = sizeof(TTBButton); + + tbb.pszService = MS_CRASHDUMPER_STORETOCLIP; + tbb.name = tbb.pszTooltipUp = LPGEN("Version Information To Clipboard"); + tbb.hIconHandleUp = GetIconHandle("storeToClip"); + tbb.dwFlags = TTBBF_VISIBLE; + TopToolbar_AddButton(&tbb); + + tbb.pszService = MS_CRASHDUMPER_STORETOFILE; + tbb.name = tbb.pszTooltipUp = LPGEN("Version Information To File"); + tbb.hIconHandleUp = GetIconHandle("storeToFile"); + tbb.dwFlags = 0; + TopToolbar_AddButton(&tbb); + + tbb.pszService = MS_CRASHDUMPER_VIEWINFO; + tbb.name = tbb.pszTooltipUp = LPGEN("Show Version Information"); + tbb.hIconHandleUp = GetIconHandle("showInfo"); + TopToolbar_AddButton(&tbb); + + tbb.pszService = MS_CRASHDUMPER_UPLOAD; + tbb.name = tbb.pszTooltipUp = LPGEN("Upload Version Information"); + tbb.hIconHandleUp = GetIconHandle("uploadInfo"); + TopToolbar_AddButton(&tbb); + return 0; +} + +static int ModulesLoaded(WPARAM, LPARAM) +{ + char temp[MAX_PATH]; + CallService(MS_SYSTEM_GETVERSIONTEXT, (WPARAM)SIZEOF(temp), (LPARAM)temp); + crs_a2t(vertxt, temp); + + profname = Utils_ReplaceVarsT(_T("%miranda_profilename%.dat")); + if (ServiceExists(MS_FOLDERS_REGISTER_PATH)) + { + profpath = _T("%miranda_userdata%"); + } + else + { + profpath = Utils_ReplaceVarsT(_T("%miranda_userdata%")); + } + + crs_sntprintf(CrashLogFolder, MAX_PATH, TEXT("%s\\CrashLog"), profpath); + crs_sntprintf(VersionInfoFolder, MAX_PATH, TEXT("%s"), profpath); + + SetExceptionHandler(); + + hCrashLogFolder = FoldersRegisterCustomPathT(PluginName, "Crash Reports", CrashLogFolder); + hVerInfoFolder = FoldersRegisterCustomPathT(PluginName, "Version Information", VersionInfoFolder); + + FoldersPathChanged(0, 0); + + + + hHooks[2] = HookEvent(ME_FOLDERS_PATH_CHANGED, FoldersPathChanged); + if (hHooks[3] == NULL) hHooks[3] = HookEvent(ME_TTB_MODULELOADED, ToolbarModulesLoaded); + + UploadInit(); + + CLISTMENUITEM mi = { 0 }; + + mi.cbSize = sizeof(mi); + + mi.popupPosition = 2000089999; + mi.position = 2000089999; + mi.flags = CMIF_ROOTPOPUP | CMIF_ICONFROMICOLIB | CMIF_TCHAR; + mi.icolibItem = GetIconHandle("versionInfo"); + mi.ptszName = LPGENT("Version Information"); + mi.pszPopupName = (char *)-1; + HANDLE hMenuRoot = Menu_AddMainMenuItem(&mi); + + mi.flags = CMIF_CHILDPOPUP | CMIF_ICONFROMICOLIB | CMIF_TCHAR; + mi.pszPopupName = (char *)hMenuRoot; + mi.popupPosition = 0; + + mi.position = 2000089995; + mi.ptszName = LPGENT("Copy to clipboard"); + mi.icolibItem = GetIconHandle("storeToClip"); + mi.pszService = MS_CRASHDUMPER_STORETOCLIP; + Menu_AddMainMenuItem(&mi); + + mi.position = 2000089996; + mi.ptszName = LPGENT("Store to file"); + mi.icolibItem = GetIconHandle("storeToFile"); + mi.pszService = MS_CRASHDUMPER_STORETOFILE; + Menu_AddMainMenuItem(&mi); + + mi.position = 2000089997; + mi.ptszName = LPGENT("Show"); + mi.icolibItem = GetIconHandle("showInfo"); + mi.pszService = MS_CRASHDUMPER_VIEWINFO; + Menu_AddMainMenuItem(&mi); + + mi.popupPosition = 1; + mi.position = 2000089998; + mi.ptszName = LPGENT("Show with DLLs"); + mi.icolibItem = GetIconHandle("showInfo"); + mi.pszService = MS_CRASHDUMPER_VIEWINFO; + Menu_AddMainMenuItem(&mi); + + mi.popupPosition = 0; + mi.position = 2000089999; + mi.ptszName = LPGENT("Upload"); + mi.icolibItem = GetIconHandle("uploadInfo"); + mi.pszService = MS_CRASHDUMPER_UPLOAD; + Menu_AddMainMenuItem(&mi); + + mi.position = 2000099990; + mi.ptszName = LPGENT("Open crash report directory"); + mi.icolibItem = LoadSkinnedIconHandle(SKINICON_EVENT_FILE); + mi.pszService = MS_CRASHDUMPER_URL; + Menu_AddMainMenuItem(&mi); + + mi.popupPosition = 1; + mi.position = 2000099991; + mi.ptszName = LPGENT("Open miranda-vi.org"); + mi.icolibItem = LoadSkinnedIconHandle(SKINICON_EVENT_URL); + mi.pszService = MS_CRASHDUMPER_URL; + Menu_AddMainMenuItem(&mi); + + HOTKEYDESC hk = {0}; + hk.cbSize = sizeof(hk); + hk.pszSection = PluginName; + + hk.pszDescription = LPGEN("Copy Version Info to clipboard"); + hk.pszName = "CopyVerInfo"; + hk.pszService = MS_CRASHDUMPER_STORETOCLIP; + Hotkey_Register(&hk); + + hk.pszDescription = LPGEN("Show Version Info"); + hk.pszName = "ShowVerInfo"; + hk.pszService = MS_CRASHDUMPER_VIEWINFO; + Hotkey_Register(&hk); + + if (servicemode) ViewVersionInfo(0, 0); + else + { + if (DBGetContactSettingByte(NULL, PluginName, "UploadChanged", 0) && !ProcessVIHash(false)) + UploadVersionInfo(0, 0xa1); + } + + CheckForOtherCrashReportingPlugins(); + return 0; +} + +static int PreShutdown(WPARAM, LPARAM) +{ + unsigned i; + + DestroyAllWindows(); + UploadClose(); + + for (i=0; i. +*/ + +#include "utils.h" +#include + +struct _tag_iconList +{ + const char* szDescr; + const char* szName; + int defIconID; +} +static const iconList[] = +{ + { "Version Information", "versionInfo", IDI_VI }, + { "Copy To Clipboard", "storeToClip", IDI_VITOCLIP }, + { "Store to file", "storeToFile", IDI_VITOFILE }, + { "Show", "showInfo", IDI_VISHOW }, + { "Upload", "uploadInfo", IDI_VIUPLOAD }, +}; + +static HANDLE hIconLibItem[SIZEOF(iconList)]; + +void InitIcons(void) +{ + char szFile[MAX_PATH]; + char szSettingName[100]; + SKINICONDESC sid = {0}; + + sid.cbSize = sizeof(SKINICONDESC); + sid.pszDefaultFile = szFile; + sid.pszName = szSettingName; + sid.pszSection = (char*)PluginName; + + GetModuleFileNameA(hInst, szFile, MAX_PATH); + + for (unsigned i = 0; i < SIZEOF(iconList); i++) + { + mir_snprintf(szSettingName, sizeof(szSettingName), "%s_%s", PluginName, iconList[i].szName); + + sid.pszDescription = (char*)iconList[i].szDescr; + sid.iDefaultIndex = -iconList[i].defIconID; + hIconLibItem[i] = Skin_AddIcon(&sid); + } +} + +HICON LoadIconEx(const char* name, bool big) +{ + char szSettingName[100]; + mir_snprintf(szSettingName, sizeof(szSettingName), "%s_%s", PluginName, name); + return (HICON)CallService(MS_SKIN2_GETICON, big, (LPARAM)szSettingName); +} + +HANDLE GetIconHandle(const char* name) +{ + unsigned i; + for (i=0; i < SIZEOF(iconList); i++) + if (strcmp(iconList[i].szName, name) == 0) + return hIconLibItem[i]; + return NULL; +} + +void ReleaseIconEx(const char* name) +{ + char szSettingName[100]; + mir_snprintf(szSettingName, sizeof(szSettingName), "%s_%s", PluginName, name); + CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM)szSettingName); +} + +void ReleaseIconEx(HICON hIcon) +{ + CallService(MS_SKIN2_RELEASEICON, (WPARAM)hIcon, 0); +} diff --git a/plugins/CrashDumper/src/dumper.cpp b/plugins/CrashDumper/src/dumper.cpp new file mode 100644 index 0000000000..bae091a023 --- /dev/null +++ b/plugins/CrashDumper/src/dumper.cpp @@ -0,0 +1,745 @@ +/* +Miranda Crash Dumper Plugin +Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "utils.h" + +extern TCHAR* vertxt; +extern TCHAR* profname; +extern TCHAR* profpath; + + +void CreateMiniDump(HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr) +{ + MINIDUMP_EXCEPTION_INFORMATION exceptionInfo; + exceptionInfo.ThreadId = GetCurrentThreadId(); + exceptionInfo.ExceptionPointers = exc_ptr; + exceptionInfo.ClientPointers = false; + + MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), + hDumpFile, MiniDumpNormal, &exceptionInfo, NULL, NULL); +} + + +void WriteBBFile(bkstring& buffer, bool hdr) +{ + static const TCHAR header[] = TEXT("[quote][size=1]"); + static const TCHAR footer[] = TEXT("[/size][/quote]"); + + buffer.append(hdr ? header : footer); +} + + +void WriteUtfFile(HANDLE hDumpFile, char* bufu) +{ + DWORD bytes; + + static const unsigned char bytemark[] = { 0xEF, 0xBB, 0xBF }; + WriteFile(hDumpFile, bytemark, 3, &bytes, NULL); + WriteFile(hDumpFile, bufu, (DWORD)strlen(bufu), &bytes, NULL); +} + + +BOOL CALLBACK LoadedModules64(LPCSTR, DWORD64 ModuleBase, ULONG ModuleSize, PVOID UserContext) +{ + bkstring& buffer = *(bkstring*)UserContext; + + const HMODULE hModule = (HMODULE)ModuleBase; + + TCHAR path[MAX_PATH]; + GetModuleFileName(hModule, path, MAX_PATH); + + buffer.appendfmt(TEXT("%s %p - %p"), path, (LPVOID)ModuleBase, (LPVOID)(ModuleBase + ModuleSize)); + + GetVersionInfo(hModule, buffer); + + TCHAR timebuf[30] = TEXT(""); + GetLastWriteTime(path, timebuf, 30); + + buffer.appendfmt(TEXT(" [%s]\r\n"), timebuf); + + return TRUE; +} + +typedef struct _FindData +{ + DWORD64 Offset; IMAGEHLP_MODULE64* pModule; +} FindData; + + +BOOL CALLBACK LoadedModulesFind64(LPCSTR ModuleName, DWORD64 ModuleBase, ULONG ModuleSize, PVOID UserContext) +{ + FindData* data = (FindData*)UserContext; + + if ((DWORD)(data->Offset - ModuleBase) < ModuleSize) + { + const size_t len = SIZEOF(data->pModule->ModuleName); + strncpy(data->pModule->ModuleName, ModuleName, len); + data->pModule->ModuleName[len-1] = 0; + + data->pModule->BaseOfImage = ModuleBase; + + const HMODULE hModule = (HMODULE)ModuleBase; + GetModuleFileNameA(hModule, data->pModule->LoadedImageName, SIZEOF(data->pModule->LoadedImageName)); + + return FALSE; + } + return TRUE; +} + + +void GetLinkedModulesInfo(TCHAR *moduleName, bkstring &buffer) +{ + HANDLE hDllFile = CreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hDllFile == INVALID_HANDLE_VALUE) return; + + HANDLE hDllMapping = CreateFileMapping(hDllFile, NULL, PAGE_READONLY, 0, 0, NULL); + if (hDllMapping == INVALID_HANDLE_VALUE) + { + CloseHandle(hDllFile); + return; + } + + LPVOID dllAddr = MapViewOfFile(hDllMapping, FILE_MAP_READ, 0, 0, 0); + + + static const TCHAR format[] = TEXT(" Plugin statically linked to missing module: %S\r\n"); + + + __try + { + PIMAGE_NT_HEADERS nthdrs = ImageNtHeader(dllAddr); + + ULONG tableSize; + PIMAGE_IMPORT_DESCRIPTOR importData = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(dllAddr, FALSE, + IMAGE_DIRECTORY_ENTRY_IMPORT, &tableSize); + if (importData) + { + while (importData->Name) + { + char* moduleName = (char*)ImageRvaToVa(nthdrs, dllAddr, importData->Name, NULL); + if (!SearchPathA(NULL, moduleName, NULL, NULL, 0, NULL)) + { + buffer.appendfmt(format, moduleName); + } + importData++; //go to next record + } + } + + bool found = false; + PIMAGE_EXPORT_DIRECTORY exportData = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(dllAddr, FALSE, + IMAGE_DIRECTORY_ENTRY_EXPORT, &tableSize); + if (exportData) + { + ULONG* funcAddr = (ULONG*)ImageRvaToVa(nthdrs, dllAddr, exportData->AddressOfNames, NULL); + for(unsigned i=0; iNumberOfNames && !found; ++i) + { + char* funcName = (char*)ImageRvaToVa(nthdrs, dllAddr, funcAddr[i], NULL); + found = strcmp(funcName, "MirandaPluginInfoEx") == 0 || strcmp(funcName, "MirandaPluginInfo") == 0; + if (strcmp(funcName, "DatabasePluginInfo") == 0) + { + buffer.append(TEXT(" This dll is a Miranda database plugin, another database is active right now\r\n")); + found = true; + } + } + } + if (!found) + buffer.append(TEXT(" This dll is not a Miranda plugin and should be removed from plugins directory\r\n")); + } + __except(EXCEPTION_EXECUTE_HANDLER) {} + + UnmapViewOfFile(dllAddr); + CloseHandle(hDllMapping); + CloseHandle(hDllFile); +} + + +struct ListItem +{ + ListItem() : str(), next(NULL) {} + + bkstring str; + ListItem *next; +}; + +static void GetPluginsString(bkstring& buffer, unsigned& flags) +{ + buffer.appendfmt(TEXT("Service Mode: %s\r\n"), servicemode ? TEXT("Yes") : TEXT("No")); + + TCHAR path[MAX_PATH]; + GetModuleFileName(NULL, path, MAX_PATH); + + LPTSTR fname = _tcsrchr(path, TEXT('\\')); + if (fname == NULL) fname = path; + crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\plugins\\*.dll")); + + WIN32_FIND_DATA FindFileData; + HANDLE hFind = FindFirstFile(path, &FindFileData); + if (hFind == INVALID_HANDLE_VALUE) return; + + size_t count = 0, ucount = 0; + + bkstring ubuffer; + ListItem* dlllist = NULL; + + + static const TCHAR format[] = TEXT("%c %s v.%s%d.%d.%d.%d%s [%s] - %S %s\r\n"); + + + do + { + bool loaded = false; + crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\plugins\\%s"), FindFileData.cFileName); + HMODULE hModule = GetModuleHandle(path); + if (hModule == NULL && servicemode) + { + hModule = LoadLibrary(path); + loaded = true; + } + if (hModule == NULL) + { + if ((flags & VI_FLAG_PRNVAR) && IsPluginEnabled(FindFileData.cFileName)) + { + TCHAR timebuf[30] = TEXT(""); + GetLastWriteTime(&FindFileData.ftLastWriteTime, timebuf, 30); + + ubuffer.appendfmt(format, TEXT(' '), FindFileData.cFileName, + (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), + 0, 0, 0, 0, + (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""), + timebuf, "", TEXT("")); + + GetLinkedModulesInfo(path, ubuffer); + ubuffer.append(TEXT("\r\n")); + + ++ucount; + } + continue; + } + + PLUGININFOEX* pi = GetMirInfo(hModule); + if (pi != NULL) + { + TCHAR timebuf[30] = TEXT(""); + GetLastWriteTime(&FindFileData.ftLastWriteTime, timebuf, 30); + + bool ep = (size_t)pi->cbSize > sizeof(PLUGININFOEX); + const TCHAR *unica = (ep && ((PLUGININFOEX*)pi)->flags & 1) ? TEXT("|Unicode aware|") : TEXT(""); + + ListItem* lst = new ListItem; + DWORD ver = pi->version; + lst->str.appendfmt(format, ep ? TEXT('\xa4') : TEXT(' '), FindFileData.cFileName, + (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), + HIBYTE(HIWORD(ver)), LOBYTE(HIWORD(ver)), HIBYTE(LOWORD(ver)), LOBYTE(LOWORD(ver)), + (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""), + timebuf, pi->shortName ? pi->shortName : "", unica); + + ListItem* lsttmp = dlllist; + ListItem* lsttmppv = NULL; + while (lsttmp != NULL) + { + size_t sz = min(lsttmp->str.size(), lst->str.size()) - 2; + if (lsttmp->str.comparei(2, sz, lst->str, 2, sz) > 0) break; + lsttmppv = lsttmp; + lsttmp = lsttmp->next; + } + lst->next = lsttmp; + if (lsttmppv == NULL) + dlllist = lst; + else + lsttmppv->next = lst; + + if (_tcsicmp(FindFileData.cFileName, TEXT("weather.dll")) == 0) + flags |= VI_FLAG_WEATHER; + + ++count; + } + if (loaded) FreeLibrary(hModule); + } + while (FindNextFile(hFind, &FindFileData)); + FindClose(hFind); + + buffer.appendfmt(TEXT("\r\n%sActive Plugins (%u):%s\r\n"), + (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), count, (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT("")); + + ListItem* lsttmp = dlllist; + while (lsttmp != NULL) + { + buffer.append(lsttmp->str); + ListItem* lsttmp1 = lsttmp->next; + delete lsttmp; + lsttmp = lsttmp1; + } + + if (ucount) + { + buffer.appendfmt(TEXT("\r\n%sUnloadable Plugins (%u):%s\r\n"), + (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), ucount, (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT("")); + buffer.append(ubuffer); + } +} + + +struct ProtoCount +{ + char countse; + char countsd; + bool nloaded; +}; + +static void GetProtocolStrings(bkstring& buffer) +{ + PROTOACCOUNT **accList; + int accCount, protoCount; + int i, j; + + PROTOCOLDESCRIPTOR **protoList; + if (ProtoEnumAccounts(&accCount, &accList) == CALLSERVICE_NOTFOUND || (accCount > 0 && accList[0]->cbSize == 0)) + { + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&protoCount, (LPARAM)&protoList); + for (i = 0; i < protoCount; i++) + { + if (protoList[i]->type != PROTOTYPE_PROTOCOL) continue; + + TCHAR* nm; + crsi_a2t(nm, protoList[i]->szName); + buffer.appendfmt(TEXT(" 1 - %s\r\n"), nm); + } + } + else + { + CallService(MS_PROTO_ENUMPROTOS, (WPARAM)&protoCount, (LPARAM)&protoList); + + int protoCountMy = 0; + char** protoListMy = (char**)alloca((protoCount + accCount) * sizeof(char*)); + + for (i = 0; i < protoCount; i++) + { + if (protoList[i]->type != PROTOTYPE_PROTOCOL) continue; + protoListMy[protoCountMy++] = protoList[i]->szName; + } + + for (j = 0; j < accCount; j++) + { + for (i = 0; i < protoCountMy; i++) + { + if (strcmp(protoListMy[i], accList[j]->szProtoName) == 0) + break; + } + if (i == protoCountMy) + protoListMy[protoCountMy++] = accList[j]->szProtoName; + } + + ProtoCount *protos = (ProtoCount*)alloca(sizeof(ProtoCount) * protoCountMy); + memset(protos, 0, sizeof(ProtoCount) * protoCountMy); + + for (j = 0; j < accCount; j++) + { + for (i = 0; i < protoCountMy; i++) + { + if (strcmp(protoListMy[i], accList[j]->szProtoName) == 0) + { + protos[i].nloaded = accList[j]->bDynDisabled != 0; + if (IsAccountEnabled(accList[j])) + ++protos[i].countse; + else + ++protos[i].countsd; + break; + } + } + } + for (i = 0; i < protoCountMy; i++) + { + TCHAR* nm; + crsi_a2t(nm, protoListMy[i]); + buffer.appendfmt(TEXT("%-24s %d - Enabled %d - Disabled %sLoaded\r\n"), nm, protos[i].countse, + protos[i].countsd, protos[i].nloaded ? _T("Not ") : _T("")); + } + } +} + + +static void GetWeatherStrings(bkstring& buffer, unsigned flags) +{ + TCHAR path[MAX_PATH]; + GetModuleFileName(NULL, path, MAX_PATH); + + LPTSTR fname = _tcsrchr(path, TEXT('\\')); + if (fname == NULL) fname = path; + crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\plugins\\weather\\*.ini")); + + WIN32_FIND_DATA FindFileData; + HANDLE hFind = FindFirstFile(path, &FindFileData); + if (hFind == INVALID_HANDLE_VALUE) return; + + do + { + if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; + + crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\plugins\\weather\\%s"), FindFileData.cFileName); + HANDLE hDumpFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hDumpFile != INVALID_HANDLE_VALUE) + { + char buf[8192]; + + DWORD bytes = 0; + ReadFile(hDumpFile, buf, 8190, &bytes, NULL); + buf[bytes] = 0; + + char* ver = strstr(buf, "Version="); + if (ver != NULL) + { + char *endid = strchr(ver, '\r'); + if (endid != NULL) *endid = 0; + else + { + endid = strchr(ver, '\n'); + if (endid != NULL) *endid = 0; + } + ver += 8; + } + + char *id = strstr(buf, "Name="); + if (id != NULL) + { + char *endid = strchr(id, '\r'); + if (endid != NULL) *endid = 0; + else + { + endid = strchr(id, '\n'); + if (endid != NULL) *endid = 0; + } + id += 5; + } + + TCHAR timebuf[30] = TEXT(""); + GetLastWriteTime(&FindFileData.ftLastWriteTime, timebuf, 30); + + + static const TCHAR format[] = TEXT(" %s v.%s%S%s [%s] - %S\r\n"); + + buffer.appendfmt(format, FindFileData.cFileName, + (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), + ver, + (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT(""), + timebuf, id); + CloseHandle(hDumpFile); + } + } + while (FindNextFile(hFind, &FindFileData)); + FindClose(hFind); +} + + +static void GetIconStrings(bkstring& buffer) +{ + TCHAR path[MAX_PATH]; + GetModuleFileName(NULL, path, MAX_PATH); + + LPTSTR fname = _tcsrchr(path, TEXT('\\')); + if (fname == NULL) fname = path; + crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\Icons\\*.*")); + + WIN32_FIND_DATA FindFileData; + HANDLE hFind = FindFirstFile(path, &FindFileData); + if (hFind == INVALID_HANDLE_VALUE) return; + + do + { + if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; + + TCHAR timebuf[30] = TEXT(""); + GetLastWriteTime(&FindFileData.ftLastWriteTime, timebuf, 30); + + buffer.appendfmt(TEXT(" %s [%s]\r\n"), FindFileData.cFileName, timebuf); + } + while (FindNextFile(hFind, &FindFileData)); + FindClose(hFind); +} + + +void PrintVersionInfo(bkstring& buffer, unsigned flags) +{ + GetProcessorString(buffer); + buffer.append(TEXT("\r\n")); + + GetFreeMemoryString(buffer); + buffer.append(TEXT("\r\n")); + + GetOSDisplayString(buffer); + buffer.append(TEXT("\r\n")); + + GetInternetExplorerVersion(buffer); + buffer.append(TEXT("\r\n")); + + GetAdminString(buffer); + buffer.append(TEXT("\r\n")); + + GetLanguageString(buffer); + buffer.append(TEXT("\r\n")); + + TCHAR *profpathfull = Utils_ReplaceVarsT(profpath); + if (flags & VI_FLAG_PRNVAR) + { + GetFreeDiskString(profpathfull, buffer); + buffer.append(TEXT("\r\n")); + } + + buffer.appendfmt(TEXT("\r\nMiranda IM Version: %s"), vertxt); + GetWow64String(buffer); + buffer.append(TEXT("\r\n")); + + TCHAR path[MAX_PATH], mirtime[30]; + GetModuleFileName(NULL, path, MAX_PATH); + GetLastWriteTime(path, mirtime, 30); + buffer.appendfmt(TEXT("Build time: %s\r\n"), mirtime); + + TCHAR profpn[MAX_PATH]; + crs_sntprintf(profpn, SIZEOF(profpn), TEXT("%s\\%s"), profpathfull, profname); + + buffer.appendfmt(TEXT("Profile: %s\r\n"), profpn); + + if (flags & VI_FLAG_PRNVAR) + { + WIN32_FIND_DATA FindFileData; + + HANDLE hFind = FindFirstFile(profpn, &FindFileData); + if (hFind != INVALID_HANDLE_VALUE) + { + FindClose(hFind); + + unsigned __int64 fsize = (unsigned __int64)FindFileData.nFileSizeHigh << 32 | FindFileData.nFileSizeLow; + buffer.appendfmt(TEXT("Profile size: %I64u Bytes\r\n"), fsize), + + GetLastWriteTime(&FindFileData.ftCreationTime, mirtime, 30); + buffer.appendfmt(TEXT("Profile creation date: %s\r\n"), mirtime); + } + } + mir_free(profpathfull); + + GetLanguagePackString(buffer); + buffer.append(TEXT("\r\n")); + + buffer.appendfmt(TEXT("Nightly: %s\r\n"), _tcsstr(vertxt, TEXT("alpha")) ? TEXT("Yes") : TEXT("No")); + buffer.appendfmt(TEXT("Unicode: %s\r\n"), _tcsstr(vertxt, TEXT("Unicode")) ? TEXT("Yes") : TEXT("No")); + + GetPluginsString(buffer, flags); + + if (flags & VI_FLAG_WEATHER) + { + buffer.appendfmt(TEXT("\r\n%sWeather ini files:%s\r\n-------------------------------------------------------------------------------\r\n"), + (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), + (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT("")); + GetWeatherStrings(buffer, flags); + } + + if (flags & VI_FLAG_PRNVAR && !servicemode) + { + buffer.appendfmt(TEXT("\r\n%sProtocols and Accounts:%s\r\n-------------------------------------------------------------------------------\r\n"), + (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), + (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT("")); + GetProtocolStrings(buffer); + } + + if (flags & VI_FLAG_PRNVAR) + { + buffer.appendfmt(TEXT("\r\n%sIcon Packs:%s\r\n-------------------------------------------------------------------------------\r\n"), + (flags & VI_FLAG_FORMAT) ? TEXT("[b]") : TEXT(""), + (flags & VI_FLAG_FORMAT) ? TEXT("[/b]") : TEXT("")); + GetIconStrings(buffer); + } + + if (flags & VI_FLAG_PRNDLL) + { + __try + { + buffer.append(TEXT("\r\nLoaded Modules:\r\n-------------------------------------------------------------------------------\r\n")); + EnumerateLoadedModules64(GetCurrentProcess(), LoadedModules64, &buffer); + } + __except(EXCEPTION_EXECUTE_HANDLER) {} + } + + if (flags & (VI_FLAG_PRNVAR | VI_FLAG_PRNDLL)) UnloadDbgHlp(); +} + + +void CreateCrashReport(HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr, const TCHAR* msg) +{ + if (exc_ptr->ContextRecord == NULL || (exc_ptr->ContextRecord->ContextFlags & CONTEXT_CONTROL) == 0) + return; + + CONTEXT context = *exc_ptr->ContextRecord; + + STACKFRAME64 frame = {0}; + +#if defined(_AMD64_) +#define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_AMD64 + frame.AddrPC.Offset = context.Rip; + frame.AddrFrame.Offset = context.Rbp; + frame.AddrStack.Offset = context.Rsp; +#elif defined(_IA64_) +#define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_IA64 + frame.AddrPC.Offset = context.StIIP; + frame.AddrFrame.Offset = context.AddrBStore; + frame.AddrStack.Offset = context.SP; +#else +#define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_I386 + frame.AddrPC.Offset = context.Eip; + frame.AddrFrame.Offset = context.Ebp; + frame.AddrStack.Offset = context.Esp; +#endif + + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Mode = AddrModeFlat; + + const PLUGININFOEX *pluginInfoEx = GetPluginInfoEx(); + + bkstring buffer; + buffer.reserve(0x5000); + + TCHAR curtime[30]; + GetISO8061Time(NULL, curtime, 30); + + buffer.appendfmt(TEXT("Miranda Crash Report from %s. Crash Dumper v.%d.%d.%d.%d\r\n"), + curtime, + HIBYTE(HIWORD(pluginInfoEx->version)), LOBYTE(HIWORD(pluginInfoEx->version)), + HIBYTE(LOWORD(pluginInfoEx->version)), LOBYTE(LOWORD(pluginInfoEx->version))); + + size_t crashpos = buffer.size(); + + ReadableExceptionInfo(exc_ptr->ExceptionRecord, buffer); + buffer.append(TEXT("\r\n")); + + const HANDLE hProcess = GetCurrentProcess(); + + if (&SymSetOptions) + SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES); + SymInitialize(hProcess, NULL, TRUE); + + buffer.append(TEXT("\r\nStack Trace:\r\n---------------------------------------------------------------\r\n")); + + for (int i=81; --i;) + { + /* + char symbuf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + 4] = {0}; + PSYMBOL_INFO pSym = (PSYMBOL_INFO)symbuf; + pSym->SizeOfStruct = sizeof(SYMBOL_INFO); + pSym->MaxNameLen = MAX_SYM_NAME; + */ + + char symbuf[sizeof(IMAGEHLP_SYMBOL64) + MAX_SYM_NAME * sizeof(TCHAR) + 4] = {0}; + PIMAGEHLP_SYMBOL64 pSym = (PIMAGEHLP_SYMBOL64)symbuf; + pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); + pSym->MaxNameLength = MAX_SYM_NAME; + + IMAGEHLP_LINE64 Line = {0}; + Line.SizeOfStruct = sizeof(Line); + + IMAGEHLP_MODULE64 Module = {0}; + Module.SizeOfStruct = sizeof(IMAGEHLP_MODULE64_V2); + + char undName[MAX_SYM_NAME] = ""; + char undFullName[MAX_SYM_NAME] = ""; + + DWORD64 offsetFromSmybol = 0; + DWORD offsetFromLine = 0; + + if (!StackWalk64(IMAGE_FILE_MACHINE, hProcess, GetCurrentThread(), &frame, &context, + NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL)) break; + + if (frame.AddrPC.Offset == frame.AddrReturn.Offset) break; + + if (frame.AddrPC.Offset != 0) + { + if (SymGetSymFromAddr64(hProcess, frame.AddrPC.Offset, &offsetFromSmybol, pSym)) + // if (SymFromAddr(hProcess, frame.AddrPC.Offset, &offsetFromSmybol, pSym)) + { + UnDecorateSymbolName(pSym->Name, undName, MAX_SYM_NAME, UNDNAME_NAME_ONLY); + UnDecorateSymbolName(pSym->Name, undFullName, MAX_SYM_NAME, UNDNAME_COMPLETE); + } + + SymGetLineFromAddr64(hProcess, frame.AddrPC.Offset, &offsetFromLine, &Line); + SymGetModuleInfo64(hProcess, frame.AddrPC.Offset, &Module); + if (Module.ModuleName[0] == 0) + { + FindData data; + data.Offset = frame.AddrPC.Offset; + data.pModule = &Module; + EnumerateLoadedModules64(hProcess, LoadedModulesFind64, &data); + } + } + + const char* name; + if (undFullName[0] != 0) + name = undFullName; + else if (undName[0] != 0) + name = undName; + else if (pSym->Name[0] != 0) + name = pSym->Name; + else + name = "(function-name not available)"; + + const char *lineFileName = Line.FileName ? Line.FileName : "(filename not available)"; + const char *moduleName = Module.ModuleName[0] ? Module.ModuleName : "(module-name not available)"; + + if (crashpos != 0) + { + HMODULE hModule = (HMODULE)Module.BaseOfImage; + PLUGININFOEX *pi = GetMirInfo(hModule); + if (pi != NULL) + { + + static const TCHAR formatc[] = TEXT("\r\nLikely cause of the crash plugin: %S\r\n\r\n"); + + if (pi->shortName) + { + bkstring crashcause; + crashcause.appendfmt(formatc, pi->shortName); + buffer.insert(crashpos, crashcause); + } + crashpos = 0; + } + } + + + static const TCHAR formatd[] = TEXT("%p (%S %p): %S (%d): %S\r\n"); + + buffer.appendfmt(formatd, + (LPVOID)frame.AddrPC.Offset, moduleName, (LPVOID)Module.BaseOfImage, + lineFileName, Line.LineNumber, name); + } + SymCleanup(hProcess); + buffer.append(TEXT("\r\n")); + + PrintVersionInfo(buffer, VI_FLAG_PRNDLL); + + + int len = WideCharToMultiByte(CP_UTF8, 0, buffer.c_str(), -1, NULL, 0, NULL, NULL); + char* dst = (char*)(len > 8192 ? malloc(len) : alloca(len)); + WideCharToMultiByte(CP_UTF8, 0, buffer.c_str(), -1, dst, len, NULL, NULL); + + WriteUtfFile(hDumpFile, dst); + + if (len > 8192) free(dst); + + + if (msg && MessageBox(NULL, msg, TEXT("Miranda Crash Dumper"), MB_YESNO | MB_ICONERROR | MB_TASKMODAL | MB_DEFBUTTON2 | MB_TOPMOST) == IDYES) + StoreStringToClip(buffer); +} diff --git a/plugins/CrashDumper/src/exhndlr.cpp b/plugins/CrashDumper/src/exhndlr.cpp new file mode 100644 index 0000000000..93406efaa8 --- /dev/null +++ b/plugins/CrashDumper/src/exhndlr.cpp @@ -0,0 +1,207 @@ +#include "utils.h" +#include "crtdbg.h" + +static PVOID exchndlr, exchndlrv; +static pfnExceptionFilter threadfltr; +static PEXCEPTION_POINTERS lastptr; + +static HMODULE hKernel = GetModuleHandle(TEXT("kernel32.dll")); + +tAddVectoredExceptionHandler pAddVectoredExceptionHandler = (tAddVectoredExceptionHandler)GetProcAddress(hKernel, "AddVectoredExceptionHandler"); +tRemoveVectoredExceptionHandler pRemoveVectoredExceptionHandler = (tRemoveVectoredExceptionHandler)GetProcAddress(hKernel, "RemoveVectoredExceptionHandler"); +tRtlCaptureContext pRtlCaptureContext = (tRtlCaptureContext)GetProcAddress(hKernel, "RtlCaptureContext"); + +void SetExceptionHandler(void) +{ + // if (pAddVectoredExceptionHandler && !exchndlrv) + // exchndlrv = pAddVectoredExceptionHandler(0, myfilterv); + /*exchndlr = */ SetUnhandledExceptionFilter(myfilter); +} + +void RemoveExceptionHandler(void) +{ + if (pRemoveVectoredExceptionHandler && exchndlrv) + pRemoveVectoredExceptionHandler(exchndlrv); + SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)exchndlr); + exchndlr = NULL; + exchndlrv = NULL; +} + +void UnloadDbgHlp(void) +{ +#ifdef _MSC_VER +#if _MSC_VER > 1200 + __FUnloadDelayLoadedDLL2("dbghelp.dll"); +#else + __FUnloadDelayLoadedDLL("dbghelp.dll"); +#endif +#endif +} + +int myDebugFilter(unsigned int code, PEXCEPTION_POINTERS ep) +{ + if (code == VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND) || + code == VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND)) + { + PDelayLoadInfo dlld = (PDelayLoadInfo)ep->ExceptionRecord->ExceptionInformation[0]; + + char str[256]; + int off = mir_snprintf(str, SIZEOF(str), "dbghelp.dll v.5.0 or later required to provide a crash report\n"); + off += mir_snprintf(str+off, SIZEOF(str)-off, "Missing Module: %s ", dlld->szDll); + + if (dlld->dlp.fImportByName) + mir_snprintf(str+off, SIZEOF(str)-off, "Function: %s ", dlld->dlp.szProcName); + else + mir_snprintf(str+off, SIZEOF(str)-off, "Ordinal: %x ", dlld->dlp.dwOrdinal); + + MessageBoxA(NULL, str, "Miranda Crash Dumper", MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_TOPMOST); + } + + return EXCEPTION_EXECUTE_HANDLER; +} + + +void myfilterWorker(PEXCEPTION_POINTERS exc_ptr, bool notify) +{ + TCHAR path[MAX_PATH]; + SYSTEMTIME st; + HANDLE hDumpFile = NULL; + + GetLocalTime(&st); + CreateDirectoryTree(CrashLogFolder); + + __try + { + if (dtsubfldr) + { + crs_sntprintf(path, MAX_PATH, TEXT("%s\\%02d.%02d.%02d"), CrashLogFolder, st.wYear, st.wMonth, st.wDay); + CreateDirectory(path, NULL); + crs_sntprintf(path, MAX_PATH, TEXT("%s\\%02d.%02d.%02d\\crash%02d%02d%02d%02d%02d%02d.mdmp"), CrashLogFolder, + st.wYear, st.wMonth, st.wDay, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + } + else + { + crs_sntprintf(path, MAX_PATH, TEXT("%s\\crash%02d%02d%02d%02d%02d%02d.mdmp"), CrashLogFolder, + st.wYear, st.wMonth, st.wDay, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + } + hDumpFile = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + if (hDumpFile != INVALID_HANDLE_VALUE) + CreateMiniDump(hDumpFile, exc_ptr); + else if (GetLastError() != ERROR_ALREADY_EXISTS) + MessageBox(NULL, TranslateT("Crash Report write location is inaccesible"), + TEXT("Miranda Crash Dumper"), MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_TOPMOST); + + } + __except(EXCEPTION_EXECUTE_HANDLER) {} + + bool empty = GetFileSize(hDumpFile, NULL) == 0; + CloseHandle(hDumpFile); + if (empty) DeleteFile(path); + + __try + { + if (dtsubfldr) + { + crs_sntprintf(path, MAX_PATH, TEXT("%s\\%02d.%02d.%02d"), CrashLogFolder, st.wYear, st.wMonth, st.wDay); + CreateDirectory(path, NULL); + crs_sntprintf(path, MAX_PATH, TEXT("%s\\%02d.%02d.%02d\\crash%02d%02d%02d%02d%02d%02d.txt"), CrashLogFolder, + st.wYear, st.wMonth, st.wDay, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + } + else + { + crs_sntprintf(path, MAX_PATH, TEXT("%s\\crash%02d%02d%02d%02d%02d%02d.txt"), CrashLogFolder, + st.wYear, st.wMonth, st.wDay, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + } + hDumpFile = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + + crs_sntprintf(path, MAX_PATH, TranslateT("Miranda crashed. Crash report stored in the folder:\n %s\n\n Would you like store it in the clipboard as well?"), CrashLogFolder); + + if (hDumpFile != INVALID_HANDLE_VALUE) + CreateCrashReport(hDumpFile, exc_ptr, notify ? path : NULL); + } + __except(myDebugFilter(GetExceptionCode(), GetExceptionInformation())) {} + + bool empty1 = GetFileSize(hDumpFile, NULL) == 0; + CloseHandle(hDumpFile); + if (empty1) DeleteFile(path); + + UnloadDbgHlp(); +} + +LONG WINAPI myfilter(PEXCEPTION_POINTERS exc_ptr) +{ + if (exc_ptr == lastptr) return EXCEPTION_EXECUTE_HANDLER; + lastptr = exc_ptr; + + myfilterWorker(exc_ptr, true); + + return exchndlr ? ((LPTOP_LEVEL_EXCEPTION_FILTER)exchndlr)(exc_ptr) : EXCEPTION_CONTINUE_SEARCH; +} + +LONG WINAPI myfilterv(PEXCEPTION_POINTERS exc_ptr) +{ + if (0xC0000000L <= exc_ptr->ExceptionRecord->ExceptionCode && 0xC0000500L >= exc_ptr->ExceptionRecord->ExceptionCode) + { + if (exc_ptr == lastptr) return EXCEPTION_EXECUTE_HANDLER; + lastptr = exc_ptr; + + myfilterWorker(exc_ptr, true); + } + return EXCEPTION_CONTINUE_SEARCH; +} + +DWORD MirandaThreadFilter(DWORD code, EXCEPTION_POINTERS* info) +{ + if (info != lastptr) + { + lastptr = info; + myfilterWorker(info, true); + } + return threadfltr(code, info); +} + +#if _MSC_VER >= 1400 +void InvalidParameterHandler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, UINT_PTR) +{ + EXCEPTION_RECORD ExceptionRecord = {0}; + CONTEXT ContextRecord = {0}; + EXCEPTION_POINTERS info = { &ExceptionRecord, &ContextRecord }; + + if (pRtlCaptureContext) + pRtlCaptureContext(&ContextRecord); + else + { + ContextRecord.ContextFlags = CONTEXT_ALL; + GetThreadContext(GetCurrentThread(), &ContextRecord); + } + +#if defined(_AMD64_) + ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.Rip; +#elif defined(_IA64_) + ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.BrRp; +#else + ExceptionRecord.ExceptionAddress = (PVOID)ContextRecord.Eip; +#endif + + ExceptionRecord.ExceptionCode = STATUS_INVALID_CRUNTIME_PARAMETER; + ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE; + + myfilterWorker(&info, true); +} +#endif + +void InitExceptionHandler(void) +{ +#if _MSC_VER >= 1400 + _set_invalid_parameter_handler(InvalidParameterHandler); +#endif + threadfltr = Miranda_SetExceptFilter(MirandaThreadFilter); + SetExceptionHandler(); +} + +void DestroyExceptionHandler(void) +{ + Miranda_SetExceptFilter(threadfltr); + RemoveExceptionHandler(); +} + diff --git a/plugins/CrashDumper/src/resource.h b/plugins/CrashDumper/src/resource.h new file mode 100644 index 0000000000..83d8a491e4 --- /dev/null +++ b/plugins/CrashDumper/src/resource.h @@ -0,0 +1,34 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by crshdmp.rc +// +#define IDD_VIEWVERSION 101 +#define IDR_CONTEXT 102 +#define IDI_VI 104 +#define IDI_VISHOW 105 +#define IDI_VITOCLIP 106 +#define IDI_VITOFILE 107 +#define IDI_VIUPLOAD 108 +#define IDD_OPTIONS 109 +#define IDC_VIEWVERSIONINFO 1001 +#define IDC_FILEVER 1003 +#define IDC_CLIPVER 1004 +#define IDC_USERNAME 1006 +#define IDC_PASSWORD 1007 +#define IDC_UPLOADCHN 1008 +#define IDC_CLASSICDATES 1009 +#define IDC_DATESUBFOLDER 1010 +#define IDM_COPY 40002 +#define IDM_COPYALL 40003 +#define IDM_SELECTALL 40004 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 110 +#define _APS_NEXT_COMMAND_VALUE 40005 +#define _APS_NEXT_CONTROL_VALUE 1011 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/CrashDumper/src/sdkstuff.h b/plugins/CrashDumper/src/sdkstuff.h new file mode 100644 index 0000000000..536a00bc40 --- /dev/null +++ b/plugins/CrashDumper/src/sdkstuff.h @@ -0,0 +1,124 @@ +/* +Miranda Crash Dumper Plugin +Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include + + +//#define DBGHELP_TRANSLATE_TCHAR + + +#ifndef __in_bcount_opt +#define __in_bcount_opt(x) +#endif + +#ifndef __out_bcount_opt +#define __out_bcount_opt(x) +#endif + +#include "dbghelp.h" + + +#ifndef PRODUCT_ULTIMATE + +#define PRODUCT_UNDEFINED 0x00000000 + +#define PRODUCT_ULTIMATE 0x00000001 +#define PRODUCT_HOME_BASIC 0x00000002 +#define PRODUCT_HOME_PREMIUM 0x00000003 +#define PRODUCT_ENTERPRISE 0x00000004 +#define PRODUCT_HOME_BASIC_N 0x00000005 +#define PRODUCT_BUSINESS 0x00000006 +#define PRODUCT_STANDARD_SERVER 0x00000007 +#define PRODUCT_DATACENTER_SERVER 0x00000008 +#define PRODUCT_SMALLBUSINESS_SERVER 0x00000009 +#define PRODUCT_ENTERPRISE_SERVER 0x0000000A +#define PRODUCT_STARTER 0x0000000B +#define PRODUCT_DATACENTER_SERVER_CORE 0x0000000C +#define PRODUCT_STANDARD_SERVER_CORE 0x0000000D +#define PRODUCT_ENTERPRISE_SERVER_CORE 0x0000000E +#define PRODUCT_ENTERPRISE_SERVER_IA64 0x0000000F +#define PRODUCT_BUSINESS_N 0x00000010 +#define PRODUCT_WEB_SERVER 0x00000011 +#define PRODUCT_CLUSTER_SERVER 0x00000012 +#define PRODUCT_HOME_SERVER 0x00000013 +#define PRODUCT_STORAGE_EXPRESS_SERVER 0x00000014 +#define PRODUCT_STORAGE_STANDARD_SERVER 0x00000015 +#define PRODUCT_STORAGE_WORKGROUP_SERVER 0x00000016 +#define PRODUCT_STORAGE_ENTERPRISE_SERVER 0x00000017 +#define PRODUCT_SERVER_FOR_SMALLBUSINESS 0x00000018 +#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM 0x00000019 + +#define PRODUCT_UNLICENSED 0xABCDABCD + +#define SM_TABLETPC 86 +#define SM_MEDIACENTER 87 +#define SM_STARTER 88 +#define SM_SERVERR2 89 + +#endif + +#ifndef VER_SUITE_STORAGE_SERVER +#define VER_SUITE_STORAGE_SERVER 0x00002000 +#define VER_SUITE_COMPUTE_SERVER 0x00004000 +#endif + +#ifndef PF_NX_ENABLED +#define PF_NX_ENABLED 12 +#endif + +typedef struct _IMAGEHLP_MODULE64_V2 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name +} IMAGEHLP_MODULE64_V2; + +typedef struct _IMAGEHLP_MODULEW64_V2 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + WCHAR ModuleName[32]; // module name + WCHAR ImageName[256]; // image name + WCHAR LoadedImageName[256]; // symbol file name +} IMAGEHLP_MODULEW64_V2; + +#ifdef DBGHELP_TRANSLATE_TCHAR +#define IMAGEHLP_MODULE64_V2 IMAGEHLP_MODULEW64_V2 +#endif + +typedef void (WINAPI *tGetNativeSystemInfo)(LPSYSTEM_INFO); +typedef BOOL (WINAPI *tGetProductInfo)(DWORD, DWORD, DWORD, DWORD, PDWORD); +typedef BOOL (WINAPI *tGlobalMemoryStatusEx)(LPMEMORYSTATUSEX lpBuffer); +typedef BOOL (WINAPI *tGetDiskFreeSpaceEx)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER); +typedef LANGID (WINAPI *tGetUserDefaultUILanguage)(void); +typedef LANGID (WINAPI *tGetSystemDefaultUILanguage)(void); +typedef BOOL (WINAPI *tIsWow64Process)(HANDLE, PBOOL); +typedef PVOID (WINAPI *tAddVectoredExceptionHandler)(ULONG FirstHandler, PVECTORED_EXCEPTION_HANDLER VectoredHandler); +typedef ULONG (WINAPI *tRemoveVectoredExceptionHandler)(PVOID Handler); +typedef BOOL (WINAPI *tIsProcessorFeaturePresent)(DWORD ProcessorFeature); +typedef VOID (WINAPI *tRtlCaptureContext)(PCONTEXT ContextRecord); diff --git a/plugins/CrashDumper/src/ui.cpp b/plugins/CrashDumper/src/ui.cpp new file mode 100644 index 0000000000..00cf9c26cd --- /dev/null +++ b/plugins/CrashDumper/src/ui.cpp @@ -0,0 +1,327 @@ +/* +Miranda Crash Dumper Plugin +Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "utils.h" +#include +#include +#include + +HWND hViewWnd; +extern HINSTANCE hInst; + + +HDWP MyResizeWindow (HDWP hDwp, HWND hwndDlg, HWND hwndCtrl, int nHorizontalOffset, int nVerticalOffset, + int nWidthOffset, int nHeightOffset) +{ + POINT pt; + RECT rcinit; + + // get current bounding rectangle + GetWindowRect(hwndCtrl, &rcinit); + + // get current top left point + pt.x = rcinit.left; + pt.y = rcinit.top; + ScreenToClient(hwndDlg, &pt); + + return DeferWindowPos(hDwp, hwndCtrl, NULL, + pt.x + nHorizontalOffset, + pt.y + nVerticalOffset, + rcinit.right - rcinit.left + nWidthOffset, + rcinit.bottom - rcinit.top + nHeightOffset, + SWP_NOZORDER); +} + +BOOL MyResizeGetOffset(HWND hwndCtrl, int nWidth, int nHeight, int* nDx, int* nDy) +{ + RECT rcinit; + + // get current bounding rectangle + GetWindowRect(hwndCtrl, &rcinit); + + // calculate offsets + *nDx = nWidth - (rcinit.right - rcinit.left); + *nDy = nHeight - (rcinit.bottom - rcinit.top); + + return rcinit.bottom != rcinit.top && nHeight > 0; +} + +INT_PTR CALLBACK DlgProcView(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + if (hViewWnd == NULL) + { + hViewWnd = hwndDlg; + TranslateDialogDefault(hwndDlg); + SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIconEx("versionInfo", true)); + SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIconEx("versionInfo")); + + CHARFORMAT2 chf; + chf.cbSize = sizeof(chf); + SendDlgItemMessage(hwndDlg, IDC_VIEWVERSIONINFO, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM)&chf); + _tcscpy(chf.szFaceName, TEXT("Courier New")); + SendDlgItemMessage(hwndDlg, IDC_VIEWVERSIONINFO, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&chf); + + bkstring buffer; + buffer.reserve(0x1800); + PrintVersionInfo(buffer, (unsigned int)lParam); + SetDlgItemText(hwndDlg, IDC_VIEWVERSIONINFO, buffer.c_str()); + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); + + Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, PluginName, "ViewInfo_"); + ShowWindow(hwndDlg, SW_SHOW); + } + else + DestroyWindow(hwndDlg); + break; + + case WM_SIZE: + { + int dx, dy, bsz; + HDWP hDwp; + RECT rc; + + GetWindowRect(GetDlgItem(hwndDlg, IDC_FILEVER), &rc); + bsz = rc.bottom - rc.top; + + if (MyResizeGetOffset(GetDlgItem(hwndDlg, IDC_VIEWVERSIONINFO), + LOWORD(lParam)-20, HIWORD(lParam)-30-bsz, &dx, &dy)) + { + hDwp = BeginDeferWindowPos(4); + hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_FILEVER), 0, dy, 0, 0); + hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_CLIPVER), dx/2, dy, 0, 0); + hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDCANCEL), dx, dy, 0, 0); + hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_VIEWVERSIONINFO), 0, 0, dx, dy); + EndDeferWindowPos(hDwp); + } + } + break; + + case WM_GETMINMAXINFO: + { + LPMINMAXINFO mmi = (LPMINMAXINFO)lParam; + + // The minimum width in points + mmi->ptMinTrackSize.x = 350; + // The minimum height in points + mmi->ptMinTrackSize.y = 300; + } + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_CLIPVER: + CallService(MS_CRASHDUMPER_STORETOCLIP, 0, GetWindowLongPtr(hwndDlg, GWLP_USERDATA)); + break; + + case IDC_FILEVER: + CallService(MS_CRASHDUMPER_STORETOFILE, 0, GetWindowLongPtr(hwndDlg, GWLP_USERDATA)); + break; + + case IDCANCEL: + DestroyWindow(hwndDlg); + break; + } + break; + + case WM_CONTEXTMENU: + { + HWND hView = GetDlgItem(hwndDlg, IDC_VIEWVERSIONINFO); + RECT rc; + GetWindowRect(hView, &rc); + + POINT pt; + pt.x = LOWORD(lParam); + pt.y = HIWORD(lParam); + if (PtInRect(&rc, pt)) + { + static const CHARRANGE all = { 0, -1 }; + + HMENU hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXT)); + HMENU hSubMenu = GetSubMenu(hMenu, 0); + TranslateMenu(hSubMenu); + + CHARRANGE sel; + SendMessage(hView, EM_EXGETSEL, 0, (LPARAM)&sel); + if (sel.cpMin == sel.cpMax) + EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); + + switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) + { + case IDM_COPY: + SendMessage(hView, WM_COPY, 0, 0); + break; + + case IDM_COPYALL: + SendMessage(hView, EM_EXSETSEL, 0, (LPARAM)&all); + SendMessage(hView, WM_COPY, 0, 0); + SendMessage(hView, EM_EXSETSEL, 0, (LPARAM)&sel); + break; + + case IDM_SELECTALL: + SendMessage(hView, EM_EXSETSEL, 0, (LPARAM)&all); + break; + } + DestroyMenu(hMenu); + } + } + break; + + case WM_DESTROY: + hViewWnd = NULL; + ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0)); + ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, 0)); + Utils_SaveWindowPosition(hwndDlg, NULL, PluginName, "ViewInfo_"); + if (servicemode) PostQuitMessage(0); + break; + } + return FALSE; +} + + +void DestroyAllWindows(void) +{ + if (hViewWnd != NULL) DestroyWindow(hViewWnd); + hViewWnd = NULL; +} + + +INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + { + TranslateDialogDefault(hwndDlg); + + DBVARIANT dbv; + if (DBGetContactSettingString(NULL, PluginName, "Username", &dbv) == 0) + { + SetDlgItemTextA(hwndDlg, IDC_USERNAME, dbv.pszVal); + DBFreeVariant(&dbv); + } + if (DBGetContactSettingString(NULL, PluginName, "Password", &dbv) == 0) + { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); + SetDlgItemTextA(hwndDlg, IDC_PASSWORD, dbv.pszVal); + DBFreeVariant(&dbv); + } + CheckDlgButton(hwndDlg, IDC_UPLOADCHN, DBGetContactSettingByte(NULL, PluginName, "UploadChanged", 0)); + CheckDlgButton(hwndDlg, IDC_CLASSICDATES, clsdates); + CheckDlgButton(hwndDlg, IDC_DATESUBFOLDER, dtsubfldr); + } + break; + + case WM_COMMAND: + if ((HIWORD(wParam) == EN_CHANGE || HIWORD(wParam) == BN_CLICKED) && (HWND)lParam == GetFocus()) + SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); + break; + + case WM_NOTIFY: + if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY) + { + char szSetting[100]; + GetDlgItemTextA(hwndDlg, IDC_USERNAME, szSetting, SIZEOF(szSetting)); + DBWriteContactSettingString(NULL, PluginName, "Username", szSetting); + + GetDlgItemTextA(hwndDlg, IDC_PASSWORD, szSetting, SIZEOF(szSetting)); + CallService(MS_DB_CRYPT_ENCODESTRING, SIZEOF(szSetting), (LPARAM)szSetting); + DBWriteContactSettingString(NULL, PluginName, "Password", szSetting); + + DBWriteContactSettingByte(NULL, PluginName, "UploadChanged", + (BYTE)IsDlgButtonChecked(hwndDlg, IDC_UPLOADCHN)); + + clsdates = IsDlgButtonChecked(hwndDlg, IDC_CLASSICDATES) == BST_CHECKED; + if (clsdates) + DBWriteContactSettingByte(NULL, PluginName, "ClassicDates", 1); + else + DBDeleteContactSetting(NULL, PluginName, "ClassicDates"); + dtsubfldr = IsDlgButtonChecked(hwndDlg, IDC_DATESUBFOLDER) == BST_CHECKED; + if (dtsubfldr) + DBWriteContactSettingByte(NULL, PluginName, "SubFolders", 1); + else + DBDeleteContactSetting(NULL, PluginName, "SubFolders"); + } + break; + } + return FALSE; +} + + +LRESULT CALLBACK DlgProcPopup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_CONTEXTMENU: + PUDeletePopUp(hWnd); + break; + + case WM_COMMAND: + switch ((int)PUGetPluginData(hWnd)) + { + case 0: + OpenAuthUrl("http://www.miranda-vi.org/"); + break; + + case 1: + OpenAuthUrl("http://%s.miranda-vi.org/global"); + break; + + case 3: + TCHAR path[MAX_PATH]; + crs_sntprintf(path, MAX_PATH, TEXT("%s\\VersionInfo.txt"), VersionInfoFolder); + ShellExecute(NULL, TEXT("open"), path, NULL, NULL, SW_SHOW); + break; + + } + PUDeletePopUp(hWnd); + break; + + case UM_FREEPLUGINDATA: + ReleaseIconEx("versionInfo"); + break; + } + + return DefWindowProc(hWnd, msg, wParam, lParam); +} + +void ShowMessage(int type, const TCHAR* format, ...) +{ + POPUPDATAT pi = {0}; + + va_list va; + va_start(va, format); + int len = _vsntprintf(pi.lptzText, SIZEOF(pi.lptzText)-1, format, va); + pi.lptzText[len] = 0; + va_end(va); + + if (ServiceExists(MS_POPUP_ADDPOPUPT)) + { + _tcscpy(pi.lptzContactName, TEXT(PluginName)); + pi.lchIcon = LoadIconEx("versionInfo"); + pi.PluginWindowProc = DlgProcPopup; + pi.PluginData = (void*)type; + + PUAddPopUpT(&pi); + } + else + MessageBox(NULL, pi.lptzText, TEXT(PluginName), MB_OK | MB_ICONINFORMATION); +} diff --git a/plugins/CrashDumper/src/upload.cpp b/plugins/CrashDumper/src/upload.cpp new file mode 100644 index 0000000000..498b5cb2f6 --- /dev/null +++ b/plugins/CrashDumper/src/upload.cpp @@ -0,0 +1,292 @@ +/* +Miranda Crash Dumper Plugin +Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "utils.h" +#include + +HANDLE hNetlibUser; + +static void arrayToHex(BYTE* data, size_t datasz, char* res) +{ + char* resptr = res; + for (unsigned i=0; i> 4); + *resptr++ = (char)((ch0 <= 9) ? ('0' + ch0) : (('a' - 10) + ch0)); + + const char ch1 = (char)(ch & 0xF); + *resptr++ = (char)((ch1 <= 9) ? ('0' + ch1) : (('a' - 10) + ch1)); + } + *resptr = '\0'; +} + +void GetLoginStr(char* user, size_t szuser, char* pass) +{ + DBVARIANT dbv; + + if (DBGetContactSettingString(NULL, PluginName, "Username", &dbv) == 0) + { + mir_snprintf(user, szuser, "%s", dbv.pszVal); + DBFreeVariant(&dbv); + } + else + user[0] = 0; + + if (DBGetContactSettingString(NULL, PluginName, "Password", &dbv) == 0) + { + CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); + + mir_md5_byte_t hash[16]; + mir_md5_state_t context; + + mir_md5_init(&context); + mir_md5_append(&context, (BYTE*)dbv.pszVal, (int)strlen(dbv.pszVal)); + mir_md5_finish(&context, hash); + + arrayToHex(hash, sizeof(hash), pass); + + DBFreeVariant(&dbv); + } + else + pass[0] = 0; +} + +void OpenAuthUrl(const char* url) +{ + char user[64], pass[40]; + GetLoginStr(user, sizeof(user), pass); + + if (user[0] && pass[0]) + { + char str[256]; + + mir_snprintf(str, sizeof(str), url, user); + char* eurl = (char*)CallService(MS_NETLIB_URLENCODE, 0, (LPARAM)str); + + mir_snprintf(str, sizeof(str), "http://www.miranda-vi.org/cdlogin?name=%s&pass=%s&redir=%s", user, pass, eurl); + CallService(MS_UTILS_OPENURL, 1, (LPARAM)str); + HeapFree(GetProcessHeap(), 0, eurl); + } + else + CallService(MS_UTILS_OPENURL, 1, (LPARAM)"http://www.miranda-vi.org/"); +} + +void CreateAuthString(char* auth) +{ + char user[64], pass[40]; + GetLoginStr(user, sizeof(user), pass); + + char str[110]; + int len = mir_snprintf(str, sizeof(str), "%s:%s", user, pass); + + strcpy(auth, "Basic "); + NETLIBBASE64 nlb = { auth+6, 250, (PBYTE)str, len }; + CallService(MS_NETLIB_BASE64ENCODE, 0, LPARAM(&nlb)); +} + + +bool InternetDownloadFile(const char *szUrl, VerTrnsfr* szReq) +{ + int result = 0xBADBAD; + char* szRedirUrl = NULL; + NETLIBHTTPREQUEST nlhr = {0}; + + // initialize the netlib request + nlhr.cbSize = sizeof(nlhr); + nlhr.requestType = REQUEST_POST; + nlhr.flags = NLHRF_HTTP11 | NLHRF_NODUMP; + nlhr.szUrl = (char*)szUrl; + + nlhr.headersCount = 6; + nlhr.headers=(NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)*nlhr.headersCount); + nlhr.headers[0].szName = "Connection"; + nlhr.headers[0].szValue = "close"; + nlhr.headers[1].szName = "Cache-Control"; + nlhr.headers[1].szValue = "no-cache"; + nlhr.headers[2].szName = "Pragma"; + nlhr.headers[2].szValue = "no-cache"; + nlhr.headers[3].szName = "Content-Type"; + nlhr.headers[3].szValue = "text/plain; charset=utf-8"; + nlhr.headers[4].szName = "AutoUpload"; + nlhr.headers[4].szValue = (char*)(szReq->autot ? "1" : "0"); + nlhr.headers[5].szName = "Authorization"; + + char auth[256]; + CreateAuthString(auth); + nlhr.headers[5].szValue = auth; + + nlhr.pData = szReq->buf; + nlhr.dataLength = (int)strlen(szReq->buf); + + while (result == 0xBADBAD) + { + // download the page + NETLIBHTTPREQUEST *nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, + (WPARAM)hNetlibUser,(LPARAM)&nlhr); + + if (nlhrReply) + { + int i; + + // if the recieved code is 200 OK + switch(nlhrReply->resultCode) + { + case 200: + if (DBGetContactSettingByte(NULL, PluginName, "UploadChanged", 0)) + ProcessVIHash(true); + + for (i=nlhrReply->headersCount; i--; ) + { + if (_stricmp(nlhrReply->headers[i].szName, "OldPlugins") == 0) + { + i = atoi(nlhrReply->headers[i].szValue); + break; + } + } + + ShowMessage(1, TranslateT("VersionInfo upload successful,\n %d old plugins"), i); + result = 0; + break; + + case 401: + ShowMessage(0, TranslateT("Cannot upload VersionInfo. Incorrect username or password")); + result = 1; + break; + + case 510: + ShowMessage(0, TranslateT("Cannot upload VersionInfo. User is banned")); + result = 1; + break; + + case 511: + ShowMessage(0, TranslateT("Cannot upload VersionInfo. Daily upload limit exceeded")); + result = 1; + break; + + case 301: + case 302: + case 307: + // get the url for the new location and save it to szInfo + // look for the reply header "Location" + for (i=0; iheadersCount; i++) + { + if (!strcmp(nlhrReply->headers[i].szName, "Location")) + { + size_t rlen = 0; + if (nlhrReply->headers[i].szValue[0] == '/') + { + const char* szPath; + const char* szPref = strstr(szUrl, "://"); + szPref = szPref ? szPref + 3 : szUrl; + szPath = strchr(szPref, '/'); + rlen = szPath != NULL ? szPath - szUrl : strlen(szUrl); + } + + szRedirUrl = (char*)mir_realloc(szRedirUrl, + rlen + strlen(nlhrReply->headers[i].szValue)*3 + 1); + + strncpy(szRedirUrl, szUrl, rlen); + strcpy(szRedirUrl+rlen, nlhrReply->headers[i].szValue); + + nlhr.szUrl = szRedirUrl; + break; + } + } + break; + + default: + result = 1; + ShowMessage(0, TranslateT("Cannot upload VersionInfo. Unknown error")); + } + } + else + { + result = 1; + ShowMessage(0, TranslateT("Cannot upload VersionInfo. Host unreachable.")); + } + + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)nlhrReply); + } + + mir_free(szRedirUrl); + mir_free(nlhr.headers); + + return result == 0; +} + +void __cdecl VersionInfoUploadThread(void* arg) +{ + VerTrnsfr* trn = (VerTrnsfr*)arg; + InternetDownloadFile("http://www.miranda-vi.org/uploadpost", trn); + mir_free(trn->buf); + mir_free(trn); +} + + +void UploadInit(void) +{ + NETLIBUSER nlu = {0}; + nlu.cbSize = sizeof(nlu); + nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_NOHTTPSOPTION | NUF_TCHAR; + nlu.szSettingsModule = (char*)PluginName; + nlu.ptszDescriptiveName = TranslateT("Crash Dumper HTTP connections"); + hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); +} + +void UploadClose(void) +{ + Netlib_CloseHandle(hNetlibUser); +} + +bool ProcessVIHash(bool store) +{ + bkstring buffer; + buffer.reserve(0x1800); + PrintVersionInfo(buffer, 0); + + mir_md5_byte_t hash[16]; + mir_md5_state_t context; + + mir_md5_init(&context); + mir_md5_append(&context, (PBYTE)buffer.c_str(), (int)buffer.sizebytes()); + mir_md5_finish(&context, hash); + + char hashstr[40]; + arrayToHex(hash, sizeof(hash), hashstr); + + bool result; + if (store) + { + DBWriteContactSettingString(NULL, PluginName, "VIHash", hashstr); + result = true; + } + else + { + DBVARIANT dbv; + if (DBGetContactSettingString(NULL, PluginName, "VIHash", &dbv) == 0) + { + result = strcmp(hashstr, dbv.pszVal) == 0; + DBFreeVariant(&dbv); + } + else + result = false; + } + return result; +} diff --git a/plugins/CrashDumper/src/utils.cpp b/plugins/CrashDumper/src/utils.cpp new file mode 100644 index 0000000000..d4dced7d70 --- /dev/null +++ b/plugins/CrashDumper/src/utils.cpp @@ -0,0 +1,836 @@ +/* +Miranda Crash Dumper Plugin +Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "utils.h" +#include + +static HMODULE hKernel = GetModuleHandle(TEXT("kernel32.dll")); + +tGetNativeSystemInfo pGetNativeSystemInfo = (tGetNativeSystemInfo)GetProcAddress(hKernel, "GetNativeSystemInfo"); +tGetProductInfo pGetProductInfo = (tGetProductInfo) GetProcAddress(hKernel, "GetProductInfo"); +tGlobalMemoryStatusEx pGlobalMemoryStatusEx = (tGlobalMemoryStatusEx) GetProcAddress(hKernel, "GlobalMemoryStatusEx"); +tGetUserDefaultUILanguage pGetUserDefaultUILanguage = (tGetUserDefaultUILanguage) GetProcAddress(hKernel, "GetUserDefaultUILanguage"); +tGetSystemDefaultUILanguage pGetSystemDefaultUILanguage = (tGetSystemDefaultUILanguage) GetProcAddress(hKernel, "GetSystemDefaultUILanguage"); +tIsWow64Process pIsWow64Process = (tIsWow64Process) GetProcAddress(hKernel, "IsWow64Process"); +tIsProcessorFeaturePresent pIsProcessorFeaturePresent = (tIsProcessorFeaturePresent) GetProcAddress(hKernel, "IsProcessorFeaturePresent"); + + +tGetDiskFreeSpaceEx pGetDiskFreeSpaceEx = (tGetDiskFreeSpaceEx) GetProcAddress(hKernel, "GetDiskFreeSpaceExW"); + + + +void CheckForOtherCrashReportingPlugins(void) +{ + HMODULE hModule = GetModuleHandle(TEXT("attache.dll")); + if (hModule == NULL) + hModule = GetModuleHandle(TEXT("crashrpt.dll")); + if (hModule == NULL) + hModule = GetModuleHandle(TEXT("crashdmp.dll")); + + if (hModule == NULL) return; + + MessageBox(NULL, TranslateT("More then one crash reporting plugin installed. This will result in inability of creating crash reports"), + TEXT("Miranda Crash Dumper"), MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_TOPMOST); +} + +void GetOSDisplayString(bkstring& buffer) +{ + OSVERSIONINFOEX osvi = {0}; + SYSTEM_INFO si = {0}; + BOOL bOsVersionInfoEx; + DWORD dwType = 0; + + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*)&osvi); + if (!bOsVersionInfoEx) + { + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (!GetVersionEx((OSVERSIONINFO*)&osvi)) + return; + } + + // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise. + pGetNativeSystemInfo = (tGetNativeSystemInfo)GetProcAddress(hKernel, "GetNativeSystemInfo"); + if (NULL != pGetNativeSystemInfo) pGetNativeSystemInfo(&si); + else GetSystemInfo(&si); + + if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && osvi.dwMajorVersion > 4) + { + buffer.append(TEXT("Operating System: Microsoft ")); + + // Test for the specific product. + if (osvi.dwMajorVersion == 6) + { + switch (osvi.dwMinorVersion) + { + case 0: + if (osvi.wProductType == VER_NT_WORKSTATION) + buffer.append(TEXT("Windows Vista ")); + else + buffer.append(TEXT("Windows Server 2008 ")); + break; + + case 1: + if (osvi.wProductType == VER_NT_WORKSTATION) + buffer.append(TEXT("Windows 7 ")); + else + buffer.append(TEXT("Windows Server 2008 R2 ")); + break; + + default: + if (osvi.wProductType == VER_NT_WORKSTATION) + buffer.append(TEXT("Windows 8 ")); + else + buffer.append(TEXT("Windows Server 2012 ")); + break; + } + + pGetProductInfo = (tGetProductInfo) GetProcAddress(hKernel, "GetProductInfo"); + if (pGetProductInfo != NULL) pGetProductInfo(6, 0, 0, 0, &dwType); + + switch(dwType) + { + case PRODUCT_ULTIMATE: + buffer.append(TEXT("Ultimate Edition")); + break; + case PRODUCT_HOME_PREMIUM: + buffer.append(TEXT("Home Premium Edition")); + break; + case PRODUCT_HOME_BASIC: + buffer.append(TEXT("Home Basic Edition")); + break; + case PRODUCT_ENTERPRISE: + buffer.append(TEXT("Enterprise Edition")); + break; + case PRODUCT_BUSINESS: + buffer.append(TEXT("Business Edition")); + break; + case PRODUCT_STARTER: + buffer.append(TEXT("Starter Edition")); + break; + case PRODUCT_CLUSTER_SERVER: + buffer.append(TEXT("Cluster Server Edition")); + break; + case PRODUCT_DATACENTER_SERVER: + buffer.append(TEXT("Datacenter Edition")); + break; + case PRODUCT_DATACENTER_SERVER_CORE: + buffer.append(TEXT("Datacenter Edition (core installation)")); + break; + case PRODUCT_ENTERPRISE_SERVER: + buffer.append(TEXT("Enterprise Edition")); + break; + case PRODUCT_ENTERPRISE_SERVER_CORE: + buffer.append(TEXT("Enterprise Edition (core installation)")); + break; + case PRODUCT_ENTERPRISE_SERVER_IA64: + buffer.append(TEXT("Enterprise Edition for Itanium-based Systems")); + break; + case PRODUCT_SMALLBUSINESS_SERVER: + buffer.append(TEXT("Small Business Server")); + break; + case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM: + buffer.append(TEXT("Small Business Server Premium Edition")); + break; + case PRODUCT_STANDARD_SERVER: + buffer.append(TEXT("Standard Edition")); + break; + case PRODUCT_STANDARD_SERVER_CORE: + buffer.append(TEXT("Standard Edition (core installation)")); + break; + case PRODUCT_WEB_SERVER: + buffer.append(TEXT("Web Server Edition")); + break; + } + + if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) + buffer.append(TEXT(", 64-bit")); + else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL) + buffer.append(TEXT(", 32-bit")); + } + + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) + { + if (GetSystemMetrics(SM_SERVERR2)) + buffer.append(TEXT("Windows Server 2003 R2, ")); + else if (osvi.wSuiteMask==VER_SUITE_STORAGE_SERVER) + buffer.append(TEXT("Windows Storage Server 2003")); + else if (osvi.wProductType == VER_NT_WORKSTATION && + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + buffer.append(TEXT("Windows XP Professional x64 Edition")); + else buffer.append(TEXT("Windows Server 2003, ")); + + // Test for the server type. + if (osvi.wProductType != VER_NT_WORKSTATION) + { + if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64) + { + if(osvi.wSuiteMask & VER_SUITE_DATACENTER) + buffer.append(TEXT("Datacenter Edition for Itanium-based Systems")); + else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE) + buffer.append(TEXT("Enterprise Edition for Itanium-based Systems")); + } + + else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) + { + if(osvi.wSuiteMask & VER_SUITE_DATACENTER) + buffer.append(TEXT("Datacenter x64 Edition")); + else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE) + buffer.append(TEXT("Enterprise x64 Edition")); + else buffer.append(TEXT("Standard x64 Edition")); + } + + else + { + if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER) + buffer.append(TEXT("Compute Cluster Edition")); + else if(osvi.wSuiteMask & VER_SUITE_DATACENTER) + buffer.append(TEXT("Datacenter Edition")); + else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE) + buffer.append(TEXT("Enterprise Edition")); + else if (osvi.wSuiteMask & VER_SUITE_BLADE) + buffer.append(TEXT("Web Edition")); + else buffer.append(TEXT("Standard Edition")); + } + } + } + + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) + { + buffer.append(TEXT("Windows XP ")); + if (osvi.wSuiteMask & VER_SUITE_PERSONAL) + buffer.append(TEXT("Home Edition")); + else + buffer.append(TEXT("Professional")); + } + + if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) + { + buffer.append(TEXT("Windows 2000 ")); + + if (osvi.wProductType == VER_NT_WORKSTATION) + { + buffer.append(TEXT("Professional")); + } + else + { + if(osvi.wSuiteMask & VER_SUITE_DATACENTER) + buffer.append(TEXT("Datacenter Server")); + else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE) + buffer.append(TEXT("Advanced Server")); + else buffer.append(TEXT("Server")); + } + } + if (_tcslen(osvi.szCSDVersion) > 0) + { + buffer.append(TEXT(" ")); + buffer.append(osvi.szCSDVersion); + } + + buffer.appendfmt(TEXT(" (build %d)"), osvi.dwBuildNumber); + } + else + { + if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId) + { + buffer.append(TEXT("Microsoft Windows NT ")); + if (osvi.wProductType == VER_NT_WORKSTATION) + buffer.append(TEXT("Workstation 4.0 ")); + else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) + buffer.append(TEXT("Server 4.0, Enterprise Edition ")); + else + buffer.append(TEXT("Server 4.0 ")); + } + + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && osvi.dwMajorVersion == 4) + { + if (osvi.dwMinorVersion == 0) + { + buffer.append(TEXT("Microsoft Windows 95 ")); + if (osvi.szCSDVersion[1]==TEXT('C') || osvi.szCSDVersion[1]==TEXT('B')) + buffer.append(TEXT("OSR2 ")); + } + + if (osvi.dwMinorVersion == 10) + { + buffer.append(TEXT("Microsoft Windows 98 ")); + if (osvi.szCSDVersion[1]==TEXT('A') || osvi.szCSDVersion[1]==TEXT('B')) + buffer.append(TEXT("SE ")); + } + + if (osvi.dwMinorVersion == 90) + { + buffer.append(TEXT("Microsoft Windows Millennium Edition")); + } + buffer.appendfmt(TEXT("(build %d)"), LOWORD(osvi.dwBuildNumber)); + } + else if (osvi.dwPlatformId == VER_PLATFORM_WIN32s) + { + buffer.append(TEXT("Microsoft Win32s")); + } + } +} + +int GetTZOffset(void) +{ + TIME_ZONE_INFORMATION tzInfo = {0}; + DWORD type = GetTimeZoneInformation(&tzInfo); + + int offset = 0; + switch (type) + { + case TIME_ZONE_ID_DAYLIGHT: + offset = -(tzInfo.Bias + tzInfo.DaylightBias); + break; + + case TIME_ZONE_ID_STANDARD: + offset = -(tzInfo.Bias + tzInfo.StandardBias); + break; + + case TIME_ZONE_ID_UNKNOWN: + offset = -tzInfo.Bias; + break; + } + return offset; +} + +void GetISO8061Time(SYSTEMTIME* stLocal, LPTSTR lpszString, DWORD dwSize) +{ + SYSTEMTIME loctime; + if (stLocal == NULL) + { + stLocal = &loctime; + GetLocalTime(stLocal); + } + + if (clsdates) + { + GetDateFormat(LOCALE_INVARIANT, 0, stLocal, TEXT("d MMM yyyy"), lpszString, dwSize); + int dlen = (int)_tcslen(lpszString); + GetTimeFormat(LOCALE_INVARIANT, 0, stLocal, TEXT(" H:mm:ss"), lpszString+dlen, dwSize-dlen); + } + else + { + int offset = GetTZOffset(); + + // Build a string showing the date and time. + crs_sntprintf(lpszString, dwSize, TEXT("%d-%02d-%02d %02d:%02d:%02d%+03d%02d"), + stLocal->wYear, stLocal->wMonth, stLocal->wDay, + stLocal->wHour, stLocal->wMinute, stLocal->wSecond, + offset / 60, offset % 60); + } +} + +void GetLastWriteTime(FILETIME* ftime, LPTSTR lpszString, DWORD dwSize) +{ + FILETIME ftLocal; + SYSTEMTIME stLocal; + + // Convert the last-write time to local time. + FileTimeToLocalFileTime(ftime, &ftLocal); + FileTimeToSystemTime(&ftLocal, &stLocal); + + GetISO8061Time(&stLocal, lpszString, dwSize); +} + +void GetLastWriteTime(LPCTSTR fileName, LPTSTR lpszString, DWORD dwSize) +{ + WIN32_FIND_DATA FindFileData; + + HANDLE hFind = FindFirstFile(fileName, &FindFileData); + if (hFind == INVALID_HANDLE_VALUE) return; + FindClose(hFind); + + GetLastWriteTime(&FindFileData.ftLastWriteTime, lpszString, dwSize); +} + +typedef PLUGININFOEX * (__cdecl * Miranda_Plugin_Info) (DWORD mirandaVersion); + +PLUGININFOEX* GetMirInfo(HMODULE hModule) +{ + Miranda_Plugin_Info bpi = (Miranda_Plugin_Info)GetProcAddress(hModule, "MirandaPluginInfoEx"); + if (bpi == NULL) + return NULL; + + return bpi(mirandaVersion); +} + + +void GetInternetExplorerVersion(bkstring& buffer) +{ + HKEY hKey; + DWORD size; + + TCHAR ieVersion[1024] = {0}; + TCHAR ieBuild[512] = {0}; + TCHAR iVer[64] = {0}; + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Internet Explorer"), 0, + KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + size = sizeof(ieBuild)/sizeof(ieBuild[0]); + if (RegQueryValueEx(hKey, TEXT("Build"), NULL, NULL, (LPBYTE) ieBuild, &size) != ERROR_SUCCESS) + ieBuild[0] = 0; + + size = sizeof(ieVersion)/sizeof(ieVersion[0]); + if (RegQueryValueEx(hKey, TEXT("Version"), NULL, NULL, (LPBYTE) ieVersion, &size) != ERROR_SUCCESS) + ieVersion[0] = 0; + + size = sizeof(iVer)/sizeof(iVer[0]); + if (RegQueryValueEx(hKey, TEXT("IVer"), NULL, NULL, (LPBYTE) iVer, &size) != ERROR_SUCCESS) + iVer[0] = 0; + + RegCloseKey(hKey); + } + + buffer.append(TEXT("Internet Explorer: ")); + if (ieVersion[0] == 0) + { + if (iVer[0] == 0) + buffer.append(TEXT("")); + else if (_tcscmp(iVer, TEXT("100")) == 0) + buffer.append(TEXT("1.0")); + else if (_tcscmp(iVer, TEXT("101")) == 0) + buffer.append(TEXT("NT")); + else if (_tcscmp(iVer, TEXT("102")) == 0) + buffer.append(TEXT("2.0")); + else if (_tcscmp(iVer, TEXT("103")) == 0) + buffer.append(TEXT("3.0")); + } + else + { + buffer.append(ieVersion); + } + if (ieBuild[0] != 0) + { + buffer.appendfmt(TEXT(" (build %s)"), ieBuild); + } +} + + +void TrimMultiSpaces(TCHAR* str) +{ + TCHAR *src = str, *dest = str; + bool trimst = false; + + for (;;) + { + if (*src == TEXT(' ')) + { + if (!trimst) + { + trimst = true; + *dest++ = *src; + } + } + else + { + trimst = false; + *dest++ = *src; + } + if (*src++ == 0) break; + } +} + +void GetProcessorString(bkstring& buffer) +{ + HKEY hKey; + DWORD size; + + TCHAR cpuIdent[512] = {0}; + TCHAR cpuName[512] = {0}; + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Hardware\\Description\\System\\CentralProcessor\\0"), 0, + KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) + { + size = sizeof(cpuName)/sizeof(cpuName[0]); + if (RegQueryValueEx(hKey, TEXT("ProcessorNameString"), NULL, NULL, (LPBYTE) cpuName, &size) != ERROR_SUCCESS) + _tcscpy(cpuName, TEXT("Unknown")); + + size = sizeof(cpuIdent)/sizeof(cpuIdent[0]); + if (RegQueryValueEx(hKey, TEXT("Identifier"), NULL, NULL, (LPBYTE) cpuIdent, &size) != ERROR_SUCCESS) + if (RegQueryValueEx(hKey, TEXT("VendorIdentifier"), NULL, NULL, (LPBYTE) cpuIdent, &size) != ERROR_SUCCESS) + _tcscpy(cpuIdent, TEXT("Unknown")); + + RegCloseKey(hKey); + } + TrimMultiSpaces(cpuName); + buffer.appendfmt(TEXT("CPU: %s [%s]"), cpuName, cpuIdent); + + if (pIsProcessorFeaturePresent && pIsProcessorFeaturePresent(PF_NX_ENABLED)) + buffer.append(TEXT(" [DEP Enabled]")); + + SYSTEM_INFO si = {0}; + GetSystemInfo(&si); + + if (si.dwNumberOfProcessors > 1) + buffer.appendfmt(TEXT(" [%u CPUs]"), si.dwNumberOfProcessors); +} + +void GetFreeMemoryString(bkstring& buffer) +{ + unsigned ram; + if (pGlobalMemoryStatusEx) + { + MEMORYSTATUSEX ms = {0}; + ms.dwLength = sizeof(ms); + pGlobalMemoryStatusEx(&ms); + ram = (unsigned int) ((ms.ullTotalPhys / (1024 * 1024)) + 1); + } + else + { + MEMORYSTATUS ms = {0}; + ZeroMemory(&ms, sizeof(ms)); + ms.dwLength = sizeof(ms); + GlobalMemoryStatus(&ms); + ram = (unsigned int)(ms.dwTotalPhys/(1024*1024))+1; + } + buffer.appendfmt(TEXT("Installed RAM: %u MBytes"), ram); +} + +void GetFreeDiskString(LPCTSTR dirname, bkstring& buffer) +{ + ULARGE_INTEGER tnb, tfb, fs = {0}; + if (pGetDiskFreeSpaceEx) + pGetDiskFreeSpaceEx(dirname, &fs, &tnb, &tfb); + else + { + DWORD SectorsPerCluster, BytesPerSector; + DWORD NumberOfFreeClusters, TotalNumberOfClusters; + + GetDiskFreeSpace(dirname, &SectorsPerCluster, &BytesPerSector, + &NumberOfFreeClusters, &TotalNumberOfClusters); + + fs.QuadPart = BytesPerSector * SectorsPerCluster; + fs.QuadPart *= NumberOfFreeClusters; + } + fs.QuadPart /= (1024*1024); + + buffer.appendfmt(TEXT("Free disk space on Miranda partition: %u MBytes"), fs.LowPart); +} + +void ReadableExceptionInfo(PEXCEPTION_RECORD excrec, bkstring& buffer) +{ + buffer.append(TEXT("Exception: ")); + + switch (excrec->ExceptionCode) + { + case EXCEPTION_BREAKPOINT: + buffer.append(TEXT("User Defined Breakpoint")); + break; + + case EXCEPTION_ACCESS_VIOLATION: + buffer.append(TEXT("Access Violation")); + break; + + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + buffer.append(TEXT("Array Bounds Exceeded")); + break; + + case EXCEPTION_DATATYPE_MISALIGNMENT: + buffer.append(TEXT("Datatype Misalignment")); + break; + + case EXCEPTION_FLT_DENORMAL_OPERAND: + buffer.append(TEXT("Floating Point denormlized operand")); + break; + + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + buffer.append(TEXT("Floating Point divide by 0")); + break; + + case EXCEPTION_FLT_INEXACT_RESULT: + buffer.append(TEXT("Floating Point inexact result")); + break; + + case EXCEPTION_FLT_INVALID_OPERATION: + buffer.append(TEXT("Floating Point invalid operation")); + break; + + case EXCEPTION_FLT_OVERFLOW: + buffer.append(TEXT("Floating Point overflow")); + break; + + case EXCEPTION_FLT_STACK_CHECK: + buffer.append(TEXT("Floating Point stack overflow/underflow")); + break; + + case EXCEPTION_FLT_UNDERFLOW: + buffer.append(TEXT("Floating Point underflow")); + break; + + case EXCEPTION_ILLEGAL_INSTRUCTION: + buffer.append(TEXT("Invalid instruction executed")); + break; + + case EXCEPTION_IN_PAGE_ERROR: + buffer.append(TEXT("Access to the not present page")); + break; + + case EXCEPTION_INT_DIVIDE_BY_ZERO: + buffer.append(TEXT("Integer divide by zero")); + break; + + case EXCEPTION_INT_OVERFLOW: + buffer.append(TEXT("Integer overflow")); + break; + + case EXCEPTION_PRIV_INSTRUCTION: + buffer.append(TEXT("Priveleged instruction executed")); + break; + + case EXCEPTION_STACK_OVERFLOW: + buffer.append(TEXT("Stack overflow")); + break; + + case 0xe06d7363: + buffer.append(TEXT("Unhandled C++ software exception")); + break; + + default: + buffer.appendfmt(TEXT("%x"), excrec->ExceptionCode); + break; + } + + buffer.appendfmt(TEXT(" at address %p."), excrec->ExceptionAddress); + + if (excrec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION || + excrec->ExceptionCode == EXCEPTION_IN_PAGE_ERROR) + { + switch(excrec->ExceptionInformation[0]) + { + case 0: + buffer.appendfmt(TEXT(" Reading from address %p."), (LPVOID)excrec->ExceptionInformation[1]); + break; + + case 1: + buffer.appendfmt(TEXT(" Writing to address %p."), (LPVOID)excrec->ExceptionInformation[1]); + break; + + case 8: + buffer.appendfmt(TEXT(" DEP at address %p."), (LPVOID)excrec->ExceptionInformation[1]); + break; + } + } +} + +void GetAdminString(bkstring& buffer) +{ + BOOL b; + __try + { + SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; + PSID AdministratorsGroup; + + b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup); + if (b) + { + if (!CheckTokenMembership(NULL, AdministratorsGroup, &b)) + b = FALSE; + FreeSid(AdministratorsGroup); + } + else + b = GetLastError() == ERROR_CALL_NOT_IMPLEMENTED; + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + b = TRUE; + } + + buffer.appendfmt(TEXT("Administrator privileges: %s"), b ? TEXT("Yes") : TEXT ("No")); +} + +void GetLanguageString(bkstring& buffer) +{ + TCHAR name1[256], name2[256], name3[256], name4[256]; + + GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SENGLANGUAGE, name1, 256); + GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE, name2, 256); + + if (pGetUserDefaultUILanguage && pGetSystemDefaultUILanguage) + { + GetLocaleInfo(MAKELCID(pGetUserDefaultUILanguage(), SORT_DEFAULT), LOCALE_SENGLANGUAGE, name3, 256); + GetLocaleInfo(MAKELCID(pGetSystemDefaultUILanguage(), SORT_DEFAULT), LOCALE_SENGLANGUAGE, name4, 256); + } + else + { + _tcscpy(name3, name1); + _tcscpy(name4, name2); + } + + buffer.appendfmt(TEXT("OS Languages: (UI | Locale (User/System)) : %s/%s | %s/%s"), name3, name4, name1, name2); +} + +void GetLanguagePackString(bkstring& buffer) +{ + buffer.append(TEXT("Language pack: ")); + if (packlcid == LOCALE_USER_DEFAULT) + buffer.append(TEXT("No language pack installed")); + else + { + TCHAR path[MAX_PATH] = TEXT("Locale id invalid"); + GetLocaleInfo(packlcid, LOCALE_SENGLANGUAGE, path, MAX_PATH); + buffer.append(path); + + GetLocaleInfo(packlcid, LOCALE_SISO3166CTRYNAME, path, MAX_PATH); + buffer.appendfmt(TEXT(" (%s) [%04x]"), path, packlcid); + + GetModuleFileName(NULL, path, MAX_PATH); + + LPTSTR fname = _tcsrchr(path, TEXT('\\')); + if (fname == NULL) fname = path; + crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\langpack_*.txt")); + + WIN32_FIND_DATA FindFileData; + HANDLE hFind = FindFirstFile(path, &FindFileData); + if (hFind == INVALID_HANDLE_VALUE) return; + FindClose(hFind); + + crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\%s"), FindFileData.cFileName); + HANDLE hDumpFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hDumpFile != INVALID_HANDLE_VALUE) + { + char buf[8192]; + + DWORD bytes = 0; + ReadFile(hDumpFile, buf, 8190, &bytes, NULL); + buf[bytes] = 0; + + char *id = strstr(buf, "FLID:"); + if (id != NULL) + { + char *endid = strchr(id, '\r'); + if (endid != NULL) *endid = 0; + + endid = strchr(id, '\n'); + if (endid != NULL) *endid = 0; + + TCHAR mirtime[30]; + GetLastWriteTime(path, mirtime, 30); + + TCHAR* tid; + crsi_a2t(tid, id+5); + buffer.appendfmt(TEXT(", %s, modified: %s"), tid, mirtime); + } + CloseHandle(hDumpFile); + } + } +} + +void GetWow64String(bkstring& buffer) +{ + BOOL wow64 = 0; + if (pIsWow64Process) + { + if (!pIsWow64Process(GetCurrentProcess(), &wow64)) + { + wow64 = 0; + } + } + if (wow64) buffer.append(TEXT(" [running inside WOW64]")); +} + + +bool CreateDirectoryTree(LPTSTR szDir) +{ + DWORD dwAttr = GetFileAttributes(szDir); + if (dwAttr != INVALID_FILE_ATTRIBUTES && (dwAttr & FILE_ATTRIBUTE_DIRECTORY)) + return true; + + TCHAR* pszSlash = _tcsrchr(szDir, TEXT('\\')); + if (pszSlash == NULL) + return false; + + *pszSlash = 0; + bool res = CreateDirectoryTree(szDir); + *pszSlash = TEXT('\\'); + + if (res) res = CreateDirectory(szDir, NULL) != 0; + + return res; +} + +int crs_sntprintf(TCHAR *buffer, size_t count, const TCHAR* fmt, ...) +{ + va_list va; + va_start(va, fmt); + + int len = _vsntprintf(buffer, count-1, fmt, va); + buffer[len] = 0; + + va_end(va); + return len; +} + +void GetVersionInfo(HMODULE hLib, bkstring& buffer) +{ + HRSRC hVersion = FindResource(hLib, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION); + if (hVersion != NULL) + { + HGLOBAL hGlobal = LoadResource(hLib, hVersion); + if (hGlobal != NULL) + { + LPVOID versionInfo = LockResource(hGlobal); + if (versionInfo != NULL) + { + int vl = *(unsigned short*)versionInfo; + unsigned *res = (unsigned*)versionInfo; + while (*res != 0xfeef04bd && ((char*)res - (char*)versionInfo) < vl) ++res; + + if (((char*)res - (char*)versionInfo) < vl) + { + VS_FIXEDFILEINFO *vsInfo = (VS_FIXEDFILEINFO*)res; + buffer.appendfmt(TEXT(" v.%u.%u.%u.%u"), + HIWORD(vsInfo->dwFileVersionMS), LOWORD(vsInfo->dwFileVersionMS), + HIWORD(vsInfo->dwFileVersionLS), LOWORD(vsInfo->dwFileVersionLS)); + } + } + FreeResource(hGlobal); + } + } +} + +void StoreStringToClip(bkstring& buffer) +{ + HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, buffer.sizebytes() + sizeof(TCHAR)); + LPSTR buf = (LPSTR)GlobalLock(hData); + + memcpy(buf, buffer.c_str(), buffer.sizebytes() + sizeof(TCHAR)); + + GlobalUnlock(hData); + + OpenClipboard(NULL); + EmptyClipboard(); + + + SetClipboardData(CF_UNICODETEXT, hData); + +} + +bool IsPluginEnabled(TCHAR* filename) +{ + char* fname; + crsi_t2a(fname, filename); + char* ext = strstr(_strlwr(fname), ".dll"); + bool res = ext && ext[4] == '\0' && DBGetContactSettingByte(NULL, "PluginDisable", fname, 0) == 0; + return res; +} diff --git a/plugins/CrashDumper/src/utils.h b/plugins/CrashDumper/src/utils.h new file mode 100644 index 0000000000..9089f57571 --- /dev/null +++ b/plugins/CrashDumper/src/utils.h @@ -0,0 +1,177 @@ +/* +Miranda Crash Dumper Plugin +Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#define _CRT_SECURE_NO_WARNINGS +#define MIRANDA_VER 0x0A00 + +#include +#include "sdkstuff.h" + +#ifdef _MSC_VER +#include +#endif + +#include + +#include "resource.h" + +#include + +#ifdef _MSC_VER + +#pragma warning( push ) +#pragma warning( disable : 4201 4100 ) +#include +#pragma warning( pop ) + +#else + +#include + +#endif + +#ifdef __GNUC__ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bkstring.h" + +#define MS_PROTO_ENUMPROTOS "Proto/EnumProtos" + +int crs_sntprintf(TCHAR *buffer, size_t count, const TCHAR* fmt, ...); + +#define crsi_u2a(dst, src) \ +{ \ + int cbLen = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL); \ + dst = (char*)alloca(cbLen+1); \ + WideCharToMultiByte(CP_ACP, 0, src, -1, dst, cbLen, NULL, NULL); \ +} + +#define crsi_a2u(dst, src, alloc) \ +{ \ + int cbLen = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0); \ + dst = (wchar_t*)alloc(sizeof(wchar_t) * (cbLen+1)); \ + MultiByteToWideChar(CP_ACP, 0, src, -1, dst, cbLen); \ +} + + + +#define crsi_t2a(d,s) crsi_u2a(d,s) +#define crsi_a2t(d,s) crsi_a2u(d,s,alloca) +#define crs_a2t(d,s) crsi_a2u(d,s,mir_alloc) + + + +#define SIZEOF(X) (sizeof(X)/sizeof(X[0])) + +#define MS_CRASHDUMPER_STORETOFILE "CrashDmp/StoreVerInfoToFile" +#define MS_CRASHDUMPER_STORETOCLIP "CrashDmp/StoreVerInfoToClip" +#define MS_CRASHDUMPER_GETINFO "Versioninfo/GetInfo" +#define MS_CRASHDUMPER_VIEWINFO "CrashDmp/ViewInfo" +#define MS_CRASHDUMPER_UPLOAD "CrashDmp/UploadInfo" +#define MS_CRASHDUMPER_URL "CrashDmp/StartUrl" + +#define PluginName "Crash Dumper" + +#define VI_FLAG_FORMAT 1 +#define VI_FLAG_PRNVAR 2 +#define VI_FLAG_PRNDLL 4 +#define VI_FLAG_WEATHER 8 + +struct VerTrnsfr +{ + char* buf; + bool autot; +}; + +extern HMODULE hInst; +extern DWORD mirandaVersion; +extern LCID packlcid; +extern bool servicemode; +extern bool clsdates; +extern bool dtsubfldr; + +extern TCHAR CrashLogFolder[MAX_PATH]; +extern TCHAR VersionInfoFolder[MAX_PATH]; + +void WriteBBFile(bkstring& buffer, bool hdr); +void WriteUtfFile(HANDLE hDumpFile, char* bufu); +void UnloadDbgHlp(void); + +LONG WINAPI myfilter(PEXCEPTION_POINTERS exc_ptr); +LONG WINAPI myfilterv(PEXCEPTION_POINTERS exc_ptr); +DWORD MirandaThreadFilter(DWORD code, EXCEPTION_POINTERS* info); + +void GetOSDisplayString(bkstring& buffer); +void GetInternetExplorerVersion(bkstring& buffer); +void GetProcessorString(bkstring& buffer); +void GetFreeMemoryString(bkstring& buffer); +void GetFreeDiskString(LPCTSTR dirname, bkstring& buffer); +void GetAdminString(bkstring& buffer); +void GetLanguageString(bkstring& buffer); +void GetLanguagePackString(bkstring& buffer); +void GetWow64String(bkstring& buffer); +void GetVersionInfo(HMODULE hLib, bkstring& buffer); + +void GetISO8061Time(SYSTEMTIME* stLocal, LPTSTR lpszString, DWORD dwSize); + +void ReadableExceptionInfo(PEXCEPTION_RECORD excrec, bkstring& buffer); + +void GetLastWriteTime(LPCTSTR fileName, LPTSTR lpszString, DWORD dwSize); +void GetLastWriteTime(FILETIME* ftime, LPTSTR lpszString, DWORD dwSize); +bool CreateDirectoryTree(LPTSTR szDir); +void StoreStringToClip(bkstring& buffer); +void ShowMessage(int type, const TCHAR* format, ...); +bool IsPluginEnabled(TCHAR* filename); + +PLUGININFOEX* GetMirInfo(HMODULE hModule); +const PLUGININFOEX* GetPluginInfoEx(void); + +void CreateMiniDump (HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr); +void CreateCrashReport(HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr, const TCHAR* msg); +void PrintVersionInfo(bkstring& buffer, unsigned flags = VI_FLAG_PRNVAR); +bool ProcessVIHash(bool store); + +void InitExceptionHandler(void); +void DestroyExceptionHandler(void); +void SetExceptionHandler(void); +void RemoveExceptionHandler(void); +void CheckForOtherCrashReportingPlugins(void); + +INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK DlgProcView(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); +void DestroyAllWindows(void); + +void UploadInit(void); +void UploadClose(void); +void OpenAuthUrl(const char* url); +void __cdecl VersionInfoUploadThread(void* arg); + +void InitIcons(void); +HICON LoadIconEx(const char* name, bool big = false); +HANDLE GetIconHandle(const char* name); +void ReleaseIconEx(const char* name); +void ReleaseIconEx(HICON hIcon); diff --git a/plugins/CrashDumper/src/vc6/dbghelp.h b/plugins/CrashDumper/src/vc6/dbghelp.h new file mode 100644 index 0000000000..d8a713060b --- /dev/null +++ b/plugins/CrashDumper/src/vc6/dbghelp.h @@ -0,0 +1,4532 @@ +/*++ BUILD Version: 0000 Increment this if a change has global effects + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + dbghelp.h + +Abstract: + + This module defines the prototypes and constants required for the image + help routines. + + Contains debugging support routines that are redistributable. + +Revision History: + +--*/ + +#ifndef _DBGHELP_ +#define _DBGHELP_ + +#if _MSC_VER > 1020 +#pragma once +#endif + + +// As a general principal always call the 64 bit version +// of every API, if a choice exists. The 64 bit version +// works great on 32 bit platforms, and is forward +// compatible to 64 bit platforms. + +#ifdef _WIN64 +#ifndef _IMAGEHLP64 +#define _IMAGEHLP64 +#endif +#endif + +// For those without specstrings.h +// Since there are different versions of this header, I need to +// individually test each item and define it if it is not around. + +#ifndef __in + #define __in +#endif +#ifndef __out + #define __out +#endif +#ifndef __inout + #define __inout +#endif +#ifndef __in_opt + #define __in_opt +#endif +#ifndef __out_opt + #define __out_opt +#endif +#ifndef __inout_opt + #define __inout_opt +#endif +#ifndef __in_ecount + #define __in_ecount(x) +#endif +#ifndef __out_ecount + #define __out_ecount(x) +#endif +#ifndef __inout_ecount + #define __inout_ecount(x) +#endif +#ifndef __in_bcount + #define __in_bcount(x) +#endif +#ifndef __out_bcount + #define __out_bcount(x) +#endif +#ifndef __inout_bcount + #define __inout_bcount(x) +#endif +#ifndef __out_xcount + #define __out_xcount(x) +#endif +#ifndef __deref_opt_out + #define __deref_opt_out +#endif +#ifndef __deref_out + #define __deref_out +#endif +#ifndef __out_ecount_opt + #define __out_ecount_opt(x) +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _IMAGEHLP_SOURCE_ + #define IMAGEAPI __stdcall + #define DBHLP_DEPRECIATED +#else + #define IMAGEAPI DECLSPEC_IMPORT __stdcall + #if (_MSC_VER >= 1300) && !defined(MIDL_PASS) + #define DBHLP_DEPRECIATED __declspec(deprecated) + #else + #define DBHLP_DEPRECIATED + #endif +#endif + +#define DBHLPAPI IMAGEAPI + +#define IMAGE_SEPARATION (64*1024) + +// Observant readers may notice that 2 new fields, +// 'fReadOnly' and 'Version' have been added to +// the LOADED_IMAGE structure after 'fDOSImage'. +// This does not change the size of the structure +// from previous headers. That is because while +// 'fDOSImage' is a byte, it is padded by the +// compiler to 4 bytes. So the 2 new fields are +// slipped into the extra space. + +typedef struct _LOADED_IMAGE { + PSTR ModuleName; + HANDLE hFile; + PUCHAR MappedAddress; +#ifdef _IMAGEHLP64 + PIMAGE_NT_HEADERS64 FileHeader; +#else + PIMAGE_NT_HEADERS32 FileHeader; +#endif + PIMAGE_SECTION_HEADER LastRvaSection; + ULONG NumberOfSections; + PIMAGE_SECTION_HEADER Sections; + ULONG Characteristics; + BOOLEAN fSystemImage; + BOOLEAN fDOSImage; + BOOLEAN fReadOnly; + UCHAR Version; + LIST_ENTRY Links; + ULONG SizeOfImage; +} LOADED_IMAGE, *PLOADED_IMAGE; + +#define MAX_SYM_NAME 2000 + + +// Error codes set by dbghelp functions. Call GetLastError +// to see them. +// Dbghelp also sets error codes found in winerror.h + +#define ERROR_IMAGE_NOT_STRIPPED 0x8800 // the image is not stripped. No dbg file available. +#define ERROR_NO_DBG_POINTER 0x8801 // image is stripped but there is no pointer to a dbg file +#define ERROR_NO_PDB_POINTER 0x8802 // image does not point to a pdb file + +typedef BOOL +(CALLBACK *PFIND_DEBUG_FILE_CALLBACK)( + __in HANDLE FileHandle, + __in PCSTR FileName, + __in PVOID CallerData + ); + +HANDLE +IMAGEAPI +SymFindDebugInfoFile( + __in HANDLE hProcess, + __in PCSTR FileName, + __out_ecount(MAX_PATH + 1) PSTR DebugFilePath, + __in_opt PFIND_DEBUG_FILE_CALLBACK Callback, + __in_opt PVOID CallerData + ); + +typedef BOOL +(CALLBACK *PFIND_DEBUG_FILE_CALLBACKW)( + __in HANDLE FileHandle, + __in PCWSTR FileName, + __in PVOID CallerData + ); + +HANDLE +IMAGEAPI +SymFindDebugInfoFileW( + __in HANDLE hProcess, + __in PCWSTR FileName, + __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath, + __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback, + __in_opt PVOID CallerData + ); + +HANDLE +IMAGEAPI +FindDebugInfoFile ( + __in PCSTR FileName, + __in PCSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PSTR DebugFilePath + ); + +HANDLE +IMAGEAPI +FindDebugInfoFileEx ( + __in PCSTR FileName, + __in PCSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PSTR DebugFilePath, + __in_opt PFIND_DEBUG_FILE_CALLBACK Callback, + __in_opt PVOID CallerData + ); + +HANDLE +IMAGEAPI +FindDebugInfoFileExW ( + __in PCWSTR FileName, + __in PCWSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath, + __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback, + __in_opt PVOID CallerData + ); + +typedef BOOL +(CALLBACK *PFINDFILEINPATHCALLBACK)( + PCSTR filename, + PVOID context + ); + +BOOL +IMAGEAPI +SymFindFileInPath( + __in HANDLE hprocess, + __in_opt PCSTR SearchPath, + __in PCSTR FileName, + __in_opt PVOID id, + __in DWORD two, + __in DWORD three, + __in DWORD flags, + __out_ecount(MAX_PATH + 1) PSTR FoundFile, + __in_opt PFINDFILEINPATHCALLBACK callback, + __in_opt PVOID context + ); + +typedef BOOL +(CALLBACK *PFINDFILEINPATHCALLBACKW)( + __in PCWSTR filename, + __in PVOID context + ); + +BOOL +IMAGEAPI +SymFindFileInPathW( + __in HANDLE hprocess, + __in_opt PCWSTR SearchPath, + __in PCWSTR FileName, + __in_opt PVOID id, + __in DWORD two, + __in DWORD three, + __in DWORD flags, + __out_ecount(MAX_PATH + 1) PWSTR FoundFile, + __in_opt PFINDFILEINPATHCALLBACKW callback, + __in_opt PVOID context + ); + +typedef BOOL +(CALLBACK *PFIND_EXE_FILE_CALLBACK)( + __in HANDLE FileHandle, + __in PCSTR FileName, + __in_opt PVOID CallerData + ); + +HANDLE +IMAGEAPI +SymFindExecutableImage( + __in HANDLE hProcess, + __in PCSTR FileName, + __out_ecount(MAX_PATH + 1) PSTR ImageFilePath, + __in PFIND_EXE_FILE_CALLBACK Callback, + __in PVOID CallerData + ); + +typedef BOOL +(CALLBACK *PFIND_EXE_FILE_CALLBACKW)( + __in HANDLE FileHandle, + __in PCWSTR FileName, + __in_opt PVOID CallerData + ); + +HANDLE +IMAGEAPI +SymFindExecutableImageW( + __in HANDLE hProcess, + __in PCWSTR FileName, + __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath, + __in PFIND_EXE_FILE_CALLBACKW Callback, + __in PVOID CallerData + ); + +HANDLE +IMAGEAPI +FindExecutableImage( + __in PCSTR FileName, + __in PCSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PSTR ImageFilePath + ); + +HANDLE +IMAGEAPI +FindExecutableImageEx( + __in PCSTR FileName, + __in PCSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PSTR ImageFilePath, + __in_opt PFIND_EXE_FILE_CALLBACK Callback, + __in_opt PVOID CallerData + ); + +HANDLE +IMAGEAPI +FindExecutableImageExW( + __in PCWSTR FileName, + __in PCWSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath, + __in_opt PFIND_EXE_FILE_CALLBACKW Callback, + __in PVOID CallerData + ); + +PIMAGE_NT_HEADERS +IMAGEAPI +ImageNtHeader ( + __in PVOID Base + ); + +PVOID +IMAGEAPI +ImageDirectoryEntryToDataEx ( + __in PVOID Base, + __in BOOLEAN MappedAsImage, + __in USHORT DirectoryEntry, + __out PULONG Size, + __out_opt PIMAGE_SECTION_HEADER *FoundHeader + ); + +PVOID +IMAGEAPI +ImageDirectoryEntryToData ( + __in PVOID Base, + __in BOOLEAN MappedAsImage, + __in USHORT DirectoryEntry, + __out PULONG Size + ); + +PIMAGE_SECTION_HEADER +IMAGEAPI +ImageRvaToSection( + __in PIMAGE_NT_HEADERS NtHeaders, + __in PVOID Base, + __in ULONG Rva + ); + +PVOID +IMAGEAPI +ImageRvaToVa( + __in PIMAGE_NT_HEADERS NtHeaders, + __in PVOID Base, + __in ULONG Rva, + __in_opt OUT PIMAGE_SECTION_HEADER *LastRvaSection + ); + +#ifndef _WIN64 +// This api won't be ported to Win64 - Fix your code. + +typedef struct _IMAGE_DEBUG_INFORMATION { + LIST_ENTRY List; + DWORD ReservedSize; + PVOID ReservedMappedBase; + USHORT ReservedMachine; + USHORT ReservedCharacteristics; + DWORD ReservedCheckSum; + DWORD ImageBase; + DWORD SizeOfImage; + + DWORD ReservedNumberOfSections; + PIMAGE_SECTION_HEADER ReservedSections; + + DWORD ReservedExportedNamesSize; + PSTR ReservedExportedNames; + + DWORD ReservedNumberOfFunctionTableEntries; + PIMAGE_FUNCTION_ENTRY ReservedFunctionTableEntries; + DWORD ReservedLowestFunctionStartingAddress; + DWORD ReservedHighestFunctionEndingAddress; + + DWORD ReservedNumberOfFpoTableEntries; + PFPO_DATA ReservedFpoTableEntries; + + DWORD SizeOfCoffSymbols; + PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols; + + DWORD ReservedSizeOfCodeViewSymbols; + PVOID ReservedCodeViewSymbols; + + PSTR ImageFilePath; + PSTR ImageFileName; + PSTR ReservedDebugFilePath; + + DWORD ReservedTimeDateStamp; + + BOOL ReservedRomImage; + PIMAGE_DEBUG_DIRECTORY ReservedDebugDirectory; + DWORD ReservedNumberOfDebugDirectories; + + DWORD ReservedOriginalFunctionTableBaseAddress; + + DWORD Reserved[ 2 ]; + +} IMAGE_DEBUG_INFORMATION, *PIMAGE_DEBUG_INFORMATION; + + +PIMAGE_DEBUG_INFORMATION +IMAGEAPI +MapDebugInformation( + __in_opt HANDLE FileHandle, + __in PCSTR FileName, + __in_opt PCSTR SymbolPath, + __in ULONG ImageBase + ); + +BOOL +IMAGEAPI +UnmapDebugInformation( + __out_xcount(unknown) PIMAGE_DEBUG_INFORMATION DebugInfo + ); + +#endif + +BOOL +IMAGEAPI +SearchTreeForFile( + __in PCSTR RootPath, + __in PCSTR InputPathName, + __out_ecount(MAX_PATH + 1) PSTR OutputPathBuffer + ); + +BOOL +IMAGEAPI +SearchTreeForFileW( + __in PCWSTR RootPath, + __in PCWSTR InputPathName, + __out_ecount(MAX_PATH + 1) PWSTR OutputPathBuffer + ); + +typedef BOOL +(CALLBACK *PENUMDIRTREE_CALLBACK)( + __in PCSTR FilePath, + __in_opt PVOID CallerData + ); + +BOOL +IMAGEAPI +EnumDirTree( + __in_opt HANDLE hProcess, + __in PCSTR RootPath, + __in PCSTR InputPathName, + __out_ecount_opt(MAX_PATH + 1) PSTR OutputPathBuffer, + __in_opt PENUMDIRTREE_CALLBACK cb, + __in_opt PVOID data + ); + +typedef BOOL +(CALLBACK *PENUMDIRTREE_CALLBACKW)( + __in PCWSTR FilePath, + __in_opt PVOID CallerData + ); + +BOOL +IMAGEAPI +EnumDirTreeW( + __in_opt HANDLE hProcess, + __in PCWSTR RootPath, + __in PCWSTR InputPathName, + __out_ecount_opt(MAX_PATH + 1) PWSTR OutputPathBuffer, + __in_opt PENUMDIRTREE_CALLBACKW cb, + __in_opt PVOID data + ); + +BOOL +IMAGEAPI +MakeSureDirectoryPathExists( + __in PCSTR DirPath + ); + +// +// UnDecorateSymbolName Flags +// + +#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration +#define UNDNAME_NO_LEADING_UNDERSCORES (0x0001) // Remove leading underscores from MS extended keywords +#define UNDNAME_NO_MS_KEYWORDS (0x0002) // Disable expansion of MS extended keywords +#define UNDNAME_NO_FUNCTION_RETURNS (0x0004) // Disable expansion of return type for primary declaration +#define UNDNAME_NO_ALLOCATION_MODEL (0x0008) // Disable expansion of the declaration model +#define UNDNAME_NO_ALLOCATION_LANGUAGE (0x0010) // Disable expansion of the declaration language specifier +#define UNDNAME_NO_MS_THISTYPE (0x0020) // NYI Disable expansion of MS keywords on the 'this' type for primary declaration +#define UNDNAME_NO_CV_THISTYPE (0x0040) // NYI Disable expansion of CV modifiers on the 'this' type for primary declaration +#define UNDNAME_NO_THISTYPE (0x0060) // Disable all modifiers on the 'this' type +#define UNDNAME_NO_ACCESS_SPECIFIERS (0x0080) // Disable expansion of access specifiers for members +#define UNDNAME_NO_THROW_SIGNATURES (0x0100) // Disable expansion of 'throw-signatures' for functions and pointers to functions +#define UNDNAME_NO_MEMBER_TYPE (0x0200) // Disable expansion of 'static' or 'virtual'ness of members +#define UNDNAME_NO_RETURN_UDT_MODEL (0x0400) // Disable expansion of MS model for UDT returns +#define UNDNAME_32_BIT_DECODE (0x0800) // Undecorate 32-bit decorated names +#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration; + // return just [scope::]name. Does expand template params +#define UNDNAME_NO_ARGUMENTS (0x2000) // Don't undecorate arguments to function +#define UNDNAME_NO_SPECIAL_SYMS (0x4000) // Don't undecorate special names (v-table, vcall, vector xxx, metatype, etc) + +DWORD +IMAGEAPI +WINAPI +UnDecorateSymbolName( + __in PCSTR name, + __out_ecount(maxStringLength) PSTR outputString, + __in DWORD maxStringLength, + __in DWORD flags + ); + +DWORD +IMAGEAPI +WINAPI +UnDecorateSymbolNameW( + __in PCWSTR name, + __out_ecount(maxStringLength) PWSTR outputString, + __in DWORD maxStringLength, + __in DWORD flags + ); + +// +// these values are used for synthesized file types +// that can be passed in as image headers instead of +// the standard ones from ntimage.h +// + +#define DBHHEADER_DEBUGDIRS 0x1 +#define DBHHEADER_CVMISC 0x2 + +typedef struct _MODLOAD_DATA { + DWORD ssize; // size of this struct + DWORD ssig; // signature identifying the passed data + PVOID data; // pointer to passed data + DWORD size; // size of passed data + DWORD flags; // options +} MODLOAD_DATA, *PMODLOAD_DATA; + +typedef struct _MODLOAD_CVMISC { + DWORD oCV; // ofset to the codeview record + size_t cCV; // size of the codeview record + DWORD oMisc; // offset to the misc record + size_t cMisc; // size of the misc record + DWORD dtImage; // datetime stamp of the image + DWORD cImage; // size of the image +} MODLOAD_CVMISC, *PMODLOAD_CVMISC; + +// +// StackWalking API +// + +typedef enum { + AddrMode1616, + AddrMode1632, + AddrModeReal, + AddrModeFlat +} ADDRESS_MODE; + +typedef struct _tagADDRESS64 { + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; +} ADDRESS64, *LPADDRESS64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define ADDRESS ADDRESS64 +#define LPADDRESS LPADDRESS64 +#else +typedef struct _tagADDRESS { + DWORD Offset; + WORD Segment; + ADDRESS_MODE Mode; +} ADDRESS, *LPADDRESS; + +__inline +void +Address32To64( + __in LPADDRESS a32, + __out LPADDRESS64 a64 + ) +{ + a64->Offset = (ULONG64)(LONG64)(LONG)a32->Offset; + a64->Segment = a32->Segment; + a64->Mode = a32->Mode; +} + +__inline +void +Address64To32( + __in LPADDRESS64 a64, + __out LPADDRESS a32 + ) +{ + a32->Offset = (ULONG)a64->Offset; + a32->Segment = a64->Segment; + a32->Mode = a64->Mode; +} +#endif + +// +// This structure is included in the STACKFRAME structure, +// and is used to trace through usermode callbacks in a thread's +// kernel stack. The values must be copied by the kernel debugger +// from the DBGKD_GET_VERSION and WAIT_STATE_CHANGE packets. +// + +// +// New KDHELP structure for 64 bit system support. +// This structure is preferred in new code. +// +typedef struct _KDHELP64 { + + // + // address of kernel thread object, as provided in the + // WAIT_STATE_CHANGE packet. + // + DWORD64 Thread; + + // + // offset in thread object to pointer to the current callback frame + // in kernel stack. + // + DWORD ThCallbackStack; + + // + // offset in thread object to pointer to the current callback backing + // store frame in kernel stack. + // + DWORD ThCallbackBStore; + + // + // offsets to values in frame: + // + // address of next callback frame + DWORD NextCallback; + + // address of saved frame pointer (if applicable) + DWORD FramePointer; + + + // + // Address of the kernel function that calls out to user mode + // + DWORD64 KiCallUserMode; + + // + // Address of the user mode dispatcher function + // + DWORD64 KeUserCallbackDispatcher; + + // + // Lowest kernel mode address + // + DWORD64 SystemRangeStart; + + // + // Address of the user mode exception dispatcher function. + // Added in API version 10. + // + DWORD64 KiUserExceptionDispatcher; + + // + // Stack bounds, added in API version 11. + // + DWORD64 StackBase; + DWORD64 StackLimit; + + DWORD64 Reserved[5]; + +} KDHELP64, *PKDHELP64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define KDHELP KDHELP64 +#define PKDHELP PKDHELP64 +#else +typedef struct _KDHELP { + + // + // address of kernel thread object, as provided in the + // WAIT_STATE_CHANGE packet. + // + DWORD Thread; + + // + // offset in thread object to pointer to the current callback frame + // in kernel stack. + // + DWORD ThCallbackStack; + + // + // offsets to values in frame: + // + // address of next callback frame + DWORD NextCallback; + + // address of saved frame pointer (if applicable) + DWORD FramePointer; + + // + // Address of the kernel function that calls out to user mode + // + DWORD KiCallUserMode; + + // + // Address of the user mode dispatcher function + // + DWORD KeUserCallbackDispatcher; + + // + // Lowest kernel mode address + // + DWORD SystemRangeStart; + + // + // offset in thread object to pointer to the current callback backing + // store frame in kernel stack. + // + DWORD ThCallbackBStore; + + // + // Address of the user mode exception dispatcher function. + // Added in API version 10. + // + DWORD KiUserExceptionDispatcher; + + // + // Stack bounds, added in API version 11. + // + DWORD StackBase; + DWORD StackLimit; + + DWORD Reserved[5]; + +} KDHELP, *PKDHELP; + +__inline +void +KdHelp32To64( + __in PKDHELP p32, + __out PKDHELP64 p64 + ) +{ + p64->Thread = p32->Thread; + p64->ThCallbackStack = p32->ThCallbackStack; + p64->NextCallback = p32->NextCallback; + p64->FramePointer = p32->FramePointer; + p64->KiCallUserMode = p32->KiCallUserMode; + p64->KeUserCallbackDispatcher = p32->KeUserCallbackDispatcher; + p64->SystemRangeStart = p32->SystemRangeStart; + p64->KiUserExceptionDispatcher = p32->KiUserExceptionDispatcher; + p64->StackBase = p32->StackBase; + p64->StackLimit = p32->StackLimit; +} +#endif + +typedef struct _tagSTACKFRAME64 { + ADDRESS64 AddrPC; // program counter + ADDRESS64 AddrReturn; // return address + ADDRESS64 AddrFrame; // frame pointer + ADDRESS64 AddrStack; // stack pointer + ADDRESS64 AddrBStore; // backing store pointer + PVOID FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD64 Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD64 Reserved[3]; + KDHELP64 KdHelp; +} STACKFRAME64, *LPSTACKFRAME64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define STACKFRAME STACKFRAME64 +#define LPSTACKFRAME LPSTACKFRAME64 +#else +typedef struct _tagSTACKFRAME { + ADDRESS AddrPC; // program counter + ADDRESS AddrReturn; // return address + ADDRESS AddrFrame; // frame pointer + ADDRESS AddrStack; // stack pointer + PVOID FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD Reserved[3]; + KDHELP KdHelp; + ADDRESS AddrBStore; // backing store pointer +} STACKFRAME, *LPSTACKFRAME; +#endif + + +typedef +BOOL +(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)( + __in HANDLE hProcess, + __in DWORD64 qwBaseAddress, + __out_bcount(nSize) PVOID lpBuffer, + __in DWORD nSize, + __out LPDWORD lpNumberOfBytesRead + ); + +typedef +PVOID +(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( + __in HANDLE ahProcess, + __in DWORD64 AddrBase + ); + +typedef +DWORD64 +(__stdcall *PGET_MODULE_BASE_ROUTINE64)( + __in HANDLE hProcess, + __in DWORD64 Address + ); + +typedef +DWORD64 +(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)( + __in HANDLE hProcess, + __in HANDLE hThread, + __in LPADDRESS64 lpaddr + ); + +BOOL +IMAGEAPI +StackWalk64( + __in DWORD MachineType, + __in HANDLE hProcess, + __in HANDLE hThread, + __inout LPSTACKFRAME64 StackFrame, + __inout PVOID ContextRecord, + __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) + +#define PREAD_PROCESS_MEMORY_ROUTINE PREAD_PROCESS_MEMORY_ROUTINE64 +#define PFUNCTION_TABLE_ACCESS_ROUTINE PFUNCTION_TABLE_ACCESS_ROUTINE64 +#define PGET_MODULE_BASE_ROUTINE PGET_MODULE_BASE_ROUTINE64 +#define PTRANSLATE_ADDRESS_ROUTINE PTRANSLATE_ADDRESS_ROUTINE64 + +#define StackWalk StackWalk64 + +#else + +typedef +BOOL +(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE)( + __in HANDLE hProcess, + __in DWORD lpBaseAddress, + __out_bcount(nSize) PVOID lpBuffer, + __in DWORD nSize, + __out PDWORD lpNumberOfBytesRead + ); + +typedef +PVOID +(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE)( + __in HANDLE hProcess, + __in DWORD AddrBase + ); + +typedef +DWORD +(__stdcall *PGET_MODULE_BASE_ROUTINE)( + __in HANDLE hProcess, + __in DWORD Address + ); + +typedef +DWORD +(__stdcall *PTRANSLATE_ADDRESS_ROUTINE)( + __in HANDLE hProcess, + __in HANDLE hThread, + __out LPADDRESS lpaddr + ); + +BOOL +IMAGEAPI +StackWalk( + DWORD MachineType, + __in HANDLE hProcess, + __in HANDLE hThread, + __inout LPSTACKFRAME StackFrame, + __inout PVOID ContextRecord, + __in_opt PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, + __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, + __in_opt PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, + __in_opt PTRANSLATE_ADDRESS_ROUTINE TranslateAddress + ); + +#endif + + +#define API_VERSION_NUMBER 11 + +typedef struct API_VERSION { + USHORT MajorVersion; + USHORT MinorVersion; + USHORT Revision; + USHORT Reserved; +} API_VERSION, *LPAPI_VERSION; + +LPAPI_VERSION +IMAGEAPI +ImagehlpApiVersion( + VOID + ); + +LPAPI_VERSION +IMAGEAPI +ImagehlpApiVersionEx( + __in LPAPI_VERSION AppVersion + ); + +DWORD +IMAGEAPI +GetTimestampForLoadedLibrary( + __in HMODULE Module + ); + +// +// typedefs for function pointers +// +typedef BOOL +(CALLBACK *PSYM_ENUMMODULES_CALLBACK64)( + __in PCSTR ModuleName, + __in DWORD64 BaseOfDll, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMMODULES_CALLBACKW64)( + __in PCWSTR ModuleName, + __in DWORD64 BaseOfDll, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PENUMLOADED_MODULES_CALLBACK64)( + __in PCSTR ModuleName, + __in DWORD64 ModuleBase, + __in ULONG ModuleSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PENUMLOADED_MODULES_CALLBACKW64)( + __in PCWSTR ModuleName, + __in DWORD64 ModuleBase, + __in ULONG ModuleSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64)( + __in PCSTR SymbolName, + __in DWORD64 SymbolAddress, + __in ULONG SymbolSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64W)( + __in PCWSTR SymbolName, + __in DWORD64 SymbolAddress, + __in ULONG SymbolSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYMBOL_REGISTERED_CALLBACK64)( + __in HANDLE hProcess, + __in ULONG ActionCode, + __in_opt ULONG64 CallbackData, + __in_opt ULONG64 UserContext + ); + +typedef +PVOID +(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK)( + __in HANDLE hProcess, + __in DWORD AddrBase, + __in_opt PVOID UserContext + ); + +typedef +PVOID +(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK64)( + __in HANDLE hProcess, + __in ULONG64 AddrBase, + __in ULONG64 UserContext + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) + +#define PSYM_ENUMMODULES_CALLBACK PSYM_ENUMMODULES_CALLBACK64 +#define PSYM_ENUMSYMBOLS_CALLBACK PSYM_ENUMSYMBOLS_CALLBACK64 +#define PSYM_ENUMSYMBOLS_CALLBACKW PSYM_ENUMSYMBOLS_CALLBACK64W +#define PENUMLOADED_MODULES_CALLBACK PENUMLOADED_MODULES_CALLBACK64 +#define PSYMBOL_REGISTERED_CALLBACK PSYMBOL_REGISTERED_CALLBACK64 +#define PSYMBOL_FUNCENTRY_CALLBACK PSYMBOL_FUNCENTRY_CALLBACK64 + +#else + +typedef BOOL +(CALLBACK *PSYM_ENUMMODULES_CALLBACK)( + __in PCSTR ModuleName, + __in ULONG BaseOfDll, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK)( + __in PCSTR SymbolName, + __in ULONG SymbolAddress, + __in ULONG SymbolSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACKW)( + __in PCWSTR SymbolName, + __in ULONG SymbolAddress, + __in ULONG SymbolSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PENUMLOADED_MODULES_CALLBACK)( + __in PCSTR ModuleName, + __in ULONG ModuleBase, + __in ULONG ModuleSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYMBOL_REGISTERED_CALLBACK)( + __in HANDLE hProcess, + __in ULONG ActionCode, + __in_opt PVOID CallbackData, + __in_opt PVOID UserContext + ); + +#endif + + +// values found in SYMBOL_INFO.Tag +// +// This was taken from cvconst.h and should +// not override any values found there. +// +// #define _NO_CVCONST_H_ if you don't +// have access to that file... + +#ifdef _NO_CVCONST_H + +// DIA enums + +enum SymTagEnum +{ + SymTagNull, + SymTagExe, + SymTagCompiland, + SymTagCompilandDetails, + SymTagCompilandEnv, + SymTagFunction, + SymTagBlock, + SymTagData, + SymTagAnnotation, + SymTagLabel, + SymTagPublicSymbol, + SymTagUDT, + SymTagEnum, + SymTagFunctionType, + SymTagPointerType, + SymTagArrayType, + SymTagBaseType, + SymTagTypedef, + SymTagBaseClass, + SymTagFriend, + SymTagFunctionArgType, + SymTagFuncDebugStart, + SymTagFuncDebugEnd, + SymTagUsingNamespace, + SymTagVTableShape, + SymTagVTable, + SymTagCustom, + SymTagThunk, + SymTagCustomType, + SymTagManagedType, + SymTagDimension, + SymTagMax +}; + +#endif + +// +// flags found in SYMBOL_INFO.Flags +// + +#define SYMFLAG_VALUEPRESENT 0x00000001 +#define SYMFLAG_REGISTER 0x00000008 +#define SYMFLAG_REGREL 0x00000010 +#define SYMFLAG_FRAMEREL 0x00000020 +#define SYMFLAG_PARAMETER 0x00000040 +#define SYMFLAG_LOCAL 0x00000080 +#define SYMFLAG_CONSTANT 0x00000100 +#define SYMFLAG_EXPORT 0x00000200 +#define SYMFLAG_FORWARDER 0x00000400 +#define SYMFLAG_FUNCTION 0x00000800 +#define SYMFLAG_VIRTUAL 0x00001000 +#define SYMFLAG_THUNK 0x00002000 +#define SYMFLAG_TLSREL 0x00004000 +#define SYMFLAG_SLOT 0x00008000 +#define SYMFLAG_ILREL 0x00010000 +#define SYMFLAG_METADATA 0x00020000 +#define SYMFLAG_CLR_TOKEN 0x00040000 + +// this resets SymNext/Prev to the beginning +// of the module passed in the address field + +#define SYMFLAG_RESET 0x80000000 + +// +// symbol type enumeration +// +typedef enum { + SymNone = 0, + SymCoff, + SymCv, + SymPdb, + SymExport, + SymDeferred, + SymSym, // .sym file + SymDia, + SymVirtual, + NumSymTypes +} SYM_TYPE; + +// +// symbol data structure +// + +typedef struct _IMAGEHLP_SYMBOL64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64) + DWORD64 Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + CHAR Name[1]; // symbol name (null terminated string) +} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; + +typedef struct _IMAGEHLP_SYMBOL64_PACKAGE { + IMAGEHLP_SYMBOL64 sym; + CHAR name[MAX_SYM_NAME + 1]; +} IMAGEHLP_SYMBOL64_PACKAGE, *PIMAGEHLP_SYMBOL64_PACKAGE; + +typedef struct _IMAGEHLP_SYMBOLW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOLW64) + DWORD64 Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + WCHAR Name[1]; // symbol name (null terminated string) +} IMAGEHLP_SYMBOLW64, *PIMAGEHLP_SYMBOLW64; + +typedef struct _IMAGEHLP_SYMBOLW64_PACKAGE { + IMAGEHLP_SYMBOLW64 sym; + WCHAR name[MAX_SYM_NAME + 1]; +} IMAGEHLP_SYMBOLW64_PACKAGE, *PIMAGEHLP_SYMBOLW64_PACKAGE; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) + + #define IMAGEHLP_SYMBOL IMAGEHLP_SYMBOL64 + #define PIMAGEHLP_SYMBOL PIMAGEHLP_SYMBOL64 + #define IMAGEHLP_SYMBOL_PACKAGE IMAGEHLP_SYMBOL64_PACKAGE + #define PIMAGEHLP_SYMBOL_PACKAGE PIMAGEHLP_SYMBOL64_PACKAGE + #define IMAGEHLP_SYMBOLW IMAGEHLP_SYMBOLW64 + #define PIMAGEHLP_SYMBOLW PIMAGEHLP_SYMBOLW64 + #define IMAGEHLP_SYMBOLW_PACKAGE IMAGEHLP_SYMBOLW64_PACKAGE + #define PIMAGEHLP_SYMBOLW_PACKAGE PIMAGEHLP_SYMBOLW64_PACKAGE + +#else + + typedef struct _IMAGEHLP_SYMBOL { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL) + DWORD Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + CHAR Name[1]; // symbol name (null terminated string) + } IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL; + + typedef struct _IMAGEHLP_SYMBOL_PACKAGE { + IMAGEHLP_SYMBOL sym; + CHAR name[MAX_SYM_NAME + 1]; + } IMAGEHLP_SYMBOL_PACKAGE, *PIMAGEHLP_SYMBOL_PACKAGE; + + typedef struct _IMAGEHLP_SYMBOLW { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOLW) + DWORD Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + WCHAR Name[1]; // symbol name (null terminated string) + } IMAGEHLP_SYMBOLW, *PIMAGEHLP_SYMBOLW; + + typedef struct _IMAGEHLP_SYMBOLW_PACKAGE { + IMAGEHLP_SYMBOLW sym; + WCHAR name[MAX_SYM_NAME + 1]; + } IMAGEHLP_SYMBOLW_PACKAGE, *PIMAGEHLP_SYMBOLW_PACKAGE; + +#endif + +// +// module data structure +// + +typedef struct _IMAGEHLP_MODULE64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name + // new elements: 07-Jun-2002 + CHAR LoadedPdbName[256]; // pdb file name + DWORD CVSig; // Signature of the CV record in the debug directories + CHAR CVData[MAX_PATH * 3]; // Contents of the CV record + DWORD PdbSig; // Signature of PDB + GUID PdbSig70; // Signature of PDB (VC 7 and up) + DWORD PdbAge; // DBI age of pdb + BOOL PdbUnmatched; // loaded an unmatched pdb + BOOL DbgUnmatched; // loaded an unmatched dbg + BOOL LineNumbers; // we have line number information + BOOL GlobalSymbols; // we have internal symbol information + BOOL TypeInfo; // we have type information + // new elements: 17-Dec-2003 + BOOL SourceIndexed; // pdb supports source server + BOOL Publics; // contains public symbols +} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; + +typedef struct _IMAGEHLP_MODULEW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + WCHAR ModuleName[32]; // module name + WCHAR ImageName[256]; // image name + // new elements: 07-Jun-2002 + WCHAR LoadedImageName[256]; // symbol file name + WCHAR LoadedPdbName[256]; // pdb file name + DWORD CVSig; // Signature of the CV record in the debug directories + WCHAR CVData[MAX_PATH * 3]; // Contents of the CV record + DWORD PdbSig; // Signature of PDB + GUID PdbSig70; // Signature of PDB (VC 7 and up) + DWORD PdbAge; // DBI age of pdb + BOOL PdbUnmatched; // loaded an unmatched pdb + BOOL DbgUnmatched; // loaded an unmatched dbg + BOOL LineNumbers; // we have line number information + BOOL GlobalSymbols; // we have internal symbol information + BOOL TypeInfo; // we have type information + // new elements: 17-Dec-2003 + BOOL SourceIndexed; // pdb supports source server + BOOL Publics; // contains public symbols +} IMAGEHLP_MODULEW64, *PIMAGEHLP_MODULEW64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_MODULE IMAGEHLP_MODULE64 +#define PIMAGEHLP_MODULE PIMAGEHLP_MODULE64 +#define IMAGEHLP_MODULEW IMAGEHLP_MODULEW64 +#define PIMAGEHLP_MODULEW PIMAGEHLP_MODULEW64 +#else +typedef struct _IMAGEHLP_MODULE { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE) + DWORD BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name +} IMAGEHLP_MODULE, *PIMAGEHLP_MODULE; + +typedef struct _IMAGEHLP_MODULEW { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE) + DWORD BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + WCHAR ModuleName[32]; // module name + WCHAR ImageName[256]; // image name + WCHAR LoadedImageName[256]; // symbol file name +} IMAGEHLP_MODULEW, *PIMAGEHLP_MODULEW; +#endif + +// +// source file line data structure +// + +typedef struct _IMAGEHLP_LINE64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; + +typedef struct _IMAGEHLP_LINEW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PWSTR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINEW64, *PIMAGEHLP_LINEW64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_LINE IMAGEHLP_LINE64 +#define PIMAGEHLP_LINE PIMAGEHLP_LINE64 +#else +typedef struct _IMAGEHLP_LINE { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD Address; // first instruction of line +} IMAGEHLP_LINE, *PIMAGEHLP_LINE; + +typedef struct _IMAGEHLP_LINEW { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINEW, *PIMAGEHLP_LINEW; +#endif + +// +// source file structure +// + +typedef struct _SOURCEFILE { + DWORD64 ModBase; // base address of loaded module + PCHAR FileName; // full filename of source +} SOURCEFILE, *PSOURCEFILE; + +typedef struct _SOURCEFILEW { + DWORD64 ModBase; // base address of loaded module + PWSTR FileName; // full filename of source +} SOURCEFILEW, *PSOURCEFILEW; + +// +// data structures used for registered symbol callbacks +// + +#define CBA_DEFERRED_SYMBOL_LOAD_START 0x00000001 +#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE 0x00000002 +#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE 0x00000003 +#define CBA_SYMBOLS_UNLOADED 0x00000004 +#define CBA_DUPLICATE_SYMBOL 0x00000005 +#define CBA_READ_MEMORY 0x00000006 +#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL 0x00000007 +#define CBA_SET_OPTIONS 0x00000008 +#define CBA_EVENT 0x00000010 +#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL 0x00000020 +#define CBA_DEBUG_INFO 0x10000000 +#define CBA_SRCSRV_INFO 0x20000000 +#define CBA_SRCSRV_EVENT 0x40000000 + +typedef struct _IMAGEHLP_CBA_READ_MEMORY { + DWORD64 addr; // address to read from + PVOID buf; // buffer to read to + DWORD bytes; // amount of bytes to read + DWORD *bytesread; // pointer to store amount of bytes read +} IMAGEHLP_CBA_READ_MEMORY, *PIMAGEHLP_CBA_READ_MEMORY; + +enum { + sevInfo = 0, + sevProblem, + sevAttn, + sevFatal, + sevMax // unused +}; + +#define EVENT_SRCSPEW_START 100 +#define EVENT_SRCSPEW 100 +#define EVENT_SRCSPEW_END 199 + +typedef struct _IMAGEHLP_CBA_EVENT { + DWORD severity; // values from sevInfo to sevFatal + DWORD code; // numerical code IDs the error + PCHAR desc; // may contain a text description of the error + PVOID object; // value dependant upon the error code +} IMAGEHLP_CBA_EVENT, *PIMAGEHLP_CBA_EVENT; + +typedef struct _IMAGEHLP_CBA_EVENTW { + DWORD severity; // values from sevInfo to sevFatal + DWORD code; // numerical code IDs the error + PCWSTR desc; // may contain a text description of the error + PVOID object; // value dependant upon the error code +} IMAGEHLP_CBA_EVENTW, *PIMAGEHLP_CBA_EVENTW; + +typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64) + DWORD64 BaseOfImage; // base load address of module + DWORD CheckSum; // checksum from the pe header + DWORD TimeDateStamp; // date/time stamp from pe header + CHAR FileName[MAX_PATH]; // symbols file or image name + BOOLEAN Reparse; // load failure reparse + HANDLE hFile; // file handle, if passed + DWORD Flags; // +} IMAGEHLP_DEFERRED_SYMBOL_LOAD64, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD64; + +typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOADW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOADW64) + DWORD64 BaseOfImage; // base load address of module + DWORD CheckSum; // checksum from the pe header + DWORD TimeDateStamp; // date/time stamp from pe header + WCHAR FileName[MAX_PATH + 1]; // symbols file or image name + BOOLEAN Reparse; // load failure reparse + HANDLE hFile; // file handle, if passed + DWORD Flags; // +} IMAGEHLP_DEFERRED_SYMBOL_LOADW64, *PIMAGEHLP_DEFERRED_SYMBOL_LOADW64; + +#define DSLFLAG_MISMATCHED_PDB 0x1 +#define DSLFLAG_MISMATCHED_DBG 0x2 + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_DEFERRED_SYMBOL_LOAD IMAGEHLP_DEFERRED_SYMBOL_LOAD64 +#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 +#else +typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD) + DWORD BaseOfImage; // base load address of module + DWORD CheckSum; // checksum from the pe header + DWORD TimeDateStamp; // date/time stamp from pe header + CHAR FileName[MAX_PATH]; // symbols file or image name + BOOLEAN Reparse; // load failure reparse + HANDLE hFile; // file handle, if passed +} IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD; +#endif + +typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL64) + DWORD NumberOfDups; // number of duplicates in the Symbol array + PIMAGEHLP_SYMBOL64 Symbol; // array of duplicate symbols + DWORD SelectedSymbol; // symbol selected (-1 to start) +} IMAGEHLP_DUPLICATE_SYMBOL64, *PIMAGEHLP_DUPLICATE_SYMBOL64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_DUPLICATE_SYMBOL IMAGEHLP_DUPLICATE_SYMBOL64 +#define PIMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_DUPLICATE_SYMBOL64 +#else +typedef struct _IMAGEHLP_DUPLICATE_SYMBOL { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL) + DWORD NumberOfDups; // number of duplicates in the Symbol array + PIMAGEHLP_SYMBOL Symbol; // array of duplicate symbols + DWORD SelectedSymbol; // symbol selected (-1 to start) +} IMAGEHLP_DUPLICATE_SYMBOL, *PIMAGEHLP_DUPLICATE_SYMBOL; +#endif + +// If dbghelp ever needs to display graphical UI, it will use this as the parent window. + +BOOL +IMAGEAPI +SymSetParentWindow( + __in HWND hwnd + ); + +PCHAR +IMAGEAPI +SymSetHomeDirectory( + __in_opt HANDLE hProcess, + __in_opt PCSTR dir + ); + +PWSTR +IMAGEAPI +SymSetHomeDirectoryW( + __in_opt HANDLE hProcess, + __in_opt PCWSTR dir + ); + +PCHAR +IMAGEAPI +SymGetHomeDirectory( + __in DWORD type, + __out_ecount(size) PSTR dir, + __in size_t size + ); + +PWSTR +IMAGEAPI +SymGetHomeDirectoryW( + __in DWORD type, + __out_ecount(size) PWSTR dir, + __in size_t size + ); + +enum { + hdBase = 0, // root directory for dbghelp + hdSym, // where symbols are stored + hdSrc, // where source is stored + hdMax // end marker +}; + +typedef struct _OMAP { + ULONG rva; + ULONG rvaTo; +} OMAP, *POMAP; + +BOOL +IMAGEAPI +SymGetOmaps( + __in HANDLE hProcess, + __in DWORD64 BaseOfDll, + __out POMAP *OmapTo, + __out PDWORD64 cOmapTo, + __out POMAP *OmapFrom, + __out PDWORD64 cOmapFrom + ); + +// +// options that are set/returned by SymSetOptions() & SymGetOptions() +// these are used as a mask +// +#define SYMOPT_CASE_INSENSITIVE 0x00000001 +#define SYMOPT_UNDNAME 0x00000002 +#define SYMOPT_DEFERRED_LOADS 0x00000004 +#define SYMOPT_NO_CPP 0x00000008 +#define SYMOPT_LOAD_LINES 0x00000010 +#define SYMOPT_OMAP_FIND_NEAREST 0x00000020 +#define SYMOPT_LOAD_ANYTHING 0x00000040 +#define SYMOPT_IGNORE_CVREC 0x00000080 +#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 +#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 +#define SYMOPT_EXACT_SYMBOLS 0x00000400 +#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 +#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 +#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 +#define SYMOPT_PUBLICS_ONLY 0x00004000 +#define SYMOPT_NO_PUBLICS 0x00008000 +#define SYMOPT_AUTO_PUBLICS 0x00010000 +#define SYMOPT_NO_IMAGE_SEARCH 0x00020000 +#define SYMOPT_SECURE 0x00040000 +#define SYMOPT_NO_PROMPTS 0x00080000 +#define SYMOPT_OVERWRITE 0x00100000 +#define SYMOPT_IGNORE_IMAGEDIR 0x00200000 +#define SYMOPT_FLAT_DIRECTORY 0x00400000 +#define SYMOPT_FAVOR_COMPRESSED 0x00800000 +#define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 +#define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 + +#define SYMOPT_DEBUG 0x80000000 + +DWORD +IMAGEAPI +SymSetOptions( + __in DWORD SymOptions + ); + +DWORD +IMAGEAPI +SymGetOptions( + VOID + ); + +BOOL +IMAGEAPI +SymCleanup( + __in HANDLE hProcess + ); + +BOOL +IMAGEAPI +SymMatchString( + __in PCSTR string, + __in PCSTR expression, + __in BOOL fCase + ); + +BOOL +IMAGEAPI +SymMatchStringA( + __in PCSTR string, + __in PCSTR expression, + __in BOOL fCase + ); + +BOOL +IMAGEAPI +SymMatchStringW( + __in PCWSTR string, + __in PCWSTR expression, + __in BOOL fCase + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMSOURCEFILES_CALLBACK)( + __in PSOURCEFILE pSourceFile, + __in_opt PVOID UserContext + ); + +// for backwards compatibility - don't use this +#define PSYM_ENUMSOURCFILES_CALLBACK PSYM_ENUMSOURCEFILES_CALLBACK + +BOOL +IMAGEAPI +SymEnumSourceFiles( + __in HANDLE hProcess, + __in ULONG64 ModBase, + __in_opt PCSTR Mask, + __in PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMSOURCEFILES_CALLBACKW)( + __in PSOURCEFILEW pSourceFile, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumSourceFilesW( + __in HANDLE hProcess, + __in ULONG64 ModBase, + __in_opt PCWSTR Mask, + __in PSYM_ENUMSOURCEFILES_CALLBACKW cbSrcFiles, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumerateModules64( + __in HANDLE hProcess, + __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumerateModulesW64( + __in HANDLE hProcess, + __in PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback, + __in_opt PVOID UserContext + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymEnumerateModules SymEnumerateModules64 +#else +BOOL +IMAGEAPI +SymEnumerateModules( + __in HANDLE hProcess, + __in PSYM_ENUMMODULES_CALLBACK EnumModulesCallback, + __in_opt PVOID UserContext + ); +#endif + +BOOL +IMAGEAPI +EnumerateLoadedModulesEx( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +EnumerateLoadedModulesExW( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +EnumerateLoadedModules64( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +EnumerateLoadedModulesW64( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, + __in_opt PVOID UserContext + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define EnumerateLoadedModules EnumerateLoadedModules64 +#else +BOOL +IMAGEAPI +EnumerateLoadedModules( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback, + __in_opt PVOID UserContext + ); +#endif + +PVOID +IMAGEAPI +SymFunctionTableAccess64( + __in HANDLE hProcess, + __in DWORD64 AddrBase + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymFunctionTableAccess SymFunctionTableAccess64 +#else +PVOID +IMAGEAPI +SymFunctionTableAccess( + __in HANDLE hProcess, + __in DWORD AddrBase + ); +#endif + +BOOL +IMAGEAPI +SymGetUnwindInfo( + __in HANDLE hProcess, + __in DWORD64 Address, + __out_bcount_opt(*Size) PVOID Buffer, + __inout PULONG Size + ); + +BOOL +IMAGEAPI +SymGetModuleInfo64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PIMAGEHLP_MODULE64 ModuleInfo + ); + +BOOL +IMAGEAPI +SymGetModuleInfoW64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PIMAGEHLP_MODULEW64 ModuleInfo + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetModuleInfo SymGetModuleInfo64 +#define SymGetModuleInfoW SymGetModuleInfoW64 +#else +BOOL +IMAGEAPI +SymGetModuleInfo( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out PIMAGEHLP_MODULE ModuleInfo + ); + +BOOL +IMAGEAPI +SymGetModuleInfoW( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out PIMAGEHLP_MODULEW ModuleInfo + ); +#endif + +DWORD64 +IMAGEAPI +SymGetModuleBase64( + __in HANDLE hProcess, + __in DWORD64 qwAddr + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetModuleBase SymGetModuleBase64 +#else +DWORD +IMAGEAPI +SymGetModuleBase( + __in HANDLE hProcess, + __in DWORD dwAddr + ); +#endif + +typedef struct _SRCCODEINFO { + DWORD SizeOfStruct; // set to sizeof(SRCCODEINFO) + PVOID Key; // not used + DWORD64 ModBase; // base address of module this applies to + CHAR Obj[MAX_PATH + 1]; // the object file within the module + CHAR FileName[MAX_PATH + 1]; // full filename + DWORD LineNumber; // line number in file + DWORD64 Address; // first instruction of line +} SRCCODEINFO, *PSRCCODEINFO; + +typedef struct _SRCCODEINFOW { + DWORD SizeOfStruct; // set to sizeof(SRCCODEINFO) + PVOID Key; // not used + DWORD64 ModBase; // base address of module this applies to + WCHAR Obj[MAX_PATH + 1]; // the object file within the module + WCHAR FileName[MAX_PATH + 1]; // full filename + DWORD LineNumber; // line number in file + DWORD64 Address; // first instruction of line +} SRCCODEINFOW, *PSRCCODEINFOW; + +typedef BOOL +(CALLBACK *PSYM_ENUMLINES_CALLBACK)( + __in PSRCCODEINFO LineInfo, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumLines( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR Obj, + __in_opt PCSTR File, + __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMLINES_CALLBACKW)( + __in PSRCCODEINFOW LineInfo, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumLinesW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCWSTR Obj, + __in_opt PCWSTR File, + __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymGetLineFromAddr64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINE64 Line64 + ); + +BOOL +IMAGEAPI +SymGetLineFromAddrW64( + __in HANDLE hProcess, + __in DWORD64 dwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINEW64 Line + ); + +BOOL +IMAGEAPI +SymEnumSourceLines( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR Obj, + __in_opt PCSTR File, + __in_opt DWORD Line, + __in DWORD Flags, + __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumSourceLinesW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCWSTR Obj, + __in_opt PCWSTR File, + __in_opt DWORD Line, + __in DWORD Flags, + __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback, + __in_opt PVOID UserContext + ); + +// flags for SymEnumSourceLines + +#define ESLFLAG_FULLPATH 0x1 +#define ESLFLAG_NEAREST 0x2 +#define ESLFLAG_PREV 0x4 +#define ESLFLAG_NEXT 0x8 + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetLineFromAddr SymGetLineFromAddr64 +#define SymGetLineFromAddrW SymGetLineFromAddrW64 +#else +BOOL +IMAGEAPI +SymGetLineFromAddr( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINE Line + ); + +BOOL +IMAGEAPI +SymGetLineFromAddrW( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINEW Line + ); +#endif + +BOOL +IMAGEAPI +SymGetLineFromName64( + __in HANDLE hProcess, + __in_opt PCSTR ModuleName, + __in_opt PCSTR FileName, + __in DWORD dwLineNumber, + __out PLONG plDisplacement, + __inout PIMAGEHLP_LINE64 Line + ); + +BOOL +IMAGEAPI +SymGetLineFromNameW64( + __in HANDLE hProcess, + __in_opt PCWSTR ModuleName, + __in_opt PCWSTR FileName, + __in DWORD dwLineNumber, + __out PLONG plDisplacement, + __inout PIMAGEHLP_LINEW64 Line + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetLineFromName SymGetLineFromName64 +#else +BOOL +IMAGEAPI +SymGetLineFromName( + __in HANDLE hProcess, + __in_opt PCSTR ModuleName, + __in_opt PCSTR FileName, + __in DWORD dwLineNumber, + __out PLONG plDisplacement, + __inout PIMAGEHLP_LINE Line + ); +#endif + +BOOL +IMAGEAPI +SymGetLineNext64( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINE64 Line + ); + +BOOL +IMAGEAPI +SymGetLineNextW64( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINEW64 Line + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetLineNext SymGetLineNext64 +#else +BOOL +IMAGEAPI +SymGetLineNext( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINE Line + ); + +BOOL +IMAGEAPI +SymGetLineNextW( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINEW Line + ); +#endif + +BOOL +IMAGEAPI +SymGetLinePrev64( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINE64 Line + ); + +BOOL +IMAGEAPI +SymGetLinePrevW64( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINEW64 Line + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetLinePrev SymGetLinePrev64 +#else +BOOL +IMAGEAPI +SymGetLinePrev( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINE Line + ); + +BOOL +IMAGEAPI +SymGetLinePrevW( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINEW Line + ); +#endif + +ULONG +IMAGEAPI +SymGetFileLineOffsets64( + __in HANDLE hProcess, + __in_opt PCSTR ModuleName, + __in PCSTR FileName, + __out_ecount(BufferLines) PDWORD64 Buffer, + __in ULONG BufferLines + ); + +BOOL +IMAGEAPI +SymMatchFileName( + __in PCSTR FileName, + __in PCSTR Match, + __deref_opt_out PSTR *FileNameStop, + __deref_opt_out PSTR *MatchStop + ); + +BOOL +IMAGEAPI +SymMatchFileNameW( + __in PCWSTR FileName, + __in PCWSTR Match, + __deref_opt_out PWSTR *FileNameStop, + __deref_opt_out PWSTR *MatchStop + ); + +BOOL +IMAGEAPI +SymGetSourceFile( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR Params, + __in PCSTR FileSpec, + __out_ecount(Size) PSTR FilePath, + __in DWORD Size + ); + +BOOL +IMAGEAPI +SymGetSourceFileW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCWSTR Params, + __in PCWSTR FileSpec, + __out_ecount(Size) PWSTR FilePath, + __in DWORD Size + ); + +BOOL +IMAGEAPI +SymGetSourceFileToken( + __in HANDLE hProcess, + __in ULONG64 Base, + __in PCSTR FileSpec, + __deref_out PVOID *Token, + __out DWORD *Size + ); + +BOOL +IMAGEAPI +SymGetSourceFileTokenW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in PCWSTR FileSpec, + __deref_out PVOID *Token, + __out DWORD *Size + ); + +BOOL +IMAGEAPI +SymGetSourceFileFromToken( + __in HANDLE hProcess, + __in PVOID Token, + __in_opt PCSTR Params, + __out_ecount(Size) PSTR FilePath, + __in DWORD Size + ); + +BOOL +IMAGEAPI +SymGetSourceFileFromTokenW( + __in HANDLE hProcess, + __in PVOID Token, + __in_opt PCWSTR Params, + __out_ecount(Size) PWSTR FilePath, + __in DWORD Size + ); + +BOOL +IMAGEAPI +SymGetSourceVarFromToken( + __in HANDLE hProcess, + __in PVOID Token, + __in_opt PCSTR Params, + __in PCSTR VarName, + __out_ecount(Size) PSTR Value, + __in DWORD Size + ); + +BOOL +IMAGEAPI +SymGetSourceVarFromTokenW( + __in HANDLE hProcess, + __in PVOID Token, + __in_opt PCWSTR Params, + __in PCWSTR VarName, + __out_ecount(Size) PWSTR Value, + __in DWORD Size + ); + +typedef BOOL (CALLBACK *PENUMSOURCEFILETOKENSCALLBACK)(__in PVOID token, __in size_t size); + +BOOL +IMAGEAPI +SymEnumSourceFileTokens( + __in HANDLE hProcess, + __in ULONG64 Base, + __in PENUMSOURCEFILETOKENSCALLBACK Callback + ); + +BOOL +IMAGEAPI +SymInitialize( + __in HANDLE hProcess, + __in_opt PCSTR UserSearchPath, + __in BOOL fInvadeProcess + ); + +BOOL +IMAGEAPI +SymInitializeW( + __in HANDLE hProcess, + __in_opt PCWSTR UserSearchPath, + __in BOOL fInvadeProcess + ); + +BOOL +IMAGEAPI +SymGetSearchPath( + __in HANDLE hProcess, + __out_ecount(SearchPathLength) PSTR SearchPath, + __in DWORD SearchPathLength + ); + +BOOL +IMAGEAPI +SymGetSearchPathW( + __in HANDLE hProcess, + __out_ecount(SearchPathLength) PWSTR SearchPath, + __in DWORD SearchPathLength + ); + +BOOL +IMAGEAPI +SymSetSearchPath( + __in HANDLE hProcess, + __in_opt PCSTR SearchPath + ); + +BOOL +IMAGEAPI +SymSetSearchPathW( + __in HANDLE hProcess, + __in_opt PCWSTR SearchPath + ); + +#define SLMFLAG_VIRTUAL 0x1 +#define SLMFLAG_ALT_INDEX 0x2 +#define SLMFLAG_NO_SYMBOLS 0x4 + +DWORD64 +IMAGEAPI +SymLoadModuleEx( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCSTR ImageName, + __in_opt PCSTR ModuleName, + __in DWORD64 BaseOfDll, + __in DWORD DllSize, + __in_opt PMODLOAD_DATA Data, + __in_opt DWORD Flags + ); + +DWORD64 +IMAGEAPI +SymLoadModuleExW( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCWSTR ImageName, + __in_opt PCWSTR ModuleName, + __in DWORD64 BaseOfDll, + __in DWORD DllSize, + __in_opt PMODLOAD_DATA Data, + __in_opt DWORD Flags + ); + +BOOL +IMAGEAPI +SymUnloadModule64( + __in HANDLE hProcess, + __in DWORD64 BaseOfDll + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymUnloadModule SymUnloadModule64 +#else +BOOL +IMAGEAPI +SymUnloadModule( + __in HANDLE hProcess, + __in DWORD BaseOfDll + ); +#endif + +BOOL +IMAGEAPI +SymUnDName64( + __in PIMAGEHLP_SYMBOL64 sym, // Symbol to undecorate + __out_ecount(UnDecNameLength) PSTR UnDecName, // Buffer to store undecorated name in + __in DWORD UnDecNameLength // Size of the buffer + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymUnDName SymUnDName64 +#else +BOOL +IMAGEAPI +SymUnDName( + __in PIMAGEHLP_SYMBOL sym, // Symbol to undecorate + __out_ecount(UnDecNameLength) PSTR UnDecName, // Buffer to store undecorated name in + __in DWORD UnDecNameLength // Size of the buffer + ); +#endif + +BOOL +IMAGEAPI +SymRegisterCallback64( + __in HANDLE hProcess, + __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, + __in ULONG64 UserContext + ); + +BOOL +IMAGEAPI +SymRegisterCallbackW64( + __in HANDLE hProcess, + __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, + __in ULONG64 UserContext + ); + +BOOL +IMAGEAPI +SymRegisterFunctionEntryCallback64( + __in HANDLE hProcess, + __in PSYMBOL_FUNCENTRY_CALLBACK64 CallbackFunction, + __in ULONG64 UserContext + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymRegisterCallback SymRegisterCallback64 +#define SymRegisterFunctionEntryCallback SymRegisterFunctionEntryCallback64 +#else +BOOL +IMAGEAPI +SymRegisterCallback( + __in HANDLE hProcess, + __in PSYMBOL_REGISTERED_CALLBACK CallbackFunction, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymRegisterFunctionEntryCallback( + __in HANDLE hProcess, + __in PSYMBOL_FUNCENTRY_CALLBACK CallbackFunction, + __in_opt PVOID UserContext + ); +#endif + + +typedef struct _IMAGEHLP_SYMBOL_SRC { + DWORD sizeofstruct; + DWORD type; + char file[MAX_PATH]; +} IMAGEHLP_SYMBOL_SRC, *PIMAGEHLP_SYMBOL_SRC; + +typedef struct _MODULE_TYPE_INFO { // AKA TYPTYP + USHORT dataLength; + USHORT leaf; + BYTE data[1]; +} MODULE_TYPE_INFO, *PMODULE_TYPE_INFO; + +typedef struct _SYMBOL_INFO { + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG Index; + ULONG Size; + ULONG64 ModBase; // Base Address of module comtaining this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + CHAR Name[1]; // Name of symbol +} SYMBOL_INFO, *PSYMBOL_INFO; + +typedef struct _SYMBOL_INFO_PACKAGE { + SYMBOL_INFO si; + CHAR name[MAX_SYM_NAME + 1]; +} SYMBOL_INFO_PACKAGE, *PSYMBOL_INFO_PACKAGE; + +typedef struct _SYMBOL_INFOW { + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG Index; + ULONG Size; + ULONG64 ModBase; // Base Address of module comtaining this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + WCHAR Name[1]; // Name of symbol +} SYMBOL_INFOW, *PSYMBOL_INFOW; + +typedef struct _SYMBOL_INFO_PACKAGEW { + SYMBOL_INFOW si; + WCHAR name[MAX_SYM_NAME + 1]; +} SYMBOL_INFO_PACKAGEW, *PSYMBOL_INFO_PACKAGEW; + +typedef struct _IMAGEHLP_STACK_FRAME +{ + ULONG64 InstructionOffset; + ULONG64 ReturnOffset; + ULONG64 FrameOffset; + ULONG64 StackOffset; + ULONG64 BackingStoreOffset; + ULONG64 FuncTableEntry; + ULONG64 Params[4]; + ULONG64 Reserved[5]; + BOOL Virtual; + ULONG Reserved2; +} IMAGEHLP_STACK_FRAME, *PIMAGEHLP_STACK_FRAME; + +typedef VOID IMAGEHLP_CONTEXT, *PIMAGEHLP_CONTEXT; + + +BOOL +IMAGEAPI +SymSetContext( + __in HANDLE hProcess, + __in PIMAGEHLP_STACK_FRAME StackFrame, + __in_opt PIMAGEHLP_CONTEXT Context + ); + +BOOL +IMAGEAPI +SymSetScopeFromAddr( + __in HANDLE hProcess, + __in ULONG64 Address + ); + +BOOL +IMAGEAPI +SymSetScopeFromIndex( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMPROCESSES_CALLBACK)( + __in HANDLE hProcess, + __in PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumProcesses( + __in PSYM_ENUMPROCESSES_CALLBACK EnumProcessesCallback, + __in PVOID UserContext + ); + +BOOL +IMAGEAPI +SymFromAddr( + __in HANDLE hProcess, + __in DWORD64 Address, + __out_opt PDWORD64 Displacement, + __inout PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymFromAddrW( + __in HANDLE hProcess, + __in DWORD64 Address, + __out_opt PDWORD64 Displacement, + __inout PSYMBOL_INFOW Symbol + ); + +BOOL +IMAGEAPI +SymFromToken( + __in HANDLE hProcess, + __in DWORD64 Base, + __in DWORD Token, + __inout PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymFromTokenW( + __in HANDLE hProcess, + __in DWORD64 Base, + __in DWORD Token, + __inout PSYMBOL_INFOW Symbol + ); + +BOOL +IMAGEAPI +SymNext( + __in HANDLE hProcess, + __inout PSYMBOL_INFO si + ); + +BOOL +IMAGEAPI +SymNextW( + __in HANDLE hProcess, + __inout PSYMBOL_INFOW siw + ); + +BOOL +IMAGEAPI +SymPrev( + __in HANDLE hProcess, + __inout PSYMBOL_INFO si + ); + +BOOL +IMAGEAPI +SymPrevW( + __in HANDLE hProcess, + __inout PSYMBOL_INFOW siw + ); + +// While SymFromName will provide a symbol from a name, +// SymEnumSymbols can provide the same matching information +// for ALL symbols with a matching name, even regular +// expressions. That way you can search across modules +// and differentiate between identically named symbols. + +BOOL +IMAGEAPI +SymFromName( + __in HANDLE hProcess, + __in PCSTR Name, + __inout PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymFromNameW( + __in HANDLE hProcess, + __in PCWSTR Name, + __inout PSYMBOL_INFOW Symbol + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACK)( + __in PSYMBOL_INFO pSymInfo, + __in ULONG SymbolSize, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumSymbols( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCSTR Mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACKW)( + __in PSYMBOL_INFOW pSymInfo, + __in ULONG SymbolSize, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumSymbolsW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCWSTR Mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumSymbolsForAddr( + __in HANDLE hProcess, + __in DWORD64 Address, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumSymbolsForAddrW( + __in HANDLE hProcess, + __in DWORD64 Address, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +#define SYMSEARCH_MASKOBJS 0x01 // used internally to implement other APIs +#define SYMSEARCH_RECURSE 0X02 // recurse scopes +#define SYMSEARCH_GLOBALSONLY 0X04 // search only for global symbols +#define SYMSEARCH_ALLITEMS 0X08 // search for everything in the pdb, not just normal scoped symbols + +BOOL +IMAGEAPI +SymSearch( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt DWORD Index, + __in_opt DWORD SymTag, + __in_opt PCSTR Mask, + __in_opt DWORD64 Address, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext, + __in DWORD Options + ); + +BOOL +IMAGEAPI +SymSearchW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt DWORD Index, + __in_opt DWORD SymTag, + __in_opt PCWSTR Mask, + __in_opt DWORD64 Address, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext, + __in DWORD Options + ); + +BOOL +IMAGEAPI +SymGetScope( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index, + __inout PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymGetScopeW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index, + __inout PSYMBOL_INFOW Symbol + ); + +BOOL +IMAGEAPI +SymFromIndex( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index, + __inout PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymFromIndexW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index, + __inout PSYMBOL_INFOW Symbol + ); + +typedef enum _IMAGEHLP_SYMBOL_TYPE_INFO { + TI_GET_SYMTAG, + TI_GET_SYMNAME, + TI_GET_LENGTH, + TI_GET_TYPE, + TI_GET_TYPEID, + TI_GET_BASETYPE, + TI_GET_ARRAYINDEXTYPEID, + TI_FINDCHILDREN, + TI_GET_DATAKIND, + TI_GET_ADDRESSOFFSET, + TI_GET_OFFSET, + TI_GET_VALUE, + TI_GET_COUNT, + TI_GET_CHILDRENCOUNT, + TI_GET_BITPOSITION, + TI_GET_VIRTUALBASECLASS, + TI_GET_VIRTUALTABLESHAPEID, + TI_GET_VIRTUALBASEPOINTEROFFSET, + TI_GET_CLASSPARENTID, + TI_GET_NESTED, + TI_GET_SYMINDEX, + TI_GET_LEXICALPARENT, + TI_GET_ADDRESS, + TI_GET_THISADJUST, + TI_GET_UDTKIND, + TI_IS_EQUIV_TO, + TI_GET_CALLING_CONVENTION, + TI_IS_CLOSE_EQUIV_TO, + TI_GTIEX_REQS_VALID, + TI_GET_VIRTUALBASEOFFSET, + TI_GET_VIRTUALBASEDISPINDEX, + TI_GET_IS_REFERENCE, + TI_GET_INDIRECTVIRTUALBASECLASS, + IMAGEHLP_SYMBOL_TYPE_INFO_MAX, +} IMAGEHLP_SYMBOL_TYPE_INFO; + +typedef struct _TI_FINDCHILDREN_PARAMS { + ULONG Count; + ULONG Start; + ULONG ChildId[1]; +} TI_FINDCHILDREN_PARAMS; + +BOOL +IMAGEAPI +SymGetTypeInfo( + __in HANDLE hProcess, + __in DWORD64 ModBase, + __in ULONG TypeId, + __in IMAGEHLP_SYMBOL_TYPE_INFO GetType, + __out PVOID pInfo + ); + +#define IMAGEHLP_GET_TYPE_INFO_UNCACHED 0x00000001 +#define IMAGEHLP_GET_TYPE_INFO_CHILDREN 0x00000002 + +typedef struct _IMAGEHLP_GET_TYPE_INFO_PARAMS { + IN ULONG SizeOfStruct; + IN ULONG Flags; + IN ULONG NumIds; + IN PULONG TypeIds; + IN ULONG64 TagFilter; + IN ULONG NumReqs; + IN IMAGEHLP_SYMBOL_TYPE_INFO* ReqKinds; + IN PULONG_PTR ReqOffsets; + IN PULONG ReqSizes; + IN ULONG_PTR ReqStride; + IN ULONG_PTR BufferSize; + OUT PVOID Buffer; + OUT ULONG EntriesMatched; + OUT ULONG EntriesFilled; + OUT ULONG64 TagsFound; + OUT ULONG64 AllReqsValid; + IN ULONG NumReqsValid; + OUT PULONG64 ReqsValid OPTIONAL; +} IMAGEHLP_GET_TYPE_INFO_PARAMS, *PIMAGEHLP_GET_TYPE_INFO_PARAMS; + +BOOL +IMAGEAPI +SymGetTypeInfoEx( + __in HANDLE hProcess, + __in DWORD64 ModBase, + __inout PIMAGEHLP_GET_TYPE_INFO_PARAMS Params + ); + +BOOL +IMAGEAPI +SymEnumTypes( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumTypesW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumTypesByName( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCSTR mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumTypesByNameW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCWSTR mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymGetTypeFromName( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PCSTR Name, + __inout PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymGetTypeFromNameW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PCWSTR Name, + __inout PSYMBOL_INFOW Symbol + ); + +BOOL +IMAGEAPI +SymAddSymbol( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PCSTR Name, + __in DWORD64 Address, + __in DWORD Size, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymAddSymbolW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PCWSTR Name, + __in DWORD64 Address, + __in DWORD Size, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymDeleteSymbol( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCSTR Name, + __in DWORD64 Address, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymDeleteSymbolW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCWSTR Name, + __in DWORD64 Address, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymRefreshModuleList( + __in HANDLE hProcess + ); + +BOOL +IMAGEAPI +SymAddSourceStream( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR StreamFile, + __in_bcount_opt(Size) PBYTE Buffer, + __in size_t Size + ); + +typedef BOOL (WINAPI *SYMADDSOURCESTREAM)(HANDLE, ULONG64, PCSTR, PBYTE, size_t); + +BOOL +IMAGEAPI +SymAddSourceStreamA( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR StreamFile, + __in_bcount_opt(Size) PBYTE Buffer, + __in size_t Size + ); + +typedef BOOL (WINAPI *SYMADDSOURCESTREAMA)(HANDLE, ULONG64, PCSTR, PBYTE, size_t); + +BOOL +IMAGEAPI +SymAddSourceStreamW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCWSTR FileSpec, + __in_bcount_opt(Size) PBYTE Buffer, + __in size_t Size + ); + +BOOL +IMAGEAPI +SymSrvIsStoreW( + __in_opt HANDLE hProcess, + __in PCWSTR path + ); + +BOOL +IMAGEAPI +SymSrvIsStore( + __in_opt HANDLE hProcess, + __in PCSTR path + ); + +PCSTR +IMAGEAPI +SymSrvDeltaName( + __in HANDLE hProcess, + __in_opt PCSTR SymPath, + __in PCSTR Type, + __in PCSTR File1, + __in PCSTR File2 + ); + +PCWSTR +IMAGEAPI +SymSrvDeltaNameW( + __in HANDLE hProcess, + __in_opt PCWSTR SymPath, + __in PCWSTR Type, + __in PCWSTR File1, + __in PCWSTR File2 + ); + +PCSTR +IMAGEAPI +SymSrvGetSupplement( + __in HANDLE hProcess, + __in_opt PCSTR SymPath, + __in PCSTR Node, + __in PCSTR File + ); + +PCWSTR +IMAGEAPI +SymSrvGetSupplementW( + __in HANDLE hProcess, + __in_opt PCWSTR SymPath, + __in PCWSTR Node, + __in PCWSTR File + ); + +BOOL +IMAGEAPI +SymSrvGetFileIndexes( + __in PCSTR File, + __out GUID *Id, + __out PDWORD Val1, + __out_opt PDWORD Val2, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymSrvGetFileIndexesW( + __in PCWSTR File, + __out GUID *Id, + __out PDWORD Val1, + __out_opt PDWORD Val2, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymSrvGetFileIndexStringW( + __in HANDLE hProcess, + __in_opt PCWSTR SrvPath, + __in PCWSTR File, + __out_ecount(Size) PWSTR Index, + __in size_t Size, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymSrvGetFileIndexString( + __in HANDLE hProcess, + __in_opt PCSTR SrvPath, + __in PCSTR File, + __out_ecount(Size) PSTR Index, + __in size_t Size, + __in DWORD Flags + ); + +typedef struct { + DWORD sizeofstruct; + char file[MAX_PATH +1]; + BOOL stripped; + DWORD timestamp; + DWORD size; + char dbgfile[MAX_PATH +1]; + char pdbfile[MAX_PATH + 1]; + GUID guid; + DWORD sig; + DWORD age; +} SYMSRV_INDEX_INFO, *PSYMSRV_INDEX_INFO; + +typedef struct { + DWORD sizeofstruct; + WCHAR file[MAX_PATH +1]; + BOOL stripped; + DWORD timestamp; + DWORD size; + WCHAR dbgfile[MAX_PATH +1]; + WCHAR pdbfile[MAX_PATH + 1]; + GUID guid; + DWORD sig; + DWORD age; +} SYMSRV_INDEX_INFOW, *PSYMSRV_INDEX_INFOW; + +BOOL +IMAGEAPI +SymSrvGetFileIndexInfo( + __in PCSTR File, + __out PSYMSRV_INDEX_INFO Info, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymSrvGetFileIndexInfoW( + __in PCWSTR File, + __out PSYMSRV_INDEX_INFOW Info, + __in DWORD Flags + ); + +PCSTR +IMAGEAPI +SymSrvStoreSupplement( + __in HANDLE hProcess, + __in_opt PCSTR SrvPath, + __in PCSTR Node, + __in PCSTR File, + __in DWORD Flags + ); + +PCWSTR +IMAGEAPI +SymSrvStoreSupplementW( + __in HANDLE hProcess, + __in_opt PCWSTR SymPath, + __in PCWSTR Node, + __in PCWSTR File, + __in DWORD Flags + ); + +PCSTR +IMAGEAPI +SymSrvStoreFile( + __in HANDLE hProcess, + __in_opt PCSTR SrvPath, + __in PCSTR File, + __in DWORD Flags + ); + +PCWSTR +IMAGEAPI +SymSrvStoreFileW( + __in HANDLE hProcess, + __in_opt PCWSTR SrvPath, + __in PCWSTR File, + __in DWORD Flags + ); + +// used by SymGetSymbolFile's "Type" parameter + +enum { + sfImage = 0, + sfDbg, + sfPdb, + sfMpd, + sfMax +}; + +BOOL +IMAGEAPI +SymGetSymbolFile( + __in_opt HANDLE hProcess, + __in_opt PCSTR SymPath, + __in PCSTR ImageFile, + __in DWORD Type, + __out_ecount(cSymbolFile) PSTR SymbolFile, + __in size_t cSymbolFile, + __out_ecount(cDbgFile) PSTR DbgFile, + __in size_t cDbgFile + ); + +BOOL +IMAGEAPI +SymGetSymbolFileW( + __in_opt HANDLE hProcess, + __in_opt PCWSTR SymPath, + __in PCWSTR ImageFile, + __in DWORD Type, + __out_ecount(cSymbolFile) PWSTR SymbolFile, + __in size_t cSymbolFile, + __out_ecount(cDbgFile) PWSTR DbgFile, + __in size_t cDbgFile + ); + +// +// Full user-mode dump creation. +// + +typedef BOOL (WINAPI *PDBGHELP_CREATE_USER_DUMP_CALLBACK)( + __in DWORD DataType, + __in PVOID* Data, + __out LPDWORD DataLength, + __in_opt PVOID UserData + ); + +BOOL +WINAPI +DbgHelpCreateUserDump( + __in_opt LPCSTR FileName, + __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback, + __in_opt PVOID UserData + ); + +BOOL +WINAPI +DbgHelpCreateUserDumpW( + __in_opt LPCWSTR FileName, + __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback, + __in_opt PVOID UserData + ); + +// ----------------------------------------------------------------- +// The following 4 legacy APIs are fully supported, but newer +// ones are recommended. SymFromName and SymFromAddr provide +// much more detailed info on the returned symbol. + +BOOL +IMAGEAPI +SymGetSymFromAddr64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out_opt PDWORD64 pdwDisplacement, + __inout PIMAGEHLP_SYMBOL64 Symbol + ); + + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetSymFromAddr SymGetSymFromAddr64 +#else +BOOL +IMAGEAPI +SymGetSymFromAddr( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out_opt PDWORD pdwDisplacement, + __inout PIMAGEHLP_SYMBOL Symbol + ); +#endif + +// While following two APIs will provide a symbol from a name, +// SymEnumSymbols can provide the same matching information +// for ALL symbols with a matching name, even regular +// expressions. That way you can search across modules +// and differentiate between identically named symbols. + +BOOL +IMAGEAPI +SymGetSymFromName64( + __in HANDLE hProcess, + __in PCSTR Name, + __inout PIMAGEHLP_SYMBOL64 Symbol + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetSymFromName SymGetSymFromName64 +#else +BOOL +IMAGEAPI +SymGetSymFromName( + __in HANDLE hProcess, + __in PCSTR Name, + __inout PIMAGEHLP_SYMBOL Symbol + ); +#endif + + +// Symbol server exports + +typedef BOOL (WINAPI *PSYMBOLSERVERPROC)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERPROCA)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERPROCW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROC)(PCSTR, PCSTR, PCSTR, PSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROCA)(PCSTR, PCSTR, PCSTR, PSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROCW)(PCWSTR, PCWSTR, PCWSTR, PWSTR); +typedef BOOL (WINAPI *PSYMBOLSERVEROPENPROC)(VOID); +typedef BOOL (WINAPI *PSYMBOLSERVERCLOSEPROC)(VOID); +typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSPROC)(UINT_PTR, ULONG64); +typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSWPROC)(UINT_PTR, ULONG64); +typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERCALLBACKPROC)(UINT_PTR action, ULONG64 data, ULONG64 context); +typedef UINT_PTR (WINAPI *PSYMBOLSERVERGETOPTIONSPROC)(); +typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROC)(PCSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCA)(PCSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCW)(PCWSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERGETVERSION)(LPAPI_VERSION); +typedef BOOL (WINAPI *PSYMBOLSERVERDELTANAME)(PCSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PSTR, size_t); +typedef BOOL (WINAPI *PSYMBOLSERVERDELTANAMEW)(PCWSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PWSTR, size_t); +typedef BOOL (WINAPI *PSYMBOLSERVERGETSUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t); +typedef BOOL (WINAPI *PSYMBOLSERVERGETSUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t); +typedef BOOL (WINAPI *PSYMBOLSERVERSTORESUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t, DWORD); +typedef BOOL (WINAPI *PSYMBOLSERVERSTORESUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t, DWORD); +typedef BOOL (WINAPI *PSYMBOLSERVERGETINDEXSTRING)(PVOID, DWORD, DWORD, PSTR, size_t); +typedef BOOL (WINAPI *PSYMBOLSERVERGETINDEXSTRINGW)(PVOID, DWORD, DWORD, PWSTR, size_t); +typedef BOOL (WINAPI *PSYMBOLSERVERSTOREFILE)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR, size_t, DWORD); +typedef BOOL (WINAPI *PSYMBOLSERVERSTOREFILEW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR, size_t, DWORD); +typedef BOOL (WINAPI *PSYMBOLSERVERISSTORE)(PCSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERISSTOREW)(PCWSTR); +typedef DWORD (WINAPI *PSYMBOLSERVERVERSION)(); +typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERMESSAGEPROC)(UINT_PTR action, ULONG64 data, ULONG64 context); + +#define SYMSRV_VERSION 2 + +#define SSRVOPT_CALLBACK 0x00000001 +#define SSRVOPT_DWORD 0x00000002 +#define SSRVOPT_DWORDPTR 0x00000004 +#define SSRVOPT_GUIDPTR 0x00000008 +#define SSRVOPT_OLDGUIDPTR 0x00000010 +#define SSRVOPT_UNATTENDED 0x00000020 +#define SSRVOPT_NOCOPY 0x00000040 +#define SSRVOPT_GETPATH 0x00000040 +#define SSRVOPT_PARENTWIN 0x00000080 +#define SSRVOPT_PARAMTYPE 0x00000100 +#define SSRVOPT_SECURE 0x00000200 +#define SSRVOPT_TRACE 0x00000400 +#define SSRVOPT_SETCONTEXT 0x00000800 +#define SSRVOPT_PROXY 0x00001000 +#define SSRVOPT_DOWNSTREAM_STORE 0x00002000 +#define SSRVOPT_OVERWRITE 0x00004000 +#define SSRVOPT_RESETTOU 0x00008000 +#define SSRVOPT_CALLBACKW 0x00010000 +#define SSRVOPT_FLAT_DEFAULT_STORE 0x00020000 +#define SSRVOPT_PROXYW 0x00040000 +#define SSRVOPT_MESSAGE 0x00080000 +#define SSRVOPT_SERVICE 0x00100000 // deprecated +#define SSRVOPT_FAVOR_COMPRESSED 0x00200000 +#define SSRVOPT_STRING 0x00400000 +#define SSRVOPT_WINHTTP 0x00800000 +#define SSRVOPT_WININET 0x01000000 + +#define SSRVOPT_MAX 0x0100000 + +#define SSRVOPT_RESET ((ULONG_PTR)-1) + + +#define NUM_SSRVOPTS 30 + +#define SSRVACTION_TRACE 1 +#define SSRVACTION_QUERYCANCEL 2 +#define SSRVACTION_EVENT 3 +#define SSRVACTION_EVENTW 4 +#define SSRVACTION_SIZE 5 + +#define SYMSTOREOPT_COMPRESS 0x01 +#define SYMSTOREOPT_OVERWRITE 0x02 +#define SYMSTOREOPT_RETURNINDEX 0x04 +#define SYMSTOREOPT_POINTER 0x08 +#define SYMSTOREOPT_ALT_INDEX 0x10 +#define SYMSTOREOPT_UNICODE 0x20 +#define SYMSTOREOPT_PASS_IF_EXISTS 0x40 + +#ifdef DBGHELP_TRANSLATE_TCHAR + #define SymInitialize SymInitializeW + #define SymAddSymbol SymAddSymbolW + #define SymDeleteSymbol SymDeleteSymbolW + #define SearchTreeForFile SearchTreeForFileW + #define UnDecorateSymbolName UnDecorateSymbolNameW + #define SymGetLineFromName64 SymGetLineFromNameW64 + #define SymGetLineFromAddr64 SymGetLineFromAddrW64 + #define SymGetLineNext64 SymGetLineNextW64 + #define SymGetLinePrev64 SymGetLinePrevW64 + #define SymFromName SymFromNameW + #define SymFindExecutableImage SymFindExecutableImageW + #define FindExecutableImageEx FindExecutableImageExW + #define SymSearch SymSearchW + #define SymEnumLines SymEnumLinesW + #define SymEnumSourceLines SymEnumSourceLinesW + #define SymGetTypeFromName SymGetTypeFromNameW + #define SymEnumSymbolsForAddr SymEnumSymbolsForAddrW + #define SymFromAddr SymFromAddrW + #define SymMatchString SymMatchStringW + #define SymEnumSourceFiles SymEnumSourceFilesW + #define SymEnumSymbols SymEnumSymbolsW + #define SymLoadModuleEx SymLoadModuleExW + #define SymSetSearchPath SymSetSearchPathW + #define SymGetSearchPath SymGetSearchPathW + #define EnumDirTree EnumDirTreeW + #define SymFromToken SymFromTokenW + #define SymFromIndex SymFromIndexW + #define SymGetScope SymGetScopeW + #define SymNext SymNextW + #define SymPrev SymPrevW + #define SymEnumTypes SymEnumTypesW + #define SymEnumTypesByName SymEnumTypesByNameW + #define SymRegisterCallback64 SymRegisterCallbackW64 + #define SymFindDebugInfoFile SymFindDebugInfoFileW + #define FindDebugInfoFileEx FindDebugInfoFileExW + #define SymFindFileInPath SymFindFileInPathW + #define SymEnumerateModules64 SymEnumerateModulesW64 + #define SymSetHomeDirectory SymSetHomeDirectoryW + #define SymGetHomeDirectory SymGetHomeDirectoryW + #define SymGetSourceFile SymGetSourceFileW + #define SymGetSourceFileToken SymGetSourceFileTokenW + #define SymGetSourceFileFromToken SymGetSourceFileFromTokenW + #define SymGetSourceVarFromToken SymGetSourceVarFromTokenW + #define SymGetSourceFileToken SymGetSourceFileTokenW + #define SymGetFileLineOffsets64 SymGetFileLineOffsetsW64 + #define SymFindFileInPath SymFindFileInPathW + #define SymMatchFileName SymMatchFileNameW + #define SymGetSourceFileFromToken SymGetSourceFileFromTokenW + #define SymGetSourceVarFromToken SymGetSourceVarFromTokenW + #define SymGetModuleInfo64 SymGetModuleInfoW64 + #define SymSrvIsStore SymSrvIsStoreW + #define SymSrvDeltaName SymSrvDeltaNameW + #define SymSrvGetSupplement SymSrvGetSupplementW + #define SymSrvStoreSupplement SymSrvStoreSupplementW + #define SymSrvGetFileIndexes SymSrvGetFileIndexes + #define SymSrvGetFileIndexString SymSrvGetFileIndexStringW + #define SymSrvStoreFile SymSrvStoreFileW + #define SymGetSymbolFile SymGetSymbolFileW + #define EnumerateLoadedModules64 EnumerateLoadedModulesW64 + #define EnumerateLoadedModulesEx EnumerateLoadedModulesExW + #define SymSrvGetFileIndexInfo SymSrvGetFileIndexInfoW + + #define IMAGEHLP_LINE64 IMAGEHLP_LINEW64 + #define PIMAGEHLP_LINE64 PIMAGEHLP_LINEW64 + #define SYMBOL_INFO SYMBOL_INFOW + #define PSYMBOL_INFO PSYMBOL_INFOW + #define SYMBOL_INFO_PACKAGE SYMBOL_INFO_PACKAGEW + #define PSYMBOL_INFO_PACKAGE PSYMBOL_INFO_PACKAGEW + #define FIND_EXE_FILE_CALLBACK FIND_EXE_FILE_CALLBACKW + #define PFIND_EXE_FILE_CALLBACK PFIND_EXE_FILE_CALLBACKW + #define SYM_ENUMERATESYMBOLS_CALLBACK SYM_ENUMERATESYMBOLS_CALLBACKW + #define PSYM_ENUMERATESYMBOLS_CALLBACK PSYM_ENUMERATESYMBOLS_CALLBACKW + #define SRCCODEINFO SRCCODEINFOW + #define PSRCCODEINFO PSRCCODEINFOW + #define SOURCEFILE SOURCEFILEW + #define PSOURCEFILE PSOURCEFILEW + #define SYM_ENUMSOURECFILES_CALLBACK SYM_ENUMSOURCEFILES_CALLBACKW + #define PSYM_ENUMSOURCEFILES_CALLBACK PSYM_ENUMSOURECFILES_CALLBACKW + #define IMAGEHLP_CBA_EVENT IMAGEHLP_CBA_EVENTW + #define PIMAGEHLP_CBA_EVENT PIMAGEHLP_CBA_EVENTW + #define PENUMDIRTREE_CALLBACK PENUMDIRTREE_CALLBACKW + #define IMAGEHLP_DEFERRED_SYMBOL_LOAD64 IMAGEHLP_DEFERRED_SYMBOL_LOADW64 + #define PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 PIMAGEHLP_DEFERRED_SYMBOL_LOADW64 + #define PFIND_DEBUG_FILE_CALLBACK PFIND_DEBUG_FILE_CALLBACKW + #define PFINDFILEINPATHCALLBACK PFINDFILEINPATHCALLBACKW + #define IMAGEHLP_MODULE64 IMAGEHLP_MODULEW64 + #define PIMAGEHLP_MODULE64 PIMAGEHLP_MODULEW64 + #define SYMSRV_INDEX_INFO SYMSRV_INDEX_INFOW + #define PSYMSRV_INDEX_INFO PSYMSRV_INDEX_INFOW + + #define PSYMBOLSERVERPROC PSYMBOLSERVERPROCW + #define PSYMBOLSERVERPINGPROC PSYMBOLSERVERPINGPROCW +#endif + +// ----------------------------------------------------------------- +// The following APIs exist only for backwards compatibility +// with a pre-release version documented in an MSDN release. + +// You should use SymFindFileInPath if you want to maintain +// future compatibility. + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +FindFileInPath( + __in HANDLE hprocess, + __in PCSTR SearchPath, + __in PCSTR FileName, + __in PVOID id, + __in DWORD two, + __in DWORD three, + __in DWORD flags, + __out_ecount(MAX_PATH + 1) PSTR FilePath + ); + +// You should use SymFindFileInPath if you want to maintain +// future compatibility. + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +FindFileInSearchPath( + __in HANDLE hprocess, + __in PCSTR SearchPath, + __in PCSTR FileName, + __in DWORD one, + __in DWORD two, + __in DWORD three, + __out_ecount(MAX_PATH + 1) PSTR FilePath + ); + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumSym( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumerateSymbols64( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumerateSymbolsW64( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMSYMBOLS_CALLBACK64W EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymEnumerateSymbols SymEnumerateSymbols64 +#define SymEnumerateSymbolsW SymEnumerateSymbolsW64 +#else +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumerateSymbols( + __in HANDLE hProcess, + __in ULONG BaseOfDll, + __in PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumerateSymbolsW( + __in HANDLE hProcess, + __in ULONG BaseOfDll, + __in PSYM_ENUMSYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext + ); +#endif + +// use SymLoadModuleEx + +DWORD64 +IMAGEAPI +SymLoadModule64( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCSTR ImageName, + __in_opt PCSTR ModuleName, + __in DWORD64 BaseOfDll, + __in DWORD SizeOfDll + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymLoadModule SymLoadModule64 +#else +DWORD +IMAGEAPI +SymLoadModule( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCSTR ImageName, + __in_opt PCSTR ModuleName, + __in DWORD BaseOfDll, + __in DWORD SizeOfDll + ); +#endif + +BOOL +IMAGEAPI +SymGetSymNext64( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOL64 Symbol + ); + +BOOL +IMAGEAPI +SymGetSymNextW64( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOLW64 Symbol + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetSymNext SymGetSymNext64 +#define SymGetSymNextW SymGetSymNextW64 +#else +BOOL +IMAGEAPI +SymGetSymNext( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOL Symbol + ); + +BOOL +IMAGEAPI +SymGetSymNextW( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOLW Symbol + ); +#endif + +BOOL +IMAGEAPI +SymGetSymPrev64( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOL64 Symbol + ); + +BOOL +IMAGEAPI +SymGetSymPrevW64( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOLW64 Symbol + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetSymPrev SymGetSymPrev64 +#define SymGetSymPrevW SymGetSymPrevW64 +#else +BOOL +IMAGEAPI +SymGetSymPrev( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOL Symbol + ); + +BOOL +IMAGEAPI +SymGetSymPrevW( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOLW Symbol + ); +#endif + + +// These values should not be used. +// They have been replaced by SYMFLAG_ values. + +#define SYMF_OMAP_GENERATED 0x00000001 +#define SYMF_OMAP_MODIFIED 0x00000002 +#define SYMF_REGISTER 0x00000008 +#define SYMF_REGREL 0x00000010 +#define SYMF_FRAMEREL 0x00000020 +#define SYMF_PARAMETER 0x00000040 +#define SYMF_LOCAL 0x00000080 +#define SYMF_CONSTANT 0x00000100 +#define SYMF_EXPORT 0x00000200 +#define SYMF_FORWARDER 0x00000400 +#define SYMF_FUNCTION 0x00000800 +#define SYMF_VIRTUAL 0x00001000 +#define SYMF_THUNK 0x00002000 +#define SYMF_TLSREL 0x00004000 + +// These values should also not be used. +// They have been replaced by SYMFLAG_ values. + +#define IMAGEHLP_SYMBOL_INFO_VALUEPRESENT 1 +#define IMAGEHLP_SYMBOL_INFO_REGISTER SYMF_REGISTER // 0x0008 +#define IMAGEHLP_SYMBOL_INFO_REGRELATIVE SYMF_REGREL // 0x0010 +#define IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE SYMF_FRAMEREL // 0x0020 +#define IMAGEHLP_SYMBOL_INFO_PARAMETER SYMF_PARAMETER // 0x0040 +#define IMAGEHLP_SYMBOL_INFO_LOCAL SYMF_LOCAL // 0x0080 +#define IMAGEHLP_SYMBOL_INFO_CONSTANT SYMF_CONSTANT // 0x0100 +#define IMAGEHLP_SYMBOL_FUNCTION SYMF_FUNCTION // 0x0800 +#define IMAGEHLP_SYMBOL_VIRTUAL SYMF_VIRTUAL // 0x1000 +#define IMAGEHLP_SYMBOL_THUNK SYMF_THUNK // 0x2000 +#define IMAGEHLP_SYMBOL_INFO_TLSRELATIVE SYMF_TLSREL // 0x4000 + + +#include + +#if defined(_MSC_VER) +#if _MSC_VER >= 800 +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning(disable:4200) /* Zero length array */ +#pragma warning(disable:4201) /* Nameless struct/union */ +#endif +#endif + +#define MINIDUMP_SIGNATURE ('PMDM') +#define MINIDUMP_VERSION (42899) +typedef DWORD RVA; +typedef ULONG64 RVA64; + +typedef struct _MINIDUMP_LOCATION_DESCRIPTOR { + ULONG32 DataSize; + RVA Rva; +} MINIDUMP_LOCATION_DESCRIPTOR; + +typedef struct _MINIDUMP_LOCATION_DESCRIPTOR64 { + ULONG64 DataSize; + RVA64 Rva; +} MINIDUMP_LOCATION_DESCRIPTOR64; + + +typedef struct _MINIDUMP_MEMORY_DESCRIPTOR { + ULONG64 StartOfMemoryRange; + MINIDUMP_LOCATION_DESCRIPTOR Memory; +} MINIDUMP_MEMORY_DESCRIPTOR, *PMINIDUMP_MEMORY_DESCRIPTOR; + +// DESCRIPTOR64 is used for full-memory minidumps where +// all of the raw memory is laid out sequentially at the +// end of the dump. There is no need for individual RVAs +// as the RVA is the base RVA plus the sum of the preceeding +// data blocks. +typedef struct _MINIDUMP_MEMORY_DESCRIPTOR64 { + ULONG64 StartOfMemoryRange; + ULONG64 DataSize; +} MINIDUMP_MEMORY_DESCRIPTOR64, *PMINIDUMP_MEMORY_DESCRIPTOR64; + + +typedef struct _MINIDUMP_HEADER { + ULONG32 Signature; + ULONG32 Version; + ULONG32 NumberOfStreams; + RVA StreamDirectoryRva; + ULONG32 CheckSum; + union { + ULONG32 Reserved; + ULONG32 TimeDateStamp; + }; + ULONG64 Flags; +} MINIDUMP_HEADER, *PMINIDUMP_HEADER; + +// +// The MINIDUMP_HEADER field StreamDirectoryRva points to +// an array of MINIDUMP_DIRECTORY structures. +// + +typedef struct _MINIDUMP_DIRECTORY { + ULONG32 StreamType; + MINIDUMP_LOCATION_DESCRIPTOR Location; +} MINIDUMP_DIRECTORY, *PMINIDUMP_DIRECTORY; + + +typedef struct _MINIDUMP_STRING { + ULONG32 Length; // Length in bytes of the string + WCHAR Buffer [0]; // Variable size buffer +} MINIDUMP_STRING, *PMINIDUMP_STRING; + + + +// +// The MINIDUMP_DIRECTORY field StreamType may be one of the following types. +// Types will be added in the future, so if a program reading the minidump +// header encounters a stream type it does not understand it should ignore +// the data altogether. Any tag above LastReservedStream will not be used by +// the system and is reserved for program-specific information. +// + +typedef enum _MINIDUMP_STREAM_TYPE { + + UnusedStream = 0, + ReservedStream0 = 1, + ReservedStream1 = 2, + ThreadListStream = 3, + ModuleListStream = 4, + MemoryListStream = 5, + ExceptionStream = 6, + SystemInfoStream = 7, + ThreadExListStream = 8, + Memory64ListStream = 9, + CommentStreamA = 10, + CommentStreamW = 11, + HandleDataStream = 12, + FunctionTableStream = 13, + UnloadedModuleListStream = 14, + MiscInfoStream = 15, + MemoryInfoListStream = 16, + ThreadInfoListStream = 17, + HandleOperationListStream = 18, + + ceStreamNull = 0x8000, + ceStreamSystemInfo = 0x8001, + ceStreamException = 0x8002, + ceStreamModuleList = 0x8003, + ceStreamProcessList = 0x8004, + ceStreamThreadList = 0x8005, + ceStreamThreadContextList = 0x8006, + ceStreamThreadCallStackList = 0x8007, + ceStreamMemoryVirtualList = 0x8008, + ceStreamMemoryPhysicalList = 0x8009, + ceStreamBucketParameters = 0x800A, + + LastReservedStream = 0xffff + +} MINIDUMP_STREAM_TYPE; + + +// +// The minidump system information contains processor and +// Operating System specific information. +// + +// +// CPU information is obtained from one of two places. +// +// 1) On x86 computers, CPU_INFORMATION is obtained from the CPUID +// instruction. You must use the X86 portion of the union for X86 +// computers. +// +// 2) On non-x86 architectures, CPU_INFORMATION is obtained by calling +// IsProcessorFeatureSupported(). +// + +typedef union _CPU_INFORMATION { + + // + // X86 platforms use CPUID function to obtain processor information. + // + + struct { + + // + // CPUID Subfunction 0, register EAX (VendorId [0]), + // EBX (VendorId [1]) and ECX (VendorId [2]). + // + + ULONG32 VendorId [ 3 ]; + + // + // CPUID Subfunction 1, register EAX + // + + ULONG32 VersionInformation; + + // + // CPUID Subfunction 1, register EDX + // + + ULONG32 FeatureInformation; + + + // + // CPUID, Subfunction 80000001, register EBX. This will only + // be obtained if the vendor id is "AuthenticAMD". + // + + ULONG32 AMDExtendedCpuFeatures; + + } X86CpuInfo; + + // + // Non-x86 platforms use processor feature flags. + // + + struct { + + ULONG64 ProcessorFeatures [ 2 ]; + + } OtherCpuInfo; + +} CPU_INFORMATION, *PCPU_INFORMATION; + +typedef struct _MINIDUMP_SYSTEM_INFO { + + // + // ProcessorArchitecture, ProcessorLevel and ProcessorRevision are all + // taken from the SYSTEM_INFO structure obtained by GetSystemInfo( ). + // + + USHORT ProcessorArchitecture; + USHORT ProcessorLevel; + USHORT ProcessorRevision; + + union { + USHORT Reserved0; + struct { + UCHAR NumberOfProcessors; + UCHAR ProductType; + }; + }; + + // + // MajorVersion, MinorVersion, BuildNumber, PlatformId and + // CSDVersion are all taken from the OSVERSIONINFO structure + // returned by GetVersionEx( ). + // + + ULONG32 MajorVersion; + ULONG32 MinorVersion; + ULONG32 BuildNumber; + ULONG32 PlatformId; + + // + // RVA to a CSDVersion string in the string table. + // + + RVA CSDVersionRva; + + union { + ULONG32 Reserved1; + struct { + USHORT SuiteMask; + USHORT Reserved2; + }; + }; + + CPU_INFORMATION Cpu; + +} MINIDUMP_SYSTEM_INFO, *PMINIDUMP_SYSTEM_INFO; + + +// +// The minidump thread contains standard thread +// information plus an RVA to the memory for this +// thread and an RVA to the CONTEXT structure for +// this thread. +// + + +// +// ThreadId must be 4 bytes on all architectures. +// + +C_ASSERT (sizeof ( ((PPROCESS_INFORMATION)0)->dwThreadId ) == 4); + +typedef struct _MINIDUMP_THREAD { + ULONG32 ThreadId; + ULONG32 SuspendCount; + ULONG32 PriorityClass; + ULONG32 Priority; + ULONG64 Teb; + MINIDUMP_MEMORY_DESCRIPTOR Stack; + MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; +} MINIDUMP_THREAD, *PMINIDUMP_THREAD; + +// +// The thread list is a container of threads. +// + +typedef struct _MINIDUMP_THREAD_LIST { + ULONG32 NumberOfThreads; + MINIDUMP_THREAD Threads [0]; +} MINIDUMP_THREAD_LIST, *PMINIDUMP_THREAD_LIST; + + +typedef struct _MINIDUMP_THREAD_EX { + ULONG32 ThreadId; + ULONG32 SuspendCount; + ULONG32 PriorityClass; + ULONG32 Priority; + ULONG64 Teb; + MINIDUMP_MEMORY_DESCRIPTOR Stack; + MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; + MINIDUMP_MEMORY_DESCRIPTOR BackingStore; +} MINIDUMP_THREAD_EX, *PMINIDUMP_THREAD_EX; + +// +// The thread list is a container of threads. +// + +typedef struct _MINIDUMP_THREAD_EX_LIST { + ULONG32 NumberOfThreads; + MINIDUMP_THREAD_EX Threads [0]; +} MINIDUMP_THREAD_EX_LIST, *PMINIDUMP_THREAD_EX_LIST; + + +// +// The MINIDUMP_EXCEPTION is the same as EXCEPTION on Win64. +// + +typedef struct _MINIDUMP_EXCEPTION { + ULONG32 ExceptionCode; + ULONG32 ExceptionFlags; + ULONG64 ExceptionRecord; + ULONG64 ExceptionAddress; + ULONG32 NumberParameters; + ULONG32 __unusedAlignment; + ULONG64 ExceptionInformation [ EXCEPTION_MAXIMUM_PARAMETERS ]; +} MINIDUMP_EXCEPTION, *PMINIDUMP_EXCEPTION; + + +// +// The exception information stream contains the id of the thread that caused +// the exception (ThreadId), the exception record for the exception +// (ExceptionRecord) and an RVA to the thread context where the exception +// occured. +// + +typedef struct MINIDUMP_EXCEPTION_STREAM { + ULONG32 ThreadId; + ULONG32 __alignment; + MINIDUMP_EXCEPTION ExceptionRecord; + MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; +} MINIDUMP_EXCEPTION_STREAM, *PMINIDUMP_EXCEPTION_STREAM; + + +// +// The MINIDUMP_MODULE contains information about a +// a specific module. It includes the CheckSum and +// the TimeDateStamp for the module so the module +// can be reloaded during the analysis phase. +// + +typedef struct _MINIDUMP_MODULE { + ULONG64 BaseOfImage; + ULONG32 SizeOfImage; + ULONG32 CheckSum; + ULONG32 TimeDateStamp; + RVA ModuleNameRva; + VS_FIXEDFILEINFO VersionInfo; + MINIDUMP_LOCATION_DESCRIPTOR CvRecord; + MINIDUMP_LOCATION_DESCRIPTOR MiscRecord; + ULONG64 Reserved0; // Reserved for future use. + ULONG64 Reserved1; // Reserved for future use. +} MINIDUMP_MODULE, *PMINIDUMP_MODULE; + + +// +// The minidump module list is a container for modules. +// + +typedef struct _MINIDUMP_MODULE_LIST { + ULONG32 NumberOfModules; + MINIDUMP_MODULE Modules [ 0 ]; +} MINIDUMP_MODULE_LIST, *PMINIDUMP_MODULE_LIST; + + +// +// Memory Ranges +// + +typedef struct _MINIDUMP_MEMORY_LIST { + ULONG32 NumberOfMemoryRanges; + MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges [0]; +} MINIDUMP_MEMORY_LIST, *PMINIDUMP_MEMORY_LIST; + +typedef struct _MINIDUMP_MEMORY64_LIST { + ULONG64 NumberOfMemoryRanges; + RVA64 BaseRva; + MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges [0]; +} MINIDUMP_MEMORY64_LIST, *PMINIDUMP_MEMORY64_LIST; + + +// +// Support for user supplied exception information. +// + +typedef struct _MINIDUMP_EXCEPTION_INFORMATION { + DWORD ThreadId; + PEXCEPTION_POINTERS ExceptionPointers; + BOOL ClientPointers; +} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; + +typedef struct _MINIDUMP_EXCEPTION_INFORMATION64 { + DWORD ThreadId; + ULONG64 ExceptionRecord; + ULONG64 ContextRecord; + BOOL ClientPointers; +} MINIDUMP_EXCEPTION_INFORMATION64, *PMINIDUMP_EXCEPTION_INFORMATION64; + + +// +// Support for capturing system handle state at the time of the dump. +// + +// Per-handle object information varies according to +// the OS, the OS version, the processor type and +// so on. The minidump gives a minidump identifier +// to each possible data format for identification +// purposes but does not control nor describe the actual data. +typedef enum _MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE { + MiniHandleObjectInformationNone, + MiniThreadInformation1, + MiniMutantInformation1, + MiniMutantInformation2, + MiniProcessInformation1, + MiniProcessInformation2, + MiniHandleObjectInformationTypeMax +} MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE; + +typedef struct _MINIDUMP_HANDLE_OBJECT_INFORMATION { + RVA NextInfoRva; + ULONG32 InfoType; + ULONG32 SizeOfInfo; + // Raw information follows. +} MINIDUMP_HANDLE_OBJECT_INFORMATION; + +typedef struct _MINIDUMP_HANDLE_DESCRIPTOR { + ULONG64 Handle; + RVA TypeNameRva; + RVA ObjectNameRva; + ULONG32 Attributes; + ULONG32 GrantedAccess; + ULONG32 HandleCount; + ULONG32 PointerCount; +} MINIDUMP_HANDLE_DESCRIPTOR, *PMINIDUMP_HANDLE_DESCRIPTOR; + +typedef struct _MINIDUMP_HANDLE_DESCRIPTOR_2 { + ULONG64 Handle; + RVA TypeNameRva; + RVA ObjectNameRva; + ULONG32 Attributes; + ULONG32 GrantedAccess; + ULONG32 HandleCount; + ULONG32 PointerCount; + RVA ObjectInfoRva; + ULONG32 Reserved0; +} MINIDUMP_HANDLE_DESCRIPTOR_2, *PMINIDUMP_HANDLE_DESCRIPTOR_2; + +// The latest MINIDUMP_HANDLE_DESCRIPTOR definition. +typedef MINIDUMP_HANDLE_DESCRIPTOR_2 MINIDUMP_HANDLE_DESCRIPTOR_N; +typedef MINIDUMP_HANDLE_DESCRIPTOR_N *PMINIDUMP_HANDLE_DESCRIPTOR_N; + +typedef struct _MINIDUMP_HANDLE_DATA_STREAM { + ULONG32 SizeOfHeader; + ULONG32 SizeOfDescriptor; + ULONG32 NumberOfDescriptors; + ULONG32 Reserved; +} MINIDUMP_HANDLE_DATA_STREAM, *PMINIDUMP_HANDLE_DATA_STREAM; + +// Some operating systems can track the last operations +// performed on a handle. For example, Application Verifier +// can enable this for some versions of Windows. The +// handle operation list collects handle operations +// known for the dump target. +// Each entry is an AVRF_HANDLE_OPERATION. +typedef struct _MINIDUMP_HANDLE_OPERATION_LIST { + ULONG32 SizeOfHeader; + ULONG32 SizeOfEntry; + ULONG32 NumberOfEntries; + ULONG32 Reserved; +} MINIDUMP_HANDLE_OPERATION_LIST, *PMINIDUMP_HANDLE_OPERATION_LIST; + + +// +// Support for capturing dynamic function table state at the time of the dump. +// + +typedef struct _MINIDUMP_FUNCTION_TABLE_DESCRIPTOR { + ULONG64 MinimumAddress; + ULONG64 MaximumAddress; + ULONG64 BaseAddress; + ULONG32 EntryCount; + ULONG32 SizeOfAlignPad; +} MINIDUMP_FUNCTION_TABLE_DESCRIPTOR, *PMINIDUMP_FUNCTION_TABLE_DESCRIPTOR; + +typedef struct _MINIDUMP_FUNCTION_TABLE_STREAM { + ULONG32 SizeOfHeader; + ULONG32 SizeOfDescriptor; + ULONG32 SizeOfNativeDescriptor; + ULONG32 SizeOfFunctionEntry; + ULONG32 NumberOfDescriptors; + ULONG32 SizeOfAlignPad; +} MINIDUMP_FUNCTION_TABLE_STREAM, *PMINIDUMP_FUNCTION_TABLE_STREAM; + + +// +// The MINIDUMP_UNLOADED_MODULE contains information about a +// a specific module that was previously loaded but no +// longer is. This can help with diagnosing problems where +// callers attempt to call code that is no longer loaded. +// + +typedef struct _MINIDUMP_UNLOADED_MODULE { + ULONG64 BaseOfImage; + ULONG32 SizeOfImage; + ULONG32 CheckSum; + ULONG32 TimeDateStamp; + RVA ModuleNameRva; +} MINIDUMP_UNLOADED_MODULE, *PMINIDUMP_UNLOADED_MODULE; + + +// +// The minidump unloaded module list is a container for unloaded modules. +// + +typedef struct _MINIDUMP_UNLOADED_MODULE_LIST { + ULONG32 SizeOfHeader; + ULONG32 SizeOfEntry; + ULONG32 NumberOfEntries; +} MINIDUMP_UNLOADED_MODULE_LIST, *PMINIDUMP_UNLOADED_MODULE_LIST; + + +// +// The miscellaneous information stream contains a variety +// of small pieces of information. A member is valid if +// it's within the available size and its corresponding +// bit is set. +// + +#define MINIDUMP_MISC1_PROCESS_ID 0x00000001 +#define MINIDUMP_MISC1_PROCESS_TIMES 0x00000002 +#define MINIDUMP_MISC1_PROCESSOR_POWER_INFO 0x00000004 + +typedef struct _MINIDUMP_MISC_INFO { + ULONG32 SizeOfInfo; + ULONG32 Flags1; + ULONG32 ProcessId; + ULONG32 ProcessCreateTime; + ULONG32 ProcessUserTime; + ULONG32 ProcessKernelTime; +} MINIDUMP_MISC_INFO, *PMINIDUMP_MISC_INFO; + +typedef struct _MINIDUMP_MISC_INFO_2 { + ULONG32 SizeOfInfo; + ULONG32 Flags1; + ULONG32 ProcessId; + ULONG32 ProcessCreateTime; + ULONG32 ProcessUserTime; + ULONG32 ProcessKernelTime; + ULONG32 ProcessorMaxMhz; + ULONG32 ProcessorCurrentMhz; + ULONG32 ProcessorMhzLimit; + ULONG32 ProcessorMaxIdleState; + ULONG32 ProcessorCurrentIdleState; +} MINIDUMP_MISC_INFO_2, *PMINIDUMP_MISC_INFO_2; + +// The latest MINIDUMP_MISC_INFO definition. +typedef MINIDUMP_MISC_INFO_2 MINIDUMP_MISC_INFO_N; +typedef MINIDUMP_MISC_INFO_N* PMINIDUMP_MISC_INFO_N; + + +// +// The memory information stream contains memory region +// description information. This stream corresponds to +// what VirtualQuery would return for the process the +// dump was created for. +// + +typedef struct _MINIDUMP_MEMORY_INFO { + ULONG64 BaseAddress; + ULONG64 AllocationBase; + ULONG32 AllocationProtect; + ULONG32 __alignment1; + ULONG64 RegionSize; + ULONG32 State; + ULONG32 Protect; + ULONG32 Type; + ULONG32 __alignment2; +} MINIDUMP_MEMORY_INFO, *PMINIDUMP_MEMORY_INFO; + +typedef struct _MINIDUMP_MEMORY_INFO_LIST { + ULONG SizeOfHeader; + ULONG SizeOfEntry; + ULONG64 NumberOfEntries; +} MINIDUMP_MEMORY_INFO_LIST, *PMINIDUMP_MEMORY_INFO_LIST; + + +// +// The memory information stream contains memory region +// description information. This stream corresponds to +// what VirtualQuery would return for the process the +// dump was created for. +// + +// Thread dump writer status flags. +#define MINIDUMP_THREAD_INFO_ERROR_THREAD 0x00000001 +#define MINIDUMP_THREAD_INFO_WRITING_THREAD 0x00000002 +#define MINIDUMP_THREAD_INFO_EXITED_THREAD 0x00000004 +#define MINIDUMP_THREAD_INFO_INVALID_INFO 0x00000008 +#define MINIDUMP_THREAD_INFO_INVALID_CONTEXT 0x00000010 +#define MINIDUMP_THREAD_INFO_INVALID_TEB 0x00000020 + +typedef struct _MINIDUMP_THREAD_INFO { + ULONG32 ThreadId; + ULONG32 DumpFlags; + ULONG32 DumpError; + ULONG32 ExitStatus; + ULONG64 CreateTime; + ULONG64 ExitTime; + ULONG64 KernelTime; + ULONG64 UserTime; + ULONG64 StartAddress; + ULONG64 Affinity; +} MINIDUMP_THREAD_INFO, *PMINIDUMP_THREAD_INFO; + +typedef struct _MINIDUMP_THREAD_INFO_LIST { + ULONG SizeOfHeader; + ULONG SizeOfEntry; + ULONG NumberOfEntries; +} MINIDUMP_THREAD_INFO_LIST, *PMINIDUMP_THREAD_INFO_LIST; + + +// +// Support for arbitrary user-defined information. +// + +typedef struct _MINIDUMP_USER_RECORD { + ULONG32 Type; + MINIDUMP_LOCATION_DESCRIPTOR Memory; +} MINIDUMP_USER_RECORD, *PMINIDUMP_USER_RECORD; + + +typedef struct _MINIDUMP_USER_STREAM { + ULONG32 Type; + ULONG BufferSize; + PVOID Buffer; + +} MINIDUMP_USER_STREAM, *PMINIDUMP_USER_STREAM; + + +typedef struct _MINIDUMP_USER_STREAM_INFORMATION { + ULONG UserStreamCount; + PMINIDUMP_USER_STREAM UserStreamArray; +} MINIDUMP_USER_STREAM_INFORMATION, *PMINIDUMP_USER_STREAM_INFORMATION; + +// +// Callback support. +// + +typedef enum _MINIDUMP_CALLBACK_TYPE { + ModuleCallback, + ThreadCallback, + ThreadExCallback, + IncludeThreadCallback, + IncludeModuleCallback, + MemoryCallback, + CancelCallback, + WriteKernelMinidumpCallback, + KernelMinidumpStatusCallback, + RemoveMemoryCallback, + IncludeVmRegionCallback, + IoStartCallback, + IoWriteAllCallback, + IoFinishCallback, + ReadMemoryFailureCallback, + SecondaryFlagsCallback, +} MINIDUMP_CALLBACK_TYPE; + + +typedef struct _MINIDUMP_THREAD_CALLBACK { + ULONG ThreadId; + HANDLE ThreadHandle; + CONTEXT Context; + ULONG SizeOfContext; + ULONG64 StackBase; + ULONG64 StackEnd; +} MINIDUMP_THREAD_CALLBACK, *PMINIDUMP_THREAD_CALLBACK; + + +typedef struct _MINIDUMP_THREAD_EX_CALLBACK { + ULONG ThreadId; + HANDLE ThreadHandle; + CONTEXT Context; + ULONG SizeOfContext; + ULONG64 StackBase; + ULONG64 StackEnd; + ULONG64 BackingStoreBase; + ULONG64 BackingStoreEnd; +} MINIDUMP_THREAD_EX_CALLBACK, *PMINIDUMP_THREAD_EX_CALLBACK; + + +typedef struct _MINIDUMP_INCLUDE_THREAD_CALLBACK { + ULONG ThreadId; +} MINIDUMP_INCLUDE_THREAD_CALLBACK, *PMINIDUMP_INCLUDE_THREAD_CALLBACK; + + +typedef enum _THREAD_WRITE_FLAGS { + ThreadWriteThread = 0x0001, + ThreadWriteStack = 0x0002, + ThreadWriteContext = 0x0004, + ThreadWriteBackingStore = 0x0008, + ThreadWriteInstructionWindow = 0x0010, + ThreadWriteThreadData = 0x0020, + ThreadWriteThreadInfo = 0x0040, +} THREAD_WRITE_FLAGS; + +typedef struct _MINIDUMP_MODULE_CALLBACK { + PWCHAR FullPath; + ULONG64 BaseOfImage; + ULONG SizeOfImage; + ULONG CheckSum; + ULONG TimeDateStamp; + VS_FIXEDFILEINFO VersionInfo; + PVOID CvRecord; + ULONG SizeOfCvRecord; + PVOID MiscRecord; + ULONG SizeOfMiscRecord; +} MINIDUMP_MODULE_CALLBACK, *PMINIDUMP_MODULE_CALLBACK; + + +typedef struct _MINIDUMP_INCLUDE_MODULE_CALLBACK { + ULONG64 BaseOfImage; +} MINIDUMP_INCLUDE_MODULE_CALLBACK, *PMINIDUMP_INCLUDE_MODULE_CALLBACK; + + +typedef enum _MODULE_WRITE_FLAGS { + ModuleWriteModule = 0x0001, + ModuleWriteDataSeg = 0x0002, + ModuleWriteMiscRecord = 0x0004, + ModuleWriteCvRecord = 0x0008, + ModuleReferencedByMemory = 0x0010, + ModuleWriteTlsData = 0x0020, + ModuleWriteCodeSegs = 0x0040, +} MODULE_WRITE_FLAGS; + + +typedef struct _MINIDUMP_IO_CALLBACK { + HANDLE Handle; + ULONG64 Offset; + PVOID Buffer; + ULONG BufferBytes; +} MINIDUMP_IO_CALLBACK, *PMINIDUMP_IO_CALLBACK; + + +typedef struct _MINIDUMP_READ_MEMORY_FAILURE_CALLBACK +{ + ULONG64 Offset; + ULONG Bytes; + HRESULT FailureStatus; +} MINIDUMP_READ_MEMORY_FAILURE_CALLBACK, + *PMINIDUMP_READ_MEMORY_FAILURE_CALLBACK; + + +typedef struct _MINIDUMP_CALLBACK_INPUT { + ULONG ProcessId; + HANDLE ProcessHandle; + ULONG CallbackType; + union { + HRESULT Status; + MINIDUMP_THREAD_CALLBACK Thread; + MINIDUMP_THREAD_EX_CALLBACK ThreadEx; + MINIDUMP_MODULE_CALLBACK Module; + MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread; + MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule; + MINIDUMP_IO_CALLBACK Io; + MINIDUMP_READ_MEMORY_FAILURE_CALLBACK ReadMemoryFailure; + ULONG SecondaryFlags; + }; +} MINIDUMP_CALLBACK_INPUT, *PMINIDUMP_CALLBACK_INPUT; + +typedef struct _MINIDUMP_CALLBACK_OUTPUT { + union { + ULONG ModuleWriteFlags; + ULONG ThreadWriteFlags; + ULONG SecondaryFlags; + struct { + ULONG64 MemoryBase; + ULONG MemorySize; + }; + struct { + BOOL CheckCancel; + BOOL Cancel; + }; + HANDLE Handle; + struct { + MINIDUMP_MEMORY_INFO VmRegion; + BOOL Continue; + }; + HRESULT Status; + }; +} MINIDUMP_CALLBACK_OUTPUT, *PMINIDUMP_CALLBACK_OUTPUT; + + +// +// A normal minidump contains just the information +// necessary to capture stack traces for all of the +// existing threads in a process. +// +// A minidump with data segments includes all of the data +// sections from loaded modules in order to capture +// global variable contents. This can make the dump much +// larger if many modules have global data. +// +// A minidump with full memory includes all of the accessible +// memory in the process and can be very large. A minidump +// with full memory always has the raw memory data at the end +// of the dump so that the initial structures in the dump can +// be mapped directly without having to include the raw +// memory information. +// +// Stack and backing store memory can be filtered to remove +// data unnecessary for stack walking. This can improve +// compression of stacks and also deletes data that may +// be private and should not be stored in a dump. +// Memory can also be scanned to see what modules are +// referenced by stack and backing store memory to allow +// omission of other modules to reduce dump size. +// In either of these modes the ModuleReferencedByMemory flag +// is set for all modules referenced before the base +// module callbacks occur. +// +// On some operating systems a list of modules that were +// recently unloaded is kept in addition to the currently +// loaded module list. This information can be saved in +// the dump if desired. +// +// Stack and backing store memory can be scanned for referenced +// pages in order to pick up data referenced by locals or other +// stack memory. This can increase the size of a dump significantly. +// +// Module paths may contain undesired information such as user names +// or other important directory names so they can be stripped. This +// option reduces the ability to locate the proper image later +// and should only be used in certain situations. +// +// Complete operating system per-process and per-thread information can +// be gathered and stored in the dump. +// +// The virtual address space can be scanned for various types +// of memory to be included in the dump. +// +// Code which is concerned with potentially private information +// getting into the minidump can set a flag that automatically +// modifies all existing and future flags to avoid placing +// unnecessary data in the dump. Basic data, such as stack +// information, will still be included but optional data, such +// as indirect memory, will not. +// +// When doing a full memory dump it's possible to store all +// of the enumerated memory region descriptive information +// in a memory information stream. +// +// Additional thread information beyond the basic thread +// structure can be collected if desired. +// +// A minidump with code segments includes all of the code +// and code-related sections from loaded modules in order +// to capture executable content. +// +// MiniDumpWithoutAuxiliaryState turns off any secondary, +// auxiliary-supported memory gathering. +// +// MiniDumpWithFullAuxiliaryState asks any present auxiliary +// data providers to include all of their state in the dump. +// The exact set of what is provided depends on the auxiliary. +// This can be quite large. +// + +typedef enum _MINIDUMP_TYPE { + MiniDumpNormal = 0x00000000, + MiniDumpWithDataSegs = 0x00000001, + MiniDumpWithFullMemory = 0x00000002, + MiniDumpWithHandleData = 0x00000004, + MiniDumpFilterMemory = 0x00000008, + MiniDumpScanMemory = 0x00000010, + MiniDumpWithUnloadedModules = 0x00000020, + MiniDumpWithIndirectlyReferencedMemory = 0x00000040, + MiniDumpFilterModulePaths = 0x00000080, + MiniDumpWithProcessThreadData = 0x00000100, + MiniDumpWithPrivateReadWriteMemory = 0x00000200, + MiniDumpWithoutOptionalData = 0x00000400, + MiniDumpWithFullMemoryInfo = 0x00000800, + MiniDumpWithThreadInfo = 0x00001000, + MiniDumpWithCodeSegs = 0x00002000, + MiniDumpWithoutAuxiliaryState = 0x00004000, + MiniDumpWithFullAuxiliaryState = 0x00008000, + + MiniDumpValidTypeFlags = 0x0000ffff, +} MINIDUMP_TYPE; + +// +// In addition to the primary flags provided to +// MiniDumpWriteDump there are additional, less +// frequently used options queried via the secondary +// flags callback. +// +// MiniSecondaryWithoutPowerInfo suppresses the minidump +// query that retrieves processor power information for +// MINIDUMP_MISC_INFO. +// + +typedef enum _MINIDUMP_SECONDARY_FLAGS { + MiniSecondaryWithoutPowerInfo = 0x00000001, + + MiniSecondaryValidFlags = 0x00000001, +} MINIDUMP_SECONDARY_FLAGS; + + +// +// The minidump callback should modify the FieldsToWrite parameter to reflect +// what portions of the specified thread or module should be written to the +// file. +// + +typedef +BOOL +(WINAPI * MINIDUMP_CALLBACK_ROUTINE) ( + IN PVOID CallbackParam, + IN CONST PMINIDUMP_CALLBACK_INPUT CallbackInput, + IN OUT PMINIDUMP_CALLBACK_OUTPUT CallbackOutput + ); + +typedef struct _MINIDUMP_CALLBACK_INFORMATION { + MINIDUMP_CALLBACK_ROUTINE CallbackRoutine; + PVOID CallbackParam; +} MINIDUMP_CALLBACK_INFORMATION, *PMINIDUMP_CALLBACK_INFORMATION; + + + +//++ +// +// PVOID +// RVA_TO_ADDR( +// PVOID Mapping, +// ULONG Rva +// ) +// +// Routine Description: +// +// Map an RVA that is contained within a mapped file to it's associated +// flat address. +// +// Arguments: +// +// Mapping - Base address of mapped file containing the RVA. +// +// Rva - An Rva to fixup. +// +// Return Values: +// +// A pointer to the desired data. +// +//-- + +#define RVA_TO_ADDR(Mapping,Rva) ((PVOID)(((ULONG_PTR) (Mapping)) + (Rva))) + +BOOL +WINAPI +MiniDumpWriteDump( + IN HANDLE hProcess, + IN DWORD ProcessId, + IN HANDLE hFile, + IN MINIDUMP_TYPE DumpType, + IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL + IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL + IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL + ); + +BOOL +WINAPI +MiniDumpReadDumpStream( + IN PVOID BaseOfDump, + IN ULONG StreamNumber, + OUT PMINIDUMP_DIRECTORY * Dir, OPTIONAL + OUT PVOID * StreamPointer, OPTIONAL + OUT ULONG * StreamSize OPTIONAL + ); + +#if defined(_MSC_VER) +#if _MSC_VER >= 800 +#if _MSC_VER >= 1200 +#pragma warning(pop) +#else +#pragma warning(default:4200) /* Zero length array */ +#pragma warning(default:4201) /* Nameless struct/union */ +#endif +#endif +#endif + +#include + +#ifdef __cplusplus +} +#endif + + +#endif // _DBGHELP_ diff --git a/plugins/CrashDumper/src/vc6/dbghelp.lib b/plugins/CrashDumper/src/vc6/dbghelp.lib new file mode 100644 index 0000000000..5d50c3f74d Binary files /dev/null and b/plugins/CrashDumper/src/vc6/dbghelp.lib differ diff --git a/plugins/CrashDumper/src/version.h b/plugins/CrashDumper/src/version.h new file mode 100644 index 0000000000..776e30e404 --- /dev/null +++ b/plugins/CrashDumper/src/version.h @@ -0,0 +1,3 @@ +#define __FILEVERSION_STRING 0,0,4,21 +#define __VERSION_STRING "0.0.4.21" +#define __VERSION_DWORD PLUGIN_MAKE_VERSION(0, 0, 4, 21) diff --git a/plugins/CrashDumper/svc_crshdmp-translation.txt b/plugins/CrashDumper/svc_crshdmp-translation.txt deleted file mode 100644 index 18d251f699..0000000000 --- a/plugins/CrashDumper/svc_crshdmp-translation.txt +++ /dev/null @@ -1,54 +0,0 @@ -; Common strings that belong to many files -;[] - -; ../../plugins/Svc_crshdmp/crshdmp.cpp -;[Copy Version Info to clipboard] -;[Copy to clipboard] -;[Open crash report directory] -;[Open miranda-vi.org] -;[Services] -;[Show] -;[Show Version Info] -;[Show Version Information] -;[Show with DLLs] -;[Store to file] -;[Upload] -;[Upload Version Information] -;[Version Information] -;[Version Information To Clipboard] -;[Version Information To File] -;[VersionInfo file %s is inaccessible] -;[VersionInfo stored into file %s] - -; ../../plugins/Svc_crshdmp/crshdmp.rc -;[&Copy] -;[Close] -;[Co&py All] -;[Copy To Clipboard] -;[Create reports in subfolders naming as current date] -;[General] -;[Password] -;[Select &All] -;[Support for miranda-vi.org] -;[To File] -;[Upload automatically when changed] -;[Use classic dates] -;[Username] -;[View] -;[View Version Information ] - -; ../../plugins/Svc_crshdmp/exhndlr.cpp -;[Crash Report write location is inaccesible] -;[Miranda crashed. Crash report stored in the folder:\n %s\n\n Would you like store it in the clipboard as well?] - -; ../../plugins/Svc_crshdmp/upload.cpp -;[Cannot upload VersionInfo. Daily upload limit exceeded] -;[Cannot upload VersionInfo. Host unreachable.] -;[Cannot upload VersionInfo. Incorrect username or password] -;[Cannot upload VersionInfo. Unknown error] -;[Cannot upload VersionInfo. User is banned] -;[Crash Dumper HTTP connections] -;[VersionInfo upload successful,\n %d old plugins] - -; ../../plugins/Svc_crshdmp/utils.cpp -;[More then one crash reporting plugin installed. This will result in inability of creating crash reports] diff --git a/plugins/CrashDumper/ui.cpp b/plugins/CrashDumper/ui.cpp deleted file mode 100644 index 00cf9c26cd..0000000000 --- a/plugins/CrashDumper/ui.cpp +++ /dev/null @@ -1,327 +0,0 @@ -/* -Miranda Crash Dumper Plugin -Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "utils.h" -#include -#include -#include - -HWND hViewWnd; -extern HINSTANCE hInst; - - -HDWP MyResizeWindow (HDWP hDwp, HWND hwndDlg, HWND hwndCtrl, int nHorizontalOffset, int nVerticalOffset, - int nWidthOffset, int nHeightOffset) -{ - POINT pt; - RECT rcinit; - - // get current bounding rectangle - GetWindowRect(hwndCtrl, &rcinit); - - // get current top left point - pt.x = rcinit.left; - pt.y = rcinit.top; - ScreenToClient(hwndDlg, &pt); - - return DeferWindowPos(hDwp, hwndCtrl, NULL, - pt.x + nHorizontalOffset, - pt.y + nVerticalOffset, - rcinit.right - rcinit.left + nWidthOffset, - rcinit.bottom - rcinit.top + nHeightOffset, - SWP_NOZORDER); -} - -BOOL MyResizeGetOffset(HWND hwndCtrl, int nWidth, int nHeight, int* nDx, int* nDy) -{ - RECT rcinit; - - // get current bounding rectangle - GetWindowRect(hwndCtrl, &rcinit); - - // calculate offsets - *nDx = nWidth - (rcinit.right - rcinit.left); - *nDy = nHeight - (rcinit.bottom - rcinit.top); - - return rcinit.bottom != rcinit.top && nHeight > 0; -} - -INT_PTR CALLBACK DlgProcView(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) - { - case WM_INITDIALOG: - if (hViewWnd == NULL) - { - hViewWnd = hwndDlg; - TranslateDialogDefault(hwndDlg); - SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIconEx("versionInfo", true)); - SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIconEx("versionInfo")); - - CHARFORMAT2 chf; - chf.cbSize = sizeof(chf); - SendDlgItemMessage(hwndDlg, IDC_VIEWVERSIONINFO, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM)&chf); - _tcscpy(chf.szFaceName, TEXT("Courier New")); - SendDlgItemMessage(hwndDlg, IDC_VIEWVERSIONINFO, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&chf); - - bkstring buffer; - buffer.reserve(0x1800); - PrintVersionInfo(buffer, (unsigned int)lParam); - SetDlgItemText(hwndDlg, IDC_VIEWVERSIONINFO, buffer.c_str()); - SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); - - Utils_RestoreWindowPositionNoMove(hwndDlg, NULL, PluginName, "ViewInfo_"); - ShowWindow(hwndDlg, SW_SHOW); - } - else - DestroyWindow(hwndDlg); - break; - - case WM_SIZE: - { - int dx, dy, bsz; - HDWP hDwp; - RECT rc; - - GetWindowRect(GetDlgItem(hwndDlg, IDC_FILEVER), &rc); - bsz = rc.bottom - rc.top; - - if (MyResizeGetOffset(GetDlgItem(hwndDlg, IDC_VIEWVERSIONINFO), - LOWORD(lParam)-20, HIWORD(lParam)-30-bsz, &dx, &dy)) - { - hDwp = BeginDeferWindowPos(4); - hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_FILEVER), 0, dy, 0, 0); - hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_CLIPVER), dx/2, dy, 0, 0); - hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDCANCEL), dx, dy, 0, 0); - hDwp = MyResizeWindow(hDwp, hwndDlg, GetDlgItem(hwndDlg, IDC_VIEWVERSIONINFO), 0, 0, dx, dy); - EndDeferWindowPos(hDwp); - } - } - break; - - case WM_GETMINMAXINFO: - { - LPMINMAXINFO mmi = (LPMINMAXINFO)lParam; - - // The minimum width in points - mmi->ptMinTrackSize.x = 350; - // The minimum height in points - mmi->ptMinTrackSize.y = 300; - } - break; - - case WM_COMMAND: - switch(LOWORD(wParam)) - { - case IDC_CLIPVER: - CallService(MS_CRASHDUMPER_STORETOCLIP, 0, GetWindowLongPtr(hwndDlg, GWLP_USERDATA)); - break; - - case IDC_FILEVER: - CallService(MS_CRASHDUMPER_STORETOFILE, 0, GetWindowLongPtr(hwndDlg, GWLP_USERDATA)); - break; - - case IDCANCEL: - DestroyWindow(hwndDlg); - break; - } - break; - - case WM_CONTEXTMENU: - { - HWND hView = GetDlgItem(hwndDlg, IDC_VIEWVERSIONINFO); - RECT rc; - GetWindowRect(hView, &rc); - - POINT pt; - pt.x = LOWORD(lParam); - pt.y = HIWORD(lParam); - if (PtInRect(&rc, pt)) - { - static const CHARRANGE all = { 0, -1 }; - - HMENU hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXT)); - HMENU hSubMenu = GetSubMenu(hMenu, 0); - TranslateMenu(hSubMenu); - - CHARRANGE sel; - SendMessage(hView, EM_EXGETSEL, 0, (LPARAM)&sel); - if (sel.cpMin == sel.cpMax) - EnableMenuItem(hSubMenu, IDM_COPY, MF_BYCOMMAND | MF_GRAYED); - - switch (TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, hwndDlg, NULL)) - { - case IDM_COPY: - SendMessage(hView, WM_COPY, 0, 0); - break; - - case IDM_COPYALL: - SendMessage(hView, EM_EXSETSEL, 0, (LPARAM)&all); - SendMessage(hView, WM_COPY, 0, 0); - SendMessage(hView, EM_EXSETSEL, 0, (LPARAM)&sel); - break; - - case IDM_SELECTALL: - SendMessage(hView, EM_EXSETSEL, 0, (LPARAM)&all); - break; - } - DestroyMenu(hMenu); - } - } - break; - - case WM_DESTROY: - hViewWnd = NULL; - ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_BIG, 0)); - ReleaseIconEx((HICON)SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, 0)); - Utils_SaveWindowPosition(hwndDlg, NULL, PluginName, "ViewInfo_"); - if (servicemode) PostQuitMessage(0); - break; - } - return FALSE; -} - - -void DestroyAllWindows(void) -{ - if (hViewWnd != NULL) DestroyWindow(hViewWnd); - hViewWnd = NULL; -} - - -INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) - { - case WM_INITDIALOG: - { - TranslateDialogDefault(hwndDlg); - - DBVARIANT dbv; - if (DBGetContactSettingString(NULL, PluginName, "Username", &dbv) == 0) - { - SetDlgItemTextA(hwndDlg, IDC_USERNAME, dbv.pszVal); - DBFreeVariant(&dbv); - } - if (DBGetContactSettingString(NULL, PluginName, "Password", &dbv) == 0) - { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); - SetDlgItemTextA(hwndDlg, IDC_PASSWORD, dbv.pszVal); - DBFreeVariant(&dbv); - } - CheckDlgButton(hwndDlg, IDC_UPLOADCHN, DBGetContactSettingByte(NULL, PluginName, "UploadChanged", 0)); - CheckDlgButton(hwndDlg, IDC_CLASSICDATES, clsdates); - CheckDlgButton(hwndDlg, IDC_DATESUBFOLDER, dtsubfldr); - } - break; - - case WM_COMMAND: - if ((HIWORD(wParam) == EN_CHANGE || HIWORD(wParam) == BN_CLICKED) && (HWND)lParam == GetFocus()) - SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0); - break; - - case WM_NOTIFY: - if (((LPNMHDR)lParam)->code == (unsigned)PSN_APPLY) - { - char szSetting[100]; - GetDlgItemTextA(hwndDlg, IDC_USERNAME, szSetting, SIZEOF(szSetting)); - DBWriteContactSettingString(NULL, PluginName, "Username", szSetting); - - GetDlgItemTextA(hwndDlg, IDC_PASSWORD, szSetting, SIZEOF(szSetting)); - CallService(MS_DB_CRYPT_ENCODESTRING, SIZEOF(szSetting), (LPARAM)szSetting); - DBWriteContactSettingString(NULL, PluginName, "Password", szSetting); - - DBWriteContactSettingByte(NULL, PluginName, "UploadChanged", - (BYTE)IsDlgButtonChecked(hwndDlg, IDC_UPLOADCHN)); - - clsdates = IsDlgButtonChecked(hwndDlg, IDC_CLASSICDATES) == BST_CHECKED; - if (clsdates) - DBWriteContactSettingByte(NULL, PluginName, "ClassicDates", 1); - else - DBDeleteContactSetting(NULL, PluginName, "ClassicDates"); - dtsubfldr = IsDlgButtonChecked(hwndDlg, IDC_DATESUBFOLDER) == BST_CHECKED; - if (dtsubfldr) - DBWriteContactSettingByte(NULL, PluginName, "SubFolders", 1); - else - DBDeleteContactSetting(NULL, PluginName, "SubFolders"); - } - break; - } - return FALSE; -} - - -LRESULT CALLBACK DlgProcPopup(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) - { - case WM_CONTEXTMENU: - PUDeletePopUp(hWnd); - break; - - case WM_COMMAND: - switch ((int)PUGetPluginData(hWnd)) - { - case 0: - OpenAuthUrl("http://www.miranda-vi.org/"); - break; - - case 1: - OpenAuthUrl("http://%s.miranda-vi.org/global"); - break; - - case 3: - TCHAR path[MAX_PATH]; - crs_sntprintf(path, MAX_PATH, TEXT("%s\\VersionInfo.txt"), VersionInfoFolder); - ShellExecute(NULL, TEXT("open"), path, NULL, NULL, SW_SHOW); - break; - - } - PUDeletePopUp(hWnd); - break; - - case UM_FREEPLUGINDATA: - ReleaseIconEx("versionInfo"); - break; - } - - return DefWindowProc(hWnd, msg, wParam, lParam); -} - -void ShowMessage(int type, const TCHAR* format, ...) -{ - POPUPDATAT pi = {0}; - - va_list va; - va_start(va, format); - int len = _vsntprintf(pi.lptzText, SIZEOF(pi.lptzText)-1, format, va); - pi.lptzText[len] = 0; - va_end(va); - - if (ServiceExists(MS_POPUP_ADDPOPUPT)) - { - _tcscpy(pi.lptzContactName, TEXT(PluginName)); - pi.lchIcon = LoadIconEx("versionInfo"); - pi.PluginWindowProc = DlgProcPopup; - pi.PluginData = (void*)type; - - PUAddPopUpT(&pi); - } - else - MessageBox(NULL, pi.lptzText, TEXT(PluginName), MB_OK | MB_ICONINFORMATION); -} diff --git a/plugins/CrashDumper/upload.cpp b/plugins/CrashDumper/upload.cpp deleted file mode 100644 index 498b5cb2f6..0000000000 --- a/plugins/CrashDumper/upload.cpp +++ /dev/null @@ -1,292 +0,0 @@ -/* -Miranda Crash Dumper Plugin -Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "utils.h" -#include - -HANDLE hNetlibUser; - -static void arrayToHex(BYTE* data, size_t datasz, char* res) -{ - char* resptr = res; - for (unsigned i=0; i> 4); - *resptr++ = (char)((ch0 <= 9) ? ('0' + ch0) : (('a' - 10) + ch0)); - - const char ch1 = (char)(ch & 0xF); - *resptr++ = (char)((ch1 <= 9) ? ('0' + ch1) : (('a' - 10) + ch1)); - } - *resptr = '\0'; -} - -void GetLoginStr(char* user, size_t szuser, char* pass) -{ - DBVARIANT dbv; - - if (DBGetContactSettingString(NULL, PluginName, "Username", &dbv) == 0) - { - mir_snprintf(user, szuser, "%s", dbv.pszVal); - DBFreeVariant(&dbv); - } - else - user[0] = 0; - - if (DBGetContactSettingString(NULL, PluginName, "Password", &dbv) == 0) - { - CallService(MS_DB_CRYPT_DECODESTRING, strlen(dbv.pszVal)+1, (LPARAM)dbv.pszVal); - - mir_md5_byte_t hash[16]; - mir_md5_state_t context; - - mir_md5_init(&context); - mir_md5_append(&context, (BYTE*)dbv.pszVal, (int)strlen(dbv.pszVal)); - mir_md5_finish(&context, hash); - - arrayToHex(hash, sizeof(hash), pass); - - DBFreeVariant(&dbv); - } - else - pass[0] = 0; -} - -void OpenAuthUrl(const char* url) -{ - char user[64], pass[40]; - GetLoginStr(user, sizeof(user), pass); - - if (user[0] && pass[0]) - { - char str[256]; - - mir_snprintf(str, sizeof(str), url, user); - char* eurl = (char*)CallService(MS_NETLIB_URLENCODE, 0, (LPARAM)str); - - mir_snprintf(str, sizeof(str), "http://www.miranda-vi.org/cdlogin?name=%s&pass=%s&redir=%s", user, pass, eurl); - CallService(MS_UTILS_OPENURL, 1, (LPARAM)str); - HeapFree(GetProcessHeap(), 0, eurl); - } - else - CallService(MS_UTILS_OPENURL, 1, (LPARAM)"http://www.miranda-vi.org/"); -} - -void CreateAuthString(char* auth) -{ - char user[64], pass[40]; - GetLoginStr(user, sizeof(user), pass); - - char str[110]; - int len = mir_snprintf(str, sizeof(str), "%s:%s", user, pass); - - strcpy(auth, "Basic "); - NETLIBBASE64 nlb = { auth+6, 250, (PBYTE)str, len }; - CallService(MS_NETLIB_BASE64ENCODE, 0, LPARAM(&nlb)); -} - - -bool InternetDownloadFile(const char *szUrl, VerTrnsfr* szReq) -{ - int result = 0xBADBAD; - char* szRedirUrl = NULL; - NETLIBHTTPREQUEST nlhr = {0}; - - // initialize the netlib request - nlhr.cbSize = sizeof(nlhr); - nlhr.requestType = REQUEST_POST; - nlhr.flags = NLHRF_HTTP11 | NLHRF_NODUMP; - nlhr.szUrl = (char*)szUrl; - - nlhr.headersCount = 6; - nlhr.headers=(NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)*nlhr.headersCount); - nlhr.headers[0].szName = "Connection"; - nlhr.headers[0].szValue = "close"; - nlhr.headers[1].szName = "Cache-Control"; - nlhr.headers[1].szValue = "no-cache"; - nlhr.headers[2].szName = "Pragma"; - nlhr.headers[2].szValue = "no-cache"; - nlhr.headers[3].szName = "Content-Type"; - nlhr.headers[3].szValue = "text/plain; charset=utf-8"; - nlhr.headers[4].szName = "AutoUpload"; - nlhr.headers[4].szValue = (char*)(szReq->autot ? "1" : "0"); - nlhr.headers[5].szName = "Authorization"; - - char auth[256]; - CreateAuthString(auth); - nlhr.headers[5].szValue = auth; - - nlhr.pData = szReq->buf; - nlhr.dataLength = (int)strlen(szReq->buf); - - while (result == 0xBADBAD) - { - // download the page - NETLIBHTTPREQUEST *nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, - (WPARAM)hNetlibUser,(LPARAM)&nlhr); - - if (nlhrReply) - { - int i; - - // if the recieved code is 200 OK - switch(nlhrReply->resultCode) - { - case 200: - if (DBGetContactSettingByte(NULL, PluginName, "UploadChanged", 0)) - ProcessVIHash(true); - - for (i=nlhrReply->headersCount; i--; ) - { - if (_stricmp(nlhrReply->headers[i].szName, "OldPlugins") == 0) - { - i = atoi(nlhrReply->headers[i].szValue); - break; - } - } - - ShowMessage(1, TranslateT("VersionInfo upload successful,\n %d old plugins"), i); - result = 0; - break; - - case 401: - ShowMessage(0, TranslateT("Cannot upload VersionInfo. Incorrect username or password")); - result = 1; - break; - - case 510: - ShowMessage(0, TranslateT("Cannot upload VersionInfo. User is banned")); - result = 1; - break; - - case 511: - ShowMessage(0, TranslateT("Cannot upload VersionInfo. Daily upload limit exceeded")); - result = 1; - break; - - case 301: - case 302: - case 307: - // get the url for the new location and save it to szInfo - // look for the reply header "Location" - for (i=0; iheadersCount; i++) - { - if (!strcmp(nlhrReply->headers[i].szName, "Location")) - { - size_t rlen = 0; - if (nlhrReply->headers[i].szValue[0] == '/') - { - const char* szPath; - const char* szPref = strstr(szUrl, "://"); - szPref = szPref ? szPref + 3 : szUrl; - szPath = strchr(szPref, '/'); - rlen = szPath != NULL ? szPath - szUrl : strlen(szUrl); - } - - szRedirUrl = (char*)mir_realloc(szRedirUrl, - rlen + strlen(nlhrReply->headers[i].szValue)*3 + 1); - - strncpy(szRedirUrl, szUrl, rlen); - strcpy(szRedirUrl+rlen, nlhrReply->headers[i].szValue); - - nlhr.szUrl = szRedirUrl; - break; - } - } - break; - - default: - result = 1; - ShowMessage(0, TranslateT("Cannot upload VersionInfo. Unknown error")); - } - } - else - { - result = 1; - ShowMessage(0, TranslateT("Cannot upload VersionInfo. Host unreachable.")); - } - - CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)nlhrReply); - } - - mir_free(szRedirUrl); - mir_free(nlhr.headers); - - return result == 0; -} - -void __cdecl VersionInfoUploadThread(void* arg) -{ - VerTrnsfr* trn = (VerTrnsfr*)arg; - InternetDownloadFile("http://www.miranda-vi.org/uploadpost", trn); - mir_free(trn->buf); - mir_free(trn); -} - - -void UploadInit(void) -{ - NETLIBUSER nlu = {0}; - nlu.cbSize = sizeof(nlu); - nlu.flags = NUF_OUTGOING | NUF_HTTPCONNS | NUF_NOHTTPSOPTION | NUF_TCHAR; - nlu.szSettingsModule = (char*)PluginName; - nlu.ptszDescriptiveName = TranslateT("Crash Dumper HTTP connections"); - hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); -} - -void UploadClose(void) -{ - Netlib_CloseHandle(hNetlibUser); -} - -bool ProcessVIHash(bool store) -{ - bkstring buffer; - buffer.reserve(0x1800); - PrintVersionInfo(buffer, 0); - - mir_md5_byte_t hash[16]; - mir_md5_state_t context; - - mir_md5_init(&context); - mir_md5_append(&context, (PBYTE)buffer.c_str(), (int)buffer.sizebytes()); - mir_md5_finish(&context, hash); - - char hashstr[40]; - arrayToHex(hash, sizeof(hash), hashstr); - - bool result; - if (store) - { - DBWriteContactSettingString(NULL, PluginName, "VIHash", hashstr); - result = true; - } - else - { - DBVARIANT dbv; - if (DBGetContactSettingString(NULL, PluginName, "VIHash", &dbv) == 0) - { - result = strcmp(hashstr, dbv.pszVal) == 0; - DBFreeVariant(&dbv); - } - else - result = false; - } - return result; -} diff --git a/plugins/CrashDumper/utils.cpp b/plugins/CrashDumper/utils.cpp deleted file mode 100644 index d4dced7d70..0000000000 --- a/plugins/CrashDumper/utils.cpp +++ /dev/null @@ -1,836 +0,0 @@ -/* -Miranda Crash Dumper Plugin -Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "utils.h" -#include - -static HMODULE hKernel = GetModuleHandle(TEXT("kernel32.dll")); - -tGetNativeSystemInfo pGetNativeSystemInfo = (tGetNativeSystemInfo)GetProcAddress(hKernel, "GetNativeSystemInfo"); -tGetProductInfo pGetProductInfo = (tGetProductInfo) GetProcAddress(hKernel, "GetProductInfo"); -tGlobalMemoryStatusEx pGlobalMemoryStatusEx = (tGlobalMemoryStatusEx) GetProcAddress(hKernel, "GlobalMemoryStatusEx"); -tGetUserDefaultUILanguage pGetUserDefaultUILanguage = (tGetUserDefaultUILanguage) GetProcAddress(hKernel, "GetUserDefaultUILanguage"); -tGetSystemDefaultUILanguage pGetSystemDefaultUILanguage = (tGetSystemDefaultUILanguage) GetProcAddress(hKernel, "GetSystemDefaultUILanguage"); -tIsWow64Process pIsWow64Process = (tIsWow64Process) GetProcAddress(hKernel, "IsWow64Process"); -tIsProcessorFeaturePresent pIsProcessorFeaturePresent = (tIsProcessorFeaturePresent) GetProcAddress(hKernel, "IsProcessorFeaturePresent"); - - -tGetDiskFreeSpaceEx pGetDiskFreeSpaceEx = (tGetDiskFreeSpaceEx) GetProcAddress(hKernel, "GetDiskFreeSpaceExW"); - - - -void CheckForOtherCrashReportingPlugins(void) -{ - HMODULE hModule = GetModuleHandle(TEXT("attache.dll")); - if (hModule == NULL) - hModule = GetModuleHandle(TEXT("crashrpt.dll")); - if (hModule == NULL) - hModule = GetModuleHandle(TEXT("crashdmp.dll")); - - if (hModule == NULL) return; - - MessageBox(NULL, TranslateT("More then one crash reporting plugin installed. This will result in inability of creating crash reports"), - TEXT("Miranda Crash Dumper"), MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_TOPMOST); -} - -void GetOSDisplayString(bkstring& buffer) -{ - OSVERSIONINFOEX osvi = {0}; - SYSTEM_INFO si = {0}; - BOOL bOsVersionInfoEx; - DWORD dwType = 0; - - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - - bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*)&osvi); - if (!bOsVersionInfoEx) - { - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (!GetVersionEx((OSVERSIONINFO*)&osvi)) - return; - } - - // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise. - pGetNativeSystemInfo = (tGetNativeSystemInfo)GetProcAddress(hKernel, "GetNativeSystemInfo"); - if (NULL != pGetNativeSystemInfo) pGetNativeSystemInfo(&si); - else GetSystemInfo(&si); - - if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && osvi.dwMajorVersion > 4) - { - buffer.append(TEXT("Operating System: Microsoft ")); - - // Test for the specific product. - if (osvi.dwMajorVersion == 6) - { - switch (osvi.dwMinorVersion) - { - case 0: - if (osvi.wProductType == VER_NT_WORKSTATION) - buffer.append(TEXT("Windows Vista ")); - else - buffer.append(TEXT("Windows Server 2008 ")); - break; - - case 1: - if (osvi.wProductType == VER_NT_WORKSTATION) - buffer.append(TEXT("Windows 7 ")); - else - buffer.append(TEXT("Windows Server 2008 R2 ")); - break; - - default: - if (osvi.wProductType == VER_NT_WORKSTATION) - buffer.append(TEXT("Windows 8 ")); - else - buffer.append(TEXT("Windows Server 2012 ")); - break; - } - - pGetProductInfo = (tGetProductInfo) GetProcAddress(hKernel, "GetProductInfo"); - if (pGetProductInfo != NULL) pGetProductInfo(6, 0, 0, 0, &dwType); - - switch(dwType) - { - case PRODUCT_ULTIMATE: - buffer.append(TEXT("Ultimate Edition")); - break; - case PRODUCT_HOME_PREMIUM: - buffer.append(TEXT("Home Premium Edition")); - break; - case PRODUCT_HOME_BASIC: - buffer.append(TEXT("Home Basic Edition")); - break; - case PRODUCT_ENTERPRISE: - buffer.append(TEXT("Enterprise Edition")); - break; - case PRODUCT_BUSINESS: - buffer.append(TEXT("Business Edition")); - break; - case PRODUCT_STARTER: - buffer.append(TEXT("Starter Edition")); - break; - case PRODUCT_CLUSTER_SERVER: - buffer.append(TEXT("Cluster Server Edition")); - break; - case PRODUCT_DATACENTER_SERVER: - buffer.append(TEXT("Datacenter Edition")); - break; - case PRODUCT_DATACENTER_SERVER_CORE: - buffer.append(TEXT("Datacenter Edition (core installation)")); - break; - case PRODUCT_ENTERPRISE_SERVER: - buffer.append(TEXT("Enterprise Edition")); - break; - case PRODUCT_ENTERPRISE_SERVER_CORE: - buffer.append(TEXT("Enterprise Edition (core installation)")); - break; - case PRODUCT_ENTERPRISE_SERVER_IA64: - buffer.append(TEXT("Enterprise Edition for Itanium-based Systems")); - break; - case PRODUCT_SMALLBUSINESS_SERVER: - buffer.append(TEXT("Small Business Server")); - break; - case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM: - buffer.append(TEXT("Small Business Server Premium Edition")); - break; - case PRODUCT_STANDARD_SERVER: - buffer.append(TEXT("Standard Edition")); - break; - case PRODUCT_STANDARD_SERVER_CORE: - buffer.append(TEXT("Standard Edition (core installation)")); - break; - case PRODUCT_WEB_SERVER: - buffer.append(TEXT("Web Server Edition")); - break; - } - - if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) - buffer.append(TEXT(", 64-bit")); - else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL) - buffer.append(TEXT(", 32-bit")); - } - - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) - { - if (GetSystemMetrics(SM_SERVERR2)) - buffer.append(TEXT("Windows Server 2003 R2, ")); - else if (osvi.wSuiteMask==VER_SUITE_STORAGE_SERVER) - buffer.append(TEXT("Windows Storage Server 2003")); - else if (osvi.wProductType == VER_NT_WORKSTATION && - si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - buffer.append(TEXT("Windows XP Professional x64 Edition")); - else buffer.append(TEXT("Windows Server 2003, ")); - - // Test for the server type. - if (osvi.wProductType != VER_NT_WORKSTATION) - { - if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64) - { - if(osvi.wSuiteMask & VER_SUITE_DATACENTER) - buffer.append(TEXT("Datacenter Edition for Itanium-based Systems")); - else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE) - buffer.append(TEXT("Enterprise Edition for Itanium-based Systems")); - } - - else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) - { - if(osvi.wSuiteMask & VER_SUITE_DATACENTER) - buffer.append(TEXT("Datacenter x64 Edition")); - else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE) - buffer.append(TEXT("Enterprise x64 Edition")); - else buffer.append(TEXT("Standard x64 Edition")); - } - - else - { - if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER) - buffer.append(TEXT("Compute Cluster Edition")); - else if(osvi.wSuiteMask & VER_SUITE_DATACENTER) - buffer.append(TEXT("Datacenter Edition")); - else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE) - buffer.append(TEXT("Enterprise Edition")); - else if (osvi.wSuiteMask & VER_SUITE_BLADE) - buffer.append(TEXT("Web Edition")); - else buffer.append(TEXT("Standard Edition")); - } - } - } - - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) - { - buffer.append(TEXT("Windows XP ")); - if (osvi.wSuiteMask & VER_SUITE_PERSONAL) - buffer.append(TEXT("Home Edition")); - else - buffer.append(TEXT("Professional")); - } - - if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) - { - buffer.append(TEXT("Windows 2000 ")); - - if (osvi.wProductType == VER_NT_WORKSTATION) - { - buffer.append(TEXT("Professional")); - } - else - { - if(osvi.wSuiteMask & VER_SUITE_DATACENTER) - buffer.append(TEXT("Datacenter Server")); - else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE) - buffer.append(TEXT("Advanced Server")); - else buffer.append(TEXT("Server")); - } - } - if (_tcslen(osvi.szCSDVersion) > 0) - { - buffer.append(TEXT(" ")); - buffer.append(osvi.szCSDVersion); - } - - buffer.appendfmt(TEXT(" (build %d)"), osvi.dwBuildNumber); - } - else - { - if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId) - { - buffer.append(TEXT("Microsoft Windows NT ")); - if (osvi.wProductType == VER_NT_WORKSTATION) - buffer.append(TEXT("Workstation 4.0 ")); - else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) - buffer.append(TEXT("Server 4.0, Enterprise Edition ")); - else - buffer.append(TEXT("Server 4.0 ")); - } - - if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && osvi.dwMajorVersion == 4) - { - if (osvi.dwMinorVersion == 0) - { - buffer.append(TEXT("Microsoft Windows 95 ")); - if (osvi.szCSDVersion[1]==TEXT('C') || osvi.szCSDVersion[1]==TEXT('B')) - buffer.append(TEXT("OSR2 ")); - } - - if (osvi.dwMinorVersion == 10) - { - buffer.append(TEXT("Microsoft Windows 98 ")); - if (osvi.szCSDVersion[1]==TEXT('A') || osvi.szCSDVersion[1]==TEXT('B')) - buffer.append(TEXT("SE ")); - } - - if (osvi.dwMinorVersion == 90) - { - buffer.append(TEXT("Microsoft Windows Millennium Edition")); - } - buffer.appendfmt(TEXT("(build %d)"), LOWORD(osvi.dwBuildNumber)); - } - else if (osvi.dwPlatformId == VER_PLATFORM_WIN32s) - { - buffer.append(TEXT("Microsoft Win32s")); - } - } -} - -int GetTZOffset(void) -{ - TIME_ZONE_INFORMATION tzInfo = {0}; - DWORD type = GetTimeZoneInformation(&tzInfo); - - int offset = 0; - switch (type) - { - case TIME_ZONE_ID_DAYLIGHT: - offset = -(tzInfo.Bias + tzInfo.DaylightBias); - break; - - case TIME_ZONE_ID_STANDARD: - offset = -(tzInfo.Bias + tzInfo.StandardBias); - break; - - case TIME_ZONE_ID_UNKNOWN: - offset = -tzInfo.Bias; - break; - } - return offset; -} - -void GetISO8061Time(SYSTEMTIME* stLocal, LPTSTR lpszString, DWORD dwSize) -{ - SYSTEMTIME loctime; - if (stLocal == NULL) - { - stLocal = &loctime; - GetLocalTime(stLocal); - } - - if (clsdates) - { - GetDateFormat(LOCALE_INVARIANT, 0, stLocal, TEXT("d MMM yyyy"), lpszString, dwSize); - int dlen = (int)_tcslen(lpszString); - GetTimeFormat(LOCALE_INVARIANT, 0, stLocal, TEXT(" H:mm:ss"), lpszString+dlen, dwSize-dlen); - } - else - { - int offset = GetTZOffset(); - - // Build a string showing the date and time. - crs_sntprintf(lpszString, dwSize, TEXT("%d-%02d-%02d %02d:%02d:%02d%+03d%02d"), - stLocal->wYear, stLocal->wMonth, stLocal->wDay, - stLocal->wHour, stLocal->wMinute, stLocal->wSecond, - offset / 60, offset % 60); - } -} - -void GetLastWriteTime(FILETIME* ftime, LPTSTR lpszString, DWORD dwSize) -{ - FILETIME ftLocal; - SYSTEMTIME stLocal; - - // Convert the last-write time to local time. - FileTimeToLocalFileTime(ftime, &ftLocal); - FileTimeToSystemTime(&ftLocal, &stLocal); - - GetISO8061Time(&stLocal, lpszString, dwSize); -} - -void GetLastWriteTime(LPCTSTR fileName, LPTSTR lpszString, DWORD dwSize) -{ - WIN32_FIND_DATA FindFileData; - - HANDLE hFind = FindFirstFile(fileName, &FindFileData); - if (hFind == INVALID_HANDLE_VALUE) return; - FindClose(hFind); - - GetLastWriteTime(&FindFileData.ftLastWriteTime, lpszString, dwSize); -} - -typedef PLUGININFOEX * (__cdecl * Miranda_Plugin_Info) (DWORD mirandaVersion); - -PLUGININFOEX* GetMirInfo(HMODULE hModule) -{ - Miranda_Plugin_Info bpi = (Miranda_Plugin_Info)GetProcAddress(hModule, "MirandaPluginInfoEx"); - if (bpi == NULL) - return NULL; - - return bpi(mirandaVersion); -} - - -void GetInternetExplorerVersion(bkstring& buffer) -{ - HKEY hKey; - DWORD size; - - TCHAR ieVersion[1024] = {0}; - TCHAR ieBuild[512] = {0}; - TCHAR iVer[64] = {0}; - - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Internet Explorer"), 0, - KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) - { - size = sizeof(ieBuild)/sizeof(ieBuild[0]); - if (RegQueryValueEx(hKey, TEXT("Build"), NULL, NULL, (LPBYTE) ieBuild, &size) != ERROR_SUCCESS) - ieBuild[0] = 0; - - size = sizeof(ieVersion)/sizeof(ieVersion[0]); - if (RegQueryValueEx(hKey, TEXT("Version"), NULL, NULL, (LPBYTE) ieVersion, &size) != ERROR_SUCCESS) - ieVersion[0] = 0; - - size = sizeof(iVer)/sizeof(iVer[0]); - if (RegQueryValueEx(hKey, TEXT("IVer"), NULL, NULL, (LPBYTE) iVer, &size) != ERROR_SUCCESS) - iVer[0] = 0; - - RegCloseKey(hKey); - } - - buffer.append(TEXT("Internet Explorer: ")); - if (ieVersion[0] == 0) - { - if (iVer[0] == 0) - buffer.append(TEXT("")); - else if (_tcscmp(iVer, TEXT("100")) == 0) - buffer.append(TEXT("1.0")); - else if (_tcscmp(iVer, TEXT("101")) == 0) - buffer.append(TEXT("NT")); - else if (_tcscmp(iVer, TEXT("102")) == 0) - buffer.append(TEXT("2.0")); - else if (_tcscmp(iVer, TEXT("103")) == 0) - buffer.append(TEXT("3.0")); - } - else - { - buffer.append(ieVersion); - } - if (ieBuild[0] != 0) - { - buffer.appendfmt(TEXT(" (build %s)"), ieBuild); - } -} - - -void TrimMultiSpaces(TCHAR* str) -{ - TCHAR *src = str, *dest = str; - bool trimst = false; - - for (;;) - { - if (*src == TEXT(' ')) - { - if (!trimst) - { - trimst = true; - *dest++ = *src; - } - } - else - { - trimst = false; - *dest++ = *src; - } - if (*src++ == 0) break; - } -} - -void GetProcessorString(bkstring& buffer) -{ - HKEY hKey; - DWORD size; - - TCHAR cpuIdent[512] = {0}; - TCHAR cpuName[512] = {0}; - - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("Hardware\\Description\\System\\CentralProcessor\\0"), 0, - KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) - { - size = sizeof(cpuName)/sizeof(cpuName[0]); - if (RegQueryValueEx(hKey, TEXT("ProcessorNameString"), NULL, NULL, (LPBYTE) cpuName, &size) != ERROR_SUCCESS) - _tcscpy(cpuName, TEXT("Unknown")); - - size = sizeof(cpuIdent)/sizeof(cpuIdent[0]); - if (RegQueryValueEx(hKey, TEXT("Identifier"), NULL, NULL, (LPBYTE) cpuIdent, &size) != ERROR_SUCCESS) - if (RegQueryValueEx(hKey, TEXT("VendorIdentifier"), NULL, NULL, (LPBYTE) cpuIdent, &size) != ERROR_SUCCESS) - _tcscpy(cpuIdent, TEXT("Unknown")); - - RegCloseKey(hKey); - } - TrimMultiSpaces(cpuName); - buffer.appendfmt(TEXT("CPU: %s [%s]"), cpuName, cpuIdent); - - if (pIsProcessorFeaturePresent && pIsProcessorFeaturePresent(PF_NX_ENABLED)) - buffer.append(TEXT(" [DEP Enabled]")); - - SYSTEM_INFO si = {0}; - GetSystemInfo(&si); - - if (si.dwNumberOfProcessors > 1) - buffer.appendfmt(TEXT(" [%u CPUs]"), si.dwNumberOfProcessors); -} - -void GetFreeMemoryString(bkstring& buffer) -{ - unsigned ram; - if (pGlobalMemoryStatusEx) - { - MEMORYSTATUSEX ms = {0}; - ms.dwLength = sizeof(ms); - pGlobalMemoryStatusEx(&ms); - ram = (unsigned int) ((ms.ullTotalPhys / (1024 * 1024)) + 1); - } - else - { - MEMORYSTATUS ms = {0}; - ZeroMemory(&ms, sizeof(ms)); - ms.dwLength = sizeof(ms); - GlobalMemoryStatus(&ms); - ram = (unsigned int)(ms.dwTotalPhys/(1024*1024))+1; - } - buffer.appendfmt(TEXT("Installed RAM: %u MBytes"), ram); -} - -void GetFreeDiskString(LPCTSTR dirname, bkstring& buffer) -{ - ULARGE_INTEGER tnb, tfb, fs = {0}; - if (pGetDiskFreeSpaceEx) - pGetDiskFreeSpaceEx(dirname, &fs, &tnb, &tfb); - else - { - DWORD SectorsPerCluster, BytesPerSector; - DWORD NumberOfFreeClusters, TotalNumberOfClusters; - - GetDiskFreeSpace(dirname, &SectorsPerCluster, &BytesPerSector, - &NumberOfFreeClusters, &TotalNumberOfClusters); - - fs.QuadPart = BytesPerSector * SectorsPerCluster; - fs.QuadPart *= NumberOfFreeClusters; - } - fs.QuadPart /= (1024*1024); - - buffer.appendfmt(TEXT("Free disk space on Miranda partition: %u MBytes"), fs.LowPart); -} - -void ReadableExceptionInfo(PEXCEPTION_RECORD excrec, bkstring& buffer) -{ - buffer.append(TEXT("Exception: ")); - - switch (excrec->ExceptionCode) - { - case EXCEPTION_BREAKPOINT: - buffer.append(TEXT("User Defined Breakpoint")); - break; - - case EXCEPTION_ACCESS_VIOLATION: - buffer.append(TEXT("Access Violation")); - break; - - case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - buffer.append(TEXT("Array Bounds Exceeded")); - break; - - case EXCEPTION_DATATYPE_MISALIGNMENT: - buffer.append(TEXT("Datatype Misalignment")); - break; - - case EXCEPTION_FLT_DENORMAL_OPERAND: - buffer.append(TEXT("Floating Point denormlized operand")); - break; - - case EXCEPTION_FLT_DIVIDE_BY_ZERO: - buffer.append(TEXT("Floating Point divide by 0")); - break; - - case EXCEPTION_FLT_INEXACT_RESULT: - buffer.append(TEXT("Floating Point inexact result")); - break; - - case EXCEPTION_FLT_INVALID_OPERATION: - buffer.append(TEXT("Floating Point invalid operation")); - break; - - case EXCEPTION_FLT_OVERFLOW: - buffer.append(TEXT("Floating Point overflow")); - break; - - case EXCEPTION_FLT_STACK_CHECK: - buffer.append(TEXT("Floating Point stack overflow/underflow")); - break; - - case EXCEPTION_FLT_UNDERFLOW: - buffer.append(TEXT("Floating Point underflow")); - break; - - case EXCEPTION_ILLEGAL_INSTRUCTION: - buffer.append(TEXT("Invalid instruction executed")); - break; - - case EXCEPTION_IN_PAGE_ERROR: - buffer.append(TEXT("Access to the not present page")); - break; - - case EXCEPTION_INT_DIVIDE_BY_ZERO: - buffer.append(TEXT("Integer divide by zero")); - break; - - case EXCEPTION_INT_OVERFLOW: - buffer.append(TEXT("Integer overflow")); - break; - - case EXCEPTION_PRIV_INSTRUCTION: - buffer.append(TEXT("Priveleged instruction executed")); - break; - - case EXCEPTION_STACK_OVERFLOW: - buffer.append(TEXT("Stack overflow")); - break; - - case 0xe06d7363: - buffer.append(TEXT("Unhandled C++ software exception")); - break; - - default: - buffer.appendfmt(TEXT("%x"), excrec->ExceptionCode); - break; - } - - buffer.appendfmt(TEXT(" at address %p."), excrec->ExceptionAddress); - - if (excrec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION || - excrec->ExceptionCode == EXCEPTION_IN_PAGE_ERROR) - { - switch(excrec->ExceptionInformation[0]) - { - case 0: - buffer.appendfmt(TEXT(" Reading from address %p."), (LPVOID)excrec->ExceptionInformation[1]); - break; - - case 1: - buffer.appendfmt(TEXT(" Writing to address %p."), (LPVOID)excrec->ExceptionInformation[1]); - break; - - case 8: - buffer.appendfmt(TEXT(" DEP at address %p."), (LPVOID)excrec->ExceptionInformation[1]); - break; - } - } -} - -void GetAdminString(bkstring& buffer) -{ - BOOL b; - __try - { - SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; - PSID AdministratorsGroup; - - b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup); - if (b) - { - if (!CheckTokenMembership(NULL, AdministratorsGroup, &b)) - b = FALSE; - FreeSid(AdministratorsGroup); - } - else - b = GetLastError() == ERROR_CALL_NOT_IMPLEMENTED; - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - b = TRUE; - } - - buffer.appendfmt(TEXT("Administrator privileges: %s"), b ? TEXT("Yes") : TEXT ("No")); -} - -void GetLanguageString(bkstring& buffer) -{ - TCHAR name1[256], name2[256], name3[256], name4[256]; - - GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SENGLANGUAGE, name1, 256); - GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE, name2, 256); - - if (pGetUserDefaultUILanguage && pGetSystemDefaultUILanguage) - { - GetLocaleInfo(MAKELCID(pGetUserDefaultUILanguage(), SORT_DEFAULT), LOCALE_SENGLANGUAGE, name3, 256); - GetLocaleInfo(MAKELCID(pGetSystemDefaultUILanguage(), SORT_DEFAULT), LOCALE_SENGLANGUAGE, name4, 256); - } - else - { - _tcscpy(name3, name1); - _tcscpy(name4, name2); - } - - buffer.appendfmt(TEXT("OS Languages: (UI | Locale (User/System)) : %s/%s | %s/%s"), name3, name4, name1, name2); -} - -void GetLanguagePackString(bkstring& buffer) -{ - buffer.append(TEXT("Language pack: ")); - if (packlcid == LOCALE_USER_DEFAULT) - buffer.append(TEXT("No language pack installed")); - else - { - TCHAR path[MAX_PATH] = TEXT("Locale id invalid"); - GetLocaleInfo(packlcid, LOCALE_SENGLANGUAGE, path, MAX_PATH); - buffer.append(path); - - GetLocaleInfo(packlcid, LOCALE_SISO3166CTRYNAME, path, MAX_PATH); - buffer.appendfmt(TEXT(" (%s) [%04x]"), path, packlcid); - - GetModuleFileName(NULL, path, MAX_PATH); - - LPTSTR fname = _tcsrchr(path, TEXT('\\')); - if (fname == NULL) fname = path; - crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\langpack_*.txt")); - - WIN32_FIND_DATA FindFileData; - HANDLE hFind = FindFirstFile(path, &FindFileData); - if (hFind == INVALID_HANDLE_VALUE) return; - FindClose(hFind); - - crs_sntprintf(fname, MAX_PATH-(fname-path), TEXT("\\%s"), FindFileData.cFileName); - HANDLE hDumpFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (hDumpFile != INVALID_HANDLE_VALUE) - { - char buf[8192]; - - DWORD bytes = 0; - ReadFile(hDumpFile, buf, 8190, &bytes, NULL); - buf[bytes] = 0; - - char *id = strstr(buf, "FLID:"); - if (id != NULL) - { - char *endid = strchr(id, '\r'); - if (endid != NULL) *endid = 0; - - endid = strchr(id, '\n'); - if (endid != NULL) *endid = 0; - - TCHAR mirtime[30]; - GetLastWriteTime(path, mirtime, 30); - - TCHAR* tid; - crsi_a2t(tid, id+5); - buffer.appendfmt(TEXT(", %s, modified: %s"), tid, mirtime); - } - CloseHandle(hDumpFile); - } - } -} - -void GetWow64String(bkstring& buffer) -{ - BOOL wow64 = 0; - if (pIsWow64Process) - { - if (!pIsWow64Process(GetCurrentProcess(), &wow64)) - { - wow64 = 0; - } - } - if (wow64) buffer.append(TEXT(" [running inside WOW64]")); -} - - -bool CreateDirectoryTree(LPTSTR szDir) -{ - DWORD dwAttr = GetFileAttributes(szDir); - if (dwAttr != INVALID_FILE_ATTRIBUTES && (dwAttr & FILE_ATTRIBUTE_DIRECTORY)) - return true; - - TCHAR* pszSlash = _tcsrchr(szDir, TEXT('\\')); - if (pszSlash == NULL) - return false; - - *pszSlash = 0; - bool res = CreateDirectoryTree(szDir); - *pszSlash = TEXT('\\'); - - if (res) res = CreateDirectory(szDir, NULL) != 0; - - return res; -} - -int crs_sntprintf(TCHAR *buffer, size_t count, const TCHAR* fmt, ...) -{ - va_list va; - va_start(va, fmt); - - int len = _vsntprintf(buffer, count-1, fmt, va); - buffer[len] = 0; - - va_end(va); - return len; -} - -void GetVersionInfo(HMODULE hLib, bkstring& buffer) -{ - HRSRC hVersion = FindResource(hLib, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION); - if (hVersion != NULL) - { - HGLOBAL hGlobal = LoadResource(hLib, hVersion); - if (hGlobal != NULL) - { - LPVOID versionInfo = LockResource(hGlobal); - if (versionInfo != NULL) - { - int vl = *(unsigned short*)versionInfo; - unsigned *res = (unsigned*)versionInfo; - while (*res != 0xfeef04bd && ((char*)res - (char*)versionInfo) < vl) ++res; - - if (((char*)res - (char*)versionInfo) < vl) - { - VS_FIXEDFILEINFO *vsInfo = (VS_FIXEDFILEINFO*)res; - buffer.appendfmt(TEXT(" v.%u.%u.%u.%u"), - HIWORD(vsInfo->dwFileVersionMS), LOWORD(vsInfo->dwFileVersionMS), - HIWORD(vsInfo->dwFileVersionLS), LOWORD(vsInfo->dwFileVersionLS)); - } - } - FreeResource(hGlobal); - } - } -} - -void StoreStringToClip(bkstring& buffer) -{ - HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, buffer.sizebytes() + sizeof(TCHAR)); - LPSTR buf = (LPSTR)GlobalLock(hData); - - memcpy(buf, buffer.c_str(), buffer.sizebytes() + sizeof(TCHAR)); - - GlobalUnlock(hData); - - OpenClipboard(NULL); - EmptyClipboard(); - - - SetClipboardData(CF_UNICODETEXT, hData); - -} - -bool IsPluginEnabled(TCHAR* filename) -{ - char* fname; - crsi_t2a(fname, filename); - char* ext = strstr(_strlwr(fname), ".dll"); - bool res = ext && ext[4] == '\0' && DBGetContactSettingByte(NULL, "PluginDisable", fname, 0) == 0; - return res; -} diff --git a/plugins/CrashDumper/utils.h b/plugins/CrashDumper/utils.h deleted file mode 100644 index 9089f57571..0000000000 --- a/plugins/CrashDumper/utils.h +++ /dev/null @@ -1,177 +0,0 @@ -/* -Miranda Crash Dumper Plugin -Copyright (C) 2008 - 2012 Boris Krasnovskiy All Rights Reserved - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#define _CRT_SECURE_NO_WARNINGS -#define MIRANDA_VER 0x0A00 - -#include -#include "sdkstuff.h" - -#ifdef _MSC_VER -#include -#endif - -#include - -#include "resource.h" - -#include - -#ifdef _MSC_VER - -#pragma warning( push ) -#pragma warning( disable : 4201 4100 ) -#include -#pragma warning( pop ) - -#else - -#include - -#endif - -#ifdef __GNUC__ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "bkstring.h" - -#define MS_PROTO_ENUMPROTOS "Proto/EnumProtos" - -int crs_sntprintf(TCHAR *buffer, size_t count, const TCHAR* fmt, ...); - -#define crsi_u2a(dst, src) \ -{ \ - int cbLen = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL); \ - dst = (char*)alloca(cbLen+1); \ - WideCharToMultiByte(CP_ACP, 0, src, -1, dst, cbLen, NULL, NULL); \ -} - -#define crsi_a2u(dst, src, alloc) \ -{ \ - int cbLen = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0); \ - dst = (wchar_t*)alloc(sizeof(wchar_t) * (cbLen+1)); \ - MultiByteToWideChar(CP_ACP, 0, src, -1, dst, cbLen); \ -} - - - -#define crsi_t2a(d,s) crsi_u2a(d,s) -#define crsi_a2t(d,s) crsi_a2u(d,s,alloca) -#define crs_a2t(d,s) crsi_a2u(d,s,mir_alloc) - - - -#define SIZEOF(X) (sizeof(X)/sizeof(X[0])) - -#define MS_CRASHDUMPER_STORETOFILE "CrashDmp/StoreVerInfoToFile" -#define MS_CRASHDUMPER_STORETOCLIP "CrashDmp/StoreVerInfoToClip" -#define MS_CRASHDUMPER_GETINFO "Versioninfo/GetInfo" -#define MS_CRASHDUMPER_VIEWINFO "CrashDmp/ViewInfo" -#define MS_CRASHDUMPER_UPLOAD "CrashDmp/UploadInfo" -#define MS_CRASHDUMPER_URL "CrashDmp/StartUrl" - -#define PluginName "Crash Dumper" - -#define VI_FLAG_FORMAT 1 -#define VI_FLAG_PRNVAR 2 -#define VI_FLAG_PRNDLL 4 -#define VI_FLAG_WEATHER 8 - -struct VerTrnsfr -{ - char* buf; - bool autot; -}; - -extern HMODULE hInst; -extern DWORD mirandaVersion; -extern LCID packlcid; -extern bool servicemode; -extern bool clsdates; -extern bool dtsubfldr; - -extern TCHAR CrashLogFolder[MAX_PATH]; -extern TCHAR VersionInfoFolder[MAX_PATH]; - -void WriteBBFile(bkstring& buffer, bool hdr); -void WriteUtfFile(HANDLE hDumpFile, char* bufu); -void UnloadDbgHlp(void); - -LONG WINAPI myfilter(PEXCEPTION_POINTERS exc_ptr); -LONG WINAPI myfilterv(PEXCEPTION_POINTERS exc_ptr); -DWORD MirandaThreadFilter(DWORD code, EXCEPTION_POINTERS* info); - -void GetOSDisplayString(bkstring& buffer); -void GetInternetExplorerVersion(bkstring& buffer); -void GetProcessorString(bkstring& buffer); -void GetFreeMemoryString(bkstring& buffer); -void GetFreeDiskString(LPCTSTR dirname, bkstring& buffer); -void GetAdminString(bkstring& buffer); -void GetLanguageString(bkstring& buffer); -void GetLanguagePackString(bkstring& buffer); -void GetWow64String(bkstring& buffer); -void GetVersionInfo(HMODULE hLib, bkstring& buffer); - -void GetISO8061Time(SYSTEMTIME* stLocal, LPTSTR lpszString, DWORD dwSize); - -void ReadableExceptionInfo(PEXCEPTION_RECORD excrec, bkstring& buffer); - -void GetLastWriteTime(LPCTSTR fileName, LPTSTR lpszString, DWORD dwSize); -void GetLastWriteTime(FILETIME* ftime, LPTSTR lpszString, DWORD dwSize); -bool CreateDirectoryTree(LPTSTR szDir); -void StoreStringToClip(bkstring& buffer); -void ShowMessage(int type, const TCHAR* format, ...); -bool IsPluginEnabled(TCHAR* filename); - -PLUGININFOEX* GetMirInfo(HMODULE hModule); -const PLUGININFOEX* GetPluginInfoEx(void); - -void CreateMiniDump (HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr); -void CreateCrashReport(HANDLE hDumpFile, PEXCEPTION_POINTERS exc_ptr, const TCHAR* msg); -void PrintVersionInfo(bkstring& buffer, unsigned flags = VI_FLAG_PRNVAR); -bool ProcessVIHash(bool store); - -void InitExceptionHandler(void); -void DestroyExceptionHandler(void); -void SetExceptionHandler(void); -void RemoveExceptionHandler(void); -void CheckForOtherCrashReportingPlugins(void); - -INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK DlgProcView(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); -void DestroyAllWindows(void); - -void UploadInit(void); -void UploadClose(void); -void OpenAuthUrl(const char* url); -void __cdecl VersionInfoUploadThread(void* arg); - -void InitIcons(void); -HICON LoadIconEx(const char* name, bool big = false); -HANDLE GetIconHandle(const char* name); -void ReleaseIconEx(const char* name); -void ReleaseIconEx(HICON hIcon); diff --git a/plugins/CrashDumper/vc6/dbghelp.h b/plugins/CrashDumper/vc6/dbghelp.h deleted file mode 100644 index d8a713060b..0000000000 --- a/plugins/CrashDumper/vc6/dbghelp.h +++ /dev/null @@ -1,4532 +0,0 @@ -/*++ BUILD Version: 0000 Increment this if a change has global effects - -Copyright (c) Microsoft Corporation. All rights reserved. - -Module Name: - - dbghelp.h - -Abstract: - - This module defines the prototypes and constants required for the image - help routines. - - Contains debugging support routines that are redistributable. - -Revision History: - ---*/ - -#ifndef _DBGHELP_ -#define _DBGHELP_ - -#if _MSC_VER > 1020 -#pragma once -#endif - - -// As a general principal always call the 64 bit version -// of every API, if a choice exists. The 64 bit version -// works great on 32 bit platforms, and is forward -// compatible to 64 bit platforms. - -#ifdef _WIN64 -#ifndef _IMAGEHLP64 -#define _IMAGEHLP64 -#endif -#endif - -// For those without specstrings.h -// Since there are different versions of this header, I need to -// individually test each item and define it if it is not around. - -#ifndef __in - #define __in -#endif -#ifndef __out - #define __out -#endif -#ifndef __inout - #define __inout -#endif -#ifndef __in_opt - #define __in_opt -#endif -#ifndef __out_opt - #define __out_opt -#endif -#ifndef __inout_opt - #define __inout_opt -#endif -#ifndef __in_ecount - #define __in_ecount(x) -#endif -#ifndef __out_ecount - #define __out_ecount(x) -#endif -#ifndef __inout_ecount - #define __inout_ecount(x) -#endif -#ifndef __in_bcount - #define __in_bcount(x) -#endif -#ifndef __out_bcount - #define __out_bcount(x) -#endif -#ifndef __inout_bcount - #define __inout_bcount(x) -#endif -#ifndef __out_xcount - #define __out_xcount(x) -#endif -#ifndef __deref_opt_out - #define __deref_opt_out -#endif -#ifndef __deref_out - #define __deref_out -#endif -#ifndef __out_ecount_opt - #define __out_ecount_opt(x) -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _IMAGEHLP_SOURCE_ - #define IMAGEAPI __stdcall - #define DBHLP_DEPRECIATED -#else - #define IMAGEAPI DECLSPEC_IMPORT __stdcall - #if (_MSC_VER >= 1300) && !defined(MIDL_PASS) - #define DBHLP_DEPRECIATED __declspec(deprecated) - #else - #define DBHLP_DEPRECIATED - #endif -#endif - -#define DBHLPAPI IMAGEAPI - -#define IMAGE_SEPARATION (64*1024) - -// Observant readers may notice that 2 new fields, -// 'fReadOnly' and 'Version' have been added to -// the LOADED_IMAGE structure after 'fDOSImage'. -// This does not change the size of the structure -// from previous headers. That is because while -// 'fDOSImage' is a byte, it is padded by the -// compiler to 4 bytes. So the 2 new fields are -// slipped into the extra space. - -typedef struct _LOADED_IMAGE { - PSTR ModuleName; - HANDLE hFile; - PUCHAR MappedAddress; -#ifdef _IMAGEHLP64 - PIMAGE_NT_HEADERS64 FileHeader; -#else - PIMAGE_NT_HEADERS32 FileHeader; -#endif - PIMAGE_SECTION_HEADER LastRvaSection; - ULONG NumberOfSections; - PIMAGE_SECTION_HEADER Sections; - ULONG Characteristics; - BOOLEAN fSystemImage; - BOOLEAN fDOSImage; - BOOLEAN fReadOnly; - UCHAR Version; - LIST_ENTRY Links; - ULONG SizeOfImage; -} LOADED_IMAGE, *PLOADED_IMAGE; - -#define MAX_SYM_NAME 2000 - - -// Error codes set by dbghelp functions. Call GetLastError -// to see them. -// Dbghelp also sets error codes found in winerror.h - -#define ERROR_IMAGE_NOT_STRIPPED 0x8800 // the image is not stripped. No dbg file available. -#define ERROR_NO_DBG_POINTER 0x8801 // image is stripped but there is no pointer to a dbg file -#define ERROR_NO_PDB_POINTER 0x8802 // image does not point to a pdb file - -typedef BOOL -(CALLBACK *PFIND_DEBUG_FILE_CALLBACK)( - __in HANDLE FileHandle, - __in PCSTR FileName, - __in PVOID CallerData - ); - -HANDLE -IMAGEAPI -SymFindDebugInfoFile( - __in HANDLE hProcess, - __in PCSTR FileName, - __out_ecount(MAX_PATH + 1) PSTR DebugFilePath, - __in_opt PFIND_DEBUG_FILE_CALLBACK Callback, - __in_opt PVOID CallerData - ); - -typedef BOOL -(CALLBACK *PFIND_DEBUG_FILE_CALLBACKW)( - __in HANDLE FileHandle, - __in PCWSTR FileName, - __in PVOID CallerData - ); - -HANDLE -IMAGEAPI -SymFindDebugInfoFileW( - __in HANDLE hProcess, - __in PCWSTR FileName, - __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath, - __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback, - __in_opt PVOID CallerData - ); - -HANDLE -IMAGEAPI -FindDebugInfoFile ( - __in PCSTR FileName, - __in PCSTR SymbolPath, - __out_ecount(MAX_PATH + 1) PSTR DebugFilePath - ); - -HANDLE -IMAGEAPI -FindDebugInfoFileEx ( - __in PCSTR FileName, - __in PCSTR SymbolPath, - __out_ecount(MAX_PATH + 1) PSTR DebugFilePath, - __in_opt PFIND_DEBUG_FILE_CALLBACK Callback, - __in_opt PVOID CallerData - ); - -HANDLE -IMAGEAPI -FindDebugInfoFileExW ( - __in PCWSTR FileName, - __in PCWSTR SymbolPath, - __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath, - __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback, - __in_opt PVOID CallerData - ); - -typedef BOOL -(CALLBACK *PFINDFILEINPATHCALLBACK)( - PCSTR filename, - PVOID context - ); - -BOOL -IMAGEAPI -SymFindFileInPath( - __in HANDLE hprocess, - __in_opt PCSTR SearchPath, - __in PCSTR FileName, - __in_opt PVOID id, - __in DWORD two, - __in DWORD three, - __in DWORD flags, - __out_ecount(MAX_PATH + 1) PSTR FoundFile, - __in_opt PFINDFILEINPATHCALLBACK callback, - __in_opt PVOID context - ); - -typedef BOOL -(CALLBACK *PFINDFILEINPATHCALLBACKW)( - __in PCWSTR filename, - __in PVOID context - ); - -BOOL -IMAGEAPI -SymFindFileInPathW( - __in HANDLE hprocess, - __in_opt PCWSTR SearchPath, - __in PCWSTR FileName, - __in_opt PVOID id, - __in DWORD two, - __in DWORD three, - __in DWORD flags, - __out_ecount(MAX_PATH + 1) PWSTR FoundFile, - __in_opt PFINDFILEINPATHCALLBACKW callback, - __in_opt PVOID context - ); - -typedef BOOL -(CALLBACK *PFIND_EXE_FILE_CALLBACK)( - __in HANDLE FileHandle, - __in PCSTR FileName, - __in_opt PVOID CallerData - ); - -HANDLE -IMAGEAPI -SymFindExecutableImage( - __in HANDLE hProcess, - __in PCSTR FileName, - __out_ecount(MAX_PATH + 1) PSTR ImageFilePath, - __in PFIND_EXE_FILE_CALLBACK Callback, - __in PVOID CallerData - ); - -typedef BOOL -(CALLBACK *PFIND_EXE_FILE_CALLBACKW)( - __in HANDLE FileHandle, - __in PCWSTR FileName, - __in_opt PVOID CallerData - ); - -HANDLE -IMAGEAPI -SymFindExecutableImageW( - __in HANDLE hProcess, - __in PCWSTR FileName, - __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath, - __in PFIND_EXE_FILE_CALLBACKW Callback, - __in PVOID CallerData - ); - -HANDLE -IMAGEAPI -FindExecutableImage( - __in PCSTR FileName, - __in PCSTR SymbolPath, - __out_ecount(MAX_PATH + 1) PSTR ImageFilePath - ); - -HANDLE -IMAGEAPI -FindExecutableImageEx( - __in PCSTR FileName, - __in PCSTR SymbolPath, - __out_ecount(MAX_PATH + 1) PSTR ImageFilePath, - __in_opt PFIND_EXE_FILE_CALLBACK Callback, - __in_opt PVOID CallerData - ); - -HANDLE -IMAGEAPI -FindExecutableImageExW( - __in PCWSTR FileName, - __in PCWSTR SymbolPath, - __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath, - __in_opt PFIND_EXE_FILE_CALLBACKW Callback, - __in PVOID CallerData - ); - -PIMAGE_NT_HEADERS -IMAGEAPI -ImageNtHeader ( - __in PVOID Base - ); - -PVOID -IMAGEAPI -ImageDirectoryEntryToDataEx ( - __in PVOID Base, - __in BOOLEAN MappedAsImage, - __in USHORT DirectoryEntry, - __out PULONG Size, - __out_opt PIMAGE_SECTION_HEADER *FoundHeader - ); - -PVOID -IMAGEAPI -ImageDirectoryEntryToData ( - __in PVOID Base, - __in BOOLEAN MappedAsImage, - __in USHORT DirectoryEntry, - __out PULONG Size - ); - -PIMAGE_SECTION_HEADER -IMAGEAPI -ImageRvaToSection( - __in PIMAGE_NT_HEADERS NtHeaders, - __in PVOID Base, - __in ULONG Rva - ); - -PVOID -IMAGEAPI -ImageRvaToVa( - __in PIMAGE_NT_HEADERS NtHeaders, - __in PVOID Base, - __in ULONG Rva, - __in_opt OUT PIMAGE_SECTION_HEADER *LastRvaSection - ); - -#ifndef _WIN64 -// This api won't be ported to Win64 - Fix your code. - -typedef struct _IMAGE_DEBUG_INFORMATION { - LIST_ENTRY List; - DWORD ReservedSize; - PVOID ReservedMappedBase; - USHORT ReservedMachine; - USHORT ReservedCharacteristics; - DWORD ReservedCheckSum; - DWORD ImageBase; - DWORD SizeOfImage; - - DWORD ReservedNumberOfSections; - PIMAGE_SECTION_HEADER ReservedSections; - - DWORD ReservedExportedNamesSize; - PSTR ReservedExportedNames; - - DWORD ReservedNumberOfFunctionTableEntries; - PIMAGE_FUNCTION_ENTRY ReservedFunctionTableEntries; - DWORD ReservedLowestFunctionStartingAddress; - DWORD ReservedHighestFunctionEndingAddress; - - DWORD ReservedNumberOfFpoTableEntries; - PFPO_DATA ReservedFpoTableEntries; - - DWORD SizeOfCoffSymbols; - PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols; - - DWORD ReservedSizeOfCodeViewSymbols; - PVOID ReservedCodeViewSymbols; - - PSTR ImageFilePath; - PSTR ImageFileName; - PSTR ReservedDebugFilePath; - - DWORD ReservedTimeDateStamp; - - BOOL ReservedRomImage; - PIMAGE_DEBUG_DIRECTORY ReservedDebugDirectory; - DWORD ReservedNumberOfDebugDirectories; - - DWORD ReservedOriginalFunctionTableBaseAddress; - - DWORD Reserved[ 2 ]; - -} IMAGE_DEBUG_INFORMATION, *PIMAGE_DEBUG_INFORMATION; - - -PIMAGE_DEBUG_INFORMATION -IMAGEAPI -MapDebugInformation( - __in_opt HANDLE FileHandle, - __in PCSTR FileName, - __in_opt PCSTR SymbolPath, - __in ULONG ImageBase - ); - -BOOL -IMAGEAPI -UnmapDebugInformation( - __out_xcount(unknown) PIMAGE_DEBUG_INFORMATION DebugInfo - ); - -#endif - -BOOL -IMAGEAPI -SearchTreeForFile( - __in PCSTR RootPath, - __in PCSTR InputPathName, - __out_ecount(MAX_PATH + 1) PSTR OutputPathBuffer - ); - -BOOL -IMAGEAPI -SearchTreeForFileW( - __in PCWSTR RootPath, - __in PCWSTR InputPathName, - __out_ecount(MAX_PATH + 1) PWSTR OutputPathBuffer - ); - -typedef BOOL -(CALLBACK *PENUMDIRTREE_CALLBACK)( - __in PCSTR FilePath, - __in_opt PVOID CallerData - ); - -BOOL -IMAGEAPI -EnumDirTree( - __in_opt HANDLE hProcess, - __in PCSTR RootPath, - __in PCSTR InputPathName, - __out_ecount_opt(MAX_PATH + 1) PSTR OutputPathBuffer, - __in_opt PENUMDIRTREE_CALLBACK cb, - __in_opt PVOID data - ); - -typedef BOOL -(CALLBACK *PENUMDIRTREE_CALLBACKW)( - __in PCWSTR FilePath, - __in_opt PVOID CallerData - ); - -BOOL -IMAGEAPI -EnumDirTreeW( - __in_opt HANDLE hProcess, - __in PCWSTR RootPath, - __in PCWSTR InputPathName, - __out_ecount_opt(MAX_PATH + 1) PWSTR OutputPathBuffer, - __in_opt PENUMDIRTREE_CALLBACKW cb, - __in_opt PVOID data - ); - -BOOL -IMAGEAPI -MakeSureDirectoryPathExists( - __in PCSTR DirPath - ); - -// -// UnDecorateSymbolName Flags -// - -#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration -#define UNDNAME_NO_LEADING_UNDERSCORES (0x0001) // Remove leading underscores from MS extended keywords -#define UNDNAME_NO_MS_KEYWORDS (0x0002) // Disable expansion of MS extended keywords -#define UNDNAME_NO_FUNCTION_RETURNS (0x0004) // Disable expansion of return type for primary declaration -#define UNDNAME_NO_ALLOCATION_MODEL (0x0008) // Disable expansion of the declaration model -#define UNDNAME_NO_ALLOCATION_LANGUAGE (0x0010) // Disable expansion of the declaration language specifier -#define UNDNAME_NO_MS_THISTYPE (0x0020) // NYI Disable expansion of MS keywords on the 'this' type for primary declaration -#define UNDNAME_NO_CV_THISTYPE (0x0040) // NYI Disable expansion of CV modifiers on the 'this' type for primary declaration -#define UNDNAME_NO_THISTYPE (0x0060) // Disable all modifiers on the 'this' type -#define UNDNAME_NO_ACCESS_SPECIFIERS (0x0080) // Disable expansion of access specifiers for members -#define UNDNAME_NO_THROW_SIGNATURES (0x0100) // Disable expansion of 'throw-signatures' for functions and pointers to functions -#define UNDNAME_NO_MEMBER_TYPE (0x0200) // Disable expansion of 'static' or 'virtual'ness of members -#define UNDNAME_NO_RETURN_UDT_MODEL (0x0400) // Disable expansion of MS model for UDT returns -#define UNDNAME_32_BIT_DECODE (0x0800) // Undecorate 32-bit decorated names -#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration; - // return just [scope::]name. Does expand template params -#define UNDNAME_NO_ARGUMENTS (0x2000) // Don't undecorate arguments to function -#define UNDNAME_NO_SPECIAL_SYMS (0x4000) // Don't undecorate special names (v-table, vcall, vector xxx, metatype, etc) - -DWORD -IMAGEAPI -WINAPI -UnDecorateSymbolName( - __in PCSTR name, - __out_ecount(maxStringLength) PSTR outputString, - __in DWORD maxStringLength, - __in DWORD flags - ); - -DWORD -IMAGEAPI -WINAPI -UnDecorateSymbolNameW( - __in PCWSTR name, - __out_ecount(maxStringLength) PWSTR outputString, - __in DWORD maxStringLength, - __in DWORD flags - ); - -// -// these values are used for synthesized file types -// that can be passed in as image headers instead of -// the standard ones from ntimage.h -// - -#define DBHHEADER_DEBUGDIRS 0x1 -#define DBHHEADER_CVMISC 0x2 - -typedef struct _MODLOAD_DATA { - DWORD ssize; // size of this struct - DWORD ssig; // signature identifying the passed data - PVOID data; // pointer to passed data - DWORD size; // size of passed data - DWORD flags; // options -} MODLOAD_DATA, *PMODLOAD_DATA; - -typedef struct _MODLOAD_CVMISC { - DWORD oCV; // ofset to the codeview record - size_t cCV; // size of the codeview record - DWORD oMisc; // offset to the misc record - size_t cMisc; // size of the misc record - DWORD dtImage; // datetime stamp of the image - DWORD cImage; // size of the image -} MODLOAD_CVMISC, *PMODLOAD_CVMISC; - -// -// StackWalking API -// - -typedef enum { - AddrMode1616, - AddrMode1632, - AddrModeReal, - AddrModeFlat -} ADDRESS_MODE; - -typedef struct _tagADDRESS64 { - DWORD64 Offset; - WORD Segment; - ADDRESS_MODE Mode; -} ADDRESS64, *LPADDRESS64; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define ADDRESS ADDRESS64 -#define LPADDRESS LPADDRESS64 -#else -typedef struct _tagADDRESS { - DWORD Offset; - WORD Segment; - ADDRESS_MODE Mode; -} ADDRESS, *LPADDRESS; - -__inline -void -Address32To64( - __in LPADDRESS a32, - __out LPADDRESS64 a64 - ) -{ - a64->Offset = (ULONG64)(LONG64)(LONG)a32->Offset; - a64->Segment = a32->Segment; - a64->Mode = a32->Mode; -} - -__inline -void -Address64To32( - __in LPADDRESS64 a64, - __out LPADDRESS a32 - ) -{ - a32->Offset = (ULONG)a64->Offset; - a32->Segment = a64->Segment; - a32->Mode = a64->Mode; -} -#endif - -// -// This structure is included in the STACKFRAME structure, -// and is used to trace through usermode callbacks in a thread's -// kernel stack. The values must be copied by the kernel debugger -// from the DBGKD_GET_VERSION and WAIT_STATE_CHANGE packets. -// - -// -// New KDHELP structure for 64 bit system support. -// This structure is preferred in new code. -// -typedef struct _KDHELP64 { - - // - // address of kernel thread object, as provided in the - // WAIT_STATE_CHANGE packet. - // - DWORD64 Thread; - - // - // offset in thread object to pointer to the current callback frame - // in kernel stack. - // - DWORD ThCallbackStack; - - // - // offset in thread object to pointer to the current callback backing - // store frame in kernel stack. - // - DWORD ThCallbackBStore; - - // - // offsets to values in frame: - // - // address of next callback frame - DWORD NextCallback; - - // address of saved frame pointer (if applicable) - DWORD FramePointer; - - - // - // Address of the kernel function that calls out to user mode - // - DWORD64 KiCallUserMode; - - // - // Address of the user mode dispatcher function - // - DWORD64 KeUserCallbackDispatcher; - - // - // Lowest kernel mode address - // - DWORD64 SystemRangeStart; - - // - // Address of the user mode exception dispatcher function. - // Added in API version 10. - // - DWORD64 KiUserExceptionDispatcher; - - // - // Stack bounds, added in API version 11. - // - DWORD64 StackBase; - DWORD64 StackLimit; - - DWORD64 Reserved[5]; - -} KDHELP64, *PKDHELP64; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define KDHELP KDHELP64 -#define PKDHELP PKDHELP64 -#else -typedef struct _KDHELP { - - // - // address of kernel thread object, as provided in the - // WAIT_STATE_CHANGE packet. - // - DWORD Thread; - - // - // offset in thread object to pointer to the current callback frame - // in kernel stack. - // - DWORD ThCallbackStack; - - // - // offsets to values in frame: - // - // address of next callback frame - DWORD NextCallback; - - // address of saved frame pointer (if applicable) - DWORD FramePointer; - - // - // Address of the kernel function that calls out to user mode - // - DWORD KiCallUserMode; - - // - // Address of the user mode dispatcher function - // - DWORD KeUserCallbackDispatcher; - - // - // Lowest kernel mode address - // - DWORD SystemRangeStart; - - // - // offset in thread object to pointer to the current callback backing - // store frame in kernel stack. - // - DWORD ThCallbackBStore; - - // - // Address of the user mode exception dispatcher function. - // Added in API version 10. - // - DWORD KiUserExceptionDispatcher; - - // - // Stack bounds, added in API version 11. - // - DWORD StackBase; - DWORD StackLimit; - - DWORD Reserved[5]; - -} KDHELP, *PKDHELP; - -__inline -void -KdHelp32To64( - __in PKDHELP p32, - __out PKDHELP64 p64 - ) -{ - p64->Thread = p32->Thread; - p64->ThCallbackStack = p32->ThCallbackStack; - p64->NextCallback = p32->NextCallback; - p64->FramePointer = p32->FramePointer; - p64->KiCallUserMode = p32->KiCallUserMode; - p64->KeUserCallbackDispatcher = p32->KeUserCallbackDispatcher; - p64->SystemRangeStart = p32->SystemRangeStart; - p64->KiUserExceptionDispatcher = p32->KiUserExceptionDispatcher; - p64->StackBase = p32->StackBase; - p64->StackLimit = p32->StackLimit; -} -#endif - -typedef struct _tagSTACKFRAME64 { - ADDRESS64 AddrPC; // program counter - ADDRESS64 AddrReturn; // return address - ADDRESS64 AddrFrame; // frame pointer - ADDRESS64 AddrStack; // stack pointer - ADDRESS64 AddrBStore; // backing store pointer - PVOID FuncTableEntry; // pointer to pdata/fpo or NULL - DWORD64 Params[4]; // possible arguments to the function - BOOL Far; // WOW far call - BOOL Virtual; // is this a virtual frame? - DWORD64 Reserved[3]; - KDHELP64 KdHelp; -} STACKFRAME64, *LPSTACKFRAME64; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define STACKFRAME STACKFRAME64 -#define LPSTACKFRAME LPSTACKFRAME64 -#else -typedef struct _tagSTACKFRAME { - ADDRESS AddrPC; // program counter - ADDRESS AddrReturn; // return address - ADDRESS AddrFrame; // frame pointer - ADDRESS AddrStack; // stack pointer - PVOID FuncTableEntry; // pointer to pdata/fpo or NULL - DWORD Params[4]; // possible arguments to the function - BOOL Far; // WOW far call - BOOL Virtual; // is this a virtual frame? - DWORD Reserved[3]; - KDHELP KdHelp; - ADDRESS AddrBStore; // backing store pointer -} STACKFRAME, *LPSTACKFRAME; -#endif - - -typedef -BOOL -(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)( - __in HANDLE hProcess, - __in DWORD64 qwBaseAddress, - __out_bcount(nSize) PVOID lpBuffer, - __in DWORD nSize, - __out LPDWORD lpNumberOfBytesRead - ); - -typedef -PVOID -(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( - __in HANDLE ahProcess, - __in DWORD64 AddrBase - ); - -typedef -DWORD64 -(__stdcall *PGET_MODULE_BASE_ROUTINE64)( - __in HANDLE hProcess, - __in DWORD64 Address - ); - -typedef -DWORD64 -(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)( - __in HANDLE hProcess, - __in HANDLE hThread, - __in LPADDRESS64 lpaddr - ); - -BOOL -IMAGEAPI -StackWalk64( - __in DWORD MachineType, - __in HANDLE hProcess, - __in HANDLE hThread, - __inout LPSTACKFRAME64 StackFrame, - __inout PVOID ContextRecord, - __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, - __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, - __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, - __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) - -#define PREAD_PROCESS_MEMORY_ROUTINE PREAD_PROCESS_MEMORY_ROUTINE64 -#define PFUNCTION_TABLE_ACCESS_ROUTINE PFUNCTION_TABLE_ACCESS_ROUTINE64 -#define PGET_MODULE_BASE_ROUTINE PGET_MODULE_BASE_ROUTINE64 -#define PTRANSLATE_ADDRESS_ROUTINE PTRANSLATE_ADDRESS_ROUTINE64 - -#define StackWalk StackWalk64 - -#else - -typedef -BOOL -(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE)( - __in HANDLE hProcess, - __in DWORD lpBaseAddress, - __out_bcount(nSize) PVOID lpBuffer, - __in DWORD nSize, - __out PDWORD lpNumberOfBytesRead - ); - -typedef -PVOID -(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE)( - __in HANDLE hProcess, - __in DWORD AddrBase - ); - -typedef -DWORD -(__stdcall *PGET_MODULE_BASE_ROUTINE)( - __in HANDLE hProcess, - __in DWORD Address - ); - -typedef -DWORD -(__stdcall *PTRANSLATE_ADDRESS_ROUTINE)( - __in HANDLE hProcess, - __in HANDLE hThread, - __out LPADDRESS lpaddr - ); - -BOOL -IMAGEAPI -StackWalk( - DWORD MachineType, - __in HANDLE hProcess, - __in HANDLE hThread, - __inout LPSTACKFRAME StackFrame, - __inout PVOID ContextRecord, - __in_opt PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, - __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, - __in_opt PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, - __in_opt PTRANSLATE_ADDRESS_ROUTINE TranslateAddress - ); - -#endif - - -#define API_VERSION_NUMBER 11 - -typedef struct API_VERSION { - USHORT MajorVersion; - USHORT MinorVersion; - USHORT Revision; - USHORT Reserved; -} API_VERSION, *LPAPI_VERSION; - -LPAPI_VERSION -IMAGEAPI -ImagehlpApiVersion( - VOID - ); - -LPAPI_VERSION -IMAGEAPI -ImagehlpApiVersionEx( - __in LPAPI_VERSION AppVersion - ); - -DWORD -IMAGEAPI -GetTimestampForLoadedLibrary( - __in HMODULE Module - ); - -// -// typedefs for function pointers -// -typedef BOOL -(CALLBACK *PSYM_ENUMMODULES_CALLBACK64)( - __in PCSTR ModuleName, - __in DWORD64 BaseOfDll, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PSYM_ENUMMODULES_CALLBACKW64)( - __in PCWSTR ModuleName, - __in DWORD64 BaseOfDll, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PENUMLOADED_MODULES_CALLBACK64)( - __in PCSTR ModuleName, - __in DWORD64 ModuleBase, - __in ULONG ModuleSize, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PENUMLOADED_MODULES_CALLBACKW64)( - __in PCWSTR ModuleName, - __in DWORD64 ModuleBase, - __in ULONG ModuleSize, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64)( - __in PCSTR SymbolName, - __in DWORD64 SymbolAddress, - __in ULONG SymbolSize, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64W)( - __in PCWSTR SymbolName, - __in DWORD64 SymbolAddress, - __in ULONG SymbolSize, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PSYMBOL_REGISTERED_CALLBACK64)( - __in HANDLE hProcess, - __in ULONG ActionCode, - __in_opt ULONG64 CallbackData, - __in_opt ULONG64 UserContext - ); - -typedef -PVOID -(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK)( - __in HANDLE hProcess, - __in DWORD AddrBase, - __in_opt PVOID UserContext - ); - -typedef -PVOID -(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK64)( - __in HANDLE hProcess, - __in ULONG64 AddrBase, - __in ULONG64 UserContext - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) - -#define PSYM_ENUMMODULES_CALLBACK PSYM_ENUMMODULES_CALLBACK64 -#define PSYM_ENUMSYMBOLS_CALLBACK PSYM_ENUMSYMBOLS_CALLBACK64 -#define PSYM_ENUMSYMBOLS_CALLBACKW PSYM_ENUMSYMBOLS_CALLBACK64W -#define PENUMLOADED_MODULES_CALLBACK PENUMLOADED_MODULES_CALLBACK64 -#define PSYMBOL_REGISTERED_CALLBACK PSYMBOL_REGISTERED_CALLBACK64 -#define PSYMBOL_FUNCENTRY_CALLBACK PSYMBOL_FUNCENTRY_CALLBACK64 - -#else - -typedef BOOL -(CALLBACK *PSYM_ENUMMODULES_CALLBACK)( - __in PCSTR ModuleName, - __in ULONG BaseOfDll, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK)( - __in PCSTR SymbolName, - __in ULONG SymbolAddress, - __in ULONG SymbolSize, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACKW)( - __in PCWSTR SymbolName, - __in ULONG SymbolAddress, - __in ULONG SymbolSize, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PENUMLOADED_MODULES_CALLBACK)( - __in PCSTR ModuleName, - __in ULONG ModuleBase, - __in ULONG ModuleSize, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PSYMBOL_REGISTERED_CALLBACK)( - __in HANDLE hProcess, - __in ULONG ActionCode, - __in_opt PVOID CallbackData, - __in_opt PVOID UserContext - ); - -#endif - - -// values found in SYMBOL_INFO.Tag -// -// This was taken from cvconst.h and should -// not override any values found there. -// -// #define _NO_CVCONST_H_ if you don't -// have access to that file... - -#ifdef _NO_CVCONST_H - -// DIA enums - -enum SymTagEnum -{ - SymTagNull, - SymTagExe, - SymTagCompiland, - SymTagCompilandDetails, - SymTagCompilandEnv, - SymTagFunction, - SymTagBlock, - SymTagData, - SymTagAnnotation, - SymTagLabel, - SymTagPublicSymbol, - SymTagUDT, - SymTagEnum, - SymTagFunctionType, - SymTagPointerType, - SymTagArrayType, - SymTagBaseType, - SymTagTypedef, - SymTagBaseClass, - SymTagFriend, - SymTagFunctionArgType, - SymTagFuncDebugStart, - SymTagFuncDebugEnd, - SymTagUsingNamespace, - SymTagVTableShape, - SymTagVTable, - SymTagCustom, - SymTagThunk, - SymTagCustomType, - SymTagManagedType, - SymTagDimension, - SymTagMax -}; - -#endif - -// -// flags found in SYMBOL_INFO.Flags -// - -#define SYMFLAG_VALUEPRESENT 0x00000001 -#define SYMFLAG_REGISTER 0x00000008 -#define SYMFLAG_REGREL 0x00000010 -#define SYMFLAG_FRAMEREL 0x00000020 -#define SYMFLAG_PARAMETER 0x00000040 -#define SYMFLAG_LOCAL 0x00000080 -#define SYMFLAG_CONSTANT 0x00000100 -#define SYMFLAG_EXPORT 0x00000200 -#define SYMFLAG_FORWARDER 0x00000400 -#define SYMFLAG_FUNCTION 0x00000800 -#define SYMFLAG_VIRTUAL 0x00001000 -#define SYMFLAG_THUNK 0x00002000 -#define SYMFLAG_TLSREL 0x00004000 -#define SYMFLAG_SLOT 0x00008000 -#define SYMFLAG_ILREL 0x00010000 -#define SYMFLAG_METADATA 0x00020000 -#define SYMFLAG_CLR_TOKEN 0x00040000 - -// this resets SymNext/Prev to the beginning -// of the module passed in the address field - -#define SYMFLAG_RESET 0x80000000 - -// -// symbol type enumeration -// -typedef enum { - SymNone = 0, - SymCoff, - SymCv, - SymPdb, - SymExport, - SymDeferred, - SymSym, // .sym file - SymDia, - SymVirtual, - NumSymTypes -} SYM_TYPE; - -// -// symbol data structure -// - -typedef struct _IMAGEHLP_SYMBOL64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64) - DWORD64 Address; // virtual address including dll base address - DWORD Size; // estimated size of symbol, can be zero - DWORD Flags; // info about the symbols, see the SYMF defines - DWORD MaxNameLength; // maximum size of symbol name in 'Name' - CHAR Name[1]; // symbol name (null terminated string) -} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; - -typedef struct _IMAGEHLP_SYMBOL64_PACKAGE { - IMAGEHLP_SYMBOL64 sym; - CHAR name[MAX_SYM_NAME + 1]; -} IMAGEHLP_SYMBOL64_PACKAGE, *PIMAGEHLP_SYMBOL64_PACKAGE; - -typedef struct _IMAGEHLP_SYMBOLW64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOLW64) - DWORD64 Address; // virtual address including dll base address - DWORD Size; // estimated size of symbol, can be zero - DWORD Flags; // info about the symbols, see the SYMF defines - DWORD MaxNameLength; // maximum size of symbol name in 'Name' - WCHAR Name[1]; // symbol name (null terminated string) -} IMAGEHLP_SYMBOLW64, *PIMAGEHLP_SYMBOLW64; - -typedef struct _IMAGEHLP_SYMBOLW64_PACKAGE { - IMAGEHLP_SYMBOLW64 sym; - WCHAR name[MAX_SYM_NAME + 1]; -} IMAGEHLP_SYMBOLW64_PACKAGE, *PIMAGEHLP_SYMBOLW64_PACKAGE; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) - - #define IMAGEHLP_SYMBOL IMAGEHLP_SYMBOL64 - #define PIMAGEHLP_SYMBOL PIMAGEHLP_SYMBOL64 - #define IMAGEHLP_SYMBOL_PACKAGE IMAGEHLP_SYMBOL64_PACKAGE - #define PIMAGEHLP_SYMBOL_PACKAGE PIMAGEHLP_SYMBOL64_PACKAGE - #define IMAGEHLP_SYMBOLW IMAGEHLP_SYMBOLW64 - #define PIMAGEHLP_SYMBOLW PIMAGEHLP_SYMBOLW64 - #define IMAGEHLP_SYMBOLW_PACKAGE IMAGEHLP_SYMBOLW64_PACKAGE - #define PIMAGEHLP_SYMBOLW_PACKAGE PIMAGEHLP_SYMBOLW64_PACKAGE - -#else - - typedef struct _IMAGEHLP_SYMBOL { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL) - DWORD Address; // virtual address including dll base address - DWORD Size; // estimated size of symbol, can be zero - DWORD Flags; // info about the symbols, see the SYMF defines - DWORD MaxNameLength; // maximum size of symbol name in 'Name' - CHAR Name[1]; // symbol name (null terminated string) - } IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL; - - typedef struct _IMAGEHLP_SYMBOL_PACKAGE { - IMAGEHLP_SYMBOL sym; - CHAR name[MAX_SYM_NAME + 1]; - } IMAGEHLP_SYMBOL_PACKAGE, *PIMAGEHLP_SYMBOL_PACKAGE; - - typedef struct _IMAGEHLP_SYMBOLW { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOLW) - DWORD Address; // virtual address including dll base address - DWORD Size; // estimated size of symbol, can be zero - DWORD Flags; // info about the symbols, see the SYMF defines - DWORD MaxNameLength; // maximum size of symbol name in 'Name' - WCHAR Name[1]; // symbol name (null terminated string) - } IMAGEHLP_SYMBOLW, *PIMAGEHLP_SYMBOLW; - - typedef struct _IMAGEHLP_SYMBOLW_PACKAGE { - IMAGEHLP_SYMBOLW sym; - WCHAR name[MAX_SYM_NAME + 1]; - } IMAGEHLP_SYMBOLW_PACKAGE, *PIMAGEHLP_SYMBOLW_PACKAGE; - -#endif - -// -// module data structure -// - -typedef struct _IMAGEHLP_MODULE64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) - DWORD64 BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - CHAR ModuleName[32]; // module name - CHAR ImageName[256]; // image name - CHAR LoadedImageName[256]; // symbol file name - // new elements: 07-Jun-2002 - CHAR LoadedPdbName[256]; // pdb file name - DWORD CVSig; // Signature of the CV record in the debug directories - CHAR CVData[MAX_PATH * 3]; // Contents of the CV record - DWORD PdbSig; // Signature of PDB - GUID PdbSig70; // Signature of PDB (VC 7 and up) - DWORD PdbAge; // DBI age of pdb - BOOL PdbUnmatched; // loaded an unmatched pdb - BOOL DbgUnmatched; // loaded an unmatched dbg - BOOL LineNumbers; // we have line number information - BOOL GlobalSymbols; // we have internal symbol information - BOOL TypeInfo; // we have type information - // new elements: 17-Dec-2003 - BOOL SourceIndexed; // pdb supports source server - BOOL Publics; // contains public symbols -} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; - -typedef struct _IMAGEHLP_MODULEW64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) - DWORD64 BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - WCHAR ModuleName[32]; // module name - WCHAR ImageName[256]; // image name - // new elements: 07-Jun-2002 - WCHAR LoadedImageName[256]; // symbol file name - WCHAR LoadedPdbName[256]; // pdb file name - DWORD CVSig; // Signature of the CV record in the debug directories - WCHAR CVData[MAX_PATH * 3]; // Contents of the CV record - DWORD PdbSig; // Signature of PDB - GUID PdbSig70; // Signature of PDB (VC 7 and up) - DWORD PdbAge; // DBI age of pdb - BOOL PdbUnmatched; // loaded an unmatched pdb - BOOL DbgUnmatched; // loaded an unmatched dbg - BOOL LineNumbers; // we have line number information - BOOL GlobalSymbols; // we have internal symbol information - BOOL TypeInfo; // we have type information - // new elements: 17-Dec-2003 - BOOL SourceIndexed; // pdb supports source server - BOOL Publics; // contains public symbols -} IMAGEHLP_MODULEW64, *PIMAGEHLP_MODULEW64; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define IMAGEHLP_MODULE IMAGEHLP_MODULE64 -#define PIMAGEHLP_MODULE PIMAGEHLP_MODULE64 -#define IMAGEHLP_MODULEW IMAGEHLP_MODULEW64 -#define PIMAGEHLP_MODULEW PIMAGEHLP_MODULEW64 -#else -typedef struct _IMAGEHLP_MODULE { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE) - DWORD BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - CHAR ModuleName[32]; // module name - CHAR ImageName[256]; // image name - CHAR LoadedImageName[256]; // symbol file name -} IMAGEHLP_MODULE, *PIMAGEHLP_MODULE; - -typedef struct _IMAGEHLP_MODULEW { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE) - DWORD BaseOfImage; // base load address of module - DWORD ImageSize; // virtual size of the loaded module - DWORD TimeDateStamp; // date/time stamp from pe header - DWORD CheckSum; // checksum from the pe header - DWORD NumSyms; // number of symbols in the symbol table - SYM_TYPE SymType; // type of symbols loaded - WCHAR ModuleName[32]; // module name - WCHAR ImageName[256]; // image name - WCHAR LoadedImageName[256]; // symbol file name -} IMAGEHLP_MODULEW, *PIMAGEHLP_MODULEW; -#endif - -// -// source file line data structure -// - -typedef struct _IMAGEHLP_LINE64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) - PVOID Key; // internal - DWORD LineNumber; // line number in file - PCHAR FileName; // full filename - DWORD64 Address; // first instruction of line -} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; - -typedef struct _IMAGEHLP_LINEW64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) - PVOID Key; // internal - DWORD LineNumber; // line number in file - PWSTR FileName; // full filename - DWORD64 Address; // first instruction of line -} IMAGEHLP_LINEW64, *PIMAGEHLP_LINEW64; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define IMAGEHLP_LINE IMAGEHLP_LINE64 -#define PIMAGEHLP_LINE PIMAGEHLP_LINE64 -#else -typedef struct _IMAGEHLP_LINE { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE) - PVOID Key; // internal - DWORD LineNumber; // line number in file - PCHAR FileName; // full filename - DWORD Address; // first instruction of line -} IMAGEHLP_LINE, *PIMAGEHLP_LINE; - -typedef struct _IMAGEHLP_LINEW { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) - PVOID Key; // internal - DWORD LineNumber; // line number in file - PCHAR FileName; // full filename - DWORD64 Address; // first instruction of line -} IMAGEHLP_LINEW, *PIMAGEHLP_LINEW; -#endif - -// -// source file structure -// - -typedef struct _SOURCEFILE { - DWORD64 ModBase; // base address of loaded module - PCHAR FileName; // full filename of source -} SOURCEFILE, *PSOURCEFILE; - -typedef struct _SOURCEFILEW { - DWORD64 ModBase; // base address of loaded module - PWSTR FileName; // full filename of source -} SOURCEFILEW, *PSOURCEFILEW; - -// -// data structures used for registered symbol callbacks -// - -#define CBA_DEFERRED_SYMBOL_LOAD_START 0x00000001 -#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE 0x00000002 -#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE 0x00000003 -#define CBA_SYMBOLS_UNLOADED 0x00000004 -#define CBA_DUPLICATE_SYMBOL 0x00000005 -#define CBA_READ_MEMORY 0x00000006 -#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL 0x00000007 -#define CBA_SET_OPTIONS 0x00000008 -#define CBA_EVENT 0x00000010 -#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL 0x00000020 -#define CBA_DEBUG_INFO 0x10000000 -#define CBA_SRCSRV_INFO 0x20000000 -#define CBA_SRCSRV_EVENT 0x40000000 - -typedef struct _IMAGEHLP_CBA_READ_MEMORY { - DWORD64 addr; // address to read from - PVOID buf; // buffer to read to - DWORD bytes; // amount of bytes to read - DWORD *bytesread; // pointer to store amount of bytes read -} IMAGEHLP_CBA_READ_MEMORY, *PIMAGEHLP_CBA_READ_MEMORY; - -enum { - sevInfo = 0, - sevProblem, - sevAttn, - sevFatal, - sevMax // unused -}; - -#define EVENT_SRCSPEW_START 100 -#define EVENT_SRCSPEW 100 -#define EVENT_SRCSPEW_END 199 - -typedef struct _IMAGEHLP_CBA_EVENT { - DWORD severity; // values from sevInfo to sevFatal - DWORD code; // numerical code IDs the error - PCHAR desc; // may contain a text description of the error - PVOID object; // value dependant upon the error code -} IMAGEHLP_CBA_EVENT, *PIMAGEHLP_CBA_EVENT; - -typedef struct _IMAGEHLP_CBA_EVENTW { - DWORD severity; // values from sevInfo to sevFatal - DWORD code; // numerical code IDs the error - PCWSTR desc; // may contain a text description of the error - PVOID object; // value dependant upon the error code -} IMAGEHLP_CBA_EVENTW, *PIMAGEHLP_CBA_EVENTW; - -typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64) - DWORD64 BaseOfImage; // base load address of module - DWORD CheckSum; // checksum from the pe header - DWORD TimeDateStamp; // date/time stamp from pe header - CHAR FileName[MAX_PATH]; // symbols file or image name - BOOLEAN Reparse; // load failure reparse - HANDLE hFile; // file handle, if passed - DWORD Flags; // -} IMAGEHLP_DEFERRED_SYMBOL_LOAD64, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD64; - -typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOADW64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOADW64) - DWORD64 BaseOfImage; // base load address of module - DWORD CheckSum; // checksum from the pe header - DWORD TimeDateStamp; // date/time stamp from pe header - WCHAR FileName[MAX_PATH + 1]; // symbols file or image name - BOOLEAN Reparse; // load failure reparse - HANDLE hFile; // file handle, if passed - DWORD Flags; // -} IMAGEHLP_DEFERRED_SYMBOL_LOADW64, *PIMAGEHLP_DEFERRED_SYMBOL_LOADW64; - -#define DSLFLAG_MISMATCHED_PDB 0x1 -#define DSLFLAG_MISMATCHED_DBG 0x2 - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define IMAGEHLP_DEFERRED_SYMBOL_LOAD IMAGEHLP_DEFERRED_SYMBOL_LOAD64 -#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 -#else -typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD) - DWORD BaseOfImage; // base load address of module - DWORD CheckSum; // checksum from the pe header - DWORD TimeDateStamp; // date/time stamp from pe header - CHAR FileName[MAX_PATH]; // symbols file or image name - BOOLEAN Reparse; // load failure reparse - HANDLE hFile; // file handle, if passed -} IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD; -#endif - -typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL64) - DWORD NumberOfDups; // number of duplicates in the Symbol array - PIMAGEHLP_SYMBOL64 Symbol; // array of duplicate symbols - DWORD SelectedSymbol; // symbol selected (-1 to start) -} IMAGEHLP_DUPLICATE_SYMBOL64, *PIMAGEHLP_DUPLICATE_SYMBOL64; - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define IMAGEHLP_DUPLICATE_SYMBOL IMAGEHLP_DUPLICATE_SYMBOL64 -#define PIMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_DUPLICATE_SYMBOL64 -#else -typedef struct _IMAGEHLP_DUPLICATE_SYMBOL { - DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL) - DWORD NumberOfDups; // number of duplicates in the Symbol array - PIMAGEHLP_SYMBOL Symbol; // array of duplicate symbols - DWORD SelectedSymbol; // symbol selected (-1 to start) -} IMAGEHLP_DUPLICATE_SYMBOL, *PIMAGEHLP_DUPLICATE_SYMBOL; -#endif - -// If dbghelp ever needs to display graphical UI, it will use this as the parent window. - -BOOL -IMAGEAPI -SymSetParentWindow( - __in HWND hwnd - ); - -PCHAR -IMAGEAPI -SymSetHomeDirectory( - __in_opt HANDLE hProcess, - __in_opt PCSTR dir - ); - -PWSTR -IMAGEAPI -SymSetHomeDirectoryW( - __in_opt HANDLE hProcess, - __in_opt PCWSTR dir - ); - -PCHAR -IMAGEAPI -SymGetHomeDirectory( - __in DWORD type, - __out_ecount(size) PSTR dir, - __in size_t size - ); - -PWSTR -IMAGEAPI -SymGetHomeDirectoryW( - __in DWORD type, - __out_ecount(size) PWSTR dir, - __in size_t size - ); - -enum { - hdBase = 0, // root directory for dbghelp - hdSym, // where symbols are stored - hdSrc, // where source is stored - hdMax // end marker -}; - -typedef struct _OMAP { - ULONG rva; - ULONG rvaTo; -} OMAP, *POMAP; - -BOOL -IMAGEAPI -SymGetOmaps( - __in HANDLE hProcess, - __in DWORD64 BaseOfDll, - __out POMAP *OmapTo, - __out PDWORD64 cOmapTo, - __out POMAP *OmapFrom, - __out PDWORD64 cOmapFrom - ); - -// -// options that are set/returned by SymSetOptions() & SymGetOptions() -// these are used as a mask -// -#define SYMOPT_CASE_INSENSITIVE 0x00000001 -#define SYMOPT_UNDNAME 0x00000002 -#define SYMOPT_DEFERRED_LOADS 0x00000004 -#define SYMOPT_NO_CPP 0x00000008 -#define SYMOPT_LOAD_LINES 0x00000010 -#define SYMOPT_OMAP_FIND_NEAREST 0x00000020 -#define SYMOPT_LOAD_ANYTHING 0x00000040 -#define SYMOPT_IGNORE_CVREC 0x00000080 -#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 -#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 -#define SYMOPT_EXACT_SYMBOLS 0x00000400 -#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 -#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 -#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 -#define SYMOPT_PUBLICS_ONLY 0x00004000 -#define SYMOPT_NO_PUBLICS 0x00008000 -#define SYMOPT_AUTO_PUBLICS 0x00010000 -#define SYMOPT_NO_IMAGE_SEARCH 0x00020000 -#define SYMOPT_SECURE 0x00040000 -#define SYMOPT_NO_PROMPTS 0x00080000 -#define SYMOPT_OVERWRITE 0x00100000 -#define SYMOPT_IGNORE_IMAGEDIR 0x00200000 -#define SYMOPT_FLAT_DIRECTORY 0x00400000 -#define SYMOPT_FAVOR_COMPRESSED 0x00800000 -#define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 -#define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 - -#define SYMOPT_DEBUG 0x80000000 - -DWORD -IMAGEAPI -SymSetOptions( - __in DWORD SymOptions - ); - -DWORD -IMAGEAPI -SymGetOptions( - VOID - ); - -BOOL -IMAGEAPI -SymCleanup( - __in HANDLE hProcess - ); - -BOOL -IMAGEAPI -SymMatchString( - __in PCSTR string, - __in PCSTR expression, - __in BOOL fCase - ); - -BOOL -IMAGEAPI -SymMatchStringA( - __in PCSTR string, - __in PCSTR expression, - __in BOOL fCase - ); - -BOOL -IMAGEAPI -SymMatchStringW( - __in PCWSTR string, - __in PCWSTR expression, - __in BOOL fCase - ); - -typedef BOOL -(CALLBACK *PSYM_ENUMSOURCEFILES_CALLBACK)( - __in PSOURCEFILE pSourceFile, - __in_opt PVOID UserContext - ); - -// for backwards compatibility - don't use this -#define PSYM_ENUMSOURCFILES_CALLBACK PSYM_ENUMSOURCEFILES_CALLBACK - -BOOL -IMAGEAPI -SymEnumSourceFiles( - __in HANDLE hProcess, - __in ULONG64 ModBase, - __in_opt PCSTR Mask, - __in PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PSYM_ENUMSOURCEFILES_CALLBACKW)( - __in PSOURCEFILEW pSourceFile, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumSourceFilesW( - __in HANDLE hProcess, - __in ULONG64 ModBase, - __in_opt PCWSTR Mask, - __in PSYM_ENUMSOURCEFILES_CALLBACKW cbSrcFiles, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumerateModules64( - __in HANDLE hProcess, - __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumerateModulesW64( - __in HANDLE hProcess, - __in PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback, - __in_opt PVOID UserContext - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymEnumerateModules SymEnumerateModules64 -#else -BOOL -IMAGEAPI -SymEnumerateModules( - __in HANDLE hProcess, - __in PSYM_ENUMMODULES_CALLBACK EnumModulesCallback, - __in_opt PVOID UserContext - ); -#endif - -BOOL -IMAGEAPI -EnumerateLoadedModulesEx( - __in HANDLE hProcess, - __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -EnumerateLoadedModulesExW( - __in HANDLE hProcess, - __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -EnumerateLoadedModules64( - __in HANDLE hProcess, - __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -EnumerateLoadedModulesW64( - __in HANDLE hProcess, - __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, - __in_opt PVOID UserContext - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define EnumerateLoadedModules EnumerateLoadedModules64 -#else -BOOL -IMAGEAPI -EnumerateLoadedModules( - __in HANDLE hProcess, - __in PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback, - __in_opt PVOID UserContext - ); -#endif - -PVOID -IMAGEAPI -SymFunctionTableAccess64( - __in HANDLE hProcess, - __in DWORD64 AddrBase - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymFunctionTableAccess SymFunctionTableAccess64 -#else -PVOID -IMAGEAPI -SymFunctionTableAccess( - __in HANDLE hProcess, - __in DWORD AddrBase - ); -#endif - -BOOL -IMAGEAPI -SymGetUnwindInfo( - __in HANDLE hProcess, - __in DWORD64 Address, - __out_bcount_opt(*Size) PVOID Buffer, - __inout PULONG Size - ); - -BOOL -IMAGEAPI -SymGetModuleInfo64( - __in HANDLE hProcess, - __in DWORD64 qwAddr, - __out PIMAGEHLP_MODULE64 ModuleInfo - ); - -BOOL -IMAGEAPI -SymGetModuleInfoW64( - __in HANDLE hProcess, - __in DWORD64 qwAddr, - __out PIMAGEHLP_MODULEW64 ModuleInfo - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetModuleInfo SymGetModuleInfo64 -#define SymGetModuleInfoW SymGetModuleInfoW64 -#else -BOOL -IMAGEAPI -SymGetModuleInfo( - __in HANDLE hProcess, - __in DWORD dwAddr, - __out PIMAGEHLP_MODULE ModuleInfo - ); - -BOOL -IMAGEAPI -SymGetModuleInfoW( - __in HANDLE hProcess, - __in DWORD dwAddr, - __out PIMAGEHLP_MODULEW ModuleInfo - ); -#endif - -DWORD64 -IMAGEAPI -SymGetModuleBase64( - __in HANDLE hProcess, - __in DWORD64 qwAddr - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetModuleBase SymGetModuleBase64 -#else -DWORD -IMAGEAPI -SymGetModuleBase( - __in HANDLE hProcess, - __in DWORD dwAddr - ); -#endif - -typedef struct _SRCCODEINFO { - DWORD SizeOfStruct; // set to sizeof(SRCCODEINFO) - PVOID Key; // not used - DWORD64 ModBase; // base address of module this applies to - CHAR Obj[MAX_PATH + 1]; // the object file within the module - CHAR FileName[MAX_PATH + 1]; // full filename - DWORD LineNumber; // line number in file - DWORD64 Address; // first instruction of line -} SRCCODEINFO, *PSRCCODEINFO; - -typedef struct _SRCCODEINFOW { - DWORD SizeOfStruct; // set to sizeof(SRCCODEINFO) - PVOID Key; // not used - DWORD64 ModBase; // base address of module this applies to - WCHAR Obj[MAX_PATH + 1]; // the object file within the module - WCHAR FileName[MAX_PATH + 1]; // full filename - DWORD LineNumber; // line number in file - DWORD64 Address; // first instruction of line -} SRCCODEINFOW, *PSRCCODEINFOW; - -typedef BOOL -(CALLBACK *PSYM_ENUMLINES_CALLBACK)( - __in PSRCCODEINFO LineInfo, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumLines( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCSTR Obj, - __in_opt PCSTR File, - __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PSYM_ENUMLINES_CALLBACKW)( - __in PSRCCODEINFOW LineInfo, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumLinesW( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCWSTR Obj, - __in_opt PCWSTR File, - __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymGetLineFromAddr64( - __in HANDLE hProcess, - __in DWORD64 qwAddr, - __out PDWORD pdwDisplacement, - __out PIMAGEHLP_LINE64 Line64 - ); - -BOOL -IMAGEAPI -SymGetLineFromAddrW64( - __in HANDLE hProcess, - __in DWORD64 dwAddr, - __out PDWORD pdwDisplacement, - __out PIMAGEHLP_LINEW64 Line - ); - -BOOL -IMAGEAPI -SymEnumSourceLines( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCSTR Obj, - __in_opt PCSTR File, - __in_opt DWORD Line, - __in DWORD Flags, - __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumSourceLinesW( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCWSTR Obj, - __in_opt PCWSTR File, - __in_opt DWORD Line, - __in DWORD Flags, - __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback, - __in_opt PVOID UserContext - ); - -// flags for SymEnumSourceLines - -#define ESLFLAG_FULLPATH 0x1 -#define ESLFLAG_NEAREST 0x2 -#define ESLFLAG_PREV 0x4 -#define ESLFLAG_NEXT 0x8 - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetLineFromAddr SymGetLineFromAddr64 -#define SymGetLineFromAddrW SymGetLineFromAddrW64 -#else -BOOL -IMAGEAPI -SymGetLineFromAddr( - __in HANDLE hProcess, - __in DWORD dwAddr, - __out PDWORD pdwDisplacement, - __out PIMAGEHLP_LINE Line - ); - -BOOL -IMAGEAPI -SymGetLineFromAddrW( - __in HANDLE hProcess, - __in DWORD dwAddr, - __out PDWORD pdwDisplacement, - __out PIMAGEHLP_LINEW Line - ); -#endif - -BOOL -IMAGEAPI -SymGetLineFromName64( - __in HANDLE hProcess, - __in_opt PCSTR ModuleName, - __in_opt PCSTR FileName, - __in DWORD dwLineNumber, - __out PLONG plDisplacement, - __inout PIMAGEHLP_LINE64 Line - ); - -BOOL -IMAGEAPI -SymGetLineFromNameW64( - __in HANDLE hProcess, - __in_opt PCWSTR ModuleName, - __in_opt PCWSTR FileName, - __in DWORD dwLineNumber, - __out PLONG plDisplacement, - __inout PIMAGEHLP_LINEW64 Line - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetLineFromName SymGetLineFromName64 -#else -BOOL -IMAGEAPI -SymGetLineFromName( - __in HANDLE hProcess, - __in_opt PCSTR ModuleName, - __in_opt PCSTR FileName, - __in DWORD dwLineNumber, - __out PLONG plDisplacement, - __inout PIMAGEHLP_LINE Line - ); -#endif - -BOOL -IMAGEAPI -SymGetLineNext64( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINE64 Line - ); - -BOOL -IMAGEAPI -SymGetLineNextW64( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINEW64 Line - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetLineNext SymGetLineNext64 -#else -BOOL -IMAGEAPI -SymGetLineNext( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINE Line - ); - -BOOL -IMAGEAPI -SymGetLineNextW( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINEW Line - ); -#endif - -BOOL -IMAGEAPI -SymGetLinePrev64( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINE64 Line - ); - -BOOL -IMAGEAPI -SymGetLinePrevW64( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINEW64 Line - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetLinePrev SymGetLinePrev64 -#else -BOOL -IMAGEAPI -SymGetLinePrev( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINE Line - ); - -BOOL -IMAGEAPI -SymGetLinePrevW( - __in HANDLE hProcess, - __inout PIMAGEHLP_LINEW Line - ); -#endif - -ULONG -IMAGEAPI -SymGetFileLineOffsets64( - __in HANDLE hProcess, - __in_opt PCSTR ModuleName, - __in PCSTR FileName, - __out_ecount(BufferLines) PDWORD64 Buffer, - __in ULONG BufferLines - ); - -BOOL -IMAGEAPI -SymMatchFileName( - __in PCSTR FileName, - __in PCSTR Match, - __deref_opt_out PSTR *FileNameStop, - __deref_opt_out PSTR *MatchStop - ); - -BOOL -IMAGEAPI -SymMatchFileNameW( - __in PCWSTR FileName, - __in PCWSTR Match, - __deref_opt_out PWSTR *FileNameStop, - __deref_opt_out PWSTR *MatchStop - ); - -BOOL -IMAGEAPI -SymGetSourceFile( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCSTR Params, - __in PCSTR FileSpec, - __out_ecount(Size) PSTR FilePath, - __in DWORD Size - ); - -BOOL -IMAGEAPI -SymGetSourceFileW( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCWSTR Params, - __in PCWSTR FileSpec, - __out_ecount(Size) PWSTR FilePath, - __in DWORD Size - ); - -BOOL -IMAGEAPI -SymGetSourceFileToken( - __in HANDLE hProcess, - __in ULONG64 Base, - __in PCSTR FileSpec, - __deref_out PVOID *Token, - __out DWORD *Size - ); - -BOOL -IMAGEAPI -SymGetSourceFileTokenW( - __in HANDLE hProcess, - __in ULONG64 Base, - __in PCWSTR FileSpec, - __deref_out PVOID *Token, - __out DWORD *Size - ); - -BOOL -IMAGEAPI -SymGetSourceFileFromToken( - __in HANDLE hProcess, - __in PVOID Token, - __in_opt PCSTR Params, - __out_ecount(Size) PSTR FilePath, - __in DWORD Size - ); - -BOOL -IMAGEAPI -SymGetSourceFileFromTokenW( - __in HANDLE hProcess, - __in PVOID Token, - __in_opt PCWSTR Params, - __out_ecount(Size) PWSTR FilePath, - __in DWORD Size - ); - -BOOL -IMAGEAPI -SymGetSourceVarFromToken( - __in HANDLE hProcess, - __in PVOID Token, - __in_opt PCSTR Params, - __in PCSTR VarName, - __out_ecount(Size) PSTR Value, - __in DWORD Size - ); - -BOOL -IMAGEAPI -SymGetSourceVarFromTokenW( - __in HANDLE hProcess, - __in PVOID Token, - __in_opt PCWSTR Params, - __in PCWSTR VarName, - __out_ecount(Size) PWSTR Value, - __in DWORD Size - ); - -typedef BOOL (CALLBACK *PENUMSOURCEFILETOKENSCALLBACK)(__in PVOID token, __in size_t size); - -BOOL -IMAGEAPI -SymEnumSourceFileTokens( - __in HANDLE hProcess, - __in ULONG64 Base, - __in PENUMSOURCEFILETOKENSCALLBACK Callback - ); - -BOOL -IMAGEAPI -SymInitialize( - __in HANDLE hProcess, - __in_opt PCSTR UserSearchPath, - __in BOOL fInvadeProcess - ); - -BOOL -IMAGEAPI -SymInitializeW( - __in HANDLE hProcess, - __in_opt PCWSTR UserSearchPath, - __in BOOL fInvadeProcess - ); - -BOOL -IMAGEAPI -SymGetSearchPath( - __in HANDLE hProcess, - __out_ecount(SearchPathLength) PSTR SearchPath, - __in DWORD SearchPathLength - ); - -BOOL -IMAGEAPI -SymGetSearchPathW( - __in HANDLE hProcess, - __out_ecount(SearchPathLength) PWSTR SearchPath, - __in DWORD SearchPathLength - ); - -BOOL -IMAGEAPI -SymSetSearchPath( - __in HANDLE hProcess, - __in_opt PCSTR SearchPath - ); - -BOOL -IMAGEAPI -SymSetSearchPathW( - __in HANDLE hProcess, - __in_opt PCWSTR SearchPath - ); - -#define SLMFLAG_VIRTUAL 0x1 -#define SLMFLAG_ALT_INDEX 0x2 -#define SLMFLAG_NO_SYMBOLS 0x4 - -DWORD64 -IMAGEAPI -SymLoadModuleEx( - __in HANDLE hProcess, - __in_opt HANDLE hFile, - __in_opt PCSTR ImageName, - __in_opt PCSTR ModuleName, - __in DWORD64 BaseOfDll, - __in DWORD DllSize, - __in_opt PMODLOAD_DATA Data, - __in_opt DWORD Flags - ); - -DWORD64 -IMAGEAPI -SymLoadModuleExW( - __in HANDLE hProcess, - __in_opt HANDLE hFile, - __in_opt PCWSTR ImageName, - __in_opt PCWSTR ModuleName, - __in DWORD64 BaseOfDll, - __in DWORD DllSize, - __in_opt PMODLOAD_DATA Data, - __in_opt DWORD Flags - ); - -BOOL -IMAGEAPI -SymUnloadModule64( - __in HANDLE hProcess, - __in DWORD64 BaseOfDll - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymUnloadModule SymUnloadModule64 -#else -BOOL -IMAGEAPI -SymUnloadModule( - __in HANDLE hProcess, - __in DWORD BaseOfDll - ); -#endif - -BOOL -IMAGEAPI -SymUnDName64( - __in PIMAGEHLP_SYMBOL64 sym, // Symbol to undecorate - __out_ecount(UnDecNameLength) PSTR UnDecName, // Buffer to store undecorated name in - __in DWORD UnDecNameLength // Size of the buffer - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymUnDName SymUnDName64 -#else -BOOL -IMAGEAPI -SymUnDName( - __in PIMAGEHLP_SYMBOL sym, // Symbol to undecorate - __out_ecount(UnDecNameLength) PSTR UnDecName, // Buffer to store undecorated name in - __in DWORD UnDecNameLength // Size of the buffer - ); -#endif - -BOOL -IMAGEAPI -SymRegisterCallback64( - __in HANDLE hProcess, - __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, - __in ULONG64 UserContext - ); - -BOOL -IMAGEAPI -SymRegisterCallbackW64( - __in HANDLE hProcess, - __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, - __in ULONG64 UserContext - ); - -BOOL -IMAGEAPI -SymRegisterFunctionEntryCallback64( - __in HANDLE hProcess, - __in PSYMBOL_FUNCENTRY_CALLBACK64 CallbackFunction, - __in ULONG64 UserContext - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymRegisterCallback SymRegisterCallback64 -#define SymRegisterFunctionEntryCallback SymRegisterFunctionEntryCallback64 -#else -BOOL -IMAGEAPI -SymRegisterCallback( - __in HANDLE hProcess, - __in PSYMBOL_REGISTERED_CALLBACK CallbackFunction, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymRegisterFunctionEntryCallback( - __in HANDLE hProcess, - __in PSYMBOL_FUNCENTRY_CALLBACK CallbackFunction, - __in_opt PVOID UserContext - ); -#endif - - -typedef struct _IMAGEHLP_SYMBOL_SRC { - DWORD sizeofstruct; - DWORD type; - char file[MAX_PATH]; -} IMAGEHLP_SYMBOL_SRC, *PIMAGEHLP_SYMBOL_SRC; - -typedef struct _MODULE_TYPE_INFO { // AKA TYPTYP - USHORT dataLength; - USHORT leaf; - BYTE data[1]; -} MODULE_TYPE_INFO, *PMODULE_TYPE_INFO; - -typedef struct _SYMBOL_INFO { - ULONG SizeOfStruct; - ULONG TypeIndex; // Type Index of symbol - ULONG64 Reserved[2]; - ULONG Index; - ULONG Size; - ULONG64 ModBase; // Base Address of module comtaining this symbol - ULONG Flags; - ULONG64 Value; // Value of symbol, ValuePresent should be 1 - ULONG64 Address; // Address of symbol including base address of module - ULONG Register; // register holding value or pointer to value - ULONG Scope; // scope of the symbol - ULONG Tag; // pdb classification - ULONG NameLen; // Actual length of name - ULONG MaxNameLen; - CHAR Name[1]; // Name of symbol -} SYMBOL_INFO, *PSYMBOL_INFO; - -typedef struct _SYMBOL_INFO_PACKAGE { - SYMBOL_INFO si; - CHAR name[MAX_SYM_NAME + 1]; -} SYMBOL_INFO_PACKAGE, *PSYMBOL_INFO_PACKAGE; - -typedef struct _SYMBOL_INFOW { - ULONG SizeOfStruct; - ULONG TypeIndex; // Type Index of symbol - ULONG64 Reserved[2]; - ULONG Index; - ULONG Size; - ULONG64 ModBase; // Base Address of module comtaining this symbol - ULONG Flags; - ULONG64 Value; // Value of symbol, ValuePresent should be 1 - ULONG64 Address; // Address of symbol including base address of module - ULONG Register; // register holding value or pointer to value - ULONG Scope; // scope of the symbol - ULONG Tag; // pdb classification - ULONG NameLen; // Actual length of name - ULONG MaxNameLen; - WCHAR Name[1]; // Name of symbol -} SYMBOL_INFOW, *PSYMBOL_INFOW; - -typedef struct _SYMBOL_INFO_PACKAGEW { - SYMBOL_INFOW si; - WCHAR name[MAX_SYM_NAME + 1]; -} SYMBOL_INFO_PACKAGEW, *PSYMBOL_INFO_PACKAGEW; - -typedef struct _IMAGEHLP_STACK_FRAME -{ - ULONG64 InstructionOffset; - ULONG64 ReturnOffset; - ULONG64 FrameOffset; - ULONG64 StackOffset; - ULONG64 BackingStoreOffset; - ULONG64 FuncTableEntry; - ULONG64 Params[4]; - ULONG64 Reserved[5]; - BOOL Virtual; - ULONG Reserved2; -} IMAGEHLP_STACK_FRAME, *PIMAGEHLP_STACK_FRAME; - -typedef VOID IMAGEHLP_CONTEXT, *PIMAGEHLP_CONTEXT; - - -BOOL -IMAGEAPI -SymSetContext( - __in HANDLE hProcess, - __in PIMAGEHLP_STACK_FRAME StackFrame, - __in_opt PIMAGEHLP_CONTEXT Context - ); - -BOOL -IMAGEAPI -SymSetScopeFromAddr( - __in HANDLE hProcess, - __in ULONG64 Address - ); - -BOOL -IMAGEAPI -SymSetScopeFromIndex( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in DWORD Index - ); - -typedef BOOL -(CALLBACK *PSYM_ENUMPROCESSES_CALLBACK)( - __in HANDLE hProcess, - __in PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumProcesses( - __in PSYM_ENUMPROCESSES_CALLBACK EnumProcessesCallback, - __in PVOID UserContext - ); - -BOOL -IMAGEAPI -SymFromAddr( - __in HANDLE hProcess, - __in DWORD64 Address, - __out_opt PDWORD64 Displacement, - __inout PSYMBOL_INFO Symbol - ); - -BOOL -IMAGEAPI -SymFromAddrW( - __in HANDLE hProcess, - __in DWORD64 Address, - __out_opt PDWORD64 Displacement, - __inout PSYMBOL_INFOW Symbol - ); - -BOOL -IMAGEAPI -SymFromToken( - __in HANDLE hProcess, - __in DWORD64 Base, - __in DWORD Token, - __inout PSYMBOL_INFO Symbol - ); - -BOOL -IMAGEAPI -SymFromTokenW( - __in HANDLE hProcess, - __in DWORD64 Base, - __in DWORD Token, - __inout PSYMBOL_INFOW Symbol - ); - -BOOL -IMAGEAPI -SymNext( - __in HANDLE hProcess, - __inout PSYMBOL_INFO si - ); - -BOOL -IMAGEAPI -SymNextW( - __in HANDLE hProcess, - __inout PSYMBOL_INFOW siw - ); - -BOOL -IMAGEAPI -SymPrev( - __in HANDLE hProcess, - __inout PSYMBOL_INFO si - ); - -BOOL -IMAGEAPI -SymPrevW( - __in HANDLE hProcess, - __inout PSYMBOL_INFOW siw - ); - -// While SymFromName will provide a symbol from a name, -// SymEnumSymbols can provide the same matching information -// for ALL symbols with a matching name, even regular -// expressions. That way you can search across modules -// and differentiate between identically named symbols. - -BOOL -IMAGEAPI -SymFromName( - __in HANDLE hProcess, - __in PCSTR Name, - __inout PSYMBOL_INFO Symbol - ); - -BOOL -IMAGEAPI -SymFromNameW( - __in HANDLE hProcess, - __in PCWSTR Name, - __inout PSYMBOL_INFOW Symbol - ); - -typedef BOOL -(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACK)( - __in PSYMBOL_INFO pSymInfo, - __in ULONG SymbolSize, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumSymbols( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCSTR Mask, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext - ); - -typedef BOOL -(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACKW)( - __in PSYMBOL_INFOW pSymInfo, - __in ULONG SymbolSize, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumSymbolsW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCWSTR Mask, - __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumSymbolsForAddr( - __in HANDLE hProcess, - __in DWORD64 Address, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumSymbolsForAddrW( - __in HANDLE hProcess, - __in DWORD64 Address, - __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, - __in_opt PVOID UserContext - ); - -#define SYMSEARCH_MASKOBJS 0x01 // used internally to implement other APIs -#define SYMSEARCH_RECURSE 0X02 // recurse scopes -#define SYMSEARCH_GLOBALSONLY 0X04 // search only for global symbols -#define SYMSEARCH_ALLITEMS 0X08 // search for everything in the pdb, not just normal scoped symbols - -BOOL -IMAGEAPI -SymSearch( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt DWORD Index, - __in_opt DWORD SymTag, - __in_opt PCSTR Mask, - __in_opt DWORD64 Address, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext, - __in DWORD Options - ); - -BOOL -IMAGEAPI -SymSearchW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt DWORD Index, - __in_opt DWORD SymTag, - __in_opt PCWSTR Mask, - __in_opt DWORD64 Address, - __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, - __in_opt PVOID UserContext, - __in DWORD Options - ); - -BOOL -IMAGEAPI -SymGetScope( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in DWORD Index, - __inout PSYMBOL_INFO Symbol - ); - -BOOL -IMAGEAPI -SymGetScopeW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in DWORD Index, - __inout PSYMBOL_INFOW Symbol - ); - -BOOL -IMAGEAPI -SymFromIndex( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in DWORD Index, - __inout PSYMBOL_INFO Symbol - ); - -BOOL -IMAGEAPI -SymFromIndexW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in DWORD Index, - __inout PSYMBOL_INFOW Symbol - ); - -typedef enum _IMAGEHLP_SYMBOL_TYPE_INFO { - TI_GET_SYMTAG, - TI_GET_SYMNAME, - TI_GET_LENGTH, - TI_GET_TYPE, - TI_GET_TYPEID, - TI_GET_BASETYPE, - TI_GET_ARRAYINDEXTYPEID, - TI_FINDCHILDREN, - TI_GET_DATAKIND, - TI_GET_ADDRESSOFFSET, - TI_GET_OFFSET, - TI_GET_VALUE, - TI_GET_COUNT, - TI_GET_CHILDRENCOUNT, - TI_GET_BITPOSITION, - TI_GET_VIRTUALBASECLASS, - TI_GET_VIRTUALTABLESHAPEID, - TI_GET_VIRTUALBASEPOINTEROFFSET, - TI_GET_CLASSPARENTID, - TI_GET_NESTED, - TI_GET_SYMINDEX, - TI_GET_LEXICALPARENT, - TI_GET_ADDRESS, - TI_GET_THISADJUST, - TI_GET_UDTKIND, - TI_IS_EQUIV_TO, - TI_GET_CALLING_CONVENTION, - TI_IS_CLOSE_EQUIV_TO, - TI_GTIEX_REQS_VALID, - TI_GET_VIRTUALBASEOFFSET, - TI_GET_VIRTUALBASEDISPINDEX, - TI_GET_IS_REFERENCE, - TI_GET_INDIRECTVIRTUALBASECLASS, - IMAGEHLP_SYMBOL_TYPE_INFO_MAX, -} IMAGEHLP_SYMBOL_TYPE_INFO; - -typedef struct _TI_FINDCHILDREN_PARAMS { - ULONG Count; - ULONG Start; - ULONG ChildId[1]; -} TI_FINDCHILDREN_PARAMS; - -BOOL -IMAGEAPI -SymGetTypeInfo( - __in HANDLE hProcess, - __in DWORD64 ModBase, - __in ULONG TypeId, - __in IMAGEHLP_SYMBOL_TYPE_INFO GetType, - __out PVOID pInfo - ); - -#define IMAGEHLP_GET_TYPE_INFO_UNCACHED 0x00000001 -#define IMAGEHLP_GET_TYPE_INFO_CHILDREN 0x00000002 - -typedef struct _IMAGEHLP_GET_TYPE_INFO_PARAMS { - IN ULONG SizeOfStruct; - IN ULONG Flags; - IN ULONG NumIds; - IN PULONG TypeIds; - IN ULONG64 TagFilter; - IN ULONG NumReqs; - IN IMAGEHLP_SYMBOL_TYPE_INFO* ReqKinds; - IN PULONG_PTR ReqOffsets; - IN PULONG ReqSizes; - IN ULONG_PTR ReqStride; - IN ULONG_PTR BufferSize; - OUT PVOID Buffer; - OUT ULONG EntriesMatched; - OUT ULONG EntriesFilled; - OUT ULONG64 TagsFound; - OUT ULONG64 AllReqsValid; - IN ULONG NumReqsValid; - OUT PULONG64 ReqsValid OPTIONAL; -} IMAGEHLP_GET_TYPE_INFO_PARAMS, *PIMAGEHLP_GET_TYPE_INFO_PARAMS; - -BOOL -IMAGEAPI -SymGetTypeInfoEx( - __in HANDLE hProcess, - __in DWORD64 ModBase, - __inout PIMAGEHLP_GET_TYPE_INFO_PARAMS Params - ); - -BOOL -IMAGEAPI -SymEnumTypes( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumTypesW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumTypesByName( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCSTR mask, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymEnumTypesByNameW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCWSTR mask, - __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, - __in_opt PVOID UserContext - ); - -BOOL -IMAGEAPI -SymGetTypeFromName( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PCSTR Name, - __inout PSYMBOL_INFO Symbol - ); - -BOOL -IMAGEAPI -SymGetTypeFromNameW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PCWSTR Name, - __inout PSYMBOL_INFOW Symbol - ); - -BOOL -IMAGEAPI -SymAddSymbol( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PCSTR Name, - __in DWORD64 Address, - __in DWORD Size, - __in DWORD Flags - ); - -BOOL -IMAGEAPI -SymAddSymbolW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PCWSTR Name, - __in DWORD64 Address, - __in DWORD Size, - __in DWORD Flags - ); - -BOOL -IMAGEAPI -SymDeleteSymbol( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCSTR Name, - __in DWORD64 Address, - __in DWORD Flags - ); - -BOOL -IMAGEAPI -SymDeleteSymbolW( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in_opt PCWSTR Name, - __in DWORD64 Address, - __in DWORD Flags - ); - -BOOL -IMAGEAPI -SymRefreshModuleList( - __in HANDLE hProcess - ); - -BOOL -IMAGEAPI -SymAddSourceStream( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCSTR StreamFile, - __in_bcount_opt(Size) PBYTE Buffer, - __in size_t Size - ); - -typedef BOOL (WINAPI *SYMADDSOURCESTREAM)(HANDLE, ULONG64, PCSTR, PBYTE, size_t); - -BOOL -IMAGEAPI -SymAddSourceStreamA( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCSTR StreamFile, - __in_bcount_opt(Size) PBYTE Buffer, - __in size_t Size - ); - -typedef BOOL (WINAPI *SYMADDSOURCESTREAMA)(HANDLE, ULONG64, PCSTR, PBYTE, size_t); - -BOOL -IMAGEAPI -SymAddSourceStreamW( - __in HANDLE hProcess, - __in ULONG64 Base, - __in_opt PCWSTR FileSpec, - __in_bcount_opt(Size) PBYTE Buffer, - __in size_t Size - ); - -BOOL -IMAGEAPI -SymSrvIsStoreW( - __in_opt HANDLE hProcess, - __in PCWSTR path - ); - -BOOL -IMAGEAPI -SymSrvIsStore( - __in_opt HANDLE hProcess, - __in PCSTR path - ); - -PCSTR -IMAGEAPI -SymSrvDeltaName( - __in HANDLE hProcess, - __in_opt PCSTR SymPath, - __in PCSTR Type, - __in PCSTR File1, - __in PCSTR File2 - ); - -PCWSTR -IMAGEAPI -SymSrvDeltaNameW( - __in HANDLE hProcess, - __in_opt PCWSTR SymPath, - __in PCWSTR Type, - __in PCWSTR File1, - __in PCWSTR File2 - ); - -PCSTR -IMAGEAPI -SymSrvGetSupplement( - __in HANDLE hProcess, - __in_opt PCSTR SymPath, - __in PCSTR Node, - __in PCSTR File - ); - -PCWSTR -IMAGEAPI -SymSrvGetSupplementW( - __in HANDLE hProcess, - __in_opt PCWSTR SymPath, - __in PCWSTR Node, - __in PCWSTR File - ); - -BOOL -IMAGEAPI -SymSrvGetFileIndexes( - __in PCSTR File, - __out GUID *Id, - __out PDWORD Val1, - __out_opt PDWORD Val2, - __in DWORD Flags - ); - -BOOL -IMAGEAPI -SymSrvGetFileIndexesW( - __in PCWSTR File, - __out GUID *Id, - __out PDWORD Val1, - __out_opt PDWORD Val2, - __in DWORD Flags - ); - -BOOL -IMAGEAPI -SymSrvGetFileIndexStringW( - __in HANDLE hProcess, - __in_opt PCWSTR SrvPath, - __in PCWSTR File, - __out_ecount(Size) PWSTR Index, - __in size_t Size, - __in DWORD Flags - ); - -BOOL -IMAGEAPI -SymSrvGetFileIndexString( - __in HANDLE hProcess, - __in_opt PCSTR SrvPath, - __in PCSTR File, - __out_ecount(Size) PSTR Index, - __in size_t Size, - __in DWORD Flags - ); - -typedef struct { - DWORD sizeofstruct; - char file[MAX_PATH +1]; - BOOL stripped; - DWORD timestamp; - DWORD size; - char dbgfile[MAX_PATH +1]; - char pdbfile[MAX_PATH + 1]; - GUID guid; - DWORD sig; - DWORD age; -} SYMSRV_INDEX_INFO, *PSYMSRV_INDEX_INFO; - -typedef struct { - DWORD sizeofstruct; - WCHAR file[MAX_PATH +1]; - BOOL stripped; - DWORD timestamp; - DWORD size; - WCHAR dbgfile[MAX_PATH +1]; - WCHAR pdbfile[MAX_PATH + 1]; - GUID guid; - DWORD sig; - DWORD age; -} SYMSRV_INDEX_INFOW, *PSYMSRV_INDEX_INFOW; - -BOOL -IMAGEAPI -SymSrvGetFileIndexInfo( - __in PCSTR File, - __out PSYMSRV_INDEX_INFO Info, - __in DWORD Flags - ); - -BOOL -IMAGEAPI -SymSrvGetFileIndexInfoW( - __in PCWSTR File, - __out PSYMSRV_INDEX_INFOW Info, - __in DWORD Flags - ); - -PCSTR -IMAGEAPI -SymSrvStoreSupplement( - __in HANDLE hProcess, - __in_opt PCSTR SrvPath, - __in PCSTR Node, - __in PCSTR File, - __in DWORD Flags - ); - -PCWSTR -IMAGEAPI -SymSrvStoreSupplementW( - __in HANDLE hProcess, - __in_opt PCWSTR SymPath, - __in PCWSTR Node, - __in PCWSTR File, - __in DWORD Flags - ); - -PCSTR -IMAGEAPI -SymSrvStoreFile( - __in HANDLE hProcess, - __in_opt PCSTR SrvPath, - __in PCSTR File, - __in DWORD Flags - ); - -PCWSTR -IMAGEAPI -SymSrvStoreFileW( - __in HANDLE hProcess, - __in_opt PCWSTR SrvPath, - __in PCWSTR File, - __in DWORD Flags - ); - -// used by SymGetSymbolFile's "Type" parameter - -enum { - sfImage = 0, - sfDbg, - sfPdb, - sfMpd, - sfMax -}; - -BOOL -IMAGEAPI -SymGetSymbolFile( - __in_opt HANDLE hProcess, - __in_opt PCSTR SymPath, - __in PCSTR ImageFile, - __in DWORD Type, - __out_ecount(cSymbolFile) PSTR SymbolFile, - __in size_t cSymbolFile, - __out_ecount(cDbgFile) PSTR DbgFile, - __in size_t cDbgFile - ); - -BOOL -IMAGEAPI -SymGetSymbolFileW( - __in_opt HANDLE hProcess, - __in_opt PCWSTR SymPath, - __in PCWSTR ImageFile, - __in DWORD Type, - __out_ecount(cSymbolFile) PWSTR SymbolFile, - __in size_t cSymbolFile, - __out_ecount(cDbgFile) PWSTR DbgFile, - __in size_t cDbgFile - ); - -// -// Full user-mode dump creation. -// - -typedef BOOL (WINAPI *PDBGHELP_CREATE_USER_DUMP_CALLBACK)( - __in DWORD DataType, - __in PVOID* Data, - __out LPDWORD DataLength, - __in_opt PVOID UserData - ); - -BOOL -WINAPI -DbgHelpCreateUserDump( - __in_opt LPCSTR FileName, - __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback, - __in_opt PVOID UserData - ); - -BOOL -WINAPI -DbgHelpCreateUserDumpW( - __in_opt LPCWSTR FileName, - __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback, - __in_opt PVOID UserData - ); - -// ----------------------------------------------------------------- -// The following 4 legacy APIs are fully supported, but newer -// ones are recommended. SymFromName and SymFromAddr provide -// much more detailed info on the returned symbol. - -BOOL -IMAGEAPI -SymGetSymFromAddr64( - __in HANDLE hProcess, - __in DWORD64 qwAddr, - __out_opt PDWORD64 pdwDisplacement, - __inout PIMAGEHLP_SYMBOL64 Symbol - ); - - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetSymFromAddr SymGetSymFromAddr64 -#else -BOOL -IMAGEAPI -SymGetSymFromAddr( - __in HANDLE hProcess, - __in DWORD dwAddr, - __out_opt PDWORD pdwDisplacement, - __inout PIMAGEHLP_SYMBOL Symbol - ); -#endif - -// While following two APIs will provide a symbol from a name, -// SymEnumSymbols can provide the same matching information -// for ALL symbols with a matching name, even regular -// expressions. That way you can search across modules -// and differentiate between identically named symbols. - -BOOL -IMAGEAPI -SymGetSymFromName64( - __in HANDLE hProcess, - __in PCSTR Name, - __inout PIMAGEHLP_SYMBOL64 Symbol - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetSymFromName SymGetSymFromName64 -#else -BOOL -IMAGEAPI -SymGetSymFromName( - __in HANDLE hProcess, - __in PCSTR Name, - __inout PIMAGEHLP_SYMBOL Symbol - ); -#endif - - -// Symbol server exports - -typedef BOOL (WINAPI *PSYMBOLSERVERPROC)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR); -typedef BOOL (WINAPI *PSYMBOLSERVERPROCA)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR); -typedef BOOL (WINAPI *PSYMBOLSERVERPROCW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR); -typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROC)(PCSTR, PCSTR, PCSTR, PSTR); -typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROCA)(PCSTR, PCSTR, PCSTR, PSTR); -typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROCW)(PCWSTR, PCWSTR, PCWSTR, PWSTR); -typedef BOOL (WINAPI *PSYMBOLSERVEROPENPROC)(VOID); -typedef BOOL (WINAPI *PSYMBOLSERVERCLOSEPROC)(VOID); -typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSPROC)(UINT_PTR, ULONG64); -typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSWPROC)(UINT_PTR, ULONG64); -typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERCALLBACKPROC)(UINT_PTR action, ULONG64 data, ULONG64 context); -typedef UINT_PTR (WINAPI *PSYMBOLSERVERGETOPTIONSPROC)(); -typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROC)(PCSTR); -typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCA)(PCSTR); -typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCW)(PCWSTR); -typedef BOOL (WINAPI *PSYMBOLSERVERGETVERSION)(LPAPI_VERSION); -typedef BOOL (WINAPI *PSYMBOLSERVERDELTANAME)(PCSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PSTR, size_t); -typedef BOOL (WINAPI *PSYMBOLSERVERDELTANAMEW)(PCWSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PWSTR, size_t); -typedef BOOL (WINAPI *PSYMBOLSERVERGETSUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t); -typedef BOOL (WINAPI *PSYMBOLSERVERGETSUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t); -typedef BOOL (WINAPI *PSYMBOLSERVERSTORESUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t, DWORD); -typedef BOOL (WINAPI *PSYMBOLSERVERSTORESUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t, DWORD); -typedef BOOL (WINAPI *PSYMBOLSERVERGETINDEXSTRING)(PVOID, DWORD, DWORD, PSTR, size_t); -typedef BOOL (WINAPI *PSYMBOLSERVERGETINDEXSTRINGW)(PVOID, DWORD, DWORD, PWSTR, size_t); -typedef BOOL (WINAPI *PSYMBOLSERVERSTOREFILE)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR, size_t, DWORD); -typedef BOOL (WINAPI *PSYMBOLSERVERSTOREFILEW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR, size_t, DWORD); -typedef BOOL (WINAPI *PSYMBOLSERVERISSTORE)(PCSTR); -typedef BOOL (WINAPI *PSYMBOLSERVERISSTOREW)(PCWSTR); -typedef DWORD (WINAPI *PSYMBOLSERVERVERSION)(); -typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERMESSAGEPROC)(UINT_PTR action, ULONG64 data, ULONG64 context); - -#define SYMSRV_VERSION 2 - -#define SSRVOPT_CALLBACK 0x00000001 -#define SSRVOPT_DWORD 0x00000002 -#define SSRVOPT_DWORDPTR 0x00000004 -#define SSRVOPT_GUIDPTR 0x00000008 -#define SSRVOPT_OLDGUIDPTR 0x00000010 -#define SSRVOPT_UNATTENDED 0x00000020 -#define SSRVOPT_NOCOPY 0x00000040 -#define SSRVOPT_GETPATH 0x00000040 -#define SSRVOPT_PARENTWIN 0x00000080 -#define SSRVOPT_PARAMTYPE 0x00000100 -#define SSRVOPT_SECURE 0x00000200 -#define SSRVOPT_TRACE 0x00000400 -#define SSRVOPT_SETCONTEXT 0x00000800 -#define SSRVOPT_PROXY 0x00001000 -#define SSRVOPT_DOWNSTREAM_STORE 0x00002000 -#define SSRVOPT_OVERWRITE 0x00004000 -#define SSRVOPT_RESETTOU 0x00008000 -#define SSRVOPT_CALLBACKW 0x00010000 -#define SSRVOPT_FLAT_DEFAULT_STORE 0x00020000 -#define SSRVOPT_PROXYW 0x00040000 -#define SSRVOPT_MESSAGE 0x00080000 -#define SSRVOPT_SERVICE 0x00100000 // deprecated -#define SSRVOPT_FAVOR_COMPRESSED 0x00200000 -#define SSRVOPT_STRING 0x00400000 -#define SSRVOPT_WINHTTP 0x00800000 -#define SSRVOPT_WININET 0x01000000 - -#define SSRVOPT_MAX 0x0100000 - -#define SSRVOPT_RESET ((ULONG_PTR)-1) - - -#define NUM_SSRVOPTS 30 - -#define SSRVACTION_TRACE 1 -#define SSRVACTION_QUERYCANCEL 2 -#define SSRVACTION_EVENT 3 -#define SSRVACTION_EVENTW 4 -#define SSRVACTION_SIZE 5 - -#define SYMSTOREOPT_COMPRESS 0x01 -#define SYMSTOREOPT_OVERWRITE 0x02 -#define SYMSTOREOPT_RETURNINDEX 0x04 -#define SYMSTOREOPT_POINTER 0x08 -#define SYMSTOREOPT_ALT_INDEX 0x10 -#define SYMSTOREOPT_UNICODE 0x20 -#define SYMSTOREOPT_PASS_IF_EXISTS 0x40 - -#ifdef DBGHELP_TRANSLATE_TCHAR - #define SymInitialize SymInitializeW - #define SymAddSymbol SymAddSymbolW - #define SymDeleteSymbol SymDeleteSymbolW - #define SearchTreeForFile SearchTreeForFileW - #define UnDecorateSymbolName UnDecorateSymbolNameW - #define SymGetLineFromName64 SymGetLineFromNameW64 - #define SymGetLineFromAddr64 SymGetLineFromAddrW64 - #define SymGetLineNext64 SymGetLineNextW64 - #define SymGetLinePrev64 SymGetLinePrevW64 - #define SymFromName SymFromNameW - #define SymFindExecutableImage SymFindExecutableImageW - #define FindExecutableImageEx FindExecutableImageExW - #define SymSearch SymSearchW - #define SymEnumLines SymEnumLinesW - #define SymEnumSourceLines SymEnumSourceLinesW - #define SymGetTypeFromName SymGetTypeFromNameW - #define SymEnumSymbolsForAddr SymEnumSymbolsForAddrW - #define SymFromAddr SymFromAddrW - #define SymMatchString SymMatchStringW - #define SymEnumSourceFiles SymEnumSourceFilesW - #define SymEnumSymbols SymEnumSymbolsW - #define SymLoadModuleEx SymLoadModuleExW - #define SymSetSearchPath SymSetSearchPathW - #define SymGetSearchPath SymGetSearchPathW - #define EnumDirTree EnumDirTreeW - #define SymFromToken SymFromTokenW - #define SymFromIndex SymFromIndexW - #define SymGetScope SymGetScopeW - #define SymNext SymNextW - #define SymPrev SymPrevW - #define SymEnumTypes SymEnumTypesW - #define SymEnumTypesByName SymEnumTypesByNameW - #define SymRegisterCallback64 SymRegisterCallbackW64 - #define SymFindDebugInfoFile SymFindDebugInfoFileW - #define FindDebugInfoFileEx FindDebugInfoFileExW - #define SymFindFileInPath SymFindFileInPathW - #define SymEnumerateModules64 SymEnumerateModulesW64 - #define SymSetHomeDirectory SymSetHomeDirectoryW - #define SymGetHomeDirectory SymGetHomeDirectoryW - #define SymGetSourceFile SymGetSourceFileW - #define SymGetSourceFileToken SymGetSourceFileTokenW - #define SymGetSourceFileFromToken SymGetSourceFileFromTokenW - #define SymGetSourceVarFromToken SymGetSourceVarFromTokenW - #define SymGetSourceFileToken SymGetSourceFileTokenW - #define SymGetFileLineOffsets64 SymGetFileLineOffsetsW64 - #define SymFindFileInPath SymFindFileInPathW - #define SymMatchFileName SymMatchFileNameW - #define SymGetSourceFileFromToken SymGetSourceFileFromTokenW - #define SymGetSourceVarFromToken SymGetSourceVarFromTokenW - #define SymGetModuleInfo64 SymGetModuleInfoW64 - #define SymSrvIsStore SymSrvIsStoreW - #define SymSrvDeltaName SymSrvDeltaNameW - #define SymSrvGetSupplement SymSrvGetSupplementW - #define SymSrvStoreSupplement SymSrvStoreSupplementW - #define SymSrvGetFileIndexes SymSrvGetFileIndexes - #define SymSrvGetFileIndexString SymSrvGetFileIndexStringW - #define SymSrvStoreFile SymSrvStoreFileW - #define SymGetSymbolFile SymGetSymbolFileW - #define EnumerateLoadedModules64 EnumerateLoadedModulesW64 - #define EnumerateLoadedModulesEx EnumerateLoadedModulesExW - #define SymSrvGetFileIndexInfo SymSrvGetFileIndexInfoW - - #define IMAGEHLP_LINE64 IMAGEHLP_LINEW64 - #define PIMAGEHLP_LINE64 PIMAGEHLP_LINEW64 - #define SYMBOL_INFO SYMBOL_INFOW - #define PSYMBOL_INFO PSYMBOL_INFOW - #define SYMBOL_INFO_PACKAGE SYMBOL_INFO_PACKAGEW - #define PSYMBOL_INFO_PACKAGE PSYMBOL_INFO_PACKAGEW - #define FIND_EXE_FILE_CALLBACK FIND_EXE_FILE_CALLBACKW - #define PFIND_EXE_FILE_CALLBACK PFIND_EXE_FILE_CALLBACKW - #define SYM_ENUMERATESYMBOLS_CALLBACK SYM_ENUMERATESYMBOLS_CALLBACKW - #define PSYM_ENUMERATESYMBOLS_CALLBACK PSYM_ENUMERATESYMBOLS_CALLBACKW - #define SRCCODEINFO SRCCODEINFOW - #define PSRCCODEINFO PSRCCODEINFOW - #define SOURCEFILE SOURCEFILEW - #define PSOURCEFILE PSOURCEFILEW - #define SYM_ENUMSOURECFILES_CALLBACK SYM_ENUMSOURCEFILES_CALLBACKW - #define PSYM_ENUMSOURCEFILES_CALLBACK PSYM_ENUMSOURECFILES_CALLBACKW - #define IMAGEHLP_CBA_EVENT IMAGEHLP_CBA_EVENTW - #define PIMAGEHLP_CBA_EVENT PIMAGEHLP_CBA_EVENTW - #define PENUMDIRTREE_CALLBACK PENUMDIRTREE_CALLBACKW - #define IMAGEHLP_DEFERRED_SYMBOL_LOAD64 IMAGEHLP_DEFERRED_SYMBOL_LOADW64 - #define PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 PIMAGEHLP_DEFERRED_SYMBOL_LOADW64 - #define PFIND_DEBUG_FILE_CALLBACK PFIND_DEBUG_FILE_CALLBACKW - #define PFINDFILEINPATHCALLBACK PFINDFILEINPATHCALLBACKW - #define IMAGEHLP_MODULE64 IMAGEHLP_MODULEW64 - #define PIMAGEHLP_MODULE64 PIMAGEHLP_MODULEW64 - #define SYMSRV_INDEX_INFO SYMSRV_INDEX_INFOW - #define PSYMSRV_INDEX_INFO PSYMSRV_INDEX_INFOW - - #define PSYMBOLSERVERPROC PSYMBOLSERVERPROCW - #define PSYMBOLSERVERPINGPROC PSYMBOLSERVERPINGPROCW -#endif - -// ----------------------------------------------------------------- -// The following APIs exist only for backwards compatibility -// with a pre-release version documented in an MSDN release. - -// You should use SymFindFileInPath if you want to maintain -// future compatibility. - -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -FindFileInPath( - __in HANDLE hprocess, - __in PCSTR SearchPath, - __in PCSTR FileName, - __in PVOID id, - __in DWORD two, - __in DWORD three, - __in DWORD flags, - __out_ecount(MAX_PATH + 1) PSTR FilePath - ); - -// You should use SymFindFileInPath if you want to maintain -// future compatibility. - -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -FindFileInSearchPath( - __in HANDLE hprocess, - __in PCSTR SearchPath, - __in PCSTR FileName, - __in DWORD one, - __in DWORD two, - __in DWORD three, - __out_ecount(MAX_PATH + 1) PSTR FilePath - ); - -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -SymEnumSym( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext - ); - -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -SymEnumerateSymbols64( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback, - __in_opt PVOID UserContext - ); - -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -SymEnumerateSymbolsW64( - __in HANDLE hProcess, - __in ULONG64 BaseOfDll, - __in PSYM_ENUMSYMBOLS_CALLBACK64W EnumSymbolsCallback, - __in_opt PVOID UserContext - ); - - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymEnumerateSymbols SymEnumerateSymbols64 -#define SymEnumerateSymbolsW SymEnumerateSymbolsW64 -#else -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -SymEnumerateSymbols( - __in HANDLE hProcess, - __in ULONG BaseOfDll, - __in PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, - __in_opt PVOID UserContext - ); - -DBHLP_DEPRECIATED -BOOL -IMAGEAPI -SymEnumerateSymbolsW( - __in HANDLE hProcess, - __in ULONG BaseOfDll, - __in PSYM_ENUMSYMBOLS_CALLBACKW EnumSymbolsCallback, - __in_opt PVOID UserContext - ); -#endif - -// use SymLoadModuleEx - -DWORD64 -IMAGEAPI -SymLoadModule64( - __in HANDLE hProcess, - __in_opt HANDLE hFile, - __in_opt PCSTR ImageName, - __in_opt PCSTR ModuleName, - __in DWORD64 BaseOfDll, - __in DWORD SizeOfDll - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymLoadModule SymLoadModule64 -#else -DWORD -IMAGEAPI -SymLoadModule( - __in HANDLE hProcess, - __in_opt HANDLE hFile, - __in_opt PCSTR ImageName, - __in_opt PCSTR ModuleName, - __in DWORD BaseOfDll, - __in DWORD SizeOfDll - ); -#endif - -BOOL -IMAGEAPI -SymGetSymNext64( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOL64 Symbol - ); - -BOOL -IMAGEAPI -SymGetSymNextW64( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOLW64 Symbol - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetSymNext SymGetSymNext64 -#define SymGetSymNextW SymGetSymNextW64 -#else -BOOL -IMAGEAPI -SymGetSymNext( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOL Symbol - ); - -BOOL -IMAGEAPI -SymGetSymNextW( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOLW Symbol - ); -#endif - -BOOL -IMAGEAPI -SymGetSymPrev64( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOL64 Symbol - ); - -BOOL -IMAGEAPI -SymGetSymPrevW64( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOLW64 Symbol - ); - -#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) -#define SymGetSymPrev SymGetSymPrev64 -#define SymGetSymPrevW SymGetSymPrevW64 -#else -BOOL -IMAGEAPI -SymGetSymPrev( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOL Symbol - ); - -BOOL -IMAGEAPI -SymGetSymPrevW( - __in HANDLE hProcess, - __inout PIMAGEHLP_SYMBOLW Symbol - ); -#endif - - -// These values should not be used. -// They have been replaced by SYMFLAG_ values. - -#define SYMF_OMAP_GENERATED 0x00000001 -#define SYMF_OMAP_MODIFIED 0x00000002 -#define SYMF_REGISTER 0x00000008 -#define SYMF_REGREL 0x00000010 -#define SYMF_FRAMEREL 0x00000020 -#define SYMF_PARAMETER 0x00000040 -#define SYMF_LOCAL 0x00000080 -#define SYMF_CONSTANT 0x00000100 -#define SYMF_EXPORT 0x00000200 -#define SYMF_FORWARDER 0x00000400 -#define SYMF_FUNCTION 0x00000800 -#define SYMF_VIRTUAL 0x00001000 -#define SYMF_THUNK 0x00002000 -#define SYMF_TLSREL 0x00004000 - -// These values should also not be used. -// They have been replaced by SYMFLAG_ values. - -#define IMAGEHLP_SYMBOL_INFO_VALUEPRESENT 1 -#define IMAGEHLP_SYMBOL_INFO_REGISTER SYMF_REGISTER // 0x0008 -#define IMAGEHLP_SYMBOL_INFO_REGRELATIVE SYMF_REGREL // 0x0010 -#define IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE SYMF_FRAMEREL // 0x0020 -#define IMAGEHLP_SYMBOL_INFO_PARAMETER SYMF_PARAMETER // 0x0040 -#define IMAGEHLP_SYMBOL_INFO_LOCAL SYMF_LOCAL // 0x0080 -#define IMAGEHLP_SYMBOL_INFO_CONSTANT SYMF_CONSTANT // 0x0100 -#define IMAGEHLP_SYMBOL_FUNCTION SYMF_FUNCTION // 0x0800 -#define IMAGEHLP_SYMBOL_VIRTUAL SYMF_VIRTUAL // 0x1000 -#define IMAGEHLP_SYMBOL_THUNK SYMF_THUNK // 0x2000 -#define IMAGEHLP_SYMBOL_INFO_TLSRELATIVE SYMF_TLSREL // 0x4000 - - -#include - -#if defined(_MSC_VER) -#if _MSC_VER >= 800 -#if _MSC_VER >= 1200 -#pragma warning(push) -#endif -#pragma warning(disable:4200) /* Zero length array */ -#pragma warning(disable:4201) /* Nameless struct/union */ -#endif -#endif - -#define MINIDUMP_SIGNATURE ('PMDM') -#define MINIDUMP_VERSION (42899) -typedef DWORD RVA; -typedef ULONG64 RVA64; - -typedef struct _MINIDUMP_LOCATION_DESCRIPTOR { - ULONG32 DataSize; - RVA Rva; -} MINIDUMP_LOCATION_DESCRIPTOR; - -typedef struct _MINIDUMP_LOCATION_DESCRIPTOR64 { - ULONG64 DataSize; - RVA64 Rva; -} MINIDUMP_LOCATION_DESCRIPTOR64; - - -typedef struct _MINIDUMP_MEMORY_DESCRIPTOR { - ULONG64 StartOfMemoryRange; - MINIDUMP_LOCATION_DESCRIPTOR Memory; -} MINIDUMP_MEMORY_DESCRIPTOR, *PMINIDUMP_MEMORY_DESCRIPTOR; - -// DESCRIPTOR64 is used for full-memory minidumps where -// all of the raw memory is laid out sequentially at the -// end of the dump. There is no need for individual RVAs -// as the RVA is the base RVA plus the sum of the preceeding -// data blocks. -typedef struct _MINIDUMP_MEMORY_DESCRIPTOR64 { - ULONG64 StartOfMemoryRange; - ULONG64 DataSize; -} MINIDUMP_MEMORY_DESCRIPTOR64, *PMINIDUMP_MEMORY_DESCRIPTOR64; - - -typedef struct _MINIDUMP_HEADER { - ULONG32 Signature; - ULONG32 Version; - ULONG32 NumberOfStreams; - RVA StreamDirectoryRva; - ULONG32 CheckSum; - union { - ULONG32 Reserved; - ULONG32 TimeDateStamp; - }; - ULONG64 Flags; -} MINIDUMP_HEADER, *PMINIDUMP_HEADER; - -// -// The MINIDUMP_HEADER field StreamDirectoryRva points to -// an array of MINIDUMP_DIRECTORY structures. -// - -typedef struct _MINIDUMP_DIRECTORY { - ULONG32 StreamType; - MINIDUMP_LOCATION_DESCRIPTOR Location; -} MINIDUMP_DIRECTORY, *PMINIDUMP_DIRECTORY; - - -typedef struct _MINIDUMP_STRING { - ULONG32 Length; // Length in bytes of the string - WCHAR Buffer [0]; // Variable size buffer -} MINIDUMP_STRING, *PMINIDUMP_STRING; - - - -// -// The MINIDUMP_DIRECTORY field StreamType may be one of the following types. -// Types will be added in the future, so if a program reading the minidump -// header encounters a stream type it does not understand it should ignore -// the data altogether. Any tag above LastReservedStream will not be used by -// the system and is reserved for program-specific information. -// - -typedef enum _MINIDUMP_STREAM_TYPE { - - UnusedStream = 0, - ReservedStream0 = 1, - ReservedStream1 = 2, - ThreadListStream = 3, - ModuleListStream = 4, - MemoryListStream = 5, - ExceptionStream = 6, - SystemInfoStream = 7, - ThreadExListStream = 8, - Memory64ListStream = 9, - CommentStreamA = 10, - CommentStreamW = 11, - HandleDataStream = 12, - FunctionTableStream = 13, - UnloadedModuleListStream = 14, - MiscInfoStream = 15, - MemoryInfoListStream = 16, - ThreadInfoListStream = 17, - HandleOperationListStream = 18, - - ceStreamNull = 0x8000, - ceStreamSystemInfo = 0x8001, - ceStreamException = 0x8002, - ceStreamModuleList = 0x8003, - ceStreamProcessList = 0x8004, - ceStreamThreadList = 0x8005, - ceStreamThreadContextList = 0x8006, - ceStreamThreadCallStackList = 0x8007, - ceStreamMemoryVirtualList = 0x8008, - ceStreamMemoryPhysicalList = 0x8009, - ceStreamBucketParameters = 0x800A, - - LastReservedStream = 0xffff - -} MINIDUMP_STREAM_TYPE; - - -// -// The minidump system information contains processor and -// Operating System specific information. -// - -// -// CPU information is obtained from one of two places. -// -// 1) On x86 computers, CPU_INFORMATION is obtained from the CPUID -// instruction. You must use the X86 portion of the union for X86 -// computers. -// -// 2) On non-x86 architectures, CPU_INFORMATION is obtained by calling -// IsProcessorFeatureSupported(). -// - -typedef union _CPU_INFORMATION { - - // - // X86 platforms use CPUID function to obtain processor information. - // - - struct { - - // - // CPUID Subfunction 0, register EAX (VendorId [0]), - // EBX (VendorId [1]) and ECX (VendorId [2]). - // - - ULONG32 VendorId [ 3 ]; - - // - // CPUID Subfunction 1, register EAX - // - - ULONG32 VersionInformation; - - // - // CPUID Subfunction 1, register EDX - // - - ULONG32 FeatureInformation; - - - // - // CPUID, Subfunction 80000001, register EBX. This will only - // be obtained if the vendor id is "AuthenticAMD". - // - - ULONG32 AMDExtendedCpuFeatures; - - } X86CpuInfo; - - // - // Non-x86 platforms use processor feature flags. - // - - struct { - - ULONG64 ProcessorFeatures [ 2 ]; - - } OtherCpuInfo; - -} CPU_INFORMATION, *PCPU_INFORMATION; - -typedef struct _MINIDUMP_SYSTEM_INFO { - - // - // ProcessorArchitecture, ProcessorLevel and ProcessorRevision are all - // taken from the SYSTEM_INFO structure obtained by GetSystemInfo( ). - // - - USHORT ProcessorArchitecture; - USHORT ProcessorLevel; - USHORT ProcessorRevision; - - union { - USHORT Reserved0; - struct { - UCHAR NumberOfProcessors; - UCHAR ProductType; - }; - }; - - // - // MajorVersion, MinorVersion, BuildNumber, PlatformId and - // CSDVersion are all taken from the OSVERSIONINFO structure - // returned by GetVersionEx( ). - // - - ULONG32 MajorVersion; - ULONG32 MinorVersion; - ULONG32 BuildNumber; - ULONG32 PlatformId; - - // - // RVA to a CSDVersion string in the string table. - // - - RVA CSDVersionRva; - - union { - ULONG32 Reserved1; - struct { - USHORT SuiteMask; - USHORT Reserved2; - }; - }; - - CPU_INFORMATION Cpu; - -} MINIDUMP_SYSTEM_INFO, *PMINIDUMP_SYSTEM_INFO; - - -// -// The minidump thread contains standard thread -// information plus an RVA to the memory for this -// thread and an RVA to the CONTEXT structure for -// this thread. -// - - -// -// ThreadId must be 4 bytes on all architectures. -// - -C_ASSERT (sizeof ( ((PPROCESS_INFORMATION)0)->dwThreadId ) == 4); - -typedef struct _MINIDUMP_THREAD { - ULONG32 ThreadId; - ULONG32 SuspendCount; - ULONG32 PriorityClass; - ULONG32 Priority; - ULONG64 Teb; - MINIDUMP_MEMORY_DESCRIPTOR Stack; - MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; -} MINIDUMP_THREAD, *PMINIDUMP_THREAD; - -// -// The thread list is a container of threads. -// - -typedef struct _MINIDUMP_THREAD_LIST { - ULONG32 NumberOfThreads; - MINIDUMP_THREAD Threads [0]; -} MINIDUMP_THREAD_LIST, *PMINIDUMP_THREAD_LIST; - - -typedef struct _MINIDUMP_THREAD_EX { - ULONG32 ThreadId; - ULONG32 SuspendCount; - ULONG32 PriorityClass; - ULONG32 Priority; - ULONG64 Teb; - MINIDUMP_MEMORY_DESCRIPTOR Stack; - MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; - MINIDUMP_MEMORY_DESCRIPTOR BackingStore; -} MINIDUMP_THREAD_EX, *PMINIDUMP_THREAD_EX; - -// -// The thread list is a container of threads. -// - -typedef struct _MINIDUMP_THREAD_EX_LIST { - ULONG32 NumberOfThreads; - MINIDUMP_THREAD_EX Threads [0]; -} MINIDUMP_THREAD_EX_LIST, *PMINIDUMP_THREAD_EX_LIST; - - -// -// The MINIDUMP_EXCEPTION is the same as EXCEPTION on Win64. -// - -typedef struct _MINIDUMP_EXCEPTION { - ULONG32 ExceptionCode; - ULONG32 ExceptionFlags; - ULONG64 ExceptionRecord; - ULONG64 ExceptionAddress; - ULONG32 NumberParameters; - ULONG32 __unusedAlignment; - ULONG64 ExceptionInformation [ EXCEPTION_MAXIMUM_PARAMETERS ]; -} MINIDUMP_EXCEPTION, *PMINIDUMP_EXCEPTION; - - -// -// The exception information stream contains the id of the thread that caused -// the exception (ThreadId), the exception record for the exception -// (ExceptionRecord) and an RVA to the thread context where the exception -// occured. -// - -typedef struct MINIDUMP_EXCEPTION_STREAM { - ULONG32 ThreadId; - ULONG32 __alignment; - MINIDUMP_EXCEPTION ExceptionRecord; - MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; -} MINIDUMP_EXCEPTION_STREAM, *PMINIDUMP_EXCEPTION_STREAM; - - -// -// The MINIDUMP_MODULE contains information about a -// a specific module. It includes the CheckSum and -// the TimeDateStamp for the module so the module -// can be reloaded during the analysis phase. -// - -typedef struct _MINIDUMP_MODULE { - ULONG64 BaseOfImage; - ULONG32 SizeOfImage; - ULONG32 CheckSum; - ULONG32 TimeDateStamp; - RVA ModuleNameRva; - VS_FIXEDFILEINFO VersionInfo; - MINIDUMP_LOCATION_DESCRIPTOR CvRecord; - MINIDUMP_LOCATION_DESCRIPTOR MiscRecord; - ULONG64 Reserved0; // Reserved for future use. - ULONG64 Reserved1; // Reserved for future use. -} MINIDUMP_MODULE, *PMINIDUMP_MODULE; - - -// -// The minidump module list is a container for modules. -// - -typedef struct _MINIDUMP_MODULE_LIST { - ULONG32 NumberOfModules; - MINIDUMP_MODULE Modules [ 0 ]; -} MINIDUMP_MODULE_LIST, *PMINIDUMP_MODULE_LIST; - - -// -// Memory Ranges -// - -typedef struct _MINIDUMP_MEMORY_LIST { - ULONG32 NumberOfMemoryRanges; - MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges [0]; -} MINIDUMP_MEMORY_LIST, *PMINIDUMP_MEMORY_LIST; - -typedef struct _MINIDUMP_MEMORY64_LIST { - ULONG64 NumberOfMemoryRanges; - RVA64 BaseRva; - MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges [0]; -} MINIDUMP_MEMORY64_LIST, *PMINIDUMP_MEMORY64_LIST; - - -// -// Support for user supplied exception information. -// - -typedef struct _MINIDUMP_EXCEPTION_INFORMATION { - DWORD ThreadId; - PEXCEPTION_POINTERS ExceptionPointers; - BOOL ClientPointers; -} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; - -typedef struct _MINIDUMP_EXCEPTION_INFORMATION64 { - DWORD ThreadId; - ULONG64 ExceptionRecord; - ULONG64 ContextRecord; - BOOL ClientPointers; -} MINIDUMP_EXCEPTION_INFORMATION64, *PMINIDUMP_EXCEPTION_INFORMATION64; - - -// -// Support for capturing system handle state at the time of the dump. -// - -// Per-handle object information varies according to -// the OS, the OS version, the processor type and -// so on. The minidump gives a minidump identifier -// to each possible data format for identification -// purposes but does not control nor describe the actual data. -typedef enum _MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE { - MiniHandleObjectInformationNone, - MiniThreadInformation1, - MiniMutantInformation1, - MiniMutantInformation2, - MiniProcessInformation1, - MiniProcessInformation2, - MiniHandleObjectInformationTypeMax -} MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE; - -typedef struct _MINIDUMP_HANDLE_OBJECT_INFORMATION { - RVA NextInfoRva; - ULONG32 InfoType; - ULONG32 SizeOfInfo; - // Raw information follows. -} MINIDUMP_HANDLE_OBJECT_INFORMATION; - -typedef struct _MINIDUMP_HANDLE_DESCRIPTOR { - ULONG64 Handle; - RVA TypeNameRva; - RVA ObjectNameRva; - ULONG32 Attributes; - ULONG32 GrantedAccess; - ULONG32 HandleCount; - ULONG32 PointerCount; -} MINIDUMP_HANDLE_DESCRIPTOR, *PMINIDUMP_HANDLE_DESCRIPTOR; - -typedef struct _MINIDUMP_HANDLE_DESCRIPTOR_2 { - ULONG64 Handle; - RVA TypeNameRva; - RVA ObjectNameRva; - ULONG32 Attributes; - ULONG32 GrantedAccess; - ULONG32 HandleCount; - ULONG32 PointerCount; - RVA ObjectInfoRva; - ULONG32 Reserved0; -} MINIDUMP_HANDLE_DESCRIPTOR_2, *PMINIDUMP_HANDLE_DESCRIPTOR_2; - -// The latest MINIDUMP_HANDLE_DESCRIPTOR definition. -typedef MINIDUMP_HANDLE_DESCRIPTOR_2 MINIDUMP_HANDLE_DESCRIPTOR_N; -typedef MINIDUMP_HANDLE_DESCRIPTOR_N *PMINIDUMP_HANDLE_DESCRIPTOR_N; - -typedef struct _MINIDUMP_HANDLE_DATA_STREAM { - ULONG32 SizeOfHeader; - ULONG32 SizeOfDescriptor; - ULONG32 NumberOfDescriptors; - ULONG32 Reserved; -} MINIDUMP_HANDLE_DATA_STREAM, *PMINIDUMP_HANDLE_DATA_STREAM; - -// Some operating systems can track the last operations -// performed on a handle. For example, Application Verifier -// can enable this for some versions of Windows. The -// handle operation list collects handle operations -// known for the dump target. -// Each entry is an AVRF_HANDLE_OPERATION. -typedef struct _MINIDUMP_HANDLE_OPERATION_LIST { - ULONG32 SizeOfHeader; - ULONG32 SizeOfEntry; - ULONG32 NumberOfEntries; - ULONG32 Reserved; -} MINIDUMP_HANDLE_OPERATION_LIST, *PMINIDUMP_HANDLE_OPERATION_LIST; - - -// -// Support for capturing dynamic function table state at the time of the dump. -// - -typedef struct _MINIDUMP_FUNCTION_TABLE_DESCRIPTOR { - ULONG64 MinimumAddress; - ULONG64 MaximumAddress; - ULONG64 BaseAddress; - ULONG32 EntryCount; - ULONG32 SizeOfAlignPad; -} MINIDUMP_FUNCTION_TABLE_DESCRIPTOR, *PMINIDUMP_FUNCTION_TABLE_DESCRIPTOR; - -typedef struct _MINIDUMP_FUNCTION_TABLE_STREAM { - ULONG32 SizeOfHeader; - ULONG32 SizeOfDescriptor; - ULONG32 SizeOfNativeDescriptor; - ULONG32 SizeOfFunctionEntry; - ULONG32 NumberOfDescriptors; - ULONG32 SizeOfAlignPad; -} MINIDUMP_FUNCTION_TABLE_STREAM, *PMINIDUMP_FUNCTION_TABLE_STREAM; - - -// -// The MINIDUMP_UNLOADED_MODULE contains information about a -// a specific module that was previously loaded but no -// longer is. This can help with diagnosing problems where -// callers attempt to call code that is no longer loaded. -// - -typedef struct _MINIDUMP_UNLOADED_MODULE { - ULONG64 BaseOfImage; - ULONG32 SizeOfImage; - ULONG32 CheckSum; - ULONG32 TimeDateStamp; - RVA ModuleNameRva; -} MINIDUMP_UNLOADED_MODULE, *PMINIDUMP_UNLOADED_MODULE; - - -// -// The minidump unloaded module list is a container for unloaded modules. -// - -typedef struct _MINIDUMP_UNLOADED_MODULE_LIST { - ULONG32 SizeOfHeader; - ULONG32 SizeOfEntry; - ULONG32 NumberOfEntries; -} MINIDUMP_UNLOADED_MODULE_LIST, *PMINIDUMP_UNLOADED_MODULE_LIST; - - -// -// The miscellaneous information stream contains a variety -// of small pieces of information. A member is valid if -// it's within the available size and its corresponding -// bit is set. -// - -#define MINIDUMP_MISC1_PROCESS_ID 0x00000001 -#define MINIDUMP_MISC1_PROCESS_TIMES 0x00000002 -#define MINIDUMP_MISC1_PROCESSOR_POWER_INFO 0x00000004 - -typedef struct _MINIDUMP_MISC_INFO { - ULONG32 SizeOfInfo; - ULONG32 Flags1; - ULONG32 ProcessId; - ULONG32 ProcessCreateTime; - ULONG32 ProcessUserTime; - ULONG32 ProcessKernelTime; -} MINIDUMP_MISC_INFO, *PMINIDUMP_MISC_INFO; - -typedef struct _MINIDUMP_MISC_INFO_2 { - ULONG32 SizeOfInfo; - ULONG32 Flags1; - ULONG32 ProcessId; - ULONG32 ProcessCreateTime; - ULONG32 ProcessUserTime; - ULONG32 ProcessKernelTime; - ULONG32 ProcessorMaxMhz; - ULONG32 ProcessorCurrentMhz; - ULONG32 ProcessorMhzLimit; - ULONG32 ProcessorMaxIdleState; - ULONG32 ProcessorCurrentIdleState; -} MINIDUMP_MISC_INFO_2, *PMINIDUMP_MISC_INFO_2; - -// The latest MINIDUMP_MISC_INFO definition. -typedef MINIDUMP_MISC_INFO_2 MINIDUMP_MISC_INFO_N; -typedef MINIDUMP_MISC_INFO_N* PMINIDUMP_MISC_INFO_N; - - -// -// The memory information stream contains memory region -// description information. This stream corresponds to -// what VirtualQuery would return for the process the -// dump was created for. -// - -typedef struct _MINIDUMP_MEMORY_INFO { - ULONG64 BaseAddress; - ULONG64 AllocationBase; - ULONG32 AllocationProtect; - ULONG32 __alignment1; - ULONG64 RegionSize; - ULONG32 State; - ULONG32 Protect; - ULONG32 Type; - ULONG32 __alignment2; -} MINIDUMP_MEMORY_INFO, *PMINIDUMP_MEMORY_INFO; - -typedef struct _MINIDUMP_MEMORY_INFO_LIST { - ULONG SizeOfHeader; - ULONG SizeOfEntry; - ULONG64 NumberOfEntries; -} MINIDUMP_MEMORY_INFO_LIST, *PMINIDUMP_MEMORY_INFO_LIST; - - -// -// The memory information stream contains memory region -// description information. This stream corresponds to -// what VirtualQuery would return for the process the -// dump was created for. -// - -// Thread dump writer status flags. -#define MINIDUMP_THREAD_INFO_ERROR_THREAD 0x00000001 -#define MINIDUMP_THREAD_INFO_WRITING_THREAD 0x00000002 -#define MINIDUMP_THREAD_INFO_EXITED_THREAD 0x00000004 -#define MINIDUMP_THREAD_INFO_INVALID_INFO 0x00000008 -#define MINIDUMP_THREAD_INFO_INVALID_CONTEXT 0x00000010 -#define MINIDUMP_THREAD_INFO_INVALID_TEB 0x00000020 - -typedef struct _MINIDUMP_THREAD_INFO { - ULONG32 ThreadId; - ULONG32 DumpFlags; - ULONG32 DumpError; - ULONG32 ExitStatus; - ULONG64 CreateTime; - ULONG64 ExitTime; - ULONG64 KernelTime; - ULONG64 UserTime; - ULONG64 StartAddress; - ULONG64 Affinity; -} MINIDUMP_THREAD_INFO, *PMINIDUMP_THREAD_INFO; - -typedef struct _MINIDUMP_THREAD_INFO_LIST { - ULONG SizeOfHeader; - ULONG SizeOfEntry; - ULONG NumberOfEntries; -} MINIDUMP_THREAD_INFO_LIST, *PMINIDUMP_THREAD_INFO_LIST; - - -// -// Support for arbitrary user-defined information. -// - -typedef struct _MINIDUMP_USER_RECORD { - ULONG32 Type; - MINIDUMP_LOCATION_DESCRIPTOR Memory; -} MINIDUMP_USER_RECORD, *PMINIDUMP_USER_RECORD; - - -typedef struct _MINIDUMP_USER_STREAM { - ULONG32 Type; - ULONG BufferSize; - PVOID Buffer; - -} MINIDUMP_USER_STREAM, *PMINIDUMP_USER_STREAM; - - -typedef struct _MINIDUMP_USER_STREAM_INFORMATION { - ULONG UserStreamCount; - PMINIDUMP_USER_STREAM UserStreamArray; -} MINIDUMP_USER_STREAM_INFORMATION, *PMINIDUMP_USER_STREAM_INFORMATION; - -// -// Callback support. -// - -typedef enum _MINIDUMP_CALLBACK_TYPE { - ModuleCallback, - ThreadCallback, - ThreadExCallback, - IncludeThreadCallback, - IncludeModuleCallback, - MemoryCallback, - CancelCallback, - WriteKernelMinidumpCallback, - KernelMinidumpStatusCallback, - RemoveMemoryCallback, - IncludeVmRegionCallback, - IoStartCallback, - IoWriteAllCallback, - IoFinishCallback, - ReadMemoryFailureCallback, - SecondaryFlagsCallback, -} MINIDUMP_CALLBACK_TYPE; - - -typedef struct _MINIDUMP_THREAD_CALLBACK { - ULONG ThreadId; - HANDLE ThreadHandle; - CONTEXT Context; - ULONG SizeOfContext; - ULONG64 StackBase; - ULONG64 StackEnd; -} MINIDUMP_THREAD_CALLBACK, *PMINIDUMP_THREAD_CALLBACK; - - -typedef struct _MINIDUMP_THREAD_EX_CALLBACK { - ULONG ThreadId; - HANDLE ThreadHandle; - CONTEXT Context; - ULONG SizeOfContext; - ULONG64 StackBase; - ULONG64 StackEnd; - ULONG64 BackingStoreBase; - ULONG64 BackingStoreEnd; -} MINIDUMP_THREAD_EX_CALLBACK, *PMINIDUMP_THREAD_EX_CALLBACK; - - -typedef struct _MINIDUMP_INCLUDE_THREAD_CALLBACK { - ULONG ThreadId; -} MINIDUMP_INCLUDE_THREAD_CALLBACK, *PMINIDUMP_INCLUDE_THREAD_CALLBACK; - - -typedef enum _THREAD_WRITE_FLAGS { - ThreadWriteThread = 0x0001, - ThreadWriteStack = 0x0002, - ThreadWriteContext = 0x0004, - ThreadWriteBackingStore = 0x0008, - ThreadWriteInstructionWindow = 0x0010, - ThreadWriteThreadData = 0x0020, - ThreadWriteThreadInfo = 0x0040, -} THREAD_WRITE_FLAGS; - -typedef struct _MINIDUMP_MODULE_CALLBACK { - PWCHAR FullPath; - ULONG64 BaseOfImage; - ULONG SizeOfImage; - ULONG CheckSum; - ULONG TimeDateStamp; - VS_FIXEDFILEINFO VersionInfo; - PVOID CvRecord; - ULONG SizeOfCvRecord; - PVOID MiscRecord; - ULONG SizeOfMiscRecord; -} MINIDUMP_MODULE_CALLBACK, *PMINIDUMP_MODULE_CALLBACK; - - -typedef struct _MINIDUMP_INCLUDE_MODULE_CALLBACK { - ULONG64 BaseOfImage; -} MINIDUMP_INCLUDE_MODULE_CALLBACK, *PMINIDUMP_INCLUDE_MODULE_CALLBACK; - - -typedef enum _MODULE_WRITE_FLAGS { - ModuleWriteModule = 0x0001, - ModuleWriteDataSeg = 0x0002, - ModuleWriteMiscRecord = 0x0004, - ModuleWriteCvRecord = 0x0008, - ModuleReferencedByMemory = 0x0010, - ModuleWriteTlsData = 0x0020, - ModuleWriteCodeSegs = 0x0040, -} MODULE_WRITE_FLAGS; - - -typedef struct _MINIDUMP_IO_CALLBACK { - HANDLE Handle; - ULONG64 Offset; - PVOID Buffer; - ULONG BufferBytes; -} MINIDUMP_IO_CALLBACK, *PMINIDUMP_IO_CALLBACK; - - -typedef struct _MINIDUMP_READ_MEMORY_FAILURE_CALLBACK -{ - ULONG64 Offset; - ULONG Bytes; - HRESULT FailureStatus; -} MINIDUMP_READ_MEMORY_FAILURE_CALLBACK, - *PMINIDUMP_READ_MEMORY_FAILURE_CALLBACK; - - -typedef struct _MINIDUMP_CALLBACK_INPUT { - ULONG ProcessId; - HANDLE ProcessHandle; - ULONG CallbackType; - union { - HRESULT Status; - MINIDUMP_THREAD_CALLBACK Thread; - MINIDUMP_THREAD_EX_CALLBACK ThreadEx; - MINIDUMP_MODULE_CALLBACK Module; - MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread; - MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule; - MINIDUMP_IO_CALLBACK Io; - MINIDUMP_READ_MEMORY_FAILURE_CALLBACK ReadMemoryFailure; - ULONG SecondaryFlags; - }; -} MINIDUMP_CALLBACK_INPUT, *PMINIDUMP_CALLBACK_INPUT; - -typedef struct _MINIDUMP_CALLBACK_OUTPUT { - union { - ULONG ModuleWriteFlags; - ULONG ThreadWriteFlags; - ULONG SecondaryFlags; - struct { - ULONG64 MemoryBase; - ULONG MemorySize; - }; - struct { - BOOL CheckCancel; - BOOL Cancel; - }; - HANDLE Handle; - struct { - MINIDUMP_MEMORY_INFO VmRegion; - BOOL Continue; - }; - HRESULT Status; - }; -} MINIDUMP_CALLBACK_OUTPUT, *PMINIDUMP_CALLBACK_OUTPUT; - - -// -// A normal minidump contains just the information -// necessary to capture stack traces for all of the -// existing threads in a process. -// -// A minidump with data segments includes all of the data -// sections from loaded modules in order to capture -// global variable contents. This can make the dump much -// larger if many modules have global data. -// -// A minidump with full memory includes all of the accessible -// memory in the process and can be very large. A minidump -// with full memory always has the raw memory data at the end -// of the dump so that the initial structures in the dump can -// be mapped directly without having to include the raw -// memory information. -// -// Stack and backing store memory can be filtered to remove -// data unnecessary for stack walking. This can improve -// compression of stacks and also deletes data that may -// be private and should not be stored in a dump. -// Memory can also be scanned to see what modules are -// referenced by stack and backing store memory to allow -// omission of other modules to reduce dump size. -// In either of these modes the ModuleReferencedByMemory flag -// is set for all modules referenced before the base -// module callbacks occur. -// -// On some operating systems a list of modules that were -// recently unloaded is kept in addition to the currently -// loaded module list. This information can be saved in -// the dump if desired. -// -// Stack and backing store memory can be scanned for referenced -// pages in order to pick up data referenced by locals or other -// stack memory. This can increase the size of a dump significantly. -// -// Module paths may contain undesired information such as user names -// or other important directory names so they can be stripped. This -// option reduces the ability to locate the proper image later -// and should only be used in certain situations. -// -// Complete operating system per-process and per-thread information can -// be gathered and stored in the dump. -// -// The virtual address space can be scanned for various types -// of memory to be included in the dump. -// -// Code which is concerned with potentially private information -// getting into the minidump can set a flag that automatically -// modifies all existing and future flags to avoid placing -// unnecessary data in the dump. Basic data, such as stack -// information, will still be included but optional data, such -// as indirect memory, will not. -// -// When doing a full memory dump it's possible to store all -// of the enumerated memory region descriptive information -// in a memory information stream. -// -// Additional thread information beyond the basic thread -// structure can be collected if desired. -// -// A minidump with code segments includes all of the code -// and code-related sections from loaded modules in order -// to capture executable content. -// -// MiniDumpWithoutAuxiliaryState turns off any secondary, -// auxiliary-supported memory gathering. -// -// MiniDumpWithFullAuxiliaryState asks any present auxiliary -// data providers to include all of their state in the dump. -// The exact set of what is provided depends on the auxiliary. -// This can be quite large. -// - -typedef enum _MINIDUMP_TYPE { - MiniDumpNormal = 0x00000000, - MiniDumpWithDataSegs = 0x00000001, - MiniDumpWithFullMemory = 0x00000002, - MiniDumpWithHandleData = 0x00000004, - MiniDumpFilterMemory = 0x00000008, - MiniDumpScanMemory = 0x00000010, - MiniDumpWithUnloadedModules = 0x00000020, - MiniDumpWithIndirectlyReferencedMemory = 0x00000040, - MiniDumpFilterModulePaths = 0x00000080, - MiniDumpWithProcessThreadData = 0x00000100, - MiniDumpWithPrivateReadWriteMemory = 0x00000200, - MiniDumpWithoutOptionalData = 0x00000400, - MiniDumpWithFullMemoryInfo = 0x00000800, - MiniDumpWithThreadInfo = 0x00001000, - MiniDumpWithCodeSegs = 0x00002000, - MiniDumpWithoutAuxiliaryState = 0x00004000, - MiniDumpWithFullAuxiliaryState = 0x00008000, - - MiniDumpValidTypeFlags = 0x0000ffff, -} MINIDUMP_TYPE; - -// -// In addition to the primary flags provided to -// MiniDumpWriteDump there are additional, less -// frequently used options queried via the secondary -// flags callback. -// -// MiniSecondaryWithoutPowerInfo suppresses the minidump -// query that retrieves processor power information for -// MINIDUMP_MISC_INFO. -// - -typedef enum _MINIDUMP_SECONDARY_FLAGS { - MiniSecondaryWithoutPowerInfo = 0x00000001, - - MiniSecondaryValidFlags = 0x00000001, -} MINIDUMP_SECONDARY_FLAGS; - - -// -// The minidump callback should modify the FieldsToWrite parameter to reflect -// what portions of the specified thread or module should be written to the -// file. -// - -typedef -BOOL -(WINAPI * MINIDUMP_CALLBACK_ROUTINE) ( - IN PVOID CallbackParam, - IN CONST PMINIDUMP_CALLBACK_INPUT CallbackInput, - IN OUT PMINIDUMP_CALLBACK_OUTPUT CallbackOutput - ); - -typedef struct _MINIDUMP_CALLBACK_INFORMATION { - MINIDUMP_CALLBACK_ROUTINE CallbackRoutine; - PVOID CallbackParam; -} MINIDUMP_CALLBACK_INFORMATION, *PMINIDUMP_CALLBACK_INFORMATION; - - - -//++ -// -// PVOID -// RVA_TO_ADDR( -// PVOID Mapping, -// ULONG Rva -// ) -// -// Routine Description: -// -// Map an RVA that is contained within a mapped file to it's associated -// flat address. -// -// Arguments: -// -// Mapping - Base address of mapped file containing the RVA. -// -// Rva - An Rva to fixup. -// -// Return Values: -// -// A pointer to the desired data. -// -//-- - -#define RVA_TO_ADDR(Mapping,Rva) ((PVOID)(((ULONG_PTR) (Mapping)) + (Rva))) - -BOOL -WINAPI -MiniDumpWriteDump( - IN HANDLE hProcess, - IN DWORD ProcessId, - IN HANDLE hFile, - IN MINIDUMP_TYPE DumpType, - IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL - IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL - IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL - ); - -BOOL -WINAPI -MiniDumpReadDumpStream( - IN PVOID BaseOfDump, - IN ULONG StreamNumber, - OUT PMINIDUMP_DIRECTORY * Dir, OPTIONAL - OUT PVOID * StreamPointer, OPTIONAL - OUT ULONG * StreamSize OPTIONAL - ); - -#if defined(_MSC_VER) -#if _MSC_VER >= 800 -#if _MSC_VER >= 1200 -#pragma warning(pop) -#else -#pragma warning(default:4200) /* Zero length array */ -#pragma warning(default:4201) /* Nameless struct/union */ -#endif -#endif -#endif - -#include - -#ifdef __cplusplus -} -#endif - - -#endif // _DBGHELP_ diff --git a/plugins/CrashDumper/vc6/dbghelp.lib b/plugins/CrashDumper/vc6/dbghelp.lib deleted file mode 100644 index 5d50c3f74d..0000000000 Binary files a/plugins/CrashDumper/vc6/dbghelp.lib and /dev/null differ diff --git a/plugins/CrashDumper/version.h b/plugins/CrashDumper/version.h deleted file mode 100644 index 776e30e404..0000000000 --- a/plugins/CrashDumper/version.h +++ /dev/null @@ -1,3 +0,0 @@ -#define __FILEVERSION_STRING 0,0,4,21 -#define __VERSION_STRING "0.0.4.21" -#define __VERSION_DWORD PLUGIN_MAKE_VERSION(0, 0, 4, 21) -- cgit v1.2.3