From d7730685516d6ed6fc278a6ea74f7a5cf12e0042 Mon Sep 17 00:00:00 2001 From: Gluzskiy Alexandr Date: Mon, 5 Apr 2010 19:30:17 +0300 Subject: dos2unix --- path.c | 1080 ++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 540 insertions(+), 540 deletions(-) (limited to 'path.c') diff --git a/path.c b/path.c index b829c68..325a78a 100644 --- a/path.c +++ b/path.c @@ -1,541 +1,541 @@ -/* - -"Spam Filter"-Plugin for Miranda IM - -Copyright 2003-2006 Heiko Herkenrath - -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; either version 2 -of the License, or (at your option) any later version. - -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 ("SpamFilter-License.txt"); if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - - -// -- Includes -#include "common.h" - - -// ----------------------------------------- - - -BOOL PPreparePathForWrite(HWND hwndDlg, const WCHAR* pszPath, BOOL bAskDirCreate, BOOL bContainsFileName) -{ - // Using SHPathPrepareForWrite on Win2000+ (best, only if avail) - { - HRESULT (STDAPICALLTYPE *MySHPathPrepareForWrite)(HWND, IUnknown*, LPCTSTR, DWORD); - - #if defined(UNICODE) - *(FARPROC*)&MySHPathPrepareForWrite = GetProcAddress(GetModuleHandle(_T("USER32")), "SHPathPrepareForWriteW"); - #else - *(FARPROC*)&MySHPathPrepareForWrite = GetProcAddress(GetModuleHandle(_T("USER32")), "SHPathPrepareForWriteA"); - #endif - - if (MySHPathPrepareForWrite) - { - DWORD dwFlags = SHPPFW_NOWRITECHECK; // Not impl anyway - - if (bContainsFileName) - dwFlags |= SHPPFW_IGNOREFILENAME; - - dwFlags |= bAskDirCreate ? SHPPFW_ASKDIRCREATE : SHPPFW_DIRCREATE; - - return SUCCEEDED(MySHPathPrepareForWrite(hwndDlg, NULL, (LPCTSTR)pszPath, dwFlags)); - } - } - - // Emulating SHPathPrepareForWrite: - // Using SHCreateDirectoryEx on WinME - // And: Using emulated version of SHCreateDirectoryEx on Win95/98 - { - WCHAR* pszDir; - BOOL bReturn = FALSE; - - pszDir = mir_wstrdup(pszPath); - if (!pszDir) return FALSE; - - if (bContainsFileName) - PathRemoveFileSpec((LPWSTR)pszDir); - - // No dialog is emulated, instead always behave as - // if "No" was clicked - if (bAskDirCreate) - return FALSE; - - // Create all sub directories - { - int (STDAPICALLTYPE *MySHCreateDirectoryEx)(HWND, LPCTSTR, SECURITY_ATTRIBUTES*); - - #if defined(UNICODE) - *(FARPROC*)&MySHCreateDirectoryEx = (FARPROC)GetProcAddress(GetModuleHandle(_T("SHELL32")), "SHCreateDirectoryExW"); - #else - *(FARPROC*)&MySHCreateDirectoryEx = (FARPROC)GetProcAddress(GetModuleHandle(_T("SHELL32")), "SHCreateDirectoryExA"); - #endif - - if (MySHCreateDirectoryEx) - { - int iRet = (SHCreateDirectoryEx(hwndDlg, pszDir, NULL) == ERROR_SUCCESS); - bReturn = ((iRet == ERROR_SUCCESS) || (iRet == ERROR_ALREADY_EXISTS)); - - } else { - - int iSlashOcc; - int iAbsSlashOcc; - WCHAR* pszSlash; - WCHAR szDirTemp[MAX_PATH]; - WCHAR szDirOutput[MAX_PATH]; - - ZeroMemory(&szDirTemp, sizeof(szDirTemp)); - ZeroMemory(&szDirOutput, sizeof(szDirOutput)); - - // Skip drive letter - pszSlash = StrChr(pszDir, _T('\\')); // Search for the first :'\\' - - if (pszSlash != NULL) // does not contain any slashs - { - iSlashOcc = (int)(pszSlash-pszDir+1); // Pointer arithmetic - StrCpyN(szDirTemp, pszDir+iSlashOcc, lstrlen(pszDir)-iSlashOcc); // Pointer arithmetic - iAbsSlashOcc = iSlashOcc; - - bReturn = TRUE; - pszSlash = szDirTemp; - while (pszSlash) - { - pszSlash = StrChr(szDirTemp, _T('\\')); - - iSlashOcc = (int)(pszSlash-szDirTemp+1); // Pointer arithmetic - iAbsSlashOcc = iAbsSlashOcc + iSlashOcc; - - StrCpyN(szDirOutput, pszPath, iAbsSlashOcc); // Pointer arithmetic - - StrCpyN(szDirTemp, szDirTemp+iSlashOcc, lstrlen(szDirTemp)-iSlashOcc); // Pointer arithmetic - ZeroMemory((PBYTE)szDirTemp+((lstrlen(szDirTemp)-iSlashOcc)*sizeof(WCHAR)), iSlashOcc*sizeof(WCHAR)); - - bReturn = (CreateDirectory(szDirOutput, NULL) && bReturn); - } - } - } - } - - mir_free(pszDir); - return bReturn; - } -} - - -BOOL PIsValidFile(const WCHAR* pszFileName, const WCHAR* aszFileExtensions[], int nFileExtensions, const WCHAR* aszContentTypes[], int nContentTypes) -{ - BOOL bIsOk = FALSE; - int i; - - if (!pszFileName) return FALSE; - - // Check file extensions - for (i=0; i=0; i--) - if (PathGetCharType(pszPath[i])&GCT_WILD) - RemoveSubStr(pszPath, i, 1); - - // Remove disallowed TCHARs - for (i=lstrlen(pszPath); i>=0; i--) - if (PathGetCharType(pszPath[i])&GCT_INVALID) - RemoveSubStr(pszPath, i, 1); - } - */ - - PathRemoveBlanks(pszPath); - PathUnquoteSpaces(pszPath); - - // Upper case drive TCHAR - if (PathGetDriveNumber(pszPath) != -1) - CharUpperBuff(pszPath, 1); - - // Make it use the long path name (Win98+/Win2000+) - { - DWORD (WINAPI *MyGetLongPathName)(LPCTSTR, LPCTSTR, DWORD); - - #if defined(UNICODE) - *(FARPROC*)&MyGetLongPathName = GetProcAddress(GetModuleHandle(_T("KERNEL32")), "GetLongPathNameW"); - #else - *(FARPROC*)&MyGetLongPathName = GetProcAddress(GetModuleHandle(_T("KERNEL32")), "GetLongPathNameA"); - #endif - - if (MyGetLongPathName) - { - if (MyGetLongPathName(pszPath, pszPath, MAX_PATH) == 0) - { - // Try to remove file name and see if it works then - mir_sntprintf(szBuf, ARRAYSIZE(szBuf), _T("%s"), pszPath); - - if (PathRemoveFileSpec(szBuf) && (MyGetLongPathName(szBuf, szBuf, ARRAYSIZE(szBuf)) != 0)) - { - PathAppend(szBuf, PathFindFileName(pszPath)); - mir_sntprintf(pszPath, MAX_PATH, _T("%s"), szBuf); - } - } - } - } - - // Lower case path if all upper case (only if user activated this feature for Windows-Explorer) - { - SHELLFLAGSTATE sfs; - SHGetSettings(&sfs, SSF_DONTPRETTYPATH); - - if (!sfs.fDontPrettyPath) - PathMakePretty(pszPath); - } - } - - // Make relative - if (dwFlags&PC_ABSOLUTERELATIVE) - { - if (PathRelativePathTo(szBuf, szRelativeTo, FILE_ATTRIBUTE_DIRECTORY, pszPath, FILE_ATTRIBUTE_NORMAL)) - { - mir_sntprintf(pszPath, MAX_PATH, _T("%s"), szBuf); - - // Remove backslash in front -> does not belong there (causes by PathRelativePathTo) - if ((pszPath[0] == _T('\\')) || (pszPath[0] == _T('/'))) - MoveMemory(pszPath, CharNext(pszPath), (lstrlen(CharNext(pszPath))+1)*sizeof(WCHAR)); - } - - // Miranda Utils contains a quite less featured implementation of relative paths - // (not all cases are captured, does not support Unicode, too) - //if (CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)pszPath, (LPARAM)szBuf) == 0) - // mir_sntprintf(pszPath, MAX_PATH, _T("%s"), szBuf); - } - - // Environment strings - if (dwFlags&PC_ENVIRONMENTSTRINGS) - { - BOOL (STDAPICALLTYPE *MyPathUnExpandEnvStrings)(LPCTSTR, LPTSTR, UINT); - - // PathUnExpandEnvStrings is Win98/2000+ - #if defined(UNICODE) - *(FARPROC*)&MyPathUnExpandEnvStrings = (FARPROC)GetProcAddress(GetModuleHandle(_T("SHLWAPI")), "PathUnExpandEnvStringsW"); - #else - *(FARPROC*)&MyPathUnExpandEnvStrings = (FARPROC)GetProcAddress(GetModuleHandle(_T("SHLWAPI")), "PathUnExpandEnvStringsA"); - #endif - - if (MyPathUnExpandEnvStrings) - if (MyPathUnExpandEnvStrings(pszPath, szBuf, MAX_PATH)) - mir_sntprintf(pszPath, MAX_PATH, _T("%s"), szBuf); - } -} - - -DWORD PMakePathUsable(WCHAR* pszPath) -{ - WCHAR szBuf[MAX_PATH]; - DWORD dwFlags = 0; - - if (!pszPath) - return dwFlags; - - PathUnquoteSpaces(pszPath); - - // Environment strings - { - if (ExpandEnvironmentStrings(pszPath, szBuf, ARRAYSIZE(szBuf)) != 0) - { - // Success? - if (StrCmp(pszPath, szBuf) != 0) - dwFlags |= PC_ENVIRONMENTSTRINGS; - - mir_sntprintf(pszPath, MAX_PATH, _T("%s"), szBuf); - } - } - - // Absolute/relative path - { - WCHAR szRelativeTo[MAX_PATH]; - PConstructLocalPath(szRelativeTo, CSIDL_EXT_EXECUTABLE, NULL, NULL, NULL); - - // Miranda Utils contains not a very good implementation of relative paths - // (not all cases are captured) - //(CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)szBuf, (LPARAM)pszPath) != lstrlenA(szBuf)) - - // Create absolute path if path is relative - if (PathIsRelative(pszPath)) - { - if (PathCombine(szBuf, szRelativeTo, pszPath)) - { - dwFlags |= PC_ABSOLUTERELATIVE; - mir_sntprintf(pszPath, MAX_PATH, _T("%s"), szBuf); - } - } - } - - return dwFlags; -} - - - -BOOL PConstructLocalPath(WCHAR* pszReturn, int nMainFolder, const WCHAR* pszSubFolders, const WCHAR* pszFileName, const WCHAR* pszOptFileExtension) -{ - // pszReturn muss MAX_PATH groß sein - if (!pszReturn) return FALSE; - - pszReturn[0] = _T('\0'); - - switch (nMainFolder) - { - case CSIDL_EXT_MIRANDAPROFILE: - { - // Profile directory of Miranda's database - WCHAR szBuf[MAX_PATH]; - - if (CallService(MS_DB_GETPROFILEPATH, (WPARAM)ARRAYSIZE(szBuf), (LPARAM)szBuf) != 0) - return FALSE; - - #if defined(UNICODE) - { - WCHAR* pszBuf = (WCHAR*)mir_utf8encodeW(szBuf); - if (!pszBuf) return FALSE; - - mir_sntprintf(pszReturn, MAX_PATH, _T("%s"), pszBuf); - mir_free(pszBuf); - } - #else - mir_sntprintf(pszReturn, MAX_PATH, _T("%s"), szBuf); - #endif - - break; - } - - case CSIDL_EXT_MODULE: - { - // Current DLL's directory - if (GetModuleFileName(hInstance, pszReturn, MAX_PATH) == 0) - return FALSE; - - PathRemoveFileSpec(pszReturn); - break; - } - - case CSIDL_EXT_EXECUTABLE: - { - // Current executable path - if (GetModuleFileName(NULL, pszReturn, MAX_PATH) == 0) - return FALSE; - - PathRemoveFileSpec(pszReturn); - break; - } - - case CSIDL_EXT_TEMP: - { - // Temp directory - if (GetTempPath(MAX_PATH, pszReturn) == 0) - return FALSE; - break; - } - - case CSIDL_EXT_CURRENT: - { - // Current directory - if (GetCurrentDirectory(MAX_PATH, pszReturn) == 0) - return FALSE; - break; - } - - default: - { - // CSIDL directory - if (!SHGetSpecialFolderPath(NULL, pszReturn, nMainFolder, FALSE)) - return FALSE; - - break; - } - } - - if (!PathAddBackslash(pszReturn)) - return FALSE; - - if (pszSubFolders) - { - if (!PathAppend(pszReturn, pszSubFolders)) - return FALSE; - - if (!PathAddBackslash(pszReturn)) - return FALSE; - } - - if (pszFileName) - if (!PathAppend(pszReturn, pszFileName)) - return FALSE; - - if (pszFileName && pszOptFileExtension) - if (!PathAddExtension(pszReturn, pszOptFileExtension)) - return FALSE; - - return TRUE; -} - -// Move files or whole folder from module to destination directory -BOOL PInstallFile(const WCHAR* pszFileName, const WCHAR* pszDestDir) -{ - BOOL bReturn; - WCHAR szFileFrom[MAX_PATH+1]; - WCHAR szFileTo[MAX_PATH+1]; - - if (!pszFileName) return FALSE; - PConstructLocalPath(szFileFrom, CSIDL_EXT_MODULE, NULL, pszFileName, NULL); - if (!PathFileExists(szFileFrom)) return FALSE; - mir_sntprintf(szFileTo, ARRAYSIZE(szFileTo), _T("%s"), pszDestDir); - - if (PathIsDirectory(szFileFrom)) - { - SHFILEOPSTRUCT sfo; - - ZeroMemory(&sfo, sizeof(sfo)); - sfo.fFlags = FOF_MULTIDESTFILES|FOF_NOERRORUI|FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_SILENT; - sfo.wFunc = FO_MOVE; - szFileFrom[lstrlen(szFileFrom)+1] = _T('\0'); - sfo.pFrom = szFileFrom; - szFileTo[lstrlen(szFileTo)+1] = _T('\0'); - sfo.pTo = szFileTo; - bReturn = (SHFileOperation(&sfo) == 0); - - } else { - PathAppend(szFileTo, pszFileName); - - DeleteFile(szFileTo); - bReturn = MoveFile(szFileFrom, szFileTo); // MoveFile does only support directories limitedly - } - - return bReturn; -} - -BOOL PInstallDLLFile(const WCHAR* pszFileName, BOOL bIgnoreLanguage, BOOL bIgnoreOpSystem) -{ - DWORD dwErr; - WCHAR szSrcDir[MAX_PATH]; - WCHAR szDestDir[MAX_PATH]; - WCHAR szTmpFile[MAX_PATH]; - UINT uTmpFileSize = ARRAYSIZE(szTmpFile); - - if (!pszFileName) return FALSE; - - // Test if file-to-be-installed exists - PConstructLocalPath(szSrcDir, CSIDL_EXT_MODULE, NULL, pszFileName, NULL); - if (!PathFileExists(szSrcDir)) return FALSE; - - // Source: module dir (Plugins directory) - PConstructLocalPath(szSrcDir, CSIDL_EXT_MODULE, NULL, NULL, NULL); - - // Destination: app dir - PConstructLocalPath(szDestDir, CSIDL_EXT_EXECUTABLE, NULL, NULL, NULL); - - // Install DLL using version verfication - szTmpFile[0] = _T('\0'); // needs to be empty (docs) - dwErr = VerInstallFile(0, (WCHAR*)pszFileName, (WCHAR*)pszFileName, szSrcDir, szDestDir, szDestDir, szTmpFile, &uTmpFileSize); - if (!(dwErr&VIF_WRITEPROT) && !(dwErr&VIF_SRCOLD)) - { - // Ignore language/codepage of the DLL (install anyway) -> useful for DLLs without user interface - if (bIgnoreLanguage) - if ((dwErr&VIF_DIFFLANG) && (dwErr&VIF_DIFFCODEPG)) - dwErr = VerInstallFile(VIFF_FORCEINSTALL, (WCHAR*)pszFileName, (WCHAR*)pszFileName, szSrcDir, szDestDir, szDestDir, szTmpFile, &uTmpFileSize); - - // Ignore operating system of the DLL (install anyway) -> useful for DLLs that work anyway - if (bIgnoreOpSystem) - if (dwErr&VIF_DIFFTYPE) - dwErr = VerInstallFile(VIFF_FORCEINSTALL, (WCHAR*)pszFileName, (WCHAR*)pszFileName, szSrcDir, szDestDir, szDestDir, szTmpFile, &uTmpFileSize); - } - - // Delete temp file - if ((dwErr&VIF_TEMPFILE) && !(dwErr&VIF_BUFFTOOSMALL)) // buffer too small for temp file - DeleteFile(szTmpFile); - - // Test for success - PConstructLocalPath(szDestDir, CSIDL_EXT_EXECUTABLE, NULL, pszFileName, NULL); - if (PathFileExists(szDestDir)) - { - PConstructLocalPath(szSrcDir, CSIDL_EXT_MODULE, NULL, pszFileName, NULL); - DeleteFile(szSrcDir); - return TRUE; - } - - // Debug output - OutputDebugString(_T("Spam Filter: VersionInfo DLL (VERSION.DLL) could not be used to install DLL file.\r\n")); - - // Source: module dir (Plugins directory) - PConstructLocalPath(szSrcDir, CSIDL_EXT_MODULE, NULL, pszFileName, NULL); - // Destination: app dir - PConstructLocalPath(szDestDir, CSIDL_EXT_EXECUTABLE, NULL, pszFileName, NULL); - - // Copy without version checking [danger!] - DeleteFile(szDestDir); - return MoveFile(szSrcDir, szDestDir); +/* + +"Spam Filter"-Plugin for Miranda IM + +Copyright 2003-2006 Heiko Herkenrath + +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; either version 2 +of the License, or (at your option) any later version. + +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 ("SpamFilter-License.txt"); if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + + +// -- Includes +#include "common.h" + + +// ----------------------------------------- + + +BOOL PPreparePathForWrite(HWND hwndDlg, const WCHAR* pszPath, BOOL bAskDirCreate, BOOL bContainsFileName) +{ + // Using SHPathPrepareForWrite on Win2000+ (best, only if avail) + { + HRESULT (STDAPICALLTYPE *MySHPathPrepareForWrite)(HWND, IUnknown*, LPCTSTR, DWORD); + + #if defined(UNICODE) + *(FARPROC*)&MySHPathPrepareForWrite = GetProcAddress(GetModuleHandle(_T("USER32")), "SHPathPrepareForWriteW"); + #else + *(FARPROC*)&MySHPathPrepareForWrite = GetProcAddress(GetModuleHandle(_T("USER32")), "SHPathPrepareForWriteA"); + #endif + + if (MySHPathPrepareForWrite) + { + DWORD dwFlags = SHPPFW_NOWRITECHECK; // Not impl anyway + + if (bContainsFileName) + dwFlags |= SHPPFW_IGNOREFILENAME; + + dwFlags |= bAskDirCreate ? SHPPFW_ASKDIRCREATE : SHPPFW_DIRCREATE; + + return SUCCEEDED(MySHPathPrepareForWrite(hwndDlg, NULL, (LPCTSTR)pszPath, dwFlags)); + } + } + + // Emulating SHPathPrepareForWrite: + // Using SHCreateDirectoryEx on WinME + // And: Using emulated version of SHCreateDirectoryEx on Win95/98 + { + WCHAR* pszDir; + BOOL bReturn = FALSE; + + pszDir = mir_wstrdup(pszPath); + if (!pszDir) return FALSE; + + if (bContainsFileName) + PathRemoveFileSpec((LPWSTR)pszDir); + + // No dialog is emulated, instead always behave as + // if "No" was clicked + if (bAskDirCreate) + return FALSE; + + // Create all sub directories + { + int (STDAPICALLTYPE *MySHCreateDirectoryEx)(HWND, LPCTSTR, SECURITY_ATTRIBUTES*); + + #if defined(UNICODE) + *(FARPROC*)&MySHCreateDirectoryEx = (FARPROC)GetProcAddress(GetModuleHandle(_T("SHELL32")), "SHCreateDirectoryExW"); + #else + *(FARPROC*)&MySHCreateDirectoryEx = (FARPROC)GetProcAddress(GetModuleHandle(_T("SHELL32")), "SHCreateDirectoryExA"); + #endif + + if (MySHCreateDirectoryEx) + { + int iRet = (SHCreateDirectoryEx(hwndDlg, pszDir, NULL) == ERROR_SUCCESS); + bReturn = ((iRet == ERROR_SUCCESS) || (iRet == ERROR_ALREADY_EXISTS)); + + } else { + + int iSlashOcc; + int iAbsSlashOcc; + WCHAR* pszSlash; + WCHAR szDirTemp[MAX_PATH]; + WCHAR szDirOutput[MAX_PATH]; + + ZeroMemory(&szDirTemp, sizeof(szDirTemp)); + ZeroMemory(&szDirOutput, sizeof(szDirOutput)); + + // Skip drive letter + pszSlash = StrChr(pszDir, _T('\\')); // Search for the first :'\\' + + if (pszSlash != NULL) // does not contain any slashs + { + iSlashOcc = (int)(pszSlash-pszDir+1); // Pointer arithmetic + StrCpyN(szDirTemp, pszDir+iSlashOcc, lstrlen(pszDir)-iSlashOcc); // Pointer arithmetic + iAbsSlashOcc = iSlashOcc; + + bReturn = TRUE; + pszSlash = szDirTemp; + while (pszSlash) + { + pszSlash = StrChr(szDirTemp, _T('\\')); + + iSlashOcc = (int)(pszSlash-szDirTemp+1); // Pointer arithmetic + iAbsSlashOcc = iAbsSlashOcc + iSlashOcc; + + StrCpyN(szDirOutput, pszPath, iAbsSlashOcc); // Pointer arithmetic + + StrCpyN(szDirTemp, szDirTemp+iSlashOcc, lstrlen(szDirTemp)-iSlashOcc); // Pointer arithmetic + ZeroMemory((PBYTE)szDirTemp+((lstrlen(szDirTemp)-iSlashOcc)*sizeof(WCHAR)), iSlashOcc*sizeof(WCHAR)); + + bReturn = (CreateDirectory(szDirOutput, NULL) && bReturn); + } + } + } + } + + mir_free(pszDir); + return bReturn; + } +} + + +BOOL PIsValidFile(const WCHAR* pszFileName, const WCHAR* aszFileExtensions[], int nFileExtensions, const WCHAR* aszContentTypes[], int nContentTypes) +{ + BOOL bIsOk = FALSE; + int i; + + if (!pszFileName) return FALSE; + + // Check file extensions + for (i=0; i=0; i--) + if (PathGetCharType(pszPath[i])&GCT_WILD) + RemoveSubStr(pszPath, i, 1); + + // Remove disallowed TCHARs + for (i=lstrlen(pszPath); i>=0; i--) + if (PathGetCharType(pszPath[i])&GCT_INVALID) + RemoveSubStr(pszPath, i, 1); + } + */ + + PathRemoveBlanks(pszPath); + PathUnquoteSpaces(pszPath); + + // Upper case drive TCHAR + if (PathGetDriveNumber(pszPath) != -1) + CharUpperBuff(pszPath, 1); + + // Make it use the long path name (Win98+/Win2000+) + { + DWORD (WINAPI *MyGetLongPathName)(LPCTSTR, LPCTSTR, DWORD); + + #if defined(UNICODE) + *(FARPROC*)&MyGetLongPathName = GetProcAddress(GetModuleHandle(_T("KERNEL32")), "GetLongPathNameW"); + #else + *(FARPROC*)&MyGetLongPathName = GetProcAddress(GetModuleHandle(_T("KERNEL32")), "GetLongPathNameA"); + #endif + + if (MyGetLongPathName) + { + if (MyGetLongPathName(pszPath, pszPath, MAX_PATH) == 0) + { + // Try to remove file name and see if it works then + mir_sntprintf(szBuf, ARRAYSIZE(szBuf), _T("%s"), pszPath); + + if (PathRemoveFileSpec(szBuf) && (MyGetLongPathName(szBuf, szBuf, ARRAYSIZE(szBuf)) != 0)) + { + PathAppend(szBuf, PathFindFileName(pszPath)); + mir_sntprintf(pszPath, MAX_PATH, _T("%s"), szBuf); + } + } + } + } + + // Lower case path if all upper case (only if user activated this feature for Windows-Explorer) + { + SHELLFLAGSTATE sfs; + SHGetSettings(&sfs, SSF_DONTPRETTYPATH); + + if (!sfs.fDontPrettyPath) + PathMakePretty(pszPath); + } + } + + // Make relative + if (dwFlags&PC_ABSOLUTERELATIVE) + { + if (PathRelativePathTo(szBuf, szRelativeTo, FILE_ATTRIBUTE_DIRECTORY, pszPath, FILE_ATTRIBUTE_NORMAL)) + { + mir_sntprintf(pszPath, MAX_PATH, _T("%s"), szBuf); + + // Remove backslash in front -> does not belong there (causes by PathRelativePathTo) + if ((pszPath[0] == _T('\\')) || (pszPath[0] == _T('/'))) + MoveMemory(pszPath, CharNext(pszPath), (lstrlen(CharNext(pszPath))+1)*sizeof(WCHAR)); + } + + // Miranda Utils contains a quite less featured implementation of relative paths + // (not all cases are captured, does not support Unicode, too) + //if (CallService(MS_UTILS_PATHTORELATIVE, (WPARAM)pszPath, (LPARAM)szBuf) == 0) + // mir_sntprintf(pszPath, MAX_PATH, _T("%s"), szBuf); + } + + // Environment strings + if (dwFlags&PC_ENVIRONMENTSTRINGS) + { + BOOL (STDAPICALLTYPE *MyPathUnExpandEnvStrings)(LPCTSTR, LPTSTR, UINT); + + // PathUnExpandEnvStrings is Win98/2000+ + #if defined(UNICODE) + *(FARPROC*)&MyPathUnExpandEnvStrings = (FARPROC)GetProcAddress(GetModuleHandle(_T("SHLWAPI")), "PathUnExpandEnvStringsW"); + #else + *(FARPROC*)&MyPathUnExpandEnvStrings = (FARPROC)GetProcAddress(GetModuleHandle(_T("SHLWAPI")), "PathUnExpandEnvStringsA"); + #endif + + if (MyPathUnExpandEnvStrings) + if (MyPathUnExpandEnvStrings(pszPath, szBuf, MAX_PATH)) + mir_sntprintf(pszPath, MAX_PATH, _T("%s"), szBuf); + } +} + + +DWORD PMakePathUsable(WCHAR* pszPath) +{ + WCHAR szBuf[MAX_PATH]; + DWORD dwFlags = 0; + + if (!pszPath) + return dwFlags; + + PathUnquoteSpaces(pszPath); + + // Environment strings + { + if (ExpandEnvironmentStrings(pszPath, szBuf, ARRAYSIZE(szBuf)) != 0) + { + // Success? + if (StrCmp(pszPath, szBuf) != 0) + dwFlags |= PC_ENVIRONMENTSTRINGS; + + mir_sntprintf(pszPath, MAX_PATH, _T("%s"), szBuf); + } + } + + // Absolute/relative path + { + WCHAR szRelativeTo[MAX_PATH]; + PConstructLocalPath(szRelativeTo, CSIDL_EXT_EXECUTABLE, NULL, NULL, NULL); + + // Miranda Utils contains not a very good implementation of relative paths + // (not all cases are captured) + //(CallService(MS_UTILS_PATHTOABSOLUTE, (WPARAM)szBuf, (LPARAM)pszPath) != lstrlenA(szBuf)) + + // Create absolute path if path is relative + if (PathIsRelative(pszPath)) + { + if (PathCombine(szBuf, szRelativeTo, pszPath)) + { + dwFlags |= PC_ABSOLUTERELATIVE; + mir_sntprintf(pszPath, MAX_PATH, _T("%s"), szBuf); + } + } + } + + return dwFlags; +} + + + +BOOL PConstructLocalPath(WCHAR* pszReturn, int nMainFolder, const WCHAR* pszSubFolders, const WCHAR* pszFileName, const WCHAR* pszOptFileExtension) +{ + // pszReturn muss MAX_PATH groß sein + if (!pszReturn) return FALSE; + + pszReturn[0] = _T('\0'); + + switch (nMainFolder) + { + case CSIDL_EXT_MIRANDAPROFILE: + { + // Profile directory of Miranda's database + WCHAR szBuf[MAX_PATH]; + + if (CallService(MS_DB_GETPROFILEPATH, (WPARAM)ARRAYSIZE(szBuf), (LPARAM)szBuf) != 0) + return FALSE; + + #if defined(UNICODE) + { + WCHAR* pszBuf = (WCHAR*)mir_utf8encodeW(szBuf); + if (!pszBuf) return FALSE; + + mir_sntprintf(pszReturn, MAX_PATH, _T("%s"), pszBuf); + mir_free(pszBuf); + } + #else + mir_sntprintf(pszReturn, MAX_PATH, _T("%s"), szBuf); + #endif + + break; + } + + case CSIDL_EXT_MODULE: + { + // Current DLL's directory + if (GetModuleFileName(hInstance, pszReturn, MAX_PATH) == 0) + return FALSE; + + PathRemoveFileSpec(pszReturn); + break; + } + + case CSIDL_EXT_EXECUTABLE: + { + // Current executable path + if (GetModuleFileName(NULL, pszReturn, MAX_PATH) == 0) + return FALSE; + + PathRemoveFileSpec(pszReturn); + break; + } + + case CSIDL_EXT_TEMP: + { + // Temp directory + if (GetTempPath(MAX_PATH, pszReturn) == 0) + return FALSE; + break; + } + + case CSIDL_EXT_CURRENT: + { + // Current directory + if (GetCurrentDirectory(MAX_PATH, pszReturn) == 0) + return FALSE; + break; + } + + default: + { + // CSIDL directory + if (!SHGetSpecialFolderPath(NULL, pszReturn, nMainFolder, FALSE)) + return FALSE; + + break; + } + } + + if (!PathAddBackslash(pszReturn)) + return FALSE; + + if (pszSubFolders) + { + if (!PathAppend(pszReturn, pszSubFolders)) + return FALSE; + + if (!PathAddBackslash(pszReturn)) + return FALSE; + } + + if (pszFileName) + if (!PathAppend(pszReturn, pszFileName)) + return FALSE; + + if (pszFileName && pszOptFileExtension) + if (!PathAddExtension(pszReturn, pszOptFileExtension)) + return FALSE; + + return TRUE; +} + +// Move files or whole folder from module to destination directory +BOOL PInstallFile(const WCHAR* pszFileName, const WCHAR* pszDestDir) +{ + BOOL bReturn; + WCHAR szFileFrom[MAX_PATH+1]; + WCHAR szFileTo[MAX_PATH+1]; + + if (!pszFileName) return FALSE; + PConstructLocalPath(szFileFrom, CSIDL_EXT_MODULE, NULL, pszFileName, NULL); + if (!PathFileExists(szFileFrom)) return FALSE; + mir_sntprintf(szFileTo, ARRAYSIZE(szFileTo), _T("%s"), pszDestDir); + + if (PathIsDirectory(szFileFrom)) + { + SHFILEOPSTRUCT sfo; + + ZeroMemory(&sfo, sizeof(sfo)); + sfo.fFlags = FOF_MULTIDESTFILES|FOF_NOERRORUI|FOF_NOCONFIRMATION|FOF_NOCONFIRMMKDIR|FOF_SILENT; + sfo.wFunc = FO_MOVE; + szFileFrom[lstrlen(szFileFrom)+1] = _T('\0'); + sfo.pFrom = szFileFrom; + szFileTo[lstrlen(szFileTo)+1] = _T('\0'); + sfo.pTo = szFileTo; + bReturn = (SHFileOperation(&sfo) == 0); + + } else { + PathAppend(szFileTo, pszFileName); + + DeleteFile(szFileTo); + bReturn = MoveFile(szFileFrom, szFileTo); // MoveFile does only support directories limitedly + } + + return bReturn; +} + +BOOL PInstallDLLFile(const WCHAR* pszFileName, BOOL bIgnoreLanguage, BOOL bIgnoreOpSystem) +{ + DWORD dwErr; + WCHAR szSrcDir[MAX_PATH]; + WCHAR szDestDir[MAX_PATH]; + WCHAR szTmpFile[MAX_PATH]; + UINT uTmpFileSize = ARRAYSIZE(szTmpFile); + + if (!pszFileName) return FALSE; + + // Test if file-to-be-installed exists + PConstructLocalPath(szSrcDir, CSIDL_EXT_MODULE, NULL, pszFileName, NULL); + if (!PathFileExists(szSrcDir)) return FALSE; + + // Source: module dir (Plugins directory) + PConstructLocalPath(szSrcDir, CSIDL_EXT_MODULE, NULL, NULL, NULL); + + // Destination: app dir + PConstructLocalPath(szDestDir, CSIDL_EXT_EXECUTABLE, NULL, NULL, NULL); + + // Install DLL using version verfication + szTmpFile[0] = _T('\0'); // needs to be empty (docs) + dwErr = VerInstallFile(0, (WCHAR*)pszFileName, (WCHAR*)pszFileName, szSrcDir, szDestDir, szDestDir, szTmpFile, &uTmpFileSize); + if (!(dwErr&VIF_WRITEPROT) && !(dwErr&VIF_SRCOLD)) + { + // Ignore language/codepage of the DLL (install anyway) -> useful for DLLs without user interface + if (bIgnoreLanguage) + if ((dwErr&VIF_DIFFLANG) && (dwErr&VIF_DIFFCODEPG)) + dwErr = VerInstallFile(VIFF_FORCEINSTALL, (WCHAR*)pszFileName, (WCHAR*)pszFileName, szSrcDir, szDestDir, szDestDir, szTmpFile, &uTmpFileSize); + + // Ignore operating system of the DLL (install anyway) -> useful for DLLs that work anyway + if (bIgnoreOpSystem) + if (dwErr&VIF_DIFFTYPE) + dwErr = VerInstallFile(VIFF_FORCEINSTALL, (WCHAR*)pszFileName, (WCHAR*)pszFileName, szSrcDir, szDestDir, szDestDir, szTmpFile, &uTmpFileSize); + } + + // Delete temp file + if ((dwErr&VIF_TEMPFILE) && !(dwErr&VIF_BUFFTOOSMALL)) // buffer too small for temp file + DeleteFile(szTmpFile); + + // Test for success + PConstructLocalPath(szDestDir, CSIDL_EXT_EXECUTABLE, NULL, pszFileName, NULL); + if (PathFileExists(szDestDir)) + { + PConstructLocalPath(szSrcDir, CSIDL_EXT_MODULE, NULL, pszFileName, NULL); + DeleteFile(szSrcDir); + return TRUE; + } + + // Debug output + OutputDebugString(_T("Spam Filter: VersionInfo DLL (VERSION.DLL) could not be used to install DLL file.\r\n")); + + // Source: module dir (Plugins directory) + PConstructLocalPath(szSrcDir, CSIDL_EXT_MODULE, NULL, pszFileName, NULL); + // Destination: app dir + PConstructLocalPath(szDestDir, CSIDL_EXT_EXECUTABLE, NULL, pszFileName, NULL); + + // Copy without version checking [danger!] + DeleteFile(szDestDir); + return MoveFile(szSrcDir, szDestDir); } \ No newline at end of file -- cgit v1.2.3