Add the ability to open the target file of a Shortcut (.lnk)

Fix #8483, close #8810
This commit is contained in:
Roshni-P 2020-09-04 07:25:48 +05:30 committed by Don HO
parent d9959c1a7c
commit e44ed31434
No known key found for this signature in database
GPG Key ID: 6C429F1D8D84F46E
2 changed files with 54 additions and 11 deletions

View File

@ -250,7 +250,7 @@ CXX = $(CROSS_COMPILE)g++
CXXFLAGS = $(INCLUDESPECIAL) -DTIXML_USE_STL -DTIXMLA_USE_STL $(UNICODE) -std=c++17 -fpermissive
INCLUDES = $(patsubst %,-I%,$(DIRS)) -I./include
LDFLAGS = -Wl,--subsystem,windows -municode -mwindows
LIBS = -lcomdlg32 -lcomctl32 -lgdi32 -lole32 -loleacc -lshell32 -lshlwapi -ldbghelp -lversion -lcrypt32 -lsensapi -lwintrust -lwinmm
LIBS = -lcomdlg32 -lcomctl32 -lgdi32 -lole32 -loleacc -lshell32 -lshlwapi -ldbghelp -lversion -lcrypt32 -lsensapi -lwintrust -lwinmm -luuid
RC = $(CROSS_COMPILE)windres

View File

@ -130,12 +130,55 @@ DWORD WINAPI Notepad_plus::monitorFileOnChange(void * params)
return EXIT_SUCCESS;
}
void resolveLinkFile(generic_string& linkFilePath)
{
IShellLink* psl;
WCHAR targetFilePath[MAX_PATH];
WIN32_FIND_DATA wfd;
HRESULT hres = CoInitialize(NULL);
if (SUCCEEDED(hres))
{
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
if (SUCCEEDED(hres))
{
IPersistFile* ppf;
hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
if (SUCCEEDED(hres))
{
// Load the shortcut.
hres = ppf->Load(linkFilePath.c_str(), STGM_READ);
if (SUCCEEDED(hres) && hres != S_FALSE)
{
// Resolve the link.
hres = psl->Resolve(NULL, 0);
if (SUCCEEDED(hres) && hres != S_FALSE)
{
// Get the path to the link target.
hres = psl->GetPath(targetFilePath, MAX_PATH, (WIN32_FIND_DATA*)&wfd, SLGP_SHORTPATH);
if (SUCCEEDED(hres) && hres != S_FALSE)
{
linkFilePath = targetFilePath;
}
}
}
ppf->Release();
}
psl->Release();
}
CoUninitialize();
}
}
BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive, bool isReadOnly, int encoding, const TCHAR *backupFileName, FILETIME fileNameTimestamp)
{
const rsize_t longFileNameBufferSize = MAX_PATH; // TODO stop using fixed-size buffer
if (fileName.size() >= longFileNameBufferSize - 1) // issue with all other sub-routines
return BUFFER_INVALID;
generic_string targetFileName = fileName;
resolveLinkFile(targetFileName);
//If [GetFullPathName] succeeds, the return value is the length, in TCHARs, of the string copied to lpBuffer, not including the terminating null character.
//If the lpBuffer buffer is too small to contain the path, the return value [of GetFullPathName] is the size, in TCHARs, of the buffer that is required to hold the path and the terminating null character.
//If [GetFullPathName] fails for any other reason, the return value is zero.
@ -143,7 +186,7 @@ BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive,
NppParameters& nppParam = NppParameters::getInstance();
TCHAR longFileName[longFileNameBufferSize];
const DWORD getFullPathNameResult = ::GetFullPathName(fileName.c_str(), longFileNameBufferSize, longFileName, NULL);
const DWORD getFullPathNameResult = ::GetFullPathName(targetFileName.c_str(), longFileNameBufferSize, longFileName, NULL);
if (getFullPathNameResult == 0)
{
return BUFFER_INVALID;
@ -163,12 +206,12 @@ BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive,
bool isSnapshotMode = backupFileName != NULL && PathFileExists(backupFileName);
if (isSnapshotMode && !PathFileExists(longFileName)) // UNTITLED
{
wcscpy_s(longFileName, fileName.c_str());
wcscpy_s(longFileName, targetFileName.c_str());
}
_lastRecentFileList.remove(longFileName);
generic_string fileName2Find;
generic_string gs_fileName{ fileName };
generic_string gs_fileName{ targetFileName };
// "fileName" could be:
@ -177,7 +220,7 @@ BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive,
// 3. a file name with relative path to open or create
// Search case 1 & 2 firstly
BufferID foundBufID = MainFileManager.getBufferFromName(fileName.c_str());
BufferID foundBufID = MainFileManager.getBufferFromName(targetFileName.c_str());
if (foundBufID == BUFFER_INVALID)
fileName2Find = longFileName;
@ -364,19 +407,19 @@ BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive,
}
else
{
if (globbing || ::PathIsDirectory(fileName.c_str()))
if (globbing || ::PathIsDirectory(targetFileName.c_str()))
{
vector<generic_string> fileNames;
vector<generic_string> patterns;
if (globbing)
{
const TCHAR * substring = wcsrchr(fileName.c_str(), TCHAR('\\'));
const TCHAR * substring = wcsrchr(targetFileName.c_str(), TCHAR('\\'));
if (substring)
{
size_t pos = substring - fileName.c_str();
size_t pos = substring - targetFileName.c_str();
patterns.push_back(substring + 1);
generic_string dir(fileName.c_str(), pos + 1); // use char * to evoke:
generic_string dir(targetFileName.c_str(), pos + 1); // use char * to evoke:
// string (const char* s, size_t n);
// and avoid to call (if pass string) :
// string (const string& str, size_t pos, size_t len = npos);
@ -386,8 +429,8 @@ BufferID Notepad_plus::doOpen(const generic_string& fileName, bool isRecursive,
}
else
{
generic_string fileNameStr = fileName;
if (fileName[fileName.size() - 1] != '\\')
generic_string fileNameStr = targetFileName;
if (targetFileName[targetFileName.size() - 1] != '\\')
fileNameStr += TEXT("\\");
patterns.push_back(TEXT("*"));