summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2020-03-22 14:20:52 +0300
committerGeorge Hazan <ghazan@miranda.im>2020-03-22 14:20:52 +0300
commit93b3a77b2590443e2b1e868b96196175f99180b9 (patch)
tree70601e77b9f6f7256721967eed0be10b598ad2e4
parentbb0498bf6aa0accd22bbc19091a12d54602a52be (diff)
File transfers:
- fixes #2274 (StdMsg & Scriver cannot send files to offline contacts even if their protocol allows that to do); - all copies of AddToFileList in all plugins removed; - ProcessFileDrop() function introduced to handle all file drop operations in all SRMM plugins & contact list
-rw-r--r--include/m_utils.h9
-rw-r--r--libs/win32/mir_app.libbin202444 -> 202754 bytes
-rw-r--r--libs/win64/mir_app.libbin198064 -> 198380 bytes
-rw-r--r--plugins/Scriver/src/msgdialog.cpp43
-rw-r--r--plugins/TabSRMM/src/msgdialog.cpp35
-rw-r--r--plugins/TabSRMM/src/msgdlgother.cpp13
-rw-r--r--plugins/TabSRMM/src/utils.cpp26
-rw-r--r--plugins/TabSRMM/src/utils.h68
-rw-r--r--src/core/stdmsg/src/msgdialog.cpp52
-rw-r--r--src/core/stdmsg/src/msgs.h1
-rw-r--r--src/mir_app/src/clcfiledrop.cpp52
-rw-r--r--src/mir_app/src/mir_app.def1
-rw-r--r--src/mir_app/src/mir_app64.def1
-rw-r--r--src/mir_app/src/utils.cpp62
14 files changed, 123 insertions, 240 deletions
diff --git a/include/m_utils.h b/include/m_utils.h
index d4cfd13593..e6aecec3f8 100644
--- a/include/m_utils.h
+++ b/include/m_utils.h
@@ -51,6 +51,15 @@ EXTERN_C MIR_CORE_DLL(void) Utils_OpenUrl(const char *pszUrl, bool bOpenInNewWin
EXTERN_C MIR_CORE_DLL(void) Utils_OpenUrlW(const wchar_t *pszUrl, bool bOpenInNewWindow = true);
/////////////////////////////////////////////////////////////////////////////////////////
+// Converts a dropped file into a file transfer
+//
+// #include <shellapi.h> to use this function
+
+#ifdef _INC_SHELLAPI
+MIR_APP_DLL(bool) ProcessFileDrop(HDROP hDrop, MCONTACT hContact);
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////
// Resizes a dialog by calling a custom routine to move the individual
// Returns 0 on success, or nonzero on failure
// Does not support dialogtemplateex dialog boxes, and will return failure if you try to resize one
diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib
index 7e81d2fb3f..c49d5d9c83 100644
--- a/libs/win32/mir_app.lib
+++ b/libs/win32/mir_app.lib
Binary files differ
diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib
index 47d6691a60..ecf7ebebad 100644
--- a/libs/win64/mir_app.lib
+++ b/libs/win64/mir_app.lib
Binary files differ
diff --git a/plugins/Scriver/src/msgdialog.cpp b/plugins/Scriver/src/msgdialog.cpp
index 1d4055b22a..f119bc4458 100644
--- a/plugins/Scriver/src/msgdialog.cpp
+++ b/plugins/Scriver/src/msgdialog.cpp
@@ -91,28 +91,6 @@ static wchar_t* GetQuotedTextW(wchar_t *text)
return out;
}
-static void AddToFileList(wchar_t ***pppFiles, int *totalCount, const wchar_t* szFilename)
-{
- *pppFiles = (wchar_t**)mir_realloc(*pppFiles, (++*totalCount + 1)*sizeof(wchar_t*));
- (*pppFiles)[*totalCount] = nullptr;
- (*pppFiles)[*totalCount - 1] = mir_wstrdup(szFilename);
-
- if (GetFileAttributes(szFilename) & FILE_ATTRIBUTE_DIRECTORY) {
- WIN32_FIND_DATA fd;
- wchar_t szPath[MAX_PATH];
- mir_snwprintf(szPath, L"%s\\*", szFilename);
- HANDLE hFind = FindFirstFile(szPath, &fd);
- if (hFind != INVALID_HANDLE_VALUE) {
- do {
- if (!mir_wstrcmp(fd.cFileName, L".") || !mir_wstrcmp(fd.cFileName, L"..")) continue;
- mir_snwprintf(szPath, L"%s\\%s", szFilename, fd.cFileName);
- AddToFileList(pppFiles, totalCount, szPath);
- } while (FindNextFile(hFind, &fd));
- FindClose(hFind);
- }
- }
-}
-
/////////////////////////////////////////////////////////////////////////////////////////
static INT_PTR CALLBACK ConfirmSendAllDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM)
@@ -981,7 +959,7 @@ LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam)
if (OpenClipboard(m_message.GetHwnd())) {
HANDLE hDrop = GetClipboardData(CF_HDROP);
if (hDrop)
- SendMessage(m_hwnd, WM_DROPFILES, (WPARAM)hDrop, 0);
+ ProcessFileDrop((HDROP)hDrop, m_hContact);
CloseClipboard();
}
return 0;
@@ -989,7 +967,7 @@ LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam)
break;
case WM_DROPFILES:
- SendMessage(m_hwnd, WM_DROPFILES, wParam, lParam);
+ ProcessFileDrop((HDROP)wParam, m_hContact);
return 0;
case WM_CONTEXTMENU:
@@ -1117,22 +1095,7 @@ INT_PTR CMsgDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam)
break;
case WM_DROPFILES:
- if (m_szProto == nullptr) break;
- if (!(CallProtoService(m_szProto, PS_GETCAPS, PFLAGNUM_1, 0)&PF1_FILESEND)) break;
- if (m_wStatus == ID_STATUS_OFFLINE) break;
- if (m_hContact != 0) {
- wchar_t szFilename[MAX_PATH];
- HDROP hDrop = (HDROP)wParam;
- int fileCount = DragQueryFile(hDrop, -1, nullptr, 0), totalCount = 0, i;
- wchar_t** ppFiles = nullptr;
- for (i = 0; i < fileCount; i++) {
- DragQueryFile(hDrop, i, szFilename, _countof(szFilename));
- AddToFileList(&ppFiles, &totalCount, szFilename);
- }
- CallServiceSync(MS_FILE_SENDSPECIFICFILEST, m_hContact, (LPARAM)ppFiles);
- for (i = 0; ppFiles[i]; i++) mir_free(ppFiles[i]);
- mir_free(ppFiles);
- }
+ ProcessFileDrop((HDROP)wParam, m_hContact);
break;
case DM_AVATARCHANGED:
diff --git a/plugins/TabSRMM/src/msgdialog.cpp b/plugins/TabSRMM/src/msgdialog.cpp
index dd7f2743f2..69f9d20f17 100644
--- a/plugins/TabSRMM/src/msgdialog.cpp
+++ b/plugins/TabSRMM/src/msgdialog.cpp
@@ -1897,7 +1897,7 @@ LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam)
return CSkin::DrawRichEditFrame(m_message.GetHwnd(), this, ID_EXTBKINPUTAREA, msg, wParam, lParam, stubMessageProc);
case WM_DROPFILES:
- SendMessage(m_hwnd, WM_DROPFILES, (WPARAM)wParam, (LPARAM)lParam);
+ SendMessage(m_hwnd, WM_DROPFILES, wParam, lParam);
return 0;
case WM_CHAR:
@@ -3113,37 +3113,8 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
return 0;
case WM_DROPFILES:
- {
- const char *szProto = m_cache->getActiveProto();
- if (szProto == nullptr)
- break;
-
- int pcaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0);
- if (!(pcaps & PF1_FILESEND))
- break;
- if (m_wStatus == ID_STATUS_OFFLINE) {
- pcaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0);
- if (!(pcaps & PF4_OFFLINEFILES)) {
- ActivateTooltip(IDC_SRMM_MESSAGE, TranslateT("Contact is offline and this protocol does not support sending files to offline users."));
- break;
- }
- }
-
- wchar_t szFilename[MAX_PATH];
- HDROP hDrop = (HDROP)wParam;
- int fileCount = DragQueryFile(hDrop, -1, nullptr, 0), totalCount = 0, i;
- wchar_t **ppFiles = nullptr;
- for (i = 0; i < fileCount; i++) {
- DragQueryFile(hDrop, i, szFilename, _countof(szFilename));
- Utils::AddToFileList(&ppFiles, &totalCount, szFilename);
- }
-
- CallService(MS_FILE_SENDSPECIFICFILEST, m_hContact, (LPARAM)ppFiles);
-
- for (i = 0; ppFiles[i]; i++)
- mir_free(ppFiles[i]);
- mir_free(ppFiles);
- }
+ if (!ProcessFileDrop((HDROP)wParam, m_cache->getActiveContact()))
+ ActivateTooltip(IDC_SRMM_MESSAGE, TranslateT("Contact is offline and this protocol does not support sending files to offline users."));
return 0;
case DM_CHECKQUEUEFORCLOSE:
diff --git a/plugins/TabSRMM/src/msgdlgother.cpp b/plugins/TabSRMM/src/msgdlgother.cpp
index 6396916029..249863ec01 100644
--- a/plugins/TabSRMM/src/msgdlgother.cpp
+++ b/plugins/TabSRMM/src/msgdlgother.cpp
@@ -1410,17 +1410,10 @@ void CMsgDialog::SendHBitmapAsFile(HBITMAP hbmp) const
return;
}
- int totalCount = 0;
- wchar_t **ppFiles = nullptr;
- Utils::AddToFileList(&ppFiles, &totalCount, filename);
+ vTempFilenames.insert(mir_wstrdup(filename));
- wchar_t *_t = mir_wstrdup(filename);
- vTempFilenames.insert(_t);
-
- CallService(MS_FILE_SENDSPECIFICFILEST, m_cache->getActiveContact(), (LPARAM)ppFiles);
-
- mir_free(ppFiles[0]);
- mir_free(ppFiles);
+ wchar_t *ppFiles[2] = { filename, nullptr };
+ CallService(MS_FILE_SENDSPECIFICFILEST, m_cache->getActiveContact(), (LPARAM)&ppFiles);
}
// remove all temporary files created by the "send clipboard as file" feature.
diff --git a/plugins/TabSRMM/src/utils.cpp b/plugins/TabSRMM/src/utils.cpp
index 84436070d3..f5e97fd276 100644
--- a/plugins/TabSRMM/src/utils.cpp
+++ b/plugins/TabSRMM/src/utils.cpp
@@ -955,32 +955,6 @@ HWND TSAPI GetTabWindow(HWND hwndTab, int i)
/////////////////////////////////////////////////////////////////////////////////////////
// file list handler
-void Utils::AddToFileList(wchar_t ***pppFiles, int *totalCount, LPCTSTR szFilename)
-{
- *pppFiles = (wchar_t**)mir_realloc(*pppFiles, (++*totalCount + 1) * sizeof(wchar_t*));
- (*pppFiles)[*totalCount] = nullptr;
- (*pppFiles)[*totalCount - 1] = mir_wstrdup(szFilename);
-
- if (GetFileAttributes(szFilename) & FILE_ATTRIBUTE_DIRECTORY) {
- WIN32_FIND_DATA fd;
- wchar_t szPath[MAX_PATH];
- mir_wstrcpy(szPath, szFilename);
- mir_wstrcat(szPath, L"\\*");
- HANDLE hFind = FindFirstFile(szPath, &fd);
- if (hFind != INVALID_HANDLE_VALUE) {
- do {
- if (!mir_wstrcmp(fd.cFileName, L".") || !mir_wstrcmp(fd.cFileName, L".."))
- continue;
- mir_wstrcpy(szPath, szFilename);
- mir_wstrcat(szPath, L"\\");
- mir_wstrcat(szPath, fd.cFileName);
- AddToFileList(pppFiles, totalCount, szPath);
- } while (FindNextFile(hFind, &fd));
- FindClose(hFind);
- }
- }
-}
-
int _DebugTraceW(const wchar_t *fmt, ...)
{
wchar_t debug[2048];
diff --git a/plugins/TabSRMM/src/utils.h b/plugins/TabSRMM/src/utils.h
index e2d57779bf..0aa96e8a22 100644
--- a/plugins/TabSRMM/src/utils.h
+++ b/plugins/TabSRMM/src/utils.h
@@ -48,48 +48,45 @@ struct TRTFColorTable
COLORREF clr;
};
-class Utils {
-
-public:
- static wchar_t* GetPreviewWithEllipsis(wchar_t *szText, size_t iMaxLen);
- static wchar_t* FilterEventMarkers(wchar_t *wszText);
- static char* FilterEventMarkers(char *szText);
- static void DoubleAmpersands(wchar_t *pszText, size_t len);
- static void RTF_CTableInit();
- static void RTF_ColorAdd(const wchar_t *tszColname);
- static int ReadContainerSettingsFromDB(const MCONTACT hContact, TContainerSettings *cs, const char *szKey = nullptr);
- static int WriteContainerSettingsToDB(const MCONTACT hContact, TContainerSettings *cs, const char *szKey = nullptr);
- static void SettingsToContainer(TContainerData *pContainer);
- static void ContainerToSettings(TContainerData *pContainer);
- static void ReadPrivateContainerSettings(TContainerData *pContainer, bool fForce = false);
- static void SaveContainerSettings(TContainerData *pContainer, const char *szSetting);
-
- static DWORD CALLBACK StreamOut(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb);
+namespace Utils
+{
+ wchar_t* GetPreviewWithEllipsis(wchar_t *szText, size_t iMaxLen);
+ wchar_t* FilterEventMarkers(wchar_t *wszText);
+ char* FilterEventMarkers(char *szText);
+ void DoubleAmpersands(wchar_t *pszText, size_t len);
+ void RTF_CTableInit();
+ void RTF_ColorAdd(const wchar_t *tszColname);
+ int ReadContainerSettingsFromDB(const MCONTACT hContact, TContainerSettings *cs, const char *szKey = nullptr);
+ int WriteContainerSettingsToDB(const MCONTACT hContact, TContainerSettings *cs, const char *szKey = nullptr);
+ void SettingsToContainer(TContainerData *pContainer);
+ void ContainerToSettings(TContainerData *pContainer);
+ void ReadPrivateContainerSettings(TContainerData *pContainer, bool fForce = false);
+ void SaveContainerSettings(TContainerData *pContainer, const char *szSetting);
- static void addMenuItem(const HMENU& m, MENUITEMINFO& mii, HICON hIcon, const wchar_t *szText, UINT uID, UINT pos);
- static void enableDlgControl(const HWND hwnd, UINT id, bool fEnable = true);
- static void showDlgControl(const HWND hwnd, UINT id, int showCmd);
- static void setAvatarContact(HWND hWnd, MCONTACT hContact);
- static void getIconSize(HICON hIcon, int& sizeX, int& sizeY);
+ DWORD CALLBACK StreamOut(DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb);
- static bool extractResource(const HMODULE h, const UINT uID, const wchar_t *tszName, const wchar_t *tszPath, const wchar_t *tszFilename, bool fForceOverwrite);
- static void scaleAvatarHeightLimited(const HBITMAP hBm, double& dNewWidth, double& dNewHeight, const LONG maxHeight);
+ void addMenuItem(const HMENU& m, MENUITEMINFO& mii, HICON hIcon, const wchar_t *szText, UINT uID, UINT pos);
+ void enableDlgControl(const HWND hwnd, UINT id, bool fEnable = true);
+ void showDlgControl(const HWND hwnd, UINT id, int showCmd);
+ void setAvatarContact(HWND hWnd, MCONTACT hContact);
+ void getIconSize(HICON hIcon, int& sizeX, int& sizeY);
- static AVATARCACHEENTRY* loadAvatarFromAVS(const MCONTACT hContact);
+ bool extractResource(const HMODULE h, const UINT uID, const wchar_t *tszName, const wchar_t *tszPath, const wchar_t *tszFilename, bool fForceOverwrite);
+ void scaleAvatarHeightLimited(const HBITMAP hBm, double& dNewWidth, double& dNewHeight, const LONG maxHeight);
- static void sanitizeFilename(wchar_t *tszFilename);
- static void ensureTralingBackslash(wchar_t *szPathname);
+ AVATARCACHEENTRY* loadAvatarFromAVS(const MCONTACT hContact);
- static void sendContactMessage(MCONTACT hContact, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ void sanitizeFilename(wchar_t *tszFilename);
+ void ensureTralingBackslash(wchar_t *szPathname);
- static HMODULE loadSystemLibrary(const wchar_t* szFilename);
+ void sendContactMessage(MCONTACT hContact, UINT uMsg, WPARAM wParam, LPARAM lParam);
- static LRESULT CALLBACK PopupDlgProcError(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
- static LPTSTR extractURLFromRichEdit(const ENLINK* _e, const HWND hwndRich);
+ HMODULE loadSystemLibrary(const wchar_t* szFilename);
- static size_t CopyToClipBoard(const wchar_t *str, const HWND hwndOwner);
+ LRESULT CALLBACK PopupDlgProcError(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+ LPTSTR extractURLFromRichEdit(const ENLINK* _e, const HWND hwndRich);
- static void AddToFileList(wchar_t ***pppFiles, int *totalCount, LPCTSTR szFilename);
+ size_t CopyToClipBoard(const wchar_t *str, const HWND hwndOwner);
//////////////////////////////////////////////////////////////////////////////////////
// safe mir_strlen function - do not overflow the given buffer length
@@ -98,7 +95,7 @@ public:
//
// careful: maxlen must be given in element counts!!
- template<typename T> static size_t safe_strlen(const T* src, const size_t maxlen = 0)
+ template<typename T> size_t safe_strlen(const T* src, const size_t maxlen = 0)
{
size_t s = 0;
@@ -108,8 +105,7 @@ public:
return (s >= maxlen && *src != 0) ? 0 : s;
}
-public:
- static OBJLIST<TRTFColorTable> rtf_clrs;
+ extern OBJLIST<TRTFColorTable> rtf_clrs;
};
__forceinline LRESULT _dlgReturn(HWND hWnd, LRESULT result)
diff --git a/src/core/stdmsg/src/msgdialog.cpp b/src/core/stdmsg/src/msgdialog.cpp
index 8d57bab10d..8e5aa0a79d 100644
--- a/src/core/stdmsg/src/msgdialog.cpp
+++ b/src/core/stdmsg/src/msgdialog.cpp
@@ -37,30 +37,6 @@ LIST<CMsgDialog> g_arDialogs(10, PtrKeySortT);
/////////////////////////////////////////////////////////////////////////////////////////
-static void AddToFileList(wchar_t ***pppFiles, int &totalCount, const wchar_t *szFilename)
-{
- *pppFiles = (wchar_t **)mir_realloc(*pppFiles, (++totalCount + 1) * sizeof(wchar_t *));
- (*pppFiles)[totalCount] = nullptr;
- (*pppFiles)[totalCount - 1] = mir_wstrdup(szFilename);
-
- if (GetFileAttributes(szFilename) & FILE_ATTRIBUTE_DIRECTORY) {
- WIN32_FIND_DATA fd;
- wchar_t szPath[MAX_PATH];
- mir_snwprintf(szPath, L"%s\\*", szFilename);
- HANDLE hFind = FindFirstFile(szPath, &fd);
- if (hFind != INVALID_HANDLE_VALUE) {
- do {
- if (!mir_wstrcmp(fd.cFileName, L".") || !mir_wstrcmp(fd.cFileName, L"..")) continue;
- mir_snwprintf(szPath, L"%s\\%s", szFilename, fd.cFileName);
- AddToFileList(pppFiles, totalCount, szPath);
- } while (FindNextFile(hFind, &fd));
- FindClose(hFind);
- }
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
CMsgDialog::CMsgDialog(CTabbedWindow *pOwner, MCONTACT hContact) :
CSuper(g_plugin, IDD_MSG),
m_btnOk(this, IDOK),
@@ -573,7 +549,7 @@ INT_PTR CMsgDialog::DlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
break;
case WM_DROPFILES: // Mod from tabsrmm
- ProcessFileDrop((HDROP)wParam);
+ ProcessFileDrop((HDROP)wParam, m_hContact);
return TRUE;
case HM_AVATARACK:
@@ -987,7 +963,7 @@ LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam)
break;
case WM_DROPFILES:
- ProcessFileDrop((HDROP)wParam);
+ ProcessFileDrop((HDROP)wParam, m_hContact);
break;
case WM_LBUTTONDOWN:
@@ -1107,7 +1083,7 @@ LRESULT CMsgDialog::WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam)
if (OpenClipboard(m_message.GetHwnd())) {
HANDLE hDrop = GetClipboardData(CF_HDROP);
if (hDrop)
- ProcessFileDrop((HDROP)hDrop);
+ ProcessFileDrop((HDROP)hDrop, m_hContact);
CloseClipboard();
}
}
@@ -1501,28 +1477,6 @@ void CMsgDialog::RemakeLog()
m_pLog->LogEvents(m_hDbEventFirst, -1, 0);
}
-void CMsgDialog::ProcessFileDrop(HDROP hDrop)
-{
- if (m_szProto == nullptr) return;
- if (!(CallProtoService(m_szProto, PS_GETCAPS, PFLAGNUM_1, 0) & PF1_FILESEND)) return;
- if (m_wStatus == ID_STATUS_OFFLINE) return;
- if (m_hContact != 0) {
- wchar_t szFilename[MAX_PATH];
- int fileCount = DragQueryFile(hDrop, -1, nullptr, 0), totalCount = 0;
- wchar_t **ppFiles = nullptr;
- for (int i = 0; i < fileCount; i++) {
- DragQueryFile(hDrop, i, szFilename, _countof(szFilename));
- AddToFileList(&ppFiles, totalCount, szFilename);
- }
- CallServiceSync(MS_FILE_SENDSPECIFICFILEST, m_hContact, (LPARAM)ppFiles);
- if (ppFiles) {
- for (int i = 0; ppFiles[i]; i++)
- mir_free(ppFiles[i]);
- mir_free(ppFiles);
- }
- }
-}
-
void CMsgDialog::ShowAvatar()
{
if (g_dat.bShowAvatar) {
diff --git a/src/core/stdmsg/src/msgs.h b/src/core/stdmsg/src/msgs.h
index 3f045dc17a..7b77bae289 100644
--- a/src/core/stdmsg/src/msgs.h
+++ b/src/core/stdmsg/src/msgs.h
@@ -58,7 +58,6 @@ class CMsgDialog : public CSrmmBaseDialog
void Init(void);
void NotifyTyping(int mode);
- void ProcessFileDrop(HDROP hDrop);
void ShowAvatar(void);
void ShowTime(bool bForce);
void SetupStatusBar(void);
diff --git a/src/mir_app/src/clcfiledrop.cpp b/src/mir_app/src/clcfiledrop.cpp
index a85e0fa5da..f3c1d40039 100644
--- a/src/mir_app/src/clcfiledrop.cpp
+++ b/src/mir_app/src/clcfiledrop.cpp
@@ -172,31 +172,6 @@ HRESULT CDropTarget::DragLeave(void)
return S_OK;
}
-static void AddToFileList(wchar_t ***pppFiles, int *totalCount, const wchar_t *szFilename)
-{
- *pppFiles = (wchar_t **) mir_realloc(*pppFiles, (++*totalCount + 1) * sizeof(wchar_t *));
- (*pppFiles)[*totalCount] = nullptr;
- (*pppFiles)[*totalCount - 1] = mir_wstrdup(szFilename);
- if (GetFileAttributes(szFilename) & FILE_ATTRIBUTE_DIRECTORY) {
- WIN32_FIND_DATA fd;
- HANDLE hFind;
- wchar_t szPath[MAX_PATH];
- mir_wstrcpy(szPath, szFilename);
- mir_wstrcat(szPath, L"\\*");
- if (hFind = FindFirstFile(szPath, &fd)) {
- do {
- if (!mir_wstrcmp(fd.cFileName, L".") || !mir_wstrcmp(fd.cFileName, L".."))
- continue;
- mir_wstrcpy(szPath, szFilename);
- mir_wstrcat(szPath, L"\\");
- mir_wstrcat(szPath, fd.cFileName);
- AddToFileList(pppFiles, totalCount, szPath);
- } while (FindNextFile(hFind, &fd));
- FindClose(hFind);
- }
- }
-}
-
HRESULT CDropTarget::Drop(IDataObject * pDataObj, DWORD /*fKeyState*/, POINTL pt, DWORD * pdwEffect)
{
FORMATETC fe = { CF_HDROP, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
@@ -210,33 +185,18 @@ HRESULT CDropTarget::Drop(IDataObject * pDataObj, DWORD /*fKeyState*/, POINTL pt
*pdwEffect = DROPEFFECT_NONE;
if (hwndCurrentDrag == nullptr || S_OK != pDataObj->GetData(&fe, &stg))
return S_OK;
- hDrop = (HDROP) stg.hGlobal;
- ClcData *dat = (ClcData *) GetWindowLongPtr(hwndCurrentDrag, 0);
+
+ hDrop = (HDROP)stg.hGlobal;
+ ClcData *dat = (ClcData *)GetWindowLongPtr(hwndCurrentDrag, 0);
shortPt.x = pt.x;
shortPt.y = pt.y;
ScreenToClient(hwndCurrentDrag, &shortPt);
MCONTACT hContact = HContactFromPoint(hwndCurrentDrag, dat, shortPt.x, shortPt.y, nullptr);
- if (hContact != 0) {
- wchar_t **ppFiles = nullptr;
- wchar_t szFilename[MAX_PATH];
- int fileCount, totalCount = 0, i;
-
- fileCount = DragQueryFile(hDrop, -1, nullptr, 0);
- ppFiles = nullptr;
- for (i=0; i < fileCount; i++) {
- DragQueryFile(hDrop, i, szFilename, _countof(szFilename));
- AddToFileList(&ppFiles, &totalCount, szFilename);
- }
-
- if (!CallService(MS_FILE_SENDSPECIFICFILEST, hContact, (LPARAM)ppFiles))
+ if (hContact != 0)
+ if (ProcessFileDrop(hDrop, hContact))
*pdwEffect = DROPEFFECT_COPY;
- for (i=0; ppFiles[i]; i++)
- mir_free(ppFiles[i]);
- mir_free(ppFiles);
- }
-
if (stg.pUnkForRelease)
stg.pUnkForRelease->Release();
else
@@ -248,7 +208,7 @@ HRESULT CDropTarget::Drop(IDataObject * pDataObj, DWORD /*fKeyState*/, POINTL pt
void RegisterFileDropping(HWND hwnd)
{
- RegisterDragDrop(hwnd, (IDropTarget *) & dropTarget);
+ RegisterDragDrop(hwnd, (IDropTarget*)&dropTarget);
}
void UnregisterFileDropping(HWND hwnd)
diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def
index 017b3926b6..2bf18c7b40 100644
--- a/src/mir_app/src/mir_app.def
+++ b/src/mir_app/src/mir_app.def
@@ -724,3 +724,4 @@ _WebSocket_Connect@12 @810 NONAME
Netlib_Dump @812 NONAME
?ProtoBroadcastAsync@PROTO_INTERFACE@@QAEXIHHPAXJ@Z @813 NONAME
ProtoBroadcastAsync @814 NONAME
+?ProcessFileDrop@@YG_NPAUHDROP__@@I@Z @815 NONAME
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def
index 9fc0ee75b4..f87708dd0e 100644
--- a/src/mir_app/src/mir_app64.def
+++ b/src/mir_app/src/mir_app64.def
@@ -724,3 +724,4 @@ WebSocket_Connect @810 NONAME
Netlib_Dump @812 NONAME
?ProtoBroadcastAsync@PROTO_INTERFACE@@QEAAXIHHPEAX_J@Z @813 NONAME
ProtoBroadcastAsync @814 NONAME
+?ProcessFileDrop@@YA_NPEAUHDROP__@@I@Z @815 NONAME
diff --git a/src/mir_app/src/utils.cpp b/src/mir_app/src/utils.cpp
index 9a4a91df2f..1f7c05bea9 100644
--- a/src/mir_app/src/utils.cpp
+++ b/src/mir_app/src/utils.cpp
@@ -315,6 +315,68 @@ static INT_PTR GetCountryList(WPARAM wParam, LPARAM lParam)
/////////////////////////////////////////////////////////////////////////////////////////
+static void AddToFileList(wchar_t **&pppFiles, int &totalCount, const wchar_t *szFilename)
+{
+ pppFiles = (wchar_t **)mir_realloc(pppFiles, (++totalCount + 1) * sizeof(wchar_t *));
+ pppFiles[totalCount] = nullptr;
+ pppFiles[totalCount - 1] = mir_wstrdup(szFilename);
+
+ if (GetFileAttributes(szFilename) & FILE_ATTRIBUTE_DIRECTORY) {
+ WIN32_FIND_DATA fd;
+ HANDLE hFind;
+ wchar_t szPath[MAX_PATH];
+ mir_wstrcpy(szPath, szFilename);
+ mir_wstrcat(szPath, L"\\*");
+ if (hFind = FindFirstFile(szPath, &fd)) {
+ do {
+ if (!mir_wstrcmp(fd.cFileName, L".") || !mir_wstrcmp(fd.cFileName, L".."))
+ continue;
+ mir_wstrcpy(szPath, szFilename);
+ mir_wstrcat(szPath, L"\\");
+ mir_wstrcat(szPath, fd.cFileName);
+ AddToFileList(pppFiles, totalCount, szPath);
+ } while (FindNextFile(hFind, &fd));
+ FindClose(hFind);
+ }
+ }
+}
+
+MIR_APP_DLL(bool) ProcessFileDrop(HDROP hDrop, MCONTACT hContact)
+{
+ if (hDrop == nullptr || hContact == 0)
+ return false;
+
+ auto *szProto = Proto_GetBaseAccountName(hContact);
+ if (szProto == nullptr)
+ return false;
+
+ int pcaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_1, 0);
+ if (!(pcaps & PF1_FILESEND))
+ return false;
+
+ if (Contact_GetStatus(hContact) == ID_STATUS_OFFLINE) {
+ pcaps = CallProtoService(szProto, PS_GETCAPS, PFLAGNUM_4, 0);
+ if (!(pcaps & PF4_OFFLINEFILES))
+ return false;
+ }
+
+ int fileCount = DragQueryFile(hDrop, -1, nullptr, 0), totalCount = 0;
+ wchar_t **ppFiles = nullptr;
+ for (int i = 0; i < fileCount; i++) {
+ wchar_t szFilename[MAX_PATH];
+ if (DragQueryFileW(hDrop, i, szFilename, _countof(szFilename)))
+ AddToFileList(ppFiles, totalCount, szFilename);
+ }
+
+ CallService(MS_FILE_SENDSPECIFICFILEST, hContact, (LPARAM)ppFiles);
+
+ for (int i=0; ppFiles[i]; i++)
+ mir_free(ppFiles[i]);
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
int LoadUtilsModule(void)
{
bModuleInitialized = TRUE;