diff options
-rw-r--r-- | include/m_database.h | 4 | ||||
-rw-r--r-- | include/m_protosvc.h | 1 | ||||
-rw-r--r-- | include/m_srmm_int.h | 5 | ||||
-rw-r--r-- | libs/win32/mir_app.lib | bin | 262924 -> 263386 bytes | |||
-rw-r--r-- | libs/win64/mir_app.lib | bin | 261946 -> 262438 bytes | |||
-rw-r--r-- | plugins/Dbx_sqlite/src/dbevents.cpp | 20 | ||||
-rw-r--r-- | plugins/NewStory/src/history_array.cpp | 4 | ||||
-rw-r--r-- | protocols/Telegram/src/avatars.cpp | 5 | ||||
-rw-r--r-- | src/mir_app/src/chat_svc.cpp | 4 | ||||
-rw-r--r-- | src/mir_app/src/db_events.cpp | 6 | ||||
-rw-r--r-- | src/mir_app/src/file.cpp | 166 | ||||
-rw-r--r-- | src/mir_app/src/file.h | 30 | ||||
-rw-r--r-- | src/mir_app/src/fileexistsdlg.cpp | 8 | ||||
-rw-r--r-- | src/mir_app/src/fileopts.cpp | 4 | ||||
-rw-r--r-- | src/mir_app/src/fileutils.cpp | 181 | ||||
-rw-r--r-- | src/mir_app/src/filexferdlg.cpp | 2 | ||||
-rw-r--r-- | src/mir_app/src/mir_app.def | 4 | ||||
-rw-r--r-- | src/mir_app/src/mir_app64.def | 4 | ||||
-rw-r--r-- | src/mir_app/src/proto_internal.cpp | 19 | ||||
-rw-r--r-- | src/mir_app/src/srmm_util.cpp | 35 |
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 Binary files differindex 280e32a771..77490f8a8c 100644 --- a/libs/win32/mir_app.lib +++ b/libs/win32/mir_app.lib diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib Binary files differindex dddba5a8a5..3e9b392024 100644 --- a/libs/win64/mir_app.lib +++ b/libs/win64/mir_app.lib 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
|