summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/m_database.h12
-rw-r--r--include/m_db_int.h3
-rw-r--r--include/m_protoint.h2
-rw-r--r--include/m_protosvc.h17
-rw-r--r--libs/win32/mir_app.libbin243830 -> 244964 bytes
-rw-r--r--libs/win32/mir_core.libbin491050 -> 491386 bytes
-rw-r--r--libs/win64/mir_app.libbin240858 -> 242430 bytes
-rw-r--r--libs/win64/mir_core.libbin496242 -> 496588 bytes
-rw-r--r--protocols/JabberG/src/jabber_file.cpp41
-rw-r--r--protocols/JabberG/src/jabber_proto.cpp17
-rw-r--r--protocols/JabberG/src/jabber_proto.h7
-rw-r--r--protocols/Sametime/src/sametime_proto.cpp2
-rw-r--r--protocols/Sametime/src/sametime_proto.h2
-rw-r--r--src/core/stdfile/src/file.cpp2
-rw-r--r--src/mir_app/src/MDatabaseCommon.cpp7
-rw-r--r--src/mir_app/src/db_events.cpp9
-rw-r--r--src/mir_app/src/mir_app.def6
-rw-r--r--src/mir_app/src/mir_app64.def7
-rw-r--r--src/mir_app/src/proto_interface.cpp2
-rw-r--r--src/mir_app/src/proto_internal.cpp2
-rw-r--r--src/mir_app/src/srmm_log_rtf.cpp24
-rw-r--r--src/mir_core/src/db.cpp5
-rw-r--r--src/mir_core/src/mir_core.def1
-rw-r--r--src/mir_core/src/mir_core64.def1
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
@@ -788,6 +788,23 @@ __forceinline INT_PTR ProtoChainRecvFile(MCONTACT hContact, PROTORECVFILE *pre)
}
///////////////////////////////////////////////////////////////////////////////
+// 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
// lParam = (LPARAM)(PROTORECVEVENT*)&pre
diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib
index 8a1dbc3fab..3202750581 100644
--- a/libs/win32/mir_app.lib
+++ b/libs/win32/mir_app.lib
Binary files differ
diff --git a/libs/win32/mir_core.lib b/libs/win32/mir_core.lib
index 0fcd25d444..eb68307359 100644
--- a/libs/win32/mir_core.lib
+++ b/libs/win32/mir_core.lib
Binary files differ
diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib
index f1f10235c0..e164b68a0d 100644
--- a/libs/win64/mir_app.lib
+++ b/libs/win64/mir_app.lib
Binary files differ
diff --git a/libs/win64/mir_core.lib b/libs/win64/mir_core.lib
index 48b6a8c9a0..c171b61385 100644
--- a/libs/win64/mir_core.lib
+++ b/libs/win64/mir_core.lib
Binary files 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<CJabberProto>, 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<CJabberProto>, 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<CSametimeProto>
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
@@ -547,6 +547,13 @@ STDMETHODIMP_(BOOL) MDatabaseCommon::WriteContactSetting(MCONTACT contactID, con
}
/////////////////////////////////////////////////////////////////////////////////////////
+
+STDMETHODIMP_(int) MDatabaseCommon::SetEventJson(MEVENT, const char *, DBVARIANT *)
+{
+ return 1;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
// Resident settings
STDMETHODIMP_(BOOL) MDatabaseCommon::EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam)
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