diff options
author | George Hazan <george.hazan@gmail.com> | 2023-07-09 21:01:10 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2023-07-09 21:01:10 +0300 |
commit | 4bf93234f7f2b3dfe0a0ac968ca22b8a0d19c046 (patch) | |
tree | de1cb6cd781b97cf61d9c3144dc5e82b94e7793a /protocols/ICQ-WIM | |
parent | 6872262b3619b07418092be5a7689c8c195282a2 (diff) |
fixes #3552 (ICQ: crash on cancel waiting filetransfer)
Diffstat (limited to 'protocols/ICQ-WIM')
-rw-r--r-- | protocols/ICQ-WIM/ICQ-WIM.vcxproj | 1 | ||||
-rw-r--r-- | protocols/ICQ-WIM/ICQ-WIM.vcxproj.filters | 3 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/file.cpp | 78 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/proto.cpp | 3 | ||||
-rw-r--r-- | protocols/ICQ-WIM/src/proto.h | 64 |
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>
|