Index: src/ch/AppHelper.cpp =================================================================== diff -u -r8dc649003961dad64b92da67426814fb5dd862e0 -rffb46a396ce20cda2e04020cf01c118ae81642b5 --- src/ch/AppHelper.cpp (.../AppHelper.cpp) (revision 8dc649003961dad64b92da67426814fb5dd862e0) +++ src/ch/AppHelper.cpp (.../AppHelper.cpp) (revision ffb46a396ce20cda2e04020cf01c118ae81642b5) @@ -45,192 +45,53 @@ if (m_hMutex) ReleaseMutex(m_hMutex); - delete [] m_pszProgramPath; delete [] m_pszProgramName; } -// inits mutex app protection -void CAppHelper::InitProtection() -{ - m_hMutex=CreateMutex(NULL, TRUE, CH_MUTEX_NAME); - m_bFirstInstance=(m_hMutex != NULL && GetLastError() != ERROR_ALREADY_EXISTS); -} - -// retrieves application path void CAppHelper::RetrievePaths() { // try to find '\\' in path to see if this is only exe name or fully qualified path -#ifdef _UNICODE - TCHAR* pszArgv = __wargv[0]; -#else - TCHAR* pszArgv = __argv[0]; -#endif + TCHAR* pszArgv = __wargv[ 0 ]; - TCHAR* pszName=_tcsrchr(pszArgv, _T('\\')); - if (pszName != NULL) + TCHAR* pszName = _tcsrchr(pszArgv, _T('\\')); + if(pszName != NULL) { // copy name - m_pszProgramName=new TCHAR[_tcslen(pszName+1)+1]; - _tcscpy(m_pszProgramName, pszName+1); - - // path - UINT uiSize=(UINT)(pszName-pszArgv); - m_pszProgramPath=new TCHAR[uiSize+1]; - _tcsncpy(m_pszProgramPath, pszArgv, uiSize); - m_pszProgramPath[uiSize]=_T('\0'); + m_pszProgramName = new TCHAR[ _tcslen(pszName + 1) + 1 ]; + _tcscpy(m_pszProgramName, pszName + 1); } else { // copy name - m_pszProgramName=new TCHAR[_tcslen(pszArgv)+1]; + m_pszProgramName = new TCHAR[ _tcslen(pszArgv) + 1 ]; _tcscpy(m_pszProgramName, pszArgv); - - // path - TCHAR szPath[_MAX_PATH]; - UINT uiSize=GetCurrentDirectory(_MAX_PATH, szPath); - _tcscat(szPath, _T("\\")); - m_pszProgramPath=new TCHAR[uiSize+2]; - _tcsncpy(m_pszProgramPath, szPath, uiSize+2); } } +// inits mutex app protection +void CAppHelper::InitProtection() +{ + m_hMutex=CreateMutex(NULL, TRUE, CH_MUTEX_NAME); + m_bFirstInstance=(m_hMutex != NULL && GetLastError() != ERROR_ALREADY_EXISTS); +} + void CAppHelper::RetrieveAppInfo() { m_pszAppName = _T(PRODUCT_NAME); m_pszAppNameVer = PRODUCT_FULL_VERSION_T; m_pszAppVersion = _T(PRODUCT_VERSION); } -// internal func - safe getting special folder locations -UINT CAppHelper::GetFolderLocation(int iFolder, PTSTR pszBuffer) -{ - LPITEMIDLIST piid; - HRESULT h=SHGetSpecialFolderLocation(NULL, iFolder, &piid); - if (!SUCCEEDED(h)) - return false; - - // get path - BOOL bRes=SHGetPathFromIDList(piid, pszBuffer); - - // free piid - LPMALLOC lpm; - if (!SUCCEEDED(SHGetMalloc(&lpm))) - return 0; - - lpm->Free((void*)piid); - lpm->Release(); - - // check for error - if (!bRes) - return 0; - - // strip the last '\\' - UINT uiLen=(UINT)_tcslen(pszBuffer); - if (pszBuffer[uiLen-1] == _T('\\')) - { - pszBuffer[uiLen-1]=_T('\0'); - return uiLen-1; - } - else - return uiLen; -} - -// expands given path -CString CAppHelper::ExpandPath(CString strPath) -{ - // check if there is need to perform all these checkings - if (strPath[0] != _T('<')) - return strPath; - - TCHAR szStr[ _MAX_PATH ]; - szStr[ 0 ] = _T('\0'); - - // search for string to replace - // _T(""), _T(""), _T(""), _T(""), _T(""), - // _T(""), _T("") - if (_tcsnicmp(strPath, _T(""), 9) == 0) - { - // get windows path - _tcsncpy(szStr, m_pszProgramPath ? m_pszProgramPath : _T(""), _MAX_PATH); - szStr[_MAX_PATH - 1] = _T('\0'); - _tcsncat(szStr, strPath.Mid(9), _MAX_PATH - _tcslen(szStr)); - szStr[_MAX_PATH - 1] = _T('\0'); - } - else if (_tcsnicmp(strPath, _T(""), 9) == 0) - { - // get windows path - UINT uiSize=GetWindowsDirectory(szStr, _MAX_PATH); - if (szStr[uiSize-1] == _T('\\')) - szStr[uiSize-1]=_T('\0'); - _tcsncat(szStr, strPath.Mid(9), _MAX_PATH - uiSize); - szStr[_MAX_PATH - 1] = _T('\0'); - } - else if (_tcsnicmp(strPath, _T(""), 6) == 0) // temp dir - { - // get windows path - UINT uiSize=GetTempPath(_MAX_PATH, szStr); - if (szStr[uiSize-1] == _T('\\')) - szStr[uiSize-1]=_T('\0'); - _tcsncat(szStr, strPath.Mid(6), _MAX_PATH - uiSize); - szStr[_MAX_PATH - 1] = _T('\0'); - } - else if (_tcsnicmp(strPath, _T(""), 8) == 0) // system - { - // get windows path - UINT uiSize=GetSystemDirectory(szStr, _MAX_PATH); - if (szStr[uiSize-1] == _T('\\')) - szStr[uiSize-1]=_T('\0'); - _tcsncat(szStr, strPath.Mid(8), _MAX_PATH - uiSize); - szStr[_MAX_PATH - 1] = _T('\0'); - } - else if (_tcsnicmp(strPath, _T(""), 9) == 0) // app data - { - // get windows path - UINT uiSize=GetFolderLocation(CSIDL_LOCAL_APPDATA, szStr); - if (szStr[uiSize-1] == _T('\\')) - szStr[uiSize-1]=_T('\0'); - _tcsncat(szStr, strPath.Mid(9), _MAX_PATH - uiSize); - szStr[_MAX_PATH - 1] = _T('\0'); - } - else if (_tcsnicmp(strPath, _T(""), 9) == 0) // desktop - { - // get windows path - UINT uiSize=GetFolderLocation(CSIDL_DESKTOPDIRECTORY, szStr); - if (szStr[uiSize-1] == _T('\\')) - szStr[uiSize-1]=_T('\0'); - _tcsncat(szStr, strPath.Mid(9), _MAX_PATH - uiSize); - szStr[_MAX_PATH - 1] = _T('\0'); - } - else if (_tcsnicmp(strPath, _T(""), 10) == 0) // personal... - { - // get windows path - UINT uiSize=GetFolderLocation(CSIDL_PERSONAL, szStr); - if (szStr[uiSize-1] == _T('\\')) - szStr[uiSize-1]=_T('\0'); - _tcsncat(szStr, strPath.Mid(10), _MAX_PATH - uiSize); - szStr[_MAX_PATH - 1] = _T('\0'); - } - - // copy to src string - return szStr; -} - bool CAppHelper::GetProgramDataPath(CString& rStrPath) { if(IsInPortableMode()) - rStrPath = GetProgramPath(); + rStrPath = m_pathProcessor.GetProgramPath(); else { - HRESULT hResult = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, rStrPath.GetBufferSetLength(_MAX_PATH)); - rStrPath.ReleaseBuffer(); - if(FAILED(hResult)) - return false; + rStrPath = m_pathProcessor.GetAppDataPath(); + rStrPath += L"\\Copy Handler"; - if(rStrPath.Right(1) != _T('\\')) - rStrPath += _T('\\'); - // make sure to create the required directories if they does not exist - rStrPath += _T("Copy Handler"); if(!CreateDirectory(rStrPath, NULL) && GetLastError() != ERROR_ALREADY_EXISTS) return false; } @@ -242,12 +103,22 @@ return true; } +CString CAppHelper::ExpandPath(CString strPath) +{ + return m_pathProcessor.ExpandPath(strPath); +} + +CString CAppHelper::GetProgramPath() const +{ + return m_pathProcessor.GetProgramPath(); +} + bool CAppHelper::IsInPortableMode() { if(!m_optPortableMode.is_initialized()) { // check if the ch.ini exists in the program's directory - it is the only way we can determine portable mode - CString strPortableCfgPath = CString(GetProgramPath()) + _T("\\ch.xml"); + CString strPortableCfgPath = CString(m_pathProcessor.GetProgramPath()) + _T("\\ch.xml"); if(GetFileAttributes(strPortableCfgPath) == INVALID_FILE_ATTRIBUTES) m_optPortableMode = false; else @@ -287,7 +158,7 @@ return true; // format the data to be written to registry - strKey.Format(_T("%s\\%s"), m_pszProgramPath, m_pszProgramName); + strKey.Format(_T("%s\\%s"), (PCTSTR)m_pathProcessor.GetProgramPath(), m_pszProgramName); } else { @@ -297,7 +168,7 @@ if(bEnable) { // key exists in registry, check if the value is correct - strKey.Format(_T("%s\\%s"), m_pszProgramPath, m_pszProgramName); + strKey.Format(_T("%s\\%s"), (PCTSTR)m_pathProcessor.GetProgramPath(), m_pszProgramName); if(strValue.CompareNoCase(strKey) == 0) return true; Index: src/ch/AppHelper.h =================================================================== diff -u -r44a2ec5f1eb0a435b56daef42ef5fe3b7a91da0d -rffb46a396ce20cda2e04020cf01c118ae81642b5 --- src/ch/AppHelper.h (.../AppHelper.h) (revision 44a2ec5f1eb0a435b56daef42ef5fe3b7a91da0d) +++ src/ch/AppHelper.h (.../AppHelper.h) (revision ffb46a396ce20cda2e04020cf01c118ae81642b5) @@ -20,6 +20,7 @@ #define __APPHELPER_H__ #include +#include "TPathProcessor.h" class CAppHelper { @@ -28,33 +29,32 @@ virtual ~CAppHelper(); bool SetAutorun(bool bState); // changes state of "run with system" option - CString ExpandPath(CString strPath); // expands path string - ie. into c:\windows bool IsFirstInstance() const { return m_bFirstInstance; }; PCTSTR GetAppName() const { return m_pszAppName; }; PCTSTR GetAppNameVer() const { return m_pszAppNameVer; }; PCTSTR GetAppVersion() const { return m_pszAppVersion; }; - PCTSTR GetProgramPath() const { return m_pszProgramPath; }; PCTSTR GetProgramName() const { return m_pszProgramName; }; bool GetProgramDataPath(CString& rStrPath); + CString ExpandPath(CString strPath); + CString GetProgramPath() const; bool IsInPortableMode(); protected: void InitProtection(); // optional call - protects from running multiple instance void RetrievePaths(); // reads program's path and name void RetrieveAppInfo(); // reads app name and version from VERSION resource - UINT GetFolderLocation(int iFolder, PTSTR pszBuffer); protected: HANDLE m_hMutex; bool m_bFirstInstance; // tells if it is first instance(true) or second(or third, ...) // program placement - TCHAR* m_pszProgramPath; // path from which this program was run + TPathProcessor m_pathProcessor; TCHAR* m_pszProgramName; // name of this program (ie. CH.exe) TCHAR* m_pszAppName; // app-name string of this app Index: src/ch/OptionsDlg.cpp =================================================================== diff -u -r045540c818c374806d09742ef3d7a984d8d757d3 -rffb46a396ce20cda2e04020cf01c118ae81642b5 --- src/ch/OptionsDlg.cpp (.../OptionsDlg.cpp) (revision 045540c818c374806d09742ef3d7a984d8d757d3) +++ src/ch/OptionsDlg.cpp (.../OptionsDlg.cpp) (revision ffb46a396ce20cda2e04020cf01c118ae81642b5) @@ -343,17 +343,19 @@ SetPropValue(rConfig, GetBoolProp(iPosition++)); SetPropValue(rConfig, GetUintProp(iPosition++)); SetPropValue(rConfig, IndexToPriorityClass(GetIndexProp(iPosition++))); + // language - PCTSTR pszSrc=m_vld.at(GetIndexProp(iPosition++)).GetFilename(true); - if (_tcsnicmp(pszSrc, GetApp().GetProgramPath(), _tcslen(GetApp().GetProgramPath())) == 0) + CString strSrc = m_vld.at(GetIndexProp(iPosition++)).GetFilename(true); + CString strProgramPath = GetApp().GetProgramPath(); + if (_tcsnicmp(strSrc, GetApp().GetProgramPath(), GetApp().GetProgramPath().GetLength()) == 0) { // replace the first part of path with TCHAR szData[_MAX_PATH]; - _sntprintf(szData, _MAX_PATH, _T("%s"), pszSrc+_tcslen(GetApp().GetProgramPath())); + _sntprintf(szData, _MAX_PATH, _T("%s"), strSrc.Mid(strProgramPath.GetLength())); SetPropValue(rConfig, szData); } else - SetPropValue(rConfig, pszSrc); + SetPropValue(rConfig, strSrc); SKIP_SEPARATOR(iPosition); SetPropValue(rConfig, GetUintProp(iPosition++)); Index: src/ch/TPathProcessor.cpp =================================================================== diff -u --- src/ch/TPathProcessor.cpp (revision 0) +++ src/ch/TPathProcessor.cpp (revision ffb46a396ce20cda2e04020cf01c118ae81642b5) @@ -0,0 +1,166 @@ +// ============================================================================ +// Copyright (C) 2001-2016 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// 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 Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "TPathProcessor.h" + +TPathProcessor::TPathProcessor() +{ + RetrievePaths(); +} + +CString TPathProcessor::ExpandPath(CString strPath) +{ + if(strPath[ 0 ] != _T('<')) + return strPath; + + // search for string to replace + // _T(""), _T(""), _T(""), _T(""), _T(""), + // _T(""), _T("") + if(StartsWith(strPath, _T(""))) + strPath.Replace(_T(""), m_strProgramPath); + else if(StartsWith(strPath, _T(""))) + strPath.Replace(_T(""), GetWindowsPath()); + else if(StartsWith(strPath, _T(""))) // temp dir + strPath.Replace(_T(""), GetTempPath()); + else if(StartsWith(strPath, _T(""))) // system + strPath.Replace(_T(""), GetSystemPath()); + else if(StartsWith(strPath, _T(""))) // app data + strPath.Replace(_T(""), GetFolderLocation(CSIDL_LOCAL_APPDATA)); + else if(StartsWith(strPath, _T(""))) // desktop + strPath.Replace(_T(""), GetFolderLocation(CSIDL_DESKTOPDIRECTORY)); + else if(StartsWith(strPath, _T(""))) // personal... + strPath.Replace(_T(""), GetFolderLocation(CSIDL_PERSONAL)); + + return strPath; +} + +CString TPathProcessor::GetProgramPath() const +{ + return m_strProgramPath; +} + +CString TPathProcessor::GetAppDataPath() const +{ + return GetFolderLocation(CSIDL_LOCAL_APPDATA); +} + +bool TPathProcessor::StartsWith(const CString& strWhere, const CString& strWhat) +{ + int iLen = strWhat.GetLength(); + if(iLen <= 0) + return false; + + return (strWhere.Left(iLen) == strWhat); +} + +CString TPathProcessor::GetWindowsPath() +{ + // get windows path + wchar_t szData[ _MAX_PATH + 1 ]; + UINT uiSize = GetWindowsDirectory(szData, _MAX_PATH); + if(uiSize == 0 || uiSize > _MAX_PATH) + return CString(); + + if(szData[ uiSize - 1 ] == _T('\\')) + szData[ uiSize - 1 ] = _T('\0'); + + return szData; +} + +CString TPathProcessor::GetTempPath() +{ + // get windows path + wchar_t szData[ _MAX_PATH + 1 ]; + UINT uiSize = ::GetTempPath(_MAX_PATH, szData); + if(uiSize == 0 || uiSize > _MAX_PATH) + return CString(); + + if(szData[ uiSize - 1 ] == _T('\\')) + szData[ uiSize - 1 ] = _T('\0'); + + return szData; +} + +CString TPathProcessor::GetSystemPath() +{ + // get windows path + wchar_t szData[ _MAX_PATH + 1 ]; + UINT uiSize = GetSystemDirectory(szData, _MAX_PATH); + if(uiSize == 0 || uiSize > _MAX_PATH) + return CString(); + + if(szData[ uiSize - 1 ] == _T('\\')) + szData[ uiSize - 1 ] = _T('\0'); + + return szData; +} + +CString TPathProcessor::GetFolderLocation(int iFolder) +{ + LPITEMIDLIST piid = nullptr; + HRESULT hResult = SHGetSpecialFolderLocation(NULL, iFolder, &piid); + if(!SUCCEEDED(hResult)) + return CString(); + + // get path + wchar_t szData[ _MAX_PATH ]; + BOOL bRes = SHGetPathFromIDList(piid, szData); + + // free piid + LPMALLOC lpm = nullptr; + if(!SUCCEEDED(SHGetMalloc(&lpm))) + return CString(); + + lpm->Free((void*)piid); + lpm->Release(); + + // check for error + if(!bRes) + return CString(); + + // strip the last '\\' + CString strPath = szData; + strPath.TrimRight(L'\\'); + + return strPath; +} + +void TPathProcessor::RetrievePaths() +{ + // try to find '\\' in path to see if this is only exe name or fully qualified path + TCHAR* pszArgv = __wargv[ 0 ]; + + CString strName = pszArgv; + int iPos = strName.ReverseFind(_T('\\')); + + if(iPos != -1) + m_strProgramPath = strName.Left(iPos + 1); + else + { + // path + TCHAR szPath[ _MAX_PATH ]; + UINT uiSize = GetCurrentDirectory(_MAX_PATH, szPath); + if(uiSize == 0) + m_strProgramPath.Empty(); + else + m_strProgramPath = szPath; + } + + m_strProgramPath.TrimRight(L'\\'); +} Index: src/ch/TPathProcessor.h =================================================================== diff -u --- src/ch/TPathProcessor.h (revision 0) +++ src/ch/TPathProcessor.h (revision ffb46a396ce20cda2e04020cf01c118ae81642b5) @@ -0,0 +1,46 @@ +// ============================================================================ +// Copyright (C) 2001-2016 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// 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 Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TPATHPROCESSOR_H__ +#define __TPATHPROCESSOR_H__ + +class TPathProcessor +{ +public: + TPathProcessor(); + + CString ExpandPath(CString strPath); + + CString GetProgramPath() const; + CString GetAppDataPath() const; + +private: + void RetrievePaths(); + + static CString GetFolderLocation(int iFolder); + static CString GetWindowsPath(); + static CString GetTempPath(); + static CString GetSystemPath(); + + bool StartsWith(const CString& strWhere, const CString& strWhat); + +private: + CString m_strProgramPath; // path from which this program was run +}; + +#endif Index: src/ch/ch.cpp =================================================================== diff -u -r694e362bf3ce049a7bbba8b4cf442d07e6741901 -rffb46a396ce20cda2e04020cf01c118ae81642b5 --- src/ch/ch.cpp (.../ch.cpp) (revision 694e362bf3ce049a7bbba8b4cf442d07e6741901) +++ src/ch/ch.cpp (.../ch.cpp) (revision ffb46a396ce20cda2e04020cf01c118ae81642b5) @@ -138,7 +138,7 @@ bool bChanged=false; // flag that'll be returned - if the paths has changed // generate the current filename - uses language from config - CString strHelpPath = ExpandPath(_T("\\Help\\")); + CString strHelpPath = m_pathProcessor.ExpandPath(_T("\\Help\\")); strHelpPath += GetResManager().m_ld.GetHelpName(); if(strHelpPath != m_pszHelpFilePath) { @@ -347,7 +347,7 @@ rResManager.SetCallback(ResManCallback); GetPropValue(rCfg, strPath); TRACE(_T("Help path=%s\n"), strPath); - if(!rResManager.SetLanguage(ExpandPath(strPath))) + if(!rResManager.SetLanguage(m_pathProcessor.ExpandPath(strPath))) { TCHAR szData[2048]; _sntprintf(szData, 2048, _T("Couldn't find the language file specified in configuration file:\n%s\nPlease correct this path to point the language file to use.\nProgram will now exit."), (PCTSTR)strPath); @@ -576,7 +576,7 @@ void CCopyHandlerApp::RegisterShellExtension() { - CString strPath = CString(GetProgramPath()) + _T("\\"); + CString strPath = CString(m_pathProcessor.GetProgramPath()) + _T("\\"); #ifdef _WIN64 strPath += _T("chext64.dll"); @@ -614,7 +614,7 @@ void CCopyHandlerApp::UnregisterShellExtension() { - CString strPath = CString(GetProgramPath()) + _T("\\"); + CString strPath = CString(m_pathProcessor.GetProgramPath()) + _T("\\"); #ifdef _WIN64 strPath += _T("chext64.dll"); @@ -649,7 +649,7 @@ // update language in resource manager CString strPath; GetPropValue(GetConfig(), strPath); - GetResManager().SetLanguage(ExpandPath(strPath)); + GetResManager().SetLanguage(m_pathProcessor.ExpandPath(strPath)); } if(setPropNames.HasValue(PropData::GetPropertyName())) Index: src/ch/ch.vc140.vcxproj =================================================================== diff -u -rc4b596d905262841724ae7b091c11a8c9d5b4a5f -rffb46a396ce20cda2e04020cf01c118ae81642b5 --- src/ch/ch.vc140.vcxproj (.../ch.vc140.vcxproj) (revision c4b596d905262841724ae7b091c11a8c9d5b4a5f) +++ src/ch/ch.vc140.vcxproj (.../ch.vc140.vcxproj) (revision ffb46a396ce20cda2e04020cf01c118ae81642b5) @@ -522,6 +522,7 @@ + @@ -770,6 +771,7 @@ + Index: src/ch/ch.vc140.vcxproj.filters =================================================================== diff -u -r926b1177cffa2face218fabb3d8af71910d1b8e5 -rffb46a396ce20cda2e04020cf01c118ae81642b5 --- src/ch/ch.vc140.vcxproj.filters (.../ch.vc140.vcxproj.filters) (revision 926b1177cffa2face218fabb3d8af71910d1b8e5) +++ src/ch/ch.vc140.vcxproj.filters (.../ch.vc140.vcxproj.filters) (revision ffb46a396ce20cda2e04020cf01c118ae81642b5) @@ -239,6 +239,9 @@ Source Files\GUI\Controls + + Source Files\Tools + @@ -406,6 +409,9 @@ Source Files\GUI\Controls + + Source Files\Tools +