From cd83b1c10bbe50f5aa43a8e8f7dffc5fee1d769a Mon Sep 17 00:00:00 2001 From: George Hazan Date: Tue, 11 Apr 2023 22:03:29 +0300 Subject: DB::FILE_BLOB expansion for the offline file transfers, part I --- include/m_database.h | 12 +++++++++ include/m_db_int.h | 3 +++ include/m_protoint.h | 2 +- include/m_protosvc.h | 17 +++++++++++++ libs/win32/mir_app.lib | Bin 243830 -> 244964 bytes libs/win32/mir_core.lib | Bin 491050 -> 491386 bytes libs/win64/mir_app.lib | Bin 240858 -> 242430 bytes libs/win64/mir_core.lib | Bin 496242 -> 496588 bytes protocols/JabberG/src/jabber_file.cpp | 41 ++++++++++++++++++++++++++++++ protocols/JabberG/src/jabber_proto.cpp | 17 +++++++++++++ protocols/JabberG/src/jabber_proto.h | 7 ++++- protocols/Sametime/src/sametime_proto.cpp | 2 +- protocols/Sametime/src/sametime_proto.h | 2 +- src/core/stdfile/src/file.cpp | 2 +- src/mir_app/src/MDatabaseCommon.cpp | 7 +++++ src/mir_app/src/db_events.cpp | 9 +++++++ src/mir_app/src/mir_app.def | 6 ++++- src/mir_app/src/mir_app64.def | 7 ++++- src/mir_app/src/proto_interface.cpp | 2 +- src/mir_app/src/proto_internal.cpp | 2 +- src/mir_app/src/srmm_log_rtf.cpp | 24 +++++++++++++++++ src/mir_core/src/db.cpp | 5 ++++ src/mir_core/src/mir_core.def | 1 + src/mir_core/src/mir_core64.def | 1 + 24 files changed, 160 insertions(+), 9 deletions(-) diff --git a/include/m_database.h b/include/m_database.h index 59c0dacb82..c29f589495 100644 --- a/include/m_database.h +++ b/include/m_database.h @@ -369,6 +369,10 @@ EXTERN_C MIR_CORE_DLL(MEVENT) db_event_prev(MCONTACT hContact, MEVENT hDbEvent); EXTERN_C MIR_CORE_DLL(MEVENT) db_event_getById(const char *szModule, const char *szId); +// Sets a value to the JSON field in the blob + +MIR_CORE_DLL(int) db_event_setJson(MEVENT hDbEvent, const char *szSetting, DBVARIANT *dbv); + // Updates the server ID associated with an event // Returns 0 on success or a failure otherwise @@ -702,6 +706,8 @@ namespace DB class MIR_APP_EXPORT FILE_BLOB : public MNonCopyable { ptrW m_wszFileName, m_wszDescription; + ptrA m_szProtoString; + uint32_t m_iFileSize = 0, m_iTransferred = 0; public: explicit FILE_BLOB(const wchar_t *pwszName, const wchar_t *pwszDescr = nullptr); @@ -710,8 +716,14 @@ namespace DB void write(EventInfo &dbei); + __forceinline const char* getUrl() const { return m_szProtoString; } __forceinline const wchar_t* getName() const { return m_wszFileName; } __forceinline const wchar_t* getDescr() const { return m_wszDescription; } + + __forceinline bool isCompleted() const { return m_iFileSize == 0 || m_iFileSize == m_iTransferred; } + __forceinline bool isOffline() const { return m_szProtoString != nullptr; } + + __forceinline void setSize(uint32_t iSize) { m_iFileSize = m_iTransferred = iSize; } }; ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/m_db_int.h b/include/m_db_int.h index 7c1e5f2461..fa25ddcc26 100644 --- a/include/m_db_int.h +++ b/include/m_db_int.h @@ -132,6 +132,7 @@ interface MIR_APP_EXPORT MIDatabase STDMETHOD_(MEVENT, FindLastEvent)(MCONTACT contactID) PURE; STDMETHOD_(MEVENT, FindNextEvent)(MCONTACT contactID, MEVENT hDbEvent) PURE; STDMETHOD_(MEVENT, FindPrevEvent)(MCONTACT contactID, MEVENT hDbEvent) PURE; + STDMETHOD_(int, SetEventJson)(MEVENT hDbEvent, const char *szSetting, DBVARIANT *dbv) PURE; STDMETHOD_(BOOL, DeleteModule)(MCONTACT contactID, LPCSTR szModule) PURE; STDMETHOD_(BOOL, EnumModuleNames)(DBMODULEENUMPROC pFunc, void *pParam) PURE; @@ -224,6 +225,8 @@ public: STDMETHODIMP_(BOOL) FreeVariant(DBVARIANT *dbv); STDMETHODIMP_(BOOL) WriteContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv) override; + STDMETHODIMP_(int) SetEventJson(MEVENT hDbEvent, const char *szSetting, DBVARIANT *dbv) override; + STDMETHODIMP_(BOOL) EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam) override; STDMETHODIMP_(BOOL) SetSettingResident(BOOL bIsResident, const char *pszSettingName) override; diff --git a/include/m_protoint.h b/include/m_protoint.h index 609bbfbd92..07e461a118 100644 --- a/include/m_protoint.h +++ b/include/m_protoint.h @@ -235,7 +235,7 @@ public: virtual MWindow CreateExtendedSearchUI(MWindow owner); virtual int RecvContacts(MCONTACT hContact, PROTORECVEVENT *); - virtual int RecvFile(MCONTACT hContact, PROTORECVFILE *); + virtual MEVENT RecvFile(MCONTACT hContact, PROTORECVFILE *); virtual MEVENT RecvMsg(MCONTACT hContact, PROTORECVEVENT *); virtual int SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList); diff --git a/include/m_protosvc.h b/include/m_protosvc.h index 32fcc8bc7b..a49788f6e6 100644 --- a/include/m_protosvc.h +++ b/include/m_protosvc.h @@ -787,6 +787,23 @@ __forceinline INT_PTR ProtoChainRecvFile(MCONTACT hContact, PROTORECVFILE *pre) return Proto_ChainRecv(0, &ccs); } +/////////////////////////////////////////////////////////////////////////////// +// Offline file processing + +#define PS_OFFLINEFILE "/OfflineFile" + +struct OFDTHREAD +{ + __forceinline OFDTHREAD(MEVENT _1, const CMStringW &_2) : + hDbEvent(_1), + wszPath(_2) + {} + + MEVENT hDbEvent; + CMStringW wszPath; + bool bOpen = true; +}; + /////////////////////////////////////////////////////////////////////////////// // Contacts have been received // wParam = 0 diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib index 8a1dbc3fab..3202750581 100644 Binary files a/libs/win32/mir_app.lib and b/libs/win32/mir_app.lib differ diff --git a/libs/win32/mir_core.lib b/libs/win32/mir_core.lib index 0fcd25d444..eb68307359 100644 Binary files a/libs/win32/mir_core.lib and b/libs/win32/mir_core.lib differ diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib index f1f10235c0..e164b68a0d 100644 Binary files a/libs/win64/mir_app.lib and b/libs/win64/mir_app.lib differ diff --git a/libs/win64/mir_core.lib b/libs/win64/mir_core.lib index 48b6a8c9a0..c171b61385 100644 Binary files a/libs/win64/mir_core.lib and b/libs/win64/mir_core.lib differ diff --git a/protocols/JabberG/src/jabber_file.cpp b/protocols/JabberG/src/jabber_file.cpp index e76e81b123..24ea2c6296 100644 --- a/protocols/JabberG/src/jabber_file.cpp +++ b/protocols/JabberG/src/jabber_file.cpp @@ -25,6 +25,47 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "stdafx.h" #include "jabber_caps.h" +INT_PTR __cdecl CJabberProto::OnOfflineFile(WPARAM param, LPARAM) +{ + ForkThread((MyThreadFunc)&CJabberProto::OfflineFileThread, (void*)param); + return 0; +} + +void __cdecl CJabberProto::OfflineFileThread(OFDTHREAD *param) +{ + DB::EventInfo dbei(param->hDbEvent); + if (dbei && !strcmp(dbei.szModule, m_szModuleName) && dbei.eventType == EVENTTYPE_FILE) { + DB::FILE_BLOB blob(dbei); + if (blob.isOffline()) { + // initialize the netlib request + NETLIBHTTPREQUEST nlhr = {}; + nlhr.cbSize = sizeof(nlhr); + nlhr.requestType = REQUEST_GET; + nlhr.flags = NLHRF_HTTP11 | NLHRF_DUMPASTEXT | NLHRF_REDIRECT; + nlhr.szUrl = (char*)blob.getUrl(); + + // download the page + NLHR_PTR nlhrReply(Netlib_HttpTransaction(m_hNetlibUser, &nlhr)); + if (nlhrReply) { + if (nlhrReply->resultCode == 200) { + FILE *f = _wfopen(param->wszPath, L"wb"); + fwrite(nlhrReply->pData, 1, nlhrReply->dataLength, f); + fclose(f); + + blob.setSize(nlhrReply->dataLength); + blob.write(dbei); + db_event_edit(param->hDbEvent, &dbei); + + if (param->bOpen) + ShellExecute(nullptr, L"open", param->wszPath, nullptr, nullptr, SW_SHOWDEFAULT); + } + } + } + } + + delete param; +} + #define JABBER_NETWORK_BUFFER_SIZE 2048 void __cdecl CJabberProto::FileReceiveHttpThread(filetransfer *ft) diff --git a/protocols/JabberG/src/jabber_proto.cpp b/protocols/JabberG/src/jabber_proto.cpp index 9891bfd60f..acc141e114 100644 --- a/protocols/JabberG/src/jabber_proto.cpp +++ b/protocols/JabberG/src/jabber_proto.cpp @@ -188,6 +188,9 @@ CJabberProto::CJabberProto(const char *aProtoName, const wchar_t *aUserName) : // XEP-0224 support (Attention/Nudge) CreateProtoService(PS_SEND_NUDGE, &CJabberProto::JabberSendNudge); + // Offline file transfer + CreateProtoService(PS_OFFLINEFILE, &CJabberProto::OnOfflineFile); + // service to get from protocol chat buddy info CreateProtoService(MS_GC_PROTO_GETTOOLTIPTEXT, &CJabberProto::JabberGCGetToolTipText); @@ -809,6 +812,20 @@ HANDLE CJabberProto::SearchByName(const wchar_t *nick, const wchar_t *firstName, return (HANDLE)pInfo->GetIqId(); } +MEVENT CJabberProto::RecvFile(MCONTACT hContact, PROTORECVFILE *pre) +{ + MEVENT hEvent = CSuper::RecvFile(hContact, pre); + if (hEvent) { + auto *ft = (filetransfer *)pre->lParam; + if (ft && ft->type == FT_HTTP && ft->httpPath) { + DBVARIANT dbv = { DBVT_UTF8 }; + dbv.pszVal = ft->httpPath; + db_event_setJson(hEvent, "u", &dbv); + } + } + return hEvent; +} + //////////////////////////////////////////////////////////////////////////////////////// // SendContacts diff --git a/protocols/JabberG/src/jabber_proto.h b/protocols/JabberG/src/jabber_proto.h index f940f3349d..019ea10d35 100644 --- a/protocols/JabberG/src/jabber_proto.h +++ b/protocols/JabberG/src/jabber_proto.h @@ -135,6 +135,8 @@ struct CJabberProto : public PROTO, public IJabberInterface HANDLE SearchAdvanced(HWND owner) override; HWND CreateExtendedSearchUI(HWND owner) override; + MEVENT RecvFile(MCONTACT hContact, PROTORECVFILE *pre) override; + int SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList) override; HANDLE SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles) override; int SendMsg(MCONTACT hContact, int flags, const char *msg) override; @@ -506,7 +508,10 @@ struct CJabberProto : public PROTO, public IJabberInterface void __cdecl FileReceiveThread(filetransfer *ft); void __cdecl FileServerThread(filetransfer *ft); void __cdecl FileReceiveHttpThread(filetransfer *ft); - + + INT_PTR __cdecl OnOfflineFile(WPARAM dbevent, LPARAM lParam); + void __cdecl OfflineFileThread(OFDTHREAD *param); + void FtCancel(filetransfer *ft); void FtInitiate(filetransfer *ft); void FtHandleSiRequest(const TiXmlElement *iqNode); diff --git a/protocols/Sametime/src/sametime_proto.cpp b/protocols/Sametime/src/sametime_proto.cpp index 1ca043c75a..179f01999d 100644 --- a/protocols/Sametime/src/sametime_proto.cpp +++ b/protocols/Sametime/src/sametime_proto.cpp @@ -162,7 +162,7 @@ HWND CSametimeProto::CreateExtendedSearchUI(HWND owner) } -int CSametimeProto::RecvFile(MCONTACT hContact, PROTORECVFILE* pre) +MEVENT CSametimeProto::RecvFile(MCONTACT hContact, PROTORECVFILE* pre) { debugLogW(L"CSametimeProto::RecvFile() hContact=[%x]", hContact); diff --git a/protocols/Sametime/src/sametime_proto.h b/protocols/Sametime/src/sametime_proto.h index 036ca4d2c0..fb022ae3c2 100644 --- a/protocols/Sametime/src/sametime_proto.h +++ b/protocols/Sametime/src/sametime_proto.h @@ -24,7 +24,7 @@ struct CSametimeProto : public PROTO HANDLE SearchAdvanced(HWND owner) override; HWND CreateExtendedSearchUI(HWND owner) override; - int RecvFile(MCONTACT hContact, PROTORECVFILE*) override; + MEVENT RecvFile(MCONTACT hContact, PROTORECVFILE*) override; MEVENT RecvMsg(MCONTACT hContact, PROTORECVEVENT*) override; HANDLE SendFile(MCONTACT hContact, const wchar_t* szDescription, wchar_t** ppszFiles) override; diff --git a/src/core/stdfile/src/file.cpp b/src/core/stdfile/src/file.cpp index 126b428c99..4bd5eee393 100644 --- a/src/core/stdfile/src/file.cpp +++ b/src/core/stdfile/src/file.cpp @@ -391,7 +391,7 @@ static INT_PTR Proto_RecvFileT(WPARAM, LPARAM lParam) MEVENT hdbe = db_event_add(ccs->hContact, &dbei); PushFileEvent(ccs->hContact, hdbe, pre->lParam); - return 0; + return hdbe; } int LoadSendRecvFileModule(void) diff --git a/src/mir_app/src/MDatabaseCommon.cpp b/src/mir_app/src/MDatabaseCommon.cpp index b8084148f7..934f61c91a 100644 --- a/src/mir_app/src/MDatabaseCommon.cpp +++ b/src/mir_app/src/MDatabaseCommon.cpp @@ -546,6 +546,13 @@ STDMETHODIMP_(BOOL) MDatabaseCommon::WriteContactSetting(MCONTACT contactID, con return 0; } +///////////////////////////////////////////////////////////////////////////////////////// + +STDMETHODIMP_(int) MDatabaseCommon::SetEventJson(MEVENT, const char *, DBVARIANT *) +{ + return 1; +} + ///////////////////////////////////////////////////////////////////////////////////////// // Resident settings diff --git a/src/mir_app/src/db_events.cpp b/src/mir_app/src/db_events.cpp index 9e413aac76..6f6fc281be 100644 --- a/src/mir_app/src/db_events.cpp +++ b/src/mir_app/src/db_events.cpp @@ -297,6 +297,13 @@ DB::FILE_BLOB::FILE_BLOB(const DB::EventInfo &dbei) if (root) { m_wszFileName = root["f"].as_mstring().Detach(); m_wszDescription = root["d"].as_mstring().Detach(); + + CMStringA szProtoString(root["u"].as_mstring()); + if (!szProtoString.IsEmpty()) { + m_szProtoString = szProtoString.Detach(); + m_iFileSize = root["fs"].as_int(); + m_iTransferred = root["ft"].as_int(); + } } } @@ -307,6 +314,8 @@ void DB::FILE_BLOB::write(DB::EventInfo &dbei) { JSONNode root; root << WCHAR_PARAM("f", m_wszFileName) << WCHAR_PARAM("d", m_wszDescription ? m_wszDescription : L""); + if (isOffline()) + root << CHAR_PARAM("u", m_szProtoString) << INT_PARAM("fs", m_iFileSize) << INT_PARAM("ft", m_iTransferred); std::string text = root.write(); dbei.cbBlob = (int)text.size() + 1; diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def index 92990599e4..f4c74509a7 100644 --- a/src/mir_app/src/mir_app.def +++ b/src/mir_app/src/mir_app.def @@ -55,7 +55,7 @@ Button_SetSkin_IcoLib @24 ?ProtoBroadcastAck@PROTO_INTERFACE@@QAEHIHHPAXJ@Z @56 NONAME ?RecvAwayMsg@PROTO_INTERFACE@@UAEHIHPAUPROTORECVEVENT@@@Z @57 NONAME ?RecvContacts@PROTO_INTERFACE@@UAEHIPAUPROTORECVEVENT@@@Z @58 NONAME -?RecvFile@PROTO_INTERFACE@@UAEHIPAUPROTORECVFILE@@@Z @59 NONAME +?RecvFile@PROTO_INTERFACE@@UAEIIPAUPROTORECVFILE@@@Z @59 NONAME ?RecvMsg@PROTO_INTERFACE@@UAEIIPAUPROTORECVEVENT@@@Z @60 NONAME ?SearchAdvanced@PROTO_INTERFACE@@UAEPAXPAUHWND__@@@Z @62 NONAME ?SearchBasic@PROTO_INTERFACE@@UAEPAXPB_W@Z @63 NONAME @@ -843,3 +843,7 @@ Chat_IsMuted @941 NONAME ?getDescr@FILE_BLOB@DB@@QBEPB_WXZ @958 NONAME ?getName@FILE_BLOB@DB@@QBEPB_WXZ @959 NONAME ?write@FILE_BLOB@DB@@QAEXAAVEventInfo@2@@Z @960 NONAME +?getUrl@FILE_BLOB@DB@@QBEPBDXZ @961 NONAME +?isCompleted@FILE_BLOB@DB@@QBE_NXZ @962 NONAME +?isOffline@FILE_BLOB@DB@@QBE_NXZ @963 NONAME +?setSize@FILE_BLOB@DB@@QAEXI@Z @964 NONAME diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def index 41bbf55dc6..a6e78bcdad 100644 --- a/src/mir_app/src/mir_app64.def +++ b/src/mir_app/src/mir_app64.def @@ -55,7 +55,7 @@ Button_SetSkin_IcoLib @24 ?ProtoBroadcastAck@PROTO_INTERFACE@@QEAA_JIHHPEAX_J@Z @56 NONAME ?RecvAwayMsg@PROTO_INTERFACE@@UEAAHIHPEAUPROTORECVEVENT@@@Z @57 NONAME ?RecvContacts@PROTO_INTERFACE@@UEAAHIPEAUPROTORECVEVENT@@@Z @58 NONAME -?RecvFile@PROTO_INTERFACE@@UEAAHIPEAUPROTORECVFILE@@@Z @59 NONAME +?RecvFile@PROTO_INTERFACE@@UEAAIIPEAUPROTORECVFILE@@@Z @59 NONAME ?RecvMsg@PROTO_INTERFACE@@UEAAIIPEAUPROTORECVEVENT@@@Z @60 NONAME ?SearchAdvanced@PROTO_INTERFACE@@UEAAPEAXPEAUHWND__@@@Z @62 NONAME ?SearchBasic@PROTO_INTERFACE@@UEAAPEAXPEB_W@Z @63 NONAME @@ -843,3 +843,8 @@ Chat_IsMuted @941 NONAME ?getDescr@FILE_BLOB@DB@@QEBAPEB_WXZ @958 NONAME ?getName@FILE_BLOB@DB@@QEBAPEB_WXZ @959 NONAME ?write@FILE_BLOB@DB@@QEAAXAEAVEventInfo@2@@Z @960 NONAME +?getUrl@FILE_BLOB@DB@@QEBAPEBDXZ @961 NONAME +?isCompleted@FILE_BLOB@DB@@QEBA_NXZ @962 NONAME +?isOffline@FILE_BLOB@DB@@QEBA_NXZ @963 NONAME +?setSize@FILE_BLOB@DB@@QEAAXI@Z @964 NONAME +?SetEventJson@MDatabaseCommon@@UEAAHIPEBDPEAUDBVARIANT@@@Z @965 NONAME diff --git a/src/mir_app/src/proto_interface.cpp b/src/mir_app/src/proto_interface.cpp index 07a276d20a..71a610d640 100644 --- a/src/mir_app/src/proto_interface.cpp +++ b/src/mir_app/src/proto_interface.cpp @@ -195,7 +195,7 @@ int PROTO_INTERFACE::RecvContacts(MCONTACT, PROTORECVEVENT*) return 1; // error } -int PROTO_INTERFACE::RecvFile(MCONTACT hContact, PROTORECVFILE *pcre) +MEVENT PROTO_INTERFACE::RecvFile(MCONTACT hContact, PROTORECVFILE *pcre) { CCSDATA ccs = { hContact, PSR_FILE, 0, (LPARAM)pcre }; return CallService(MS_PROTO_RECVFILET, 0, (LPARAM)&ccs); diff --git a/src/mir_app/src/proto_internal.cpp b/src/mir_app/src/proto_internal.cpp index 802f2230bc..85b587e416 100644 --- a/src/mir_app/src/proto_internal.cpp +++ b/src/mir_app/src/proto_internal.cpp @@ -192,7 +192,7 @@ struct DEFAULT_PROTO_INTERFACE : public PROTO_INTERFACE return (int)ProtoCallService(m_szModuleName, PSR_CONTACTS, 0, (LPARAM)&ccs); } - int RecvFile(MCONTACT hContact, PROTORECVFILE* evt) override + MEVENT RecvFile(MCONTACT hContact, PROTORECVFILE* evt) override { CCSDATA ccs = { hContact, PSR_FILE, 0, (LPARAM)evt }; return ProtoCallService(m_szModuleName, PSR_FILE, 0, (LPARAM)&ccs); diff --git a/src/mir_app/src/srmm_log_rtf.cpp b/src/mir_app/src/srmm_log_rtf.cpp index fd1279ec39..dec151b43d 100644 --- a/src/mir_app/src/srmm_log_rtf.cpp +++ b/src/mir_app/src/srmm_log_rtf.cpp @@ -154,6 +154,30 @@ INT_PTR CRtfLogWindow::Notify(WPARAM, LPARAM lParam) if (wcschr(tr.lpstrText, '@') != nullptr && wcschr(tr.lpstrText, ':') == nullptr && wcschr(tr.lpstrText, '/') == nullptr) wszText.Insert(0, L"mailto:"); + MEVENT hDbEvent; + if (swscanf(tr.lpstrText, L"ofile:%u", &hDbEvent) == 1) { + if (pLink->msg != WM_LBUTTONUP) + return false; + + DB::EventInfo dbei(hDbEvent); + if (!dbei) + return false; + + DB::FILE_BLOB blob(dbei); + + wchar_t tszTempPath[MAX_PATH]; + GetTempPathW(_countof(tszTempPath), tszTempPath); + CMStringW tszFilePath(FORMAT, L"%s%s", tszTempPath, blob.getName()); + + if (_waccess(tszFilePath, 0)) { + OFDTHREAD *dt = new OFDTHREAD(hDbEvent, tszFilePath); + CallProtoService(dbei.szModule, PS_OFFLINEFILE, (WPARAM)dt, 0); + } + else ShellExecute(nullptr, L"open", tszFilePath.c_str(), nullptr, nullptr, SW_SHOWDEFAULT); + + return TRUE; + } + if (pLink->msg == WM_RBUTTONDOWN) { HMENU hMenu = LoadMenu(g_plugin.getInst(), MAKEINTRESOURCE(IDR_CONTEXT)); HMENU hSubMenu = GetSubMenu(hMenu, 6); diff --git a/src/mir_core/src/db.cpp b/src/mir_core/src/db.cpp index e5d8d508ae..982d289e29 100644 --- a/src/mir_core/src/db.cpp +++ b/src/mir_core/src/db.cpp @@ -506,6 +506,11 @@ MIR_CORE_DLL(MEVENT) db_event_getById(const char *szModule, const char *szId) return (g_pCurrDb == nullptr) ? 0 : g_pCurrDb->GetEventById(szModule, szId); } +MIR_CORE_DLL(int) db_event_setJson(MEVENT hDbEvent, const char *szSetting, DBVARIANT *dbv) +{ + return (g_pCurrDb == nullptr) ? 1 : g_pCurrDb->SetEventJson(hDbEvent, szSetting, dbv); +} + MIR_CORE_DLL(int) db_event_updateId(MEVENT hDbEvent, const char *szId) { return (g_pCurrDb == nullptr) ? 0 : g_pCurrDb->UpdateEventId(hDbEvent, szId); diff --git a/src/mir_core/src/mir_core.def b/src/mir_core/src/mir_core.def index 3410eda604..64c5ef15f4 100644 --- a/src/mir_core/src/mir_core.def +++ b/src/mir_core/src/mir_core.def @@ -1551,3 +1551,4 @@ db_event_replace @1771 db_event_updateId @1772 ?db_get_usm@@YG?AV?$CMStringT@DV?$ChTraitsCRT@D@@@@IPBD00@Z @1773 NONAME ?SetPageOwner@CCtrlPages@@QAEXXZ @1774 NONAME +?db_event_setJson@@YGHIPBDPAUDBVARIANT@@@Z @1775 NONAME diff --git a/src/mir_core/src/mir_core64.def b/src/mir_core/src/mir_core64.def index d1afc89380..023b1b23b8 100644 --- a/src/mir_core/src/mir_core64.def +++ b/src/mir_core/src/mir_core64.def @@ -1551,3 +1551,4 @@ db_event_replace @1771 db_event_updateId @1772 ?db_get_usm@@YA?AV?$CMStringT@DV?$ChTraitsCRT@D@@@@IPEBD00@Z @1773 NONAME ?SetPageOwner@CCtrlPages@@QEAAXXZ @1774 NONAME +?db_event_setJson@@YAHIPEBDPEAUDBVARIANT@@@Z @1775 NONAME -- cgit v1.2.3