summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/m_database.h4
-rw-r--r--include/m_protosvc.h1
-rw-r--r--include/m_srmm_int.h5
-rw-r--r--libs/win32/mir_app.libbin262924 -> 263386 bytes
-rw-r--r--libs/win64/mir_app.libbin261946 -> 262438 bytes
-rw-r--r--plugins/Dbx_sqlite/src/dbevents.cpp20
-rw-r--r--plugins/NewStory/src/history_array.cpp4
-rw-r--r--protocols/Telegram/src/avatars.cpp5
-rw-r--r--src/mir_app/src/chat_svc.cpp4
-rw-r--r--src/mir_app/src/db_events.cpp6
-rw-r--r--src/mir_app/src/file.cpp166
-rw-r--r--src/mir_app/src/file.h30
-rw-r--r--src/mir_app/src/fileexistsdlg.cpp8
-rw-r--r--src/mir_app/src/fileopts.cpp4
-rw-r--r--src/mir_app/src/fileutils.cpp181
-rw-r--r--src/mir_app/src/filexferdlg.cpp2
-rw-r--r--src/mir_app/src/mir_app.def4
-rw-r--r--src/mir_app/src/mir_app64.def4
-rw-r--r--src/mir_app/src/proto_internal.cpp19
-rw-r--r--src/mir_app/src/srmm_util.cpp35
20 files changed, 269 insertions, 233 deletions
diff --git a/include/m_database.h b/include/m_database.h
index dd8afaca1a..90ebd63b93 100644
--- a/include/m_database.h
+++ b/include/m_database.h
@@ -701,7 +701,7 @@ namespace DB
class MIR_APP_EXPORT FILE_BLOB : public MNonCopyable
{
- ptrW m_wszFileName, m_wszDescription;
+ ptrW m_wszFileName, m_wszDescription, m_wszLocalName;
ptrA m_szProtoString;
int64_t m_iFileSize = -1, m_iTransferred = -1;
@@ -713,6 +713,7 @@ namespace DB
void write(EventInfo &dbei);
__forceinline const char* getUrl() const { return m_szProtoString; }
+ __forceinline const wchar_t* getLocalName() const { return m_wszLocalName; }
__forceinline const wchar_t* getName() const { return m_wszFileName; }
__forceinline const wchar_t* getDescr() const { return m_wszDescription; }
@@ -724,6 +725,7 @@ namespace DB
__forceinline void setUrl(const char *pszUrl) { m_szProtoString = mir_strdup(pszUrl); }
__forceinline void setSize(int64_t iSize) { m_iFileSize = iSize; }
+ __forceinline void setLocalName(const wchar_t *pszFileName) { m_wszLocalName = mir_wstrdup(pszFileName); }
};
/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/include/m_protosvc.h b/include/m_protosvc.h
index c4a62e7327..170d1260c0 100644
--- a/include/m_protosvc.h
+++ b/include/m_protosvc.h
@@ -815,6 +815,7 @@ struct MIR_APP_EXPORT OFDTHREAD : public MNonCopyable
OFDTHREAD(MEVENT, const CMStringW &, bool);
void Finish();
+ void ResetFileName(const wchar_t *pwszNewName);
MEVENT hDbEvent;
CMStringW wszPath;
diff --git a/include/m_srmm_int.h b/include/m_srmm_int.h
index 01295ff327..b2813d9a0b 100644
--- a/include/m_srmm_int.h
+++ b/include/m_srmm_int.h
@@ -356,11 +356,6 @@ MIR_APP_DLL(void) Srmm_CreateHotkey(const char *pszSection, const char *pszDescr
MIR_APP_DLL(void) Srmm_DownloadOfflineFile(MEVENT hDbEvent, bool bOpen);
/////////////////////////////////////////////////////////////////////////////////////////
-// retrieves offline file's name
-
-MIR_APP_DLL(CMStringW) Srmm_GetOfflineFileName(MCONTACT hContact);
-
-/////////////////////////////////////////////////////////////////////////////////////////
// finds a SRMM window using hContact
MIR_APP_DLL(HWND) Srmm_FindWindow(MCONTACT hContact);
diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib
index 280e32a771..77490f8a8c 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 dddba5a8a5..3e9b392024 100644
--- a/libs/win64/mir_app.lib
+++ b/libs/win64/mir_app.lib
Binary files differ
diff --git a/plugins/Dbx_sqlite/src/dbevents.cpp b/plugins/Dbx_sqlite/src/dbevents.cpp
index c8185fc815..70f3a6e740 100644
--- a/plugins/Dbx_sqlite/src/dbevents.cpp
+++ b/plugins/Dbx_sqlite/src/dbevents.cpp
@@ -287,6 +287,13 @@ BOOL CDbxSQLite::EditEvent(MEVENT hDbEvent, const DBEVENTINFO *dbei)
return 0;
}
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static void str2json(CMStringA &str)
+{
+ str.Replace("\\", "\\\\");
+}
+
int CDbxSQLite::SetEventJson(MEVENT hDbEvent, const char *szSetting, DBVARIANT *dbv)
{
if (hDbEvent == 0)
@@ -310,7 +317,18 @@ int CDbxSQLite::SetEventJson(MEVENT hDbEvent, const char *szSetting, DBVARIANT *
break;
case DBVT_ASCIIZ:
case DBVT_UTF8:
- sqlite3_bind_text(stmt, 2, dbv->pszVal, (int)mir_strlen(dbv->pszVal), nullptr);
+ {
+ tmp = dbv->pszVal;
+ str2json(tmp);
+ sqlite3_bind_text(stmt, 2, tmp, tmp.GetLength(), nullptr);
+ }
+ break;
+ case DBVT_WCHAR:
+ {
+ tmp = T2Utf(dbv->pwszVal).get();
+ str2json(tmp);
+ sqlite3_bind_text(stmt, 2, tmp, tmp.GetLength(), nullptr);
+ }
break;
default:
return 2;
diff --git a/plugins/NewStory/src/history_array.cpp b/plugins/NewStory/src/history_array.cpp
index 0bcb7e8f9b..adaa690f81 100644
--- a/plugins/NewStory/src/history_array.cpp
+++ b/plugins/NewStory/src/history_array.cpp
@@ -131,15 +131,15 @@ void ItemData::load(bool bFullLoad)
CMStringW wszFileName;
DB::FILE_BLOB blob(dbe);
if (blob.isOffline()) {
- wszFileName = Srmm_GetOfflineFileName(hContact);
+ wszFileName = blob.getLocalName();
}
else {
wchar_t buf[MAX_PATH];
CallService(MS_FILE_GETRECEIVEDFILESFOLDERW, hContact, (LPARAM)buf);
wszFileName = buf;
+ wszFileName.Append(blob.getName());
}
- wszFileName.Append(blob.getName());
// if a filename contains spaces, URL will be broken
if (wszFileName.Find(' ') != -1) {
diff --git a/protocols/Telegram/src/avatars.cpp b/protocols/Telegram/src/avatars.cpp
index c5f60605ac..4a08866989 100644
--- a/protocols/Telegram/src/avatars.cpp
+++ b/protocols/Telegram/src/avatars.cpp
@@ -199,10 +199,11 @@ void CTelegramProto::ProcessFile(TD::updateFile *pObj)
dbv.pszVal = (char *)pSlash;
db_event_setJson(F->ofd->hDbEvent, "f", &dbv);
- wszFullName.Truncate(wszFullName.ReverseFind('\\') + 1);
+ wszFullName.Truncate(wszFullName.ReverseFind('\\'));
wszFullName.Append(Utf2T(pSlash));
+ F->ofd->ResetFileName(wszFullName); // resulting ofd->wszPath may differ from wszFullName
- MoveFileW(wszExistingFile, wszFullName);
+ MoveFileW(wszExistingFile, F->ofd->wszPath);
NotifyEventHooks(g_plugin.m_hevEventEdited, 0, F->ofd->hDbEvent);
F->ofd->Finish();
diff --git a/src/mir_app/src/chat_svc.cpp b/src/mir_app/src/chat_svc.cpp
index d68448b53e..2f94b557f8 100644
--- a/src/mir_app/src/chat_svc.cpp
+++ b/src/mir_app/src/chat_svc.cpp
@@ -856,10 +856,6 @@ static int OnContactDeleted(WPARAM hContact, LPARAM)
if (Contact::GetStatus(hContact) != ID_STATUS_OFFLINE)
CallProtoService(szProto, PS_LEAVECHAT, hContact, 0);
}
-
- auto wszOfflineFileDir = Srmm_GetOfflineFileName(hContact);
- wszOfflineFileDir.Truncate(wszOfflineFileDir.GetLength() - 1);
- DeleteDirectoryTreeW(wszOfflineFileDir);
return 0;
}
diff --git a/src/mir_app/src/db_events.cpp b/src/mir_app/src/db_events.cpp
index 25b7cf0da8..ed1dcd0921 100644
--- a/src/mir_app/src/db_events.cpp
+++ b/src/mir_app/src/db_events.cpp
@@ -310,6 +310,12 @@ DB::FILE_BLOB::FILE_BLOB(const DB::EventInfo &dbei)
m_wszFileName = root["f"].as_mstring().Detach();
m_wszDescription = root["d"].as_mstring().Detach();
+ if (auto &node = root["lf"]) {
+ CMStringW tmp = node.as_mstring();
+ tmp.Replace(L"\\\\", L"\\");
+ m_wszLocalName = tmp.Detach();
+ }
+
CMStringA szProtoString(root["u"].as_mstring());
if (!szProtoString.IsEmpty()) {
m_szProtoString = szProtoString.Detach();
diff --git a/src/mir_app/src/file.cpp b/src/mir_app/src/file.cpp
index 5c82acf4d2..480066e887 100644
--- a/src/mir_app/src/file.cpp
+++ b/src/mir_app/src/file.cpp
@@ -83,20 +83,20 @@ static INT_PTR SendSpecificFilesT(WPARAM hContact, LPARAM lParam)
return (INT_PTR)CreateDialogParam(g_plugin.getInst(), MAKEINTRESOURCE(IDD_FILESEND), NULL, DlgProcSendFile, (LPARAM)&fsd);
}
-static INT_PTR GetReceivedFilesFolder(WPARAM wParam, LPARAM lParam)
+static INT_PTR GetReceivedFilesFolder(WPARAM hContact, LPARAM lParam)
{
wchar_t buf[MAX_PATH];
- GetContactReceivedFilesDir(wParam, buf, MAX_PATH, TRUE);
+ GetContactReceivedFilesDir(hContact, buf, _countof(buf), TRUE);
char *dir = mir_u2a(buf);
mir_strncpy((char *)lParam, dir, MAX_PATH);
mir_free(dir);
return 0;
}
-static INT_PTR GetReceivedFilesFolderW(WPARAM wParam, LPARAM lParam)
+static INT_PTR GetReceivedFilesFolderW(WPARAM hContact, LPARAM lParam)
{
wchar_t buf[MAX_PATH];
- GetContactReceivedFilesDir(wParam, buf, MAX_PATH, TRUE);
+ GetContactReceivedFilesDir(hContact, buf, _countof(buf), TRUE);
mir_wstrncpy((wchar_t *)lParam, buf, MAX_PATH);
return 0;
}
@@ -107,164 +107,6 @@ static INT_PTR RecvFileCommand(WPARAM, LPARAM lParam)
return 0;
}
-int SRFile_GetRegValue(HKEY hKeyBase, const wchar_t *szSubKey, const wchar_t *szValue, wchar_t *szOutput, int cbOutput)
-{
- HKEY hKey;
- DWORD cbOut = cbOutput;
-
- if (RegOpenKeyEx(hKeyBase, szSubKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
- return 0;
-
- if (RegQueryValueEx(hKey, szValue, nullptr, nullptr, (uint8_t*)szOutput, &cbOut) != ERROR_SUCCESS) {
- RegCloseKey(hKey);
- return 0;
- }
-
- RegCloseKey(hKey);
- return 1;
-}
-
-void GetSensiblyFormattedSize(__int64 size, wchar_t *szOut, int cchOut, int unitsOverride, int appendUnits, int *unitsUsed)
-{
- if (!unitsOverride) {
- if (size < 1000) unitsOverride = UNITS_BYTES;
- else if (size < 100 * 1024) unitsOverride = UNITS_KBPOINT1;
- else if (size < 1024 * 1024) unitsOverride = UNITS_KBPOINT0;
- else if (size < 1024 * 1024 * 1024) unitsOverride = UNITS_MBPOINT2;
- else unitsOverride = UNITS_GBPOINT3;
- }
-
- if (unitsUsed)
- *unitsUsed = unitsOverride;
-
- switch (unitsOverride) {
- case UNITS_BYTES: mir_snwprintf(szOut, cchOut, L"%u%s%s", (int)size, appendUnits ? L" " : L"", appendUnits ? TranslateT("bytes") : L""); break;
- case UNITS_KBPOINT1: mir_snwprintf(szOut, cchOut, L"%.1lf%s", size / 1024.0, appendUnits ? L" KB" : L""); break;
- case UNITS_KBPOINT0: mir_snwprintf(szOut, cchOut, L"%u%s", (int)(size / 1024), appendUnits ? L" KB" : L""); break;
- case UNITS_GBPOINT3: mir_snwprintf(szOut, cchOut, L"%.3f%s", (size >> 20) / 1024.0, appendUnits ? L" GB" : L""); break;
- default: mir_snwprintf(szOut, cchOut, L"%.2lf%s", size / 1048576.0, appendUnits ? L" MB" : L""); break;
- }
-}
-
-CMStringW FindUniqueFileName(const wchar_t *pszOriginalFile)
-{
- const wchar_t *pszExtension, *pszFilename;
- if ((pszFilename = wcsrchr(pszOriginalFile, '\\')) == nullptr)
- pszFilename = pszOriginalFile;
- if ((pszExtension = wcsrchr(pszFilename + 1, '.')) == nullptr)
- pszExtension = pszFilename + mir_wstrlen(pszFilename);
-
- CMStringW buf;
- for (int i = 1;; i++) {
- buf.Format(L"%.*s (%d)%s", unsigned(pszExtension - pszOriginalFile), pszOriginalFile, i, pszExtension);
- if (_waccess(buf, 0) != 0)
- break;
- }
- return buf;
-}
-
-// Triple redirection sucks but is needed to nullify the array pointer
-void FreeFilesMatrix(wchar_t ***files)
-{
- if (*files == nullptr)
- return;
-
- // Free each filename in the pointer array
- wchar_t **pFile = *files;
- while (*pFile != nullptr) {
- mir_free(*pFile);
- *pFile = nullptr;
- pFile++;
- }
-
- // Free the array itself
- mir_free(*files);
- *files = nullptr;
-}
-
-void FreeProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *fts)
-{
- mir_free(fts->szCurrentFile.w);
- if (fts->pszFiles.w) {
- for (int i = 0; i < fts->totalFiles; i++) mir_free(fts->pszFiles.w[i]);
- mir_free(fts->pszFiles.w);
- }
- mir_free(fts->szWorkingDir.w);
-}
-
-void CopyProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest, PROTOFILETRANSFERSTATUS *src)
-{
- *dest = *src;
- if (src->szCurrentFile.w) dest->szCurrentFile.w = PFTS_StringToTchar(src->flags, src->szCurrentFile);
- if (src->pszFiles.w) {
- dest->pszFiles.w = (wchar_t**)mir_alloc(sizeof(wchar_t*)*src->totalFiles);
- for (int i = 0; i < src->totalFiles; i++) {
- MAllStrings s = { src->pszFiles.a[i] };
- dest->pszFiles.w[i] = PFTS_StringToTchar(src->flags, s);
- }
- }
- if (src->szWorkingDir.w)
- dest->szWorkingDir.w = PFTS_StringToTchar(src->flags, src->szWorkingDir);
- dest->flags &= ~PFTS_UTF;
- dest->flags |= PFTS_UNICODE;
-}
-
-void UpdateProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest, PROTOFILETRANSFERSTATUS *src)
-{
- dest->hContact = src->hContact;
- dest->flags = src->flags;
- if (dest->totalFiles != src->totalFiles) {
- for (int i = 0; i < dest->totalFiles; i++) mir_free(dest->pszFiles.w[i]);
- mir_free(dest->pszFiles.w);
- dest->pszFiles.w = nullptr;
- dest->totalFiles = src->totalFiles;
- }
- if (src->pszFiles.w) {
- if (!dest->pszFiles.w)
- dest->pszFiles.w = (wchar_t**)mir_calloc(sizeof(wchar_t*)*src->totalFiles);
- for (int i = 0; i < src->totalFiles; i++) {
- MAllStrings fname; fname.w = src->pszFiles.w[i];
- if (!dest->pszFiles.w[i] || !fname.w || PFTS_CompareWithTchar(src, fname, dest->pszFiles.w[i])) {
- mir_free(dest->pszFiles.w[i]);
- if (fname.w)
- dest->pszFiles.w[i] = PFTS_StringToTchar(src->flags, fname);
- else
- dest->pszFiles.w[i] = nullptr;
- }
- }
- }
- else if (dest->pszFiles.w) {
- for (int i = 0; i < dest->totalFiles; i++)
- mir_free(dest->pszFiles.w[i]);
- mir_free(dest->pszFiles.w);
- dest->pszFiles.w = nullptr;
- }
-
- dest->currentFileNumber = src->currentFileNumber;
- dest->totalBytes = src->totalBytes;
- dest->totalProgress = src->totalProgress;
- if (src->szWorkingDir.w && (!dest->szWorkingDir.w || PFTS_CompareWithTchar(src, src->szWorkingDir, dest->szWorkingDir.w))) {
- mir_free(dest->szWorkingDir.w);
- if (src->szWorkingDir.w)
- dest->szWorkingDir.w = PFTS_StringToTchar(src->flags, src->szWorkingDir);
- else
- dest->szWorkingDir.w = nullptr;
- }
-
- if (!dest->szCurrentFile.w || !src->szCurrentFile.w || PFTS_CompareWithTchar(src, src->szCurrentFile, dest->szCurrentFile.w)) {
- mir_free(dest->szCurrentFile.w);
- if (src->szCurrentFile.w)
- dest->szCurrentFile.w = PFTS_StringToTchar(src->flags, src->szCurrentFile);
- else
- dest->szCurrentFile.w = nullptr;
- }
- dest->currentFileSize = src->currentFileSize;
- dest->currentFileProgress = src->currentFileProgress;
- dest->currentFileTime = src->currentFileTime;
- dest->flags &= ~PFTS_UTF;
- dest->flags |= PFTS_UNICODE;
-}
-
static void RemoveUnreadFileEvents(void)
{
for (auto &hContact : Contacts()) {
diff --git a/src/mir_app/src/file.h b/src/mir_app/src/file.h
index 17456425eb..6689b3ceac 100644
--- a/src/mir_app/src/file.h
+++ b/src/mir_app/src/file.h
@@ -74,24 +74,8 @@ struct FileDlgData : public MZeroedObject
};
// file.c
-#define UNITS_BYTES 1 // 0 <= size<1000: "%d bytes"
-#define UNITS_KBPOINT1 2 // 1000 <= size<100*1024: "%.1f KB"
-#define UNITS_KBPOINT0 3 // 100*1024 <= size<1024*1024: "%d KB"
-#define UNITS_MBPOINT2 4 // 1024*1024 <= size: "%.2f MB"
-#define UNITS_GBPOINT3 5 // 1024*1024*1024 <= size: "%.3f GB"
-
-int SRFile_GetRegValue(HKEY hKeyBase, const wchar_t *szSubKey, const wchar_t *szValue, wchar_t *szOutput, int cbOutput);
-
-void GetSensiblyFormattedSize(__int64 size, wchar_t *szOut, int cchOut, int unitsOverride, int appendUnits, int *unitsUsed);
-void FreeFilesMatrix(wchar_t ***files); //loving that triple indirection
-void FreeProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *fts);
-void CopyProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest, PROTOFILETRANSFERSTATUS *src);
-void UpdateProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest, PROTOFILETRANSFERSTATUS *src);
-
MEVENT Proto_RecvFile(MCONTACT hContact, PROTORECVFILE *pre);
-CMStringW FindUniqueFileName(const wchar_t *pszOriginalFile);
-
// filesenddlg.c
INT_PTR CALLBACK DlgProcSendFile(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
@@ -101,7 +85,7 @@ void RemoveInvalidFilenameChars(wchar_t *tszString);
void RemoveInvalidPathChars(wchar_t *tszString);
void GetContactReceivedFilesDir(MCONTACT hContact, wchar_t *szDir, int cchDir, BOOL substVars);
void GetReceivedFilesDir(wchar_t *szDir, int cchDir);
-int BrowseForFolder(HWND hwnd, wchar_t *szPath);
+int BrowseForFolder(HWND hwnd, wchar_t *szPath);
// fileexistsdlg.c
struct TDlgProcFileExistsParam
@@ -144,6 +128,16 @@ namespace File
};
// fieutils.c
+void FreeFilesMatrix(wchar_t ***files); //loving that triple indirection
+void FreeProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *fts);
+void CopyProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest, PROTOFILETRANSFERSTATUS *src);
+void UpdateProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest, PROTOFILETRANSFERSTATUS *src);
wchar_t *PFTS_StringToTchar(int flags, const MAllStrings s);
-int PFTS_CompareWithTchar(PROTOFILETRANSFERSTATUS *ft, const MAllStrings s, wchar_t *r);
+int PFTS_CompareWithTchar(PROTOFILETRANSFERSTATUS *ft, const MAllStrings s, wchar_t *r);
+
+CMStringW CreateUniqueFileName(const wchar_t *pszOriginalFile);
+CMStringW FindUniqueFileName(const wchar_t *pszOriginalFile);
+
+int GetRegValue(HKEY hKeyBase, const wchar_t *szSubKey, const wchar_t *szValue, wchar_t *szOutput, int cbOutput);
+void GetSensiblyFormattedSize(__int64 size, wchar_t *szOut, int cchOut, int unitsOverride, int appendUnits, int *unitsUsed);
diff --git a/src/mir_app/src/fileexistsdlg.cpp b/src/mir_app/src/fileexistsdlg.cpp
index c5d6526a01..801f409dbd 100644
--- a/src/mir_app/src/fileexistsdlg.cpp
+++ b/src/mir_app/src/fileexistsdlg.cpp
@@ -163,14 +163,14 @@ void __cdecl LoadIconsAndTypesThread(void *param)
SendDlgItemMessage(info->hwndDlg, IDC_EXISTINGICON, STM_SETICON, (WPARAM)fileInfo.hIcon, 0);
szIconFile[0] = '\0';
if (!mir_wstrcmp(szExtension, L"EXE"))
- SRFile_GetRegValue(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons", L"2", szIconFile, _countof(szIconFile));
+ GetRegValue(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons", L"2", szIconFile, _countof(szIconFile));
else {
wchar_t szTypeName[MAX_PATH];
- if (SRFile_GetRegValue(HKEY_CLASSES_ROOT, pszExtension, NULL, szTypeName, _countof(szTypeName))) {
+ if (GetRegValue(HKEY_CLASSES_ROOT, pszExtension, NULL, szTypeName, _countof(szTypeName))) {
mir_wstrcat(szTypeName, L"\\DefaultIcon");
- if (SRFile_GetRegValue(HKEY_CLASSES_ROOT, szTypeName, NULL, szIconFile, _countof(szIconFile))) {
+ if (GetRegValue(HKEY_CLASSES_ROOT, szTypeName, NULL, szIconFile, _countof(szIconFile))) {
if (wcsstr(szIconFile, L"%1"))
- SRFile_GetRegValue(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons", L"0", szIconFile, _countof(szIconFile));
+ GetRegValue(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons", L"0", szIconFile, _countof(szIconFile));
else szIconFile[0] = '\0';
}
}
diff --git a/src/mir_app/src/fileopts.cpp b/src/mir_app/src/fileopts.cpp
index 07a5ff0952..eaac150a16 100644
--- a/src/mir_app/src/fileopts.cpp
+++ b/src/mir_app/src/fileopts.cpp
@@ -172,7 +172,7 @@ public:
for (int i = 0; i < _countof(virusScanners); i++) {
wchar_t szScanExe[MAX_PATH];
- if (SRFile_GetRegValue(HKEY_LOCAL_MACHINE, virusScanners[i].szExeRegPath, virusScanners[i].szExeRegValue, szScanExe, _countof(szScanExe)))
+ if (GetRegValue(HKEY_LOCAL_MACHINE, virusScanners[i].szExeRegPath, virusScanners[i].szExeRegValue, szScanExe, _countof(szScanExe)))
cmbScanCmdLine.AddString(virusScanners[i].szProductName, i);
}
@@ -214,7 +214,7 @@ public:
return;
wchar_t szScanExe[MAX_PATH], str[512];
- if (SRFile_GetRegValue(HKEY_LOCAL_MACHINE, virusScanners[iScanner].szExeRegPath, virusScanners[iScanner].szExeRegValue, szScanExe, _countof(szScanExe)))
+ if (GetRegValue(HKEY_LOCAL_MACHINE, virusScanners[iScanner].szExeRegPath, virusScanners[iScanner].szExeRegValue, szScanExe, _countof(szScanExe)))
mir_snwprintf(str, virusScanners[iScanner].szCommandLine, szScanExe);
else
str[0] = 0;
diff --git a/src/mir_app/src/fileutils.cpp b/src/mir_app/src/fileutils.cpp
index 3533e74c42..c395710270 100644
--- a/src/mir_app/src/fileutils.cpp
+++ b/src/mir_app/src/fileutils.cpp
@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdafx.h"
+#include "file.h"
wchar_t* PFTS_StringToTchar(int flags, const MAllStrings s)
{
@@ -37,3 +38,183 @@ int PFTS_CompareWithTchar(PROTOFILETRANSFERSTATUS *ft, const MAllStrings s, wcha
return mir_wstrcmp(_A2T(s.a), r);
}
+
+void CopyProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest, PROTOFILETRANSFERSTATUS *src)
+{
+ *dest = *src;
+
+ if (src->szCurrentFile.w)
+ dest->szCurrentFile.w = PFTS_StringToTchar(src->flags, src->szCurrentFile);
+
+ if (src->pszFiles.w) {
+ dest->pszFiles.w = (wchar_t **)mir_alloc(sizeof(wchar_t *) * src->totalFiles);
+ for (int i = 0; i < src->totalFiles; i++) {
+ MAllStrings s = { src->pszFiles.a[i] };
+ dest->pszFiles.w[i] = PFTS_StringToTchar(src->flags, s);
+ }
+ }
+
+ if (src->szWorkingDir.w)
+ dest->szWorkingDir.w = PFTS_StringToTchar(src->flags, src->szWorkingDir);
+
+ dest->flags &= ~PFTS_UTF;
+ dest->flags |= PFTS_UNICODE;
+}
+
+void UpdateProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *dest, PROTOFILETRANSFERSTATUS *src)
+{
+ dest->hContact = src->hContact;
+ dest->flags = src->flags;
+ if (dest->totalFiles != src->totalFiles) {
+ for (int i = 0; i < dest->totalFiles; i++) mir_free(dest->pszFiles.w[i]);
+ mir_free(dest->pszFiles.w);
+ dest->pszFiles.w = nullptr;
+ dest->totalFiles = src->totalFiles;
+ }
+ if (src->pszFiles.w) {
+ if (!dest->pszFiles.w)
+ dest->pszFiles.w = (wchar_t **)mir_calloc(sizeof(wchar_t *) * src->totalFiles);
+ for (int i = 0; i < src->totalFiles; i++) {
+ MAllStrings fname; fname.w = src->pszFiles.w[i];
+ if (!dest->pszFiles.w[i] || !fname.w || PFTS_CompareWithTchar(src, fname, dest->pszFiles.w[i])) {
+ mir_free(dest->pszFiles.w[i]);
+ if (fname.w)
+ dest->pszFiles.w[i] = PFTS_StringToTchar(src->flags, fname);
+ else
+ dest->pszFiles.w[i] = nullptr;
+ }
+ }
+ }
+ else if (dest->pszFiles.w) {
+ for (int i = 0; i < dest->totalFiles; i++)
+ mir_free(dest->pszFiles.w[i]);
+ mir_free(dest->pszFiles.w);
+ dest->pszFiles.w = nullptr;
+ }
+
+ dest->currentFileNumber = src->currentFileNumber;
+ dest->totalBytes = src->totalBytes;
+ dest->totalProgress = src->totalProgress;
+ if (src->szWorkingDir.w && (!dest->szWorkingDir.w || PFTS_CompareWithTchar(src, src->szWorkingDir, dest->szWorkingDir.w))) {
+ mir_free(dest->szWorkingDir.w);
+ if (src->szWorkingDir.w)
+ dest->szWorkingDir.w = PFTS_StringToTchar(src->flags, src->szWorkingDir);
+ else
+ dest->szWorkingDir.w = nullptr;
+ }
+
+ if (!dest->szCurrentFile.w || !src->szCurrentFile.w || PFTS_CompareWithTchar(src, src->szCurrentFile, dest->szCurrentFile.w)) {
+ mir_free(dest->szCurrentFile.w);
+ if (src->szCurrentFile.w)
+ dest->szCurrentFile.w = PFTS_StringToTchar(src->flags, src->szCurrentFile);
+ else
+ dest->szCurrentFile.w = nullptr;
+ }
+ dest->currentFileSize = src->currentFileSize;
+ dest->currentFileProgress = src->currentFileProgress;
+ dest->currentFileTime = src->currentFileTime;
+ dest->flags &= ~PFTS_UTF;
+ dest->flags |= PFTS_UNICODE;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Triple redirection sucks but is needed to nullify the array pointer
+
+void FreeFilesMatrix(wchar_t ***files)
+{
+ if (*files == nullptr)
+ return;
+
+ // Free each filename in the pointer array
+ wchar_t **pFile = *files;
+ while (*pFile != nullptr) {
+ mir_free(*pFile);
+ *pFile = nullptr;
+ pFile++;
+ }
+
+ // Free the array itself
+ mir_free(*files);
+ *files = nullptr;
+}
+
+void FreeProtoFileTransferStatus(PROTOFILETRANSFERSTATUS *fts)
+{
+ mir_free(fts->szCurrentFile.w);
+ if (fts->pszFiles.w) {
+ for (int i = 0; i < fts->totalFiles; i++) mir_free(fts->pszFiles.w[i]);
+ mir_free(fts->pszFiles.w);
+ }
+ mir_free(fts->szWorkingDir.w);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CMStringW CreateUniqueFileName(const wchar_t *pszOriginalFile)
+{
+ const wchar_t *pszExtension, *pszFilename;
+ if ((pszFilename = wcsrchr(pszOriginalFile, '\\')) == nullptr)
+ pszFilename = pszOriginalFile;
+ if ((pszExtension = wcsrchr(pszFilename + 1, '.')) == nullptr)
+ pszExtension = pszFilename + mir_wstrlen(pszFilename);
+
+ CMStringW buf;
+ for (int i = 1;; i++) {
+ buf.Format(L"%.*s (%d)%s", unsigned(pszExtension - pszOriginalFile), pszOriginalFile, i, pszExtension);
+ if (_waccess(buf, 0) != 0)
+ break;
+ }
+ return buf;
+}
+
+CMStringW FindUniqueFileName(const wchar_t *pszOriginalFile)
+{
+ if (_waccess(pszOriginalFile, 0))
+ return pszOriginalFile;
+
+ return CreateUniqueFileName(pszOriginalFile);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int GetRegValue(HKEY hKeyBase, const wchar_t *szSubKey, const wchar_t *szValue, wchar_t *szOutput, int cbOutput)
+{
+ HKEY hKey;
+ if (RegOpenKeyEx(hKeyBase, szSubKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
+ return 0;
+
+ DWORD cbOut = cbOutput;
+ auto ret = RegQueryValueEx(hKey, szValue, nullptr, nullptr, (uint8_t *)szOutput, &cbOut);
+ RegCloseKey(hKey);
+ return ret == ERROR_SUCCESS;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#define UNITS_BYTES 1 // 0 <= size<1000: "%d bytes"
+#define UNITS_KBPOINT1 2 // 1000 <= size<100*1024: "%.1f KB"
+#define UNITS_KBPOINT0 3 // 100*1024 <= size<1024*1024: "%d KB"
+#define UNITS_MBPOINT2 4 // 1024*1024 <= size: "%.2f MB"
+#define UNITS_GBPOINT3 5 // 1024*1024*1024 <= size: "%.3f GB"
+
+void GetSensiblyFormattedSize(__int64 size, wchar_t *szOut, int cchOut, int unitsOverride, int appendUnits, int *unitsUsed)
+{
+ if (!unitsOverride) {
+ if (size < 1000) unitsOverride = UNITS_BYTES;
+ else if (size < 100 * 1024) unitsOverride = UNITS_KBPOINT1;
+ else if (size < 1024 * 1024) unitsOverride = UNITS_KBPOINT0;
+ else if (size < 1024 * 1024 * 1024) unitsOverride = UNITS_MBPOINT2;
+ else unitsOverride = UNITS_GBPOINT3;
+ }
+
+ if (unitsUsed)
+ *unitsUsed = unitsOverride;
+
+ switch (unitsOverride) {
+ case UNITS_BYTES: mir_snwprintf(szOut, cchOut, L"%u%s%s", (int)size, appendUnits ? L" " : L"", appendUnits ? TranslateT("bytes") : L""); break;
+ case UNITS_KBPOINT1: mir_snwprintf(szOut, cchOut, L"%.1lf%s", size / 1024.0, appendUnits ? L" KB" : L""); break;
+ case UNITS_KBPOINT0: mir_snwprintf(szOut, cchOut, L"%u%s", (int)(size / 1024), appendUnits ? L" KB" : L""); break;
+ case UNITS_GBPOINT3: mir_snwprintf(szOut, cchOut, L"%.3f%s", (size >> 20) / 1024.0, appendUnits ? L" GB" : L""); break;
+ default: mir_snwprintf(szOut, cchOut, L"%.2lf%s", size / 1048576.0, appendUnits ? L" MB" : L""); break;
+ }
+}
diff --git a/src/mir_app/src/filexferdlg.cpp b/src/mir_app/src/filexferdlg.cpp
index fabac20dc7..c284f9edb1 100644
--- a/src/mir_app/src/filexferdlg.cpp
+++ b/src/mir_app/src/filexferdlg.cpp
@@ -443,7 +443,7 @@ INT_PTR CALLBACK DlgProcFileTransfer(HWND hwndDlg, UINT msg, WPARAM wParam, LPAR
case FILERESUME_RENAMEALL:
pfr->action = FILERESUME_RENAME;
- replaceStrW(pfr->szFilename, FindUniqueFileName(szOriginalFilename).Detach());
+ replaceStrW(pfr->szFilename, CreateUniqueFileName(szOriginalFilename).Detach());
break;
}
diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def
index 6ec1f8b3ff..5378bc2712 100644
--- a/src/mir_app/src/mir_app.def
+++ b/src/mir_app/src/mir_app.def
@@ -247,7 +247,6 @@ Srmm_RedrawToolbarIcons @338
?Srmm_GetButtonCount@@YGHXZ @340 NONAME
?Srmm_ClickToolbarIcon@@YGXIHPAUHWND__@@H@Z @341 NONAME
?Srmm_DownloadOfflineFile@@YGXI_N@Z @342 NONAME
-?Srmm_GetOfflineFileName@@YG?AV?$CMStringT@_WV?$ChTraitsCRT@_W@@@@I@Z @343 NONAME
Miranda_OkToExit @344
Miranda_GetVersion @345
Miranda_GetFileVersion @346
@@ -879,3 +878,6 @@ Clist_RemoveEvent @989
??0OFDTHREAD@@QAE@IABV?$CMStringT@_WV?$ChTraitsCRT@_W@@@@_N@Z @995 NONAME
??1OFDTHREAD@@QAE@XZ @996 NONAME
?Finish@OFDTHREAD@@QAEXXZ @997 NONAME
+?getLocalName@FILE_BLOB@DB@@QBEPB_WXZ @998 NONAME
+?setLocalName@FILE_BLOB@DB@@QAEXPB_W@Z @999 NONAME
+?ResetFileName@OFDTHREAD@@QAEXPB_W@Z @1000 NONAME
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def
index a43ed51ffc..1b6fc9df48 100644
--- a/src/mir_app/src/mir_app64.def
+++ b/src/mir_app/src/mir_app64.def
@@ -247,7 +247,6 @@ Srmm_RedrawToolbarIcons @338
?Srmm_GetButtonCount@@YAHXZ @340 NONAME
?Srmm_ClickToolbarIcon@@YAXIHPEAUHWND__@@H@Z @341 NONAME
?Srmm_DownloadOfflineFile@@YAXI_N@Z @342 NONAME
-?Srmm_GetOfflineFileName@@YA?AV?$CMStringT@_WV?$ChTraitsCRT@_W@@@@I@Z @343 NONAME
Miranda_OkToExit @344
Miranda_GetVersion @345
Miranda_GetFileVersion @346
@@ -879,3 +878,6 @@ Clist_RemoveEvent @989
??0OFDTHREAD@@QEAA@IAEBV?$CMStringT@_WV?$ChTraitsCRT@_W@@@@_N@Z @995 NONAME
??1OFDTHREAD@@QEAA@XZ @996 NONAME
?Finish@OFDTHREAD@@QEAAXXZ @997 NONAME
+?getLocalName@FILE_BLOB@DB@@QEBAPEB_WXZ @998 NONAME
+?setLocalName@FILE_BLOB@DB@@QEAAXPEB_W@Z @999 NONAME
+?ResetFileName@OFDTHREAD@@QEAAXPEB_W@Z @1000 NONAME
diff --git a/src/mir_app/src/proto_internal.cpp b/src/mir_app/src/proto_internal.cpp
index 5e2b4c6d02..85ee586a92 100644
--- a/src/mir_app/src/proto_internal.cpp
+++ b/src/mir_app/src/proto_internal.cpp
@@ -23,27 +23,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "stdafx.h"
+#include "file.h"
char** __fastcall Proto_FilesMatrixA(wchar_t **files);
-static void FreeFilesMatrix(wchar_t ***files)
-{
- if (*files == nullptr)
- return;
-
- // Free each filename in the pointer array
- wchar_t **pFile = *files;
- while (*pFile != nullptr) {
- mir_free(*pFile);
- *pFile = nullptr;
- pFile++;
- }
-
- // Free the array itself
- mir_free(*files);
- *files = nullptr;
-}
-
struct DEFAULT_PROTO_INTERFACE : public PROTO_INTERFACE
{
typedef PROTO_INTERFACE CSuper;
diff --git a/src/mir_app/src/srmm_util.cpp b/src/mir_app/src/srmm_util.cpp
index 24f1ff1674..bd2897bef1 100644
--- a/src/mir_app/src/srmm_util.cpp
+++ b/src/mir_app/src/srmm_util.cpp
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "stdafx.h"
#include "chat.h"
+#include "file.h"
const char *g_pszHotkeySection;
@@ -115,10 +116,20 @@ OFDTHREAD::OFDTHREAD(MEVENT _1, const CMStringW &_2, bool _3) :
void OFDTHREAD::Finish()
{
+ DBVARIANT dbv = { DBVT_WCHAR };
+ dbv.pwszVal = wszPath.GetBuffer();
+ db_event_setJson(hDbEvent, "lf", &dbv);
+
if (bOpen)
ShellExecuteW(nullptr, L"open", wszPath, nullptr, nullptr, SW_SHOWDEFAULT);
}
+void OFDTHREAD::ResetFileName(const wchar_t *pwszNewName)
+{
+ if (mir_wstrlen(pwszNewName))
+ wszPath = FindUniqueFileName(pwszNewName);
+}
+
MIR_APP_DLL(void) Srmm_DownloadOfflineFile(MEVENT hDbEvent, bool bOpen)
{
DB::EventInfo dbei(hDbEvent);
@@ -129,26 +140,28 @@ MIR_APP_DLL(void) Srmm_DownloadOfflineFile(MEVENT hDbEvent, bool bOpen)
if (!blob.isOffline())
return;
- CMStringW tszFilePath(Srmm_GetOfflineFileName(db_event_getContact(hDbEvent)));
- CreateDirectoryTreeW(tszFilePath);
- tszFilePath.Append(blob.getName());
+ if (!mir_wstrlen(blob.getLocalName())) {
+ wchar_t wszReceiveFolder[MAX_PATH];
+ GetContactReceivedFilesDir(db_event_getContact(hDbEvent), wszReceiveFolder, _countof(wszReceiveFolder), true);
+ CreateDirectoryTreeW(wszReceiveFolder);
+
+ MFilePath wszFullName(wszReceiveFolder);
+ wszFullName.AppendFormat(L"\\%s", blob.getName());
+ blob.setLocalName(FindUniqueFileName(wszFullName));
+ }
struct _stat st = {};
- _wstat(tszFilePath, &st);
+ _wstat(blob.getLocalName(), &st);
if (st.st_size && st.st_size == blob.getSize() && blob.isCompleted()) {
- OFDTHREAD(hDbEvent, tszFilePath, bOpen).Finish();
+ if (bOpen)
+ ShellExecuteW(nullptr, L"open", blob.getLocalName(), nullptr, nullptr, SW_SHOWDEFAULT);
}
else {
- OFDTHREAD *ofd = new OFDTHREAD(hDbEvent, tszFilePath, bOpen);
+ OFDTHREAD *ofd = new OFDTHREAD(hDbEvent, blob.getLocalName(), bOpen);
CallProtoService(dbei.szModule, PS_OFFLINEFILE, (WPARAM)ofd, 0);
}
}
-MIR_APP_DLL(CMStringW) Srmm_GetOfflineFileName(MCONTACT hContact)
-{
- return CMStringW(FORMAT, VARSW(L"%miranda_userdata%\\dlFiles\\%u\\"), hContact);
-}
-
/////////////////////////////////////////////////////////////////////////////////////////
// serializes all thread-unsafe operation to the first thread