summaryrefslogtreecommitdiff
path: root/src/mir_app
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 /src/mir_app
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
Diffstat (limited to 'src/mir_app')
-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
4 files changed, 70 insertions, 46 deletions
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;