summaryrefslogtreecommitdiff
path: root/protocols/ICQ-WIM
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2023-07-09 21:01:10 +0300
committerGeorge Hazan <george.hazan@gmail.com>2023-07-09 21:01:10 +0300
commit4bf93234f7f2b3dfe0a0ac968ca22b8a0d19c046 (patch)
treede1cb6cd781b97cf61d9c3144dc5e82b94e7793a /protocols/ICQ-WIM
parent6872262b3619b07418092be5a7689c8c195282a2 (diff)
fixes #3552 (ICQ: crash on cancel waiting filetransfer)
Diffstat (limited to 'protocols/ICQ-WIM')
-rw-r--r--protocols/ICQ-WIM/ICQ-WIM.vcxproj1
-rw-r--r--protocols/ICQ-WIM/ICQ-WIM.vcxproj.filters3
-rw-r--r--protocols/ICQ-WIM/src/file.cpp78
-rw-r--r--protocols/ICQ-WIM/src/proto.cpp3
-rw-r--r--protocols/ICQ-WIM/src/proto.h64
5 files changed, 91 insertions, 58 deletions
diff --git a/protocols/ICQ-WIM/ICQ-WIM.vcxproj b/protocols/ICQ-WIM/ICQ-WIM.vcxproj
index e9b9f8c37e..53677eedfa 100644
--- a/protocols/ICQ-WIM/ICQ-WIM.vcxproj
+++ b/protocols/ICQ-WIM/ICQ-WIM.vcxproj
@@ -26,6 +26,7 @@
<Import Project="$(ProjectDir)..\..\build\vc.common\plugin.props" />
</ImportGroup>
<ItemGroup>
+ <ClCompile Include="src\file.cpp" />
<ClCompile Include="src\groupchats.cpp" />
<ClCompile Include="src\groups.cpp" />
<ClCompile Include="src\http.cpp" />
diff --git a/protocols/ICQ-WIM/ICQ-WIM.vcxproj.filters b/protocols/ICQ-WIM/ICQ-WIM.vcxproj.filters
index 62171a5720..d52897b648 100644
--- a/protocols/ICQ-WIM/ICQ-WIM.vcxproj.filters
+++ b/protocols/ICQ-WIM/ICQ-WIM.vcxproj.filters
@@ -41,6 +41,9 @@
<ClCompile Include="src\groups.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\file.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\http.h">
diff --git a/protocols/ICQ-WIM/src/file.cpp b/protocols/ICQ-WIM/src/file.cpp
new file mode 100644
index 0000000000..76b55026f9
--- /dev/null
+++ b/protocols/ICQ-WIM/src/file.cpp
@@ -0,0 +1,78 @@
+/*
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdafx.h"
+
+// create an object for receiving
+IcqFileTransfer::IcqFileTransfer(MCONTACT hContact, const char *pszUrl) :
+ m_szHost(pszUrl)
+{
+ pfts.hContact = hContact;
+ pfts.totalFiles = 1;
+ pfts.flags = PFTS_UNICODE | PFTS_RECEIVING;
+
+ ptrW pwszFileName(mir_utf8decodeW(pszUrl));
+ if (pwszFileName == nullptr)
+ pwszFileName = mir_a2u(pszUrl);
+
+ const wchar_t *p = wcsrchr(pwszFileName, '/');
+ m_wszFileName = (p == nullptr) ? pwszFileName : p + 1;
+ m_wszShortName = m_wszFileName;
+}
+
+// create an object for sending
+IcqFileTransfer::IcqFileTransfer(MCONTACT hContact, const wchar_t *pwszFileName) :
+ m_wszFileName(pwszFileName)
+{
+ pfts.flags = PFTS_UNICODE | PFTS_SENDING;
+ pfts.hContact = hContact;
+ pfts.szCurrentFile.w = m_wszFileName.GetBuffer();
+
+ const wchar_t *p = wcsrchr(pfts.szCurrentFile.w, '\\');
+ if (pwszFileName != nullptr)
+ p++;
+ else
+ p = pfts.szCurrentFile.w;
+ m_wszShortName = p;
+}
+
+IcqFileTransfer::~IcqFileTransfer()
+{
+ if (m_fileId >= 0)
+ _close(m_fileId);
+}
+
+void IcqFileTransfer::FillHeaders(AsyncHttpRequest *pReq)
+{
+ pReq->AddHeader("Content-Type", "application/octet-stream");
+ pReq->AddHeader("Content-Disposition", CMStringA(FORMAT, "attachment; filename=\"%s\"", T2Utf(m_wszShortName).get()));
+
+ uint32_t dwPortion = pfts.currentFileSize - pfts.currentFileProgress;
+ if (dwPortion > 1000000)
+ dwPortion = 1000000;
+
+ pReq->AddHeader("Content-Range", CMStringA(FORMAT, "bytes %lld-%lld/%lld", pfts.currentFileProgress, pfts.currentFileProgress + dwPortion - 1, pfts.currentFileSize));
+ pReq->AddHeader("Content-Length", CMStringA(FORMAT, "%d", dwPortion));
+
+ pReq->dataLength = dwPortion;
+ pReq->pData = (char *)mir_alloc(dwPortion);
+ _lseek(m_fileId, pfts.currentFileProgress, SEEK_SET);
+ _read(m_fileId, pReq->pData, dwPortion);
+
+ pfts.currentFileProgress += dwPortion;
+ pfts.totalProgress += dwPortion;
+}
diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp
index 83fb342dec..9cade4f8d9 100644
--- a/protocols/ICQ-WIM/src/proto.cpp
+++ b/protocols/ICQ-WIM/src/proto.cpp
@@ -351,6 +351,7 @@ HANDLE CIcqProto::FileAllow(MCONTACT, HANDLE hTransfer, const wchar_t *pwszSaveP
auto *ft = (IcqFileTransfer *)hTransfer;
ft->m_wszFileName.Insert(0, pwszSavePath);
ft->pfts.szCurrentFile.w = ft->m_wszFileName.GetBuffer();
+ ft->Acquire();
auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_GET, ft->m_szHost, &CIcqProto::OnFileRecv);
pReq->pUserInfo = ft;
@@ -370,7 +371,7 @@ int CIcqProto::FileCancel(MCONTACT hContact, HANDLE hTransfer)
if (ft->pfts.currentFileTime != 0)
ft->m_bCanceled = true;
else
- delete ft;
+ ft->Release();
return 0;
}
diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h
index 307e3482cd..b7cac8f5c4 100644
--- a/protocols/ICQ-WIM/src/proto.h
+++ b/protocols/ICQ-WIM/src/proto.h
@@ -144,47 +144,8 @@ struct IcqConn
int lastTs, timeout;
};
-struct IcqFileTransfer : public MZeroedObject
+struct IcqFileTransfer : public MZeroedObject, public MShareable
{
- // create an object for receiving
- IcqFileTransfer(MCONTACT hContact, const char *pszUrl) :
- m_szHost(pszUrl)
- {
- pfts.hContact = hContact;
- pfts.totalFiles = 1;
- pfts.flags = PFTS_UNICODE | PFTS_RECEIVING;
-
- ptrW pwszFileName(mir_utf8decodeW(pszUrl));
- if (pwszFileName == nullptr)
- pwszFileName = mir_a2u(pszUrl);
-
- const wchar_t *p = wcsrchr(pwszFileName, '/');
- m_wszFileName = (p == nullptr) ? pwszFileName : p + 1;
- m_wszShortName = m_wszFileName;
- }
-
- // create an object for sending
- IcqFileTransfer(MCONTACT hContact, const wchar_t *pwszFileName) :
- m_wszFileName(pwszFileName)
- {
- pfts.flags = PFTS_UNICODE | PFTS_SENDING;
- pfts.hContact = hContact;
- pfts.szCurrentFile.w = m_wszFileName.GetBuffer();
-
- const wchar_t *p = wcsrchr(pfts.szCurrentFile.w, '\\');
- if (pwszFileName != nullptr)
- p++;
- else
- p = pfts.szCurrentFile.w;
- m_wszShortName = p;
- }
-
- ~IcqFileTransfer()
- {
- if (m_fileId >= 0)
- _close(m_fileId);
- }
-
bool m_bCanceled = false, m_bStarted = false;
int m_fileId = -1;
CMStringA m_szHost;
@@ -193,26 +154,15 @@ struct IcqFileTransfer : public MZeroedObject
PROTOFILETRANSFERSTATUS pfts;
HANDLE hWaitEvent;
- void FillHeaders(AsyncHttpRequest *pReq)
- {
- pReq->AddHeader("Content-Type", "application/octet-stream");
- pReq->AddHeader("Content-Disposition", CMStringA(FORMAT, "attachment; filename=\"%s\"", T2Utf(m_wszShortName).get()));
-
- uint32_t dwPortion = pfts.currentFileSize - pfts.currentFileProgress;
- if (dwPortion > 1000000)
- dwPortion = 1000000;
+ // create an object for receiving
+ IcqFileTransfer(MCONTACT hContact, const char *pszUrl);
- pReq->AddHeader("Content-Range", CMStringA(FORMAT, "bytes %lld-%lld/%lld", pfts.currentFileProgress, pfts.currentFileProgress + dwPortion - 1, pfts.currentFileSize));
- pReq->AddHeader("Content-Length", CMStringA(FORMAT, "%d", dwPortion));
+ // create an object for sending
+ IcqFileTransfer(MCONTACT hContact, const wchar_t *pwszFileName);
- pReq->dataLength = dwPortion;
- pReq->pData = (char*)mir_alloc(dwPortion);
- _lseek(m_fileId, pfts.currentFileProgress, SEEK_SET);
- _read(m_fileId, pReq->pData, dwPortion);
+ ~IcqFileTransfer() override;
- pfts.currentFileProgress += dwPortion;
- pfts.totalProgress += dwPortion;
- }
+ void FillHeaders(AsyncHttpRequest *pReq);
};
class CIcqProto : public PROTO<CIcqProto>