Skip to content

Commit

Permalink
Support running both Notepad2 and metapath as symbolic link.
Browse files Browse the repository at this point in the history
  • Loading branch information
zufuliu committed Sep 25, 2021
1 parent 9949744 commit 930874d
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 26 deletions.
15 changes: 8 additions & 7 deletions metapath/src/Helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ BOOL FindUserResourcePath(LPCWSTR path, LPWSTR outPath) {
}

// relative to program exe file
GetModuleFileName(NULL, tchBuild, COUNTOF(tchBuild));
GetProgramRealPath(tchBuild, COUNTOF(tchBuild));
lstrcpy(PathFindFileName(tchBuild), tchFileExpanded);
if (PathIsFile(tchBuild)) {
lstrcpy(outPath, tchBuild);
Expand Down Expand Up @@ -983,7 +983,7 @@ HMODULE LoadLocalizedResourceDLL(LANGID lang, LPCWSTR dllName) {
}

WCHAR path[MAX_PATH];
GetModuleFileName(NULL, path, COUNTOF(path));
GetProgramRealPath(path, COUNTOF(path));
PathRemoveFileSpec(path);
PathAppend(path, L"locale");
PathAppend(path, folder);
Expand Down Expand Up @@ -1073,15 +1073,10 @@ BOOL PathGetRealPath(HANDLE hFile, LPCWSTR lpszSrc, LPWSTR lpszDest) {
// PathRelativeToApp()
//
void PathRelativeToApp(LPCWSTR lpszSrc, LPWSTR lpszDest, int cchDest, BOOL bSrcIsFile, BOOL bUnexpandEnv, BOOL bUnexpandMyDocs) {
WCHAR wchAppPath[MAX_PATH];
WCHAR wchWinDir[MAX_PATH];
WCHAR wchUserFiles[MAX_PATH];
WCHAR wchPath[MAX_PATH];
const DWORD dwAttrTo = bSrcIsFile ? 0 : FILE_ATTRIBUTE_DIRECTORY;

GetModuleFileName(NULL, wchAppPath, COUNTOF(wchAppPath));
PathRemoveFileSpec(wchAppPath);
GetWindowsDirectory(wchWinDir, COUNTOF(wchWinDir));
#if _WIN32_WINNT < _WIN32_WINNT_VISTA
if (S_OK != SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, wchUserFiles)) {
return;
Expand All @@ -1095,6 +1090,12 @@ void PathRelativeToApp(LPCWSTR lpszSrc, LPWSTR lpszDest, int cchDest, BOOL bSrcI
CoTaskMemFree(pszPath);
#endif

WCHAR wchAppPath[MAX_PATH];
WCHAR wchWinDir[MAX_PATH];
GetModuleFileName(NULL, wchAppPath, COUNTOF(wchAppPath));
PathRemoveFileSpec(wchAppPath);
GetWindowsDirectory(wchWinDir, COUNTOF(wchWinDir));

if (bUnexpandMyDocs &&
!PathIsRelative(lpszSrc) &&
!PathIsPrefix(wchUserFiles, wchAppPath) &&
Expand Down
13 changes: 13 additions & 0 deletions metapath/src/Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,11 @@ NP2_inline BOOL PathIsFile(LPCWSTR pszPath) {
return (GetFileAttributes(pszPath) & FILE_ATTRIBUTE_DIRECTORY) == 0;
}

NP2_inline BOOL PathIsSymbolicLink(LPCWSTR pszPath) {
// assume file exists, no check for INVALID_FILE_ATTRIBUTES.
return (GetFileAttributes(pszPath) & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
}

// https://docs.microsoft.com/en-us/windows/win32/intl/handling-sorting-in-your-applications#sort-strings-ordinally
NP2_inline BOOL PathEqual(LPCWSTR pszPath1, LPCWSTR pszPath2) {
#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
Expand All @@ -466,6 +471,14 @@ NP2_inline BOOL PathEqual(LPCWSTR pszPath1, LPCWSTR pszPath2) {

// similar to realpath() and std::filesystem::canonical()
BOOL PathGetRealPath(HANDLE hFile, LPCWSTR lpszSrc, LPWSTR lpszDest);
NP2_inline void GetProgramRealPath(LPWSTR tchModule, DWORD nSize) {
GetModuleFileName(NULL, tchModule, nSize);
// for symbolic link, module path is link's path not target's.
if (PathIsSymbolicLink(tchModule)) {
PathGetRealPath(NULL, tchModule, tchModule);
}
}

void PathRelativeToApp(LPCWSTR lpszSrc, LPWSTR lpszDest, int cchDest, BOOL bSrcIsFile,
BOOL bUnexpandEnv, BOOL bUnexpandMyDocs);
void PathAbsoluteFromApp(LPCWSTR lpszSrc, LPWSTR lpszDest, int cchDest, BOOL bExpandEnv);
Expand Down
11 changes: 6 additions & 5 deletions metapath/src/metapath.c
Original file line number Diff line number Diff line change
Expand Up @@ -3116,14 +3116,15 @@ BOOL CheckIniFileRedirect(LPWSTR lpszFile, LPCWSTR lpszModule) {
}

BOOL FindIniFile(void) {
if (StrEqualExW(szIniFile, L"*?")) {
return FALSE;
}

WCHAR tchTest[MAX_PATH];
WCHAR tchModule[MAX_PATH];
GetModuleFileName(NULL, tchModule, COUNTOF(tchModule));
GetProgramRealPath(tchModule, COUNTOF(tchModule));

if (StrNotEmpty(szIniFile)) {
if (StrEqualExW(szIniFile, L"*?")) {
return 0;
}
if (!CheckIniFile(szIniFile, tchModule)) {
ExpandEnvironmentStringsEx(szIniFile, COUNTOF(szIniFile));
if (PathIsRelative(szIniFile)) {
Expand Down Expand Up @@ -3173,7 +3174,7 @@ BOOL TestIniFile(void) {

if ((dwFileAttributes != INVALID_FILE_ATTRIBUTES) || *CharPrev(szIniFile, StrEnd(szIniFile)) == L'\\') {
WCHAR wchModule[MAX_PATH];
GetModuleFileName(NULL, wchModule, COUNTOF(wchModule));
GetProgramRealPath(wchModule, COUNTOF(wchModule));
PathAppend(szIniFile, PathFindFileName(wchModule));
PathRenameExtension(szIniFile, L".ini");
dwFileAttributes = GetFileAttributes(szIniFile);
Expand Down
2 changes: 1 addition & 1 deletion src/Edit.c
Original file line number Diff line number Diff line change
Expand Up @@ -7161,7 +7161,7 @@ void TryBrowseFile(HWND hwnd, LPCWSTR pszFile, BOOL bWarn) {
lstrcpy(tchExeFile, L"metapath.exe");
}
if (PathIsRelative(tchExeFile)) {
GetModuleFileName(NULL, tchTemp, COUNTOF(tchTemp));
GetProgramRealPath(tchTemp, COUNTOF(tchTemp));
PathRemoveFileSpec(tchTemp);
PathAppend(tchTemp, tchExeFile);
if (PathIsFile(tchTemp)) {
Expand Down
15 changes: 8 additions & 7 deletions src/Helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ BOOL FindUserResourcePath(LPCWSTR path, LPWSTR outPath) {
}

// relative to program exe file
GetModuleFileName(NULL, tchBuild, COUNTOF(tchBuild));
GetProgramRealPath(tchBuild, COUNTOF(tchBuild));
lstrcpy(PathFindFileName(tchBuild), tchFileExpanded);
if (PathIsFile(tchBuild)) {
lstrcpy(outPath, tchBuild);
Expand Down Expand Up @@ -1566,7 +1566,7 @@ HMODULE LoadLocalizedResourceDLL(LANGID lang, LPCWSTR dllName) {
}

WCHAR path[MAX_PATH];
GetModuleFileName(NULL, path, COUNTOF(path));
GetProgramRealPath(path, COUNTOF(path));
PathRemoveFileSpec(path);
PathAppend(path, L"locale");
PathAppend(path, folder);
Expand Down Expand Up @@ -1714,15 +1714,10 @@ BOOL PathEquivalent(LPCWSTR pszPath1, LPCWSTR pszPath2) {
//
void PathRelativeToApp(LPCWSTR lpszSrc, LPWSTR lpszDest, int cchDest,
BOOL bSrcIsFile, BOOL bUnexpandEnv, BOOL bUnexpandMyDocs) {
WCHAR wchAppPath[MAX_PATH];
WCHAR wchWinDir[MAX_PATH];
WCHAR wchUserFiles[MAX_PATH];
WCHAR wchPath[MAX_PATH];
const DWORD dwAttrTo = bSrcIsFile ? 0 : FILE_ATTRIBUTE_DIRECTORY;

GetModuleFileName(NULL, wchAppPath, COUNTOF(wchAppPath));
PathRemoveFileSpec(wchAppPath);
GetWindowsDirectory(wchWinDir, COUNTOF(wchWinDir));
#if _WIN32_WINNT < _WIN32_WINNT_VISTA
if (S_OK != SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, wchUserFiles)) {
return;
Expand All @@ -1736,6 +1731,12 @@ void PathRelativeToApp(LPCWSTR lpszSrc, LPWSTR lpszDest, int cchDest,
CoTaskMemFree(pszPath);
#endif

WCHAR wchAppPath[MAX_PATH];
WCHAR wchWinDir[MAX_PATH];
GetModuleFileName(NULL, wchAppPath, COUNTOF(wchAppPath));
PathRemoveFileSpec(wchAppPath);
GetWindowsDirectory(wchWinDir, COUNTOF(wchWinDir));

if (bUnexpandMyDocs &&
!PathIsRelative(lpszSrc) &&
!PathIsPrefix(wchUserFiles, wchAppPath) &&
Expand Down
13 changes: 13 additions & 0 deletions src/Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,11 @@ NP2_inline BOOL PathIsFile(LPCWSTR pszPath) {
return (GetFileAttributes(pszPath) & FILE_ATTRIBUTE_DIRECTORY) == 0;
}

NP2_inline BOOL PathIsSymbolicLink(LPCWSTR pszPath) {
// assume file exists, no check for INVALID_FILE_ATTRIBUTES.
return (GetFileAttributes(pszPath) & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
}

// https://docs.microsoft.com/en-us/windows/win32/intl/handling-sorting-in-your-applications#sort-strings-ordinally
NP2_inline BOOL PathEqual(LPCWSTR pszPath1, LPCWSTR pszPath2) {
#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
Expand All @@ -804,6 +809,14 @@ NP2_inline BOOL PathEqual(LPCWSTR pszPath1, LPCWSTR pszPath2) {

// similar to realpath() and std::filesystem::canonical()
BOOL PathGetRealPath(HANDLE hFile, LPCWSTR lpszSrc, LPWSTR lpszDest);
NP2_inline void GetProgramRealPath(LPWSTR tchModule, DWORD nSize) {
GetModuleFileName(NULL, tchModule, nSize);
// for symbolic link, module path is link's path not target's.
if (PathIsSymbolicLink(tchModule)) {
PathGetRealPath(NULL, tchModule, tchModule);
}
}

// similar to std::filesystem::equivalent()
BOOL PathEquivalent(LPCWSTR pszPath1, LPCWSTR pszPath2);
void PathRelativeToApp(LPCWSTR lpszSrc, LPWSTR lpszDest, int cchDest,
Expand Down
13 changes: 7 additions & 6 deletions src/Notepad2.c
Original file line number Diff line number Diff line change
Expand Up @@ -6736,14 +6736,15 @@ BOOL CheckIniFileRedirect(LPWSTR lpszFile, LPCWSTR lpszModule, LPCWSTR redirectK
}

BOOL FindIniFile(void) {
if (StrEqualExW(szIniFile, L"*?")) {
return FALSE;
}

WCHAR tchTest[MAX_PATH];
WCHAR tchModule[MAX_PATH];
GetModuleFileName(NULL, tchModule, COUNTOF(tchModule));
GetProgramRealPath(tchModule, COUNTOF(tchModule));

if (StrNotEmpty(szIniFile)) {
if (StrEqualExW(szIniFile, L"*?")) {
return FALSE;
}
if (!CheckIniFile(szIniFile, tchModule)) {
ExpandEnvironmentStringsEx(szIniFile, COUNTOF(szIniFile));
if (PathIsRelative(szIniFile)) {
Expand Down Expand Up @@ -6793,7 +6794,7 @@ BOOL TestIniFile(void) {

if ((dwFileAttributes != INVALID_FILE_ATTRIBUTES) || *CharPrev(szIniFile, StrEnd(szIniFile)) == L'\\') {
WCHAR wchModule[MAX_PATH];
GetModuleFileName(NULL, wchModule, COUNTOF(wchModule));
GetProgramRealPath(wchModule, COUNTOF(wchModule));
PathAppend(szIniFile, PathFindFileName(wchModule));
PathRenameExtension(szIniFile, L".ini");
dwFileAttributes = GetFileAttributes(szIniFile);
Expand Down Expand Up @@ -6835,7 +6836,7 @@ void FindExtraIniFile(LPWSTR lpszIniFile, LPCWSTR defaultName, LPCWSTR redirectK
lstrcpy(lpszIniFile, szIniFile);
} else {
// relative to program exe file
GetModuleFileName(NULL, lpszIniFile, MAX_PATH);
GetProgramRealPath(lpszIniFile, MAX_PATH);
}
lstrcpy(PathFindFileName(lpszIniFile), defaultName);
}
Expand Down

0 comments on commit 930874d

Please sign in to comment.