{ ############################################################################ } { # # } { # MirandaNG HistoryToDB Plugin v2.5 # } { # # } { # License: GPLv3 # } { # # } { # Author: Grigorev Michael (icq: 161867489, email: sleuthhound@gmail.com) # } { # # } { ############################################################################ } library MirandaNGHistoryToDB; {$I Global.inc} uses madExcept, madLinkDisAsm, madListHardware, madListProcesses, madListModules, m_api, Windows, SysUtils, XMLIntf, XMLDoc, ShellApi, WideStrUtils, JclStringConversions, Contacts in 'Contacts.pas', Database in 'Database.pas', Menu in 'Menu.pas', About in 'About.pas', MsgExport in 'MsgExport.pas' {ExportForm}, Global in 'Global.pas', FSMonitor in 'FSMonitor.pas', MapStream in 'MapStream.pas'; // use it to make plugin unicode-aware {$DEFINE UNICODE} // tell Miranda about this plugin ExVersion function MirandaPluginInfoEx(mirandaVersion:DWORD): PPLUGININFOEX; cdecl; begin PluginInfo.cbSize:= SizeOf(TPLUGININFOEX); PluginInfo.shortName:= htdPluginShortName; PluginInfo.version:= htdVersion; PluginInfo.description:= htdDescription_EN; PluginInfo.author:= htdAuthor_EN; PluginInfo.authorEmail:= htdAuthorEmail; PluginInfo.copyright:= htdCopyright_EN; PluginInfo.homepage:= htdHomePageURL; PluginInfo.flags:= UNICODE_AWARE; PluginInfo.uuid:= MIID_HISTORYTODBDLL; Result := @PluginInfo; end; var {$ifdef REPLDEFHISTMOD} PluginInterfaces: array[0..1] of TGUID; {$else} PluginInterfaces: array[0..0] of TGUID; {$endif REPLDEFHISTMOD} PluginStatus: Boolean = False; StartExport: Boolean = False; StartUpdate: Boolean = False; DefaultINICopy: Boolean = False; HookModulesLoad, HookBuildMenu, HookContactMenu, HookSystemHistoryMenu, {$ifdef REPLDEFHISTMOD} HookShowMainHistory, {$endif REPLDEFHISTMOD} HookEventAdded, //HookTTBLoaded, HookShowHistoryAPI, HookShowContactHistoryAPI, HookShowVersionAPI: THandle; //hTTBButton: THandle = 0; DialogMainWindow: HWND = 0; const hLangpack: THANDLE = 0; function OnModulesLoad(awParam:WPARAM; alParam:LPARAM): Integer; cdecl; forward; function OnBuildContactMenu(awParam: WPARAM; alParam: LPARAM): Integer; cdecl; forward; function OnEventAdded(wParam: WPARAM; lParam: LPARAM): Integer; cdecl; forward; //function OnTTBLoaded(awParam: WPARAM; alParam: LPARAM): Integer; cdecl; forward; function OpenHistoryWindow(wParam:WPARAM;lParam:LPARAM): Integer; cdecl; forward; // tell Miranda about supported interfaces function MirandaPluginInterfaces:PMUUID; cdecl; begin {$ifdef REPLDEFHISTMOD} PluginInterfaces[0]:=MIID_UIHISTORY; PluginInterfaces[1]:=MIID_LAST; {$else} PluginInterfaces[0]:=MIID_LAST; {$endif REPLDEFHISTMOD} Result := @PluginInterfaces; end; { ���������� ������� �������� } function OpenHistoryWindow(wParam: WPARAM; lParam: LPARAM): Integer; cdecl; var ContactProto, ContactID, ContactName: AnsiString; MyContactName, MyContactID: AnsiString; ProtoType: Integer; WinName: String; begin Result := 0; ContactProto := GetContactProto(wParam); ContactID := GetContactID(wParam, ContactProto); ContactName := GetContactDisplayName(wParam, '', True); MyContactName := GetMyContactDisplayName(ContactProto); MyContactID := GetMyContactID(ContactProto); if ContactID = '' then ContactID := TranslateW('Unknown Contact'); if ContactName = '' then ContactName := TranslateW('Unknown Contact'); if MyContactID = '' then MyContactID := TranslateW('Unknown Contact'); if MyContactName = '' then MyContactName := TranslateW('Unknown Contact'); // ���. �������� ��������� if ContactProto = MyAccount then ContactProto := 'ICQ'; if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ������� PluginContactMenuCommand: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName, 2); // ��� ������� ProtoType := StrContactProtoToInt(ContactProto); // ���������� ��������� N ��������� ��������� WinName := 'HistoryToDBViewer for ' + htdIMClientName + ' ('+MyAccount+')'; if SearchMainWindow(pWideChar(WinName)) then begin // ������ �������: // ��� ������� ��������: // 008|0|UserID|UserName|ProtocolType // ��� ������� ����: // 008|2|ChatName OnSendMessageToOneComponent(WinName, '008|0|'+ContactID+'|'+ContactName+'|'+IntToStr(ProtoType)); if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ��������� PluginContactMenuCommand: ���������� ������ - 008|0|'+ContactID+'|'+ContactName+'|'+IntToStr(ProtoType), 2); end else begin if FileExists(PluginPath + 'HistoryToDBViewer.exe') then begin if MatchStrings(LowerCase(ContactProto), 'skype*') then // Skype begin // ������ ������� ���� ������� (������� ���-���������) Glogal_History_Type := 2; if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ��������� PluginContactMenuCommand: ��������� ' + PluginPath + 'HistoryToDBViewer.exe' + ' "'+PluginPath+'" "'+ProfilePath+'" '+IntToStr(Glogal_History_Type)+' "'+MyContactID+'" "'+MyContactName+'" "'+ContactName+'"', 2); ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBViewer.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'" '+IntToStr(Glogal_History_Type)+' "'+MyContactID+'" "'+MyContactName+'" "'+ContactName+'"'), nil, SW_SHOWNORMAL); end else begin // ������ ������� ���� ������� (������� IM-���������) Glogal_History_Type := 0; if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ��������� PluginContactMenuCommand: ��������� ' + PluginPath + 'HistoryToDBViewer.exe' + ' "'+PluginPath+'" "'+ProfilePath+'" '+IntToStr(Glogal_History_Type)+' "'+MyContactID+'" "'+MyContactName+'" "'+ContactID+'" "'+ContactName+'" '+IntToStr(ProtoType), 2); ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBViewer.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'" '+IntToStr(Glogal_History_Type)+' "'+MyContactID+'" "'+MyContactName+'" "'+ContactID+'" "'+ContactName+'" '+IntToStr(ProtoType)), nil, SW_SHOWNORMAL); end; end else MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_VIEWER'), [PluginPath + 'HistoryToDBViewer.exe'])); end; end; { ���������� ���� �������� ������ ��� ������������ ���������� } function OnBuildContactMenu(awParam: WPARAM; alParam: LPARAM): Integer; cdecl; var MenuItem: TCLISTMENUITEM; ContactProto, ContactID, ContactName: AnsiString; begin Result := 0; ContactProto := GetContactProto(awParam); // ���� ZeroMemory(@MenuItem, SizeOf(MenuItem)); MenuItem.cbSize := SizeOf(MenuItem); MenuItem.flags := CMIM_FLAGS; if (ContactProto = MyAccount) or MatchStrings(LowerCase(ContactProto), 'icq*') or MatchStrings(LowerCase(ContactProto), 'jabber*') or MatchStrings(LowerCase(ContactProto), 'aim*') or MatchStrings(LowerCase(ContactProto), 'irc*') or MatchStrings(LowerCase(ContactProto), 'msn*') or MatchStrings(LowerCase(ContactProto), 'yahoo*') or MatchStrings(LowerCase(ContactProto), 'gadu*') or MatchStrings(LowerCase(ContactProto), 'skype*') or MatchStrings(LowerCase(ContactProto), 'vkonta*') then begin // ���������� ���� � ���� �������� ContactID := GetContactID(awParam, ContactProto); ContactName := GetContactDisplayName(awParam, '', True); if ContactName = '' then ContactName := TranslateW('Unknown Contact'); if ContactID = '' then ContactID := TranslateW('Unknown Contact'); // ���. �������� ��������� if ContactProto = MyAccount then ContactProto := 'ICQ'; MenuItem.flags := MenuItem.flags or CMIM_NAME; MenuItem.szName.a := pAnsiChar(AnsiString(Format(WideStringToString(GetLangStr('ShowContactHistory'), CP_ACP), [ContactName, ContactID]))); CallService(MS_CLIST_MODIFYMENUITEM, HookContactMenu, lParam(@MenuItem)); if EnableDebug then // ���� ������� WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ������� OnBuildContactMenu: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto, 2); end else // ��� �������� begin MenuItem.flags := MenuItem.flags or CMIF_HIDDEN; CallService(MS_CLIST_MODIFYMENUITEM, HookContactMenu, lParam(@MenuItem)); if EnableDebug then // ���� ������� begin ContactID := GetContactID(awParam, ContactProto); ContactName := GetContactDisplayName(awParam, '', True); if ContactName = '' then ContactName := TranslateW('Unknown Contact'); if ContactID = '' then ContactID := TranslateW('Unknown Contact'); // ���. �������� ��������� if ContactProto = MyAccount then ContactProto := 'ICQ'; WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ������� OnBuildContactMenu: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto, 2); end; end; end; { �������� ������� � ���� ������� } function OnEventAdded(wParam: WPARAM; lParam: LPARAM): Integer; cdecl; var ContactProto, ContactID, ContactName: AnsiString; MyContactName, MyContactID: AnsiString; BlobSize, ProtoType: Integer; DBEventInfo: TDBEventInfo; msgA: PAnsiChar; msgW: PChar; msgLen, LenW: Cardinal; I: Integer; Msg_RcvrNick, Msg_RcvrAcc, Msg_SenderNick, Msg_SenderAcc, Msg_Text, MD5String: WideString; Date_Str, MsgStatus: String; InsertSQLData, EncInsertSQLData, WinName: String; ASize: Integer; hContact: THandle; begin Result := 0; ZeroMemory(@DBEventInfo, SizeOf(DBEventInfo)); DBEventInfo.cbSize := SizeOf(DBEventInfo); DBEventInfo.pBlob := nil; BlobSize := CallService(MS_DB_EVENT_GETBLOBSIZE, lParam, 0); GetMem(DBEventInfo.pBlob, BlobSize); DBEventInfo.cbBlob := BlobSize; if (CallService(MS_DB_EVENT_GET, lParam, Integer(@DBEventInfo)) = 0) and (DBEventInfo.eventType = EVENTTYPE_MESSAGE and EVENTTYPE_URL) then begin // �������� ����� ��������� msgA := PAnsiChar(DBEventInfo.pBlob); msgW := nil; msgLen := lstrlenA(PAnsiChar(DBEventInfo.pBlob)) + 1; if msgLen > DBEventInfo.cbBlob then msgLen := DBEventInfo.cbBlob; if Boolean(DBEventInfo.flags and DBEF_UTF) then begin SetLength(Msg_Text, msgLen); LenW := Utf8ToWideChar(PChar(Msg_Text), msgLen, msgA, msgLen - 1, CP_ACP); if Integer(LenW) > 0 then SetLength(Msg_Text, LenW - 1) else Msg_Text := AnsiToWideString(msgA, CP_ACP, msgLen - 1); end else begin LenW := 0; if DBEventInfo.cbBlob >= msgLen * SizeOf(Char) then begin msgW := PChar(msgA + msgLen); for i := 0 to ((DBEventInfo.cbBlob - msgLen) div SizeOf(Char)) - 1 do if msgW[i] = #0 then begin LenW := i; Break; end; end; if (LenW > 0) and (LenW < msgLen) then SetString(Msg_Text, msgW, LenW) else Msg_Text := AnsiToWideString(msgA, CP_ACP, msgLen - 1); end; // ��� ������� hContact := wParam; ContactProto := GetContactProto(hContact); ProtoType := StrContactProtoToInt(ContactProto); // ���� ��������� �� ������������, �� �� ����� ��� � �� // �.�. ��� ������������ ���� � �� ����� ������ �������� if ProtoType = 15 then Exit; // ������ ����������� ContactID := GetContactID(hContact, ContactProto); ContactName := GetContactDisplayName(hContact, '', True); // ��� ������ MyContactName := GetMyContactDisplayName(ContactProto); MyContactID := GetMyContactID(ContactProto); // ���. �������� ��������� if ContactProto = MyAccount then ContactProto := 'ICQ'; ProtoType := StrContactProtoToInt(ContactProto); // End if ContactID = '' then ContactID := TranslateW('Unknown Contact'); if ContactName = '' then ContactName := TranslateW('Unknown Contact'); if MyContactID = '' then MyContactID := TranslateW('Unknown Contact'); if MyContactName = '' then MyContactName := TranslateW('Unknown Contact'); // ������������ MyContactID � ContactName ���� �������� � // ������������ ��������� ��� ������������ {if (ProtoType = 15) and (MyContactID = TranslateW('Unknown Contact')) and (MyContactName <> TranslateW('Unknown Contact')) then MyContactID := MyContactName; if (ProtoType = 15) and (ContactName = TranslateW('Unknown Contact')) and (ContactID <> TranslateW('Unknown Contact')) then ContactName := ContactID;} // �������������, ��������������� � �.�. Msg_SenderNick := PrepareString(pWideChar(AnsiToWideString(MyContactName, CP_ACP))); Msg_SenderAcc := PrepareString(pWideChar(AnsiToWideString(MyContactID, CP_ACP))); Msg_SenderNick := WideStringToUTF8(Msg_SenderNick); Msg_SenderAcc := WideStringToUTF8(Msg_SenderAcc); Msg_RcvrNick := PrepareString(pWideChar(AnsiToWideString(ContactName, CP_ACP))); Msg_RcvrAcc := PrepareString(pWideChar(AnsiToWideString(ContactID, CP_ACP))); Msg_RcvrNick := WideStringToUTF8(Msg_RcvrNick); Msg_RcvrAcc := WideStringToUTF8(Msg_RcvrAcc); Msg_Text := WideStringToUTF8(PrepareString(pWideChar(Msg_Text))); MD5String := Msg_RcvrAcc + FormatDateTime('YYYY-MM-DD HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + Msg_Text; if (DBType = 'oracle') or (DBType = 'oracle-9i') then Date_Str := FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) else Date_Str := FormatDateTime('YYYY-MM-DD HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)); if MatchStrings(LowerCase(ContactProto), 'skype*') then begin // ���������� ����������� �������� (�� ��������� ��� ��� ��������) if (DBEventInfo.flags and DBEF_SENT) = 0 then MsgStatus := '0' // �������� else MsgStatus := '1'; // ��������� // ��� ������� if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ������� OnEventAdded: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName + ' | Contact Proto = ' + ContactProto + ' | MsgStatus = ' + MsgStatus + ' | DateTime = ' + FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + ' | Message = ' + Msg_Text, 2); if (MatchStrings(DBType, 'oracle*')) then // ���� Oracle, �� ����� SQL-��� � ������� CHAT_MSG_LOG_ORACLE InsertSQLData := Format(CHAT_MSG_LOG_ORACLE, [DBUserName, MsgStatus, 'to_date('''+Date_Str+''', ''dd.mm.yyyy hh24:mi:ss'')', Msg_RcvrNick, 'Skype', Msg_RcvrNick+' ('+Msg_RcvrAcc+')', BoolToIntStr(True), BoolToIntStr(False), BoolToIntStr(False), Msg_Text, EncryptMD5(MD5String)]) else InsertSQLData := Format(CHAT_MSG_LOG, [DBUserName, MsgStatus, Date_Str, Msg_RcvrNick, 'Skype', Msg_RcvrNick+' ('+Msg_RcvrAcc+')', BoolToIntStr(True), BoolToIntStr(False), BoolToIntStr(False), Msg_Text, EncryptMD5(MD5String)]); end else begin // ���������� ����������� �������� (�� ��������� ��� ��� ��������) if (DBEventInfo.flags and DBEF_SENT) = 0 then MsgStatus := '1' // �������� else MsgStatus := '0'; // ��������� // ��� ������� if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ������� OnEventAdded: ' + 'Contact ID: ' + ContactID + ' | Contact Name: ' + ContactName + ' | Proto: ' + ContactProto + ' | My Contact ID: ' + MyContactID + ' | My Contact Name: ' + MyContactName + ' | Contact Proto = ' + ContactProto + ' | MsgStatus = ' + MsgStatus + ' | DateTime = ' + FormatDateTime('DD.MM.YYYY HH:MM:SS', UnixToLocalTime(DBEventInfo.timestamp)) + ' | Message = ' + Msg_Text, 2); if (MatchStrings(DBType, 'oracle*')) then // ���� Oracle, �� ����� SQL-��� � ������� MSG_LOG_ORACLE InsertSQLData := Format(MSG_LOG_ORACLE, [DBUserName, IntToStr(ProtoType), Msg_SenderNick, Msg_SenderAcc, Msg_RcvrNick, Msg_RcvrAcc, MsgStatus, 'to_date('''+Date_Str+''', ''dd.mm.yyyy hh24:mi:ss'')', Msg_Text, EncryptMD5(MD5String)]) else InsertSQLData := Format(MSG_LOG, [DBUserName, IntToStr(ProtoType), Msg_SenderNick, Msg_SenderAcc, Msg_RcvrNick, Msg_RcvrAcc, MsgStatus, Date_Str, Msg_Text, EncryptMD5(MD5String)]); end; // �������� ��������� ����� MMF ��� ��������������� ������ ������������� if SyncMethod = 0 then begin WinName := 'HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')'; if SearchMainWindow(pWideChar(WinName)) then begin EncInsertSQLData := EncryptStr(InsertSQLData); ASize := 2*Length(EncInsertSQLData); with FMap do begin Clear; WriteBuffer(@ASize,Sizeof(Integer)); WriteBuffer(PChar(EncInsertSQLData),ASize); end; // ���������� ������, ��� ��������� � ������ OnSendMessageToOneComponent('HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')', '010'); end else WriteInLog(ProfilePath, InsertSQLData, 0); end else // ��� ������ ������������� �� ���������� � ������� ����� ��������� � SQL-���� WriteInLog(ProfilePath, InsertSQLData, 0); // ���� ����� �� ���������� if SyncMethod = 2 then begin if (SyncInterval > 4) and (SyncInterval < 8) then begin Inc(MessageCount); if (SyncInterval = 5) and (MessageCount = 10) then begin OnSendMessageToAllComponent('002'); MessageCount := 0; end; if (SyncInterval = 6) and (MessageCount = 20) then begin OnSendMessageToAllComponent('002'); MessageCount := 0; end; if (SyncInterval = 7) and (MessageCount = 30) then begin OnSendMessageToAllComponent('002'); MessageCount := 0; end; end; if SyncInterval = 9 then begin Inc(MessageCount); if MessageCount = SyncMessageCount then begin OnSendMessageToAllComponent('002'); MessageCount := 0; end; end; end; end; end; {function OnTTBLoaded(awParam: WPARAM; alParam: LPARAM): Integer; cdecl; var TTB: TTBButtonV2; begin if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ������� OnTTBLoaded', 2); if hTTBButton <> 0 then begin if ServiceExists(MS_TTB_REMOVEBUTTON)>0 then begin CallService(MS_TTB_REMOVEBUTTON, WPARAM(hTTBButton),0); hTTBButton := 0; end; end; if ShowPluginButton then begin if ServiceExists(MS_TTB_ADDBUTTON) > 0 then begin ZeroMemory(@TTB, SizeOf(TTB)); TTB.cbSize := SizeOf(TTB); TTB.pszServiceUp := MHTD_SHOWSERVICE; TTB.pszServiceDown:= MHTD_SHOWSERVICE; TTB.hIconUp := LoadImage(hInstance, 'ICON_0', IMAGE_ICON, 16, 16, 0); TTB.hIconDn := ttb.hIconUp; TTB.dwFlags := TTBBF_VISIBLE; TTB.name := htdDBName; hTTBButton := CallService(MS_TTB_ADDBUTTON, WPARAM(@TTB), 0); if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ������� OnTTBLoaded: ������ ���������.', 2); end; end; Result := 0; end;} { C����� MS_MHTD_SHOWHISTORY ������ ������ � m_historytodb.inc } function HTDBShowHistory(wParam { 0 } : WPARAM; lParam { 0 } : LPARAM): int_ptr; cdecl; var WinName: String; begin Result := 0; // ���� ���� HistoryToDBViewer WinName := 'HistoryToDBViewer'; if not SearchMainWindow(pWideChar(WinName)) then // ���� HistoryToDBViewer �� ������, �� ���� ������ ���� begin WinName := 'HistoryToDBViewer for ' + htdIMClientName + ' ('+MyAccount+')'; if not SearchMainWindow(pWideChar(WinName)) then // ���� HistoryToDBViewer �� �������, �� ��������� begin if FileExists(PluginPath + 'HistoryToDBViewer.exe') then begin ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBViewer.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'"'), nil, SW_SHOWNORMAL); end else MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_VIEWER'), [PluginPath + 'HistoryToDBViewer.exe'])); end else // ����� �������� ������ �� ����� ���� OnSendMessageToOneComponent(WinName, '0040'); end else // ����� �������� ������ �� ����� ���� OnSendMessageToOneComponent(WinName, '0040'); end; { C����� MS_MHTD_SHOWCONTACTHISTORY ������ ������ � m_historytodb.inc } function HTDBShowContactHistory(wParam { hContact } : WPARAM; lParam { 0 } : LPARAM): int_ptr; cdecl; begin Result := OpenHistoryWindow(wParam, 0); end; { C����� MS_MHTD_GETVERSION ������ ������ � m_historytodb.inc } function HTDBGetVersion(wParam { 0 } : WPARAM; lParam { 0 } : LPARAM): int_ptr; cdecl; begin Result := htdVersion; end; function OnModulesLoad(awParam{0}:WPARAM; alParam{0}:LPARAM):integer; cdecl; var Mi: TCListMenuItem; //{$ifdef REPLDEFHISTMOD} Si: TCListMenuItem; //{$endif REPLDEFHISTMOD} AutoCoreLang, UpdTmpPath, WinName: String; I: Byte; MenuMainService: PAnsiChar; //IMUPD: TUpdate; begin // ���-����� ������� MsgLogOpened := False; ErrLogOpened := False; DebugLogOpened := False; ContactListLogOpened := False; ProtoListLogOpened := False; ImportLogOpened := False; // ������������� ���������� EncryptInit; // ���������� ����������� if FileExists(ExtractFilePath(ParamStr(0))+'Langpack_russian.txt') then AutoCoreLang := 'Russian' else AutoCoreLang := 'English'; // ������ �� �������� ���� ����������� ������� ���� ��� ���� �������� OnSendMessageToAllComponent('003'); // �������� ��������� ���� ������������ ����� � ������� if FileExists(PluginPath + DefININame) then begin if FileExists(ProfilePath + ININame) then RenameFile(ProfilePath + ININame, ProfilePath + ININame + '.' + FormatDateTime('ddmmyyhhmmss', Now)); if CopyFileEx(PChar(PluginPath + DefININame), PChar(ProfilePath + ININame), nil, nil, nil, COPY_FILE_FAIL_IF_EXISTS) then begin DefaultINICopy := True; if FileExists(ProfilePath + ININame) then DeleteFile(PluginPath + DefININame); end; end; // ������ ������� ��� ������ ������� if (GetDBInt(htdDBName, 'FirstRun.FirstActivate', 0) = 0) or (DefaultINICopy) then begin if AutoCoreLang = 'Russian' then begin case MessageBox(DialogMainWindow, PWideChar('�� ������� ������������ ������ ' + htdPluginShortName + '.' + #13 + '��� ���������� ������ ������� ��������� ��������� ���������� � ����� ������.' + #13 + '�� ������ ������ ������� �������?'), PWideChar(htdPluginShortName),36) of 6: StartExport := True; // �� 7: StartExport := False; // ��� end; end else begin case MessageBox(DialogMainWindow, PWideChar('The first time you activate the plugin ' + htdPluginShortName + '.' + #13 + 'To work correctly, check your plug-in connection to the database.' + #13 + 'Do you want to start exporting the history?'), PWideChar(htdPluginShortName),36) of 6: StartExport := True; // �� 7: StartExport := False; // ��� end; end; end; // ��������� �������� ����� ���������� if GetDBInt(htdDBName, 'FirstRun.RunUpdateDoneV'+IntToStr(htdVersion), 0) = 0 then begin if AutoCoreLang = 'Russian' then begin //MsgInf(htdPluginShortName, '�� ������� ������������ ������ ' + htdPluginShortName + '.' + #13 + '��� ���������� ������ ������� ��������� ��������� ���������� � ����� ������.' + #13 + '������� �� ������������� ������� ' + htdPluginShortName + '.') case MessageBox(DialogMainWindow, PWideChar('�� ������� ������������ ������ ' + htdPluginShortName + '.' + #13 + '��� ���������� ������ ������� ���������� ��������� ������� ���������� ������� ����� ��������.' + #13 + '�� ������ ������ ������� ����������?'), PWideChar(htdPluginShortName),36) of 6: StartUpdate := True; // �� 7: StartUpdate := False; // ��� end; end else begin //MsgInf(htdPluginShortName, 'The first time you activate the plugin ' + htdPluginShortName + '.' + #13 + 'To work correctly, check your plug-in connection to the database.' + #13 + 'Thank you for using the plugin ' + htdPluginShortName + '.'); case MessageBox(DialogMainWindow, PWideChar('The first time you activate the plugin ' + htdPluginShortName + '.' + #13 + 'To work correctly, the plugin must run the update plugin via the Internet.' + #13 + 'Do you want to start the update process?'), PWideChar(htdPluginShortName),36) of 6: StartUpdate := True; // �� 7: StartUpdate := False; // ��� end; end; end; // ����� ����� �� ��������� if AutoCoreLang <> DefaultLanguage then begin CoreLanguage := AutoCoreLang; WriteCustomINI(ProfilePath, 'DefaultLanguage', CoreLanguage); end else CoreLanguage := DefaultLanguage; // ��������� ��������� ����������� LangDoc := NewXMLDocument(); CoreLanguageChanged; // ���������� ���� IM ������� WriteCustomINI(ProfilePath, 'IMClientType', htdIMClientName); WriteCustomINI(ProfilePath, 'IMClientPlatformType', htdPlatform); // ���������� ���������� ������� �� ������ �������� WriteCustomINI(ProfilePath, 'SettingsFormRequestSend', '0'); // ������� ���� About � Export if not Assigned(AboutForm) then AboutForm := TAboutForm.Create(nil); ExportFormDestroy := True; // API - �������� ���� ������� HookShowHistoryAPI := CreateServiceFunction(MS_MHTD_SHOWHISTORY, @HTDBShowHistory); // API - �������� ���� ������� ���������� �������� HookShowContactHistoryAPI := CreateServiceFunction(MS_MHTD_SHOWCONTACTHISTORY, @HTDBShowContactHistory); // API - ������ ������� HookShowVersionAPI := CreateServiceFunction(MS_MHTD_GETVERSION, @HTDBGetVersion); // ������������� ��������� ���� MenuMainItemsInit; // ������� �������� ���� FillChar(Mi, SizeOf(Mi), 0); Mi.cbSize := SizeOf(Mi); Mi.szPopupName.a := '&' + htdPluginShortName; Mi.popupPosition := 500000; Mi.hIcon := LoadImage(hInstance,'ICON_0',IMAGE_ICON,16,16,0); Mi.flags := 0; for I := Low(MainMenuItems) to High(MainMenuItems) do begin if MainMenuItems[I].Icon = '' then Mi.hIcon := 0 else Mi.hIcon := LoadImage(hInstance, pChar(MainMenuItems[I].Icon), IMAGE_ICON, 16, 16, 0); Mi.szName.a := pAnsiChar(AnsiString(MainMenuItems[I].Name)); MenuMainService := pAnsiChar(AnsiString(Format('%s/MainMenuCommand%d', [htdPluginShortName, I]))); //if EnableDebug then WriteInLog(ProfilePath, FormatDateTime('dd.mm.yy hh:mm:ss', Now) + ' - ������� Load: ' + 'MenuMainName = ' + MenuMainItems[I].Name + ' | MenuMainService = ' + MenuMainService, 2); MainMenuHandle[I] := CreateServiceFunctionParam(MenuMainService, @MainMenuItems[I].Proc, I); Mi.pszService := MenuMainService; Mi.Position := MainMenuItems[I].Position; MenuHandle[I] := CallService(MS_CLIST_ADDMAINMENUITEM, 0, Windows.LPARAM(@Mi)); end; // ������� ���� ����� � �������� ���� ��� ��������� ������� //{$ifdef REPLDEFHISTMOD} FillChar(Si, SizeOf(Si), 0); Si.cbSize := SizeOf(Si); Si.Position := 500060000; Si.szName.a := pAnsiChar(AnsiString(Format(WideStringToString(GetLangStr('IMButtonCaption'), CP_ACP), [htdPluginShortName]))); Si.pszService := MS_MHTD_SHOWHISTORY;//MS_HISTORY_SHOWCONTACTHISTORY; Si.hIcon := LoadImage(hInstance,'ICON_0',IMAGE_ICON,16,16,0); HookSystemHistoryMenu := CallService(MS_CLIST_ADDMAINMENUITEM,0,LPARAM(@Si)); //{$endif REPLDEFHISTMOD} // ������� ���� ����� � ���� �������� CreateServiceFunction(htdPluginShortName+'/ContactMenuCommand', @OpenHistoryWindow); Mi.pszContactOwner := nil; // ��� �������� Mi.cbSize := SizeOf(Mi); Mi.position := 1000090000; Mi.flags := 0; Mi.hIcon := LoadImage(hInstance,'ICON_0',IMAGE_ICON,16,16,0); Mi.szName.a := pAnsiChar(WideStringToString(GetLangStr('ShowOneContactHistory'), CP_ACP)); Mi.pszService := htdPluginShortName+'/ContactMenuCommand'; HookContactMenu := CallService(MS_CLIST_ADDCONTACTMENUITEM, 0, LPARAM(@Mi)); // ��� �� �������� ���� �������� HookBuildMenu := HookEvent(ME_CLIST_PREBUILDCONTACTMENU, OnBuildContactMenu); // ��� �� ���������� ������ � ��������� �� ������� HookEventAdded := HookEvent(ME_DB_EVENT_ADDED, OnEventAdded); // �������� ���� ������� {$ifdef REPLDEFHISTMOD} HookShowMainHistory := CreateServiceFunction(MS_HISTORY_SHOWCONTACTHISTORY, @OpenHistoryWindow); {$endif REPLDEFHISTMOD} // ��������� TopToolBar //HookTTBLoaded := HookEvent(ME_TTB_MODULELOADED, OnTTBLoaded); // Register in updater {if Boolean(ServiceExists(MS_UPDATE_REGISTER)) then begin ZeroMemory(@IMUPD,SizeOf(IMUPD)); IMUPD.cbSize := SizeOf(IMUPD); IMUPD.szComponentName := htdPluginShortName; IMUPD.pbVersion := @hppVersionStr[1]; IMUPD.cpbVersion := Length(hppVersionStr); // File listing section //IMUPD.szUpdateURL = UPDATER_AUTOREGISTER; IMUPD.szUpdateURL := htdFLUpdateURL; IMUPD.szVersionURL := htdFLVersionURL; IMUPD.pbVersionPrefix := htdFLVersionPrefix; IMUPD.cpbVersionPrefix := Length(htdFLVersionPrefix); // Alpha-beta section IMUPD.szBetaUpdateURL := htdUpdateURL; IMUPD.szBetaVersionURL := htdVersionURL; IMUPD.pbBetaVersionPrefix := htdVersionPrefix; IMUPD.cpbBetaVersionPrefix := Length(htdVersionPrefix); IMUPD.szBetaChangelogURL := htdChangelogURL; CallService(MS_UPDATE_REGISTER, 0, LPARAM(@IMUPD)); end;} { ��������� �������� ����� ������������ FILE_NOTIFY_CHANGE_FILE_NAME = $00000001;//��������� ����� ����� FILE_NOTIFY_CHANGE_DIR_NAME = $00000002;//��������� ����� ����� FILE_NOTIFY_CHANGE_ATTRIBUTES = $00000004;//��������� ��������� ����� FILE_NOTIFY_CHANGE_SIZE = $00000008;//��������� ������� ����� FILE_NOTIFY_CHANGE_LAST_WRITE = $00000010;//��������� ������� ��������� ������ FILE_NOTIFY_CHANGE_LAST_ACCESS = $00000020;//��������� ������� ���������� ������� FILE_NOTIFY_CHANGE_CREATION = $00000040;//��������� ������� �������� FILE_NOTIFY_CHANGE_SECURITY = $00000100;//��������� ���� ������� } StartWatch(ProfilePath, FILE_NOTIFY_CHANGE_LAST_WRITE, False, @ProfileDirChangeCallBack); // MMF if SyncMethod = 0 then FMap := TMapStream.CreateEx('HistoryToDB for ' + htdIMClientName + ' ('+MyAccount+')',MAXDWORD,2000); // ������ �������� PluginStatus := True; // ���. ��������� MessageCount := 0; // ����� ������ � ������ ������� � ���� WriteDBInt(htdDBName, 'FirstRun.FirstActivate', 1); // ���������� ������� HistoryToDBUpdater.exe �� ��������� ����� UpdTmpPath := GetUserTempPath + 'IMHistory\'; if FileExists(UpdTmpPath + 'HistoryToDBUpdater.exe') then begin // ���� ���� HistoryToDBUpdater WinName := 'HistoryToDBUpdater'; if not SearchMainWindow(pWideChar(WinName)) then // ���� HistoryToDBUpdater �� ������, �� ���� ������ ���� begin WinName := 'HistoryToDBUpdater for ' + htdIMClientName + ' ('+MyAccount+')'; if SearchMainWindow(pWideChar(WinName)) then // ���� HistoryToDBUpdater �������, �� ��������� ��� OnSendMessageToOneComponent(WinName, '009'); end else // ����� �������� ������ OnSendMessageToOneComponent(WinName, '009'); Sleep(800); // ������� ������ ������� if DeleteFile(PluginPath + 'HistoryToDBUpdater.exe') then begin if CopyFileEx(PChar(UpdTmpPath + 'HistoryToDBUpdater.exe'), PChar(PluginPath + 'HistoryToDBUpdater.exe'), nil, nil, nil, COPY_FILE_FAIL_IF_EXISTS) then begin DeleteFile(UpdTmpPath + 'HistoryToDBUpdater.exe'); if CoreLanguage = 'Russian' then MsgInf(htdPluginShortName, Format('������� ���������� %s ������� ���������.', ['HistoryToDBUpdater.exe'])) else MsgInf(htdPluginShortName, Format('Update utility %s successfully updated.', ['HistoryToDBUpdater.exe'])); end; end else begin DeleteFile(UpdTmpPath + 'HistoryToDBUpdater.exe'); if CoreLanguage = 'Russian' then MsgDie(htdPluginShortName, Format('������ ���������� ������� %s �� ��������� �����.', [PluginPath + 'HistoryToDBUpdater.exe'])) else MsgDie(htdPluginShortName, Format('Error update utility %s', [PluginPath + 'HistoryToDBUpdater.exe'])); end; end; // ���������� ������� HistoryToDBUpdater.exe �� ����� ������� if FileExists(PluginPath + 'HistoryToDBUpdater.upd') then begin // ���� ���� HistoryToDBUpdater WinName := 'HistoryToDBUpdater'; if not SearchMainWindow(pWideChar(WinName)) then // ���� HistoryToDBUpdater �� ������, �� ���� ������ ���� begin WinName := 'HistoryToDBUpdater for ' + htdIMClientName + ' ('+MyAccount+')'; if SearchMainWindow(pWideChar(WinName)) then // ���� HistoryToDBUpdater �������, �� ��������� ��� OnSendMessageToOneComponent(WinName, '009'); end else // ����� �������� ������ OnSendMessageToOneComponent(WinName, '009'); Sleep(800); // ������� ������ ������� if DeleteFile(PluginPath + 'HistoryToDBUpdater.exe') then begin if CopyFileEx(PChar(PluginPath + 'HistoryToDBUpdater.upd'), PChar(PluginPath + 'HistoryToDBUpdater.exe'), nil, nil, nil, COPY_FILE_FAIL_IF_EXISTS) then begin DeleteFile(PluginPath + 'HistoryToDBUpdater.upd'); if CoreLanguage = 'Russian' then MsgInf(htdPluginShortName, Format('������� ���������� %s ������� ���������.', ['HistoryToDBUpdater.exe'])) else MsgInf(htdPluginShortName, Format('Update utility %s successfully updated.', ['HistoryToDBUpdater.exe'])); end; end else begin DeleteFile(PluginPath + 'HistoryToDBUpdater.upd'); if CoreLanguage = 'Russian' then MsgDie(htdPluginShortName, Format('������ ���������� ������� %s �� ����� ��������.', [PluginPath + 'HistoryToDBUpdater.exe'])) else MsgDie(htdPluginShortName, Format('Error update utility %s', [PluginPath + 'HistoryToDBUpdater.exe'])); end; end; // ������ ���������� if StartUpdate then begin if FileExists(PluginPath + 'HistoryToDBUpdater.exe') then begin // ����� ������ � ���� WriteDBInt(htdDBName, 'FirstRun.RunUpdateDoneV'+IntToStr(htdVersion), 1); // ��������� ������ ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBUpdater.exe'), PWideChar(' "'+ProfilePath+'"'), nil, SW_SHOWNORMAL); end else MsgInf(htdPluginShortName, Format(GetLangStr('ERR_NO_FOUND_UPDATER'), [PluginPath + 'HistoryToDBUpdater.exe'])); end else begin // ��������� �������� ����� ���������� if GetDBInt(htdDBName, 'FirstRun.RunUpdateDoneV'+IntToStr(htdVersion), 0) = 0 then WriteDBInt(htdDBName, 'FirstRun.RunUpdateDoneV'+IntToStr(htdVersion), 1); // ����� ������ � ���� end; // �������� ���� �������� if StartExport then begin if ExportFormDestroy then ChildExport := TExportForm.Create(nil); if Assigned(ChildExport) then begin if not ChildExport.Showing then ChildExport.Show else ChildExport.BringFormToFront(ChildExport); end; end; // ���� �� ��������� ����������, �� ��������� ��������� ������������� HistoryToDBSync if not StartUpdate then begin if FileExists(PluginPath + 'HistoryToDBSync.exe') then begin WinName := 'HistoryToDBSync for ' + htdIMClientName + ' ('+MyAccount+')'; if not SearchMainWindow(pWideChar(WinName)) then // ���� HistoryToDBSync for QIP �� �������, �� ��������� ShellExecute(0, 'open', PWideChar(PluginPath + 'HistoryToDBSync.exe'), PWideChar(' "'+PluginPath+'" "'+ProfilePath+'"'), nil, SW_SHOWNORMAL) end else begin if CoreLanguage = 'Russian' then MsgInf(htdPluginShortName, Format('��������� ������������� ������� %s �� �������.' + #13 + '��������� ������� ���������� �������.', [PluginPath + 'HistoryToDBSync.exe'])) else MsgInf(htdPluginShortName, Format('The history synchronization program %s not found.' + #13 + 'Begin the process of updating the plugin.', [PluginPath + 'HistoryToDBSync.exe'])); end; end; Result := 0; end; function Load():Integer; cdecl; var ProfileName, TmpProfilePath: String; Str: PAnsiChar; begin CallService(MS_LANGPACK_REGISTER,WPARAM(@hLangpack),LPARAM(@PluginInfo)); // ������� �������� hppCodepage := CallService(MS_LANGPACK_GETCODEPAGE, 0, 0); if (hppCodepage = CALLSERVICE_NOTFOUND) or (hppCodepage = CP_ACP) then hppCodepage := GetACP(); // �������� �� ��������� ����-��������� MetaContactsEnabled := Boolean(ServiceExists(MS_MC_GETMOSTONLINECONTACT)); if MetaContactsEnabled then begin Str := pAnsiChar(CallService(MS_MC_GETPROTOCOLNAME, 0, 0)); if Assigned(Str) then MetaContactsProto := AnsiString(Str) else MetaContactsEnabled := False; end; // ���� �� �������� SetLength(DllPath, MAX_PATH); SetLength(DllPath, GetModuleFileNameW(hInstance, @DllPath[1], MAX_PATH)); PluginPath := ExtractFilePath(DllPath); // ���� �� ���������� ������� (USERNAME\USERNAME.dat) SetLength(TmpProfilePath, MAX_PATH); CallService(MS_DB_GETPROFILEPATH, MAX_PATH, lParam(@TmpProfilePath[1])); SetLength(TmpProfilePath, StrLen(pAnsiChar(@TmpProfilePath[1]))); TmpProfilePath := pAnsiChar(TmpProfilePath) + PathDelim; // ��� ����� ������� SetLength(ProfileName, MAX_PATH); CallService(MS_DB_GETPROFILENAME, MAX_PATH, lParam(@ProfileName[1])); SetLength(ProfileName, StrLen(pAnsiChar(@ProfileName[1]))); // ���� �� ������� USERNAME.dat TmpProfilePath := TmpProfilePath + ExtractFileNameEx(TmpProfilePath+pAnsiChar(ProfileName), False) + PathDelim; if DirectoryExists(TmpProfilePath) then ProfilePath := TmpProfilePath else ProfilePath := ExtractFilePath(DllPath); // ��������� ��������� LoadINI(ProfilePath); // ���������� ��� �������, ����� ��� ������������ ��� ��������� �������� MyAccount := ExtractFileNameEx(pAnsiChar(ProfileName), False); WriteCustomINI(ProfilePath, 'MyAccount', MyAccount); // ������������� �������� ������� HookModulesLoad := HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoad); Result := 0; end; function Unload: int; cdecl; var I: Byte; begin Result := 0; if PluginStatus then begin // ������������� �������� ����� ������������ StopWatch; if Assigned(AboutForm) then FreeAndNil(AboutForm); if Assigned(ExportForm) then FreeAndNil(ExportForm); // ������� ���� for I := Low(MainMenuHandle) to High(MainMenuHandle) do begin DestroyServiceFunction(MainMenuHandle[I]); DestroyServiceFunction(MenuHandle[I]); end; {$ifdef REPLDEFHISTMOD} DestroyServiceFunction(HookShowMainHistory); {$endif REPLDEFHISTMOD} DestroyServiceFunction(HookShowHistoryAPI); DestroyServiceFunction(HookShowContactHistoryAPI); DestroyServiceFunction(HookShowVersionAPI); //{$ifdef REPLDEFHISTMOD} UnhookEvent(HookSystemHistoryMenu); //{$endif REPLDEFHISTMOD} UnhookEvent(HookContactMenu); //UnhookEvent(HookTTBLoaded); UnhookEvent(HookEventAdded); UnhookEvent(HookBuildMenu); UnhookEvent(HookModulesLoad); // ������ �� �������� ���� ����������� ������� OnSendMessageToAllComponent('003'); // ��������� ���-����� if MsgLogOpened then CloseLogFile(0); if ErrLogOpened then CloseLogFile(1); if DebugLogOpened then CloseLogFile(2); if ContactListLogOpened then CloseLogFile(3); if ProtoListLogOpened then CloseLogFile(4); // ������� ������ ���������� EncryptFree; // MMF if Assigned(FMap) then FMap.Free; // ����. �������� ��������� LangDoc.Active := False; end; end; exports MirandaPluginInfoEx, MirandaPluginInterfaces, Load, Unload; begin end.