/* IRC plugin for Miranda IM Copyright (C) 2003 Jörgen Persson 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 "irc.h" extern char * IRCPROTONAME; extern BYTE gbUtfLangpack; extern BYTE gbUnicodeAPI; static BOOL bUtfReadyDB = FALSE; void InitDB() { bUtfReadyDB = ServiceExists(MS_DB_CONTACT_GETSETTING_STR); #ifdef _DEBUG if (!bUtfReadyDB) DBGprintf("Warning: DB module does not support Unicode\n"); #endif } HANDLE GetContactByName(const char* NickName) { HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); DBVARIANT dbv; DBCONTACTGETSETTING dcs; HANDLE f=hContact; while (hContact) { char*szProto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hContact, 0); //HACK: here just replaced by lstrcmpiA if (szProto != NULL && !lstrcmpiA(szProto, IRCPROTONAME)) { dcs.szModule=IRCPROTONAME; dcs.szSetting="Nick"; dcs.pValue=&dbv; dbv.type=DBVT_ASCIIZ; CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)hContact,(LPARAM)&dcs); if(!strcmp(NickName,dbv.pszVal)) { return hContact; f=0; } CallService(MS_DB_CONTACT_FREEVARIANT,0,(LPARAM)(DBVARIANT*)&dbv); DBFreeVariant(&dbv); } hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); } if(f) { return hContact; } return NULL; } //HANDLE GetHandleFromNick(char *displayname) //{ // HANDLE hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); // char *nick, *nickfind; // nick = (char *) malloc (strlen(displayname) + 1); // nick = _strupr(_strdup(displayname)); // while (hContact != NULL) { // nickfind = (char *) malloc (strlen(GetNickFromHandle(hContact)) + 1); // nickfind = _strupr(_strdup(GetNickFromHandle(hContact))); // if (!strcmp(nickfind, nick)) // break; // free(nickfind); // hContact = (HANDLE) CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM) hContact, 0); // } // free(nickfind); // free(nick); // return hContact; //} char* calcMD5Hash(char* szFile) { md5_state_t state; md5_byte_t digest[16]; if (szFile) { HANDLE hFile = NULL, hMap = NULL; BYTE* ppMap = NULL; long cbFileSize = 0; char* res; if ((hFile = #ifdef _UNICODE CreateFile((LPCWSTR)szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL )) != INVALID_HANDLE_VALUE) #else CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL )) != INVALID_HANDLE_VALUE) #endif if ((hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL) if ((ppMap = (BYTE*)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL) cbFileSize = GetFileSize( hFile, NULL ); res = (char *)malloc(16*sizeof(char)); if (cbFileSize != 0 && res) { md5_init(&state); md5_append(&state, (const md5_byte_t *)ppMap, cbFileSize); md5_finish(&state, digest); memcpy(res, digest, 16); } if (ppMap != NULL) UnmapViewOfFile(ppMap); if (hMap != NULL) CloseHandle(hMap); if (hFile != NULL) CloseHandle(hFile); if (res) return res; } return NULL; } void EnableDlgItem(HWND hwndDlg, UINT control, int state) { EnableWindow(GetDlgItem(hwndDlg, control), state); } void IRC_EnableMultipleControls(HWND hwndDlg, const UINT *controls, int cControls, int state) { int i; for (i = 0; i < cControls; i++) EnableDlgItem(hwndDlg, controls[i], state); } int IRCGetContactSetting(HANDLE hContact, const char* szSetting, DBVARIANT *dbv) { return DBGetContactSetting(hContact, IRCPROTONAME, szSetting, dbv); } BYTE IRCGetContactSettingByte(HANDLE hContact, const char* szSetting, BYTE bDef) { return DBGetContactSettingByte(hContact, IRCPROTONAME, szSetting, bDef); } int IRCWriteContactSettingByte(HANDLE hContact, const char* szSetting, BYTE bValue) { return DBWriteContactSettingByte(hContact, IRCPROTONAME, szSetting, bValue); } DWORD IRCGetContactSettingDword(HANDLE hContact, const char* szSetting, DWORD dwDef) { DBVARIANT dbv; DBCONTACTGETSETTING cgs; DWORD dwRes; cgs.szModule = IRCPROTONAME; cgs.szSetting = szSetting; cgs.pValue = &dbv; if (CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)hContact,(LPARAM)&cgs)) return dwDef; // not found, give default if (dbv.type != DBVT_DWORD) dwRes = dwDef; // invalid type, give default else // found and valid, give result dwRes = dbv.dVal; IRCFreeVariant(&dbv); return dwRes; } int IRCWriteContactSettingDword(HANDLE hContact, const char* szSetting, DWORD dwValue) { return DBWriteContactSettingDword(hContact, IRCPROTONAME, szSetting, dwValue); } char* IRCGetContactSettingString(HANDLE hContact, const char* szSetting, char* szValue) { DBVARIANT dbv; DBCONTACTGETSETTING dcs; char* szRes; dcs.szModule=IRCPROTONAME; dcs.szSetting=szSetting; dcs.pValue=&dbv; dbv.type=DBVT_ASCIIZ; if(CallService(MS_DB_CONTACT_GETSETTING,(WPARAM)hContact,(LPARAM)&dcs) != 0) szRes = szValue; else szRes = dbv.pszVal; DBFreeVariant(&dbv); return szRes; } int IRCWriteContactSettingString(HANDLE hContact, const char* szSetting, char* szValue) { return DBWriteContactSettingString(hContact, IRCPROTONAME, szSetting, szValue); } int IRCDeleteContactSetting(HANDLE hContact, const char* szSetting) { return DBDeleteContactSetting(hContact, IRCPROTONAME, szSetting); } char* UniGetContactSettingUtf(HANDLE hContact, const char *szModule,const char* szSetting, char* szDef) { DBVARIANT dbv = {DBVT_DELETED}; char* szRes; if (bUtfReadyDB) { if (DBGetContactSettingStringUtf(hContact, szModule, szSetting, &dbv)) return null_strdup(szDef); szRes = null_strdup(dbv.pszVal); IRCFreeVariant(&dbv); } else { // old DB, we need to convert the string to UTF-8 if (DBGetContactSetting(hContact, szModule, szSetting, &dbv)) return null_strdup(szDef); szRes = ansi_to_utf8(dbv.pszVal); IRCFreeVariant(&dbv); } return szRes; } int UniWriteContactSettingUtf(HANDLE hContact, const char *szModule, const char* szSetting, char* szValue) { if (bUtfReadyDB) return DBWriteContactSettingStringUtf(hContact, szModule, szSetting, szValue); else { // old DB, we need to convert the string to Ansi int size = strlennull(szValue) + 2; char* szAnsi = (char*)_alloca(size); if (utf8_decode_static(szValue, szAnsi, size)) return DBWriteContactSettingString(hContact, szModule, szSetting, szAnsi); // failed to convert - give error return 1; } } char* IRCGetContactSettingUtf(HANDLE hContact, const char* szSetting, char* szDef) { return UniGetContactSettingUtf(hContact, IRCPROTONAME, szSetting, szDef); } int IRCWriteContactSettingUtf(HANDLE hContact, const char* szSetting, char* szValue) { return UniWriteContactSettingUtf(hContact, IRCPROTONAME, szSetting, szValue); } int IRCGetContactStaticString(HANDLE hContact, const char* valueName, char* dest, int dest_len) { DBVARIANT dbv; DBCONTACTGETSETTING sVal; dbv.pszVal = dest; dbv.cchVal = dest_len; dbv.type = DBVT_ASCIIZ; sVal.pValue = &dbv; sVal.szModule = IRCPROTONAME; sVal.szSetting = valueName; if (CallService(MS_DB_CONTACT_GETSETTINGSTATIC, (WPARAM)hContact, (LPARAM)&sVal) != 0) { dbv.pszVal = dest; dbv.cchVal = dest_len; dbv.type = DBVT_UTF8; if (CallService(MS_DB_CONTACT_GETSETTINGSTATIC, (WPARAM)hContact, (LPARAM)&sVal) != 0) return 1; // this is here due to DB module bug... } return (dbv.type != DBVT_ASCIIZ); } int IRCWriteContactSettingBlob(HANDLE hContact,const char *szSetting,const char *val, const int cbVal) { DBCONTACTWRITESETTING cws; /* if (!bdCacheTested) TestDBBlobIssue(); if (bdWorkaroundRequired) { // this is workaround for DB blob caching problems - nasty isn't it DBWriteContactSettingByte(hContact, gpszICQProtoName, szSetting, 1); DBDeleteContactSetting(hContact, gpszICQProtoName, szSetting); }*/ cws.szModule=IRCPROTONAME; cws.szSetting=szSetting; cws.value.type=DBVT_BLOB; cws.value.pbVal=(BYTE *)val; cws.value.cpbVal = cbVal; return CallService(MS_DB_CONTACT_WRITESETTING,(WPARAM)hContact,(LPARAM)&cws); } int IRCFreeVariant(DBVARIANT* dbv) { return DBFreeVariant(dbv); } char* __fastcall IRCTranslate(const char* src) { return (char*)CallService(MS_LANGPACK_TRANSLATESTRING,0,(LPARAM)src); } char* __fastcall IRCTranslateUtf(const char* src) { // this takes UTF-8 strings only!!! char* szRes = NULL; if (!strlennull(src)) { // for the case of empty strings return null_strdup(src); } if (gbUtfLangpack) { // we can use unicode translate wchar_t* usrc = make_unicode_string((const unsigned char *)src); szRes = (char *)make_utf8_string(TranslateW(usrc)); SAFE_FREE((void **)&usrc); } else { int size = strlennull(src)+2; char* asrc = (char*)_alloca(size); utf8_decode_static(src, asrc, size); utf8_encode(Translate(asrc), &szRes); } return szRes; } char* __fastcall IRCTranslateUtfStatic(const char* src, char* buf) { // this takes UTF-8 strings only!!! char* t; if (strlennull(src)) { t = IRCTranslateUtf(src); strcpy(buf, t); SAFE_FREE((void **)&t); } else buf[0] = '\0'; return buf; } int null_snprintf(char *buffer, size_t count, const char* fmt, ...) { va_list va; int len; ZeroMemory(buffer, count); va_start(va, fmt); len = _vsnprintf(buffer, count-1, fmt, va); va_end(va); return len; } /* a strlennull() that likes NULL */ size_t __fastcall strlennull(const char *string) { if (string) return strlen(string); return 0; } 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; } } void* __fastcall SAFE_MALLOC(size_t size) { void* p = malloc(size); if (p) ZeroMemory(p, size); return p; } wchar_t *GetWindowTextUcs(HWND hWnd) { wchar_t *utext; if (gbUnicodeAPI) { int nLen = GetWindowTextLengthW(hWnd); utext = (wchar_t*)malloc((nLen+2)*sizeof(wchar_t)); GetWindowTextW(hWnd, utext, nLen + 1); } else { char *text; int wchars, nLen = GetWindowTextLengthA(hWnd); text = (char*)_alloca(nLen+2); GetWindowTextA(hWnd, text, nLen + 1); wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, text, strlennull(text), NULL, 0); utext = (wchar_t *)calloc(wchars + 1, sizeof(unsigned short)); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, text, strlennull(text), utext, wchars); } return utext; } void SetWindowTextUcs(HWND hWnd, wchar_t *text) { if (gbUnicodeAPI) { SetWindowTextW(hWnd, text); } else { char *tmp = (char*)malloc(wcslen(text) + 1); tmp[0] = '\0'; WideCharToMultiByte(CP_ACP, 0, text, -1, tmp, wcslen(text)+1, NULL, NULL); SetWindowTextA(hWnd, tmp); SAFE_FREE((void **)&tmp); } } char* GetWindowTextUtf(HWND hWnd) { if (gbUnicodeAPI) { wchar_t* usText; int nLen = GetWindowTextLengthW(hWnd); usText = (wchar_t*)_alloca((nLen+2)*sizeof(wchar_t)); GetWindowTextW(hWnd, usText, nLen + 1); return (char *)make_utf8_string(usText); } else { char* szAnsi; int nLen = GetWindowTextLengthA(hWnd); szAnsi = (char*)_alloca(nLen+2); GetWindowTextA(hWnd, szAnsi, nLen + 1); return ansi_to_utf8(szAnsi); } } char* GetDlgItemTextUtf(HWND hwndDlg, int iItem) { return GetWindowTextUtf(GetDlgItem(hwndDlg, iItem)); } void SetWindowTextUtf(HWND hWnd, const char* szText) { if (gbUnicodeAPI) { wchar_t* usText = make_unicode_string((const unsigned char *)szText); SetWindowTextW(hWnd, usText); SAFE_FREE((void **)&usText); } else { int size = strlennull(szText)+2; char* szAnsi = (char*)_alloca(size); if (utf8_decode_static(szText, szAnsi, size)) SetWindowTextA(hWnd, szAnsi); } } void SetDlgItemTextUtf(HWND hwndDlg, int iItem, const char* szText) { SetWindowTextUtf(GetDlgItem(hwndDlg, iItem), szText); } LONG SetWindowLongUtf(HWND hWnd, int nIndex, LONG dwNewLong) { if (gbUnicodeAPI) return SetWindowLongW(hWnd, nIndex, dwNewLong); else return SetWindowLongA(hWnd, nIndex, dwNewLong); } LRESULT CallWindowProcUtf(WNDPROC OldProc, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (gbUnicodeAPI) return CallWindowProcW(OldProc,hWnd,msg,wParam,lParam); else return CallWindowProcA(OldProc,hWnd,msg,wParam,lParam); } HWND DialogBoxUtf(BOOL bModal, HINSTANCE hInstance, const char* szTemplate, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) { // Unicode pump ready dialog box if (gbUnicodeAPI) { if (bModal) return (HWND)DialogBoxParamW(hInstance, (LPCWSTR)szTemplate, hWndParent, lpDialogFunc, dwInitParam); else return CreateDialogParamW(hInstance, (LPCWSTR)szTemplate, hWndParent, lpDialogFunc, dwInitParam); } else { if (bModal) return (HWND)DialogBoxParamA(hInstance, szTemplate, hWndParent, lpDialogFunc, dwInitParam); else return CreateDialogParamA(hInstance, szTemplate, hWndParent, lpDialogFunc, dwInitParam); } }